如何在已Root的Android Oreo中授予WRITE_APN_SETTINGS权限及适配问题咨询
嘿,这个问题我之前帮不少开发者解决过,针对Android 6.0及以上版本(包括Oreo)Root设备上系统应用无法获取WRITE_APN_SETTINGS权限的问题,我给你梳理几个经过验证的可行方案:
从Android 6.0开始,WRITE_APN_SETTINGS被归为signature|privileged级别的特殊权限,它不在普通的危险权限列表里,所以你没法通过常规的运行时权限申请流程(requestPermissions)获取。哪怕是系统应用,也得满足两个条件之一:要么用系统签名打包,要么被放在系统的priv-app目录下——而Root设备只是给了你更高的系统操作权限,不代表能直接绕过这个权限规则。
方案1:用Root权限执行pm命令直接授权
这是最直接快速的方法,不需要修改应用本身,只要你的设备已经Root,就能通过Shell命令给应用授予权限:
- 先确认你的应用包名(比如
com.yourcompany.apntool) - 在Root权限下执行以下命令:
针对Android Oreo(8.0/8.1),需要加上pm grant com.yourcompany.apntool android.permission.WRITE_APN_SETTINGS--user参数指定主用户(ID为0):
执行完这个命令后,你的应用就能正常调用APN相关的API了。su -c "pm grant --user 0 com.yourcompany.apntool android.permission.WRITE_APN_SETTINGS"
方案2:把应用移到系统priv-app目录(适合系统应用)
如果你的应用本身就是系统应用,把它从/system/app/移到/system/priv-app/目录下,再用系统签名打包,重启设备后系统会自动授予WRITE_APN_SETTINGS权限:
- 在Root模式下,创建对应应用的文件夹:
mkdir /system/priv-app/YourApp - 把你的APK复制到这个文件夹:
cp your_app.apk /system/priv-app/YourApp/ - 修改APK文件权限:
chmod 644 /system/priv-app/YourApp/your_app.apk - 重启设备,系统会识别这是一个privileged级别的系统应用,自动赋予所需权限。
方案3:Root权限下直接操作APN数据库(绕过权限检查)
如果上面的方法都不适用,你可以直接通过Root权限操作存储APN数据的数据库,完全绕过系统权限验证:
APN数据存在/data/data/com.android.providers.telephony/databases/telephony.db的carriers表中,你可以用Root权限执行sqlite3命令来添加、修改或删除APN条目:
su -c "sqlite3 /data/data/com.android.providers.telephony/databases/telephony.db 'INSERT INTO carriers (name, apn, proxy, port) VALUES (\"MyCustomAPN\", \"myapn.example.com\", \"\", \"\");'"
当然,你也可以在应用里通过Root进程调用ContentResolver的API,因为Root进程可以跳过系统的权限检查。
在Oreo中,权限管控更严格,除了方案1里需要加--user 0参数外,你也可以用appops命令来设置权限:
su -c "appops set com.yourcompany.apntool WRITE_APN_SETTINGS allow"
不过pm grant命令的可靠性更高,优先推荐使用。
内容的提问来源于stack exchange,提问作者Md. Rashadul Alam

