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);
        }
Ejemplo n.º 2
0
        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);
        }