# Unity Native Gallery Plugin
**Available on Asset Store:** https://assetstore.unity.com/packages/tools/integration/native-gallery-for-android-ios-112630
**Forum Thread:** https://forum.unity.com/threads/native-gallery-for-android-ios-open-source.519619/
**[Support the Developer ☕](https://yasirkula.itch.io/unity3d)**
This plugin helps you save your images and/or videos to device **Gallery** on Android and **Photos** on iOS. It is also possible to pick an image or video from Gallery/Photos.
## INSTALLATION
There are 5 ways to install this plugin:
- import [NativeGallery.unitypackage](https://github.com/yasirkula/UnityNativeGallery/releases) via *Assets-Import Package*
- clone/[download](https://github.com/yasirkula/UnityNativeGallery/archive/master.zip) this repository and move the *Plugins* folder to your Unity project's *Assets* folder
- import it from [Asset Store](https://assetstore.unity.com/packages/tools/integration/native-gallery-for-android-ios-112630)
- *(via Package Manager)* add the following line to *Packages/manifest.json*:
- `"com.yasirkula.nativegallery": "https://github.com/yasirkula/UnityNativeGallery.git",`
- *(via [OpenUPM](https://openupm.com))* after installing [openupm-cli](https://github.com/openupm/openupm-cli), run the following command:
- `openupm add com.yasirkula.nativegallery`
### Android Setup
Set **Write Permission** to **External (SDCard)** in **Player Settings**. You can skip this step if your app won't be saving media to the Gallery but instead just reading media from it.
### iOS Setup
**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.
There are two ways to set up the plugin on iOS:
**a. Automated Setup for iOS**
- *(optional)* change the value of **PHOTO_LIBRARY_USAGE_DESCRIPTION** and **PHOTO_LIBRARY_ADDITIONS_USAGE_DESCRIPTION** in *Plugins/NativeGallery/Editor/NGPostProcessBuild.cs*
- *(Unity 2017.4 or earlier)* if your minimum *Deployment Target* (iOS Version) is at least 8.0, set the value of **MINIMUM_TARGET_8_OR_ABOVE** to *true* in *NGPostProcessBuild.cs*
**b. Manual Setup for iOS**
- see: https://github.com/yasirkula/UnityNativeGallery/wiki/Manual-Setup-for-iOS
## 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](https://answers.unity.com/questions/982710/where-is-the-manifest-file-in-unity.html) 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
## HOW TO
### A. Saving Media To Gallery/Photos
`NativeGallery.SaveImageToGallery( byte[] mediaBytes, string album, string filename, MediaSaveCallback callback = null )`: use this function if you have the raw bytes of the image.
- On Android, your images/videos are saved at **DCIM/album/filename**. On iOS 14+, the image/video will be saved to the default Photos album (i.e. *album* parameter will be ignored). On earlier iOS versions, the image/video will be saved to the target album. Make sure that the *filename* parameter includes the file's extension, as well
- **MediaSaveCallback** takes `bool success` and `string path` parameters. If the image/video is saved successfully, *success* becomes *true*. On Android, *path* stores where the image/video was saved to (is *null* on iOS). If the raw filepath can't be determined, an abstract Storage Access Framework path will be returned (*File.Exists* returns *false* for that path)
**IMPORTANT:** NativeGallery will never overwrite existing media on the Gallery. If there is a name conflict, NativeGallery will ensure a unique filename. So don't put `{0}` in *filename* anymore (for new users, putting {0} in filename was recommended in order to ensure unique filenames in earlier versions, this is no longer necessary).
`NativeGallery.SaveImageToGallery( string existingMediaPath, string album, string filename, MediaSaveCallback callback = null )`: use this function if the image is already saved on disk. Enter the file's path to **existingMediaPath**.
`NativeGallery.SaveImageToGallery( Texture2D image, string album, string filename, MediaSaveCallback callback = null )`: use this function to easily save a **Texture2D** to Gallery/Photos. If filename ends with "*.jpeg*" or "*.jpg*", texture will be saved as JPEG; otherwise, it will be saved as PNG.
`NativeGallery.SaveVideoToGallery( byte[] mediaBytes, string album, string filename, MediaSaveCallback callback = null )`: use this function if you have the raw bytes of the video. This function works similar to its *SaveImageToGallery* equivalent.
`NativeGallery.SaveVideoToGallery( string existingMediaPath, string album, string filename, MediaSaveCallback callback = null )`: use this function if the video is already saved on disk. This function works similar to its *SaveImageToGallery* equivalent.
### B. Retrieving Media From Gallery/Photos
`NativeGallery.GetImageFromGallery( MediaPickCallback callback, string title = "", string mime = "image/*" )`: prompts the user to select an image from Gallery/Photos.
- This operation is **asynchronous**! After user selects an image or cancels the operation, the **callback** is called (on main thread). **MediaPickCallback** takes a *string* parameter which stores the path of the selected image, or *null* if nothing is selected
- **title** determines the title of the image picker dialog on Android. Has no effect on iOS
- **mime** filters the available images on Android. For example, to request a *JPEG* image from the user, mime can be set as "image/jpeg". Setting multiple mime types is not possible (in that case, you should leave mime as "image/\*"). Has no effect on iOS
`NativeGallery.GetVideoFromGallery( MediaPickCallback callback, string title = "", string mime = "video/*" )`: prompts the user to select a video from Gallery/Photos. This function works similar to its *GetImageFromGallery* equivalent.
`NativeGallery.GetAudioFromGallery( MediaPickCallback callback, string title = "", string mime = "audio/*" )`: prompts the user to select an audio file. This function works similar to its *GetImageFromGallery* equivalent. Works on Android only.
`NativeGallery.GetMixedMediaFromGallery( MediaPickCallback callback, MediaType mediaTypes, string title = "" )`: prompts the user to select an image/vi
评论0