日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

[转]快速使用FileProvider解决Android7.0文件权限问题

發布時間:2023/12/4 Android 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [转]快速使用FileProvider解决Android7.0文件权限问题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

?

升級到Android7.0之后,啟動系統相機或者截圖,傳入URI的時候可能會導致程序閃退崩潰。這是因為7.0的新的文件權限導致的。下面是解決這個問題的快速解決方案。

?

問題代碼

?

在7.0可能會出問題的代碼:

?

final String CACHE_IMG = Environment.getExternalStorageDirectory()+"/demo/" final int TAG_PHOTO_CAMERA=200;Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);String fileName = "defaultImage.jpg";File file = new File(CACHE_IMG, fileName);Uri uri = Uri.fromFile(file);intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);startActivityForResult(intent, TAG_PHOTO_CAMERA);

?

其中Uri uri = Uri.fromFile(file);這里會導致閃退。

?

解決方法

?

step1. 將Uri的生成方式改為由FileProvider提供的臨時授權路徑,并且在intent中添加flag
修改后代碼如下

?

final String CACHE_IMG = Environment.getExternalStorageDirectory()+"/demo/" final int TAG_PHOTO_CAMERA=200;Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);String fileName = "defaultImage.jpg";File file = new File(CACHE_IMG, fileName);Uri imageUri=FileProvider.getUriForFile(activity,"me.xifengwanzhao.fileprovider", file);//這里進行替換uri的獲得方式intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);//這里加入flagstartActivityForResult(intent, TAG_PHOTO_CAMERA);

?

step2.在AndroidManifest.xml中的application標簽中添加provider的配置

?

<application ...><provider android:name="android.support.v4.content.FileProvider"android:authorities="me.xifengwanzhao.fileprovider"//這里需要和上面部分字符串相同android:exported="false"android:grantUriPermissions="true"><meta-data android:name="android.support.FILE_PROVIDER_PATHS"android:resource="@xml/file_paths" /></provider></application>

?

step3.在res/xml中新建一個文件file_paths.xml

?

<?xml version="1.0" encoding="utf-8"?> <resource xmlns:android="http://schemas.android.com/apk/res/android"><external-path name="images"path="demo/" /> </resource>

?

OK,大功告成,這樣就不會崩潰了

?

代碼解釋

?

我們先看Google官方的7.0行為變更介紹 (不需要翻墻)

?

對于面向 Android 7.0 的應用,Android 框架執行的 StrictMode API 政策禁止在您的應用外部公開 file:// URI。如果一項包含文件 URI 的 intent 離開您的應用,則應用出現故障,并出現 FileUriExposedException 異常。

要在應用間共享文件,您應發送一項 content:// URI,并授予 URI 臨時訪問權限。進行此授權的最簡單方式是使用 FileProvider 類。如需了解有關權限和共享文件的詳細信息,請參閱共享文件。

?

根據文檔提示我們使用FileProvider進行處理,同時利用xml對FileProvider進行配置
參考如下

?

java根路徑產生方式對應xml根節點名稱
Context.getFilesDir()files-path
getCacheDir()cache-path
Environment.getExternalStorageDirectory()external-path
Context#getExternalFilesDir(String) Context.getExternalFilesDir(null)external-files-path
Context.getExternalCacheDir()external-cache-path

?

節點中的name 不可重名,path為自定義

?

關于相冊選圖和相機裁剪

?

有同學反映相冊選圖和相機裁剪時候的報錯問題,這里也說一下
系統相冊選圖返回的Uri是可以直接使用的,不需要也不能使用FileProvider進行轉換
如果需要根據uri獲得轉換后的uri 可以參考如下方式

?

Uri fromUri; if (uri.getScheme() != null && uri.getScheme().startsWith("file")) {fromUri =FileProvider.getUriForFile(mContext,"me.xifengwanzhao.fileprovider", new File(FileUtils.getPath(mContext, uri)));//這里進行替換uri的獲得方式intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);//這里加入flag } else {//相冊選圖適配fromUri = uri; }

?

關于相機裁剪
相機裁剪 intent.setDataAndType(fromUri, “image/*”);這里是需要對uri進行轉換的,
而 intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));這里使用原來的方式獲取uri就可以了
那么啟動系統裁剪的方法可以寫成這樣

?

/*** 開啟截圖,啟動系統的截圖方法 返回requestCode為 {Constant.IMG_ZOOM}** @param mContext 必須為activity* @param uri 需要進行裁剪的圖片的uri* @param size 截圖的大小寬和高的數值,這里僅限截圖為1:1的正方形* @return path 截圖返回的路徑* @see Constant#IMG_ZOOM*/public static String startPhotoZoom(Activity mContext, Uri uri, int size) {//這里生成一個保存截圖用的臨時路徑并且返回出去String imgPath;File file = new File(Constant.ZOOM_IMAGE, Constant.getNewestImageName(mContext));imgPath = file.getPath();Intent intent = new Intent("com.android.camera.action.CROP");Uri fromUri;if (uri.getScheme() != null && uri.getScheme().startsWith("file")) {fromUri = FileProvider.getUriForFile(mContext, "me.xifengwanzhao.fileprovider", new File(FileUtils.getPath(mContext, uri)));//這里進行替換uri的獲得方式intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);//這里加入flag} else {//相冊選圖適配fromUri = uri;}intent.setDataAndType(fromUri, "image/*");intent.putExtra("crop", "true");intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));if (android.os.Build.MANUFACTURER.contains("HUAWEI")) {// 華為特殊處理 不然會顯示圓intent.putExtra("aspectX", 9998);intent.putExtra("aspectY", 9999);} else {intent.putExtra("aspectX", 1);intent.putExtra("aspectY", 1);}intent.putExtra("outputX", size);intent.putExtra("outputY", size);mContext.startActivityForResult(intent, Constant.IMG_ZOOM);return imgPath;}

?

參考文檔

?

[1]Android N 調用相冊crash- FileUriExposedException
[2]根據 Android Training課程寫的FileProvider小例子
[3]使用FileProvider共享文件
[4]Android7.0適配教程與心得
[5]Android N 調用相冊crash- FileUriExposedException


---------------------
作者:夕楓晚照
來源:CSDN
原文:https://blog.csdn.net/xifengwanzhao/article/details/53587234
版權聲明:本文為作者原創文章,轉載請附上博文鏈接!

總結

以上是生活随笔為你收集整理的[转]快速使用FileProvider解决Android7.0文件权限问题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。