注意:此问题特定于Unity3D
我在Plugins/Android/
文件夹下的Unity项目中有一个非常干净的Android清单文件,根本没有<uses-permissions/>
标记。我相信最终APK中的某些权限来自Android播放器设置,例如READ_EXTERNAL_STORAGE
。在我的Gear VR项目中,我看到最终清单中添加了以下行,可以在Temp/StagingArea/
中访问:
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-feature android:name="android.hardware.microphone" android:required="false" />
现在这肯定来自我项目中的一个插件(我有很多插件)。
我的应用程序被Oculus拒绝了
您的应用要求使用用户的用户权限过高 权限不当。
我找到了一个解决方法here,但我不想做这样的事情,因为这可能会再次导致拒绝应用。
所以
有没有办法让我知道这个权限来自哪里?
如何查明我的脚本中是否有某些代码导致统一包含此权限?
谢谢
答案 0 :(得分:2)
Unity会在构建期间动态添加权限,如eriQue of Unity Technologies所述,这是为了防止代码出现故障和意外行为。
您可以使用此Apk-decompiler之类的工具来查看新的清单以及它使用的权限。基于此,您可以查找可能触发这些权限的某些功能。
isGeniune
等某些功能需要多个权限,因为它会对外部服务器使用验证。
或者,您也可以在反编译的APK中替换清单,手动将清单更改为预期的清单,然后重新签名。这是一些更繁琐的工作,但如果有适当的错误记录,它可能会加快追踪有问题的功能的过程。
<强>更新强>
正如我在下面的评论中提到的那样。没有真正的方法来确定功能。但快速检查清单不会有害,但需要一些工作
很多外部服务,想想google,twitter,facebook api和工具都需要额外的权限。通常这些与存储/网络相关,但根据工具/ api的目标,它可能会更多。
尝试使用和不使用工具/ apis构建您的APK,看看是否存在任何差异。
Unity广告本身使用3个权限,旧版本甚至可以使用5个。如果您使用的是广告,那么您必须将这些视为理所当然。
曾经看过Unity似乎能够提供的那些幻想stats?好吧,除非你禁用了这个,否则你很可能也参与其中。
这些统计信息需要多项权限,因为手机将在硬件级别进行分析,并在提供的统计信息中进行分析。
您可能已经包含了一些api,工具或者来自外部方的任何dll,这些dll可能包含也可能不包含需要依赖项的代码。正如通常那些不是100%消毒,并且可能包括与其功能无关的权限要求,或者您需要的功能。
比如说,某些广告服务可能想要访问用户麦克风。但是,由于您没有使用他们的“OMG声音响应分析”功能,因此您不需要此权限。
可以手动删除这些权限,正如我之前在我的回答中所述。或者通过某种形式的自动化,例如post build marked editor脚本。
问题特定:
如果在项目的任何脚本中调用Microphone库,则 RECORD_AUDIO
权限进入android清单文件。脚本是否存在于场景中并不重要。在这种特定情况下,如果在项目中导入Oculus Platform SDK(这是商店要求),则使用Microphone
库的脚本很少。因此,如果您不使用任何录音功能,例如语音输入,只需删除OculusPlatform/Scripts
下的以下文件:MicrophoneInput.cs,IMicrophone.cs,MicrophoneInputNative.cs
答案 1 :(得分:1)
@ mx-d是对的。我只想添加另一种解决方法:在构建设置中,您可以勾选将生成Android Studio项目的Google Android Project
。从那里,您可以使用Android Studio的清单合并工具来覆盖权限。
问题#1 :找到哪个库投入额外权限的唯一方法是逐个删除库,构建项目并检查.apk清单。不幸的是,团结并不像Android Studio生产那样灵活。
问题#2 :您无法通过代码在Unity中添加权限(除非它是专门用于拼接清单文件的自定义编辑器脚本)
答案 2 :(得分:1)
我认为,如果您的Unity项目是使用gradle
构建的,则可以采用这种更简单的方法。如果不是,这是升级的另一个原因。
此外,大声喊叫Hey, Where Did These Permissions Come From?)的文章
这是文件的一部分,我在这里寻找WRITE_EXTERNAL_STORAGE权限。
uses-permission#android.permission.WRITE_EXTERNAL_STORAGE
ADDED from /Users/clinton/Projects/<<ProjectName>>/Temp/gradleOut/src/main/AndroidManifest.xml:7:3-79
MERGED from [gradleOut:IronSource:unspecified] /Users/clinton/Projects/<<ProjectName>>/Temp/gradleOut/IronSource/build/intermediates/bundles/default/AndroidManifest.xml:13:5-81
android:name
ADDED from /Users/clinton/Projects/<<ProjectName>>/Temp/gradleOut/src/main/AndroidManifest.xml:7:20-76
可以通过三种方式将权限添加到项目中。
我的示例在Mac上使用命令行工具。我不知道Windows等价物,但是可以在其中找到并运行Unix工具(使用Windows 10,cygwin,自定义二进制文件等Linux子系统)
cd /path/to/my/project/Assets
grep -r "uses-permission" --include "AndroidManifest.xml" .
这将在当前文件夹(.
)或其任何子文件夹(-r
告诉它进行递归搜索)中找到所有名为AndroidManifest的文件,并在所有行中吐出“ uses-permission”一词'。
在我当前的项目中,我得到如下输出:
./Plugins/Android/AndroidManifest.xml: <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
./Plugins/Android/AndroidManifest.xml: <uses-permission android:name="android.permission.INTERNET" />
./Plugins/Android/AndroidManifest.xml: <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
./Plugins/Android/AndroidManifest.xml: <uses-permission
./Plugins/Android/IronSource/AndroidManifest.xml: <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
./Plugins/Android/IronSource/AndroidManifest.xml: <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
您的项目可能包含android库(.aar文件)和java存档(.jar文件)。一些android库包含一个android清单,并指定使用该库所需的权限。 (我不认为.jar文件确实可以这样做,但是.aar文件绝对可以这样做)。 .aar和.jar文件都是.zip文件,具有不同的扩展名和特定位置的特定元数据。
通过运行查找它们:
find . -iname "*.?ar" -print -exec zipgrep "uses-permission" "{}" "AndroidManifest.xml" ";" 2> /dev/null
这就是它的作用。
它会找到任何文件(在当前文件夹(.
中及其子文件夹中)的扩展名(是r),即.jar或.aar(-name "*.?ar"
)。
它输出档案的文件名(-print
)。
然后,它运行zipgrep
(-exec
)。
告诉Zipgrep搜寻档案({}
)中名为“ AndroidManifest.xml”的任何文件,并输出任何带有“ uses-permission”字样的行。
然后,我们将错误通过管道传递到位存储桶(2> /dev/null
),这样就不会在其中没有android清单的档案中看到很多错误。
示例输出如下:
./OneSignal/Platforms/Android/onesignal-unity.aar
AndroidManifest.xml: <uses-permission android:name="android.permission.INTERNET" />
AndroidManifest.xml: <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
AndroidManifest.xml: <uses-permission android:name="android.permission.WAKE_LOCK" />
AndroidManifest.xml: <uses-permission android:name="android.permission.VIBRATE" />
...
./Plugins/Android/android.arch.core.common-1.1.0.jar
./Plugins/Android/android.arch.core.runtime-1.1.0.aar
./Plugins/Android/android.arch.lifecycle.common-1.1.0.jar
...
./Plugins/Android/com.google.android.gms.play-services-gcm-11.8.0.aar
AndroidManifest.xml: <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
AndroidManifest.xml: <uses-permission android:name="android.permission.INTERNET" />
./Plugins/Android/com.google.android.gms.play-services-gcm-license-11.8.0.aar
./Plugins/Android/com.google.android.gms.play-services-iid-11.8.0.aar
AndroidManifest.xml: <uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
AndroidManifest.xml: <uses-permission android:name="android.permission.INTERNET" />
./Plugins/Android/com.google.android.gms.play-services-iid-license-11.8.0.aar
...
文件名都以句点开头。因此,例如,我可以看到onesignal-unity.aar设置了多个权限,搜索了几个.jar文件,但其中没有权限,并且某些播放服务库指定了权限。
如果需要更改库,可以将.aar重命名为.zip,解压缩,编辑,压缩,然后重命名。 (更改库中的权限不一定是明智的做法,但可以这样做。)
我没有什么可补充的;如上所述,如果您使用Microphone API,Unity将为您添加权限,以便您的应用可以正常工作。
但是,自那以后,我意识到您可以执行以下操作: