分析过程:
android6以前,想让第三方APP获的读写外部SD卡的权限,只要修改
frameworks/base/data/etc/platform.xml
将
<permission name="android.permission.WRITE_EXTERNAL_STORAGE" >
<group gid="sdcard_r" />
<group gid="sdcard_rw" />
</permission>
改为
<permission name="android.permission.WRITE_EXTERNAL_STORAGE" >
<group gid="sdcard_r" />
<group gid="sdcard_rw" />
<group gid="media_rw" />
</permission>
即可,但是,安卓6以后能这么改无效,看注释:
<!-- These are permissions that were mapped to gids but we need
to keep them here until an upgrade from L to the current
version is to be supported. These permissions are built-in
and in L were not stored in packages.xml as a result if they
are not defined here while parsing packages.xml we would
ignore these permissions being granted to apps and not
propagate the granted state. From N we are storing the
built-in permissions in packages.xml as the saved storage
is negligible (one tag with the permission) compared to
the fragility as one can remove a built-in permission which
no longer needs to be mapped to gids and break grant propagation. -->
好像跟这个packages.xml文件有关,在安卓开发板的串口下执行命令看看,
find . -name packages.xml
发现这个文件在./data/system/packages.xml
打开改文件看看,
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<packages>
<version sdkVersion="25" databaseVersion="3" fingerprint="Amlogic/p212/p212:7.1.2/NHG47L/20180227:user/test-keys" />
<version volumeUuid="primary_physical" sdkVersion="25" databaseVersion="25" fingerprint="Amlogic/p212/p212:7.1.2/NHG47L/20180227:user/test-keys" />
<permission-trees>
<item name="com.google.android.googleapps.permission.GOOGLE_AUTH" package="com.google.android.gsf" />
</permission-trees>
<permissions>
<item name="android.permission.REAL_GET_TASKS" package="android" protection="18" />
<item name="android.permission.ACCESS_CACHE_FILESYSTEM" package="android" protection="18" />
<item name="android.permission.REMOTE_AUDIO_PLAYBACK" package="android" protection="2" />
<item name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" package="com.android.providers.downloads" />
<item name="android.permission.REGISTER_WINDOW_MANAGER_LISTENERS" package="android" protection="2" />
<item name="android.permission.INTENT_FILTER_VERIFICATION_AGENT" package="android" protection="18" />
<item name="android.permission.BIND_INCALL_SERVICE" package="android" protection="18" />
<item name="com.android.gallery3d.permission.GALLERY_PROVIDER" package="com.android.gallery3d" protection="18" />
<item name="android.permission.WRITE_SETTINGS" package="android" protection="1218" />
。。。。。。
一堆东西,百度了一下这个文件是管理所有apk包的信息的,
想起系统自带的FileBrowser APP是有读写外部SD卡的权限的,那么在packages.xml搜索一下这个apk的信息看看,
<package name="com.droidlogic.FileBrower" codePath="/system/app/FileBrowser" nativeLibraryPath="/system/app/FileBrowser/lib" publicFlags="403226181" privateFlags="0" ft="11e8dc5d800" it="11e8dc5d800" ut="11e8dc5d800" version="1" userId="10038" isOrphaned="true">
<sigs count="1">
<cert index="3" />
</sigs>
<perms>
<item name="android.permission.WRITE_MEDIA_STORAGE" granted="true" flags="0" />
<item name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" granted="true" flags="0" />
<item name="android.permission.WAKE_LOCK" granted="true" flags="0" />
</perms>
<proper-signing-keyset identifier="1" />
</package>
发现它用的是android.permission.WRITE_MEDIA_STORAGE这个权限,那是不是用这个权限就可以了呢?
我这这个packages.xml里搜索了自己的apk,加上这个权限,还真就可以读写外部sd卡了,
但是,只要重新安装app,这个文件就被刷新了,所以你又得手动修改,如果用这种方法这不把人逼疯了吗!
有点思路了,但是你总不能要求用户也这么干吧?这样谁还用你的产品啊?
所以,百度一下是谁创建和管理这个packages.xml文件呢?
百度的结果是PackageManagerService这个服务,那么搜索framework一下这个文件在哪里?
结果是frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
打开来看,21223行代码,就问你怕不怕!
怕也得干啊,我的想法是,写这个代码的人再牛逼他开发的时候总得打印一些东西来调试吧?所以不管三七二十一,将
这个文件所有打印的开关全部打开,然后再安装一下apk,看看打印什么内容,再根据打印的顺序和内容分析,
具体的分析过程太多就不写了(我是解决问题半年后才写的这个笔记),这里直接给出最终的答案,
解决方法
将grantPermissionsLPw函数的
case PermissionInfo.PROTECTION_SIGNATURE: {
里的
if (allowedSig)
改为
if (allowedSig || perm.equals("android.permission.MOUNT_UNMOUNT_FILESYSTEMS")
|| perm.equals("android.permission.WRITE_MEDIA_STORAGE"))
我这个是将android.permission.WRITE_MEDIA_STORAGE和android.permission.MOUNT_UNMOUNT_FILESYSTEMS权限完全开放了,
谁申请都得,如果只想自己的app才能申请的话,只要将其改成
if (allowedSig || pkg.packageName.equals(你APP包名))
即可。
然后apk就用动态申请权限的方法去申请android.permission.WRITE_MEDIA_STORAGE权限即可。
如果您感觉本篇博客对您有帮助,请打开支付宝,领个红包支持一下,祝您扫到99元,谢谢~~
Android6以后第三方APP获取读写外部SD卡权限的方法
最新推荐文章于 2024-06-15 11:23:10 发布