正在从noHistory=”的活动请求Android M权限;“真的”;和/或showOnLockScreen=";“真的”;

正在从noHistory=”的活动请求Android M权限;“真的”;和/或showOnLockScreen=";“真的”;,android,permissions,android-permissions,android-6.0-marshmallow,Android,Permissions,Android Permissions,Android 6.0 Marshmallow,我正在开发一个视频通话应用程序,我有一个“来电”屏幕,当有人打电话时会提醒用户。此屏幕是由传入GCM触发的活动,在清单中设置了noHistory=“true”和showOnLockScreen=“true”,以便用户无需解锁设备即可拨打电话 如果用户选择接受呼叫,我将启动另一个活动以参与实际呼叫。但是,在启动第二个活动之前,我会检查是否存在必要的权限(摄像头、麦克风等),如果没有,请请求这些权限 这就是问题所在 问题1: 系统显示的权限请求对话框导致“我的活动”进入暂停状态。我相信,因为在幕后,

我正在开发一个视频通话应用程序,我有一个“来电”屏幕,当有人打电话时会提醒用户。此屏幕是由传入GCM触发的活动,在清单中设置了noHistory=“true”和showOnLockScreen=“true”,以便用户无需解锁设备即可拨打电话

如果用户选择接受呼叫,我将启动另一个活动以参与实际呼叫。但是,在启动第二个活动之前,我会检查是否存在必要的权限(摄像头、麦克风等),如果没有,请请求这些权限

这就是问题所在

问题1:

系统显示的权限请求对话框导致“我的活动”进入暂停状态。我相信,因为在幕后,这个对话实际上是一种活动

由于一个新的活动正在这里启动,使用noHistory=“true”意味着我们的活动将立即被终止。从技术上讲,这是故意的行为,事实上,Android团队已经驳回了这个问题:

我可以通过在onPause中手动管理并检测是否有任何未完成的权限请求等来解决此问题

问题2: 在解决了问题1之后,我进入了第二阶段

现在请求权限时,我的活动不再被终止,但设备只是返回到锁定屏幕,我看不到权限对话框

如果我随后解锁设备,万岁,我会看到我的活动和请求权限对话框覆盖在顶部。这种用户体验令人不快

视频在此:

我猜请求权限的活动没有将showOnLockScreen属性设置为true,因此如果在锁定屏幕的情况下启动,则不会显示

那么,一个大问题是,我们能否优雅地请求允许在锁屏上显示的活动的权限?

我的直觉是不,我们不能显示权限对话框而不返回锁屏。但是,对我来说,一个可接受的折衷方案是提示用户解锁设备/i,即显示pin输入屏幕

因此,问题2:


我们能否以编程方式从屏幕锁定时显示的活动中显示pin解锁屏幕?

来自requestPermission()文档(ActivityCompat):

此方法可以启动一个活动,允许用户选择授予和拒绝哪些权限。因此,您应该准备好暂停和恢复您的活动。此外,授予某些权限可能需要重新启动应用程序。在这种情况下,系统将在将结果传递给onRequestPermissionsResult(int,String[],int[])之前重新创建活动堆栈

最后我创建了一个状态变量来处理这个问题,这样onPause()和onResume()就可以区分由于权限请求而被调用和由于其他系统事件而被调用

比如说:

private final int STATE_STARTING = 0;
private final int STATE_RUNNING = 1;
private final int STATE_REQUESTING_FINE_LOCATION_PERMISSION = 2;

private int state = STATE_STARTING;

@Override
public void onCreate() {
    super.onCreate();
    switch (state) {
        case STATE_STARTING:
            // do your initialization
            state = STATE_RUNNING;
            break;
    }
}

@Override
public void onResume() {
    super.onResume();
    switch (state) {
        case STATE_RUNNING:
            // handle other system events
            break;
        case STATE_REQUESTING_FINE_LOCATION_PERMISSION:
            // handle permission request event
            break;
    }
}

@Override
public void onPause() {
    super.onPause();
    switch (state) {
        case STATE_RUNNING:
            // handle other system events
            break;
        case STATE_REQUESTING_FINE_LOCATION_PERMISSION:
            // handle permission request event
            break;
    }
}

private void someFunction() {
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        state = STATE_REQUESTING_FINE_LOCATION_PERMISSION;
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_CODE_PERMISSION_FINE_LOCATION);
    } else {
        doProcessingRequiringFineLocationPermission();
    }

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    switch (requestCode) {
        case REQUEST_CODE_PERMISSION_FINE_LOCATION:
            if (grantResults != null && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                doProcessingRequiringFineLocationPermission();
            }
            state = STATE_RUNNING;
            break;
    }
}

为什么不早于此请求这些权限?在您的情况下,我会在您的应用程序第一次运行时请求这些权限,甚至在GCM初始化之前,更不用说触发此无历史记录活动了。作为一个用户,如果我应该处理一个来电,那么我不想在权限对话框中大惊小怪。在任何来电发生之前,请将其清除。事实上,我是这样做的,我会在应用程序启动后尽快整理权限。不过,我正在努力覆盖所有的基地。在许多情况下都会触发呼叫,当然,我总是在尝试进入呼叫屏幕之前检查权限。99%的情况下,我怀疑用户已经允许了他们,但从逻辑上讲,我所描述的情况可能会出现(用户在首次启动时拒绝许可,但随后收到一个呼叫并尝试接听)。您能否显示最终使用的代码?我也有同样的问题。