Search Unity

  1. Unity 2019.1 is now released.
    Dismiss Notice

Native Gallery for Android & iOS [Open Source]

Discussion in 'Assets and Asset Store' started by yasirkula, Feb 28, 2018.

  1. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    873
  2. Y76_Unity

    Y76_Unity

    Joined:
    Jan 29, 2018
    Posts:
    27
    New
    Hi, yasirkula

    is there a way to Open Galley on Specific Album name Directly ?
     
  3. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    873
    Unfortunately not :(
     
  4. Y76_Unity

    Y76_Unity

    Joined:
    Jan 29, 2018
    Posts:
    27
    is there any update in Future includes this feature ?
     
  5. pavan24bh

    pavan24bh

    Joined:
    Dec 11, 2018
    Posts:
    3
    yasirkula likes this.
  6. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    873
    @Qusai_Azzam I don't plan to add this feature because it doesn't seem possible to implement this feature natively, i.e. there is no way to achieve this with the native Gallery app.
     
  7. HuuLinhdr

    HuuLinhdr

    Joined:
    Nov 16, 2017
    Posts:
    3
    Thank for your answer @yasirkula , So how can show gallery, there have pictures in only my album save by Native Gallery?
     
  8. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    873
    If you are asking showing pictures in a particular album only, then it is not possible.
     
  9. Eljo_huckleberry

    Eljo_huckleberry

    Joined:
    Jun 1, 2017
    Posts:
    10
    @yasirkula I have this same behavior with the stock Photos app on Android 6, 7 and 8 (Nexus and Pixel devices) and I think it's due to the plugin saving to /storage/emulated/0/DCIM/<album>/<file> in my case, marking it as a camera source. If I don't have it in the DCIM folder, it's displayed correctly.

    This might be specifically tied to how the stock Photos app handles this as I've tried another gallery viewer as downloaded from the Play Store which worked fine with this folder setup out of the box.
     
  10. HuuLinhdr

    HuuLinhdr

    Joined:
    Nov 16, 2017
    Posts:
    3
    Thanks, So may I show both picture and video use Native Gallery?
     
  11. zetaxbr

    zetaxbr

    Joined:
    May 17, 2016
    Posts:
    2
    First of all thank you for this awesome tool! Second, its possible to integrate this with Playmaker (custom actions, etc).

    I'm designer not coder, thanks in advance!
     
  12. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    873
    @dart_ajax @thiagoberardinelli @Eljo_huckleberry Please try the attached unitypackage and see if it resolves your issues.

    @HuuLinhdr If you mean listing images and videos together in the same screen, then it is not possible with NativeGallery. Either images or videos are listed at a time.

    @zetaxbr I currently have no experience with Playmaker, I may read its tutorials to learn the process but I can't do it right now.
     

    Attached Files:

    HuuLinhdr likes this.
  13. antrinh

    antrinh

    Joined:
    Jun 11, 2018
    Posts:
    12
    Hi @yasirkula
    This is an awesome asset that I need.

    I planning dev a video player, but I want to get and show all video in storage into app (if it possible) instead of open gallery and pick a video. Is it possible with your asset?

    Thank for your awesome asset again! :D
     
  14. Eljo_huckleberry

    Eljo_huckleberry

    Joined:
    Jun 1, 2017
    Posts:
    10
    yasirkula likes this.
  15. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    873
    @antrinh Hi! Unfortunately, you can't fetch the list of the videos using NativeGallery. Listing those videos is handled by the native Gallery app and, with NativeGallery, we don't have any access to that list.
     
  16. pavan24bh

    pavan24bh

    Joined:
    Dec 11, 2018
    Posts:
    3
  17. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    873
  18. antrinh

    antrinh

    Joined:
    Jun 11, 2018
    Posts:
    12
    thanks for your support, Do you have any idea to list all videos in local storage and fetch the list to the same scene? I found an answer but only for android (java) :(

    btw: I used your native share, its so good and simple to use ;)
     
  19. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    873
    Are you trying to find a code for iOS or are you trying to use that Java code in Unity? I think the only Java-independent solution would be to traverse all directories in the storage recursively and filter files by their extensions. Otherwise, you have to communicate with the Java code.
     
  20. antrinh

    antrinh

    Joined:
    Jun 11, 2018
    Posts:
    12
    I'm trying to find a native code for both iOS and Android. That why I think Java code will not work with iOS.
     
  21. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    873
    Yes the Java code will work on only Android. On iOS, you'll probably have to use the Photos or the ALAssetLibrary frameworks to iterate through all the media on the device.
     
  22. dart_ajax

    dart_ajax

    Joined:
    Jan 17, 2018
    Posts:
    4
    Hi Yasirkula,

    Updated version works great! No more pause in my app. Thanks for the quick turnaround.

    Do you mind if I ask what you changed? I fumbled with it for a week before asking for your help, so would be nice to have closure!

    Thanks again!
     
    yasirkula likes this.
  23. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    873
  24. dart_ajax

    dart_ajax

    Joined:
    Jan 17, 2018
    Posts:
    4
    Great! Forgot to look at the code updates. Looks like quite a few changes.

    Works perfectly though. Thanks again for your help and for the great tool!
     
    yasirkula likes this.
  25. Crushem

    Crushem

    Joined:
    Nov 27, 2018
    Posts:
    2
    Hello yasurkula!
    Firstly, thank you a lot for your asset!
    I have only a one question. There are no problems with your asset in the Unity Editor and iOS, it works properly. But I have problem with android. After i choose photo, image shows just a white rect and nothing else. Draw your attention, that the same code works properly in iOs and Editor.
    Code:

    Code (CSharp):
    1. [SerializeField] Image testImage;
    2.  
    3. public void GetImageFromGallery()
    4.         {
    5.             int maxSize = 1024;
    6.             NativeGallery.Permission permission = NativeGallery.GetImageFromGallery((path) =>
    7.             {
    8. #if UNITY_EDITOR
    9.             path = Application.dataPath + "/image.png";
    10. #endif
    11.             Debug.Log("Image path: " + path);
    12.                 if (path != null)
    13.                 {
    14.                     Texture2D texture = NativeGallery.LoadImageAtPath(path, maxSize, false);
    15.  
    16.                     if (texture == null)
    17.                     {
    18.                         Debug.Log("Couldn't load texture from " + path);
    19.                         return;
    20.                     }
    21.  
    22.                     Sprite spr = Sprite.Create(texture, new Rect(0, 0, texture.width, texture.height), new Vector2(texture.width / 2, texture.height / 2));
    23.                     testImage.sprite = spr;
    24.                 }
    25.             }, "Select a PNG image", "image/png", maxSize);
    26.         }
    The strangest thing is that texture has working bytes. I have tried to show every byte from texture.EncodeToPng() and it does not return only 0. Every byte is good.
    How is it possible?

    And one more thing. This script works properly with Meizu and image is shown, but does not work with Google Pixel and Motorolla.
     
    Last edited: Dec 19, 2018
  26. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    873
  27. joesziveri

    joesziveri

    Joined:
    Dec 18, 2018
    Posts:
    6
    Howdy, I can't seem to get LoadImageAtPath working. Saving is working properly. I am saving it using this:

    NativeGallery.SaveImageToGallery(myTexture, "Wears", "Profile_Photo.png", null );

    and trying to load the image back with:

    Texture2D profile = NativeGallery.LoadImageAtPath("/DCIM/Wears/Profile_Photo.png", -1);

    I've tried using "/InternalStorage/DCIM/Wears/Profile_Photo.png" as well as countless other paths that could lead to the photo to no avail.

    When debugging my device I get this error:
    12-20 14:51:50.221: E/Unity(13318): FileNotFoundException: File not found at /Internal Storage/DCIM/Wears/Profile_Photo.png

    If I go into Internal Storage/DCIM/Wears there is clearly Profile_Photo.png in the folder

    EDIT: Got it working by using path /storage/emulated/0/DCIM/Wears/Profile_Photo.png
     
    Last edited: Dec 20, 2018
  28. Crushem

    Crushem

    Joined:
    Nov 27, 2018
    Posts:
    2
    Hello yasirkula.
    Finally I found out what was the problem. I changed project settings for Android, namely i have turned ON Auto Graphics API and Multithreading Rendering in Other Settings tab.
    May be it will be usefull for somebody who has the same problem
     
    yasirkula likes this.
  29. joesziveri

    joesziveri

    Joined:
    Dec 18, 2018
    Posts:
    6
    One last question: I currently have an SQL database setup that stores (up to 100s) of image paths on the users device. I am trying to load these images into an image carousel like so:


    My current problem is obviously it takes a lot of time to grab 100s of images from the user's gallery. Is there any resources or methods you can think of to load them asynchronously so they are added to the list ad they are loaded?
     
  30. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    873
    You can use a coroutine to load one image per frame; simply calling
    yield return null;
    before loading the next image does the job. You should also set the loaded image's maxSize as low as possible for better performance.

    Be aware that this method may not eliminate the lag spikes entirely because one of the bottlenecks here is converting an image into a Texture2D and this process can't run on a separate thread, which means it will stall the main thread no matter what.
     
  31. joesziveri

    joesziveri

    Joined:
    Dec 18, 2018
    Posts:
    6
    Thanks a ton! I was able to integrate the image loading with the UnityWebRequest workaround and with your advice on lowering the maxSize, it loads the images almost instantly!
     
    yasirkula likes this.
  32. vamsikrish229

    vamsikrish229

    Joined:
    Dec 24, 2018
    Posts:
    3
     
  33. vamsikrish229

    vamsikrish229

    Joined:
    Dec 24, 2018
    Posts:
    3
     
  34. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    873
  35. ivan_sichkar_avrspot

    ivan_sichkar_avrspot

    Joined:
    Mar 7, 2018
    Posts:
    5
    Hi yasirkula,

    Thanks for this plugin, it looks great, I'm trying to use it to retrieve image from the gallery, but
    MediaPickCallback doesn't work for me at all.

    I'm using the latest unity package from your GitHub repo (which was updated 23 days ago). I tried it with PickImage and PickVideo functions from README file. It returns me Granted permission, but no callback. I tried to export a Gradle project and added
    Code (CSharp):
    1. <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    manually to the manifest, but it gives me nothing. I'm using Unity 2018.3.0f2.

    If you have any idea please let me know :)
     
  36. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    873
    Are there any error messages in logcat? Does the code work on another device, or maybe on an emulator?
     
  37. ivan_sichkar_avrspot

    ivan_sichkar_avrspot

    Joined:
    Mar 7, 2018
    Posts:
    5
    Here is a log from logcat. I tested on Samsung S8 and Google Pixel. I suppose this is what we are looking for:

    2019-01-10 18:15:18.768 21107-21107/com.augbrite.TestGallery E/Unity: UnityException: Internal_CreateGameObject can only be called from the main thread.
    Constructors and field initializers will be executed from the loading thread when loading a scene.
    Don't use this function in the constructor or field initializers, instead move initialization code to the Awake or Start function.
    at UnityEngine.GameObject..ctor (System.String name) [0x00000] in <filename unknown>:0
    at NativeGalleryNamespace.NGMediaReceiveCallbackAndroid.OnMultipleMediaReceived (System.String paths) [0x000b3] in /Users/ivansichkar/Documents/UnityProjects/TestGallery/Assets/Plugins/NativeGallery/Android/NGMediaReceiveCallbackAndroid.cs:55
    at System.Reflection.MonoMethod.Invoke (System.Object obj, BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x000c0] in /Users/builduser/buildslave/mono/build/mcs/class/corlib/System.Reflection/MonoMethod.cs:222
    Rethrow as TargetInvocationException: NativeGalleryNamespace.NGMediaReceiveCall
     
  38. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    873
    Can I see your code, or relevant parts of it?
     
  39. ivan_sichkar_avrspot

    ivan_sichkar_avrspot

    Joined:
    Mar 7, 2018
    Posts:
    5
    Here it is
    Code (CSharp):
    1.  
    2. public class TestGallery : MonoBehaviour
    3. {
    4.     [SerializeField]
    5.     private Text debugText;
    6.     [SerializeField]
    7.     private Button openGalleryBtn;
    8.     [SerializeField]
    9.     private RawImage image;
    10.    
    11.    
    12.     private void Start()
    13.     {
    14.         openGalleryBtn.onClick.AddListener(OpenGallery);
    15.     }
    16.    
    17.     private void OpenGallery()
    18.     {
    19.         var permission = NativeGallery.CheckPermission();
    20.         if (permission != NativeGallery.Permission.Granted)
    21.         {
    22.             Debug.Log("RequestPermission");
    23.             NativeGallery.RequestPermission();
    24.         }
    25.        
    26.         PickImage(512);
    27.     }
    28.    
    29.     private void PickImage(int maxSize)
    30.     {
    31.         var permission = NativeGallery.GetImageFromGallery((path) =>
    32.         {
    33.             debugText.text = "Path - " + path;
    34.             Debug.Log( "Image path: " + path );
    35.             if( path != null )
    36.             {
    37.                 // Create Texture from selected image
    38.                 Texture2D texture = NativeGallery.LoadImageAtPath(path, maxSize);
    39.                 if( texture == null )
    40.                 {
    41.                     Debug.Log( "Couldn't load texture from " + path );
    42.                     return;
    43.                 }
    44.  
    45.                 // Assign texture to a temporary quad and destroy it after 5 seconds
    46.                 image.texture = texture;
    47.             }
    48.         }, "Select a PNG image", "image/png", maxSize);
    49.  
    50.         Debug.Log( "Permission result: " + permission );
    51.         debugText.text += "\nPermission result: " + permission;
    52.     }
    53. }
     
  40. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    873
  41. ivan_sichkar_avrspot

    ivan_sichkar_avrspot

    Joined:
    Mar 7, 2018
    Posts:
    5
    Now I just copied PickImage function from your example code snippet and jet the same result. Also, I tried to save a screenshot to the gallery and it works fine.
     
  42. johnny2014

    johnny2014

    Joined:
    Jun 11, 2014
    Posts:
    9
    Hey @yasirkula great plugin mate, and thanks for so much support.

    I was hoping to get some help. I have a GameObject (cube) on which I would like the video to play on. At the moment when I retrieve a video from my library it automatically plays in full screen. I am trying to import a video and then be able to have it embedded in the cube with the play/pause functionality.

    Is that possible to do and if so could you please with some code? I'd really appreciate some help.

    Thanks mate
     
  43. ivan_sichkar_avrspot

    ivan_sichkar_avrspot

    Joined:
    Mar 7, 2018
    Posts:
    5
    Hi again yasirkula,

    I really don't know what was wrong, but I switched to Unity 2018.3.1f1 and it working fine on this unity version.
    Anyway, thanks for your help :)
     
    yasirkula likes this.
  44. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    873
  45. johnny2014

    johnny2014

    Joined:
    Jun 11, 2014
    Posts:
    9
    Thanks for that, this code puts a very small cube in the middle of the screen that plays the video which is great. Only problem is that it's very small and the rotation is incorrect.
    Also it does not have the capability of play/pause and the scrubber.
    Do you think it's not possible to have that?
    How can I increase the the size and change the rotation?

    Sorry, for so many questions I've never used video playback before :)
     
  46. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    873
    I've provided this code for demonstration purposes only. In your own code, you'll probably want to use an existing video player that you reference in a public VideoPlayer variable instead of creating a new VideoPlayer by code.

    VideoPlayer doesn't come with play/pause like UI controls, you'll have to create them yourself or use an existing asset like this: https://github.com/JannikLassahn/unity-videoplayer-helper

    For rotation, you can set the rotation of the cube using
    NativeGallery.GetVideoProperties(videoFilePath).rotation
    .
     
    johnny2014 likes this.
  47. johnny2014

    johnny2014

    Joined:
    Jun 11, 2014
    Posts:
    9
    Thank you so much, you have been very helpful.
     
  48. suitmrt

    suitmrt

    Joined:
    May 19, 2016
    Posts:
    6
    Help! I'm in frustration now, because I cannot figure out wat's wrong. It's been three hours of search, I don't even now where to find the reasons for this bug.
    The problem is, when I go to the scene, where I save picture to gallery for the first time, the app just freezes, however, picture is saved.
    But when I go from that scene to another scene, and go back and save, everything is all right.
    The question seems to be really vague, but maybe I get some hints form forum users :)
    Could it be related to plugin settings, initialization and so on? What can be the reason for this behavior?
    The way I save. SaveColoredImage() method called by button click.

    public void SaveColoredImage()
    {
    string path = GetPathForShareSave();
    string picName = myColorizer.myColoredPicName + ".png";
    NativeGallery.SaveImageToGallery(path, "Images", picName, ImageSavedCallBack);
    }

    private string GetPathForShareSave()
    {
    string path = "";

    if (Application.platform == RuntimePlatform.Android)
    {
    path = "jar:file://" + Application.dataPath + "!/assets/" + "shareData/" + myColorizer.myColoredPicName + "_toShare.png";
    WWW www = new WWW(path);
    string filePath = Path.Combine(Application.temporaryCachePath, "heart.png");
    File.WriteAllBytes(filePath, www.bytes);
    path = filePath;
    }
    else
    path = Application.streamingAssetsPath + "/shareData/" + myColorizer.myColoredPicName + "_toShare.png";
    return path;
    }


    Everything works fine, but it freezes, when app launched for the firs time.
     
  49. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    873
    Are there any error messages in logcat? Also, I noticed that you are not using
    yield return www;
    to wait for WWW to finish. Maybe it is affecting the application somehow?
     
  50. kd_unity

    kd_unity

    Joined:
    Dec 19, 2018
    Posts:
    5
    Hi Yasirkula, Can i use this asset for get on the paths of images or videos in gallery without selecting on the image or the video manually.