简体   繁体   中英

Xamarin - Is there a similar framework to Photokit (iOS) available for Android, or a good way to get the filestream of all images in the gallery?

I'm currently creating a Xamarin Forms app where I'm looking to retreive all the images from the device gallery and display them in a grid. I want to do this using DepdencyService with native implementations.

For iOS I use the Photokit framework to retreive the Stream of each image and feed this into my grid.

I'm looking for a way to solve this similarly for Android. I've tried looking through docs but can't seem to find something that does this.

The view

 private void GetGallery()
        {
            var imageStreams = DependencyService.Get<IGalleryFetcher>().GalleryStream();

            foreach (var stream in imageStreams)
            { 
               // Create image objects and set the stream as the image source
            }

The iOS implementation

 public ObservableCollection<Stream> GalleryStream()
        {
            var streamArray = new ObservableCollection<Stream>();
            PHFetchResult fetchResult = PHAsset.FetchAssets(PHAssetMediaType.Image, null);
            for (int i = 0; i < fetchResult.Count(); i++)
            {
                PHAsset phAsset = (PHAsset)fetchResult[i];
                string fileName = (NSString)phAsset.ValueForKey((NSString)"filename");

                PHImageManager.DefaultManager.RequestImageData(phAsset, null, (data, dataUti, orientation, info) =>
                {
                    var path = (info?[(NSString)@"PHImageFileURLKey"] as NSUrl).FilePathUrl.Path;
                    Stream stream = new FileStream(path, FileMode.Open, FileAccess.Read);
                    streamArray.Add(stream);

                });
            }
            return streamArray;
        }

Android implementation

//Help needed

Is there any available framework or package that can help with doing something similar for Android as I've done for iOS?

EDIT: I use the CrossMedia plugin for taking and selecting images, but I can not find that this plugin provides the desired feature.

My desired functionality is that geting all the images from the gallery does not require an active action or selection. No file picker or import action, the (file)stream for every image should be retreived automatically when the view is opened.

You can use ContentResolver in Android .

Add the following permission in Manifest.xml

 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

in your DepdencyService

void GetAllImage()
{
   Android.Net.Uri imageUri = MediaStore.Images.Media.ExternalContentUri;
   var carsor = ContentResolver.Query(imageUri,null, MediaStore.Images.ImageColumns.MimeType + "=? or "+ MediaStore.Images.ImageColumns.MimeType+ "=?",new string[] { "image/jpeg", "image/png" }, MediaStore.Images.ImageColumns.DateModified);

   while(carsor.MoveToNext())
   {
     string path = carsor.GetString(carsor.GetColumnIndex(MediaStore.Images.ImageColumns.Data));
     Stream stream = new FileStream(path, FileMode.Open, FileAccess.Read);
     streamArray.Add(stream);
   }

}

Summary of solution for anyone interested.

Per the answer from @Lucas Zhanf - MSFT , this is the final solution.

Android - GalleryFetcherAndroid

   public ObservableCollection<string> GalleryStream()
        {
            var gallerySources = new ObservableCollection<string>();
            Android.Net.Uri imageUri = MediaStore.Images.Media.ExternalContentUri;

            var cursor = Android.App.Application.Context.ContentResolver.Query(imageUri, null, MediaStore.Images.ImageColumns.MimeType + "=? or " + MediaStore.Images.ImageColumns.MimeType + "=?", new string[] { "image/jpeg", "image/png" }, MediaStore.Images.ImageColumns.DateModified);

            while (cursor.MoveToNext())
            {
                string path = cursor.GetString(cursor.GetColumnIndex(MediaStore.Images.ImageColumns.Data));
                gallerySources.Add(path);
            }

            return gallerySources;
        }

iOS - GalleryFetcheriOS

  public ObservableCollection<string> GalleryStream()
        {
            var streamArray = new ObservableCollection<string>();
            PHFetchResult fetchResult = PHAsset.FetchAssets(PHAssetMediaType.Image, null);
            for (int i = 0; i < fetchResult.Count(); i++)
            {
                PHAsset phAsset = (PHAsset)fetchResult[i];
                string fileName = (NSString)phAsset.ValueForKey((NSString)"filename");

                PHImageManager.DefaultManager.RequestImageData(phAsset, null, (data, dataUti, orientation, info) =>
                {
                    var path = (info?[(NSString)@"PHImageFileURLKey"] as NSUrl).FilePathUrl.Path;
                    streamArray.Add(path);

                });
            }
            return streamArray;
        }

Forms interface - IGalleryFetcher

    public interface IGalleryFetcher
    {
        ObservableCollection<string> GalleryStream();
    }

Example usage - ContentPage

  private void GetGallery()
        {
            var imageSources = DependencyService.Get<IGalleryFetcher>().GalleryStream();
            foreach (var imageSource in imageSources)
            {
                //Consider applying a limitation to the amount of images to load
                ImageSource source = ImageSource.FromFile(imageSource);
                //Use the image source for your view
            }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM