Android - Activity Result API

安卓Android开发:以ActivityResultLauncher方式进行页面跳转、传递参数、拍照或选择文件,以及调用系统应用打开各种类型的指定文件 ActivityResultLauncher是安卓官方推荐的用来替代startActivityForResult的新方式。通过它可以非常方便地调用系统Intent进行拍照,或是选取本地的文件。 本文共分为5个章节 : 一、定义ActivityResultLauncher 二、注册Launcher 三、调用系统Intent 四、使用FileProvider复制一份文件 五、使用系统应用打开各种类型的指定文件 一、定义ActivityResultLauncher 在需要调用系统Intent. 阅读详情

一、概念

当 appcompat ≥ 1.3.0 的时候,startActivityForResult() 和 requestPermissions() 都已经被废弃,转而推荐更方便简洁的 Activity Result API。

registerForActivityResult( )

public final <I, O> ActivityResultLauncher<I> registerForActivityResult(
    @NonNull ActivityResultContract<I, O> contract,
    @NonNull ActivityResultCallback<O> callback) {
        return registerForActivityResult(contract, mActivityResultRegistry, callback);
} 

注册一个Activity结果的监听,参数一contract类型对应不同的需求,参数二是一个Lambda当有回调的时候会显示在这里。

Contract名称及作用
StartActivityForResult()开启Activity
StartIntentSenderForResult()
RequestPermission()申请权限。
RequestMultiplePermissions()申请多个权限。
TakePicturePreview()调用手机自带相机拍照,拍摄后有确认和重拍选项,确认后得到这张照片的Bitmap对象。
TakePicture()调用手机自带相机拍照,拍摄后有确认和重拍选项,确认后保存到指定的 Uri,返回true表示保存成功。
TakeVideo()调用系统自带相机录像,保存到指定的Uri,返回一张缩略图。
PickContact()从通讯录APP中获取联系人。
GetContent()选择一个内容,返回Uri。
GetMultipleContents()选择多个内容,返回多个Uri。
OpenDocument()选择一个文件,返回Uri。
OpenMultipleDocuments()选择多个文件,返回多个Uri。
OpenDocumentTree()选择一个目录(文件夹),返回Uri。
CreateDocument()创建一个文件,返回Uir。
PickVisualMedia()通过系统媒体选择器选择单张图片/视频(Android 13新增,11(API33)及以上可用)
PickMultipleVisualMedia()通过系统媒体选择器选择多张图片/视频(Android 13新增,11(API33)及以上可用)

二、使用

2.1 Activity之间传递数据 StartActivityForResult()

2.1.1 A→B 原来写法

class FirstActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        val intent = Intent(this, SecondActivity::class.java)
        startActivityForResult(intent, 1)
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        when (requestCode) {
            1 -> {
                if (resultCode == RESULT_OK) {
                    val data = data?.getStringExtra("data")
                    // Handle data from SecondActivity
                }
            }
        }
    }
}

2.1.2 A→B 现在写法

class FirstActivity : AppCompatActivity() {
    private val requestDataLauncher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
        if (result.resultCode == RESULT_OK) {
            val data = result.data?.getStringExtra("data")
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        val intent = Intent(this, SecondActivity::class.java)
        requestDataLauncher.launch(intent)
    }
}

2.1.3 B→A 写法没变

class SecondActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        val intent = Intent()
        setResult(RESULT_OK, intent)
        finish()
    }
}

2.2 请求权限

建议使用 PermissionX

2.2.1 单个权限 RequestPermission()

class MyActivity : AppCompatActivity() {
    private val permissionLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
        if (isGranted) {
            takePic()
        } else {
            Toast.makeText(APP.context, "相机权限被拒绝", Toast.LENGTH_SHORT).show()
        }
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        button.setOnClickListener {
            permissionLauncher.launch(Manifest.permission.CAMERA)
        }
        //判断是否有权限
        if (ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED) {}
        //是否显示权限说明(只有第一次点拒绝后才会返回true)
        if ( shouldShowRequestPermissionRationale(Manifest.permission.CAMERA) ) {}
    }
}

2.2.2 多个权限 RequestMultiplePermissions()

class MainActivity : AppCompatActivity() {
	private val requestMultiplePermissions = registerForActivityResult(
		ActivityResultContracts.RequestMultiplePermissions()
	) { permissions ->  //类型是 Map<String, Boolean>
		permissions.entries.forEach {
			//TODO...
		}
	}
	override fun onCreate(savedInstanceState: Bundle?) {
		requestMultiplePermissions.launch(
			arrayOf(
				Manifest.permission.BLUETOOTH,
				Manifest.permission.NFC,
			)
		)
	}
}

2.3 文件操作

2.3.1 获取文件 GetContent()

class MainActivity : AppCompatActivity() {
    private val requestUriLauncher = registerForActivityResult(ActivityResultContracts.GetContent()) { uri ->
        if(uri != null) {
            //将uri转为输入流来读取文件
            val inputStream = contentResolver.openInputStream(uri)
        }
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        requestUriLauncher.launch("image/*")    //只显示图片
    }
}

2.3.2 写入文件 CreateDocument()

class MainActivity : AppCompatActivity() {
    private val createDocument = registerForActivityResult(ActivityResultContracts.CreateDocument("text/plain")) { uri ->
        if (uri != null) {
            //将uri转为输出流来写入文件
            val outputStream = contentResolver.openOutputStream(uri)
        }
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        createDocument.launch("demo.txt")
    }
}

2.3.3 选择目录(选择文件夹) OpenDocumentTree()

class TestActivity : AppCompatActivity() {
    private val openTree = registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) { uri ->
        //uri转File后使用
        uri?.path?.let {
            val directory = File(it)
        }
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        openTree.launch(null)   //可传入默认目录uri
    }
}

2.4 拍照并获取Bitmap TakePicturePreview()

class MainActivity : AppCompatActivity() {
    private val takePictureLauncher = registerForActivityResult(ActivityResultContracts.TakePicturePreview()) { bitmap ->
        //TODO...
    }
    override fun onCreate(savedInstanceState: Bundle?) {
        takePictureLauncher.launch(null)
    }
}

2.5 通过系统媒体选择器选取图片/视频

Android 13 之前还是通过应用内置的图片选择器来实现业务功能,13 之后的版本仅使用系统内置的图片选择器,完全弃用 READ_EXTERNAL_STORAGE 权限。

private val pickMedia = registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { uri ->
    if (uri != null) {
        //TODO
    }
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_result)

    //选择图片或视频
    pickMedia.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageAndVideo))

    //仅选择图片
    pickMedia.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.ImageOnly))

    //仅选择视频
    pickMedia.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.VideoOnly))

    //仅选择 Gif 图片
    pickMedia.launch(PickVisualMediaRequest(ActivityResultContracts.PickVisualMedia.SingleMimeType("image/gif")))

}

三、自定义 Contract

继承 ActivityResultContract 类,指定输入参数和输出参数的泛型,重写 createIntent() 用于创建 Intent 发起动作,重写 parseResult() 用于解析响应的结果并作为输出参数返回到 Lambda 中。

class GetDataFromSecondActivity : ActivityResultContract<Void, String?>() {
    override fun createIntent(context: Context, input: Void?): Intent {
        return Intent(context, SecondActivity::class.java)
    }

    override fun parseResult(resultCode: Int, intent: Intent?): String? {
        if (resultCode == Activity.RESULT_OK) {
            if (intent != null) {
                return intent.getStringExtra("data")
            }
        }
        return null
    }
}
class MainActivity : AppCompatActivity() {
    private val getDataLauncher = registerForActivityResult(GetDataFromSecondActivity()) { data ->
        //TODO...
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        getDataLauncher.launch(null)
    }
}

`Android`优雅的封装`ActivityResultLauncher`启动活动和请求权限,外加处理意外被`kill`情况 Android优雅的封装ActivityResultLauncher启动活动和请求权限 一般我们在请求权限或者处理Activity返回结果的时候都会使用Activity#onActivityResult()和Activity#onRequestPermissionResult()这俩个方法,如今谷歌已经提供了新的请求方法:https://developer.android.com/training/permissions/requesting?hl=zh-cn。 这篇文章是解决什么的? 我想把每个处理结 阅读详情

相关推荐

Android13适配-Google官方照片视频选择器

照片选择器提供了一个直观的界面,便于与您的应用分享照片。照片选择器的界面可供浏览和搜索,并按日期降序向用户显示其媒体库中的文件。如中所示,照片选择器为用户提供了一种安全的内置授权方式,让用户可以仅向应用授予对所选图片和视频的访问权限,而不是对整个媒体库的访问权限。该工具会自动更新,让应用用户能够长期使用扩展的功能,而无需更改任何代码。

yzwfeng的专栏 5417

ActivityResultLauncher获取Activity返回数据

ActivityResultLauncher(活动结果启动器)是 Android 中用于启动活动并接收结果的新 API。它是在 AndroidX 框架中引入的,用于简化之前使用startActivityForResult()方法的流程。 在使用 ActivityResultLauncher之前,你需要选择适当的合同(contract),例如 StartActivityForResult 合同,然后通过registerForActivityResult()方法创建一个ActivityResultLaun

m0_57150356的博客 2807

告别繁琐的onActivityResult!Android Activity Result API完全指南

Android开发中,Activity Result API提供了一种更优雅的解决方案,替代传统的startActivityForResult()和onActivityResult()方法。该API通过ActivityResultLauncher、ActivityResultContract和ActivityResultRegistry等核心组件,解决了代码耦合、类型不安全、生命周期问题等痛点。内置合约覆盖了90%的常用场景,包括权限请求、拍照、文件选择等功能。开发者还可以通过自定义合约满足特定需求。相比传

dongdeaiziji的专栏 1166

【Android Studio】ActivityResultLauncher

ActivityResultLauncher是Android Studio用于在应用程序中启动活动并接收其结果的组件,它是startActivityForResult的改进版本。优点:类型安全:结果处理逻辑和启动器绑定在一起,避免传统方法中可能出现的类型转换错误。解耦:不需要重写onActivityResult(),逻辑更加清晰。生命周期感知:启动器与生命周期相关联,在适当的时间注册和取消注册。这种方法的好处是,它使用了Android Jetpack中的。

weixin_73595045的博客 3944

Android Activity数据回调:从startActivityForResult到Activity Result API

在Android应用开发中,组件间通信是构建交互式应用的基础。其核心原理基于Intent机制,通过封装操作请求和数据,实现Activity间的解耦通信。这项技术的核心价值在于建立了清晰的“请求-响应”模型,使得数据能在不同界面间可控地双向流动,是处理用户选择、表单提交等场景的标准方案。典型的应用场景包括从商品详情页返回用户选择至列表页,或从设置页面带回配置信息。本文聚焦于通过startActivityForResult与onActivityResult的传统实现,并详解如何利用Parcelable接口高效传

weixin_32447969的博客 240

Android MVVM框架搭建(十)Hilt、ViewBinding、Activity Result API

ViewBinding是Android Studio 3.6推出的新特性,目的是为了替代findViewById(内部实现还是使用findViewById)。。在启动视图绑定后,系统会为改模块中的每个xml文件生成一个绑定类,绑定类的实例包含对在相应布局中具有 ID 的所有视图的直接引用。View Binding 的优点Null 安全:由于视图绑定会创建对视图的直接引用,因此不存在因视图 ID 无效而引发 Null 指针异常的风险。

2401_84009065的博客 1364

Android Activity Result API - Activity Result API 基础(概述、核心组件、常用 ActivityResultContract、实例实操)

Android Activity Result API - Activity Result API 基础(概述、核心组件、常用 ActivityResultContract、实例实操)

weixin_52173250的博客 911

Android 新权限申请模型(Activity Result API)

Android权限请求新方式采用"回调注册前置+生命周期感知"模式,通过registerForActivityResult注册请求类型和回调函数,返回一个ActivityResultLauncher发射器。使用时先检查权限,未授权则调用launcher.launch()发起请求,系统自动回调结果。相比旧方式,新模式解决了生命周期不安全、requestCode混乱等问题,具有类型安全、解耦和逻辑清晰等优势。多权限请求使用RequestMultiplePermissions(),回调接收权限

2401_87663701的博客 395

Activity Result API 入门:Android 新版 Activity 返回结果机制详解

本文介绍了Android中Activity之间通信的新方案Activity Result API,它替代了已被弃用的startActivityForResult()方法。新API的核心组件包括Launcher(负责启动操作)、Contract(定义输入输出类型)和回调函数。通过registerForActivityResult()在onCreate中注册Launcher,可以更清晰地将结果处理逻辑与启动代码放在一起,避免集中处理的混乱。文章详细说明了如何启动目标Activity、返回结果以及处理回调数据,并

qq_51061394的博客 163

手把手教你用Foobar2000播放DSD音频(含DOP设置与SPDIF输出教程)

本文详细指导如何在Foobar2000中播放DSD音频,重点解析了DOP协议的原理与设置方法。通过安装SACD插件、配置输出设备及启用DOP模式,实现DSD音频的原生比特流输出,并特别讲解了如何通过SPDIF接口传输DSD信号,帮助发烧友充分释放高清音频设备的潜力。

weixin_29290963的博客 1821

已过tiktok校招客户端,面经分享

面试的话, 一天面完3面, 效率很高, 三天之后就发了offer 字节邮件里面也说了不能泄露面试题, 那我就把我秋招参与美团,字节,腾讯,阿里面试被问到的全部问题总结着写出来了, 这其实是我每一轮面试完之后我都会总结哪里答对了, 哪里没有答对, 总结了一大堆问题出来. 答案未必正确, 我只是给自己写了个简单的一句话概括, 可能不够完善, 建议看官自行回答一下这些问题 二本非科班, 暑假在字节实习过, 不过不是tiktok部门, 因此秋招就没啥时间准备面试了, 只投了几个大厂, 顺便也在字节跨部门转正,

a1472750149的博客 1307

Android Activity Result API

自定义Contract需要继承自ActivityResultContract,其中I是输入的类型,O是输出的类型,并实现2个方法:createIntent和parseResult,输入类型I作为createIntent方法的参数,输出类型O作为parseResult方法的返回值。使用Activity Result API完全移除了对onActivityResult()方法的重写,而是通过调用registerForActivityResult()方法注册了一个对Activity结果的监听。

zenmela2011的专栏 1253

WSL 运行make提示/lib/modules/xxx/build: No such file or directory. Stop.错误解决办法

WSL运行make提示/lib//modules/xxx文件或目录不存在。 WSL2的内核是修改过的,无法使用 ubuntu上游的内核头文件和modules文件,因此,我们需要手动编译并安装一个版本。

weixin_45668903的博客 1万+

Android Activity Result API使用

在Android开发中时常需要用到跳转新页面获取结果回传数据,一直以来使用的方法就是startActivityForResult和onActivityResult两个方法,但是startActivityForResult方法却已经被deprecation,官方推荐使用ActivityResultAPI。......

yuantian_shenhai的博客 1674

从注册到投稿:一步步教你完成KBS期刊的在线投稿流程(最新版)

本文详细介绍了如何完成KBS期刊的在线投稿流程,从账号注册到最终提交的全过程。特别针对初次使用Elsevier投稿系统的研究者,提供最新版系统的操作指南,包括投稿要求、文件格式、作者信息管理等关键步骤,帮助研究者顺利投稿至这一人工智能领域的知名期刊。

egg99的博客 1598

成本会计(第九版)王忠孝课后习题答案解析

在掌握了基础知识之后,我们还需要培养自己的实际操作能力。此外,在学习过程中,遇到困难时,要及时向老师、同学请教,不要害怕暴露自己的不足。三人行,必有我师,每个人都有值得学习的地方。首先,我们需要认真阅读教材,把基础知识掌握牢固。在这里,我建议大家使用《成本会计(第九版)》的配套练习册,这样可以帮助我们检查学习效果。同时,网上的一些优质课程和论坛也是不错的学习资源,例如网易云课堂、中国大学MOOC等。别担心,这里我给大家推荐一些实用的学习资料和方法,帮助你更好地掌握这门课程。出版社: 大连理工大学出版社。

weixin_58833001的博客 1888

Android Activity Result API 使用

1.在app下的build.gradle引入: implementation 'androidx.activity:activity:1.2.0-beta01' implementation 'androidx.fragment:fragment:1.3.0-beta01' 2.页面普通跳转(原startActivityForResult) (1)第一个页面: class MainActivity : AppCompatActivity() { private lateinit var text

一只程序菜鸡的博客 1456

R语言:基于Spatstat包的单变量和双变量平面Ripley‘s K函数分析

因为网上查找得到的R语言K函数分析的资料很少,Spatstat包的介绍也很少,所以抛砖引玉。本文简单介绍了使用R语言spatstat包的Kest,Kcross(Lcross)和Kinhom方法进行了单变量和双变量平面Ripley's K函数分析的方法及代码,希望有所帮助。

hsdcmax的博客 1万+

Activity: 三、Android Result API

Android Result API, startActivityForResult过时, 替代方案; 源码分析

孟老板的博客 794

R语言层次聚类(hierarchical clustering):数据缩放、PCA聚类结果可视化、fpc包的clusterboot函数通过bootstrap重采样的方法评估hclust层次聚类的稳定性

R语言层次聚类(hierarchical clustering):数据缩放、PCA聚类结果可视化、fpc包的clusterboot函数通过bootstrap重采样的方法评估hclust层次聚类的稳定性

data+scenario+science+insight 835

微信文件自动归档!手把手教你用OpenClaw搭个自己的“数字员工”,告别重复劳动

很多人说“AI是未来”,但未来不是靠喊口号的。OpenClaw的真正价值,是让你把重复劳动交出去,把时间留给真正需要创造力的事。这事真能干,而且不难。下载OpenClaw(GitHub仓库按我写的步骤跑一遍遇到坑,评论区留言——我亲自帮你看作者后记:上周五,我让AI自动归档了文件后,终于在5点准时下班。回家路上,我给它发了条消息:“干得漂亮”。它没回,但我知道——它在默默等我的下一条指令。

2601_94871597的博客 413

Android开发笔记:使用Activity Result API 清爽地请求权限 和 启动Activity

虽然所有 API 级别的 Activity 类均提供底层 startActivityForResult() 和 onActivityResult() API,但我们强烈建议您使用 AndroidX Activity 和 Fragment 中引入的 Activity Result API。Activity Result API 提供了用于注册结果、启动结果以及在系统分派结果后对其进行处理的组件。由于该API强大的灵活性,因此我们需要学习使用该API处理权限申请,结果回调等操作。

Tai_Monster的博客 4422

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

Activity Result API 动态申请Android权限

通常我们启动另一个Activity并不是单向操作的,我们往往会启动另外一个Activity以获取结果。如打开相机拍照获取照片。而在之中,Activity Results API 是 Google官方推荐的Activity、Fragment获取返回结果的方式。相当于原startActivityForResult和 onActivityResult方法。Activity Result API 是Androidx 提供用于注册结果、启动结果以及在系统分派结果后对其进行处理的组件。因此,我们对权限的动态申请也属于其

Android_XG的博客 1368

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

Blog #155: Activity Result API(新式结果回调)

/ 自定义Contract: 输入Device ID,输出Device对象>() {): Device?intent?// 使用自定义Contractdevice?.let {// 直接得到Device对象,类型安全Toast.makeText(this, "设备已更新:${itname// 更新设备信息// EditDeviceActivity返回结果finish()

时代我西的博客 689

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

Activity Result API 使用与源码分析,安卓移动开发实训报告

6.在其它类中接收Activity的结果 需要通过实现LifecycleObserver来实现协定的注册和启动器启动。 Activity注册这个观察者 var myLifecycleObserver=MyLifecycleObserver(registry = activityResultRegistry) lifecycle.addObserver(myLifecycleObserver) 调用 myLifecycleObserver.selectImage() 实现DefaultLifecycleObs

m0_66144992的博客 371
上一篇: Android - 大纲
下一篇: Android 应用框架指南
Jomurphys
博客等级 码龄9年 1768粉丝 261原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值