Android - Android 7.0 拍照,相册选择和系统图片裁剪和删除适配

Android 7.0 引入了 Provider 给 app 申请文件存储路径,所以需要配置 Provider ,才可以使用 存储功能。

定义 provider

res/xml 文件夹下定义

provider_path.xml


<resources>
    <paths>
        <external-path
            name="insurance"
            path="insurance" />
    paths>
resources>

AndroidManfest.xmlapplication下配置

  • authorities 自行定义,可以在 buildconfig 下进行配置
<application 
   ....>
   <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="com.smartahc.android.photo.provider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths" />
        provider>
application>

相册选择

    protected void openAlbumPage() {
        Intent pickIntent = new Intent(Intent.ACTION_PICK, null);
        // 如果限制上传到服务器的图片类型时可以直接写如:"image/jpeg 、 image/png等的类型"
        pickIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
        startActivityForResult(pickIntent, ALBUM_REQUEST_CODE);
    }

打开相机

 /**
     * 打开相机
     */
    protected void openCameraPage() {
        // 创建目录
        currentPath = createImageName();
        File file = new File(currentPath);
        if (!file.getParentFile().exists()) {
            // 创建文件夹
            file.getParentFile().mkdirs();
        }
        Intent takeIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            // 7.0
            //添加这一句表示对目标应用临时授权该Uri所代表的文件
            takeIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        }
        //下面这句指定调用相机拍照后的照片存储的路径
        currentUri = getUri(file);
        takeIntent.putExtra(MediaStore.EXTRA_OUTPUT, currentUri);
        startActivityForResult(takeIntent, CAMERA_REQUEST_CODE);
    }

根据系统不同获取拍照的输出 uri , 需要定义 provider

 /**
     * 根据系统版本获取不同的uri
     *
     * @param file file
     * @return Uri
     */

    private Uri getUri(File file) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            // 7.0 APP_PROVIDER 等于 authorities 属性值
            return FileProvider.getUriForFile(mContext, BuildConfig.APP_PROVIDER, file);
        } else {
            // > 7.0
            return Uri.fromFile(file);
        }
    }

Android 4.4 及其以上获取图片真实路径

 /**
     * android 4.4 获取 uri 真实路径
     *
     * @param uri uri
     * @return /sdcard/0/xx.jpg
     */
    public String getRealFilePath(Uri uri) {
        final String scheme = uri.getScheme();
        String data = null;
        if (scheme == null)
            data = uri.getPath();
        else if (ContentResolver.SCHEME_FILE.equals(scheme)) {
            data = uri.getPath();
        } else if (ContentResolver.SCHEME_CONTENT.equals(scheme)) {
            Cursor cursor = mContext.getContentResolver().query(uri, new String[]{MediaStore.Images.ImageColumns.DATA}, null, null, null);
            if (null != cursor) {
                if (cursor.moveToFirst()) {
                    int index = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
                    if (index > -1) {
                        data = cursor.getString(index);
                    }
                }
                cursor.close();
            }
        }
        return data;
    }

系统裁剪

 /**
     * 裁剪跳转
     */
    public void startCropActivity() {
        // 裁剪
        currentCropPath = createImageName();
        File file = new File(currentCropPath);
        // 注意: 裁剪输入的内容不需要进行 7.0 适配操作,一定要写成这个;
        currentCropUri = Uri.fromFile(file);
        Intent intent = new Intent("com.android.camera.action.CROP");
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            // 7.0
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.setDataAndType(getImageContentUri(new File(currentPath)), "image/*");
        } else {
            // > 7.0
            intent.setDataAndType(currentUri, "image/*");
        }
        intent.putExtra("crop", "true");
        //设置宽高比例
        intent.putExtra("aspectX", 1);
        intent.putExtra("aspectY", 1);
        //设置裁剪图片宽高
        intent.putExtra("outputX", 512);
        intent.putExtra("outputY", 512);
        intent.putExtra("scale", true);
        intent.putExtra("return-data", false);
        intent.putExtra(MediaStore.EXTRA_OUTPUT, currentCropUri);
        intent.putExtra("outputFormat", Bitmap.CompressFormat.JPEG.toString());
        intent.putExtra("noFaceDetection", true);
        startActivityForResult(intent, CROP_REQUEST_CODE);
}

7.0 uri 转 content uri

 public Uri getImageContentUri(File imageFile) {
        String filePath = imageFile.getAbsolutePath();

        Cursor cursor = mContext.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");
            return Uri.withAppendedPath(baseUri, "" + id);
        } else {
            if (imageFile.exists()) {
                ContentValues values = new ContentValues();
                values.put(MediaStore.Images.Media.DATA, filePath);
                return mContext.getContentResolver().insert(
                        MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
            } else {
                return null;
            }
        }
    }

删除图片

注意进行异步操作

  /**
     * delete image
     *
     * @param fileName filename
     * @param fileUri  file uri
     */
    private void deleteImage(String fileName, Uri fileUri) {
        File file = new File(fileName);
        if (file.exists()) {
            file.delete();
            Uri uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
            ContentResolver mContentResolver = mContext.getContentResolver();
            String where = MediaStore.Images.Media.DATA + "='" + fileName + "'";
            // 删除操作
            mContentResolver.delete(uri, where, null);
            //发送广播
            Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
            intent.setData(fileUri);
            mContext.sendBroadcast(intent);
        }
    }

你可能感兴趣的:(android开发经验)