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

Android 5.0 ~ 14訪問Android/data(obb)目錄的方法

這篇具有很好參考價值的文章主要介紹了Android 5.0 ~ 14訪問Android/data(obb)目錄的方法。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

眾所周知,安卓每次出新版本的時候都會收緊權(quán)限,存儲權(quán)限也不例外。雖說官方的意思是為了保護隱私安全,但這些改動著實令開發(fā)者和用戶感到頭疼,尤其是Android/data、Android/obb目錄的訪問。畢竟用戶更難操作,開發(fā)者也要費力適配。那么今天就來探索下怎么適配這些變更點吧。

不同安卓版本存儲權(quán)限差異

1、Android 6.0 之前

應(yīng)用只需要在 AndroidManifest.xml 下聲明以下權(quán)限即可自動獲取存儲權(quán)限:?

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

2、Android 6.0 起

從Android 6.0開始,除了以上操作以外,還需要在代碼中動態(tài)申請權(quán)限。

// 檢查是否有存儲權(quán)限
boolean granted = context.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) ==
 ? ?PackageManager.PERMISSION_GRANTED;
// 在activity中請求存儲權(quán)限
requestPermissions(new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, 0);

3、Android 10

Android 10 開始引入了沙盒機制,應(yīng)用在 sdcard 中默認只能讀寫私有目錄(即/sdcard/Android/data/[應(yīng)用包名]/),其他目錄即便執(zhí)行前面的操作也無法讀寫。除非在 AndroidManifest.xml 下聲明以下屬性:

<application
 ? ? ? ?...
 ? ? ? ?android:requestLegacyExternalStorage="true">

這樣的話就會暫時停用沙盒機制,正常讀寫/sdcard下文件。

4、Android 11

Android 11開始,且應(yīng)用的目標(biāo)版本在30及以上,以上的操作也無法再讀寫sdcard目錄。需要聲明以下權(quán)限:

<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />

再動態(tài)申請權(quán)限:

// 檢查是否有存儲權(quán)限
boolean granted = Environment.isExternalStorageManager();
// 在activity中請求存儲權(quán)限
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)
 ?  .setData(Uri.parse("package:"+getPackageName()));
startActivityForResult(intent, 0);

執(zhí)行以上操作后,sdcard已能夠正常讀寫。

但是,有2個特殊的目錄仍然無法讀寫:

/sdcard/Android/data/sdcard/Android/obb 。

這兩個路徑需要安卓自帶的 DocumentsUI 授權(quán)才能訪問。

首先,最重要的一點,添加 documentfile 依賴(SDK自帶的那個版本有問題):

implementation "androidx.documentfile:documentfile:1.0.1"

Activity請求授權(quán):

Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION |
 ? ? ? ? ? ? ? ?Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
 ? ?// 請求Android/data目錄的權(quán)限,Android/obb目錄則把data替換成obb即可。
 ? ?Uri treeUri = Uri.parse("content://com.android.externalstorage.documents/tree/primary%3AAndroid%2Fdata/document/primary%3AAndroid%2Fdata");
 ? ?DocumentFile df = DocumentFile.fromTreeUri(this, treeUri);
 ? ?if (df != null) {
 ? ? ? ?intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, df.getUri());
 ?  }
}
startActivityForResult(intent, 1);

還需要在回調(diào)中保存權(quán)限:

@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
 ? ?super.onActivityResult(requestCode, resultCode, data);
 ? ?Uri uri;
 ? ?if (data != null && (uri = data.getData()) != null) {
 ? ? ? ?// 授權(quán)成功
 ? ? ? ?getContentResolver().takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
 ?  } else {
 ? ? ? ?// 授權(quán)失敗
 ?  }
}

在請求授權(quán)時,會跳轉(zhuǎn)到以下界面。點擊下方按鈕授權(quán)即可。

android14解鎖data目錄,android

android14解鎖data目錄,android

然后,使用接口獲取文件列表:

// Android 11~12轉(zhuǎn)換路徑。例如:/sdcard/Android/data,轉(zhuǎn)換成:
// Uri.parse("content://com.android.externalstorage.documents/tree/primary%3AAndroid%2Fdata/document/primary%3AAndroid%2Fdata")

// 路徑 /sdcard/Android/data/com.xxx.yyy,轉(zhuǎn)換成:
// Uri.parse("content://com.android.externalstorage.documents/tree/primary%3AAndroid%2Fdata/document/primary%3AAndroid%2Fdata%2Fcom.xxx.yyy")
// 以此類推。
Uri pathUri = pathToUri(path);
DocumentFile documentFile = DocumentFile.fromTreeUri(context, pathUri);
if (documentFile != null) {
    DocumentFile[] documentFiles = documentFile.listFiles();
    for (DocumentFile df : documentFiles) {
        // 文件名
        String fName = df.getName();
        // 路徑
        String fPath = path + "/" + fName;
    }
}

5、Android 13

Android 13 開始,上面提到的授權(quán) Android/data、Android/obb目錄的方法失效了。請求授權(quán)會出現(xiàn)如下界面:

android14解鎖data目錄,android

點擊下方按鈕會提示:

android14解鎖data目錄,android

說明安卓13無法再直接授權(quán) Android/data 和 Android/obb 這兩個目錄了。但也并非無計可施。我們可以授權(quán)他們的子目錄。

我們知道,這個目錄下的文件夾名稱一般都是應(yīng)用的包名。我們可以直接用應(yīng)用包名的路徑來請求授權(quán)。

這里要注意,Android 13和Android 11~12的路徑轉(zhuǎn)換規(guī)則不一樣。

// Android 13轉(zhuǎn)換路徑。例如:/sdcard/Android/data/com.xxx.yyy,轉(zhuǎn)換成:
// Uri.parse("content://com.android.externalstorage.documents/tree/primary%3AAndroid%2Fdata%2Fcom.xxx.yyy/document/primary%3AAndroid%2Fdata%2Fcom.xxx.yyy")

// 路徑 /sdcard/Android/data/com.xxx.yyy/files,轉(zhuǎn)換成:
// Uri.parse("content://com.android.externalstorage.documents/tree/primary%3AAndroid%2Fdata%2Fcom.xxx.yyy/document/primary%3AAndroid%2Fdata%2Fcom.xxx.yyy%2Ffiles")
// 以此類推。

請求授權(quán)時,出現(xiàn)如下界面。照常授權(quán)即可。

android14解鎖data目錄,android

6、Android 14

Android 14對于data、obb目錄的授權(quán)進一步收緊。在Android 14的后期版本和Android 15預(yù)覽版中,以上方法已失效(傳入uri請求授權(quán)只會跳轉(zhuǎn)到sdcard根目錄)。這種情況下,想要訪問data和obb目錄就需要使用Shizuku了。(目前MT、FV就是用這種方法訪問的)

Shizuku的用法可以查閱相關(guān)教程,這里不多贅述。請先將Shizuku啟動,便于后續(xù)使用。

首先,添加Shizuku的依賴:

def shizuku_version = "13.1.5"
implementation "dev.rikka.shizuku:api:$shizuku_version"
// Add this line if you want to support Shizuku
implementation "dev.rikka.shizuku:provider:$shizuku_version"

AndroidManifest.xml添加以下內(nèi)容:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">

    <uses-sdk tools:overrideLibrary="rikka.shizuku.api, rikka.shizuku.provider, rikka.shizuku.shared, rikka.shizuku.aidl" />
    <uses-permission android:name="moe.shizuku.manager.permission.API_V23" />

    <application>
        <provider
            android:name="rikka.shizuku.ShizukuProvider"
            android:authorities="${applicationId}.shizuku"
            android:enabled="true"
            android:exported="true"
            android:multiprocess="false"
            android:permission="android.permission.INTERACT_ACROSS_USERS_FULL" />
        <meta-data
            android:name="moe.shizuku.client.V3_SUPPORT"
            android:value="true" />
    </application>
</manifest>

判斷Shizuku是否安裝:

private static boolean isShizukuInstalled() {
    try {
        context.getPackageManager().getPackageInfo("moe.shizuku.privileged.api", 0);
        return true;
    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
    }
    return false;
}

判斷Shizuku是否可用:

boolean available = Shizuku.pingBinder();

檢查Shizuku是否授權(quán):

boolean granted = Shizuku.checkSelfPermission() == PackageManager.PERMISSION_GRANTED;

請求Shizuku權(quán)限:

Shizuku.requestPermission(0);

監(jiān)聽授權(quán)結(jié)果:

Shizuku.addRequestPermissionResultListener(listener);
Shizuku.removeRequestPermissionResultListener(listener);

授權(quán)后,自己定義一個aidl文件:

IFileExplorerService.aidl

package com.magicianguo.fileexplorer.userservice;

import com.magicianguo.fileexplorer.bean.BeanFile;

interface IFileExplorerService {
    List<BeanFile> listFiles(String path);
}

BeanFile.java

public class BeanFile implements Parcelable {
    public BeanFile(String name, String path, boolean isDir, boolean isGrantedPath, String pathPackageName) {
        this.name = name;
        this.path = path;
        this.isDir = isDir;
        this.isGrantedPath = isGrantedPath;
        this.pathPackageName = pathPackageName;
    }

    /**
     * 文件名
     */
    public String name;
    /**
     * 文件路徑
     */
    public String path;
    /**
     * 是否文件夾
     */
    public boolean isDir;
    /**
     * 是否被Document授權(quán)的路徑
     */
    public boolean isGrantedPath;
    /**
     * 如果文件夾名稱是應(yīng)用包名,則將包名保存到該字段
     */
    public String pathPackageName;

    protected BeanFile(Parcel in) {
        name = in.readString();
        path = in.readString();
        isDir = in.readByte() != 0;
        isGrantedPath = in.readByte() != 0;
        pathPackageName = in.readString();
    }

    public static final Creator<BeanFile> CREATOR = new Creator<BeanFile>() {
        @Override
        public BeanFile createFromParcel(Parcel in) {
            return new BeanFile(in);
        }

        @Override
        public BeanFile[] newArray(int size) {
            return new BeanFile[size];
        }
    };

    @Override
    public int describeContents() {
        return 0;
    }

    @Override
    public void writeToParcel(@NonNull Parcel dest, int flags) {
        dest.writeString(name);
        dest.writeString(path);
        dest.writeByte((byte) (isDir ? 1 : 0));
        dest.writeByte((byte) (isGrantedPath ? 1 : 0));
        dest.writeString(pathPackageName);
    }
}

IFileExplorerService實現(xiàn)類:

public class FileExplorerService extends IFileExplorerService.Stub {

    @Override
    public List<BeanFile> listFiles(String path) throws RemoteException {
        List<BeanFile> list = new ArrayList<>();
        File[] files = new File(path).listFiles();
        if (files != null) {
            for (File f : files) {
                list.add(new BeanFile(f.getName(), f.getPath(), f.isDirectory(), false, f.getName()));
            }
        }
        return list;
    }
}

然后使用Shizuku綁定UserService:

private static final Shizuku.UserServiceArgs USER_SERVICE_ARGS = new Shizuku.UserServiceArgs(
    new ComponentName(packageName, FileExplorerService.class.getName())
).daemon(false).debuggable(BuildConfig.DEBUG).processNameSuffix("file_explorer_service").version(1);

public static IFileExplorerService iFileExplorerService;

private static final ServiceConnection SERVICE_CONNECTION = new ServiceConnection() {
    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        Log.d(TAG, "onServiceConnected: ");
        iFileExplorerService = IFileExplorerService.Stub.asInterface(service);
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        Log.d(TAG, "onServiceDisconnected: ");
        iFileExplorerService = null;
    }
};

// 綁定服務(wù)
public static void bindService() {
    Shizuku.bindUserService(USER_SERVICE_ARGS, SERVICE_CONNECTION);
}

綁定之后,調(diào)用 aidl 里面的方法來管理文件即可。

源代碼:GitHub - MagicianGuo/Android-FileExplorerDemo: 能夠訪問Android/data(obb)目錄,已適配Android 5.0 ~ 14。安卓高版本可以使用Shizuku授權(quán)。文章來源地址http://www.zghlxwxcb.cn/news/detail-842940.html

到了這里,關(guān)于Android 5.0 ~ 14訪問Android/data(obb)目錄的方法的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

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

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

相關(guān)文章

  • Android 11 訪問 Android/data/或者getExternalCacheDir() root方式

    前言 : 需求要求安裝三方應(yīng)用ExternalCacheDir()下載下來的apk文件。 getExternalCacheDir() : /storage/emulated/0/Android/data/com. . /cache/ 獲取訪問權(quán)限 如果手機安卓版本為Android10的時候,可以在AndroidManifest.xml中添加下列代碼 以此禁用分區(qū)存儲,但這在Android11及以上版本不起作用。 root方式 (

    2024年02月21日
    瀏覽(19)
  • Android免Root執(zhí)行腳本,無Root可以修改權(quán)限的目錄 :/data/local/tmp

    在Android中,訪問data目錄是需要root權(quán)限,但是有個例外那就是/data/local/tmp目錄,這個目錄通過使用ADB來打開就會擁有讀寫權(quán)限! 注意: (1)這個目錄不能一級一級的打開,需要通過cd ?/data/local/tmp 一次性進入 (2)該目錄下的文件屬性,權(quán)限都是可以修改的,例如chmod 777 /d

    2024年02月09日
    瀏覽(24)
  • 關(guān)于安卓13中Android/data目錄下的文件夾只能查看無法進行刪改的問題

    因為升級了安卓13,然后有個app需要恢復(fù)數(shù)據(jù),打算和以前一樣直接刪除Android/data下對應(yīng)目錄再添加,結(jié)果不行,以下是結(jié)合網(wǎng)上以及自己手機情況來做的一種解決方案。 準(zhǔn)備: 待恢復(fù)app(包名com.test.ai) 其他app(包名com.other.ai,這個app當(dāng)做臨時變量就行,隨便任意app,且知

    2024年02月09日
    瀏覽(30)
  • 使用 adb 命令修改 Android/data 目錄下的文件(給碧藍檔案國服吃布丁)

    使用 adb 命令修改 Android/data 目錄下的文件(給碧藍檔案國服吃布丁)

    本文記錄如何使用 adb 命令修改 Android/data 目錄下的文件,然后給國服的碧藍檔案打上布丁??~ 今天下午刷著刷著微博就看到國服 BA 又又又發(fā)了和諧公告 ... 心情復(fù)雜。jpg 于是乎終于想起來得吃布丁??了,至于此次更新后布丁有沒有用還未知,但還是先搞上 食用方法之前就出

    2024年03月24日
    瀏覽(20)
  • 手機解鎖方法:8個頂級的 Android 手機解鎖軟件

    手機解鎖方法:8個頂級的 Android 手機解鎖軟件

    一般來說,太簡單的密碼是不安全的,所以我們設(shè)置一個安全的密碼,可能會稍微復(fù)雜一點。然而,我們可能經(jīng)常會忘記復(fù)雜的密碼并鎖定我們的 Android 智能手機。 如果您遇到過這種情況并且正在尋找一種有效的方法來解鎖您的 Android 設(shè)備而不丟失數(shù)據(jù),您可以看看這篇介紹

    2024年02月03日
    瀏覽(27)
  • 從 PC 解鎖 Android 手機的 6 種有效方法

    從 PC 解鎖 Android 手機的 6 種有效方法

    在這個數(shù)字時代,手機已成為我們生活的重要組成部分。我們將它們用于各種用途,從跟蹤我們的工作和社交日程到與親人交流。 然而,有時我們的手機會成為令人沮喪的源頭,尤其是當(dāng)我們不小心將自己拒之門外時。但是您知道可以使用計算機解鎖您的 Android 手機嗎?您可

    2024年02月03日
    瀏覽(16)
  • Android 14新特性,選擇性照片和視頻訪問授權(quán)

    Android 14新特性,選擇性照片和視頻訪問授權(quán)

    本文同步發(fā)表于我的微信公眾號,掃一掃文章底部的二維碼或在微信搜索 郭霖 即可關(guān)注,每個工作日都有文章更新。 今天這篇文章給大家介紹一下Android 14系統(tǒng)中的一個新特性,對部分照片和視頻進行訪問授權(quán),也可以稱之為選擇性照片和視頻訪問授權(quán)。 這是Android系統(tǒng)在隱

    2024年04月17日
    瀏覽(19)
  • Android 訪問存儲卡的三種主要的目錄

    Android 訪問存儲卡(即外部存儲)通常涉及以下三種主要的目錄: 1. 外部存儲公共目錄 (Public External Storage) 這些目錄對所有應(yīng)用都是可見的,并且不需要任何特殊權(quán)限來讀取媒體文件。但是從Android 10(API 級別 29)開始,如果要寫入這些目錄,則需要 WRITE_EXTERNAL_STORAGE 權(quán)限,

    2024年01月24日
    瀏覽(28)
  • [5 種有效方法] 適用于 Android 的通用解鎖圖案/密碼

    [5 種有效方法] 適用于 Android 的通用解鎖圖案/密碼

    在當(dāng)今世界,保護您的密碼對于您的文件和數(shù)據(jù)的安全至關(guān)重要,尤其是在第三方應(yīng)用程序盛行的情況下。為這些應(yīng)用程序注冊帳戶不是問題,就像記住它們一樣。但是,如果您不知何故忘記了手機密碼,您仍然可以在不丟失寶貴數(shù)據(jù)的情況下找到解決方法。 一些工具在互聯(lián)

    2024年02月11日
    瀏覽(17)
  • 瀟灑郎: 小白一次性成功——紅米 Note 12 5G Android12 系統(tǒng)13.0.16/14.0.9 小米紅米手機解BL鎖+ROOT-刷面具—官方ROM下載-線刷降級—解鎖system系統(tǒng)分區(qū)

    瀟灑郎: 小白一次性成功——紅米 Note 12 5G Android12 系統(tǒng)13.0.16/14.0.9 小米紅米手機解BL鎖+ROOT-刷面具—官方ROM下載-線刷降級—解鎖system系統(tǒng)分區(qū)

    下載工具 申請解鎖小米手機 (miui.com) 驅(qū)動安裝進入Fastboot模式后,會自動識別已連接, 否則顯示未連接

    2024年01月25日
    瀏覽(37)

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

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

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

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

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包