public async Task <FileResult> PickAsync(MediaPickerOptions options, bool photo) { var intent = new Intent(Intent.ActionGetContent); intent.SetType(photo ? FileMimeTypes.ImageAll : FileMimeTypes.VideoAll); var pickerIntent = Intent.CreateChooser(intent, options?.Title); try { string path = null; void OnResult(Intent intent) { // The uri returned is only temporary and only lives as long as the Activity that requested it, // so this means that it will always be cleaned up by the time we need it because we are using // an intermediate activity. path = FileSystemUtils.EnsurePhysicalPath(intent.Data); } await IntermediateActivity.StartAsync(pickerIntent, PlatformUtils.requestCodeMediaPicker, onResult : OnResult); return(new FileResult(path)); } catch (OperationCanceledException) { return(null); } }
static async Task <FileResult> PlatformPickAsync(MediaPickerOptions options, bool photo) { // We only need the permission when accessing the file, but it's more natural // to ask the user first, then show the picker. await Permissions.RequestAsync <Permissions.StorageRead>(); var intent = new Intent(Intent.ActionGetContent); intent.SetType(photo ? FileSystem.MimeTypes.ImageAll : FileSystem.MimeTypes.VideoAll); var pickerIntent = Intent.CreateChooser(intent, options?.Title); try { string path = null; void OnResult(Intent intent) { // The uri returned is only temporary and only lives as long as the Activity that requested it, // so this means that it will always be cleaned up by the time we need it because we are using // an intermediate activity. path = FileSystem.EnsurePhysicalPath(intent.Data); } await IntermediateActivity.StartAsync(pickerIntent, Platform.requestCodeMediaPicker, onResult : OnResult); return(new FileResult(path)); } catch (OperationCanceledException) { return(null); } }
static async Task <IEnumerable <FilePickerResult> > PlatformPickAsync(PickOptions options, bool allowMultiple = false) { // we only need the permission when accessing the file, but it's more natural // to ask the user first, then show the picker. await Permissions.RequestAsync <Permissions.StorageRead>(); // Essentials supports >= API 19 where this action is available var action = Intent.ActionOpenDocument; var intent = new Intent(action); intent.SetType("*/*"); intent.AddFlags(ActivityFlags.GrantPersistableUriPermission); intent.PutExtra(Intent.ExtraAllowMultiple, allowMultiple); var allowedTypes = options?.FileTypes?.Value?.ToArray(); if (allowedTypes?.Length > 0) { intent.PutExtra(Intent.ExtraMimeTypes, allowedTypes); } var pickerIntent = Intent.CreateChooser(intent, options?.PickerTitle ?? "Select file"); try { var result = await IntermediateActivity.StartAsync(pickerIntent, requestCodeFilePicker); var resultList = new List <FilePickerResult>(); var clipData = new List <global::Android.Net.Uri>(); if (result.ClipData == null) { clipData.Add(result.Data); } else { for (var i = 0; i < result.ClipData.ItemCount; i++) { clipData.Add(result.ClipData.GetItemAt(i).Uri); } } foreach (var contentUri in clipData) { Platform.AppContext.ContentResolver.TakePersistableUriPermission( contentUri, ActivityFlags.GrantReadUriPermission); resultList.Add(new FilePickerResult(contentUri)); } return(resultList); } catch (OperationCanceledException) { return(null); } }
public static async void StartOrStop(Activity activity, bool startOrStop) { if (ProxySettings.IsVpnMode.Value) { if (startOrStop) { // 调用 VpnService.prepare() 以询问权限(需要时) var intent = AndroidNetVpnService.Prepare(activity); if (intent != null) { void OnResult(Intent intent) => activity.StartOrStopForegroundService <VpnService>(true); await IntermediateActivity.StartAsync(intent, requestCodeVpnService, onResult : OnResult); return; } } // 不需要授权则直接启动 activity.StartOrStopForegroundService <VpnService>(startOrStop); } else { activity.StartOrStopForegroundService <Service>(startOrStop); } }
static async Task <FileResult> PlatformCaptureAsync(MediaPickerOptions options, bool photo) { await Permissions.EnsureGrantedAsync <Permissions.Camera>(); await Permissions.EnsureGrantedAsync <Permissions.StorageWrite>(); var capturePhotoIntent = new Intent(photo ? MediaStore.ActionImageCapture : MediaStore.ActionVideoCapture); if (capturePhotoIntent.ResolveActivity(Platform.AppContext.PackageManager) != null) { try { var activity = Platform.GetCurrentActivity(true); var storageDir = Platform.AppContext.ExternalCacheDir; var tmpFile = Java.IO.File.CreateTempFile(Guid.NewGuid().ToString(), photo ? ".jpg" : ".mp4", storageDir); tmpFile.DeleteOnExit(); capturePhotoIntent.AddFlags(ActivityFlags.GrantReadUriPermission); capturePhotoIntent.AddFlags(ActivityFlags.GrantWriteUriPermission); var result = await IntermediateActivity.StartAsync(capturePhotoIntent, Platform.requestCodeMediaCapture, tmpFile); var outputUri = result.GetParcelableExtra(IntermediateActivity.OutputUriExtra) as global::Android.Net.Uri; return(new FileResult(outputUri)); } catch (OperationCanceledException) { return(null); } } return(null); }
static async Task <IEnumerable <FileResult> > PlatformPickAsync(PickOptions options, bool allowMultiple = false) { // we only need the permission when accessing the file, but it's more natural // to ask the user first, then show the picker. await Permissions.RequestAsync <Permissions.StorageRead>(); // Essentials supports >= API 19 where this action is available var action = Intent.ActionOpenDocument; var intent = new Intent(action); intent.SetType(FileSystem.MimeTypes.All); intent.PutExtra(Intent.ExtraAllowMultiple, allowMultiple); var allowedTypes = options?.FileTypes?.Value?.ToArray(); if (allowedTypes?.Length > 0) { intent.PutExtra(Intent.ExtraMimeTypes, allowedTypes); } var pickerIntent = Intent.CreateChooser(intent, options?.PickerTitle ?? "Select file"); try { var resultList = new List <FileResult>(); void OnResult(Intent intent) { // The uri returned is only temporary and only lives as long as the Activity that requested it, // so this means that it will always be cleaned up by the time we need it because we are using // an intermediate activity. if (intent.ClipData == null) { var path = FileSystem.EnsurePhysicalPath(intent.Data); resultList.Add(new FileResult(path)); } else { for (var i = 0; i < intent.ClipData.ItemCount; i++) { var uri = intent.ClipData.GetItemAt(i).Uri; var path = FileSystem.EnsurePhysicalPath(uri); resultList.Add(new FileResult(path)); } } } await IntermediateActivity.StartAsync(pickerIntent, Platform.requestCodeFilePicker, onResult : OnResult); return(resultList); } catch (OperationCanceledException) { return(null); } }
public async Task <FileResult> CaptureAsync(MediaPickerOptions options, bool photo) { if (!IsCaptureSupported) { throw new FeatureNotSupportedException(); } await Permissions.EnsureGrantedAsync <Permissions.Camera>(); await Permissions.EnsureGrantedAsync <Permissions.StorageWrite>(); var capturePhotoIntent = new Intent(photo ? MediaStore.ActionImageCapture : MediaStore.ActionVideoCapture); if (!PlatformUtils.IsIntentSupported(capturePhotoIntent)) { throw new FeatureNotSupportedException($"Either there was no camera on the device or '{capturePhotoIntent.Action}' was not added to the <queries> element in the app's manifest file. See more: https://developer.android.com/about/versions/11/privacy/package-visibility"); } capturePhotoIntent.AddFlags(ActivityFlags.GrantReadUriPermission); capturePhotoIntent.AddFlags(ActivityFlags.GrantWriteUriPermission); try { var activity = ActivityStateManager.Default.GetCurrentActivity(true); // Create the temporary file var ext = photo ? FileExtensions.Jpg : FileExtensions.Mp4; var fileName = Guid.NewGuid().ToString("N") + ext; var tmpFile = FileSystemUtils.GetTemporaryFile(Application.Context.CacheDir, fileName); // Set up the content:// uri AndroidUri outputUri = null; void OnCreate(Intent intent) { // Android requires that using a file provider to get a content:// uri for a file to be called // from within the context of the actual activity which may share that uri with another intent // it launches. outputUri ??= FileProvider.GetUriForFile(tmpFile); intent.PutExtra(MediaStore.ExtraOutput, outputUri); } // Start the capture process await IntermediateActivity.StartAsync(capturePhotoIntent, PlatformUtils.requestCodeMediaCapture, OnCreate); // Return the file that we just captured return(new FileResult(tmpFile.AbsolutePath)); } catch (OperationCanceledException) { return(null); } }
static async Task <Contact> PlatformPickContactAsync() { using var intent = new Intent(Intent.ActionPick); intent.SetType(ContactsContract.CommonDataKinds.Phone.ContentType); var result = await IntermediateActivity.StartAsync(intent, Platform.requestCodePickContact).ConfigureAwait(false); if (result?.Data != null) { return(PlatformGetContacts(result.Data)); } return(null); }
public async Task <FilePicker2.SaveFileResult?> PlatformSaveAsync(FilePicker2.SaveOptions?options) { // https://developer.android.google.cn/training/data-storage/shared/documents-files?hl=zh-cn#create-file // https://github.com/xamarin/Essentials/blob/main/Xamarin.Essentials/MediaPicker/MediaPicker.android.cs var intent = new Intent(Intent.ActionCreateDocument); intent.AddCategory(Intent.CategoryOpenable); intent.SetType(MediaTypeNames.All); if (options != null) { if (!string.IsNullOrEmpty(options.InitialFileName)) { intent.PutExtra(Intent.ExtraTitle, options.InitialFileName); } var mimetypes = options.FileTypes?.Value; if (mimetypes.Any_Nullable()) { intent.PutExtra(Intent.ExtraMimeTypes, mimetypes.ToArray()); } } try { FilePicker2.SaveFileResult?result = null; void OnResult(Intent intent) { // The uri returned is only temporary and only lives as long as the Activity that requested it, // so this means that it will always be cleaned up by the time we need it because we are using // an intermediate activity. var uri = intent.Data; if (uri != null) { var uriString = uri.ToString(); var outputStream = XEPlatform.AppContext.ContentResolver !.OpenOutputStream(uri); result = new FilePicker2.SaveFileResult(outputStream ?? throw new ArgumentNullException(nameof(outputStream)), uriString); } } await IntermediateActivity.StartAsync(intent, requestCodeSaveFileDialog, onResult : OnResult); return(result); } catch (OperationCanceledException) { return(null); } }
static async Task <Contact> PlatformPickContactAsync() { var intent = new Intent(Intent.ActionPick, ContactsContract.Contacts.ContentUri); var result = await IntermediateActivity.StartAsync(intent, Platform.requestCodePickContact).ConfigureAwait(false); if (result?.Data == null) { return(null); } using var cursor = Platform.ContentResolver.Query(result?.Data, null, null, null, null); if (cursor?.MoveToFirst() != true) { return(null); } return(GetContact(cursor)); }
static async Task <FileResult> PlatformPickAsync(MediaPickerOptions options, bool photo) { // we only need the permission when accessing the file, but it's more natural // to ask the user first, then show the picker. await Permissions.RequestAsync <Permissions.StorageRead>(); var intent = new Intent(Intent.ActionGetContent); intent.SetType(photo ? "image/*" : "video/*"); var pickerIntent = Intent.CreateChooser(intent, options?.Title); try { var result = await IntermediateActivity.StartAsync(pickerIntent, Platform.requestCodeMediaPicker); return(new FileResult(result.Data)); } catch (OperationCanceledException) { return(null); } }