sdCard訪問權限

P90訪問SDCard

之前的文章說過,SDCard在O到P上有重大改動。在P上必須使用storageVolume.createAccessIntent

        if (storageVolume!=null&&canFindPath){
            Intent intent = storageVolume.createAccessIntent(getDirectoryName("DCIM"));//
            permissionPath=storagePath + File.separator+"DCIM";
            startActivityForResult(intent, OPEN_DIRECTORY_REQUEST_CODE);
        }

Q100上的改動

在Q上又有了一些改動,storageVolume.createAccessIntent一些action被禁用

* @deprecated Callers should migrate to using {@link Intent#ACTION_OPEN_DOCUMENT_TREE} instead.
     *             Launching this {@link Intent} on devices running
     *             {@link android.os.Build.VERSION_CODES#Q} or higher, will immediately finish
     *             with a result code of {@link android.app.Activity#RESULT_CANCELED}.

P90上的frameworks層啓動log

實際上,P上通過storageVolume.createAccessIntent獲得intent,請求權限,啓動的是system.ui下面的ScopedAccessActivity

10-05 14:22:56.073 6246-6246/? D/GrantPermissionHelper: getSdCardPermission startActivityForResult intent Intent { act=android.os.storage.action.OPEN_EXTERNAL_DIRECTORY (has extras) }
10-05 14:22:56.077 1520-2111/system_process I/ActivityTaskManager: START u0 {act=android.os.storage.action.OPEN_EXTERNAL_DIRECTORY cmp=com.android.documentsui/.ScopedAccessActivity (has extras)} from uid 10147 pid 6246
10-05 14:22:56.080 1520-2111/system_process D/BoostFramework: perfHint : hint: 0x1081 pkg_name(userDataStr): android duration(userData1): -1 type(userData2): 1
10-05 14:22:56.080 1520-1606/system_process I/system_server: Compiler filter for /data/app/com.htc.zero-V5KQqHfsFhUeIDCLbDnbRA==/oat/arm64/base.odex is quicken
10-05 14:22:56.080 1520-1606/system_process I/system_server: Compiler filter for /data/app/com.htc.zero-V5KQqHfsFhUeIDCLbDnbRA==/oat/arm64/base.odex is quicken
10-05 14:22:56.084 1520-1606/system_process I/ActivityTaskManager: Displayed com.htc.zero/.activity.GrantPermissionActivity: +514ms

Q100上frameworks一些類被禁用

但是在Q上ScopedAccessActivity被廢棄,禁止通過代碼StorageVolume#createAccessIntent(String)直接申請某個目錄的讀寫權限

建議使用Callers should migrate to using {@link Intent#ACTION_OPEN_DOCUMENT_TREE} instead

這個intent會打開一個文件目錄讓用戶自己選擇授權的目錄,給了用戶更多的選擇權,禁止了應用私自申請目錄權限創建文件。

相當於進一步規範了SDCard目錄

26/**
27 * Activity responsible for handling {@link StorageVolume#createAccessIntent(String)}.
28 *
29 * @deprecated This class handles the deprecated {@link StorageVolume#createAccessIntent(String)}.
30 */
31@Deprecated
32public class ScopedAccessActivity extends Activity {
33    @Override
34    public void onCreate(Bundle savedInstanceState) {
35        super.onCreate(savedInstanceState);
36        logInvalidScopedAccessRequest(SCOPED_DIRECTORY_ACCESS_DEPRECATED);
37        setResult(RESULT_CANCELED);
38        finish();
39    }
40}

==================----------------------------------------======================

三方應用Android 4.4之後不能直接對外置SD卡通過FileOutputStream寫數據,只能通過DocumentFile這個接口來實現

Android 6.0 運行時權限

系統應用Android 9.0之後不能直接對外置SD卡通過FileOutputStream寫數據,只能通過DocumentFile這個接口來實現

 

AndroidQ上禁止通過代碼StorageVolume#createAccessIntent(String)直接申請某個目錄的讀寫權限

只能使用Intent#ACTION_OPEN_DOCUMENT_TREE讓用戶選擇某個目錄

 

Android R上 對ACTION_OPEN_DOCUMENT_TREE 或 ACTION_OPEN_DOCUMENT也進行了限制

改爲使用MANAGE_EXTERNAL_STORAGE進行大量的文件操作

==================----------------------------------------======================

Android 4.4(API 19 級)引入了存儲訪問框架 (SAF)

尾註:

  • 從4.4開始google開始規範SDCard卡讀寫問題,旨在保護用戶空間和規範空間使用。
  • 讓程序員更不容易操作存儲空間目錄。
  • P90上強制執行,刪除了SDCard寫權限,必須使用DocumentFile進行存儲訪問。
  • Q上對DocumentFile的訪問方式也進行了限制,讓程序員無法直接申請想要讀寫的路徑,改爲用戶去選擇給app的訪問路徑。
  • R上進一步對ACTION_OPEN_DOCUMENT_TREE 或 ACTION_OPEN_DOCUMENT進行限制,

無法再使用 ACTION_OPEN_DOCUMENT_TREE intent 操作來請求訪問以下目錄:

1.Downloads 根目錄。

2.設備製造商認爲可靠的各個 SD 卡卷的根目錄,無論該卡是模擬卡還是可移除的卡。

無法再使用 ACTION_OPEN_DOCUMENT_TREE 或 ACTION_OPEN_DOCUMENT intent 操作來請求用戶從以下目錄中選擇單獨的文件:

3.Android/data/ 目錄及其所有子目錄。

4.Android/obb/ 目錄及其所有子目錄。

以上 是各個版本對存儲進行的限制訪問。

由於公司項目只做到Q,P上面的方式已經驗證可行,Q上被棄用的方式也跟蹤了源碼進行驗證。讓用戶選擇路徑不符合app設計,也由底層frameworks那邊直接授權,所以不需要使用DocumentFile,R上面的訪問沒有進行驗證。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章