安卓获取图片(相机拍摄/相册选择)
1、在项目res中的xml目录(没有的话新建一个就行)中新建file_path_my.xml
<?xml version="1.0" encoding="utf-8"?>
<paths><external-pathname="external"path="." /><external-files-pathname="external_files"path="." /><cache-pathname="cache"path="." /><external-cache-pathname="external_cache"path="." /><files-pathname="files"path="." /><external-files-path name="my_images" path="Pictures/" /></paths>
2、在AndroidManifast.xml中静态申请相机权限,创建FileProvider
<uses-permission android:name="android.permission.CAMERA" /><uses-featureandroid:name="android.hardware.camera"android:required="false" /> <!--申明是否必须拥有相机的设备才能安装本应用--><queries><intent><action android:name="android.media.action.IMAGE_CAPTURE" /></intent>
</queries><application...>...<providerandroid:name="androidx.core.content.FileProvider"android:authorities="${applicationId}.provider"android:exported="false"android:grantUriPermissions="true"><meta-dataandroid: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;@Overrideprotected 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"><RelativeLayoutandroid: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"><TextViewandroid:layout_centerInParent="true"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="从相册选择"android:textColor="#ff464646"android:textSize="@dimen/sp16"/></RelativeLayout><RelativeLayoutandroid: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"><TextViewandroid: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;...@Overrideprivate 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() {@Overridepublic void onClick(View v) {new SelectItemDialog(MyActivity .this, id -> {if (id == R.id.layout_select_capture) {permissionGrantTool.startPermissionsMethod(permissions, new PermissionGrantTool.PermissionsMethodCallback() {@Overridepublic 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");}}@Overridepublic 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>() {@Overridepublic 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;}}