第一次写技术文章贴,可能写的不是很好,见谅了~
原本我以为,能像启动系统相机那样,能从拍照页面,进入相册。整了半天,也没整出来。看了一下微信,也是 拍照和相册分开的。
所以,作为一个api user,那就随大流,不做太多深入了解了
1.新建配置文件 provider_pah.xml
2.在AndroidManifest.xml 中配置
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"/>
3.获取相册照片
public static int ALBUM_RESULT_CODE =0x999;
private void openSysAlbum() {
Intent albumIntent =new Intent(Intent.ACTION_PICK);
albumIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
startActivityForResult(albumIntent, ALBUM_RESULT_CODE);
}
2.进入相机
public static int CAMERA_RESULT_CODE =0x998;
public static StringFILE_PATH = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) +"/my_pic.jpg";
private void openCamera(){
Intent intent =new Intent();
intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
intent.addCategory(Intent.CATEGORY_DEFAULT);
// 根据文件地址创建文件
File file =new File(StringFILE_PATH);
if (file.exists()) {
file.delete();
}
Uri photoURI = FileProvider.getUriForFile(this,
getApplicationContext().getPackageName() +".provider", file );
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(intent, CAMERA_RESULT_CODE);
}
3.处理相册获取的照片,或者拍照的照片
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode ==ALBUM_RESULT_CODE){
HandlePhotoFromAlbumCameraUtils PhotoAlbum =new HandlePhotoFromAlbumCameraUtils(this);
PhotoAlbum.handleImageFromAlbum(data);
PhotoAlbum.SetPhoto(new HandlePhotoFromAlbumCameraUtils.SetPhotoListener() {
@Override
public void photoBitmap(Bitmap bitmap) {
}
@Override
public void photoFile(File file) {
}
});
}else if (requestCode ==CAMERA_RESULT_CODE){
HandlePhotoFromAlbumCameraUtils photoCamera =new HandlePhotoFromAlbumCameraUtils(this);
photoCamera.handleImageFromCamera();
photoCamera.SetPhoto(new HandlePhotoFromAlbumCameraUtils.SetPhotoListener() {
@Override
public void photoBitmap(Bitmap bitmap) {
}
@Override
public void photoFile(File file) {
}
});
}
}
4.工具类HandlePhotoFromAlbumCameraUtils 用到了Luban 这个开源控件进行图片压缩处理
implementation'top.zibin:Luban:1.1.3'
5.最重要的来了,是你需要我封装的一个工具类--- HandlePhotoFromAlbumCameraUtils
import android.annotation.TargetApi;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import java.io.File;
import java.io.IOException;
import java.util.List;
import top.zibin.luban.Luban;
import top.zibin.luban.OnCompressListener;
/**
* author : zzmm
* date : 2021/10/12 15:48
* desc :
* version: 1.0
*/
public class HandlePhotoFromAlbumCameraUtils {
public static StringFILE_PATH = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) +"/my_pic.jpg";
public static StringFILE_PATH_OUTPUT = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM) +"";
private Contextcontext;
private SetPhotoListenersetPhotoListener;
public HandlePhotoFromAlbumCameraUtils(Context context){
this.context = context;
}
@TargetApi(value =19)
public void handleImageFromAlbum(Intent data) {
if (data ==null){
return;
}
String imagePath =null;
Uri uri = data.getData();
if (DocumentsContract.isDocumentUri(context, uri)) {
// 如果是document类型的Uri,则通过document id处理
String docId = DocumentsContract.getDocumentId(uri);
if ("com.android.providers.media.documents".equals(uri.getAuthority())) {
String id = docId.split(":")[1];
// 解析出数字格式的id
String selection = MediaStore.Images.Media._ID +"=" + id;
imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection);
}else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())) {
Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(docId));
imagePath = getImagePath(contentUri, null);
}
}else if ("content".equalsIgnoreCase(uri.getScheme())) {
// 如果是content类型的Uri,则使用普通方式处理
imagePath = getImagePath(uri, null);
}else if ("file".equalsIgnoreCase(uri.getScheme())) {
// 如果是file类型的Uri,直接获取图片路径即可
imagePath = uri.getPath();
}
// 根据图片路径显示图片
displayImage(imagePath);
Log.e("imagePath","imagePath : " + imagePath);
}
@TargetApi(value =19)
public void handleImageFromCamera() {
File file =new File(FILE_PATH);
Uri uri = Uri.fromFile(file);
String imagePath =null;
if (DocumentsContract.isDocumentUri(context, uri)) {
// 如果是document类型的Uri,则通过document id处理
String docId = DocumentsContract.getDocumentId(uri);
if ("com.android.providers.media.documents".equals(uri.getAuthority())) {
String id = docId.split(":")[1];
// 解析出数字格式的id
String selection = MediaStore.Images.Media._ID +"=" + id;
imagePath = getImagePath(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, selection);
}else if ("com.android.providers.downloads.documents".equals(uri.getAuthority())) {
Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(docId));
imagePath = getImagePath(contentUri, null);
}
}else if ("content".equalsIgnoreCase(uri.getScheme())) {
// 如果是content类型的Uri,则使用普通方式处理
imagePath = getImagePath(uri, null);
}else if ("file".equalsIgnoreCase(uri.getScheme())) {
// 如果是file类型的Uri,直接获取图片路径即可
imagePath = uri.getPath();
}
// 根据图片路径显示图片
displayImage(imagePath);
Log.e("imagePath","imagePath : " + imagePath);
}
/**获取图片的路径*/
private StringgetImagePath(Uri uri, String selection) {
String path =null;
Cursor cursor =context.getContentResolver().query(uri, null, selection, null, null);
if(cursor !=null){
if(cursor.moveToFirst()){
path = cursor.getString(cursor.getColumnIndex(MediaStore.Images.Media.DATA));
}
cursor.close();
}
return path;
}
/**展示图片*/
private void displayImage(String imagePath) {
File filePic =new File(imagePath);
Luban.with(context)
.load(filePic)// 传人要压缩的图片列表
.ignoreBy(40)
.setTargetDir(FILE_PATH_OUTPUT)
.setCompressListener(new OnCompressListener() {//设置回调
@Override
public void onStart() {
Log.e("onStart","onStart" );
}
@Override
public void onSuccess(File file) {
String handleImageStr = file.getAbsolutePath();
Bitmap bp = BitmapFactory.decodeFile(handleImageStr);
Log.e("handleImageStr","handleImageStr : " + handleImageStr);
if (bp ==null){
Toast.makeText(context,"照片获取异常啦,请再次获取照片",Toast.LENGTH_LONG).show();
}else {
if (setPhotoListener !=null){
setPhotoListener.photoBitmap(bp);
setPhotoListener.photoFile(file);
}
}
}
@Override
public void onError(Throwable e) {
Log.e("onError","onError : " + e.toString() );
}
}).launch(); //启动压缩
}
public interface SetPhotoListener{
public void photoBitmap(Bitmap bitmap);
public void photoFile(File file);
}
public void SetPhoto(SetPhotoListener setPhotoListener){
this.setPhotoListener = setPhotoListener;
}
}
在Manifest中加入 android:requestLegacyExternalStorage="true"