public static VideoProperties GetVideoProperties(string videoPath) { if (!File.Exists(videoPath)) { throw new FileNotFoundException("File not found at " + videoPath); } #if !UNITY_EDITOR && UNITY_ANDROID string value = AJC.CallStatic <string>("GetVideoProperties", Context, videoPath); #elif !UNITY_EDITOR && UNITY_IOS string value = _NativeCamera_GetVideoProperties(videoPath); #else string value = null; #endif int width = 0, height = 0; long duration = 0L; float rotation = 0f; if (!string.IsNullOrEmpty(value)) { string[] properties = value.Split('>'); if (properties != null && properties.Length >= 4) { if (!int.TryParse(properties[0].Trim(), out width)) { width = 0; } if (!int.TryParse(properties[1].Trim(), out height)) { height = 0; } if (!long.TryParse(properties[2].Trim(), out duration)) { duration = 0L; } if (!float.TryParse(properties[3].Trim().Replace(',', '.'), NumberStyles.Float, CultureInfo.InvariantCulture, out rotation)) { rotation = 0f; } } } if (rotation == -90f) { rotation = 270f; } return(new VideoProperties(width, height, duration, rotation)); }
public static string ConvertExtensionToFileType(string extension) { if (string.IsNullOrEmpty(extension)) { return(null); } #if !UNITY_EDITOR && UNITY_ANDROID return(AJC.CallStatic <string>("GetMimeTypeFromExtension", extension.ToLowerInvariant())); #elif !UNITY_EDITOR && UNITY_IOS return(_NativeFilePicker_ConvertExtensionToUTI(extension.ToLowerInvariant())); #else return(extension); #endif }
public static Permission TakePicture(CameraCallback callback, int maxSize = -1) { Permission result = RequestPermission(); if (result == Permission.Granted && !IsCameraBusy()) { #if !UNITY_EDITOR && UNITY_ANDROID object threadLock = new object(); lock ( threadLock ) { NCCameraCallbackAndroid nativeCallback = new NCCameraCallbackAndroid(threadLock); AJC.CallStatic("TakePicture", Context, nativeCallback); if (string.IsNullOrEmpty(nativeCallback.Path)) { System.Threading.Monitor.Wait(threadLock); } string path = nativeCallback.Path; if (string.IsNullOrEmpty(path)) { path = null; } if (callback != null) { callback(path); } } #elif !UNITY_EDITOR && UNITY_IOS if (maxSize <= 0) { maxSize = SystemInfo.maxTextureSize; } NCCameraCallbackiOS.Initialize(callback); _NativeCamera_TakePicture(IOSSelectedImagePath, maxSize); #else if (callback != null) { callback(null); } #endif } return(result); }
public static Permission CheckPermission() { #if !UNITY_EDITOR && UNITY_ANDROID Permission result = (Permission)AJC.CallStatic <int>("CheckPermission", Context); if (result == Permission.Denied && (Permission)PlayerPrefs.GetInt("NativeGalleryPermission", (int)Permission.ShouldAsk) == Permission.ShouldAsk) { result = Permission.ShouldAsk; } return(result); #elif !UNITY_EDITOR && UNITY_IOS return((Permission)_NativeGallery_CheckPermission()); #else return(Permission.Granted); #endif }
private static Permission GetMultipleMediaFromGallery(MediaPickMultipleCallback callback, bool imageMode, string mime, string title, int maxSize) { Permission result = RequestPermission(); if (result == Permission.Granted && !IsMediaPickerBusy()) { if (CanSelectMultipleFilesFromGallery()) { #if !UNITY_EDITOR && UNITY_ANDROID object threadLock = new object(); lock ( threadLock ) { NGMediaReceiveCallbackAndroid nativeCallback = new NGMediaReceiveCallbackAndroid(threadLock); AJC.CallStatic("PickMedia", Context, nativeCallback, imageMode, true, mime, title); if (nativeCallback.Paths == null) { System.Threading.Monitor.Wait(threadLock); } string[] paths = nativeCallback.Paths; if (paths != null && paths.Length == 0) { paths = null; } if (callback != null) { callback(paths); } } #else if (callback != null) { callback(null); } #endif } else if (callback != null) { callback(null); } } return(result); }
public static bool TargetExists(string androidPackageName, string androidClassName = null) { if (string.IsNullOrEmpty(androidPackageName)) { return(false); } if (androidClassName == null) { androidClassName = string.Empty; } return(AJC.CallStatic <bool>("TargetExists", new object[3] { Context, androidPackageName, androidClassName })); }
public static void AppendBytesToFile(string targetPath, byte[] bytes) { #if !UNITY_EDITOR && UNITY_ANDROID if (ShouldUseSAF) { File.WriteAllBytes(TemporaryFilePath, bytes); AJC.CallStatic("WriteToSAFEntry", Context, targetPath, TemporaryFilePath, true); File.Delete(TemporaryFilePath); return; } #endif using (var stream = new FileStream(targetPath, FileMode.Append, FileAccess.Write)) { stream.Write(bytes, 0, bytes.Length); } }
public void CopyLog() { string log = logEntry.ToString(); if (string.IsNullOrEmpty(log)) { return; } #if UNITY_EDITOR || UNITY_2018_1_OR_NEWER || (!UNITY_ANDROID && !UNITY_IOS) GUIUtility.systemCopyBuffer = log; #elif UNITY_ANDROID AJC.CallStatic("CopyText", Context, log); #elif UNITY_IOS _DebugConsole_CopyText(log); #endif }
private static Permission GetMediaFromGallery(MediaPickCallback callback, MediaType mediaType, string mime, string title) { Permission result = RequestPermission(true); if (result == Permission.Granted && !IsMediaPickerBusy()) { #if !UNITY_EDITOR && UNITY_ANDROID string savePath; if (mediaType == MediaType.Image) { savePath = SelectedImagePath; } else if (mediaType == MediaType.Video) { savePath = SelectedVideoPath; } else { savePath = SelectedAudioPath; } AJC.CallStatic("PickMedia", Context, new NGMediaReceiveCallbackAndroid(callback, null), (int)mediaType, false, savePath, mime, title); #elif !UNITY_EDITOR && UNITY_IOS NGMediaReceiveCallbackiOS.Initialize(callback); if (mediaType == MediaType.Image) { _NativeGallery_PickImage(SelectedImagePath); } else if (mediaType == MediaType.Video) { _NativeGallery_PickVideo(SelectedVideoPath); } else if (callback != null) // Selecting audio files is not supported on iOS { callback(null); } #else if (callback != null) { callback(null); } #endif } return(result); }
private static Permission GetMediaFromGallery(MediaPickCallback callback, MediaType mediaType, string mime, string title, bool crop = true, int action = 0) { // action 2相册,3拍照 #if !UNITY_EDITOR && UNITY_ANDROID string savePath; if (mediaType == MediaType.Image) { savePath = SelectedImagePath; } else if (mediaType == MediaType.Video) { savePath = SelectedVideoPath; } else { savePath = SelectedAudioPath; } AJC.CallStatic("PickMedia", Context, new NGMediaReceiveCallbackAndroid(callback, null), (int)mediaType, false, savePath, mime, title, crop, action); return(Permission.Granted); #elif !UNITY_EDITOR && UNITY_IOS if (!IsMediaPickerBusy()) { NGMediaReceiveCallbackiOS.Initialize(callback); if (mediaType == MediaType.Image) { _NativeGallery_PickImage(SelectedImagePath); } else if (mediaType == MediaType.Video) { _NativeGallery_PickVideo(SelectedVideoPath); } else if (callback != null) // Selecting audio files is not supported on iOS { callback(null); } } #else if (callback != null) { callback(null); } #endif return(Permission.Denied); }
public static Permission CheckPermission(PermissionType permissionType) { #if !UNITY_EDITOR && UNITY_ANDROID Permission result = (Permission)AJC.CallStatic <int>("CheckPermission", Context, permissionType == PermissionType.Read); if (result == Permission.Denied && (Permission)PlayerPrefs.GetInt("NativeGalleryPermission", (int)Permission.ShouldAsk) == Permission.ShouldAsk) { result = Permission.ShouldAsk; } return(result); #elif !UNITY_EDITOR && UNITY_IOS // result == 3: LimitedAccess permission on iOS, no need to handle it when PermissionFreeMode is set to true int result = _NativeGallery_CheckPermission(permissionType == PermissionType.Read ? 1 : 0, PermissionFreeMode ? 1 : 0); return(result == 3 ? Permission.Granted : (Permission)result); #else return(Permission.Granted); #endif }
public static bool TargetExists(string androidPackageName, string androidClassName = null) { #if !UNITY_EDITOR && UNITY_ANDROID if (string.IsNullOrEmpty(androidPackageName)) { return(false); } if (androidClassName == null) { androidClassName = string.Empty; } return(AJC.CallStatic <bool>("TargetExists", Context, androidPackageName, androidClassName)); #else return(true); #endif }
public void Share() { if (files.Count == 0 && subject.Length == 0 && text.Length == 0 && recipients == 0) { Debug.LogWarning("Share Error: attempting to share nothing!"); return; } #if UNITY_EDITOR Debug.Log("Shared!"); #elif UNITY_ANDROID AJC.CallStatic("Share", Context, targetPackage, targetClass, files.ToArray(), mimes.ToArray(), subject, text, title, recipients); #elif UNITY_IOS _NativeShare_Share(files.ToArray(), files.Count, subject, text); #else Debug.Log("No sharing set up for this platform."); #endif }
private static void SaveToGalleryInternal(string path, string album, bool isImage) { #if !UNITY_EDITOR && UNITY_ANDROID AJC.CallStatic("MediaScanFile", Context, path); Debug.Log("Saving to gallery: " + path); #elif !UNITY_EDITOR && UNITY_IOS if (isImage) { _ImageWriteToAlbum(path, album); } else { _VideoWriteToAlbum(path, album); } Debug.Log("Saving to Pictures: " + Path.GetFileName(path)); #endif }
public static Permission RecordVideo(CameraCallback callback, Quality quality = Quality.Default, int maxDuration = 0, long maxSizeBytes = 0L) { Permission result = RequestPermission(); if (result == Permission.Granted && !IsCameraBusy()) { #if !UNITY_EDITOR && UNITY_ANDROID object threadLock = new object(); lock ( threadLock ) { NCCameraCallbackAndroid nativeCallback = new NCCameraCallbackAndroid(threadLock); AJC.CallStatic("RecordVideo", Context, nativeCallback, (int)quality, maxDuration, maxSizeBytes); if (string.IsNullOrEmpty(nativeCallback.Path)) { System.Threading.Monitor.Wait(threadLock); } string path = nativeCallback.Path; if (string.IsNullOrEmpty(path)) { path = null; } if (callback != null) { callback(path); } } #elif !UNITY_EDITOR && UNITY_IOS NCCameraCallbackiOS.Initialize(callback); _NativeCamera_RecordVideo((int)quality, maxDuration); #else if (callback != null) { callback(null); } #endif } return(result); }
private static void SaveToGalleryInternal(string path, string album, MediaType mediaType, MediaSaveCallback callback) { #if !UNITY_EDITOR && UNITY_ANDROID string savePath = AJC.CallStatic <string>("SaveMedia", Context, (int)mediaType, path, album); File.Delete(path); if (callback != null) { callback(!string.IsNullOrEmpty(savePath), savePath); } #elif !UNITY_EDITOR && UNITY_IOS if (mediaType == MediaType.Audio) { Debug.LogError("Saving audio files is not supported on iOS"); if (callback != null) { callback(false, null); } return; } Debug.Log("Saving to Pictures: " + Path.GetFileName(path)); NGMediaSaveCallbackiOS.Initialize(callback); if (mediaType == MediaType.Image) { _NativeGallery_ImageWriteToAlbum(path, album, PermissionFreeMode ? 1 : 0); } else if (mediaType == MediaType.Video) { _NativeGallery_VideoWriteToAlbum(path, album, PermissionFreeMode ? 1 : 0); } #else if (callback != null) { callback(true, null); } #endif }
private static void AppendFileToFile(string targetPath, string sourceFileToAppend) { #if !UNITY_EDITOR && UNITY_ANDROID if (ShouldUseSAF) { AJC.CallStatic("WriteToSAFEntry", Context, targetPath, sourceFileToAppend, true); return; } #endif using (Stream input = File.OpenRead(sourceFileToAppend)) using (Stream output = new FileStream(targetPath, FileMode.Append, FileAccess.Write)) { byte[] buffer = new byte[4096]; int bytesRead; while ((bytesRead = input.Read(buffer, 0, buffer.Length)) > 0) { output.Write(buffer, 0, bytesRead); } } }
public static bool IsDirectory(string path) { #if !UNITY_EDITOR && UNITY_ANDROID if (ShouldUseSAF) { return(AJC.CallStatic <bool>("SAFEntryDirectory", Context, path)); } #endif if (Directory.Exists(path)) { return(true); } if (File.Exists(path)) { return(false); } string extension = Path.GetExtension(path); return(extension == null || extension.Length <= 1); // extension includes '.' }
public static Permission RecordVideo(CameraCallback callback, Quality quality = Quality.Default, int maxDuration = 0, long maxSizeBytes = 0L) { Permission result = RequestPermission(); if (result == Permission.Granted && !IsCameraBusy()) { #if !UNITY_EDITOR && UNITY_ANDROID AJC.CallStatic("RecordVideo", Context, new NCCameraCallbackAndroid(callback), (int)quality, maxDuration, maxSizeBytes); #elif !UNITY_EDITOR && UNITY_IOS NCCameraCallbackiOS.Initialize(callback); _NativeCamera_RecordVideo((int)quality, maxDuration); #else if (callback != null) { callback(null); } #endif } return(result); }
private static Permission GetMultipleMediaFromGallery(MediaPickMultipleCallback callback, MediaType mediaType, string mime, string title) { Permission result = RequestPermission(PermissionType.Read); if (result == Permission.Granted && !IsMediaPickerBusy()) { if (CanSelectMultipleFilesFromGallery()) { #if !UNITY_EDITOR && UNITY_ANDROID AJC.CallStatic("PickMedia", Context, new NGMediaReceiveCallbackAndroid(null, callback), (int)mediaType, true, SelectedMediaPath, mime, title); #elif !UNITY_EDITOR && UNITY_IOS if (mediaType == MediaType.Audio) { Debug.LogError("Picking audio files is not supported on iOS"); if (callback != null) // Selecting audio files is not supported on iOS { callback(null); } } else { NGMediaReceiveCallbackiOS.Initialize(null, callback); _NativeGallery_PickMedia(SelectedMediaPath, (int)(mediaType & ~MediaType.Audio), PermissionFreeMode ? 1 : 0, 0); } #else if (callback != null) { callback(null); } #endif } else if (callback != null) { callback(null); } } return(result); }
private static void SaveToGalleryInternal(string path, string album, MediaType mediaType, MediaSaveCallback callback) { #if !UNITY_EDITOR && UNITY_ANDROID AJC.CallStatic("SaveMedia", Context, (int)mediaType, path, album); File.Delete(path); if (callback != null) { callback(null); } #elif !UNITY_EDITOR && UNITY_IOS if (mediaType == MediaType.Audio) { if (callback != null) { callback("Saving audio files is not supported on iOS"); } return; } Debug.Log("Saving to Pictures: " + Path.GetFileName(path)); NGMediaSaveCallbackiOS.Initialize(callback); if (mediaType == MediaType.Image) { _NativeGallery_ImageWriteToAlbum(path, album); } else if (mediaType == MediaType.Video) { _NativeGallery_VideoWriteToAlbum(path, album); } #else if (callback != null) { callback(null); } #endif }
private static Permission GetMultipleMediaFromGallery(MediaPickMultipleCallback callback, MediaType mediaType, string mime, string title) { Permission result = RequestPermission(true); if (result == Permission.Granted && !IsMediaPickerBusy()) { if (CanSelectMultipleFilesFromGallery()) { #if !UNITY_EDITOR && UNITY_ANDROID string savePath; if (mediaType == MediaType.Image) { savePath = SelectedImagePath; } else if (mediaType == MediaType.Video) { savePath = SelectedVideoPath; } else { savePath = SelectedAudioPath; } AJC.CallStatic("PickMedia", Context, new NGMediaReceiveCallbackAndroid(null, callback), (int)mediaType, true, savePath, mime, title); #else if (callback != null) { callback(null); } #endif } else if (callback != null) { callback(null); } } return(result); }
public static bool DirectoryExists(string path) { #if !UNITY_EDITOR && UNITY_ANDROID if (ShouldUseSAFForPath(path)) { return(AJC.CallStatic <bool>("SAFEntryExists", Context, path, true)); } else if (ShouldUseSAF) // Directory.Exists returns true even for inaccessible directories on Android 10+, we need to check if the directory is accessible { try { Directory.GetFiles(path, "testtesttest"); return(true); } catch { return(false); } } #endif return(Directory.Exists(path)); }
private static string GetSavePath(string album, string filenameFormatted) { string saveDir; #if !UNITY_EDITOR && UNITY_ANDROID saveDir = AJC.CallStatic <string>("GetMediaPath", album); #else saveDir = Application.persistentDataPath; #endif if (filenameFormatted.Contains("{0}")) { int fileIndex = 0; string path; do { path = Path.Combine(saveDir, string.Format(filenameFormatted, ++fileIndex)); } while(File.Exists(path)); return(path); } saveDir = Path.Combine(saveDir, filenameFormatted); #if !UNITY_EDITOR && UNITY_IOS // iOS internally copies images/videos to Photos directory of the system, // but the process is async. The redundant file is deleted by objective-c code // automatically after the media is saved but while it is being saved, the file // should NOT be overwritten. Therefore, always ensure a unique filename on iOS if (File.Exists(saveDir)) { return(GetSavePath(album, Path.GetFileNameWithoutExtension(filenameFormatted) + " {0}" + Path.GetExtension(filenameFormatted))); } #endif return(saveDir); }
public static Permission[] RequestPermissions(params string[] permissions) { ValidateArgument(permissions); #if IS_ANDROID_PLATFORM PermissionCallback nativeCallback; object threadLock = new object(); lock ( threadLock ) { nativeCallback = new PermissionCallback(threadLock); AJC.CallStatic("RequestPermission", permissions, Context, nativeCallback, GetCachedPermissions(permissions)); if (nativeCallback.Result == null) { System.Threading.Monitor.Wait(threadLock); } } return(ProcessPermissionRequest(permissions, nativeCallback.Result)); #else return(GetDummyResult(permissions)); #endif }
public void Share() { if (files.Count == 0 && subject.Length == 0 && text.Length == 0 && url.Length == 0) { Debug.LogWarning("Share Error: attempting to share nothing!"); return; } #if UNITY_EDITOR || UNITY_WINDOWS Debug.Log("Shared!"); foreach (var file in files) { Application.OpenURL("file://" + file); } if (callback != null) { callback(ShareResult.Shared, null); } #elif UNITY_ANDROID AJC.CallStatic("Share", Context, new NSShareResultCallbackAndroid(callback), targetPackages.ToArray(), targetClasses.ToArray(), files.ToArray(), mimes.ToArray(), subject, CombineURLWithText(), title); #elif UNITY_IOS NSShareResultCallbackiOS.Initialize(callback); if (files.Count == 0) { _NativeShare_Share(new string[0], 0, subject, text, GetURLWithScheme()); } else { // While sharing both a URL and a file, some apps either don't show up in share sheet or omit the file // If we append URL to text, the issue is resolved for at least some of these apps _NativeShare_Share(files.ToArray(), files.Count, subject, CombineURLWithText(), ""); } #else Debug.LogWarning("NativeShare is not supported on this platform!"); #endif }
public void Share() { if (files.Count == 0 && subject.Length == 0 && text.Length == 0) { Debug.LogWarning("Share Error: attempting to share nothing!"); return; } #if UNITY_EDITOR Debug.Log("Shared!"); if (callback != null) { callback(ShareResult.Shared, null); } #elif UNITY_ANDROID AJC.CallStatic("Share", Context, new NSShareResultCallbackAndroid(callback), targetPackages.ToArray(), targetClasses.ToArray(), files.ToArray(), mimes.ToArray(), subject, text, title); #elif UNITY_IOS NSShareResultCallbackiOS.Initialize(callback); _NativeShare_Share(files.ToArray(), files.Count, subject, text); #else Debug.LogWarning("NativeShare is not supported on this platform!"); #endif }
public static Texture2D GetVideoThumbnail(string videoPath, int maxSize = -1, double captureTimeInSeconds = -1.0, bool markTextureNonReadable = true) { if (maxSize <= 0) { maxSize = SystemInfo.maxTextureSize; } #if !UNITY_EDITOR && UNITY_ANDROID string thumbnailPath = AJC.CallStatic <string>("GetVideoThumbnail", Context, videoPath, TemporaryImagePath + ".png", false, maxSize, captureTimeInSeconds); #elif !UNITY_EDITOR && UNITY_IOS string thumbnailPath = _NativeGallery_GetVideoThumbnail(videoPath, TemporaryImagePath + ".png", maxSize, captureTimeInSeconds); #else string thumbnailPath = null; #endif if (!string.IsNullOrEmpty(thumbnailPath)) { return(LoadImageAtPath(thumbnailPath, maxSize, markTextureNonReadable)); } else { return(null); } }
public static bool FindTarget(out string androidPackageName, out string androidClassName, string packageNameRegex, string classNameRegex = null) { androidPackageName = null; androidClassName = null; #if !UNITY_EDITOR && UNITY_ANDROID if (string.IsNullOrEmpty(packageNameRegex)) { return(false); } if (classNameRegex == null) { classNameRegex = string.Empty; } string result = AJC.CallStatic <string>("FindMatchingTarget", Context, packageNameRegex, classNameRegex); if (string.IsNullOrEmpty(result)) { return(false); } int splitIndex = result.IndexOf('>'); if (splitIndex <= 0 || splitIndex >= result.Length - 1) { return(false); } androidPackageName = result.Substring(0, splitIndex); androidClassName = result.Substring(splitIndex + 1); return(true); #else return(false); #endif }
public static Permission ExportMultipleFiles(string[] filePaths, FilesExportedCallback callback = null) { if (filePaths == null || filePaths.Length == 0) { throw new ArgumentException("Parameter 'filePaths' is null or empty!"); } Permission result = RequestPermission(false); if (result == Permission.Granted && !IsFilePickerBusy()) { if (CanExportMultipleFiles()) { #if UNITY_EDITOR string destination = UnityEditor.EditorUtility.OpenFolderPanel("Select destination", Path.GetDirectoryName(filePaths[0]), ""); if (string.IsNullOrEmpty(destination)) { if (callback != null) { callback(false); } } else { try { for (int i = 0; i < filePaths.Length; i++) { File.Copy(filePaths[i], Path.Combine(destination, Path.GetFileName(filePaths[i])), true); } if (callback != null) { callback(true); } } catch (Exception e) { Debug.LogException(e); if (callback != null) { callback(false); } } } #elif UNITY_ANDROID AJC.CallStatic("ExportFiles", Context, new FPResultCallbackAndroid(null, null, callback), filePaths, filePaths.Length); #elif UNITY_IOS FPResultCallbackiOS.Initialize(null, null, callback); _NativeFilePicker_ExportFiles(filePaths, filePaths.Length); #endif } else if (callback != null) { callback(false); } } return(result); }