IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> Android 使用 ActivityResult 处理 Activity 之间的数据通信及调起拍照实例 -> 正文阅读

[移动开发]Android 使用 ActivityResult 处理 Activity 之间的数据通信及调起拍照实例

在 Android 中,我们如果想在 Activity 之间双向传递数据,需要使用 startActivityForResult 启动,然后在 onActivityResult 中处理返回,另外申请权限也是类似的步骤。
但是这样的处理方式会让我们的代码变得非常复杂,并且也无法保证在 Activity 发送或接收数据时参数的类型安全。
ActivityResult 是 Jetpack 提供的一个功能,可以简化 Activity 直接的数据传递 (包括权限申请)。它通过提供类型安全的 contract (协定) 来简化处理来自 Activity 的数据。这些协定为一些常见操作 (比如: 拍照或请求权限) 定义了预期的输入和输出类型,除此之外您还能够自定义协定来满足不同场景的需求。
ActivityResult API 提供了一些组件用于注册 Activity 的处理结果、发起请求以及在系统返回结果后立即进行相应处理。您也可以在启动 Activity 的地方使用一个独立的类接收返回结果,这样依然能够保证类型安全。

一、ActivityResult 使用

使用 ActivityResult 先添加依赖:

dependencies {
  // 在 https://developer.android.google.cn/jetpack/androidx/releases/activity 获得最新版本号
  def activity_version = "1.2.0"
  // 在 https://developer.android.google.cn/jetpack/androidx/releases/fragment 获得最新版本号
  def fragment_version = "1.3.0"

  implementation "androidx.activity:activity:$activity_version"
  implementation "androidx.fragment:fragment:$fragment_version”
}

然后先看看最简单的使用方式,比如打开系统文件管理器选择一个图片,代码如下:

val getContent = registerForActivityResult(GetContent()) { uri: Uri? ->
    // 处理返回的 Uri
}

getContent.launch("image/*") //过滤图片

这里涉及几个重要的类和函数:

(1) registerForActivityResult: 是 ComponentActivity 的一个函数,注意这里的 ComponentActivity 是 androidx.activity.ComponentActivity 而不是 androidx.core.app.ComponentActivity,androidx.core 中的对应类 (截止 1.3.0) 还不支持这项功能。

public final <I, O> ActivityResultLauncher<I> registerForActivityResult(
            @NonNull ActivityResultContract<I, O> contract,
            @NonNull ActivityResultCallback<O> callback)

可以看到这个函数接收两个参数,分别是 ActivityResultContract 和回调 ActivityResultCallback,ActivityResultContract 是封装启动所需要的各项参数 (组成 Intent,后面会细说)。函数返回 ActivityResultLauncher,可以看到后面通过他的 launch 函数就可以启动 activity。

(2) GetContent: ActivityResultContracts.GetContent 类是一个继承 ActivityResultContract 的具体实现类,封装了调用系统文件管理器的功能。Jetpack 提供了一些常用的 ActivityResultContract,比如选取图片,拍照等等,如果我们需要拉起自己的 Activity,就需要自定义一个 ActivityResultContract。

(3) launch: ActivityResultLauncher 的函数,启动 activity,代替了之前的 startActivity。

二、在 Jetpack 提供的已封装好的 ActivityResultContract 有 (都是 ActivityResultContracts 的子类):

(1) StartActivityForResult:

最简单的,相当于传统方式的 startActivityForResult,只不过将 onActivityResult 的几个参数封装成一个 ActivityResult。

(2) StartIntentSenderForResult:

相当于 Activity.startIntentSender(IntentSender, Intent, int, int, int),与 PendingIntent 配合使用。

(3) RequestMultiplePermissions:

用于批量申请权限。以 Map 形式返回每个权限的情况。

(4) RequestPermission

申请单个权限,通过这两个来申请权限就可以很方便的进行后续处理。

(5) TakePicturePreview

拉起拍照预览,直接返回 bitmap 数据。(跟传统方式一样,这个 bitmap 只是一个图片预览,因为 intent 中不能传输过大的数据) 。
注意虽然输入是 Void,但是执行 ActivityResultLauncher 的 lanch 函数是还需要传入一个 null 才行。

(6) TakePicture

拉起拍照,输入图片要保存的位置 uri

(7) TakeVideo

录制视频,输入视频要保存的位置 uri,返回视频的缩略图

(8) PickContact

选取联系人

(9) GetContent

获取单个文件,输入过滤类型,返回文件 uri

(10) GetMultipleContents

文件多选,同上

(11) OpenDocument

打开单个文档 (拉起的是系统文档管理器)
对应 Intent.ACTION_OPEN_DOCUMENT,输入的是类型过滤 (如 image/*),输出 uri

(12) OpenMultipleDocuments

打开多个文档,与上面类似

(13) OpenDocumentTree

打开文档 tree,对应 Intent.ACTION_OPEN_DOCUMENT_TREE

(14) CreateDocument

新建一个文档,对应 Intent.ACTION_CREATE_DOCUMENT

可以看到 Android 已经将常用的功能都封装了,基本可以满足我们的开发使用。

三、使用TakePicture调起拍照实例

代码:MainActivity.kt

class MainActivity : AppCompatActivity() {

    private lateinit var mImageView: ImageView
    private lateinit var mImageView1: ImageView
    private var mUri: Uri? = null
    private var mTextView: TextView? = null

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        mImageView = findViewById(R.id.image)
        mImageView1 = findViewById(R.id.image1)
        mTextView = findViewById(R.id.tx)
        Glide.with(this).load("/storage/emulated/0/Android/data/com.example.myapplication/cache.jpg").into(mImageView1)
        mUri = FileProvider.getUriForFile(
            this, applicationContext.packageName + ".fileprovider",
            File(externalCacheDir!!.absolutePath + ".jpg")
        )
        findViewById<Button>(R.id.button).setOnClickListener {
            mTakePicture.launch(mUri)
        }
    }

    private val mTakePicture = registerForActivityResult(ActivityResultContracts.TakePicture()) {
        if (it) {
            try {
                val bmp = MediaStore.Images.Media.getBitmap(
                    contentResolver,
                    Uri.fromFile(File(mUri?.path.toString().substring(5)))
                )
                mImageView.setImageBitmap(bmp)
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
    }
}

代码说明:
1、代码中有一个mImageView和一个mImageView1,在mTakePicture代码块中,如果直接使用Glide.with(this).load方式加载图片至mImageView,没图片时会成功,有图片后,会出现图片不更新,不是刚所拍照片,是因为直接使用uri会有缓存的原因。故使用Bitmap方式去加载图片。
2、之所以mUri?.path需要substring(5),因为mUri?.path的路径为(/root/storage/emulated/0/Android/data/com.example.myapplication/cache.jpg),多了一个/root,导致读取不到照片,所以需要将其处理一下。
3、实现此实例还需要申请读写权限:

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

4、需要在AndroidManifest.xml中加入:

       <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="com.example.myapplication.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true"
            >
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>
  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2021-10-22 11:03:19  更:2021-10-22 11:04:13 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 1:10:03-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码