关于xamarin:MASA-MAUI-Plugin-九Android相册多选照片使用Android-Jetpack套件库

33次阅读

共计 5434 个字符,预计需要花费 14 分钟才能阅读完成。

背景

MAUI 的呈现,赋予了宽广.Net 开发者开发多平台利用的能力,MAUI 是 Xamarin.Forms 演变而来,然而相比 Xamarin 性能更好,可扩展性更强,构造更简略。然而 MAUI 对于平台相干的实现并不残缺。所以 MASA 团队发展了一个实验性我的项目,意在对微软 MAUI 的补充和扩大

我的项目地址https://github.com/BlazorComp…

每个性能都有独自的 demo 演示我的项目,思考到 app 安装文件体积(尽管 MAUI 曾经集成裁剪性能,然而该性能对于代码自身有影响),届时每一个性能都会以独自的 nuget 包的模式提供,不便测试,当初我的项目才刚刚开始,然而置信很快就会有能够交付的内容啦。

前言

本系列文章面向挪动开发小白,从零开始进行平台相干性能开发,演示如何参考平台的官网文档应用 MAUI 技术来开发相应性能。

介绍

Jetpack 蕴含一系列 Android 库,它们都采纳最佳做法并在 Android 利用中提供向后兼容性。

https://developer.android.goo…

上一篇咱们是通过 Intent 实现的,明天咱们用 Jetpack 实现相册的多选性能。

一、实现形式

能够应用以下 activity 后果协定来启动照片选择器:
PickVisualMedia,用于抉择单张图片或单个视频。
PickMultipleVisualMedia,用于抉择多张图片或多个视频。
咱们的需要是能够多选照片,咱们次要介绍 PickMultipleVisualMedia 的应用办法。
咱们先看一下 JAVA 的示例代码

JAVA 代码
// Registering Photo Picker activity launcher with multiple selects (5 max in this example)
ActivityResultLauncher<PickVisualMediaRequest> pickMultipleMedia =
        registerForActivityResult(new PickMultipleVisualMedia(5), uris -> {
    // Callback is invoked after the user selects media items or closes the
    // photo picker.
    if (!uris.isEmpty()) {Log.d("PhotoPicker", "Number of items selected:" + uris.size());
    } else {Log.d("PhotoPicker", "No media selected");
    }
});

// For this example, launch the photo picker and allow the user to choose images
// and videos. If you want the user to select a specific type of media file,
// use the overloaded versions of launch(), as shown in the section about how
// to select a single media item.
pickMultipleMedia.launch(new PickVisualMediaRequest.Builder()
        .setMediaType(PickVisualMedia.ImageAndVideo.INSTANCE)
        .build());

这里先介绍一下registerForActivityResult

在 Android 中启动另一个 activity(无论是您利用中的 activity 还是其余利用中的 activity)不肯定是单向操作。咱们须要获取 activity 的返回后果。这里咱们就是启动了相册,并获取用户选取照片的返回后果。其余例如关上相机获取拍照后果,关上通讯录获取联系人后果都是具体的利用场景。

尽管所有 API 级别的 Activity 类均提供底层 startActivityForResult() 和 onActivityResult() API,但 Android 官网强烈建议应用 AndroidX Activity 和 Fragment 中引入的 Activity Result API。
Activity Result API 提供了用于注册后果、启动后果以及在零碎分派后果后对其进行解决的组件。
在启动 activity 以获取后果时,可能会呈现您的过程和 activity 因内存不足而被销毁的状况;如果是应用相机等内存密集型操作,简直能够确定会呈现这种状况。
因而,Activity Result API 会将后果回调从您之前启动另一个 activity 的代码地位拆散开来。因为在从新创立过程和 activity 时须要应用后果回调,因而每次创立 activity 时都必须无条件注册回调,即便启动另一个 activity 的逻辑仅基于用户输出内容或其余业务逻辑也是如此。

位于 ComponentActivity 或 Fragment 中时,Activity Result API 会提供 registerForActivityResult() API,用于注册后果回调。registerForActivityResult() 承受 ActivityResultContractActivityResultCallback 作为参数,并返回 ActivityResultLauncher,用来启动另一个 activity
ActivityResultContract 定义生成后果所需的输出类型以及后果的输入类型。这些 API 可为拍照和申请权限等根本 intent 操作提供默认协定。当然也能够创立本人的自定义协定。
ActivityResultCallback 是繁多办法接口,带有 onActivityResult() 办法,可承受 ActivityResultContract 中定义的输入类型的对象:

JAVA 代码
// GetContent creates an ActivityResultLauncher<String> to allow you to pass
// in the mime type you'd like to allow the user to select
ActivityResultLauncher<String> mGetContent = registerForActivityResult(new GetContent(),
    new ActivityResultCallback<Uri>() {
        @Override
        public void onActivityResult(Uri uri) {// Handle the returned Uri}
});

这里的代码看起来很简略,咱们只须要在 registerForActivityResult 的第二个参数中 new 一个 ActivityResultCallback 并重写 onActivityResult 办法即可实现获取用户操作返回的需要。然而目前在 MAUI 中实现并非如此简略,因为 MAUI 中没有定义好的 ActivityResultCallback 类。上面咱们来编写代码。

二、代码编写

1、实现代码

在上文代码的根底上,咱们持续在 MainActivity.cs 增加代码

    public class MainActivity : MauiAppCompatActivity
    {internal static MainActivity Instance { get; private set;}
        internal static ActivityResultLauncher PickMultipleMedia {get; private set;}

        public TaskCompletionSource<Dictionary<string, string>> PickImageTaskCompletionSource {set; get;}
        protected override void OnCreate(Bundle savedInstanceState)
        {
            Instance = this;
            PickMultipleMedia = Instance.RegisterForActivityResult(new ActivityResultContracts.PickMultipleVisualMedia(100), new ActivityResultCallback());
            base.OnCreate(savedInstanceState);
        }

        private class ActivityResultCallback : Java.Lang.Object, IActivityResultCallback
        {public void OnActivityResult(Java.Lang.Object p0)
            {if (!p0.Equals(new Android.Runtime.JavaList()))
                {var list = (Android.Runtime.JavaList)p0;
                    if (!list.IsEmpty)
                    {var uris = list.Cast<Uri>().ToList();

                        var fileList = Instance.GetImageDicFromUris(uris);
                        Instance.PickImageTaskCompletionSource.SetResult(fileList);
                    }
                    else
                    {Instance.PickImageTaskCompletionSource.SetResult(new Dictionary<string, string>());
                    }
                }
            }
        }
    }

咱们创立了一个动态的 ActivityResultLauncher 类型的PickMultipleMedia,并在OnCreate 办法中通过 RegisterForActivityResult 注册,办法第一个参数类型为 ActivityResultContract,咱们设置了 100 个图片的限度,第二个参数是一个IActivityResultCallback 类型的 Callback。因为默认没有提供,咱们须要本人定义。
留神:咱们的 callback 办法在继承 IActivityResultCallback 接口的同时,还必须显示的继承 Java.Lang.Object,否则会报错。
咱们仅需实现 OnActivityResult 办法即可,这里留神,办法的参数为 Java.Lang.Object 类型,有些文章会让咱们将 Java.Lang.Object 强制转换为 ActivityResult 类型,而后再获取其中的文件 Uri,然而通过测试目前在 MAUI 中不可用,转换之后永远为 null。通过屡次尝试后,确定多选照片返回的类型为Android.Runtime.JavaList
我这里通过 !p0.Equals(new Android.Runtime.JavaList()) 判断用户没有抉择任何照片的场景。最初通过遍历,应用之前写好的 GetImageDicFromUris 办法获取所有文件的内容。

2、测试代码

咱们在上文的 IPhotoPickerService.cs 接口中扩大一个 GetImageAsync4 不便咱们对几种实现形式进行比照。

    public class AndroidPhotoPickerService : IPhotoPickerService
    {
        ...
        public Task<Dictionary<string, string>> GetImageAsync4()
        {MainActivity.PickMultipleMedia.Launch(new PickVisualMediaRequest.Builder()
                .SetMediaType(ActivityResultContracts.PickVisualMedia.ImageAndVideo.Instance).Build());
            MainActivity.Instance.PickImageTaskCompletionSource = new TaskCompletionSource<Dictionary<string, string>>();
           
            return MainActivity.Instance.PickImageTaskCompletionSource.Task;
        }
    }

这里应用的办法非常简单,参考下面 JAVA 的写法即可

JAVA 代码
pickMultipleMedia.launch(new PickVisualMediaRequest.Builder()
        .setMediaType(PickVisualMedia.ImageAndVideo.INSTANCE)
        .build());

在 Index.razor 中增加一个 MListItem

<MList>
 ...
       <MListItem OnClick="GetImageAsync4">
               <MListItemContent>
                           <MListItemTitle>Jetpack-PickMultipleVisualMedia</MListItemTitle>
               </MListItemContent>
       </MListItem>
</MList>

三、演示成果

留神界面的变动,这里是以半屏弹出的形式展现的。


如果你对咱们的 MASA Framework 感兴趣,无论是代码奉献、应用、提 Issue,欢送分割咱们

WeChat:MasaStackTechOps
QQ:7424099

正文完
 0