Android权限:INTERACT_ACROSS_USERS_FULL

43

我有一个在Android上的大型应用程序。

这个应用程序不时会崩溃,出现不明确的错误。我不知道具体是什么情况和原因。

java.lang.SecurityException: Permission Denial: get/set setting for user asks
to run as user -2 but is calling from user 0; this requires 
android.permission.INTERACT_ACROSS_USERS_FULL

需要帮助吗?


@offset 你最终解决了这个问题吗? - not2qubit
@user1147688 我不记得了... - offset
10个回答

20

总结自回答,通过查看UserHandle.java的源代码,我们可以了解framework用户ID的含义。

# | @UserIdInt            | Value  | Status     | Description |
# | --------------------- | ------ | ---------- | ------------| 
# | USER_OWNER            | 0      | deprecated | "owner" user of the device
# | USER_SYSTEM           | 0      | ok         | "system" user of the device
# | USER_ALL              | -1     | ok         | ALL users on the device
  | USER_CURRENT          | -2     | ok         | the currently active user
# | USER_CURRENT_OR_SELF  | -3     | ok         | id from which we would like to send to the current user
# | USER_NULL             | -10000 | ok         | An undefined user id

要理解android:protectionLevel="signature"的含义,您需要阅读关于permission-element的页面,其中在表格中进行了总结:

enter image description here

因此,在您的AndroidManifest.xml中需要做什么取决于您需要支持哪些API,因为更高版本的API(大于23)还需要定义android:permissionGroup=权限组来授予非常规(危险)权限...

还需知道(由@CommonsWare提供)

要能够持有INTERACT_ACROSS_USERS,您的应用程序必须使用固件签名密钥进行签名或安装在系统分区中。

要能够持有INTERACT_ACROSS_USERS_FULL,您的应用程序必须使用固件签名密钥进行签名。


3
我会尽力为您翻译:我一直在看问题的原因,但没有看到解决方案。解决方案是什么? - sudocoder
1
@sudocoder,解决方案(如上两个句子所示)是使用设备制造商(或操作系统提供商)的OEM密钥对应用程序进行签名!如果这不够,请发布一个新的SO问题,或者可以查看Android specific SE - not2qubit
2
公平的说,这两个句子构成了一个解决方案。但是这个解决方案如何具有可扩展性呢?例如:如果我使用三星密钥签署此应用程序,那么下载我的应用程序的华为用户是否会遇到同样的问题? - sudocoder
2
当我尝试添加 <uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" android:protectionLevel="signature" /> 时,我会得到“具有签名、特权或signatureOrSystem保护级别的权限仅授予系统应用。如果一个应用是普通的非系统应用,它将永远无法使用这些权限。” - sudocoder
2
有没有一种方法可以检测应用程序是否在真正的用户帐户上运行,而不是辅助账户? - android developer

16

java.lang.SecurityException: 权限拒绝: 请求以-2用户身份运行的get/set设置,但是调用者为0用户; 这需要android.permission.INTERACT_ACROSS_USERS_FULL权限。

在您的清单文件中添加此android:protectionLevel="signature"

有关更多详细信息,请参见Permission-Element

例如:

<permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" android:protectionLevel="signature"/>

1
不好意思,这个错误又出现了... 在哪里添加这行代码? - offset
2
这样写对吗?<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" android:protectionLevel="signature" /> - offset
1
<permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" android:protectionLevel="signature"/> - sonida
3
签名不是仅通过添加就能获得的。它是由原始设备制造商签署的。 - Felix.D
由于某种原因,我在小米Mi A1上遇到了这个异常,似乎是一些自定义ROM(LineageSettings类,所以可能是LineageOs)。有任何想法吗? - android developer
显示剩余4条评论

3

其中一种可能的解决方案是禁用自动填充,但它只适用于Android Oreo。请查看此链接

只需将以下代码添加到您的应用程序中:

      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        window.decorView.importantForAutofill = 
        View.IMPORTANT_FOR_AUTOFILL_NO_EXCLUDE_DESCENDANTS;
    }

如果你有getUserId()方法,那么请重命名它。


如果你有的话,重命名getUserId()方法。这行代码救了我!为什么?谢谢你。 - Radesh
你知道为什么getUserId()会导致这个问题吗? - Sajal Jain

3

当我使用 billingProcessor.subscribe()billingProcessor.purchase() 时,遇到了同样的问题,这两个函数需要传递两个参数:Activity和产品的 product_id。在这里,我传递的 product_id 值为空

请确保您传递的product_id值不为空


1

我在设备更新操作系统后遇到了这个问题。

重新启动解决了这个问题。


0

这是一个非常奇怪的错误......我在从Java切换到Kotlin,或者从任何Android Studio更新之后,遇到了这个错误。我开始逐个注释XML和.kt文件中的元素,直到发现错误与任何userId(在错误中提到)或Retrofit调用都无关,该错误由XML中的一个Spinner元素导致,在加载元素时.kt文件中没有任何相关信息,只有这个:

<Spinner
        android:id="@+id/number_people_sp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:inputType="text" />

所以我把它删掉了,事情又变好了。我认为问题是由于元素之间的某些间距引起的(因为那个旋转器在选项卡活动中的片段中),我在错误信息的长行中看到了一些关于间距和子测量的内容。

请记住,在错误文件中检查任何可能的小问题,错误可能来自任何地方...


0

我在升级我的安卓设备操作系统版本后,遇到了同样的问题 "android.permission.INTERACT_ACROSS_USERS_FULL"。我尝试了清理和重建项目,问题得到了解决。


0
这种情况发生在我使用notificationChannel时。我是使用applicationContext创建的,但在其他地方,我尝试通过NotificationManager.getNotificationChannel()从服务的上下文中获取它。因此,可能在不同的地方使用相同的上下文,例如applicationContext,可以解决这个问题。

0

我在将手机操作系统更新为Android 9之后遇到了这个错误。只有重置(重新启动)手机和重新启动Android Studio才能解决问题。


-2

我幸运地解决了这个问题。我使用了单例片段实例,导致了这个问题。当我用new fragment()替换了fragment.getInstance()调用时,它就像魔法一样奏效了。片段不应该被用作单例,并且应该在需要时带回(如果需要)保存的状态。


这很可能不是 OP 遇到的根本原因。 - sudocoder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接