MVP模式的Android 调用系统拍照,相册,剪裁,适配到7.0,修复拍照图片旋转问题
来源:互联网 发布:江苏省软件测试中心 编辑:程序博客网 时间:2024/04/29 22:12
Android 调用系统拍照,相册,剪裁,适配到7.0,修复拍照图片旋转问题
直接上代码
首先添加拍照需要的权限
<uses-permission android:name="android.permission.CAMERA" />//相机权限<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />//写SD<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />//读SD<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTE" />
使用的常量
public static final int MY_PERMISSIONS_REQUEST_CAMERA = 100;//拍照权限public static final int MY_PERMISSIONS_REQUEST_READ_SD= 101;//读SD卡权限public static final int MY_PERMISSIONS_REQUEST_WRITE_SK = 102;//写SD卡权限public static final int MY_PERMISSIONS_REQUEST_READ_SD_PHOTOALBUM= 103;//写SD卡权限public static final int MY_PERMISSIONS_REQUEST_WRITE_SK_PHOTOALBUM = 104;//写SD卡权限public static final int CAPTURE_IMAGE_REQUEST = 104;//拍照后的返回值public static final int LOAD_IMAGE_REQUEST = 105;//相册的返回值public static final int CLIP_IMAGE_REQUEST = 106;//剪裁图片的返回值public static final String IMAGE_TYPE = "image/*";public static File mOutFile;//图片uri路径public static File mImageFile=null;//图片file路径public static Integer mBuildVersion=android.os.Build.VERSION.SDK_INT;//当前SDK版本
定义需要用到的接口
public interface UserCenterModel { /** * 拍照 * @param context */ void getFileByPhotograph(Context context); /** * 相册 * @param context */ void getFileByPhotoAlbum(Context context); /** * 创建img文件 * @return */ File getImagefile(); /** * 开始拍照 * @param context */ void startPhotograph(Context context); /** * 调用相册 * @param context */ void startPhotoAlbum(Context context); /** * 剪裁图片 * @param activity */ void startClip(Activity activity, File file); /** * API24 以上调用 * @param context * @param imageFile * @return */ Uri getImageContentUri(Context context, File imageFile);}
接口实现类
public class UserCenterRealize implements UserCenterModel { @Override public void getFileByPhotograph(Context context) { Activity activity = (Activity) context; if (AppConsts.mBuildVersion >= 23) { if (ContextCompat.checkSelfPermission(context, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) { //申请相机权限 ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.CAMERA}, AppConsts.MY_PERMISSIONS_REQUEST_CAMERA); } else { if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { //申请读SD权限 ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, AppConsts.MY_PERMISSIONS_REQUEST_READ_SD); } else { if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { //申请写SD权限 ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, AppConsts.MY_PERMISSIONS_REQUEST_WRITE_SK); } else { startPhotograph(activity); } } } } else { //拍照 startPhotograph(activity); } } @Override public File getImagefile() { File mediaStorageDir = null; File mediaFile = null; try { mediaStorageDir = new File(Environment.getExternalStorageDirectory().toString() + "/IMAGE/"); Log.d("创建文件夹成功", mediaStorageDir.toString()); } catch (Exception e) { e.printStackTrace(); Log.d("创建文件夹失败", mediaStorageDir.toString()); } if (!mediaStorageDir.exists()) { if (!mediaStorageDir.mkdirs()) { Log.d("创建文件失败", "WRITE_EXTERNAL_STORAGE 权限"); return null; } } // Create a media file name String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); mediaFile = new File(mediaStorageDir.getPath() + File.separator + "IMG_" + timeStamp + ".jpg"); Log.d("创建文件成功",mediaFile.toString()); return mediaFile; } @Override public void getFileByPhotoAlbum(Context context) { Activity activity= (Activity) context; if (AppConsts.mBuildVersion >= 23) { if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { //申请读SD权限 ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, AppConsts.MY_PERMISSIONS_REQUEST_READ_SD_PHOTOALBUM); } else { if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) { //申请写SD权限 ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, AppConsts.MY_PERMISSIONS_REQUEST_WRITE_SK_PHOTOALBUM); } else { startPhotoAlbum(context); } } } else { startPhotoAlbum(context); } } @Override public void startPhotoAlbum(Context context) { if(!BitmapUtils.existSDCard()){ Toast.makeText(context, "未检测到SD卡", Toast.LENGTH_SHORT).show(); return; } Activity a= (Activity) context; Intent getAlbum = new Intent(Intent.ACTION_GET_CONTENT); getAlbum.setType(AppConsts.IMAGE_TYPE); a.startActivityForResult(getAlbum, AppConsts.LOAD_IMAGE_REQUEST); } @Override public void startPhotograph(Context context) { if(!BitmapUtils.existSDCard()){ Toast.makeText(context, "未检测到SD卡", Toast.LENGTH_SHORT).show(); return; } Activity activity= (Activity) context; if (AppConsts.mBuildVersion<24){ Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); mImageFile=getImagefile(); intent.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(mImageFile)); activity.startActivityForResult(intent, AppConsts.CAPTURE_IMAGE_REQUEST); }else { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); ContentValues contentValues = new ContentValues(1); mImageFile=getImagefile(); contentValues.put(MediaStore.Images.Media.DATA, mImageFile.getAbsolutePath()); Uri uri = context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,contentValues); intent.putExtra(MediaStore.EXTRA_OUTPUT, uri); activity.startActivityForResult(intent, AppConsts.CAPTURE_IMAGE_REQUEST); } } @Override public void startClip(Activity activity, File file) { if(null == file){ return; } mOutFile=getImagefile(); Intent intent = new Intent("com.android.camera.action.CROP"); intent.setDataAndType(getImageContentUri(activity,file),AppConsts.IMAGE_TYPE); intent.putExtra("crop", "true"); intent.putExtra("aspectX", 1); intent.putExtra("aspectY", 1); intent.putExtra("outputX", 180); intent.putExtra("outputY", 180); intent.putExtra("scale", true); intent.putExtra("return-data", false); intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mOutFile)); intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString()); intent.putExtra("noFaceDetection", true); activity.startActivityForResult(intent, AppConsts.CLIP_IMAGE_REQUEST); } @Override public Uri getImageContentUri(Context context, File imageFile) { String filePath = imageFile.getAbsolutePath(); Uri uri=null; Cursor cursor = context.getContentResolver().query( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, new String[] { MediaStore.Images.Media._ID }, MediaStore.Images.Media.DATA + "=? ", new String[] { filePath }, null); if (cursor != null && cursor.moveToFirst()) { int id = cursor.getInt(cursor .getColumnIndex(MediaStore.MediaColumns._ID)); Uri baseUri = Uri.parse("content://media/external/images/media"); uri= Uri.withAppendedPath(baseUri, "" + id); } else { if (imageFile.exists()) { ContentValues values = new ContentValues(); values.put(MediaStore.Images.Media.DATA, filePath); uri= context.getContentResolver().insert( MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values); } else { uri= null; } } return uri; }}
Actvity界面中的回调
userCenterRealize.getFileByPhotoAlbum(this);//拍照外部调用 userCenterRealize.getFileByPhotograph(this);//相册外部调用
@Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == AppConsts.MY_PERMISSIONS_REQUEST_CAMERA) { if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { userCenterRealize.getFileByPhotograph(this); } else { Toast.makeText(this, "请授予相机权限", Toast.LENGTH_SHORT).show(); } }else if(requestCode == AppConsts.MY_PERMISSIONS_REQUEST_READ_SD){ if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { userCenterRealize.getFileByPhotograph(this); } else { Toast.makeText(this, "请授予读SD卡权限", Toast.LENGTH_SHORT).show(); } }else if(requestCode == AppConsts.MY_PERMISSIONS_REQUEST_WRITE_SK){ if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { userCenterRealize.getFileByPhotograph(this); } else { Toast.makeText(this, "请授予写SD卡权限", Toast.LENGTH_SHORT).show(); } }else if(requestCode == AppConsts.MY_PERMISSIONS_REQUEST_READ_SD_PHOTOALBUM) { if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { userCenterRealize.startPhotoAlbum(this); } else { Toast.makeText(this, "请授予读SD卡权限", Toast.LENGTH_SHORT).show(); } }else if(requestCode == AppConsts.MY_PERMISSIONS_REQUEST_WRITE_SK_PHOTOALBUM) { if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { userCenterRealize.startPhotoAlbum(this); } else { Toast.makeText(this, "请授予写SD卡权限", Toast.LENGTH_SHORT).show(); } } }@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); // 拍照 if (AppConsts.CAPTURE_IMAGE_REQUEST == requestCode) { if (RESULT_OK == resultCode) { Log.d("拍照得到图片", AppConsts.mImageFile.toString()); int mDegree=BitmapUtils.getBitmapDegree(AppConsts.mImageFile.getAbsolutePath()); Log.d("拍照得到图片的角度:", String.valueOf(mDegree)); if(mDegree==90||mDegree==180||mDegree==270){ try { Bitmap mBitmap= BitmapUtils.getFileBitmap(AppConsts.mImageFile); Bitmap bitmap=BitmapUtils.rotateBitmapByDegree(mBitmap,mDegree); if(BitmapUtils.saveBitmapFile(bitmap,AppConsts.mImageFile)){ userCenterRealize.startClip(this, AppConsts.mImageFile); }else { Toast.makeText(this, "保存图片失败", Toast.LENGTH_SHORT).show(); } } catch (Exception e) { e.printStackTrace(); Toast.makeText(this, "读取图片失败", Toast.LENGTH_SHORT).show(); } }else { userCenterRealize.startClip(this, AppConsts.mImageFile); } } //相册 } else if (AppConsts.LOAD_IMAGE_REQUEST == requestCode) { if (data != null) { Uri uri = data.getData(); String filepath=FileUtils.getImageAbsolutePath(this, uri); Log.d("相册获取到的文件路径",filepath); File file = new File(filepath); userCenterRealize.startClip(this, file); } //剪裁 } else if (AppConsts.CLIP_IMAGE_REQUEST == requestCode) { Log.d("剪裁得到图片", AppConsts.mOutFile.toString()); Bitmap bitmap = BitmapUtils.getFileBitmap(AppConsts.mOutFile); imgAvatar.setImageBitmap(bitmap); BitmapUtils.deleteFile(AppConsts.mImageFile); } }
工程中使用到的工具类
public class BitmapUtils { /** * 获取网络图片资源 * @param url * @return */ public static Bitmap getHttpBitmap(String url){ URL myFileURL; Bitmap bitmap=null; try{ myFileURL = new URL(url); //获得连接 HttpURLConnection conn=(HttpURLConnection)myFileURL.openConnection(); //设置超时时间为6000毫秒,conn.setConnectionTiem(0);表示没有时间限制 conn.setConnectTimeout(6000); //连接设置获得数据流 conn.setDoInput(true); //不使用缓存 conn.setUseCaches(false); //这句可有可无,没有影响 //conn.connect(); //得到数据流 InputStream is = conn.getInputStream(); //解析得到图片 bitmap = BitmapFactory.decodeStream(is); //关闭数据流 is.close(); }catch(Exception e){ e.printStackTrace(); } return bitmap; } /** * 判断是否有SD卡 * @return */ public static boolean existSDCard() { if (android.os.Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)){ return true; }else { return false; } } /** * 从文件中读取图片 * @param file * @return */ public static Bitmap getFileBitmap(File file) { FileInputStream fis = null; Bitmap bitmap=null; try { //把图片转化为字节流 fis = new FileInputStream(file); //把流转化图片 bitmap = BitmapFactory.decodeStream(fis); } catch (FileNotFoundException e) { e.printStackTrace(); } finally { try { fis.close();//关闭流 } catch (IOException e) { e.printStackTrace(); } } return bitmap; } /** * 读取图片的旋转的角度 * * @param path * 图片绝对路径 * @return 图片的旋转角度 */ public static int getBitmapDegree(String path) { int degree = 0; try { // 从指定路径下读取图片,并获取其EXIF信息 ExifInterface exifInterface = new ExifInterface(path); // 获取图片的旋转信息 int orientation = exifInterface.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL); switch (orientation) { case ExifInterface.ORIENTATION_ROTATE_90: degree = 90; break; case ExifInterface.ORIENTATION_ROTATE_180: degree = 180; break; case ExifInterface.ORIENTATION_ROTATE_270: degree = 270; break; } } catch (IOException e) { e.printStackTrace(); } return degree; } /** * 将图片按照某个角度进行旋转 * * @param bm * 需要旋转的图片 * @param degree * 旋转角度 * @return 旋转后的图片 */ public static Bitmap rotateBitmapByDegree(Bitmap bm, int degree) { Bitmap returnBm = null; // 根据旋转角度,生成旋转矩阵 Matrix matrix = new Matrix(); matrix.postRotate(degree); try { // 将原始图片按照旋转矩阵进行旋转,并得到新的图片 returnBm = Bitmap.createBitmap(bm, 0, 0, bm.getWidth(), bm.getHeight(), matrix, true); } catch (OutOfMemoryError e) { } if (returnBm == null) { returnBm = bm; } if (bm != returnBm) { bm.recycle(); } return returnBm; } /** * 删除文档 * @param file */ public static boolean deleteFile(File file) { try { if(file!=null) { if(FileUtils.deleteFile(file.getAbsolutePath())){ AppConsts.mImageFile=null; Log.d("删除文件","true"); return true; }else { return false; } }else { Log.d("删除文件路径为空","false"); return false; } } catch (Exception e) { e.printStackTrace(); Log.d("删除文件","false"); return false; } } /** * 保存图片 * @param bitmap * @param file */ public static boolean saveBitmapFile(Bitmap bitmap, File file){ try { BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(file)); bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bos); bos.flush(); bos.close(); return true; } catch (IOException e) { e.printStackTrace(); return false; } }public class FileUtils { /** * 删除单个文件 * @param filePath 被删除文件的文件名 * @return 文件删除成功返回true,否则返回false */ public static boolean deleteFile(String filePath) { File file = new File(filePath); if (file.isFile() && file.exists()) { return file.delete(); } return false; } /** * 根据Uri获取图片绝对路径,解决Android4.4以上版本Uri转换 * @param context * @param imageUri * @author yaoxing * @date 2014-10-12 */ @TargetApi(19) public static String getImageAbsolutePath(Activity context, Uri imageUri) { if (context == null || imageUri == null) return null; if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(context, imageUri)) { if (isExternalStorageDocument(imageUri)) { String docId = DocumentsContract.getDocumentId(imageUri); String[] split = docId.split(":"); String type = split[0]; if ("primary".equalsIgnoreCase(type)) { return Environment.getExternalStorageDirectory() + "/" + split[1]; } } else if (isDownloadsDocument(imageUri)) { String id = DocumentsContract.getDocumentId(imageUri); Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); return getDataColumn(context, contentUri, null, null); } else if (isMediaDocument(imageUri)) { String docId = DocumentsContract.getDocumentId(imageUri); String[] split = docId.split(":"); 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; } String selection = MediaStore.Images.Media._ID + "=?"; String[] selectionArgs = new String[] { split[1] }; return getDataColumn(context, contentUri, selection, selectionArgs); } } // MediaStore (and general) else if ("content".equalsIgnoreCase(imageUri.getScheme())) { // Return the remote address if (isGooglePhotosUri(imageUri)) return imageUri.getLastPathSegment(); return getDataColumn(context, imageUri, null, null); } // File else if ("file".equalsIgnoreCase(imageUri.getScheme())) { return imageUri.getPath(); } return null; } private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) { Cursor cursor = null; String column = MediaStore.Images.Media.DATA; String[] projection = { column }; try { cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); if (cursor != null && cursor.moveToFirst()) { int index = cursor.getColumnIndexOrThrow(column); return cursor.getString(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()); } /** * @param uri The Uri to check. * @return Whether the Uri authority is Google Photos. */ public static boolean isGooglePhotosUri(Uri uri) { return "com.google.android.apps.photos.content".equals(uri.getAuthority()); }}
The End
QQ:3355168235(遇到问题或者有更好的建议请联系我额)
0 1
- MVP模式的Android 调用系统拍照,相册,剪裁,适配到7.0,修复拍照图片旋转问题
- Android 7.0 调用系统拍照,相册,剪裁,修复拍照图片旋转问题
- Android7.0调用系统相机拍照、读取系统相册照片+CropImageView剪裁、旋转、翻转照片
- android:拍照,相册剪裁的实现方式
- 关于部分手机调用系统拍照和相册图片出现旋转问题处理
- android调用拍照相册遇到的问题
- android 调用系统照相机拍照后剪裁
- Android调用手机拍照以及从相册选择照片,剪裁
- Android 调用手机相册、摄像头拍照及剪裁照片
- 关于Android中调用系统拍照和剪裁,不能保存的问题
- Android 拍照剪裁,获取相册图片,上传照片至服务端
- android 拍照和相册选择照片之后。剪裁图片。
- Android 调用相册 拍照 实现系统控件缩放 切割图片
- Android 调用相册 拍照 实现系统控件缩放 切割图片
- Android 调用相册 拍照 实现系统控件缩放 切割图片
- Android 调用相册 拍照 实现系统控件缩放 切割图片
- Android 调用相册 拍照 实现系统控件缩放 切割图片
- Android 调用相册 拍照 实现系统控件缩放 切割图片 .
- 黎活明给程序员的忠告 收藏
- memcache分布式集群算法——一致性哈希算法
- c++第二次实验-1个人所得税计算器
- 7 Important Model Evaluation Error Metrics Everyone should know
- JavaScript之基本语法
- MVP模式的Android 调用系统拍照,相册,剪裁,适配到7.0,修复拍照图片旋转问题
- android 最全缓存目录获取方式和函数解析
- Linux下压缩与解压
- JS或Jquery查找父元素、子元素(网上资料保存)
- 人工智能-java
- 关于Hibernate查询返回值转换为实体或Map形式处理问题
- 声明贴:菜鸟一枚,纯属记录,仅供阅读,以免误人子弟!!!
- 倒排索引 mr实现
- 解决使用MySQL C-API开发应用时的连接超时问题