国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

Android 11 上的文件讀寫權(quán)限(MANAGE_EXTERNAL_STORAGE)

這篇具有很好參考價值的文章主要介紹了Android 11 上的文件讀寫權(quán)限(MANAGE_EXTERNAL_STORAGE)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

平臺

???? Android11 + RK3566 + AndroidStudio

Android 權(quán)限的變化, 幾乎每個版本的SDK都會有, 其中最大的一次是在6.0時, 增加的動態(tài)權(quán)限申請
讀寫存儲的權(quán)限也幾經(jīng)更迭, 對開發(fā)人員來說, 越來越難.比如, 本文所要討論的:允許管理所有文件manage_external_storage,android-framework,android,android,文件權(quán)限,permission
manage_external_storage,android-framework,android,android,文件權(quán)限,permission

如何出現(xiàn)上面兩種不同的文件權(quán)限選項?

  1. 首先是 targetSdkVersion 大于等于 30. (build.gradle)
    manage_external_storage,android-framework,android,android,文件權(quán)限,permission
  2. 當聲明了 READ_EXTERNAL_STORAGE和WRITE_EXTERNAL_STORAGE
    僅允許訪問媒體文件
  3. 當聲明了 MANAGE_EXTERNAL_STORAGE 會增加允許管理所有文件
  4. targetSdkVersion <= 28 時, 只有允許管理所有文件和 拒絕 選項.
    manage_external_storage,android-framework,android,android,文件權(quán)限,permission

編寫測試代碼執(zhí)行以下動作:

  1. 申請權(quán)限
  2. 獲取內(nèi)部存儲下的1.txt文件
  3. 若文件存在, 刪除并輸出結(jié)果
  4. 嘗試寫入文件

讀寫失敗:

2022-09-03 07:25:11.067 1262-10770/com.android.providers.media.module E/MediaProvider: insertFileIfNecessary failed
    java.lang.IllegalArgumentException: Primary directory null not allowed for content://media/external_primary/file; allowed directories are [Download, Documents]
        at com.android.providers.media.MediaProvider.ensureFileColumns(MediaProvider.java:2923)
        at com.android.providers.media.MediaProvider.ensureUniqueFileColumns(MediaProvider.java:2588)
        at com.android.providers.media.MediaProvider.insertFile(MediaProvider.java:3282)
        at com.android.providers.media.MediaProvider.insertInternal(MediaProvider.java:3826)
        at com.android.providers.media.MediaProvider.insert(MediaProvider.java:3537)
        at com.android.providers.media.MediaProvider.insertFileForFuse(MediaProvider.java:7187)
        at com.android.providers.media.MediaProvider.insertFileIfNecessaryForFuse(MediaProvider.java:7281)
2022-09-03 07:25:11.068 10710-10710/com.android.apitester W/System.err: java.io.FileNotFoundException: /storage/emulated/0/1.txt: open failed: EPERM (Operation not permitted)
2022-09-03 07:25:11.068 10710-10710/com.android.apitester W/System.err:     at libcore.io.IoBridge.open(IoBridge.java:492)
2022-09-03 07:25:11.068 10710-10710/com.android.apitester W/System.err:     at java.io.FileOutputStream.<init>(FileOutputStream.java:236)
2022-09-03 07:25:11.068 10710-10710/com.android.apitester W/System.err:     at java.io.FileOutputStream.<init>(FileOutputStream.java:186)
2022-09-03 07:25:11.069 10710-10710/com.android.apitester W/System.err:     at com.android.apitester.PermissionTest.fileOperation(PermissionTest.java:124)
2022-09-03 07:25:11.069 10710-10710/com.android.apitester W/System.err:     at com.android.apitester.PermissionTest.onClick(PermissionTest.java:50)
2022-09-03 07:25:11.069 10710-10710/com.android.apitester W/System.err:     at android.view.View.performClick(View.java:7448)
2022-09-03 07:25:11.069 10710-10710/com.android.apitester W/System.err:     at android.view.View.performClickInternal(View.java:7425)
2022-09-03 07:25:11.069 10710-10710/com.android.apitester W/System.err:     at android.view.View.access$3600(View.java:810)
2022-09-03 07:25:11.070 10710-10710/com.android.apitester W/System.err:     at android.view.View$PerformClick.run(View.java:28310)
2022-09-03 07:25:11.070 10710-10710/com.android.apitester W/System.err:     at android.os.Handler.handleCallback(Handler.java:938)
2022-09-03 07:25:11.070 10710-10710/com.android.apitester W/System.err:     at android.os.Handler.dispatchMessage(Handler.java:99)
2022-09-03 07:25:11.070 10710-10710/com.android.apitester W/System.err:     at android.os.Looper.loop(Looper.java:223)
2022-09-03 07:25:11.070 10710-10710/com.android.apitester W/System.err:     at android.app.ActivityThread.main(ActivityThread.java:7664)
2022-09-03 07:25:11.070 10710-10710/com.android.apitester W/System.err:     at java.lang.reflect.Method.invoke(Native Method)
2022-09-03 07:25:11.071 10710-10710/com.android.apitester W/System.err:     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
2022-09-03 07:25:11.071 10710-10710/com.android.apitester W/System.err:     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
2022-09-03 07:25:11.071 10710-10710/com.android.apitester W/System.err: Caused by: android.system.ErrnoException: open failed: EPERM (Operation not permitted)
2022-09-03 07:25:11.071 10710-10710/com.android.apitester W/System.err:     at libcore.io.Linux.open(Native Method)
2022-09-03 07:25:11.072 10710-10710/com.android.apitester W/System.err:     at libcore.io.ForwardingOs.open(ForwardingOs.java:166)
2022-09-03 07:25:11.072 10710-10710/com.android.apitester W/System.err:     at libcore.io.BlockGuardOs.open(BlockGuardOs.java:254)
2022-09-03 07:25:11.072 10710-10710/com.android.apitester W/System.err:     at libcore.io.ForwardingOs.open(ForwardingOs.java:166)
2022-09-03 07:25:11.072 10710-10710/com.android.apitester W/System.err:     at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:7550)
2022-09-03 07:25:11.072 10710-10710/com.android.apitester W/System.err:     at libcore.io.IoBridge.open(IoBridge.java:478)
2022-09-03 07:25:11.072 10710-10710/com.android.apitester W/System.err: 	... 15 more
2022-09-03 07:25:11.073 10710-10710/com.android.apitester E/PermissionTest: write /storage/emulated/0/1.txt failed
2022-09-03 07:25:11.094 1262-1367/com.android.providers.media.module I/MediaProvider: Deleted 1 items on external_primary due to com.android.apitester
2022-09-03 07:25:11.097 10710-10710/com.android.apitester D/PermissionTest: delete /storage/emulated/0/Download/1.txt success
2022-09-03 07:25:11.124 10710-10710/com.android.apitester D/PermissionTest: write /storage/emulated/0/Download/1.txt success
2022-09-03 07:25:11.131 10710-10710/com.android.apitester D/PermissionTest: delete /storage/emulated/0/Android/data/com.android.apitester/files/Documents/1.txt success
2022-09-03 07:25:11.137 10710-10710/com.android.apitester D/PermissionTest: write /storage/emulated/0/Android/data/com.android.apitester/files/Documents/1.txt success

結(jié)果(FAILED:失敗, SUCCESS成功):

DIR 僅允許訪問媒體文件 允許管理所有文件
/storage/emulated/0 FAILED SUCCESS
/storage/emulated/0/Download FAILED SUCCESS
/storage/emulated/0/Android/data/com.android.apitester/files/Documents SUCCESS SUCCESS

源碼中權(quán)限窗口

packages/apps/PermissionController/

START u0 {act=android.intent.action.MANAGE_APP_PERMISSIONS cmp=com.android.permissioncontroller/.permission.ui.ManagePermissionsActivity (has extras)} from uid 1000

布局文件

packages/apps/PermissionController/res/navigation/nav_graph.xml
packages/apps/PermissionController/res/layout/app_permission.xml
相關(guān)源碼
packages/apps/PermissionController/src/com/android/permissioncontroller/permission/ui/ManagePermissionsActivity.java
packages/apps/PermissionController/src/com/android/permissioncontroller/permission/ui/handheld/AppPermissionFragment.java

請求權(quán)限的交互


UI顯示內(nèi)容的判定

加載應(yīng)用存儲權(quán)限
packages/apps/PermissionController/src/com/android/permissioncontroller/permission/data/FullStoragePermissionAppsLiveData.kt

    data class FullStoragePackageState(
        val packageName: String,
        val user: UserHandle,
        val isLegacy: Boolean,
        val isGranted: Boolean
    )
    override suspend fun loadDataAndPostValue(job: Job) {
        val storagePackages = standardPermGroupsPackagesLiveData.value?.get(STORAGE) ?: return
        val appOpsManager = app.getSystemService(AppOpsManager::class.java) ?: return

        val fullStoragePackages = mutableListOf<FullStoragePackageState>()
        for ((user, packageInfoList) in AllPackageInfosLiveData.value ?: emptyMap()) {
            val userPackages = packageInfoList.filter {
                storagePackages.contains(it.packageName to user) ||
                    it.requestedPermissions.contains(MANAGE_EXTERNAL_STORAGE)
            }

            for (packageInfo in userPackages) {
                val sdk = packageInfo.targetSdkVersion
                if (sdk < Build.VERSION_CODES.P) {//targetSdkVersion 28
                    fullStoragePackages.add(FullStoragePackageState(packageInfo.packageName, user,
                        isLegacy = true, isGranted = true))
                    continue
                } else if (sdk <= Build.VERSION_CODES.Q &&//targetSdkVersion 29
                    appOpsManager.unsafeCheckOpNoThrow(OPSTR_LEGACY_STORAGE, packageInfo.uid,
                        packageInfo.packageName) == MODE_ALLOWED) {
                    fullStoragePackages.add(FullStoragePackageState(packageInfo.packageName, user,
                        isLegacy = true, isGranted = true))
                    continue
                }
                //存在MANAGE_EXTERNAL_STORAGE
                if (MANAGE_EXTERNAL_STORAGE in packageInfo.requestedPermissions) {
                    val mode = appOpsManager.unsafeCheckOpNoThrow(OPSTR_MANAGE_EXTERNAL_STORAGE,
                        packageInfo.uid, packageInfo.packageName)
                    val granted = mode == MODE_ALLOWED || mode == MODE_FOREGROUND ||
                        (mode == MODE_DEFAULT &&
                            MANAGE_EXTERNAL_STORAGE in packageInfo.grantedPermissions)
                    fullStoragePackages.add(FullStoragePackageState(packageInfo.packageName, user,
                        isLegacy = false, isGranted = granted))
                }
            }
        }

        postValue(fullStoragePackages)
    }

isLegacy表示是否是舊的權(quán)限模式, UI會根據(jù)上面的代碼進行邏輯運算并更新對應(yīng)的UI信息.

packages/apps/PermissionController/src/com/android/permissioncontroller/permission/ui/model/AppPermissionViewModel.kt

        override fun onUpdate() {
            val group = appPermGroupLiveData.value ?: return

            val admin = RestrictedLockUtils.getProfileOrDeviceOwner(app, user)

            val couldPackageHaveFgCapabilities =
                    foregroundCapableType != Utils.ForegroundCapableType.NONE

            val allowedState = ButtonState()
            val allowedAlwaysState = ButtonState()
            val allowedForegroundState = ButtonState()
            val askOneTimeState = ButtonState()
            val askState = ButtonState()
            val deniedState = ButtonState()
            val deniedForegroundState = ButtonState() // when bg is fixed as granted and fg is flex

            askState.isShown = Utils.supportsOneTimeGrant(permGroupName) &&
                    !(group.foreground.isGranted && group.isOneTime)
            deniedState.isShown = true

            if (group.hasPermWithBackgroundMode) {
                // Background / Foreground / Deny case
                allowedForegroundState.isShown = true
                if (group.hasBackgroundGroup) {
                    allowedAlwaysState.isShown = true
                }

                allowedAlwaysState.isChecked = group.background.isGranted &&
                    group.foreground.isGranted
                allowedForegroundState.isChecked = group.foreground.isGranted &&
                    !group.background.isGranted && !group.isOneTime
                askState.isChecked = !group.foreground.isGranted && group.isOneTime
                askOneTimeState.isChecked = group.foreground.isGranted && group.isOneTime
                askOneTimeState.isShown = askOneTimeState.isChecked
                deniedState.isChecked = !group.foreground.isGranted && !group.isOneTime
                var detailId = 0
                if (applyFixToForegroundBackground(group, group.foreground.isSystemFixed,
                        group.background.isSystemFixed, allowedAlwaysState,
                        allowedForegroundState, askState, deniedState,
                        deniedForegroundState) ||
                    applyFixToForegroundBackground(group, group.foreground.isPolicyFixed,
                        group.background.isPolicyFixed, allowedAlwaysState,
                        allowedForegroundState, askState, deniedState,
                        deniedForegroundState)) {
                    showAdminSupportLiveData.value = admin
                    detailId = getDetailResIdForFixedByPolicyPermissionGroup(group,
                        admin != null)
                    if (detailId != 0) {
                        detailResIdLiveData.value = detailId to null
                    }
                } else if (Utils.areGroupPermissionsIndividuallyControlled(app, permGroupName)) {
                    val detailPair = getIndividualPermissionDetailResId(group)
                    detailId = detailPair.first
                    detailResIdLiveData.value = detailId to detailPair.second
                }
                if (couldPackageHaveFgCapabilities) {
                    // Correct the UI in case the app can access bg location with only fg perm
                    allowedAlwaysState.isShown = true
                    allowedAlwaysState.isChecked =
                            allowedAlwaysState.isChecked || allowedForegroundState.isChecked
                    // Should be enabled && is denied enabled for the user to be able to switch to.
                    allowedAlwaysState.isEnabled =
                            ((allowedAlwaysState.isEnabled && allowedAlwaysState.isShown) ||
                                    allowedForegroundState.isEnabled) &&
                                    ((deniedState.isEnabled && deniedState.isShown) ||
                                            (deniedForegroundState.isEnabled &&
                                                    deniedForegroundState.isShown))
                    allowedForegroundState.isChecked = false
                    allowedForegroundState.isEnabled = false
                    deniedState.isChecked = deniedState.isChecked || askState.isChecked
                    deniedForegroundState.isChecked = deniedState.isChecked
                    askState.isEnabled = false

                    if (detailId == 0) {
                        detailId = getForegroundCapableDetailResId(foregroundCapableType)
                        if (detailId != 0) {
                            detailResIdLiveData.value = detailId to null
                        }
                    }
                }
            } else {
                // Allow / Deny case
                allowedState.isShown = true

                allowedState.isChecked = group.foreground.isGranted
                askState.isChecked = !group.foreground.isGranted && group.isOneTime
                askOneTimeState.isChecked = group.foreground.isGranted && group.isOneTime
                askOneTimeState.isShown = askOneTimeState.isChecked
                deniedState.isChecked = !group.foreground.isGranted && !group.isOneTime

                var detailId = 0
                if (group.foreground.isPolicyFixed || group.foreground.isSystemFixed) {
                    allowedState.isEnabled = false
                    askState.isEnabled = false
                    deniedState.isEnabled = false
                    showAdminSupportLiveData.value = admin
                    val detailId = getDetailResIdForFixedByPolicyPermissionGroup(group,
                        admin != null)
                    if (detailId != 0) {
                        detailResIdLiveData.value = detailId to null
                    }
                }
                if (isForegroundGroupSpecialCase(permGroupName)) {
                    allowedForegroundState.isShown = true
                    allowedState.isShown = false
                    allowedForegroundState.isChecked = allowedState.isChecked
                    allowedForegroundState.isEnabled = allowedState.isEnabled
                    if (couldPackageHaveFgCapabilities || (Utils.isEmergencyApp(app, packageName) &&
                                    isMicrophone(permGroupName))) {
                        allowedAlwaysState.isShown = true
                        allowedAlwaysState.isChecked = allowedForegroundState.isChecked
                        allowedAlwaysState.isEnabled = allowedForegroundState.isEnabled
                        allowedForegroundState.isChecked = false
                        allowedForegroundState.isEnabled = false
                        deniedState.isChecked = deniedState.isChecked || askState.isChecked
                        askState.isEnabled = false

                        if (detailId == 0) {
                            detailId = getForegroundCapableDetailResId(foregroundCapableType)
                            if (detailId != 0) {
                                detailResIdLiveData.value = detailId to null
                            }
                        }
                    }
                }
            }
            if (group.packageInfo.targetSdkVersion < Build.VERSION_CODES.M) {
                // Pre-M app's can't ask for runtime permissions
                askState.isShown = false
                deniedState.isChecked = askState.isChecked || deniedState.isChecked
                deniedForegroundState.isChecked = askState.isChecked ||
                    deniedForegroundState.isChecked
            }

            val storageState = fullStorageStateLiveData.value
            if (isStorage && storageState?.isLegacy != true) {
                val allowedAllFilesState = allowedAlwaysState
                val allowedMediaOnlyState = allowedForegroundState
                if (storageState != null) {
                        // Set up the tri state permission for storage
                        allowedAllFilesState.isEnabled = allowedState.isEnabled
                        allowedAllFilesState.isShown = true
                        if (storageState.isGranted) {
                            allowedAllFilesState.isChecked = true
                            deniedState.isChecked = false
                        }
                } else {
                    allowedAllFilesState.isEnabled = false
                    allowedAllFilesState.isShown = false
                }
                allowedMediaOnlyState.isShown = true
                allowedMediaOnlyState.isEnabled = allowedState.isEnabled
                allowedMediaOnlyState.isChecked = allowedState.isChecked &&
                    storageState?.isGranted != true
                allowedState.isChecked = false
                allowedState.isShown = false
            }

            value = mapOf(ALLOW to allowedState, ALLOW_ALWAYS to allowedAlwaysState,
                ALLOW_FOREGROUND to allowedForegroundState, ASK_ONCE to askOneTimeState,
                ASK to askState, DENY to deniedState, DENY_FOREGROUND to deniedForegroundState)
        }
    }

權(quán)限請求

targetSdkVersion設(shè)置為高版本后, 下面的權(quán)限請求代碼, 只能申請到僅允許訪問媒體文件

		String[] perms = {
				//"android.permission.MANAGE_EXTERNAL_STORAGE",
				Manifest.permission.MANAGE_EXTERNAL_STORAGE,
				Manifest.permission.READ_EXTERNAL_STORAGE,
				Manifest.permission.WRITE_EXTERNAL_STORAGE,
		};
		requestPermissions(perms, 0x01);

實際上, MANAGE_EXTERNAL_STORAGE現(xiàn)傳統(tǒng)的讀寫權(quán)限有很大的區(qū)別, 它與浮窗的權(quán)限類似, 由AppOpsService進行管理, 上面的代碼, 不是能直接向AppOpsService申請權(quán)限.

開發(fā)者可以借助三方工具實現(xiàn)權(quán)限請求一般會通過調(diào)起系統(tǒng)的授權(quán)窗口, 引導(dǎo)用戶操作授權(quán):

  1. 方法 一
    設(shè)置 > 應(yīng)用和通知 > 高級 特殊應(yīng)用權(quán)限 > 所有文件訪問權(quán)限 > App名稱 > 授予所有文件管權(quán)限
  2. 方法 二 (實際去到了PermissionController)
    設(shè)置 > 應(yīng)用和通知 > 所有應(yīng)用 > App名稱 > 權(quán)限 > 文件和媒體 > 允許管理所有文件
//方法1
START u0 {act=android.settings.MANAGE_APP_ALL_FILES_ACCESS_PERMISSION dat=package:com.android.apitester cmp=com.android.settings/.Settings$AppManageExternalStorageActivity}
方法2
START u0 {act=android.intent.action.MANAGE_APP_PERMISSIONS cmp=com.android.permissioncontroller/.permission.ui.ManagePermissionsActivity (has extras)} from uid 1000

這里不作細述.


對于XXPermissions試了下, 有兩點不習慣的地方:

  1. 要求支持android.support.v4.app.Fragment
ApiTester/src/main/java/com/android/apitester/PermissionTest.java:78: error: cannot access Fragment
		XXPermissions.with(this)
		             ^
  class file for android.support.v4.app.Fragment not found
//所以還得增加依賴包
implementation 'com.android.support:appcompat-v7:27.1.1'

2.異常

Caused by: java.lang.IllegalArgumentException: If you have applied for MANAGE_EXTERNAL_STORAGE permissions, do not apply for the READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE permissions
   at com.hjq.permissions.PermissionChecker.optimizeDeprecatedPermission(PermissionChecker.java:239)
   at com.hjq.permissions.XXPermissions.request(XXPermissions.java:167)
   at com.android.apitester.PermissionTest.onCreate(PermissionTest.java:34)
   at android.app.Activity.performCreate(Activity.java:8022)
   at android.app.Activity.performCreate(Activity.java:8006)
   at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
   at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3404)
   at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3595) 
   at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85) 
   at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
   at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
   at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066) 
   at android.os.Handler.dispatchMessage(Handler.java:106) 
   at android.os.Looper.loop(Looper.java:223) 
   at android.app.ActivityThread.main(ActivityThread.java:7664) 
   at java.lang.reflect.Method.invoke(Native Method) 
   at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592) 
   at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947) 

參考

  1. Android 11 中的存儲機制更新
    manage_external_storage,android-framework,android,android,文件權(quán)限,permission

  2. 分區(qū)存儲
    manage_external_storage,android-framework,android,android,文件權(quán)限,permission
    Android權(quán)限適配
    android grantRuntimePermission 詳解
    XXPermissions文章來源地址http://www.zghlxwxcb.cn/news/detail-793998.html

到了這里,關(guān)于Android 11 上的文件讀寫權(quán)限(MANAGE_EXTERNAL_STORAGE)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔相關(guān)法律責任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • android11 申請所有文件訪問權(quán)限

    android11 申請所有文件訪問權(quán)限

    Android 11 引入了強制執(zhí)行分區(qū)存儲的限制,導(dǎo)致應(yīng)用默認不能訪問外部文件。 針對以前涉及較多文件的操作,可采用申請所有文件訪問權(quán)限的方式來解決這一問題,實現(xiàn)方式如下。 (雖然這樣做安全性低,官方并不推薦這樣,但確實最快適配原有應(yīng)用程序的方式) 1. Android

    2024年02月04日
    瀏覽(29)
  • 手機無法訪問”xxx”目錄(Android 11及以上授予文件管理權(quán)限)的解決方法

    Android11改變了此前安卓系統(tǒng)對文件管理的規(guī)則,在Android11上,文件讀寫變成了特殊權(quán)限。應(yīng)用默認只能讀寫自己的目錄/android/data/包名,這就導(dǎo)致我們想修改某個文件里的內(nèi)容,結(jié)果卻沒有讀寫權(quán)限。本文主要提供一種解決方法——root+adb。 進入adb+ROOT權(quán)限開啟 我們進入 adb s

    2024年02月16日
    瀏覽(31)
  • Android申請權(quán)限(相機權(quán)限和讀寫權(quán)限)

    Android申請權(quán)限(相機權(quán)限和讀寫權(quán)限)

    開發(fā)一個相機應(yīng)用,需要申請三個權(quán)限:相機、讀文件、寫文件。 初步授權(quán)成功

    2024年02月11日
    瀏覽(27)
  • android 12 SD動態(tài)申請讀寫權(quán)限

    android 12 SD動態(tài)申請讀寫權(quán)限

    android 12不僅需要在AndroidManifest.xml申請讀寫權(quán)限也需要在代碼中動態(tài)的申請 關(guān)于如何動態(tài)申請讀寫權(quán)限僅需要兩步 在AndroidManifest.xml文件中申請讀寫權(quán)限 在代碼的啟動MainActivity中動態(tài)申請方法 下面是關(guān)于動態(tài)權(quán)限申請的Manifest.class類大家有興趣可以去了解下

    2024年02月11日
    瀏覽(26)
  • android 高版本sd卡目錄讀寫權(quán)限

    1、從安卓11不允許訪問sd目錄,官方說明如下: https://developer.android.com/about/versions/11/privacy/storage?hl=zh-cn 2、使用MediaStore方法 一手遮天 Android - 存儲: Android 11 通過 MediaStore 管理文件 - webabcd - 博客園 (cnblogs.com)? 3、關(guān)于權(quán)限的文章 (31條消息) Android 10、11分區(qū)存儲適配踩坑總結(jié)_安

    2024年02月15日
    瀏覽(17)
  • Android 10以上出現(xiàn)的 android Permission denied 讀寫權(quán)限問題解決方法

    原因: 從Android 10 開始,應(yīng)用即使申請了權(quán)限,也只能讀寫自己外部存儲的私有目錄,就是Android/data/對應(yīng)應(yīng)用包名 下的相關(guān)目目錄。除此之外任何目錄的讀寫都會被拒絕,并提示 android Permission denied。 解決方案 在 AndroidManifest.xml 文件中,在application標簽中添加如下屬性 and

    2024年02月03日
    瀏覽(89)
  • Android 12.0系統(tǒng)默認授予讀寫權(quán)限給第三方app

    ?在12.0的系統(tǒng)rom定制化開發(fā)中, 在6.0以前讀寫權(quán)限是默認授予的,app不需要申請權(quán)限 在10.0之前需要android.permission.WRITE_EXTERNAL_STORAGE和android.permission.READ_EXTERNAL_STORAGE 權(quán)限就可以了而在安卓11的時候繼續(xù)強化對SD卡讀寫的管理,引入了MANAGE_EXTERNAL_STORAGE權(quán)限,而之前的WRITE_EXTER

    2024年02月12日
    瀏覽(201)
  • linux更改文件的讀寫執(zhí)行等權(quán)限

    查看權(quán)限 ls -al 語法如下: chmod [who] [+ | - | =] [mode] 文件名 命令中各選項的含義為 u 表示“用戶(user)”,即文件或目錄的所有者。 g 表示“同組(group)用戶”,即與文件屬主有相同組ID的所有用戶。 o 表示“其他(others)用戶”。 a 表示“所有(all)用戶”。它是系統(tǒng)默認

    2024年02月10日
    瀏覽(17)
  • Golang:文件讀寫操作WriteFile、ReadFile和0644權(quán)限

    Golang:文件讀寫操作WriteFile、ReadFile和0644權(quán)限

    方法簽名 示例代碼 關(guān)于 0644 權(quán)限,可以參考下圖 第0位:文件屬性?!?” 表示普通文件;“d” 表示是一個目錄 第1~3位:文件所有者的權(quán)限 第4~6位:文件所屬用戶組的權(quán)限 第7~9位:其他人的權(quán)限 參考 Go寫文件的權(quán)限 WriteFile(filename, data, 0644)? Golang 基礎(chǔ)之文件操作

    2024年04月28日
    瀏覽(19)
  • 安卓學(xué)習筆記:安卓11訪問/讀寫 Android/data 目錄

    安卓學(xué)習筆記:安卓11訪問/讀寫 Android/data 目錄

    省流提示:采用android studio工具開發(fā),記錄一次低級的開發(fā),避免以后忘記或者踩坑。 最近有個業(yè)余項目開發(fā)到一小半,過程中需要讀寫 Android/data目錄的文件,采用常規(guī)的文件操作總是提示權(quán)限被拒絕,無奈上網(wǎng)參考了很多資料,終于得到了解決。 無法訪問Android/data 的原因

    2024年02月13日
    瀏覽(32)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包