应用Manifest未声明Phone/Storage权限却出现,求原因及解决方法
嘿,这个问题我碰到过好多次了——核心原因就是Android的Manifest合并机制在背后搞事情!你没直接声明的Phone和Storage权限,大概率是你引入的第三方依赖(比如各种SDK、开源库)偷偷加进去的,下面给你拆解原因和解决办法:
Android构建工具在打包时,会自动合并你的应用Manifest、所有依赖库的Manifest,以及系统默认的Manifest内容。如果某个第三方SDK(比如推送、统计、广告类工具)在自己的Manifest里声明了READ_PHONE_STATE(Phone权限)或者WRITE_EXTERNAL_STORAGE(Storage权限),这些权限就会被合并到你的最终Manifest中,哪怕你自己没写。
举个例子:很多推送SDK会声明Phone权限来获取设备标识,一些图片处理库会声明Storage权限来读写缓存文件——这些都是你看不到的隐性依赖权限。
第一步:找到权限的来源
先搞清楚是哪个依赖带进来的权限,有两个简单方法:
- 用Android Studio的Manifest Merger工具:打开你app的
AndroidManifest.xml,切换到底部的「Merged Manifest」标签。在这里你能看到所有合并后的权限,点击权限旁边的小箭头,就能直接跳转到对应的依赖Manifest文件,明确看到是哪个库加的权限。 - 用Gradle命令查看依赖树:在终端执行
./gradlew app:dependencies(Windows用gradlew.bat app:dependencies),然后在输出里搜索你要找的权限名称(比如android.permission.READ_PHONE_STATE),就能定位到对应的依赖。
第二步:强制移除多余权限
在你的app的Manifest文件里,明确添加要移除的权限,并通过tools:node="remove"属性告诉构建工具忽略这个权限的合并。记得先在Manifest根标签里引入tools命名空间!
示例代码:
<manifest xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" package="com.your.app.package"> <!-- 你原本声明的权限 --> <uses-permission android:name="android.permission.SEND_SMS" /> <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <!-- 移除不需要的Phone权限(根据实际合并的权限名调整) --> <uses-permission android:name="android.permission.READ_PHONE_STATE" tools:node="remove" /> <!-- 移除不需要的Storage权限(Android 10+可能是READ_EXTERNAL_STORAGE) --> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" tools:node="remove" /> <!-- 你的其他Manifest内容(application标签等) --> </manifest>
第三步:验证效果
重新构建你的应用,再打开「Merged Manifest」标签确认多余权限已经消失;或者安装应用后,去系统的应用权限设置里检查,应该只剩下你最初声明的Location和SMS权限了。
额外提醒
如果某个依赖必须用到这些权限,但你的应用完全不需要这个功能,那最好考虑替换成更轻量化的依赖,或者联系SDK开发者询问是否有无权限版本。不过绝大多数情况下,用tools:node="remove"就能完美解决问题,不会影响应用功能。
内容的提问来源于stack exchange,提问作者Hasan A Yousef

