Search Unity

Native Gallery for Android & iOS [Open Source]

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

  1. karankk

    karankk

    Joined:
    Sep 17, 2013
    Posts:
    3
    Hi yasirkula, awesome work with the asset.
    i am just facing an issue while activating proguard in android. I dont get any errors but it simply doesnt open gallary or aything. Can you help me with that?
     
  2. grit_tickers

    grit_tickers

    Joined:
    Sep 27, 2018
    Posts:
    2
    Hey

    Anyone else using "Build and Run" on Android? Testing Native Gallery using the example code I get "Access Denied" in Android Monitor. How are people enabling permissions? Should I export the build another way?
     
  3. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,875
    @Ibukii I've tried to mention it in the documentation but perhaps logging a warning is also a good idea, thanks!

    @karankk Try adding the following line to ProGuard filters:
    -keep class com.yasirkula.unity.* { *; }


    @grit_tickers Please make sure that Write Permission is set to "External (SDCard)". You can check PROJECT_PATH/Temp/StagingArea/AndroidManifest.xml after building your project to see if it contains the WRITE_EXTERNAL_STORAGE permission.
     
    gnsx likes this.
  4. grit_tickers

    grit_tickers

    Joined:
    Sep 27, 2018
    Posts:
    2
    Thank you @yasirkula problem has been resolved!

    For the other newbs that were not having any response to the example code on Android go to:

    Player Settings > Other Settings > Configuration > Write Permission > External (SDCard)

    Now when the app starts it will ask for permission to access media.
     
  5. amybuc95

    amybuc95

    Joined:
    Nov 18, 2015
    Posts:
    7
    Hi! I've been able to successfully get a video recording in the app I'm working on, and it saves to the persistent data path, meaning I can locate it and play it with a file browser app, but I've been unable to get the video appearing in my phone's gallery.

    Here's what I've got, with 'videoPathArray' being the file name of the video as a string:

    Debug.Log("Permission result: " + NativeGallery.SaveVideoToGallery(System.IO.Path.Combine(Application.persistentDataPath, videoPathArray), "videofolder", "video.mp4"));


    When I debug
    System.IO.Path.Combine(Application.persistentDataPath, videoPathArray)
    , i seem to get the correct file path and name, so I'm not too sure what's happening.

    I've tried a couple of different things, but I've had no luck at all, so just thought I'd post and see if there's something I'm doing glaringly wrong.

    Thanks!
     
  6. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,875
    Did you set Write Permission to External (SDCard)? Also, before calling SaveVideoToGallery, please check if
    File.Exists(System.IO.Path.Combine(Application.persistentDataPath, videoPathArray))
    returns true. If so, please also check logcat for any error messages.
     
  7. amybuc95

    amybuc95

    Joined:
    Nov 18, 2015
    Posts:
    7
    Thanks for your reply! I've double checked that the Write Permission was set to External, and it was. I also ran a check to see whether the file exists before attempting to save it to the gallery, and it's returning true, so the file is definitely there.

    As for logcat, nothing obvious is being returned as far as I can see - the one thing is when Saving to the gallery is fired, the ActivityManager logs a REQUEST_PERMISSIONS Action, and then later returning Permissions result as false. Aside from that, there is a notable pause in the app, logged by logcat, when the Save to gallery button is pressed. In terms of permissions, the manifest includes both writing and reading external storage - might I be missing something in my manifest that I'd need to save to the gallery, if it's an issue with permissions?
     
  8. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,875
    What does SaveVideoToGallery function return? Is it Granted or Denied? If it is Denied, try reinstalling the app (by first uninstalling it) and see if the issue persists.
     
  9. BaseOfCoding

    BaseOfCoding

    Joined:
    Jul 27, 2018
    Posts:
    11
    I have a question and I'll ask you a question.
    The samples in the current github classify images and videos, right?
    Is there a way to display only the folders you want and see the images and videos in that folder all at once?
     
  10. twgamesstudio

    twgamesstudio

    Joined:
    Oct 12, 2018
    Posts:
    1
    Thank you for such a great asset. It works like a charm.
    I have a question though,
    Is there a way to save the image on the device (both ios and android) but a location not accessible to user directly
    and then how to load from that location but not prompting user about the selection of image but rather accessing it directly from the code ?
     
  11. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,875
    @Lee-Jung-Min Unfortunately not :( You may have to fetch the images/videos in those directories manually and display them in a custom UI.

    @twgamesstudio You can simply save/load your image to/from the Application.persistentDataPath directory, it satisfies all your requirements.
     
  12. pertz

    pertz

    Joined:
    Jan 8, 2015
    Posts:
    106
    Hi!

    If I use your plugin to only read photos from the gallery, what kind of permission do I need?

    I was asking previously for WRITE permission for other reasons (other features of my game), and now I want to remove this permission, but dont know if it will cause any problems with your plugin. I only read photos using your plugin, I never save/write. So do I need READ_EXTERNAL_STORAGE or something?

    EDIT: also, I am currently calling "NativeGallery.CheckPermission()". What permission does it check? WRITE or READ? Given that I dont write to the gallery, what should I call to check if I have the correct permission (if WRITE is not needed I dont want to check for that permission)

    Thanks!
     
    Last edited: Nov 8, 2018
  13. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,875
    An ideal solution should check for only READ_EXTERNAL_STORAGE permission in this case. However, currently NativeGallery checks both READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE permissions, so you need WRITE_EXTERNAL_STORAGE (which implicitly grants READ_EXTERNAL_STORAGE, as well) permission.
     
  14. pertz

    pertz

    Joined:
    Jan 8, 2015
    Posts:
    106
    Thanks for the reply.

    In the meantime I tested with a device and indeed it gave me problems, my code went into infinite loop: your plugin would say the permission (write) is needed, and my code would check and see the permission (read) is already given and it would go on forever...

    Is there any chance you will update the plugin to add a read only parameter for the CheckPermission method? Or maybe rename the method to CheckWritePermission and create a CheckReadPermission that gets called on the GetMediaFromGallery flow?

    I tried to make a quick hack (removed the permission checks on your unity plugin code, and am handling myself the read permission with another plugin), but it didnt work as the internal JAR/Java code also checks for the permission again.
     
  15. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,875
    Yes, I plan to add some way to check for read permission only. Sorry for the inconvenience.
     
  16. pertz

    pertz

    Joined:
    Jan 8, 2015
    Posts:
    106
    Awesome, that's great news, thanks a lot!! :)
     
  17. Tieco

    Tieco

    Joined:
    Feb 2, 2018
    Posts:
    4
    Hi!
    I'm having a problem with GetImageFromGallery method, here is my code :

    Code (CSharp):
    1. public void LoadPictureFromGallery()
    2.     {
    3.         NativeGallery.GetImageFromGallery(path =>
    4.         {
    5.             txtLog.text = path; // <-- this variable is always empty
    6.             if (!string.IsNullOrEmpty(path))
    7.             {
    8.                 // do something
    9.             }
    10.         }, maxSize : 1024);
    11.     }
    The "path" variable is always empty...
    Permission returned is always "GRANTED".

    Am i doing something wrong? It seems pretty standard code, I've almost copied it from one of your answers.
    I've just imported the plugin and tried this code, do I need to set something else first?
    Thank you
     
  18. Berno

    Berno

    Joined:
    Oct 29, 2014
    Posts:
    40
    Hey,
    Thanks a lot for this asset!

    Its running fine for me on Android however I'm having a problem on iOS.
    When selecting the image it cancels out with the following errors:


    2018-11-11 09:11:00.667039+1100 DashPanel[429:17357] [Assert] Bounding path likely out of sync with its coordinate space: The view's bounds must contain the bounding rect. Bounding rect: {{-6.3582596653808251e-15, 0}, {320.00000000000006, 568}}; coordinate space: <_UISizeTrackingView: 0x141abe4c0; frame = (0 0; 320 568); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x2839b3200>>
    2018-11-11 09:11:00.821185+1100 DashPanel[429:17357] [Assert] Bounding path likely out of sync with its coordinate space: The view's bounds must contain the bounding rect. Bounding rect: {{-6.3582596653808251e-15, 0}, {320.00000000000006, 568}}; coordinate space: <_UISizeTrackingView: 0x141abe4c0; frame = (0 0; 320 568); clipsToBounds = YES; autoresize = W+H; layer = <CALayer: 0x2839b3200>>
    2018-11-11 09:11:00.862605+1100 DashPanel[429:17640] [discovery] errors encountered while discovering extensions: Error Domain=PlugInKit Code=13 "query cancelled" UserInfo={NSLocalizedDescription=query cancelled}


    These are my first days building for iOS so I'm pretty lost.
    I found this question:
    https://stackoverflow.com/questions...iscovery-error-error-domain-pluginkit-code-13

    The main suggestion was the swift version so I went from xcode 10 back to 8.3.3 but the problem still occurs.
    Strangely there is one animated gif I can choose in my gallery without error.

    Do you have any ideas what might be going wrong?
    Thanks
     
  19. Dip98

    Dip98

    Joined:
    Nov 7, 2018
    Posts:
    1
    Hi! First of all, thank you for the fantastic plugin.
    I'm trying to assign to an empty Cube the texture of an image from the gallery, so i wrote this and it works perfecty:

    Code (CSharp):
    1.  
    2. using System.Collections;
    3. using System.Collections.Generic;
    4. using UnityEngine;
    5. using System.IO;
    6. using UnityEditor;
    7. using System.Text;
    8.  
    9.  
    10. public class Prova : MonoBehaviour
    11. {
    12.  
    13.     public GameObject empty;
    14.     public Renderer rend;
    15.     public Texture2D texture;
    16.  
    17.  
    18.     public void Start()
    19.     {
    20.         empty = GameObject.Find("Vuoto");
    21.         rend = empty.GetComponent<MeshRenderer>();
    22.        
    23.        
    24.  
    25.     }
    26.  
    27.  
    28.     public void PickImageFromGallery(int maxSize = 1024)
    29.     {
    30.         NativeGallery.Permission permission = NativeGallery.GetImageFromGallery((path) =>
    31.         {
    32.             Debug.Log("Image path: " + path);
    33.  
    34.             if (path != null)
    35.             {
    36.                
    37.        
    38.                 texture = NativeGallery.LoadImageAtPath(path, 2048);
    39.                 if (texture == null)
    40.                 {
    41.                     Debug.Log("Couldn't load texture from " + path);
    42.                     return;
    43.                 }
    44.  
    45.                 rend.material.mainTexture = texture;
    46.              
    47.                
    48.             }
    49.  
    50.            
    51.         });
    52.      
    53.        
    54.     }
    55.  
    56. }
    Now i want to save this texture permanent, can you help me?
     
  20. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,875
    @Tieco Your code looks correct, yes. Given the fact that the returned permission is Granted, I can't really think of any reasons for this behaviour. Are there any error messages in Logcat, perhaps?

    @Berno I don't think that these logs are related to NativeGallery. Does the example code on the GitHub repository also not work? What is the value of the returned Permission?

    @lucadipalma98 You can copy the image at 'path' to Application.persistentDataPath, save the copied image's path to PlayerPrefs and load the image from that path the next time the game is launched.
     
  21. Tieco

    Tieco

    Joined:
    Feb 2, 2018
    Posts:
    4
    @yasirkula Solved. Added WRITE_EXTERNAL_STORAGE permission directly in the manifest and now works correctly. I have no idea why the permission returned was "Granted" before. Anyway thanks for this amazing plugin!
     
    yasirkula likes this.
  22. DaniyarGilymov

    DaniyarGilymov

    Joined:
    Dec 26, 2017
    Posts:
    14
    @Tieco could you help me, i'm having the same problem, where should i write WRITE_EXTERNAL_STORAGE?
     
  23. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,875
    @DaniyarGilymov In most cases, setting Write Permission to External (SDCard) in Player Settings should resolve the issue. You can verify that the WRITE_EXTERNAL_STORAGE permission is added to the final AndroidManifest by checking the contents of PROJECT_PATH/Temp/StagingArea/AndroidManifest.xml after building your project to Android.
     
  24. Berno

    Berno

    Joined:
    Oct 29, 2014
    Posts:
    40
    Sorry for the confusion yasirkula its been my first few days ever using Macs and its been pretty overwhelming jumping in at the deep end!

    You were correct those logs were unrelated.
    I wasn't seeing the behaviour I expected because I didn't realise that on iOS GetImageFromGallery would always return the filename tmp.png.
    My app features the ability to import images however I copy selected images into an Import folder for ease of use when users share created content with each other.
    So no matter what I selected it kept copying over tmp.png in the Import folder.

    I managed, after learning that swift and objective c are two different things, to get enough info off stackoverflow to change your code so that the original filename is preserved.

    NativeGallery.cs
    Code (CSharp):
    1. //m_iOSSelectedImagePath = Path.Combine( Application.temporaryCachePath, "tmp.png" );
    2.                 m_iOSSelectedImagePath = Application.temporaryCachePath;
    3.                 Directory.CreateDirectory( Application.temporaryCachePath );
    NativeGallery.mm
    Code (CSharp):
    1. + (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    2.     NSString *path;
    3.     if ([info[UIImagePickerControllerMediaType] isEqualToString:(NSString *)kUTTypeImage]) { // image picked
    4.         // Temporarily save image as PNG
    5.         UIImage *image = info[UIImagePickerControllerOriginalImage];
    6.         if (image == nil)
    7.             path = nil;
    8.         else {
    9.             //[UIImagePNGRepresentation([self scaleImage:image maxSize:pickMediaMaxSize]) writeToFile:pickedMediaSavePath atomically:YES];
    10.             //path = pickedMediaSavePath;
    11.  
    12.             //get filename
    13.             NSURL *imageURL = [info valueForKey:UIImagePickerControllerReferenceURL];
    14.             PHAsset *phAsset = [[PHAsset fetchAssetsWithALAssetURLs:@[imageURL] options:nil] lastObject];
    15.             NSString *imageName = [phAsset valueForKey:@"filename"];
    16.  
    17.             //concat
    18.             //NSString *str = [NSString stringWithFormat: @"%@ %@", path, imageName];
    19.             NSLog(@"Picked image: %@",imageName);
    20.  
    21.             //create path based of actual name
    22.             path = [[[pickedMediaSavePath stringByAppendingString:@"/"] stringByAppendingString:imageName] stringByAppendingString:@".PNG"];
    23.             path = [path stringByStandardizingPath];
    24.             NSLog(@"Full path: %@",path);
    25.  
    26.             [UIImagePNGRepresentation([self scaleImage:image maxSize:pickMediaMaxSize]) writeToFile:path atomically:YES];
    27.         }
    28.     }
    29.     else { // video picked
    30.         NSURL *mediaUrl = info[UIImagePickerControllerMediaURL] ?: info[UIImagePickerControllerReferenceURL];
    31.         if (mediaUrl == nil)
    32.             path = nil;
    33.         else
    34.             path = [mediaUrl path];
    35.     }
    36.  
    37.     popup = nil;
    38.     imagePicker = nil;
    39.     imagePickerState = 2;
    40.     UnitySendMessage("NGMediaReceiveCallbackiOS", "OnMediaReceived", [self getCString:path]);
    41.  
    42.     [picker dismissViewControllerAnimated:NO completion:nil];
    43. }
    This has solved my problem and each selected file gets copied to the import folder with a unique name.
    The only doubt I have is that I couldn't understand where in the obective c code you deleted the temporary file from the cache folder?
    Have I broken this with my update or will the cache files be cleared by some process I don't know about?

    Thanks again and if any of the above code is usable to you please add it to the project.
     
  25. ericalan

    ericalan

    Joined:
    Jun 10, 2016
    Posts:
    17
    hey, so, i am trying to get this working, and i am able to select an image from the device, returns the path fine, but it seems like when coming out of the native gallery selection one of my scenes is changing sort order, is there any reason why this might happen from the plugin?

    so, there's multiple scenes loaded, eg...
    1. first
    2. second
    3. third

    from the third scene i call the plugin, perform some logic on the resulting file etc, but now the scene order is:
    1. first
    2. third
    3. second

    and like, even if i create a 4th scene and use the 4th one to load the gallery selection it still brings "second" to the top of the sort order. i cant imagine why the plugin would be causing this behavior but i've run out of workarounds to try so going to probably have to abandon using it if i can't figure out why this is happening.
     
  26. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,875
    @Berno Thanks for sharing your code! In the original code, the file tmp.png is never deleted by NativeGallery, so it stays in the temporaryCachePath until the OS decides to automatically clear some applications' caches to free up some space, or until it is overwritten by another tmp.png.

    The thing with your code is that, some of the functions are deprecated or are not available before iOS 8.0 (e.g. UIImagePickerControllerReferenceURL, fetchAssetsWithALAssetURLs). So, I don't plan to change the original code just yet.

    @lulzbane That's the first time I'm hearing about such an issue. I honestly have no clue why it would happen, sorry :/
     
  27. ahching

    ahching

    Joined:
    Nov 11, 2016
    Posts:
    4
    Hi Yasirkula,
    Thanks for your great plugin.
    I have experienced the same issue, the app freeze for > 3 seconds after calling NativeGallery.GetImageFromGallery,
    Test on Samsung Note 8, Android 8.0.
    Any suggestion ?

    Thanks
     
  28. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,875
    Hi, I still don't have a workaround for this issue or know whether or not this delay can be avoided at all.
     
  29. fschaar

    fschaar

    Joined:
    Jul 3, 2012
    Posts:
    14
    Hi @yasirkula

    Is your plugin able to read Audio files from Android MediaStore?
    To me it seems like this is a similar funktion like reading images from gallery, but I haven't found a plugin yet, that accesses the Audio Listing of Android.
     
  30. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,875
  31. jackiechieng1

    jackiechieng1

    Joined:
    Oct 13, 2018
    Posts:
    3
    Hey @yasirkula,

    I've started using your plugin to let users upload their image. I'm having difficulties saving the image. How should I go about it? I wanted to take the image and reuse immediately after it gets uploaded to update the albedo of another object.
     
  32. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,875
    Simply calling NativeGallery.SaveImageToGallery will save (upload?) the image to the Gallery. You can use that image as albedo in the following line in your code.
     
  33. jackiechieng1

    jackiechieng1

    Joined:
    Oct 13, 2018
    Posts:
    3
    Thank you for replying!

    My bad, to clarify, I meant that I used NativeGallery.LoadImageAtPath after getting the image to store the image in a texture2d object as seen with your example on your git page. The issue that I'm having is that I'm not sure if it creates an image or not. And if it does, does setting that texture2d object as the albedo of another object work? I can't really tell since I'm new to unity. I've been testing by building and running it on my phone.
     
  34. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,875
    LoadImageAtPath does create a Texture2D from the image file (or returns null, if it fails). Did it not work for you? Does the example code on the Git repository work as is for you?
     
  35. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,875
    @pertz I've updated the GitHub repository. Now, fetching media from the Gallery requires only the READ_EXTERNAL_STORAGE permission.
     
  36. jackiechieng1

    jackiechieng1

    Joined:
    Oct 13, 2018
    Posts:
    3
    The example code works perfectly, and it does create a Texture2D with the image. I managed to find my mistake, and it turns out to be a mistake with referencing the renderer, so I was not able to update the albedo. Sorry for troubling you, I just wanted to check if I was using your plugin correctly.
     
    yasirkula likes this.
  37. epiccomm

    epiccomm

    Joined:
    Mar 5, 2018
    Posts:
    1
    it cannot save images on ios properly.
    The save images are black only.

    part of code i used:
    Texture2D ss = ScreenCapture.CaptureScreenshotAsTexture();
    NativeGallery.SaveImageToGallery (ss,"xxx","xxx_{0}.png");

    xcode log :
    UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
    (Filename: /Users/builduser/buildslave/unity/build/Runtime/Export/Debug.bindings.h Line: 43)
    Saving to Pictures: xxx_1.png
    NativeGallery:SaveToGallery(Byte[], String, String, Boolean, MediaSaveCallback)
    c__Iterator0:MoveNext()
    UnityEngine.SetupCoroutine:InvokeMoveNext(IEnumerator, IntPtr)
    (Filename: /Users/builduser/buildslave/unity/build/Runtime/Export/Debug.bindings.h Line: 43)
    2018-12-01 17:07:27.443415+0800 xxxxxx[2268:957267] [Common] _BSMachError: port 12e03; (os/kern) invalid capability (0x14) "Unable to insert COPY_SEND"
    2018-12-01 17:07:27.447260+0800 xxxxxx[2268:957267] [Common] _BSMachError: port 12e03; (os/kern) invalid capability (0x14) "Unable to insert COPY_SEND"
    -> applicationWillResignActive()
    (Filename: /Users/builduser/buildslave/unity/build/Runtime/Export/Debug.bindings.h Line: 43)
    (Filename: /Users/builduser/buildslave/unity/build/Runtime/Export/Debug.bindings.h Line: 43)
     
  38. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,875
  39. avinash213

    avinash213

    Joined:
    Dec 4, 2018
    Posts:
    5
    @yasirkula thanks for the plugin. I have a question might be already answered i dont know.
    How to create a folder to my customised path in SD Card using your plugin? Because we should not hard code like
    Code (CSharp):
    1. public static string screenShotPath = "/storage/emulated/0/NewFolder/";
    So i want to create a folder to my internal storage in case of android. Can you please help.

    Thanks in advance.
     
  40. bromelee

    bromelee

    Joined:
    Sep 14, 2017
    Posts:
    1
    Hello, first thank for this incredible asset, i been working in a project and this is so usefull, but i have a problem, it seems to be with android permisions and i dont know what to do right nox xd.

    I use the NativeGallery.SaveImageToGallery

    when i run the code in the phone it crash. With the adb monitor i could get the error.
    https://i.gyazo.com/66beff095e17e07b4baaae5b9fc49426.png

    And i check the apk generated with android studio and it has the write and read permission in the manifest.xml

    before use this asset, i save the image with the writeallbytes, it saves the images correctly but dont appear in the android gallery, so i use this code too

    AndroidJavaClass classPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
    AndroidJavaObject objActivity = classPlayer.GetStatic<AndroidJavaObject>("currentActivity");
    AndroidJavaClass classUri = new AndroidJavaClass("android.net.Uri");
    AndroidJavaObject objIntent = new AndroidJavaObject("android.content.Intent", new object[2] { "android.intent.action.MEDIA_SCANNER_SCAN_FILE", classUri.CallStatic<AndroidJavaObject>("parse", "file://" + myFolderLocation + "/photo" + PNum + ".png") });

    objActivity.Call("sendBroadcast", myFolderLocation + "/photo" + PNum + ".png");

    and get a similar error
    https://i.gyazo.com/d0d349d3d159150a09e079e08d01e7f2.png

    so to be honest now i dont know what to do xd, dont know if using wrong the asset or something with the android.

    Thank for read and hope you can help me with this problem X3
     
  41. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,875
    @avinashjuego There is no official way to achieve that in NativeGallery but you may try making NativeGallery.GetSavePath public and then using the following code:

    Code (CSharp):
    1. DirectoryInfo newFolder = new FileInfo(NativeGallery.GetSavePath("tmp","tmp")).Directory.Parent.Parent.CreateSubdirectory("NewFolder");
    @bromelee UnauthorizedAccessException is an annoying one because so far, it has been hard to debug. Please check out these issues to see if there is a solution for your case: https://github.com/yasirkula/UnityNativeGallery/issues?utf8=✓&q=is:issue+UnauthorizedAccessException
     
  42. thiagoberardinelli

    thiagoberardinelli

    Joined:
    Dec 3, 2018
    Posts:
    2
    Hi, first I want to say that your asset is awesome and it's helping me a lot!

    Yesterday i was trying to mesh your Native Camera Asset with the Native Gallery one, to save a camera picture into a specific path in the Android gallery but i'm not being succesfull. In the TakePicture() it should open the camera, set the picture taken as the reference image.texture and then save it on the specified path. The first two parts are ok but it`s not saving the picture anywhere... here is my code.
    Code (CSharp):
    1. public void TakePicture (int maxSize)
    2.     {
    3.         NativeCamera.Permission permission = NativeCamera.TakePicture((path) =>
    4.         {
    5.             Debug.Log("Image path: " + path);
    6.             if (path != null)
    7.             {
    8.                 // Create a Texture2D from the captured image
    9.                 Texture2D texture = NativeCamera.LoadImageAtPath(path, maxSize);
    10.                 if (texture == null)
    11.                 {
    12.                     Debug.Log("Couldn't load texture from " + path);
    13.                     return;
    14.                 }
    15.                 // Change the reference image texture to the camera picture
    16.                 image.texture = texture;
    17.  
    18.                 // Save that texture into a specific path in the gallery.
    19.                 NativeGallery.SaveImageToGallery(texture, "GalleryTest", "Image.png");
    20.              
    21.             }
    22.         }, maxSize);
     
  43. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,875
    Did you set Write Permission to "External (SDCard)" in Player Settings? After you build your project to Android, does the WRITE_EXTERNAL_STORAGE permission exist in PROJECT_PATH/Temp/StagingArea/AndroidManifest.xml? If you use NativeGallery.SaveImageToGallery outside of NativaCamera.TakePicture function with a sample texture for testing purposes, does it work? Are there any error messages in logcat?
     
  44. dart_ajax

    dart_ajax

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

    Echo everybody else here with the thanks for the awesome app! Thank you so much for providing it.

    Seems like a few other folks have been having the problem I'm having with the pause and screen flash after selecting pictures. My case seems a little more severe since the app gets stuck and doesn't return at all. Also a newer Samsung phone. I thought I'd include a few ADB logs to see if you could give me a clue as to how to resolve the issue.

    First, the problem seems related to these steps completing in the ADB:

    12-06 08:28:46.084 12509 12509 W Unity : Timeout while trying to pause the Unity Engine.
    12-06 08:28:50.102 12509 12509 W Unity : Timeout while trying detaching primary window.

    If I watch the ADB and allow these two steps to complete. Then the program returns and works correctly. If I select a picture or video quickly though, in the 3 seconds between these steps. Then the app will get stuck and I get the log below:

    12-06 08:28:42.650 1401 1942 I ActivityManager: Start proc 12784:com.android.documentsui/u0a17 for activity com.android.documentsui/.picker.PickActivity
    12-06 08:28:42.669 1401 1942 I ActivityManager: DSS on for com.android.documentsui and scale is 1.0
    12-06 08:28:42.812 1401 1942 D ActivityManager: post active user change for 0 fullscreen true isHomeActivity() false
    12-06 08:28:42.929 1401 1522 I ActivityManager: Displayed com.android.documentsui/.picker.PickActivity: +286ms (total +341ms)
    12-06 08:28:43.562 1401 15893 D ActivityManager: isScaleDownAnimationEnabled() : true
    12-06 08:28:46.084 12509 12509 W Unity : Timeout while trying to pause the Unity Engine.
    12-06 08:28:50.102 12509 12509 W Unity : Timeout while trying detaching primary window.
    12-06 08:28:50.118 12509 12509 D Unity : Selected media uri: content://com.android.providers.media.documents/document/image%3A53075
    12-06 08:28:50.145 12509 12525 I Unity : Image path: System.String[]
    12-06 08:28:50.145 12509 12525 I Unity :
    12-06 08:28:50.145 12509 12525 I Unity : (Filename: ./Runtime/Export/Debug.bindings.h Line: 43)
    12-06 08:28:50.145 12509 12525 I Unity :
    12-06 08:28:50.148 1401 2108 D ActivityManager: post active user change for 0 fullscreen true isHomeActivity() false
    12-06 08:28:50.178 1401 2108 I ActivityManager: Activity reported stop, but no longer stopping: ActivityRecord{bd9dbf6 u0 com.PictureViewer/com.setik.kampertee.AndroidUtils t9706}
    12-06 08:28:50.434 12509 12525 I Unity : Permission result: Granted
    12-06 08:28:50.434 12509 12525 I Unity :
    12-06 08:28:50.434 12509 12525 I Unity : (Filename: ./Runtime/Export/Debug.bindings.h Line: 43)
    12-06 08:28:50.434 12509 12525 I Unity :
    12-06 08:29:18.041 1401 3375 I ActivityManager: KPU : put [com.qualcomm.embms:remote] : 4881 K
    12-06 08:29:18.042 1401 3375 I ActivityManager: Killing 9784:com.qualcomm.embms:remote/u0a183 (adj 906): DHA:SPC_empty #25
    12-06 08:29:18.096 1401 3375 W ActivityManager: Scheduling restart of crashed service com.qualcomm.embms/.EmbmsService in 0ms
    12-06 08:29:18.113 1401 1484 D ActivityManager: package com.qualcomm.embms, user - 0 is SDcard whitelisted
    12-06 08:29:18.144 1401 1484 I ActivityManager: Start proc 12819:com.qualcomm.embms:remote/u0a183 for service com.qual

    Same failure selecting a single video:

    12-06 08:22:52.794 1401 1484 D ActivityManager: package com.qualcomm.atfwd, user - 0 is SDcard whitelisted
    12-06 08:22:52.805 1401 1484 I ActivityManager: Start proc 12317:com.qualcomm.telephony/1000 for service com.qualcomm.atfwd/.AtFwdService
    12-06 08:22:52.826 1401 11975 I ActivityManager: DSS on for com.qualcomm.atfwd and scale is 1.0
    12-06 08:22:54.061 1401 11975 D ActivityManager: isScaleDownAnimationEnabled() : true
    12-06 08:22:55.433 11813 11813 W Unity : Timeout while trying to pause the Unity Engine.
    12-06 08:22:59.450 11813 11813 W Unity : Timeout while trying detaching primary window.
    12-06 08:22:59.470 11813 11813 D Unity : Selected media uri: content://media/external/video/media/51798
    12-06 08:22:59.489 11813 11828 I Unity : Video path: /storage/emulated/0/DCIM/Camera/20180906_181920.mp4
    12-06 08:22:59.489 11813 11828 I Unity :
    12-06 08:22:59.489 11813 11828 I Unity : (Filename: ./Runtime/Export/Debug.bindings.h Line: 43)
    12-06 08:22:59.489 11813 11828 I Unity :
    12-06 08:22:59.501 1401 3043 D ActivityManager: post active user change for 0 fullscreen true isHomeActivity() false
    12-06 08:22:59.527 1401 2081 I ActivityManager: Activity reported stop, but no longer stopping: ActivityRecord{1ada40f u0 com.PictureViewer/com.setik.kampertee.AndroidUtils t9705}
    12-06 08:23:14.475 1401 1401 I ActivityManager: KPU : put [com.samsung.android.rubin.app] : 16339 K
    12-06 08:23:14.475 1401 1401 I ActivityManager: Killing 8769:com.samsung.android.rubin.app/5010 (adj 906): DHA:empty #25
    12-06 08:23:14.478 1401 1401 I ActivityManager: KPU : put [com.sec.android.provider.badge] : 5125 K
    12-06 08:23:14.478 1401 1401 I ActivityManager: Killing 10225:com.sec.android.provider.badge/u0a4 (adj 906): DHA:empty #25
    12-06 08:23:21.766 1401 3043 I ActivityManager: KPU : put [com.samsung.android.incallui] : 57805 K
    12-06 08:23:21.767 1401 3043 I ActivityManager: Killing 8074:com.samsung.android.incallui/1001 (adj 906): DHA:empty #25
    12-06 08:23:21.884 1401 1522 W ActivityManager: setHasOverlayUi called on unknown pid: 8074
    12-06 08:23:35.131 1401 3032 I ActivityManager: KPU : put [com.samsung.android.mateagent:service] : 9948 K
    12-06 08:23:35.132 1401 3032 I ActivityManager: Killing 11514:com.samsung.android.mateagent:service/u0a46 (adj 906): DHA:empty #25


    If I select a picture after the two timeout steps complete though. The app returns as expected and I see the log below:

    11-21 11:09:47.590 11333 11333 W Unity : Timeout while trying to pause the Unity Engine.
    11-21 11:09:51.515 1390 2599 D ActivityManager: isScaleDownAnimationEnabled() : true
    11-21 11:09:51.600 11333 11333 W Unity : Timeout while trying detaching primary window.
    11-21 11:09:51.613 11333 11333 D Unity : Selected media uri: content://com.android.providers.downloads.documents/document/raw%3A%2Fstorage%2Femulated%2F0%2FDownload%2FaB03NoO460swp.webp
    11-21 11:09:51.628 1390 3091 D ActivityManager: post active user change for 0 fullscreen true isHomeActivity() false
    11-21 11:09:51.629 1390 2599 I ActivityManager: Activity reported stop, but no longer stopping: ActivityRecord{881a426 u0 com.PictureViewer/com.setik.kampertee.AndroidUtils t9022}
    11-21 11:09:51.629 11333 11349 I Unity : Image path: System.String[]
    11-21 11:09:51.629 11333 11349 I Unity :
    11-21 11:09:51.629 11333 11349 I Unity : (Filename: ./Runtime/Export/Debug.bindings.h Line: 43)
    11-21 11:09:51.629 11333 11349 I Unity :
    11-21 11:09:51.760 11333 11349 I Unity : Permission result: Granted
    11-21 11:09:51.760 11333 11349 I Unity :
    11-21 11:09:51.760 11333 11349 I Unity : (Filename: ./Runtime/Export/Debug.bindings.h Line: 43)
    11-21 11:09:51.760 11333 11349 I Unity :
    11-21 11:09:55.360 11333 11349 E Unity : Unable to find arcore_instant_preview_unity_plugin
    11-21 11:09:55.968 11333 11398 E Unity : OPENGL NATIVE PLUG-IN ERROR: GL_INVALID_ENUM: enum argument out of range
    11-21 11:09:55.968 11333 11398 E Unity :
    11-21 11:09:55.968 11333 11398 E Unity : (Filename: /Users/builduser/buildslave/unity/build/Runtime/GfxDevice/opengles/GfxDeviceGLES.cpp Line: 338)
    11-21 11:09:55.968 11333 11398 E Unity :
    11-21 11:09:56.193 1390 3091 I ActivityManager: START u0 {act=null typ=null flg=0x0 cmp=ComponentInfo{com.android.systemui/com.android.systemui.media.MediaProjectionPermissionActivity}} from uid 10287
    11-21 11:09:56.677 1390 3089 D ActivityManager: isScaleDownAnimationEnabled() : true
    11-21 11:09:56.701 1390 3089 D ActivityManager: isScaleDownAnimationEnabled() : true
    11-21 11:09:56.733 1390 1519 I ActivityManager: Override config changes=205df8 {0 0.0 themeSeq = 0 showBtnBg = 0 ?mcc?mnc ?localeList ?layoutDir sw116dp w240dp h116dp 480dpi smll land ?uimode ?night finger -keyb/v/h -nav/h appBounds=Rect(0, 0 - 720, 350) mkbd/h desktop/d ?dc} for displayId=46
    11-21 11:09:57.214 1390 10661 D ActivityManager: post active user change for 0 fullscreen true isHomeActivity() false
    11-21 11:10:03.020 1390 2255 D ActivityManager: setLockScreenShown(true) is called from 1907
    11-21 11:10:03.063 1390 1519 I ActivityManager: Config changes=480 {0 1.0 themeSeq = 0 showBtnBg = 0 310mcc260mnc [en_US] ldltr sw360dp w360dp h668dp 480dpi nrml long hdr port finger -keyb/v/h -nav/h appBounds=Rect(0, 0 - 1080, 2076) s.207 mkbd/h desktop/d ?dc}
    11-21 11:10:03.073 1390 1519 I ActivityManager: Override config changes=480 {0 1.0 themeSeq = 0 showBtnBg = 0 310mcc260mnc [en_US] ldltr sw360dp w360dp h668dp 480dpi nrml long hdr port finger -keyb/v/h -nav/h appBounds=Rect(0, 0 - 1080, 2076) s.207 mkbd/h desktop/d ?dc} for displayId=0
     
  45. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,875
    By getting stuck, do you mean indefinitely or only for a few seconds? If it is the latter, unfortunately I don't have a workaround for this yet :/
     
  46. dart_ajax

    dart_ajax

    Joined:
    Jan 17, 2018
    Posts:
    4
    If I start the app for the first time and select pictures then it only gets stuck for a few seconds. If I navigate to a different scene, then use the scene manager to restart the application and select pictures again, then it will get completely stuck and the app will freeze and can only be killed.

    Again, the pause and the freeze can be avoided if I wait for those two timeout lines to complete. I'm wondering if this has something to do with the threadlock in the NGMediaReceiveCallbackAndroid?

    lock( threadLock )

    {
    Monitor.Pulse( threadLock );
    }

    I've tried various options to try to add a pause when the user clicks the button to open the NativeGallery (thread.sleep or a wait seconds coroutine), but since it seems to happen after they've selected the pictures but before it returns to my application I haven't had any success.

    I'm not opposed to a solution like a pause in the NativeGallery while waiting for those two timeouts to complete. I just don't want my app to freeze completely and force the user to restart.

    Thanks again for the quick response. Let me know if there's any debugging stuff I can try to get you more information.
     
  47. thiagoberardinelli

    thiagoberardinelli

    Joined:
    Dec 3, 2018
    Posts:
    2
    Hello again and sorry for the late reply.

    1- Yes, WRITE_EXTERNAL_STORAGE permission exists after the project is built.
    2- Even testing with a sample texture, the SaveImageToGallery method does not save anything in the selected path. But, if I copy and paste your TakeScreenShot example method, it works perfectly...

    Logcat:
    (Filename: ./Runtime/Export/Debug.bindings.h Line: 43)
    2018-12-09 17:37:22.174 28212-28231/? E/Unity: ArgumentException: Texture '' is not readable, the texture memory can not be accessed from scripts. You can make the texture readable in the Texture Import Settings.
    at NativeGallery.SaveImageToGallery (UnityEngine.Texture2D image, System.String album, System.String filenameFormatted, .MediaSaveCallback callback) [0x00000] in <filename unknown>:0
    at Controller+<TakePicture>c__AnonStorey1.<>m__0 (System.String path) [0x00000] in <filename unknown>:0
    at NativeCamera.TakePicture (.CameraCallback callback, Int32 maxSize) [0x00000] in <filename unknown>:0
    at Controller.TakePicture (Int32 maxSize) [0x00000] in <filename unknown>:0
    at UnityEngine.Events.InvokableCall`1[System.Int32].Invoke (Int32 args0) [0x00000] in <filename unknown>:0
    at UnityEngine.Events.CachedInvokableCall`1[System.Int32].Invoke (System.Object[] args) [0x00000] in <filename unknown>:0
    at UnityEngine.Events.UnityEvent.Invoke () [0x00000] in <filename unknown>:0
    at UnityEngine.UI.Button.Press () [0x00000] in <filename unkn
    2018-12-09 17:37:22.189 526-631/? E/BufferQueueProducer: [SurfaceView - com.Panelinha.CameraTest/com.unity3d.player.UnityPlayerActivity] query: BufferQueue has been abandoned
    2018-12-09 17:37:22.189 526-631/? E/BufferQueueProducer: [SurfaceView - com.Panelinha.CameraTest/com.unity3d.player.UnityPlayerActivity] dequeueBuffer: BufferQueue has been abandoned
    2018-12-09 17:37:22.235 1540-1564/? I/Timeline: Timeline: Activity_windows_visible id: ActivityRecord{8779b57 u0 com.Panelinha.CameraTest/com.unity3d.player.UnityPlayerActivity t298} time:171005018
     
    Last edited: Dec 9, 2018
  48. HuuLinhdr

    HuuLinhdr

    Joined:
    Nov 16, 2017
    Posts:
    5
    I'm using IOS, I can save image to album like "My App", and I'm using Replay kit to record video. So how i can save video to album "My App" ?
     
  49. yasirkula

    yasirkula

    Joined:
    Aug 1, 2011
    Posts:
    2,875
    @dart_ajax I'll try another method soon and keep you updated.

    @thiagoberardinelli The error message says that the Texture you are trying to save to the Gallery is not readable, i.e. NativeGallery is unable to call its EncodeToPNG/EncodeToJPG function. If the texture is generated procedurally, don't mark it as non-readable. Nevertheless, I'll try to implement a workaround for this soon.

    @HuuLinhdr You need to know the path of the video generated by ReplayKit. Then, you can call the corresponding NativeGallery.SaveVideoToGallery function.
     
  50. pavan24bh

    pavan24bh

    Joined:
    Dec 11, 2018
    Posts:
    3
    Hello,yasirkula... Does your plugin can play videos from gallery on a quad gameobject.I can't find anywhere... Want help from you!!