async Task <IList <MediaAsset> > LoadMediaAsync() { IList <MediaAsset> assets = new List <MediaAsset>(); var imageManager = new PHCachingImageManager(); var hasPermission = await RequestPermissionAsync(); if (hasPermission) { await Task.Run(async() => { var thumbnailRequestOptions = new PHImageRequestOptions(); thumbnailRequestOptions.ResizeMode = PHImageRequestOptionsResizeMode.Fast; thumbnailRequestOptions.DeliveryMode = PHImageRequestOptionsDeliveryMode.FastFormat; thumbnailRequestOptions.NetworkAccessAllowed = true; thumbnailRequestOptions.Synchronous = true; var requestOptions = new PHImageRequestOptions(); requestOptions.ResizeMode = PHImageRequestOptionsResizeMode.Exact; requestOptions.DeliveryMode = PHImageRequestOptionsDeliveryMode.HighQualityFormat; requestOptions.NetworkAccessAllowed = true; requestOptions.Synchronous = true; var fetchOptions = new PHFetchOptions(); fetchOptions.SortDescriptors = new NSSortDescriptor[] { new NSSortDescriptor("creationDate", false) }; fetchOptions.Predicate = NSPredicate.FromFormat($"mediaType == {(int)PHAssetMediaType.Image} || mediaType == {(int)PHAssetMediaType.Video}"); var fetchResults = PHAsset.FetchAssets(fetchOptions); var tmpPath = Path.GetTempPath(); var allAssets = fetchResults.Select(p => p as PHAsset).ToArray(); var thumbnailSize = new CGSize(300.0f, 300.0f); imageManager.StartCaching(allAssets, thumbnailSize, PHImageContentMode.AspectFit, thumbnailRequestOptions); imageManager.StartCaching(allAssets, PHImageManager.MaximumSize, PHImageContentMode.AspectFit, requestOptions); foreach (var result in fetchResults) { var phAsset = (result as PHAsset); var name = PHAssetResource.GetAssetResources(phAsset)?.FirstOrDefault()?.OriginalFilename; var asset = new MediaAsset() { Id = phAsset.LocalIdentifier, Name = name, Type = phAsset.MediaType == PHAssetMediaType.Image ? MediaAssetType.Image : MediaAssetType.Video, }; imageManager.RequestImageForAsset(phAsset, thumbnailSize, PHImageContentMode.AspectFit, thumbnailRequestOptions, (image, info) => { if (image != null) { NSData imageData = null; if (image.CGImage.RenderingIntent == CGColorRenderingIntent.Default) { imageData = image.AsJPEG(0.8f); } else { imageData = image.AsPNG(); } if (imageData != null) { var fileName = Path.Combine(tmpPath, $"tmp_thumbnail_{Path.GetFileNameWithoutExtension(name)}.jpg"); NSError error = null; imageData.Save(fileName, true, out error); if (error == null) { asset.PreviewPath = fileName; } } } }); switch (phAsset.MediaType) { case PHAssetMediaType.Image: imageManager.RequestImageForAsset(phAsset, PHImageManager.MaximumSize, PHImageContentMode.AspectFit, requestOptions, (image, info) => { if (image != null) { NSData imageData = null; if (image.CGImage.RenderingIntent == CGColorRenderingIntent.Default) { imageData = image.AsJPEG(0.8f); } else { imageData = image.AsPNG(); } if (imageData != null) { var fileName = Path.Combine(tmpPath, $"tmp_{name}"); NSError error = null; imageData.Save(fileName, true, out error); if (error == null) { asset.Path = fileName; } } } }); break; case PHAssetMediaType.Video: var videoRequestOptions = new PHVideoRequestOptions(); videoRequestOptions.NetworkAccessAllowed = true; var tcs = new TaskCompletionSource <bool>(); imageManager.RequestAvAsset(phAsset, null, (vAsset, audioMix, info) => { var avAsset = vAsset as AVUrlAsset; var avData = NSData.FromUrl(avAsset.Url); NSError error = null; var path = Path.Combine(tmpPath, $"tmp_{name}"); avData.Save(path, true, out error); if (error == null) { asset.Path = path; tcs.TrySetResult(true); } else { tcs.TrySetResult(false); } }); await tcs.Task; break; } UIApplication.SharedApplication.InvokeOnMainThread(delegate { OnMediaAssetLoaded?.Invoke(this, new MediaEventArgs(asset)); }); assets.Add(asset); if (requestStop) { break; } } }); imageManager.StopCaching(); } return(assets); }
async Task <IList <MediaAssest> > LoadMediaAsync() { IList <MediaAssest> assets = new List <MediaAssest>(); var hasPermission = await RequestPermissionAsync(); if (hasPermission) { var uri = MediaStore.Files.GetContentUri("external"); var ctx = Android.App.Application.Context; await Task.Run(async() => { var cursor = ctx.ApplicationContext.ContentResolver.Query(uri, new string[] { MediaStore.Files.FileColumns.Id, MediaStore.Files.FileColumns.Data, MediaStore.Files.FileColumns.DateAdded, MediaStore.Files.FileColumns.MediaType, MediaStore.Files.FileColumns.MimeType, MediaStore.Files.FileColumns.Title, MediaStore.Files.FileColumns.Parent, MediaStore.Files.FileColumns.DisplayName, MediaStore.Files.FileColumns.Size //}, $"{MediaStore.Files.FileColumns.MediaType} = {(int)MediaType.Image} OR {MediaStore.Files.FileColumns.MediaType} = {(int)MediaType.Video}", null, $"{MediaStore.Files.FileColumns.DateAdded} DESC"); }, $"{MediaStore.Files.FileColumns.MediaType} = {(int)MediaType.Image}", null, $"{MediaStore.Files.FileColumns.DateAdded} DESC"); if (cursor.Count > 0) { while (cursor.MoveToNext()) { try { var id = cursor.GetInt(cursor.GetColumnIndex(MediaStore.Files.FileColumns.Id)); var mediaType = cursor.GetInt(cursor.GetColumnIndex(MediaStore.Files.FileColumns.MediaType)); Bitmap bitmap = null; switch (mediaType) { case (int)MediaType.Image: bitmap = MediaStore.Images.Thumbnails.GetThumbnail(MainActivity.FormsActivity.ContentResolver, id, ThumbnailKind.MiniKind, new BitmapFactory.Options() { InSampleSize = 4, InPurgeable = true }); break; case (int)MediaType.Video: bitmap = MediaStore.Video.Thumbnails.GetThumbnail(MainActivity.FormsActivity.ContentResolver, id, VideoThumbnailKind.MiniKind, new BitmapFactory.Options() { InSampleSize = 4, InPurgeable = true }); break; } var tmpPath = System.IO.Path.GetTempPath(); var name = GetString(cursor, MediaStore.Files.FileColumns.DisplayName); var filePath = System.IO.Path.Combine(tmpPath, $"tmp_{name}"); var path = GetString(cursor, MediaStore.Files.FileColumns.Data); //filePath = path; using (var stream = new FileStream(filePath, FileMode.Create)) { bitmap?.Compress(Bitmap.CompressFormat.Png, 100, stream); stream.Close(); } if (!string.IsNullOrWhiteSpace(filePath)) { var asset = new MediaAssest() { Id = $"{id}", Type = mediaType == (int)MediaType.Video ? MediaAssetType.Video : MediaAssetType.Image, Name = name, PreviewPath = filePath, Path = path, IsSelectable = true }; using (var h = new Handler(Looper.MainLooper)) h.Post(async() => { OnMediaAssetLoaded?.Invoke(this, new Model.MediaEventArgs(asset)); }); assets.Add(asset); } if (stopLoad) { break; } } catch (Exception ex) { await UserDialogs.Instance.AlertAsync(ex.StackTrace.ToString(), "error", "ok"); } } } }); } return(assets); }