README.txt 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. = Native Gallery for Android & iOS (v1.7.2) =
  2. Online documentation & example code available at: https://github.com/yasirkula/UnityNativeGallery
  3. E-mail: yasirkula@gmail.com
  4. 1. ABOUT
  5. This plugin helps you interact with Gallery/Photos on Android & iOS.
  6. 2. HOW TO
  7. for Android: set "Write Permission" to "External (SDCard)" in Player Settings
  8. for iOS: there are two ways to set up the plugin on iOS:
  9. a. Automated Setup for iOS
  10. - (optional) change the values of 'Photo Library Usage Description' and 'Photo Library Additions Usage Description' at 'Project Settings/yasirkula/Native Gallery'
  11. - (Unity 2017.4 or earlier) if your minimum Deployment Target (iOS Version) is at least 8.0, set the value of 'Deployment Target Is 8.0 Or Above' to true at 'Project Settings/yasirkula/Native Gallery'
  12. b. Manual Setup for iOS
  13. - set the value of 'Automated Setup' to false at 'Project Settings/yasirkula/Native Gallery'
  14. - build your project
  15. - enter a Photo Library Usage Description to Info.plist in Xcode
  16. - also enter a "Photo Library Additions Usage Description" to Info.plist in Xcode, if exists
  17. - set Info.plist's "Prevent limited photos access alert" property's value to 1 in Xcode, if exists
  18. - insert "-weak_framework PhotosUI -weak_framework Photos -framework AssetsLibrary -framework MobileCoreServices -framework ImageIO" to the "Other Linker Flags" of Unity-iPhone Target (and UnityFramework Target on Unity 2019.3 or newer) (if your Deployment Target is at least 8.0, it is sufficient to insert "-weak_framework PhotosUI -framework Photos -framework MobileCoreServices -framework ImageIO")
  19. - lastly, remove Photos.framework and PhotosUI.framework from Link Binary With Libraries of Unity-iPhone Target (and UnityFramework Target on Unity 2019.3 or newer) in Build Phases, if exists
  20. 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.
  21. 3. FAQ
  22. - How can I fetch the path of the saved image or the original path of the picked image on iOS?
  23. 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).
  24. - Android build fails, it says "error: attribute android:requestLegacyExternalStorage not found" in Console
  25. "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.
  26. - Can't access the Gallery, it says "java.lang.ClassNotFoundException: com.yasirkula.unity.NativeGallery" in Logcat
  27. 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.* { *; }
  28. - Nothing happens when I try to access the Gallery on Android
  29. Make sure that you've set the "Write Permission" to "External (SDCard)" in Player Settings.
  30. - NativeGallery functions return Permission.Denied even though I've set "Write Permission" to "External (SDCard)"
  31. Declare the WRITE_EXTERNAL_STORAGE permission manually in your Plugins/Android/AndroidManifest.xml file as follows: <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:node="replace"/>
  32. You'll need to add the following attribute to the '<manifest ...>' element: xmlns:tools="http://schemas.android.com/tools"
  33. - Saving image/video doesn't work properly
  34. Make sure that the "filename" parameter of the Save function includes the file's extension, as well
  35. 4. SCRIPTING API
  36. Please see the online documentation for a more in-depth documentation of the Scripting API: https://github.com/yasirkula/UnityNativeGallery
  37. enum NativeGallery.PermissionType { Read = 0, Write = 1 };
  38. enum NativeGallery.Permission { Denied = 0, Granted = 1, ShouldAsk = 2 };
  39. enum NativeGallery.ImageOrientation { Unknown = -1, Normal = 0, Rotate90 = 1, Rotate180 = 2, Rotate270 = 3, FlipHorizontal = 4, Transpose = 5, FlipVertical = 6, Transverse = 7 }; // EXIF orientation: http://sylvana.net/jpegcrop/exif_orientation.html (indices are reordered)
  40. enum MediaType { Image = 1, Video = 2, Audio = 4 };
  41. delegate void MediaSaveCallback( bool success, string path );
  42. delegate void NativeGallery.MediaPickCallback( string path );
  43. delegate void MediaPickMultipleCallback( string[] paths );
  44. //// Saving Media To Gallery/Photos ////
  45. // 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.
  46. // NOTE: Make sure that the filename parameter includes the file's extension, as well
  47. // 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).
  48. // 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)
  49. NativeGallery.Permission NativeGallery.SaveImageToGallery( byte[] mediaBytes, string album, string filename, MediaSaveCallback callback = null );
  50. NativeGallery.Permission NativeGallery.SaveImageToGallery( string existingMediaPath, string album, string filename, MediaSaveCallback callback = null );
  51. NativeGallery.Permission NativeGallery.SaveImageToGallery( Texture2D image, string album, string filename, MediaSaveCallback callback = null );
  52. NativeGallery.Permission NativeGallery.SaveVideoToGallery( byte[] mediaBytes, string album, string filename, MediaSaveCallback callback = null );
  53. NativeGallery.Permission NativeGallery.SaveVideoToGallery( string existingMediaPath, string album, string filename, MediaSaveCallback callback = null );
  54. //// Retrieving Media From Gallery/Photos ////
  55. // This operation is asynchronous! After user selects an image/video or cancels the operation, the callback is called (on main thread)
  56. // MediaPickCallback takes a string parameter which stores the path of the selected image/video, or null if nothing is selected
  57. // MediaPickMultipleCallback takes a string[] parameter which stores the path(s) of the selected image(s)/video(s), or null if nothing is selected
  58. // title: determines the title of the image picker dialog on Android. Has no effect on iOS
  59. // mime: filters the available images/videos 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 is). Has no effect on iOS
  60. NativeGallery.Permission NativeGallery.GetImageFromGallery( MediaPickCallback callback, string title = "", string mime = "image/*" );
  61. NativeGallery.Permission NativeGallery.GetVideoFromGallery( MediaPickCallback callback, string title = "", string mime = "video/*" );
  62. NativeGallery.Permission NativeGallery.GetImagesFromGallery( MediaPickMultipleCallback callback, string title = "", string mime = "image/*" );
  63. NativeGallery.Permission NativeGallery.GetVideosFromGallery( MediaPickMultipleCallback callback, string title = "", string mime = "video/*" );
  64. // Picking audio files is supported on Android only
  65. NativeGallery.Permission NativeGallery.GetAudioFromGallery( MediaPickCallback callback, string title = "", string mime = "audio/*" );
  66. NativeGallery.Permission NativeGallery.GetAudiosFromGallery( MediaPickMultipleCallback callback, string title = "", string mime = "audio/*" );
  67. // Allows you to pick images/videos/audios at the same time
  68. // mediaTypes: bitwise OR'ed media types to pick from (e.g. to pick an image or video, use 'MediaType.Image | MediaType.Video')
  69. NativeGallery.Permission NativeGallery.GetMixedMediaFromGallery( MediaPickCallback callback, MediaType mediaTypes, string title = "" );
  70. NativeGallery.Permission NativeGallery.GetMixedMediasFromGallery( MediaPickMultipleCallback callback, MediaType mediaTypes, string title = "" );
  71. // Returns true if selecting multiple images/videos from Gallery/Photos is possible on this device (only available on Android 18 and later and iOS 14 and later)
  72. bool NativeGallery.CanSelectMultipleFilesFromGallery();
  73. // Returns true if GetMixedMediaFromGallery/GetMixedMediasFromGallery functions are supported (available on Android 19 and later and all iOS versions)
  74. bool NativeGallery.CanSelectMultipleMediaTypesFromGallery();
  75. // Returns true if the user is currently picking media from Gallery/Photos. In that case, another GetImageFromGallery, GetVideoFromGallery or GetAudioFromGallery request will simply be ignored
  76. bool NativeGallery.IsMediaPickerBusy();
  77. //// Runtime Permissions ////
  78. // Interacting with Gallery/Photos is only possible when permission state is Permission.Granted. Most of the functions request permission internally (and return the result) but you can also check/request the permissions manually
  79. // mediaTypes: for which media type(s) we're checking the permission for. Has no effect on iOS
  80. NativeGallery.Permission NativeGallery.CheckPermission( PermissionType permissionType, MediaType mediaTypes );
  81. NativeGallery.Permission NativeGallery.RequestPermission( PermissionType permissionType, MediaType mediaTypes );
  82. // If permission state is Permission.Denied, user must grant the necessary permission (Storage on Android and Photos on iOS) manually from the Settings. These functions help you open the Settings directly from within the app
  83. void NativeGallery.OpenSettings();
  84. bool NativeGallery.CanOpenSettings();
  85. //// Utility Functions ////
  86. // Creates a Texture2D from the specified image file in correct orientation and returns it. Returns null, if something goes wrong
  87. // maxSize: determines the maximum size of the returned Texture2D in pixels. Larger textures will be down-scaled. If untouched, its value will be set to SystemInfo.maxTextureSize. It is recommended to set a proper maxSize for better performance
  88. // markTextureNonReadable: marks the generated texture as non-readable for better memory usage. If you plan to modify the texture later (e.g. GetPixels/SetPixels), set its value to false
  89. // generateMipmaps: determines whether texture should have mipmaps or not
  90. // linearColorSpace: determines whether texture should be in linear color space or sRGB color space
  91. Texture2D NativeGallery.LoadImageAtPath( string imagePath, int maxSize = -1, bool markTextureNonReadable = true, bool generateMipmaps = true, bool linearColorSpace = false );
  92. async Task<Texture2D> NativeGallery.LoadImageAtPathAsync( string imagePath, int maxSize = -1, bool markTextureNonReadable = true, bool generateMipmaps = true, bool linearColorSpace = false );
  93. // Creates a Texture2D thumbnail from a video file and returns it. Returns null, if something goes wrong
  94. // maxSize: determines the maximum size of the returned Texture2D in pixels. Larger thumbnails will be down-scaled. If untouched, its value will be set to SystemInfo.maxTextureSize. It is recommended to set a proper maxSize for better performance
  95. // captureTimeInSeconds: determines the frame of the video that the thumbnail is captured from. If untouched, OS will decide this value
  96. // markTextureNonReadable: see LoadImageAtPath
  97. // generateMipmaps: see LoadImageAtPath
  98. // linearColorSpace: see LoadImageAtPath
  99. Texture2D NativeGallery.GetVideoThumbnail( string videoPath, int maxSize = -1, double captureTimeInSeconds = -1.0, bool markTextureNonReadable = true, bool generateMipmaps = true, bool linearColorSpace = false );
  100. async Task<Texture2D> NativeGallery.GetVideoThumbnailAsync( string videoPath, int maxSize = -1, double captureTimeInSeconds = -1.0, bool markTextureNonReadable = true, bool generateMipmaps = true, bool linearColorSpace = false );
  101. // Returns an ImageProperties instance that holds the width, height and mime type information of an image file without creating a Texture2D object. Mime type will be null, if it can't be determined
  102. NativeGallery.ImageProperties NativeGallery.GetImageProperties( string imagePath );
  103. // Returns a VideoProperties instance that holds the width, height, duration (in milliseconds) and rotation information of a video file. To play a video in correct orientation, you should rotate it by rotation degrees clockwise. For a 90-degree or 270-degree rotated video, values of width and height should be swapped to get the display size of the video
  104. NativeGallery.VideoProperties NativeGallery.GetVideoProperties( string videoPath );
  105. // Returns the media type of the file at the specified path: Image, Video, Audio or neither of these (if media type can't be determined)
  106. NativeGallery.MediaType NativeGallery.GetMediaTypeOfFile( string path );