添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

本篇文章介绍下如何使用 Activity Result API 实现拍照以及选择手机中的图片。

在之前的文章中提到过, ActivityResutlContract 已经有一些官方实现好的默认合约,其中就包含了两个拍照相关的合约 TakePicture TakePicturePreview ,二者都可以实现拍照功能。

TakePicture

TakePicture 合约需要传入保存照片文件的Uri,因此需要使用 FileProvider ,通过 TakePicture 合约实现拍照代码如下:

//在res文件夹下新建xml资源文件夹,并新建file_path.xml资源文件
<?xml version="1.0" encoding="utf-8"?>
<paths>
    <files-path
        name="images"
        path="." />
    <cache-path
        name="cache-path"
        path="." />
    <external-path
        name="external_storage_root"
        path="." />
    <external-cache-path
        name="external_cache_path"
        path="." />
</paths>
//在Manifest中配置FileProvider
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
    <application>
        <provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="${applicationId}.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_path" />
        </provider>
    </application>
</manifest>
class PhotoActivity : AppCompatActivity() {
    private lateinit var binding: LayoutPhotoActivityBinding
    private var photoUri: Uri? = null
    private val takePicture =
        registerForActivityResult(ActivityResultContracts.TakePicture()) { success ->
            if (success) {
                photoUri?.let {
                    binding.ivPhoto.setImageURI(it)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.layout_photo_activity)
        photoUri = getPhotoFileUri()
        binding.btnTakePhoto.setOnClickListener {
            takePicture.launch(photoUri)
    //获取保存照片的Uri
    private fun getPhotoFileUri(): Uri? {
        val storageFile: File? =
            if (Environment.MEDIA_MOUNTED == Environment.getExternalStorageState()) {
                externalCacheDir
            } else {
                cacheDir
        val photoFile = File.createTempFile("tmp_image_file", ".png", storageFile).apply {
            createNewFile()
            deleteOnExit()
        val fileProviderUri = FileProvider.getUriForFile(this, "${BuildConfig.APPLICATION_ID}.provider", photoFile)
        return fileProviderUri

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zfIYynZe-1653555168217)(https://p3-juejin.byteimg.com/tos-cn-i-k3u1fbpfcp/13ff7f22a09b4535870ba912c90c0a8c~tplv-k3u1fbpfcp-zoom-in-crop-mark:1956:0:0:0.image?)]

TakePicturePreview

通过TakePicturePreview合约实现拍照代码如下:

class PhotoActivity : AppCompatActivity() {
    private lateinit var binding: LayoutPhotoActivityBinding
    private val takePicturePreview =
        registerForActivityResult(ActivityResultContracts.TakePicturePreview()) { photoPreview ->
            //该合约返回的是Bitmap,如需保存要进行额外的处理
            binding.ivPhoto.setImageBitmap(photoPreview)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.layout_photo_activity)
        binding.btnTakePhotoPreview.setOnClickListener {
            takePicturePreview.launch(null)

实现选择图片

ActivityResutlContract官方实现好的默认合约中,GetContentGetMultipleContents可以用来获取手机中的资源,因此可以使用这两个合约来获取手机中的图片。

GetContent

通过GetContent合约实现选择单张照片代码如下:

class PhotoActivity : AppCompatActivity() {
    private lateinit var binding: LayoutPhotoActivityBinding
    private val selectPhoto =
        registerForActivityResult(ActivityResultContracts.GetContent()) { uri ->
            binding.ivPhoto.setImageURI(uri)
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.layout_photo_activity)
        binding.btnSelectPhoto.setOnClickListener {
            //传入的参数就是你想要选择的资源类型
            selectPhoto.launch("image/*")

GetMultipleContents

通过GetMultipleContents合约实现选择多张照片代码如下:

class PhotoActivity : AppCompatActivity() {
    private lateinit var binding: LayoutPhotoActivityBinding
    private val selectMultiplePhoto =
        registerForActivityResult(ActivityResultContracts.GetMultipleContents()) { uriList ->
            if (uriList.size > 1) {
                binding.ivPhoto.setImageURI(uriList[0])
                binding.ivPhoto1.setImageURI(uriList[1])
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        binding = DataBindingUtil.setContentView(this, R.layout.layout_photo_activity)
        binding.btnSelectMultiplePhoto.setOnClickListener {
            //传入的参数就是你想要选择的资源类型
            selectMultiplePhoto.launch("image/*")
                    本篇文章介绍下如何使用Activity Result API 实现拍照以及选择手机中的图片。实现拍照在之前的文章中提到过,ActivityResutlContract已经有一些官方实现好的默认合约,其中就包含了两个拍照相关的合约TakePicture和TakePicturePreview,二者都可以实现拍照功能。TakePictureTakePicture合约需要传入保存照片文件的Uri,因此需要使用FileProvider,通过TakePicture合约实现拍照代码如下://在res文件夹下新建
				
提示:ActivityResultLauncher必须在onCreate或者onAttach方法下初始化 一、ActivityResultContract 示例:由android提供的一些标准活动调用契约的集合。 StartActivityForResult 使用Intent在activity(fragment)间通信,返回ActivityResult StartIntentSenderForResult 使用IntentSenderRequest. builder构造,可以返回带有activity的Ac
Camera preview by placing it in a layout XML (and calling the start method) Configuration by attributes As... 布局文件: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.c
文章目录Android Activity Results API使用startActivityForResult问题自定义ActivityResultContract定义协议注册协议跳转系统内置ActivityResultContractStartActivityFoResultRequestPermissionRequestMultiplePermissionsTakePicturePreviewPickContact源码下载 Android Activity Results API使用 startAct
Android 中,我们如果想在 Activity 之间双向传递数据,需要使用 startActivityForResult 启动,然后在 onActivityResult 中处理返回,另外申请权限也是类似的步骤。 但是这样的处理方式会让我们的代码变得非常复杂,并且也无法保证在 Activity 发送或接收数据时参数的类型安全。 ActivityResult 是 Jetpack 提供的一个功能,可以简化 Activity 直接的数据传递 (包括权限申请)。它通过提供类型安全的 contract (协定)
Android ActivityResult 介绍 ActivityResult APIandroidx.activity:activity 包引入的新 API,用来替代原有的 onActivityResult 获取上一个 Activity 返回的结果。 被废弃的 startActivityForResult 和 onActivityResult startActivityForResult 从 ComponentActivity 的 startActivityForResult 方法 @Deprec
今天打开 Typora 写作时,发现这款陪伴自己多年的工具终于发布了正式版本且以购买序列号的形式落地产品变现,毫无迟疑,第一时间购买序列号支持,付费是对产品和知识的助力,用爱发电很难持续,希望开发这款工具的开发者伴随工具越来越好。 启动另一个 activity(无论是应用中的 activity 还是其他应用中的 activity)不一定是单向操作。很多场景下,我们启动另一个 activity 是为了接收返回的结果。例如,应用可启动相机应用并接收拍摄的照片作为结果。在过去的很长一段时间里,开发者皆是.
Intent intent = new Intent(); intent.setType("image/*"); intent.setAction(Intent.ACTION_GET_CONTENT); activity.startActivityForResult(intent, GET_IMAGE...
Activity Result APIAndroid操作系统提供的一种机制,用于在应用程序组件之间传递数据和结果。当一个Activity启动另一个Activity时,第一个Activity可以通过调用startActivityForResult()方法传递请求码和数据。第二个Activity完成任务后,会返回结果给第一个Activity,并将结果数据放在Intent对象中,通过调用setResult()方法设置返回结果和响应码。第一个Activity在onActivityResult()方法中接收返回的数据和结果,并根据需要进行处理。这种机制使得应用程序组件之间的交互更加灵活和方便。