如何知道用户是否已禁用画中画功能权限?

6

enter image description here

这里是另一个例子:

enter image description here

从上面的截图中,我们可以看到用户能够禁用画中画模式。您可以在模拟器API 27上的“特殊应用程序访问”屏幕中找到它。我该如何检测用户是否已禁用此功能?
我尝试了以下检查,但并不起作用:
packageManager.hasSystemFeature(PackageManager.FEATURE_PICTURE_IN_PICTURE)

编译器报告找不到AppOpsManager。有什么想法吗?

4个回答

10

就像AlexTa所说的那样。但我想实际编写代码来为某人节省时间:

private fun hasPermission(): Boolean {
    val appOps = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
        getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager
    } else {
        return false
    }
    return appOps.checkOpNoThrow(AppOpsManager.OPSTR_PICTURE_IN_PICTURE, android.os.Process.myUid(), packageName) == AppOpsManager.MODE_ALLOWED
}

如果我们在Chrome上检查这个,UID和包名应该是Chrome的,对吗? - Jim_Ktr
为什么不通过切换设置来测试一下呢?我对此并不太确定。 - j2emanue
我已经完成了这个任务,当我使用我的应用程序UID时,我总是得到MODE_ALLOWED。但是当我使用Chrome的UID时,我会遇到一个SecurityException异常,即[我的应用程序UID]没有android.permission.UPDATE_APP_OPS_STATS权限。 - Jim_Ktr
如果您想让用户启用权限,请使用以下代码:startActivityForResult(Intent("android.settings.PICTURE_IN_PICTURE_SETTINGS", Uri.parse("package:$packageName")), 0) - Ultimo_m
KitKat,你是什么意思?OPSTR_PICTURE_IN_PICTURE 是从 OREO 开始提供的... 所以它甚至不适用于 Nougat,而在这里有 KitKat... - user924
KitKat,你是什么意思?OPSTR_PICTURE_IN_PICTURE从OREO开始就可用了...所以它甚至不适用于Nougat,更别说KitKat了... - undefined

6
尝试使用AppOpsManager.checkOp(String op,int uid,String packageName)方法,其中op OPSTR_PICTURE_IN_PICTURE 操作。 如果支持画中画操作,则该方法应返回 MODE_ALLOWED 常量。 要了解更多信息,请查看此链接

我看到解决方案已经被检查了,它对你有用吗?你是否正在获取 Chrome 中图片中的图片状态? - Jim_Ktr

5

可能我来晚了,但这就是答案。

private fun hasPermission(): Boolean {
    val appOps = getSystemService(Context.APP_OPS_SERVICE) as AppOpsManager?
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            appOps?.unsafeCheckOpNoThrow(AppOpsManager.OPSTR_PICTURE_IN_PICTURE, android.os.Process.myUid(), packageName) == AppOpsManager.MODE_ALLOWED
        } else {
            appOps?.checkOpNoThrow(AppOpsManager.OPSTR_PICTURE_IN_PICTURE, android.os.Process.myUid(), packageName) == AppOpsManager.MODE_ALLOWED
        }
    } else {
        false
    }
}

0

在Android 26+(奥利奥)及以上版本中可以获得权限。

在Android 24+中,默认情况下允许所有应用程序使用该权限。

在Android 23及更低版本中不可用,正如其他答案中所提到的。

因此,正确的逻辑应该是:

private fun hasPipPermission(context: Context): Boolean {
    val appOps = context.getSystemService(Context.APP_OPS_SERVICE) as? AppOpsManager?
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val mode = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            appOps?.unsafeCheckOpNoThrow(
                AppOpsManager.OPSTR_PICTURE_IN_PICTURE,
                android.os.Process.myUid(),
                context.packageName
            )
        } else {
            @Suppress("DEPRECATION")
            appOps?.checkOpNoThrow(
                AppOpsManager.OPSTR_PICTURE_IN_PICTURE,
                android.os.Process.myUid(),
                context.packageName
            )
        }
        mode == AppOpsManager.MODE_ALLOWED
    } else {
        Build.VERSION.SDK_INT >= Build.VERSION_CODES.N
    }
}

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