Android10/11使用ProcessBuilder调用/system/bin/sh执行Python报权限拒绝问题
问题根因
- 你遇到的权限报错和存储权限完全无关,是Android 10(API 29)及以上版本引入的可执行文件权限限制导致的:Google从API 29开始推行W^X安全策略,禁止应用在私有目录(/data/user/0/包名/)、外部存储目录下执行任意下载、解压写入的第三方二进制可执行文件,哪怕文件是你的应用自己写入的,也没有执行权限。
- 你之前申请的
READ_EXTERNAL_STORAGE、MANAGE_EXTERNAL_STORAGE等权限仅控制文件的读写能力,不赋予文件执行权限,因此完全不解决该问题。 - API < 29的版本没有该限制,所以你的代码在Android 10以下可以正常运行。
可行解决方案
- 方案1:降级targetSdkVersion到28(Android 9)
该方案可以直接绕过限制,但仅适合临时测试使用,目前国内主流应用商店已经要求应用targetSdkVersion≥31,该方案无法满足上架要求。 - 方案2:将Python二进制伪装成原生库打包
这是最通用的合规解决方案:- 把你要用的对应ABI架构的Python可执行文件改名为
libpythonxxx.so的格式(比如libpython310.so,前缀必须是lib,后缀必须是.so) - 将改名后的文件放到项目的
jniLibs对应架构目录下(比如jniLibs/arm64-v8a/、jniLibs/armeabi-v7a/) - 在
AndroidManifest.xml的application标签中添加属性android:extractNativeLibs="true",确保安装时系统会把这个伪装的so文件解压到应用的/data/app/[包名]/lib/[架构]/目录下,该目录下的文件系统默认赋予执行权限 - 调用时直接使用该lib目录下的文件路径即可,不需要再自己放到files目录下
- 把你要用的对应ABI架构的Python可执行文件改名为
- 方案3:使用成熟的Python集成框架
直接使用Chaquopy框架集成Python功能,框架已经做好了全Android版本的适配,不需要你自己处理二进制调用、权限适配等问题,直接在Java/Kotlin层即可调用Python代码、导入Python依赖包,是长期维护项目的最优选择。 - 方案4:如果是root设备,可以申请root权限后执行,但该方案仅适合自用测试,完全不适合普通用户使用。
内容的提问来源于stack exchange,提问作者BestAndroid
相关产品推荐
相关产品推荐

