Android Q 屏幕锁定时如何从广播接收器启动 Activity

Ram*_*thy 5 android broadcastreceiver android-alarms keyguard android-windowmanager

我正在尝试使用广播接收器在Android Q中实现基于警报的应用程序。我正在使用通知来运行前台服务来触发警报广播接收器。该服务工作正常,并且还触发广播接收器。如果我们在设置闹钟后关闭应用程序或锁定屏幕,该服务将在前台运行并发出通知。

当调用警报广播时,我试图在屏幕锁定时打开一个新活动,以提供停止警报和服务的功能。我尝试禁用键盘保护,打开屏幕,然后从广播接收器打开活动,但我无法成功。

我尝试使用WindowManager 标志,但它们已被弃用,并且在代码中没有任何区别。

WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
Run Code Online (Sandbox Code Playgroud)

由于我尝试从 BroadcastReceiver 启动活动,因此我不会有任何活动使用KeyguardManager.requestDismissKeyguard(Activity Activity, KeyguardDismissCallback callback)

有没有办法在屏幕锁定时启动活动来关闭闹钟。我的实现如下:

我还在清单文件中添加了权限。

AndroidManifest.xml

<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
Run Code Online (Sandbox Code Playgroud)

AlarmBroadcastReceiver.class

public class AlarmBroadcastReceiver extends BroadcastReceiver {
    public static MediaPlayer mp;
    public static Vibrator vibrator;

    private boolean isVibrationEnabled = false;

    @Override
    public void onReceive(Context context, Intent intent) {

        long[] mVibratePattern = new long[]{0, 400, 400, 400, 400, 400, 400, 400};
        final int[] mAmplitudes = new int[]{0, 128, 0, 128, 0, 128, 0, 128};

        isVibrationEnabled = intent.getExtras().getBoolean(LocationAlertService.IS_VIBRATE);

        mp=MediaPlayer.create(context, R.raw.ring1);
        mp.setLooping(true);
        mp.start();

        if(isVibrationEnabled) {
            vibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                vibrator.vibrate(VibrationEffect.createWaveform(mVibratePattern, mAmplitudes, 0));
            } else {
                //deprecated in API 26
                vibrator.vibrate(mVibratePattern, 3);
            }
        }

        Intent wakeIntent = new Intent(context, WakeUpActivity.class);
        wakeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(wakeIntent);
    }
}
Run Code Online (Sandbox Code Playgroud)

我知道我错过了一些东西。如果有任何建议来解决我面临的问题,我会很高兴。预先感谢您帮助我。

Ere*_*kçi 1

在 Android Q 中,如果您的应用不包含下面链接中列出的例外情况,则无法从后台自动启动 Activity。您可以选择仅显示服务通知,然后通过单击启动待处理意图。

https://developer.android.com/guide/components/activities/background-starts

为了让系统发挥作用。我认为最可能的解决方案是将“SYSTEM_ALERT_WINDOW”添加到清单文件中。并在应用程序第一次打开时请求用户权限一次。(用户可以手动授予此权限 - (设置 - 应用程序 - 您的应用程序 - 高级 - 覆盖其他应用程序))请求权限的示例代码:

在清单中:

    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
Run Code Online (Sandbox Code Playgroud)

应用程序中的某处:

 private void RequestPermission() {
            // Check if Android M or higher
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                // Show alert dialog to the user saying a separate permission is needed
                // Launch the settings activity if the user prefers
                Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                        Uri.parse("package:" + getActivity().getPackageName()));
                startActivityForResult(intent, ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE);
            }
        }

    @Override
    public void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (requestCode == ACTION_MANAGE_OVERLAY_PERMISSION_REQUEST_CODE) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (!Settings.canDrawOverlays(getContext())) {
                    PermissionDenied();
                }
                else
                {
                 //Permission Granted-System will work
            }

        }
    }
Run Code Online (Sandbox Code Playgroud)