Android6以后第三方APP获取读写外部SD卡权限的方法

分析过程:
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权限即可。




猜你喜欢

转载自blog.csdn.net/rookie_wei/article/details/80460795