How to start a activity from a broadcast receiver when the screen is locked in Android Q

淺唱寂寞╮ 提交于 2021-01-28 02:20:42

问题


I am trying to implement an alarm based application in Android Q using a broadcast receiver. I am running a foreground service using notification for triggering the alarm broadcast receiver. The service is working fine and it is also triggering the broadcast receiver. If we close the application or lock the screen after setting an alarm, the service will be running in the foreground with a notification.

When the alarm broadcast is called I am trying to open a new activity when the screen is locked to provide the functionality to stop the alarm and service. I tried disabling the keyguard, turn on the screen and then opening the activity from the broadcast receiver, but I couldn't succeed.

I tried using WindowManager flags but they are deprecated and do not make any difference in the code.

WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
| WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD
| WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON

Since I am trying to start an activity from a BroadcastReceiver I won't be having any Activity to use KeyguardManager.requestDismissKeyguard(Activity activity, KeyguardDismissCallback callback)

Is there any way to start an activity when the screen is locked to turn off the alarm. My implementation is given as follows,

I also added permissions in the manifest file.

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" />

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);
    }
}

I know that I am missing something. I would be happy if there are any suggestions to overcome the issue which I am facing. Thanks in advance for helping me out.


回答1:


With Android Q, it is impossible to start an activity from background automatically if your app is not includes those exceptions listed in the link below. You can choose just show a service notification, and start pending intent with click.

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

To make the system work. The most possible solution in my view is adding "SYSTEM_ALERT_WINDOW" to manifest file. And ask for user permission once when the app opened first time.(The user can give this permission manually - (Settings-Apps-Your App-Advanced- Draw over other apps)) Example code to request permission :

In Manifest:

    <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>

Somewhere in app:

 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
            }

        }
    }


来源:https://stackoverflow.com/questions/59416738/how-to-start-a-activity-from-a-broadcast-receiver-when-the-screen-is-locked-in-a

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!