100字范文,内容丰富有趣,生活中的好帮手!
100字范文 > Android调用系统相册 拍照以及裁剪最简单的实现(兼容7.0)

Android调用系统相册 拍照以及裁剪最简单的实现(兼容7.0)

时间:2020-10-09 14:21:02

相关推荐

Android调用系统相册 拍照以及裁剪最简单的实现(兼容7.0)

这里我只实现功能,具体Android 7.0 的一些细节参考 /lmj623565791/article/details/72859156

具体步骤:

一、在清单文件中配置provider

<provider android:name="android.support.v4.content.FileProvider" android:authorities="com.MainActivity.provider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths"/></provider>

注意:name属性的值是固定的写法,authorities属性的值可以随意写,但是必须要和后面将要说的FileProvider.getUrlForFile()方法中第二个参数一致(我喜欢写包的全路径名)

二、在res目录下创建一个xml文件夹,并创建名为file_paths的xml文件

<?xml version="1.0" encoding="utf-8"?><paths> <external-path name="camera_photos" path="" /></paths>

注意:name属性的值随意写,path属性的值表示共享的具体路径(这里写一个空字符串,表示将整个SD卡进行共享)

三、使用下面工具类(包括Fragment中的回调)

/** * 相片工具类 */public class PhotoUtils {private static final StringTAG= "PhotoUtils";/*** @param activity* 当前activity* @param imageUri* 拍照后照片存储路径* @param requestCode* 调用系统相机请求码*/ public static void takePicture(Activity activity, Uri imageUri, int requestCode) {//调用系统相机 Intent intentCamera = new Intent();if (Build.VERSION.SDK_INT>= Build.VERSION_CODES.N) {intentCamera.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //添加这一句表示对目标应用临时授权该Uri所代表的文件 }intentCamera.setAction(MediaStore.ACTION_IMAGE_CAPTURE);//将拍照结果保存至photo_file的Uri中,不保留在相册中 intentCamera.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);activity.startActivityForResult(intentCamera, requestCode);}/*** @param fragment* 当前fragment* @param imageUri* 拍照后照片存储路径* @param requestCode* 调用系统相机请求码*/ public static void takePicture(Fragment fragment, Uri imageUri, int requestCode) {//调用系统相机 Intent intentCamera = new Intent();if (Build.VERSION.SDK_INT>= Build.VERSION_CODES.N) {intentCamera.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //添加这一句表示对目标应用临时授权该Uri所代表的文件 }intentCamera.setAction(MediaStore.ACTION_IMAGE_CAPTURE);//将拍照结果保存至photo_file的Uri中,不保留在相册中 intentCamera.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);fragment.startActivityForResult(intentCamera, requestCode);}/*** @param activity* 当前activity* @param requestCode* 打开相册的请求码*/ public static void openPic(Activity activity, int requestCode) {Intent photoPickerIntent = new Intent(Intent.ACTION_GET_CONTENT);photoPickerIntent.setType("image/*");activity.startActivityForResult(photoPickerIntent, requestCode);}/*** @param fragment* 当前fragment* @param requestCode* 打开相册的请求码*/ public static void openPic(Fragment fragment, int requestCode) {Intent photoPickerIntent = new Intent(Intent.ACTION_GET_CONTENT);photoPickerIntent.setType("image/*");fragment.startActivityForResult(photoPickerIntent, requestCode);}/*** @param activity* 当前activity* @param orgUri* 剪裁原图的Uri* @param desUri* 剪裁后的图片的Uri* @param aspectX* X方向的比例* @param aspectY* Y方向的比例* @param width* 剪裁图片的宽度* @param height* 剪裁图片高度* @param requestCode* 剪裁图片的请求码*/ public static void cropImageUri(Activity activity, Uri orgUri,Uri desUri, int aspectX, int aspectY, int width, int height, int requestCode) {Intent intent = new Intent("com.android.camera.action.CROP");if (Build.VERSION.SDK_INT>= Build.VERSION_CODES.N) {intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);}intent.setDataAndType(orgUri, "image/*");intent.putExtra("crop", "true");/* intent.putExtra("aspectX", aspectX); intent.putExtra("aspectY", aspectY); intent.putExtra("outputX", width); intent.putExtra("outputY", height);*/intent.putExtra("scale", true);//将剪切的图片保存到目标Uri中 intent.putExtra(MediaStore.EXTRA_OUTPUT, desUri);intent.putExtra("return-data", false);intent.putExtra("outputFormat", pressFormat.JPEG.toString());intent.putExtra("noFaceDetection", true);activity.startActivityForResult(intent, requestCode);}/*** @param fragment* 当前activity* @param orgUri* 剪裁原图的Uri* @param desUri* 剪裁后的图片的Uri* @param aspectX* X方向的比例* @param aspectY* Y方向的比例* @param width* 剪裁图片的宽度* @param height* 剪裁图片高度* @param requestCode* 剪裁图片的请求码*/ public static void cropImageUri(Fragment fragment, Uri orgUri, Uri desUri,int aspectX, int aspectY, int width,int height, int requestCode) {Intent intent = new Intent("com.android.camera.action.CROP");if (Build.VERSION.SDK_INT>= Build.VERSION_CODES.N) {intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);}intent.setDataAndType(orgUri, "image/*");intent.putExtra("crop", "true");intent.putExtra("aspectX", aspectX);intent.putExtra("aspectY", aspectY);intent.putExtra("outputX", width);intent.putExtra("outputY", height);intent.putExtra("scale", true);//将剪切的图片保存到目标Uri中 intent.putExtra(MediaStore.EXTRA_OUTPUT, desUri);intent.putExtra("return-data", false);intent.putExtra("outputFormat", pressFormat.JPEG.toString());intent.putExtra("noFaceDetection", true);fragment.startActivityForResult(intent, requestCode);}/*** 读取uri所在的图片* @param uri* 图片对应的Uri* @param mContext* 上下文对象* @return 获取图像的Bitmap*/ public static Bitmap getBitmapFromUri(Uri uri, Context mContext) {try {Bitmap bitmap = MediaStore.Images.Media.getBitmap(mContext.getContentResolver(), uri);return bitmap;} catch (Exception e) {e.printStackTrace();return null;}}/*** @param context* 上下文对象* @param uri* 当前相册照片的Uri* @return 解析后的Uri对应的String*/ @SuppressLint("NewApi")public static String getPath(final Context context, final Uri uri) {final boolean isKitKat = Build.VERSION.SDK_INT>= Build.VERSION_CODES.KITKAT;String pathHead = "file:///";// DocumentProvider if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {// ExternalStorageProvider if (isExternalStorageDocument(uri)) {final String docId = DocumentsContract.getDocumentId(uri);final String[] split = docId.split(":");final String type = split[0];if ("primary".equalsIgnoreCase(type)) {return pathHead + Environment.getExternalStorageDirectory() + "/" + split[1];}}// DownloadsProvider else if (isDownloadsDocument(uri)) {final String id = DocumentsContract.getDocumentId(uri);final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"),Long.valueOf(id));return pathHead +getDataColumn(context,contentUri, null, null);}// MediaProvider else if (isMediaDocument(uri)) {final String docId = DocumentsContract.getDocumentId(uri);final String[] split = docId.split(":");final String type = split[0];Uri contentUri = null;if ("image".equals(type)) {contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;} else if ("video".equals(type)) {contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;} else if ("audio".equals(type)) {contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;}final String selection = "_id=?";final String[] selectionArgs = new String[]{split[1]};return pathHead +getDataColumn(context, contentUri, selection, selectionArgs);}}// MediaStore (and general) else if ("content".equalsIgnoreCase(uri.getScheme())) {return pathHead +getDataColumn(context, uri, null, null);}// File else if ("file".equalsIgnoreCase(uri.getScheme())) {return pathHead + uri.getPath();}return null;}/*** Get the value of the data column for this Uri. This is useful for* MediaStore Uris, and other file-based ContentProviders.* @param context* The context.* @param uri* The Uri to query.* @param selection* (Optional) Filter used in the query.* @param selectionArgs* (Optional) Selection arguments used in the query.* @return The value of the _data column, which is typically a file path.*/ private static String getDataColumn(Context context, Uri uri,String selection, String[] selectionArgs) {Cursor cursor = null;final String column = "_data";final String[] projection = {column};try {cursor = context.getContentResolver().query(uri, projection, selection,selectionArgs, null);if (cursor != null && cursor.moveToFirst()) {final int column_index = cursor.getColumnIndexOrThrow(column);return cursor.getString(column_index);}} finally {if (cursor != null)cursor.close();}return null;}/*** @param uri* The Uri to check.* @return Whether the Uri authority is ExternalStorageProvider.*/ private static boolean isExternalStorageDocument(Uri uri) {return "com.android.externalstorage.documents".equals(uri.getAuthority());}/*** @param uri* The Uri to check.* @return Whether the Uri authority is DownloadsProvider.*/ private static boolean isDownloadsDocument(Uri uri) {return "com.android.providers.downloads.documents".equals(uri.getAuthority());}/*** @param uri* The Uri to check.* @return Whether the Uri authority is MediaProvider.*/ private static boolean isMediaDocument(Uri uri) {return "com.android.providers.media.documents".equals(uri.getAuthority());}}

具体的应用:

public class MainActivity extends AppCompatActivity {private ImageView photo;private static final int CODE_GALLERY_REQUEST= 0xa0;private static final int CODE_CAMERA_REQUEST = 0xa1;private static final int CODE_RESULT_REQUEST = 0xa2;private File fileUri = new File(Environment.getExternalStorageDirectory().getPath() + "/photo.jpg");private File fileCropUri= new File(Environment.getExternalStorageDirectory().getPath() + "/crop_photo.jpg");private Uri imageUri;private Uri cropImageUri;@Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);photo = (ImageView) findViewById(R.id.iv_photo);}/*** 拍照* @param view*/ public void takePhoto(View view) {if (hasSdcard()) {imageUri = Uri.fromFile(fileUri);if (Build.VERSION.SDK_INT>= Build.VERSION_CODES.N)//通过FileProvider创建一个content类型的UriimageUri = FileProvider.getUriForFile(MainActivity.this, "com.MainActivity.provider", fileUri);PhotoUtils.takePicture(MainActivity.this, imageUri,CODE_CAMERA_REQUEST);} else {Toast.makeText(MainActivity.this, "设备没有SD卡!", Toast.LENGTH_SHORT).show();Log.e("asd", "设备没有SD卡");}}/*** 调用系统相册* @param view*/ public void getPhoto(View view) {PhotoUtils.openPic(MainActivity.this,CODE_GALLERY_REQUEST);}@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {super.onActivityResult(requestCode, resultCode, data);int output_X = 480, output_Y = 480;if (resultCode ==RESULT_OK) {switch (requestCode) {caseCODE_CAMERA_REQUEST://拍照完成回调cropImageUri = Uri.fromFile(fileCropUri);PhotoUtils.cropImageUri(this, imageUri, cropImageUri, 1, 1, output_X, output_Y,CODE_RESULT_REQUEST);break;caseCODE_GALLERY_REQUEST://访问相册完成回调if (hasSdcard()) {cropImageUri = Uri.fromFile(fileCropUri);Uri newUri = Uri.parse(PhotoUtils.getPath(this, data.getData()));if (Build.VERSION.SDK_INT>= Build.VERSION_CODES.N)newUri = FileProvider.getUriForFile(this, "com.MainActivity.provider", new File(newUri.getPath()));PhotoUtils.cropImageUri(this, newUri, cropImageUri, 1, 1, output_X, output_Y,CODE_RESULT_REQUEST);} else {Toast.makeText(MainActivity.this, "设备没有SD卡!", Toast.LENGTH_SHORT).show();}break;caseCODE_RESULT_REQUEST:Bitmap bitmap = PhotoUtils.getBitmapFromUri(cropImageUri, this);if (bitmap != null) {showImages(bitmap);}break;}}}/*** 展示图片* @param bitmap*/ private void showImages(Bitmap bitmap) {photo.setImageBitmap(bitmap);}/*** 检查设备是否存在SDCard的工具方法*/ public static boolean hasSdcard() {String state = Environment.getExternalStorageState();return state.equals(Environment.MEDIA_MOUNTED);}}

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。