Android11 无Root 访问data目录实现、Android11访问data目录、Android11解除data目录限制、Android11 data空白解决

本文详细介绍了如何在Android11及以上系统中无Root访问Android/data目录,包括通过SAF框架、DocumentFile API以及利用ROOT权限的解决方法。作者提供了一个已实现的文件管理应用,供用户和开发者参考。
摘要由CSDN通过智能技术生成

正文开始

关于Android11权限变化

谷歌在Android11及以上系统中采用了文件沙盒存储模式,导致第三方应用无法像以前一样访问Android/data目录,这是好事。但是我所不能理解的是已经获得"所有文件管理"权限的APP为何还是限制了,岂不是完全不留给清理、文件管理类软件后路?实在不应该!

作为普通安卓用户该如何方便快速地访问Android/data目录

众所周知,不能访问Android/data目录非常不方便,比如要管理QQ、微信接收到的文件、其他App下载的数据(如迅雷等等)。

现本人开发的应用已实现无Root访问Android/data目录(其中文件浏览器功能),并且可以方便地进行管理。

https://www.coolapk.com/apk/com.magicalstory.cleaner

软件下载

欢迎安卓手机用户下载使用 和 Android开发者下载预览功能的实现。

App界面预览
在这里插入图片描述

开发者该如何实现无ROOT访问Data目录

1.首先,可根据需要获取所有文件管理权限:
在清单中声明:

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission
        android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
        tools:ignore="ScopedStorage" />

2.动态获取读写权限,这个不用多说了吧,如果觉得麻烦可以使用郭霖大神的permissionX库
Github

关于"管理所有文件"权限
这个权限可以让你的App跟Android11以前一样,通过File API访问所有文件(除Android/data目录)

如有需要,请在清单声明不启用沙盒存储

        android:preserveLegacyExternalStorage="true"
        android:requestLegacyExternalStorage="true"

相关判断

   //判断是否需要所有文件权限
            if (!(Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && !Environment.isExternalStorageManager())) {
   
            //表明已经有这个权限了
            }

获取权限

  Intent intent = new Intent(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
            startActivity(intent);

正式开始解决Android/data问题

首先,使用的方式是SAF框架(Android Storage Access Framework)
这个框架在Android4.4就引入了,如果没有了解过的话,可以百度。

获取某个文件目录的权限

方法很简单,使用android.intent.action.OPEN_DOCUMENT_TREE(调用SAF框架的文件选择器选择一个文件夹)的Intent就可以授权了
等下会放出工具类,现在看下例子:

//获取指定目录的访问权限
 public static void startFor(String path, Activity context, int REQUEST_CODE_FOR_DIR) {
   
        statusHolder.path = path;//这里主要是我的一个状态保存类,说明现在获取权限的路径是他,大家不用管。
        String uri = changeToUri(path);//调用方法,把path转换成可解析的uri文本,这个方法在下面会公布
        Uri parse = Uri.parse(uri);
        Intent intent = new Intent("android.intent.action.OPEN_DOCUMENT_TREE");
        intent.addFlags(
                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) {
   
            intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, parse);
        }
        context.startActivityForResult(intent, REQUEST_CODE_FOR_DIR);//开始授权
    }

调用后的示意图:
在这里插入图片描述

回调并永久保存某个目录的权限

    //返回授权状态
    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
   
        super.onActivityResult(requestCode, resultCode, data);
        Uri uri;

        if (data == null) {
   
            return;
        }

        if (requestCode == REQUEST_CODE_FOR_DIR && (uri = data.getData()) != null) {
   
            getContentResolver().takePersistableUriPermission(uri, data.getFlags
### 回答1: 用 sklearn 库中的 KMeans 算法进行聚类分析后,可以使用 Matplotlib 库进行可视化。可以使用 scatter 方法绘制数据点,并使用不同颜色表示不同类别。代码示例如下: ``` from sklearn.cluster import KMeans from matplotlib import pyplot as plt # 进行 KMeans 聚类 kmeans = KMeans(n_clusters=3) kmeans.fit(X) # 绘制聚类结果 plt.scatter(X[:, 0], X[:, 1], c=kmeans.labels_) plt.show() ``` 其中 X 是待聚类数据,n_clusters 是聚类数量。 ### 回答2: k-means是一种常见的聚类算法,在机器学习中应用广泛。sklearn库中提供了k-means算法的实现,同时也支持对聚类结果进行可视化展示,方便用户观察聚类结果并进一步分析。 在sklearn中,通过导入sklearn.cluster中的KMeans类来使用k-means算法。在使用KMeans类前,需要指定算法参数,如簇类数量、初始质心位置等。具体参数配置可参照官方文档进行设置。 针对聚类结果的可视化展示,sklearn提供了多种方法。以下介绍两种常见的可视化方法: 1. 绘制散点图 将聚类结果用散点图进行可视化是一种常见方法。在绘制散点图时,通常根据聚类簇别,对不同数据点进行颜色编码,以便用户能够更清晰地区分不同类别的数据点。代码示例: ``` import matplotlib.pyplot as plt # 聚类簇别结果保存在labels中 # 聚类中心位置保存在cluster_centers_中 # X为原始数据 for i in range(n_clusters): plt.scatter(X[labels == i, 0], X[labels == i, 1], s=30, label='Cluster %d' % (i+1)) plt.scatter(cluster_centers_[:, 0], cluster_centers_[:, 1], marker='*', s=200, label='Centroids') plt.legend() plt.show() ``` 2. 绘制决策边界 决策边界用于划分不同聚类簇别的区域,相邻区域的簇别不同。通过绘制决策边界,可以更清晰地展示不同聚类簇别的分布情况。代码示例: ``` from sklearn.metrics import pairwise_distances_argmin # 聚类簇别结果保存在labels中 # X为原始数据 def plot_kmeans(kmeans, X, n_clusters=3, rseed=0, ax=None): labels = kmeans.fit_predict(X) # 绘制决策边界 ax = ax or plt.gca() ax.axis('equal') ax.scatter(X[:, 0], X[:, 1], c=labels, s=40, cmap='viridis', zorder=2) # 绘制聚类中心 centers = kmeans.cluster_centers_ radii = [cdist(X[labels == i], [center]).max() for i, center in enumerate(centers)] for c, r in zip(centers, radii): ax.add_patch(plt.Circle(c, r, fc='#CCCCCC', lw=3, alpha=0.5, zorder=1)) kmeans = KMeans(n_clusters=3, random_state=0) plot_kmeans(kmeans, X) plt.show() ``` 无论是绘制散点图还是绘制决策边界,k-means聚类的可视化展示都能够为用户提供全局性的聚类结果,方便用户进一步分析和探索数据。 ### 回答3: 机器学习中的K均值聚类算法是一种无监督学习方法,可用于将数据点分成不同的类别。在scikit-learn(sklearn)包中,我们可以使用KMeans类来实现K均值聚类算法,同时通过可视化的方式更直观地了解到该算法的结果。 首先,我们需要生成一些数据。在这里,可以通过使用make_blobs函数生成随机的数据点,并将其分成不同的类别。然后,我们可以使用KMeans类对这些数据点进行聚类分析。在KMeans类中,我们可以设置聚类的数量(也称为k值)和迭代次数(max_iter)。例如,我们可以设置k值为3,迭代次数为100,并使用fit_predict函数进行聚类,将每个数据点分配到其所属的簇中。 接下来,我们可以使用matplotlib库来可视化聚类结果。对于二维数据,我们可以使用散点图来显示每个数据点所属的簇。我们还可以使用不同的颜色来区分不同的簇,使得结果更加直观。在二维数据的情况下,可以使用plt.scatter函数来绘制散点图,使用不同的颜色为不同的簇分配不同的值。我们还可以使用KMeans类的cluster_centers_属性来显示每个簇的中心点,用不同的标记区分每个簇的中心点。 总之,通过使用sklearn kmeans聚类可视化,我们可以更好地了解K均值聚类算法的工作原理,并更好地理解每个数据点所属的不同簇。此外,该过程也可以帮助我们选择最佳的k值和max_iter值,以便获得更好的聚类结果。
评论 76
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值