1. 程式人生 > >Android 7.0 拍照,相簿選擇和系統圖片裁剪和刪除適配

Android 7.0 拍照,相簿選擇和系統圖片裁剪和刪除適配

Android 7.0 引入了 Provider 給 app 申請檔案儲存路徑,所以需要配置 Provider ,才可以使用 儲存功能。

定義 provider

res/xml 資料夾下定義

provider_path.xml

<?xml version="1.0" encoding="utf-8"?>
<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);
        }
    }