一、 7.0文件地址传输的问题
异常信息:FileUriExposedException:
<!-- android 7.0以上 --> <provider android:name="android.support.v4.content.FileProvider" android:authorities="应用报名.fileProvider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>
在res.下的xml文件:
文件名是:file_paths(和清单文件中一致)
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-path name="files_root" path="Android/data/com.lechuang.letaotao/" /> <external-path name="external_storage_root" path="." /> </paths>
在 传输过程中提供图片地址:
public static Uri getUriForFile(Context context, File file) { if (context == null || file == null) { throw new NullPointerException(); } Uri uri; if (Build.VERSION.SDK_INT >= 24) { uri = FileProvider.getUriForFile(context, "应用包名.fileProvider", file); } else { uri = Uri.fromFile(file); } return uri; }
打开照相机:
//android 7.0 // Uri imageUri = FileProvider.getUriForFile(mContext, "应用包名.fileProvider", file); // 7.0 以// Uri uri = Uri.fromFile(file);//适配7.0和7.0一下的地址Uri imageUri = getUriForFile(mContext, file);Intent intent = new Intent();intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri); //把拍照后的图片放在指定的文件intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0);startActivityForResult(intent, 2);
相册选择:
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI); intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*"); //*代表全部 startActivityForResult(intent, 1);
裁剪图片:
public static void resizeImage(Uri uri, Activity activity, int requestCode) { Intent intent = new Intent("com.android.camera.action.CROP"); intent.setDataAndType(uri, "image/png"); //限定图片类型 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //重要 ,权限要求。 intent.putExtra("crop", "true"); // aspectX , aspectY :宽高的比例 intent.putExtra("aspectX", 1); intent.putExtra("aspectY", 1); // outputX , outputY : 裁剪图片宽高 intent.putExtra("outputX", 150); intent.putExtra("outputY", 150); intent.putExtra("return-data", true); activity.startActivityForResult(intent, requestCode); }
压缩图片:
private void showResizeImage(Intent data) { Bundle extras = data.getExtras(); if (extras != null) { Bitmap bitmap = extras.getParcelable("data"); String path = Uri.fromFile(file).getPath(); bitmap =toSmall(bitmap, path); } }
压缩处理的具体方法:
public static Bitmap toSmall(Bitmap bitmap, String path) { int scale = 1; int width_tmp = bitmap.getWidth(); int height_tmp = bitmap.getHeight(); while (true) { if (width_tmp / 2 < 100 || height_tmp / 2 < 100) break; width_tmp /= 2; height_tmp /= 2; scale *= 2; } Matrix matrix = new Matrix(); matrix.postScale(scale, scale); // 长和宽放大缩小的比例 bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); try { FileOutputStream fileOutputStream = new FileOutputStream(path); try { bitmap.compress(Bitmap.CompressFormat.PNG, 100, fileOutputStream); } finally { try { fileOutputStream.flush(); fileOutputStream.close(); } catch (IOException e) { } } } catch (FileNotFoundException e) { e.printStackTrace(); } return bitmap; }
主界面的处理:
@Override public void onActivityResult(int requestCode, int resultCode, Intent data) { switch (requestCode) { case 1: if (resultCode != -1) { return; } .resizeImage(data.getData(), this, 3); //处理从相册返回的信息: break; case 2: if (resultCode != -1) { return; } if (PhotoUtil.isSdcardExisting()) { //处理从照相机返回的图片 Uri uriForFile = getUriForFile(mContext, file); resizeImage(uriForFile, this, 3); //开始裁剪 } else { Utils.show(mContext, "未找到存储卡,无法存储照片"); } break; case 3: if (data != null) { showResizeImage(data); // 压缩图片 } break; default: break; } super.onActivityResult(requestCode, resultCode, data); }
附 Android6.0 文件和照相机权限申请:
private static final int REQUEST_PERMISSION_CAMERA = 222; private static final int REQUEST_PERMISSION_STORAGE = 333; private void setCamear() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { int checkCallPhonePermission = ContextCompat.checkSelfPermission(mContext, Manifest.permission.CAMERA); if (checkCallPhonePermission != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, REQUEST_PERMISSION_CAMERA); return; } } if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { int checkCallPhonePermission = ContextCompat.checkSelfPermission(mContext, Manifest.permission.WRITE_EXTERNAL_STORAGE); if (checkCallPhonePermission != PackageManager.PERMISSION_GRANTED) { ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_PERMISSION_STORAGE); return; } } } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { switch (requestCode) { //就像onActivityResult一样这个地方就是判断你是从哪来的。 case REQUEST_PERMISSION_CAMERA: if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { } else { Utils.show(mContext, "很遗憾你把相机权限禁用了!"); finish(); } break; case REQUEST_PERMISSION_STORAGE: if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { } else { // Permission Denied Utils.show(mContext, "很遗憾你把读取文件权限禁用了!"); finish(); } break; default: super.onRequestPermissionsResult(requestCode, permissions, grantResults); } }