Java 基于应用程序安装顺序的Android自定义权限失败
我在Google Play上的应用程序有问题。我有一个使用自定义权限的免费应用程序。此权限允许访问付费应用。这些付费应用程序充当免费应用程序中的“钥匙”和解锁功能。基本上,免费应用程序将尝试启动其中一个付费应用程序的意图。付费应用程序会做一些事情,然后返回,说明免费应用程序是否应该解锁功能 根据应用程序安装顺序出现问题。如果先安装免费应用,然后安装付费应用,则免费应用无法启动。返回权限拒绝。如果先安装付费应用程序,然后安装免费应用程序,那么免费应用程序可以启动intent,没有问题。重新启动设备和/或强制停止应用程序并不能解决问题。我正在附上相关代码。有些事告诉我我做得不对Java 基于应用程序安装顺序的Android自定义权限失败,java,android,android-intent,android-manifest,android-permissions,Java,Android,Android Intent,Android Manifest,Android Permissions,我在Google Play上的应用程序有问题。我有一个使用自定义权限的免费应用程序。此权限允许访问付费应用。这些付费应用程序充当免费应用程序中的“钥匙”和解锁功能。基本上,免费应用程序将尝试启动其中一个付费应用程序的意图。付费应用程序会做一些事情,然后返回,说明免费应用程序是否应该解锁功能 根据应用程序安装顺序出现问题。如果先安装免费应用,然后安装付费应用,则免费应用无法启动。返回权限拒绝。如果先安装付费应用程序,然后安装免费应用程序,那么免费应用程序可以启动intent,没有问题。重新启动设备
- 免费应用程序清单(相关代码):
- 付费应用程序清单(相关代码):
而不是在两个应用程序中放置相同的
元素。此外,由于这是针对您的两个应用程序的,我将使用android:protectionLevel=“signature”
——这意味着用户永远不需要批准权限,其他人也无法请求权限。而且,此配方允许按任意顺序安装 更新:但是,请注意,自定义权限的使用将打开normal
更新#2:现在是这样,因为两个应用程序不能同时具有相同的
元素,除非它们由相同的签名密钥签名。我能够解决他在更新#2中提到的@commonware问题。只需在将首先安装的应用程序中声明权限。 说明: 我有应用A和应用B,用不同的签名签名。应用程序A需要使用应用程序B登录,但应用程序A首先安装,并确保用户安装应用程序B 因为应用程序B似乎是我在应用程序B中声明了自定义权限的(登录)服务。应用程序B有一个其他应用程序可以使用的(意图)服务,只要它们使用该权限并且在我们的白名单中。因此,应用程序B声明了服务和权限 但是,由于应用程序A在应用程序B之前安装,我发现我需要将权限也添加到应用程序A。否则,应用程序A在安装应用程序B之后似乎没有权限。我最好的猜测是,这是因为权限内容是在安装时完成的。由于应用程序A没有声明权限,在安装时没有发生任何事情。但随后安装了具有该权限的应用程序B,但应用程序A仍然没有收到该权限 但后来我在安卓5上进行了测试,遇到了他们独特的权限更改。因此,我测试了一些流和权限声明,并提出了一个可行的解决方案:
在首先安装的应用程序中声明自定义权限!当然,这只有在您知道将首先安装哪个应用程序时才起作用。但在我的例子中,应用程序A依赖于应用程序B,而应用程序A安装应用程序B,这就是解决方案:)问题:如果第一个安装的应用程序指定了相同的权限,则在安装时不会通知用户权限请求。安装第二个应用程序后,第一个应用程序可以访问需要该权限的第二个应用程序的组件。主要安全问题?@MarkCarter:用户肯定不会被提示输入
级别的权限。然而,这并不真正取决于安装顺序<代码>签名-永远不会出现级别权限。由于签名
级别的权限是针对由一个开发人员(或团队)编写的代码的,因此假设这些权限控制着聚合内部通信的数量,用户无需担心。但是,如果您在自定义签名
或normal
权限中看到您描述的行为,这会让我感到惊讶,我需要做更多的研究。是的,我在“normal”(仅在权限应用程序中)中看到。此外,由于uses权限应用程序可以指定自己的级别(在权限标记中),因此只需在permission only应用程序中对不同级别进行测试。话虽如此,我只测试了两个具有相同签名的应用程序。MarkCarter:如果你能发布一个可复制的示例项目(或者,在本例中,是两个项目),我可以看看它们。不过,我很难解析你前面评论的第二句话。这可能是因为睡眠不足。@plaisthos:有意思!这个周末我将进行一些测试。谢谢danger
... <uses-permission android:name="com.company.license.PERMISSION" /> ...
Intent KeyApp = new Intent("com.company.license.action.AUTH_1"); KeyApp.putExtra("com.company.license.challenge", 1); //If free app is installed first, an exception is thrown for not having the proper permission. If paid app is installed first, no exception is thrown try { startActivityForResult(KeyApp, COMMING_FROM_KEYAPP); } catch (Exception e) { cancelStartUp(); }
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.company.installer.1" ... <permission android:name="com.company.license.PERMISSION" android:icon="@drawable/icon" android:label="@string/app_name" android:protectionLevel="normal" > </permission> <application android:icon="@drawable/icon" android:label="@string/app_name" android:theme="@android:style/Theme.NoDisplay" > <activity android:name="com.company.license.auth" android:configChanges="keyboardHidden|orientation" android:exported="true" android:permission="com.company.license.PERMISSION" android:theme="@style/Theme.Transparent" > <intent-filter> <action android:name="com.company.license.action.AUTH_1" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity> <activity android:name="com.company.installer.redirect" android:configChanges="keyboardHidden|orientation" android:exported="true" android:theme="@style/Theme.Transparent" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>