Android调用系统相册、拍照以及裁剪最简单的实现(兼容7.0)
这里我只实现功能,具体Android 7.0 的一些细节参考 http://blog.csdn.net/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 String TAG = "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", Bitmap.CompressFormat.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", Bitmap.CompressFormat.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类型的Uri imageUri = 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) {case CODE_CAMERA_REQUEST://拍照完成回调 cropImageUri = Uri.fromFile(fileCropUri);PhotoUtils.cropImageUri(this, imageUri, cropImageUri, 1, 1, output_X, output_Y, CODE_RESULT_REQUEST);break;case CODE_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;case CODE_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);} }
Android调用系统相册、拍照以及裁剪最简单的实现(兼容7.0)相关推荐
- Android调用系统的拍照,打开相册功能
Android调用系统的拍照,打开相册功能 1 添加权限: <!-- 往SDCard写入数据权限 --> <uses-permission android:name="an ...
- Android多层嵌套Fragment中调用系统相机拍照以及裁剪的相关问题解决
多层嵌套Fragment中调用系统相机拍照.裁剪 最近公司项目有频繁使用相机拍照的需求,然后频繁的实际使用过程中遇到很多大大小小的坑,在此记录下. (ps.关于一些拍照后图片旋转.裁剪设置返回数据为t ...
- Android调用系统相机拍照并保存到指定位置
Android调用系统相机拍照并保存到指定位置 @Click(R.id.btn_takePhoto)void onclick() {Intent intent = new Intent(MediaSt ...
- Android 调用系统照相机拍照和录像
Android 调用系统照相机拍照和录像 项目的布局相当简单,只有一个Button: <RelativeLayout xmlns:android="http://schemas.and ...
- android固定位置拍照,Android调用系统相机拍照并保存到指定位置
Android调用系统相机拍照并保存到指定位置 @Click(R.id.btn_takePhoto) void onclick() { Intent intent = new Intent(Media ...
- iOS 调用系统相册拍照时显示英文问题
在调用系统相册拍照的时候,在选择照片的时候,发现用的都是英文,效果如下: 我们想把那个Retake 和Use Photo 改为对应的汉字,先来一种最笨的方法,最后在来个高级的方法,最笨的办法当然是我们 ...
- android 调用系统相机拍照 获取原图
博客源址:android 调用系统相机拍照 获取原图 博客时间:2013-04-23 11:08 好吧,为了这个问题又折腾了一整天.之前在网上找来的方法,如果在onActivityResult中直接用 ...
- Android调用系统相机拍照
参考: Taking Photos Simply FileProvider 项目地址(好多人找我要,我传到百度云啦,大家自取):链接:https://pan.baidu.com/s/1nWsoE0eS ...
- Android调用系统摄像头拍照并显示在ImageView上
简介 现在市面上的apk只要涉及用户中心都会有头像,而且这个头像也是可自定义的,有的会采取读取相册选择其中一张作为需求照片,另一种就是调用系统摄像头拍照并获取即时照片,本博文就是讲述如何调用摄像头拍照 ...
最新文章
- 大数据与数据挖掘考试题_北京2020届中考物理出题策略大揭秘!
- 浙大超重力离心模拟与实验装置有望年底开建 释放五大利好
- QMYSQL driver not loaded
- “金融与安全大数据”专题导读
- 面试题系列(9):对前端界面工程师这个职位是怎么样理解的?
- php 中间表统计,多对多中间表详解
- 【Linux】CentOS 7 安装Redis
- Linux 下mysql操作
- 13、几点小结,unsigned long long
- 宝塔控制面板如何添加伪静态
- 环保数采仪 环保行业的绿色卫士
- Mac MF打印机驱动程序安装(亲测MacOS11.6和Mac12.4都可以)
- Ubuntu16.04 忘记登陆密码 重新设置密码
- 三步生活法:土豆(Todo),优势,庆祝
- FastAPI + tortoise-orm基础使用
- 使用canvas绘制海报
- 游戏自定义金币单位换算管理类
- 搜狗拼音输入法,披着紫皮的狗
- 【lwIP(第三章)】内存管理
- 图的建立——邻接矩阵