安卓获取图片(相机拍摄/相册选择)

发布于:2025-07-01 ⋅ 阅读:(20) ⋅ 点赞:(0)

1、在项目res中的xml目录(没有的话新建一个就行)中新建file_path_my.xml

<?xml version="1.0" encoding="utf-8"?>
<paths>

    <external-path
        name="external"
        path="." />
    <external-files-path
        name="external_files"
        path="." />
    <cache-path
        name="cache"
        path="." />
    <external-cache-path
        name="external_cache"
        path="." />
    <files-path
        name="files"
        path="." />
    <external-files-path name="my_images" path="Pictures/" />

</paths>

2、在AndroidManifast.xml中静态申请相机权限,创建FileProvider

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

<uses-feature
     android:name="android.hardware.camera"
     android:required="false" />  <!--申明是否必须拥有相机的设备才能安装本应用-->

<queries>
     <intent>
           <action android:name="android.media.action.IMAGE_CAPTURE" />
     </intent>
</queries>

<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_my" />
        </provider>

</application>

3.写一个弹窗用来选择获取图片的方式,是相机拍摄还是相册选择

import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.Gravity;
import android.view.Window;
import android.view.WindowManager;

import androidx.annotation.NonNull;

public class SelectItemDialog extends Dialog {
    BtnCallback btnCallback;
    public SelectItemDialog(@NonNull Context context, BtnCallback btnCallback) {
        super(context);
        this.btnCallback=btnCallback;
    }

   CommonDialogSelectItemBinding binding;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        binding= CommonDialogSelectItemBinding.inflate(getLayoutInflater());
        setContentView(binding.getRoot());
        setCanceledOnTouchOutside(true);
        Window window = getWindow();
        window.setBackgroundDrawableResource(android.R.color.transparent);
        WindowManager.LayoutParams attributes = window.getAttributes();
        attributes.gravity= Gravity.CENTER;
        attributes.width= getWidth(getContext())*270/375;
        binding.layoutSelectCapture.setOnClickListener(v -> {
            if (btnCallback!=null){
                btnCallback.select(binding.layoutSelectCapture.getId());
            }
            dismiss();
        });
        binding.layoutSelectPhoto.setOnClickListener(v -> {
            if (btnCallback!=null){
                btnCallback.select(binding.layoutSelectPhoto.getId());
            }
            dismiss();

        });
    }
    public interface BtnCallback{
        void select(int id);
    }
    public  int getWidth(Context context) {
        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics outMetrics = new DisplayMetrics();
        wm.getDefaultDisplay().getMetrics(outMetrics);
        return outMetrics.widthPixels;
    }
}
common_dialog_select_item.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical"
    android:paddingLeft="@dimen/dp16"
    android:paddingRight="@dimen/dp16"
    android:paddingTop="10dp"
    android:paddingBottom="4dp"
    xmlns:app="http://schemas.android.com/apk/res-auto"
   >

    <RelativeLayout
        android:id="@+id/layout_select_photo"
        android:layout_marginTop="@dimen/dp17"
        android:paddingLeft="@dimen/dp13"
        android:paddingRight="@dimen/dp13"
        android:paddingTop="@dimen/dp17"
        android:paddingBottom="@dimen/dp17"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:layout_centerInParent="true"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="从相册选择"
            android:textColor="#ff464646"
            android:textSize="@dimen/sp16"
            />
    </RelativeLayout>
    <RelativeLayout
        android:id="@+id/layout_select_capture"
        android:layout_marginVertical="@dimen/dp17"
        android:paddingLeft="@dimen/dp13"
        android:paddingRight="@dimen/dp13"
        android:paddingTop="@dimen/dp17"
        android:paddingBottom="@dimen/dp17"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <TextView
            android:layout_centerInParent="true"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="相机拍照"
            android:textColor="#ff464646"
            android:textSize="@dimen/sp16"
            />
    </RelativeLayout>

</LinearLayout>

4.导入动态权限申请库(也可以原生实现)

implementation "cn.canfankeji:permission:1.0.2"

5.具体界面

public class MyActivity extends AppCompatActivity {

    PermissionGrantTool permissionGrantTool;

    String[] permissions = new String[]{Manifest.permission.CAMERA};

    ActivityResultLauncher<Intent> activityResultLauncherCardFront;
    
    Uri idCardFrontUri = null;
    
    File tempFrontFile = null;

    ...

    @Override
    private void onCreate(Bundle savedInstanceState) {
    
         ...
        Map<String, String[]> map = new HashMap<>();
        map.put("android.permission.CAMERA", new String[]{"相机拍照", "实名认证,拍照并上传驾驶证正反面图片"});
        PermissionGrantTool.setPermissionMap(map);

        permissionGrantTool = new PermissionGrantTool(this);

        initCallBack();

        binding.imgView1.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
 
                new SelectItemDialog(MyActivity .this, id -> {
                    if (id == R.id.layout_select_capture) {

                        permissionGrantTool.startPermissionsMethod(permissions, 
                            new PermissionGrantTool.PermissionsMethodCallback() {

                            @Override
                            public void granted() {
                                Intent intent = null;
                                intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                                if (intent.resolveActivity(getPackageManager()) != null){

                                    // 创建临时文件用于存储拍摄的照片
                                    tempFrontFile = createImageFile();
                                    if (tempFrontFile != null) {
                                        Uri imageUri = FileProvider.getUriForFile(getApplicationContext(),
                                                getPackageName() + ".provider",
                                                tempFrontFile);
                                        intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
                                        activityResultLauncherCardFront.launch(intent);

                                    } else {
                                        Log.i("", "intent photoFile is null");
                                    }
                                } else {
                                    Log.i("", "intent resolveActivity is null");

                                }
                            }

                            @Override
                            public void denied() {

                            }
                        });
                    } else {
                        Intent intent = null;
                        intent = new Intent(Intent.ACTION_PICK);
                        intent.setType("image/*");
                        activityResultLauncherCardFront.launch(intent);

                    }

                }).show();

            }
        });
    }

    
    private void initCallBack() {
    activityResultLauncherCardFront = registerForActivityResult(
        new ActivityResultContracts.StartActivityForResult(),
        new ActivityResultCallback<ActivityResult>() {
            @Override
            public void onActivityResult(ActivityResult o) {
                try {
                    if (o.getResultCode() == RESULT_OK) {
                        Intent data = o.getData();
                        if (data != null && data.getData() != null) {
                            // 从相册选择
                            idCardFrontUri = data.getData();
                            Glide.with(MyActivity.this)
                                .load(idCardFrontUri)
                                .into(binding.imgView1);
                        } else if (tempFrontFile != null && tempFrontFile.exists()) {
                            // 相机拍摄
                            idCardFrontUri = FileProvider.getUriForFile(
                                getApplicationContext(),
                                getPackageName() + ".provider",
                                tempFrontFile);
                            Glide.with(MyActivity.this)
                                .load(idCardFrontUri)
                                .into(binding.imgView1);
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                    Toast.makeText(MyActivity.this, "图片加载失败", Toast.LENGTH_SHORT).show();
                }
            }
        });
}

    private File createImageFile() {
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "JPEG_" + timeStamp + "_";
        File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        File image = null;
        try {
            image = File.createTempFile(imageFileName, ".png", storageDir);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return image;
    }

}


网站公告

今日签到

点亮在社区的每一天
去签到