IMPORTANT: If you are targeting iOS 14 or later, you need to build your app with Xcode 12 or later to avoid any permission issues.
FAQ
How can I fetch the path of the saved image or the original path of the picked image on iOS?
You can’t. On iOS, these files are stored in an internal directory that we have no access to (I don’t think there is even a way to fetch that internal path).
Can’t access the Gallery, it says “java.lang.ClassNotFoundException: com.yasirkula.unity.NativeGallery” in Logcat
If you are sure that your plugin is up-to-date, then enable Custom Proguard File option from Player Settings and add the following line to that file: -keep class com.yasirkula.unity.* { *; }
Android build fails, it says “error: attribute android:requestLegacyExternalStorage not found” in Console
android:requestLegacyExternalStorage attribute in AndroidManifest.xml fixes a rare UnauthorizedAccessException on Android 10 but requires you to update your Android SDK to at least SDK 29. If this isn’t possible for you, you should open NativeGallery.aar with WinRAR or 7-Zip and then remove the <application ... /> tag from AndroidManifest.xml.
Nothing happens when I try to access the Gallery on Android
Make sure that you’ve set the Write Permission to External (SDCard) in Player Settings.
NativeGallery functions return Permission.Denied even though I’ve set “Write Permission” to “External (SDCard)”
Declare the WRITE_EXTERNAL_STORAGE permission manually in your Plugins/Android/AndroidManifest.xml file with the tools:node="replace" attribute as follows: <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:node="replace"/> (you’ll need to add the xmlns:tools="http://schemas.android.com/tools" attribute to the <manifest ...> element)
Saving image/video doesn’t work properly
Make sure that the filename parameter of the Save function includes the file’s extension, as well
Hi, I am trying to use your asset but I have difficulties. I can’t connect the script “NativeGallery” to any Gameobject. I have the error “the script class can’t be abstract”. Could you please help me with this?
NativeGallery is a static class, so it can’t be attached to any GameObject. Instead, you should simply call its static functions from your scripts, like this:
NativeGallery.SaveImageToGallery( myTexture, "GalleryTest", "My img {0}.png" )
Hi there!
First of all, great job on the Plugin!
I am using it to make a memory game where the user can create its own theme by using its photos from the phone gallery. I am having a little bit of trouble trying to understand some things.
I want to check if the device supports multiple image picker to know if I should call the “GetImage” method or the “GetImages”
I want to get the images from the gallery and create a path to store all of them, so I can call a method like “Resources.LoadAll(“Sprites/Themes/” + path);”
The problem is that I don’t know how to treat the path returned by GetImagesFromGallery. I tried to Debug but it didn’t show me the path (I used Android Monitor Log, from Android Studio). If you could give me some advice I would be really thankful. Here is my code:
NativeGallery.Permission permission;
if (NativeGallery.CanSelectMultipleFilesFromGallery())
{
permission = NativeGallery.GetImagesFromGallery((paths) =>
{
if (paths != null)
{
Debug.Log("Path multiple Images: " + paths);
}
if (path != null)
{
Debug.Log("Path Single Image: " + path);
Texture2D texture = new Texture2D(2, 2);
texture.LoadImage(File.ReadAllBytes(path));
imageTest.texture = texture; //Raw Image. It worked for a single image
}
}, title: “Select single image”, mime: “image/*”);
}
You are using NativeGallery.CanSelectMultipleFilesFromGallery() correctly. It returns true only if the device supports multiple image picker.
The only problem with your code is that, as the callback of GetImagesFromGallery returns a string array (rather than a string), you should iterate over the paths variable:
if (paths != null)
{
foreach( string path in paths )
{
Debug.Log("Path multiple Images: " + path);
}
}
Unfortunately, Resources.LoadAll only works for files that are located inside the Resources folder of your project. So, you will have to create textures from the selected images using a code similar to the one you wrote inside GetImageFromGallery. You don’t really have to copy the selected images to a single directory for this. Simply iterate over paths variable and create a texture for each path.
Hi there, I’m using your software to save/load images on mobile devices, and I’m very happy so far, however I’m running into a problem.
The software I’m developing requires me to save the full filepath of the images I’m saving, and have run into a problem doing this on IOS builds using the NativeGallery.
//save image taken from camera
NativeGallery.SaveImageToGallery(toSave, "PassionMaps", m_currentMap + m_imageCount);
//then grab full path so we can save it elsewhere
m_fullImagePath = NativeGallery.GetSavePath("PassionMaps", m_currentMap + m_imageCount + ".png");
As you can see, I’ve made the GetSavePath a public function from within the NativeGallery.cs script, but due to the way you’re handling IOS image loading, using this method doesn’t work on my IOS builds. (It adds a “_1” to my images, causing an incorrect filepath, and removing this string still results in an incorrect directory.)
Is there a recommended way that I can get the full filepath of the image on IOS?
Plugin saves the image to a temporary location on iOS and deletes this temporary copy after the image is successfully saved to Photos. That’s because Photos app internally keeps a separate copy of its images/videos. AFAIK, the full path of images in Photos app is not accessible to developers.
Therefore, on iOS, you may have to write your image to Application.persistentDataPath or another accessible directory and save its full path instead. Then, you can call the SaveImageToGallery function that takes existingMediaPath as parameter to save the image to Photos.
So, on iOS, your code should look similar to this (assuming that toSave is a Texture2D):
Hi there!
Does anybody know if it is possible to hide the path where the images are saved so that the user can’t access the photos through the android gallery? And how to delete photos from the path only through the application?
I am working on a game in which the images are saved on a path and it is a requisite that the user may only be able to get or delete the photos on this path through the game.
I would really appreciate if somebody could point me the right direction. Thanks!
You can save your photos to Application.persistentDataPath or, preferably, a subfolder of it. These images will not be visible to Gallery/Photos. However, you will not be able to use NativeGallery to save/load these images, which means you will have to create your own UI to save/load these images.
You can use the following functions save/load/delete images:
I am finding a plugin which can pick .bmp images from Android Gallery so that I can get the pixel data from it for further usage. Does this plugin support .bmp format? Or only for jpg & png? Thanks!:)
Although haven’t tested it myself, the NativeGallery.LoadImageAtPath function should support bmp, gif, jpeg, png and webp formats. Here is an example code:
NativeGallery.GetImageFromGallery( ( path ) =>
{
Debug.Log( "Image path: " + path );
if( path != null )
{
// Create Texture from selected image
Texture2D texture = NativeGallery.LoadImageAtPath( path, 1024 ); // image will be downscaled if its width or height is larger than 1024px
if( texture == null )
{
Debug.Log( "Couldn't load texture from " + path );
return;
}
// Use 'texture' here
// ...
}
}
yasirkula, thanks for writing such a great plugin. I can really import a bmp image from android gallery and set it as the texture2D of a raw image. However, when I tried to use getpixel() functions to read pixel data from the texture, the texture turns white. And I do not understand what’s wrong…
NativeGallery.LoadImageAtPath has an optional parameter called markTextureNonReadable, which is set to true by default. Can you try loading the image with it set to false, instead: