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.EnsureGrantedAsync <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 <FileResult> PlatformMediaAsync(MediaPickerOptions options, bool photo) { Permissions.EnsureDeclared <Permissions.LaunchApp>(); await Permissions.EnsureGrantedAsync <Permissions.StorageRead>(); var tcs = new TaskCompletionSource <FileResult>(); var appControl = new AppControl(); appControl.Operation = photo ? AppControlOperations.ImageCapture : AppControlOperations.VideoCapture; appControl.LaunchMode = AppControlLaunchMode.Group; var appId = AppControl.GetMatchedApplicationIds(appControl)?.FirstOrDefault(); if (!string.IsNullOrEmpty(appId)) { appControl.ApplicationId = appId; } AppControl.SendLaunchRequest(appControl, (request, reply, result) => { if (result == AppControlReplyResult.Succeeded && reply.ExtraData.Count() > 0) { var file = reply.ExtraData.Get <IEnumerable <string> >(AppControlData.Selected)?.FirstOrDefault(); tcs.TrySetResult(new FileResult(file)); } else { tcs.TrySetCanceled(); } }); return(await tcs.Task); }
static async Task <Location> PlatformLocationAsync(GeolocationRequest request, CancellationToken cancellationToken) { await Permissions.EnsureGrantedAsync <Permissions.LocationWhenInUse>(); var geolocator = new Geolocator { DesiredAccuracyInMeters = request.PlatformDesiredAccuracy }; CheckStatus(geolocator.LocationStatus); cancellationToken = Utils.TimeoutToken(cancellationToken, request.Timeout); var location = await geolocator.GetGeopositionAsync().AsTask(cancellationToken); return(location?.Coordinate?.ToLocation()); void CheckStatus(PositionStatus status) { switch (status) { case PositionStatus.Disabled: case PositionStatus.NotAvailable: throw new FeatureNotEnabledException("Location services are not enabled on device."); } } }
static async Task <IEnumerable <FileResult> > PlatformPickAsync(PickOptions options, bool allowMultiple = false) { Permissions.EnsureDeclared <Permissions.LaunchApp>(); await Permissions.EnsureGrantedAsync <Permissions.StorageRead>(); var tcs = new TaskCompletionSource <IEnumerable <FileResult> >(); var appControl = new AppControl(); appControl.Operation = AppControlOperations.Pick; appControl.ExtraData.Add(AppControlData.SectionMode, allowMultiple ? "multiple" : "single"); appControl.LaunchMode = AppControlLaunchMode.Single; var fileType = options?.FileTypes?.Value?.FirstOrDefault(); appControl.Mime = fileType ?? FileSystem.MimeTypes.All; var fileResults = new List <FileResult>(); AppControl.SendLaunchRequest(appControl, (request, reply, result) => { if (result == AppControlReplyResult.Succeeded) { if (reply.ExtraData.Count() > 0) { var selectedFiles = reply.ExtraData.Get <IEnumerable <string> >(AppControlData.Selected).ToList(); fileResults.AddRange(selectedFiles.Select(f => new FileResult(f))); } } tcs.TrySetResult(fileResults); }); return(await tcs.Task); }
static async Task CheckSupportAsync() { if (!IsSupported) { throw new FeatureNotSupportedException(); } await Permissions.EnsureGrantedAsync <Permissions.Flashlight>(); }
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.EnsureGrantedAsync <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 static async Task <Contact> PickContactAsync() { // iOS does not require permissions for the picker if (DeviceInfo.Platform != DevicePlatform.iOS) { await Permissions.EnsureGrantedAsync <Permissions.ContactsRead>(); } return(await PlatformPickContactAsync()); }
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 (!Platform.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 = Platform.GetCurrentActivity(true); // Create the temporary file var ext = photo ? FileSystem.Extensions.Jpg : FileSystem.Extensions.Mp4; var fileName = Guid.NewGuid().ToString("N") + ext; var tmpFile = FileSystem.GetEssentialsTemporaryFile(Platform.AppContext.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, Platform.requestCodeMediaCapture, OnCreate); // Return the file that we just captured return(new FileResult(tmpFile.AbsolutePath)); } catch (OperationCanceledException) { return(null); } }
static async Task <Location> PlatformLastKnownLocationAsync() { if (!CLLocationManager.LocationServicesEnabled) { throw new FeatureNotEnabledException("Location services are not enabled on device."); } await Permissions.EnsureGrantedAsync <Permissions.LocationWhenInUse>(); var manager = new CLLocationManager(); var location = manager.Location; return(location?.ToLocation()); }
static async Task <Location> PlatformLocationAsync(GeolocationRequest request, CancellationToken cancellationToken) { if (!CLLocationManager.LocationServicesEnabled) { throw new FeatureNotEnabledException("Location services are not enabled on device."); } await Permissions.EnsureGrantedAsync <Permissions.LocationWhenInUse>(); // the location manager requires an active run loop // so just use the main loop var manager = MainThread.InvokeOnMainThread(() => new CLLocationManager()); var tcs = new TaskCompletionSource <CLLocation>(manager); var listener = new SingleLocationListener(); listener.LocationHandler += HandleLocation; cancellationToken = Utils.TimeoutToken(cancellationToken, request.Timeout); cancellationToken.Register(Cancel); manager.DesiredAccuracy = request.PlatformDesiredAccuracy; manager.Delegate = listener; #if __IOS__ // we're only listening for a single update manager.PausesLocationUpdatesAutomatically = false; #endif manager.StartUpdatingLocation(); var clLocation = await tcs.Task; return(clLocation?.ToLocation()); void HandleLocation(CLLocation location) { manager.StopUpdatingLocation(); tcs.TrySetResult(location); } void Cancel() { manager.StopUpdatingLocation(); tcs.TrySetResult(null); } }
static async Task <Location> PlatformLastKnownLocationAsync() { await Permissions.EnsureGrantedAsync <Permissions.LocationWhenInUse>(); var lm = Platform.LocationManager; AndroidLocation bestLocation = null; foreach (var provider in lm.GetProviders(true)) { var location = lm.GetLastKnownLocation(provider); if (location != null && IsBetterLocation(location, bestLocation)) { bestLocation = location; } } return(bestLocation?.ToLocation()); }
static async Task <Contact> PlatformPickContactAsync() { Permissions.EnsureDeclared <Permissions.ContactsRead>(); Permissions.EnsureDeclared <Permissions.LaunchApp>(); await Permissions.EnsureGrantedAsync <Permissions.ContactsRead>(); var tcs = new TaskCompletionSource <Contact>(); var appControl = new AppControl(); appControl.Operation = AppControlOperations.Pick; appControl.ExtraData.Add(AppControlData.SectionMode, "single"); appControl.LaunchMode = AppControlLaunchMode.Single; appControl.Mime = "application/vnd.tizen.contact"; AppControl.SendLaunchRequest(appControl, (request, reply, result) => { Contact contact = null; if (result == AppControlReplyResult.Succeeded) { var contactId = reply.ExtraData.Get <IEnumerable <string> >(AppControlData.Selected)?.FirstOrDefault(); if (int.TryParse(contactId, out var contactInt)) { var record = manager.Database.Get(TizenContact.Uri, contactInt); if (record != null) { contact = ToContact(record); } } } tcs.TrySetResult(contact); }); return(await tcs.Task); }
static async Task <FileResult> PhotoAsync(MediaPickerOptions options, bool photo, bool pickExisting) { var sourceType = pickExisting ? UIImagePickerControllerSourceType.PhotoLibrary : UIImagePickerControllerSourceType.Camera; var mediaType = photo ? UTType.Image : UTType.Movie; if (!UIImagePickerController.IsSourceTypeAvailable(sourceType)) { throw new FeatureNotSupportedException(); } if (!UIImagePickerController.AvailableMediaTypes(sourceType).Contains(mediaType)) { throw new FeatureNotSupportedException(); } if (!photo) { await Permissions.EnsureGrantedAsync <Permissions.Microphone>(); } // Check if picking existing or not and ensure permission accordingly as they can be set independently from each other if (pickExisting && !Platform.HasOSVersion(11, 0)) { await Permissions.EnsureGrantedAsync <Permissions.Photos>(); } if (!pickExisting) { await Permissions.EnsureGrantedAsync <Permissions.Camera>(); } var vc = Platform.GetCurrentViewController(true); picker = new UIImagePickerController(); picker.SourceType = sourceType; picker.MediaTypes = new string[] { mediaType }; picker.AllowsEditing = false; if (!photo && !pickExisting) { picker.CameraCaptureMode = UIImagePickerControllerCameraCaptureMode.Video; } if (!string.IsNullOrWhiteSpace(options?.Title)) { picker.Title = options.Title; } if (DeviceInfo.Idiom == DeviceIdiom.Tablet && picker.PopoverPresentationController != null && vc.View != null) { picker.PopoverPresentationController.SourceRect = vc.View.Bounds; } var tcs = new TaskCompletionSource <FileResult>(picker); picker.Delegate = new PhotoPickerDelegate { CompletedHandler = info => GetFileResult(info, tcs) }; if (picker.PresentationController != null) { picker.PresentationController.Delegate = new PhotoPickerPresentationControllerDelegate { CompletedHandler = info => GetFileResult(info, tcs) }; } await vc.PresentViewControllerAsync(picker, true); var result = await tcs.Task; await vc.DismissViewControllerAsync(true); picker?.Dispose(); picker = null; return(result); }
static async Task <Location> PlatformLocationAsync(GeolocationRequest request, CancellationToken cancellationToken) { await Permissions.EnsureGrantedAsync <Permissions.LocationWhenInUse>(); var locationManager = Platform.LocationManager; var enabledProviders = locationManager.GetProviders(true); var hasProviders = enabledProviders.Any(p => !ignoredProviders.Contains(p)); if (!hasProviders) { throw new FeatureNotEnabledException("Location services are not enabled on device."); } // get the best possible provider for the requested accuracy var providerInfo = GetBestProvider(locationManager, request.DesiredAccuracy); // if no providers exist, we can't get a location // let's punt and try to get the last known location if (string.IsNullOrEmpty(providerInfo.Provider)) { return(await GetLastKnownLocationAsync()); } var tcs = new TaskCompletionSource <AndroidLocation>(); var allProviders = locationManager.GetProviders(false); var providers = new List <string>(); if (allProviders.Contains(LocationManager.GpsProvider)) { providers.Add(LocationManager.GpsProvider); } if (allProviders.Contains(LocationManager.NetworkProvider)) { providers.Add(LocationManager.NetworkProvider); } if (providers.Count == 0) { providers.Add(providerInfo.Provider); } var listener = new SingleLocationListener(locationManager, providerInfo.Accuracy, providers); listener.LocationHandler = HandleLocation; cancellationToken = Utils.TimeoutToken(cancellationToken, request.Timeout); cancellationToken.Register(Cancel); // start getting location updates // make sure to use a thread with a looper var looper = Looper.MyLooper() ?? Looper.MainLooper; foreach (var provider in providers) { locationManager.RequestLocationUpdates(provider, 0, 0, listener, looper); } var androidLocation = await tcs.Task; if (androidLocation == null) { return(null); } return(androidLocation.ToLocation()); void HandleLocation(AndroidLocation location) { RemoveUpdates(); tcs.TrySetResult(location); } void Cancel() { RemoveUpdates(); tcs.TrySetResult(listener.BestLocation); } void RemoveUpdates() { for (var i = 0; i < providers.Count; i++) { locationManager.RemoveUpdates(listener); } } }
static async Task <Location> PlatformLocationAsync(GeolocationRequest request, CancellationToken cancellationToken) { await Permissions.EnsureGrantedAsync <Permissions.LocationWhenInUse>(); Locator service = null; var gps = Platform.GetFeatureInfo <bool>("location.gps"); var wps = Platform.GetFeatureInfo <bool>("location.wps"); if (gps) { if (wps) { service = new Locator(LocationType.Hybrid); } else { service = new Locator(LocationType.Gps); } } else { if (wps) { service = new Locator(LocationType.Wps); } else { service = new Locator(LocationType.Passive); } } var tcs = new TaskCompletionSource <bool>(); cancellationToken = Utils.TimeoutToken(cancellationToken, request.Timeout); cancellationToken.Register(() => { service?.Stop(); tcs.TrySetResult(false); }); double KmToMetersPerSecond(double km) => km * 0.277778; service.LocationChanged += (s, e) => { if (e.Location != null) { lastKnownLocation.Accuracy = e.Location.Accuracy; lastKnownLocation.Altitude = e.Location.Altitude; lastKnownLocation.Course = e.Location.Direction; lastKnownLocation.Latitude = e.Location.Latitude; lastKnownLocation.Longitude = e.Location.Longitude; lastKnownLocation.Speed = KmToMetersPerSecond(e.Location.Speed); lastKnownLocation.Timestamp = e.Location.Timestamp; } service?.Stop(); tcs.TrySetResult(true); }; service.Start(); await tcs.Task; return(lastKnownLocation); }