Android中startActivityForResult已废弃,如何用registerForActivityResult实现Java版拍照功能
Java 版本 registerForActivityResult 实现相机拍照教程
核心修改逻辑
- 移除原有手动维护的权限、拍照请求码常量,新API会自动管理请求标识
- 注册两个
ActivityResultLauncher作为类成员变量,分别处理相机权限申请结果、拍照返回结果 - 替换原有废弃的权限申请、启动相机方法
完整修改后代码
package com.example.myapplication; import androidx.activity.result.ActivityResultLauncher; import androidx.activity.result.contract.ActivityResultContracts; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import android.Manifest; import android.content.Intent; import android.content.pm.PackageManager; import android.graphics.Bitmap; import android.os.Bundle; import android.provider.MediaStore; import android.view.View; import android.widget.Button; import android.widget.ImageView; import android.widget.RelativeLayout; import android.widget.Toast; import com.google.android.material.snackbar.Snackbar; public class MainActivity extends AppCompatActivity { private Button button; private ImageView image; private RelativeLayout parent; // 注册权限申请回调 private final ActivityResultLauncher<String> permissionLauncher = registerForActivityResult( new ActivityResultContracts.RequestPermission(), isGranted -> { if (isGranted) { // 权限通过,打开相机 openCamera(); Toast.makeText(this, "你已获得相机权限", Toast.LENGTH_SHORT).show(); } else { // 权限被拒绝 Toast.makeText(this, "相机权限被拒绝,无法拍照", Toast.LENGTH_SHORT).show(); } } ); // 注册拍照结果回调 private final ActivityResultLauncher<Intent> takePhotoLauncher = registerForActivityResult( new ActivityResultContracts.StartActivityForResult(), result -> { if (result.getResultCode() == RESULT_OK && result.getData() != null) { // 拿到拍照缩略图,设置到ImageView Bitmap bitmap = (Bitmap) result.getData().getExtras().get("data"); image.setImageBitmap(bitmap); } } ); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); button = findViewById(R.id.button); image = findViewById(R.id.image); parent = findViewById(R.id.parent); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { handlePermission(); } }); } private void handlePermission() { if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) { openCamera(); Toast.makeText(this, "你有相机使用权限", Toast.LENGTH_SHORT).show(); } else { if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) { showSnackBar(); } else { // 直接调用权限launcher发起申请,替换原有requestPermissions方法 permissionLauncher.launch(Manifest.permission.CAMERA); } } } private void showSnackBar() { Snackbar.make(parent, "需要相机权限才能完成拍照", Snackbar.LENGTH_INDEFINITE) .setAction("去授权", v -> permissionLauncher.launch(Manifest.permission.CAMERA)) .show(); } private void openCamera() { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); // 调用拍照launcher启动相机,替换原有startActivityForResult方法 takePhotoLauncher.launch(intent); } }
注意事项
registerForActivityResult必须在Activity的onStart生命周期前完成注册,因此需要定义为类成员变量,或者在onCreate方法中执行注册逻辑,不可以在点击事件等异步场景中注册- 上述代码拿到的是相机返回的缩略图,如果需要获取高清原图,需要额外传入图片保存路径到拍照Intent中,对应调整Contract逻辑即可
内容的提问来源于stack exchange,提问作者Chris Ray
相关产品推荐
相关产品推荐

