You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Studio中基于ActivityResultLauncher的图片上传实现问题求助

排查ActivityResultLauncher实现图片选择功能的问题

我在Android Studio中实现图片上传功能,由于StartActivityForResult已被弃用,改用ActivityResultLauncher的新方式实现,但功能无法正常运行,以下是我的Java类代码,恳请帮忙排查问题:

package com.example.gas4u;

// 注:代码缺少常量定义(如STORAGE_REQUEST_CODE、CAMERA_REQUEST_CODE)、权限数组定义(storagePermission、cameraPermissions)
// 以及productIconIv、image_uri等变量声明

private void showImagePickDialog() {
    //options to display in dialog
    String[] options = {"Camera","Gallery"};
    //dialog
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle("Pick Image")
            .setItems(options, new DialogInterface.OnClickListener(){
                @Override
                public void onClick(DialogInterface dialog, int which){
                    //handle items clicks
                    if (which == 0){
                        //camera clicked
                        if (checkCameraPermission()){
                            //permission granted
                            pickFromCamera();
                        }
                        else{
                            //permission not granted, request
                            requestCameraPermission();
                        }
                    }
                    else{
                        //gallery clicked
                        if (checkStoragePermission()){
                            //permission granted
                            pickFromGallery();
                        }
                        else{
                            //permission not granted
                            requestStoragePermission();
                        }
                    }
                }
            }).show();
}

// You can do the assignment inside onAttach or onCreate, i.e, before the activity is displayed
ActivityResultLauncher<Intent> someActivityResultLauncher = registerForActivityResult(
        new ActivityResultContracts.StartActivityForResult(),
        new ActivityResultCallback<ActivityResult>() {
            @Override
            public void onActivityResult(ActivityResult result ) {
                if (result.getResultCode() == Activity.RESULT_OK) {
                    // There are no request codes
                    Intent data = result.getData();

                    if (result.getResultCode() == IMAGE_PICK_GALLERY_CODE){
                        //image picked from gallery

                        //save picked image uri
                        image_uri = data.getData();

                        //set image
                        productIconIv.setImageURI(image_uri);
                    }
                    else if (result.getResultCode() == IMAGE_PICK_CAMERA_CODE){
                        //image picked from camera

                        productIconIv.setImageURI(image_uri);
                    }

                }
            }
        });

private void pickFromGallery(){
    //intent to pick image from gallery
    Intent intent = new Intent(Intent.ACTION_PICK);
    intent.setType("image/*");
    someActivityResultLauncher.launch(intent);
    //(intent, IMAGE_PICK_GALLERY_CODE);
}

private void pickFromCamera(){
    //intent to pick image from camera

    //using media store to pick high/original quality image
    ContentValues contentValues = new ContentValues();
    contentValues.put(MediaStore.Images.Media.TITLE, "Temp_Image_Title");
    contentValues.put(MediaStore.Images.Media.DESCRIPTION, "Temp_Image_Description");

    image_uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);

    Intent intent= new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, image_uri);
    someActivityResultLauncher.launch(intent);
    //startActivityForResult(intent, IMAGE_PICK_CAMERA_CODE);
}

private boolean checkStoragePermission(){
    boolean result = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) ==
            (PackageManager.PERMISSION_GRANTED);
    return result; //returns true or false
}

private void requestStoragePermission(){
    ActivityCompat.requestPermissions(this, storagePermission, STORAGE_REQUEST_CODE);
}

private boolean checkCameraPermission(){
    boolean result = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) ==
            (PackageManager.PERMISSION_GRANTED);

    boolean result1 = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) ==
            (PackageManager.PERMISSION_GRANTED);

    return result && result1;
}

private void requestCameraPermission(){
    ActivityCompat.requestPermissions(this, cameraPermissions, CAMERA_REQUEST_CODE);
}


//handle permission results
public void onRequestPermissionResult(int requestCode, @NonNull String[] permission, @NonNull int[] grantResults){
    switch (requestCode){
        case CAMERA_REQUEST_CODE:{
            if (grantResults.length>0){
                boolean cameraAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
                boolean storageAccepted = grantResults[1] == PackageManager.PERMISSION_GRANTED;
                if (cameraAccepted && storageAccepted){
                    //both permission granted
                    pickFromCamera();
                }
                else{
                    //both or one permissions denied
                    Toast.makeText(this, "Camera & Storage permissions are required...", Toast.LENGTH_SHORT).show();
                }
            }
        }
        case STORAGE_REQUEST_CODE:{
            if (grantResults.length>0){
                boolean storageAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
                if (storageAccepted){
                    //permission granted
                    pickFromGallery();
                }else{
                    //permission denied
                    Toast.makeText(this, "Storage permissions is required...", Toast.LENGTH_SHORT).show();
                }
            }
        }
    }
    super.onRequestPermissionsResult(requestCode, permission, grantResults);
}

问题排查与修复方案

1. 核心错误:ActivityResult回调无法区分相机/图库来源

新的ActivityResultLauncher没有请求码,回调中的result.getResultCode()只能是RESULT_OK或RESULT_CANCELED,无法通过它判断是相机还是图库返回的结果。

修复方式:创建两个独立的ActivityResultLauncher,分别处理相机和图库的结果:

// 处理图库选择
ActivityResultLauncher<Intent> galleryLauncher = registerForActivityResult(
        new ActivityResultContracts.StartActivityForResult(),
        result -> {
            if (result.getResultCode() == Activity.RESULT_OK && result.getData() != null) {
                image_uri = result.getData().getData();
                productIconIv.setImageURI(image_uri);
            }
        });

// 处理相机拍摄
ActivityResultLauncher<Intent> cameraLauncher = registerForActivityResult(
        new ActivityResultContracts.StartActivityForResult(),
        result -> {
            if (result.getResultCode() == Activity.RESULT_OK) {
                // 相机拍摄的图片已通过image_uri保存,直接设置即可
                productIconIv.setImageURI(image_uri);
            }
        });

// 修改pickFromGallery方法
private void pickFromGallery(){
    Intent intent = new Intent(Intent.ACTION_PICK);
    intent.setType("image/*");
    galleryLauncher.launch(intent);
}

// 修改pickFromCamera方法
private void pickFromCamera(){
    ContentValues contentValues = new ContentValues();
    contentValues.put(MediaStore.Images.Media.TITLE, "Temp_Image_Title");
    contentValues.put(MediaStore.Images.Media.DESCRIPTION, "Temp_Image_Description");

    image_uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues);

    Intent intent= new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, image_uri);
    cameraLauncher.launch(intent);
}

2. 权限回调方法名拼写错误

原代码中的onRequestPermissionResult少了一个s,正确方法名是onRequestPermissionsResult,这个错误会导致权限申请后的回调逻辑完全不执行,必须修正:

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults){
    switch (requestCode){
        case CAMERA_REQUEST_CODE:{
            if (grantResults.length>0){
                boolean cameraAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
                boolean storageAccepted = grantResults[1] == PackageManager.PERMISSION_GRANTED;
                if (cameraAccepted && storageAccepted){
                    pickFromCamera();
                }
                else{
                    Toast.makeText(this, "Camera & Storage permissions are required...", Toast.LENGTH_SHORT).show();
                }
            }
            break; // 添加break,避免执行后续case
        }
        case STORAGE_REQUEST_CODE:{
            if (grantResults.length>0){
                boolean storageAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
                if (storageAccepted){
                    pickFromGallery();
                }else{
                    Toast.makeText(this, "Storage permission is required...", Toast.LENGTH_SHORT).show();
                }
            }
            break; // 添加break
        }
    }
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}

3. Android 13+权限适配

Android 13及以上版本,WRITE_EXTERNAL_STORAGE权限已被废弃,图库选择需使用READ_MEDIA_IMAGES权限,更新权限判断逻辑:

private boolean checkStoragePermission(){
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        return ContextCompat.checkSelfPermission(this, Manifest.permission.READ_MEDIA_IMAGES) == PackageManager.PERMISSION_GRANTED;
    } else {
        return ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
    }
}

private boolean checkCameraPermission(){
    boolean cameraGranted = ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        return cameraGranted; // Android13+不需要存储权限
    } else {
        boolean storageGranted = ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
        return cameraGranted && storageGranted;
    }
}

同时更新权限数组定义(示例):

private String[] storagePermission;
private String[] cameraPermissions;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        storagePermission = new String[]{Manifest.permission.READ_MEDIA_IMAGES};
        cameraPermissions = new String[]{Manifest.permission.CAMERA};
    } else {
        storagePermission = new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE};
        cameraPermissions = new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE};
    }
}

4. 补充缺失的常量定义

确保代码中定义了所需常量:

private static final int STORAGE_REQUEST_CODE = 100;
private static final int CAMERA_REQUEST_CODE = 200;
// 原代码中的IMAGE_PICK_*_CODE已不再需要,因为使用了独立的Launcher

内容的提问来源于stack exchange,提问作者Osborne

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 19:40:36