Search code examples
androidalarmmanager

Activity triggers after alarm (RTC_WAKEUP) but screen remains black


I'm setting up a skeletal app on how to react to alarms in Android. When the phone is awake all works fine, when the phone is asleep the alarm triggers (I can even activate the vibrator) but the screen stays off (completely black). I can't decipher why. Any help is welcome!

This is the code snippet in MainActivity that sets up the alarmManager (E1 is an EditText to ask the user to pick seconds to trigger the alarm):

public void startAlarm(View view) {
    EditText E1 = (EditText) findViewById(R.id.et1);
    int i = Integer.parseInt(E1.getText().toString());
    Intent intent = new Intent(this, AlarmBroadcastReceiver.class);
    PendingIntent pending_intent = 
    PendingIntent.getBroadcast(this.getApplicationContext(),
        98989898, intent, 0); // 98989898 : some big number
    AlarmManager alarmManager = (AlarmManager) 
        getSystemService(ALARM_SERVICE);
    alarmManager.set(AlarmManager.RTC_WAKEUP, 
        System.currentTimeMillis() + i*1000, pending_intent);
    Toast.makeText(this, "Alarm set in: " + i + " seconds", 
    Toast.LENGTH_LONG).show();
}

The alarm is picked up by the alarmBroadcastReceiver. It does nothing by itself, it immediately transfers to the UserResponseActivity:

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;

public class AlarmBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        // We're creating a new intent that's going to start the UserResponseActivity
        Intent in = new Intent(context, UserResponseActivity.class);
        // This boolean just makes it easier to check if the Activity has been started from
        // this class
        in.putExtra("lock", true);
        // You need to add this to your intent if you want to start an Activity fromm a class
        // that is not an Activity itself
        in.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        // Now we just start the Activity
        context.startActivity(in);
    }
}

Then UserResponseActivity is a normal activity that for the moment has the boilerplate screen from Android Studio. Later on I plan to add some code requesting a response from the user. Upon creation it shows a toast and activates the vibrator for a short period of time:

import android.content.Context;
import android.os.Bundle;
import android.os.Vibrator;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.View;
import android.widget.Toast;

public class UserResponseActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_user_response);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });

        /* Show a success toast*/
        Toast.makeText(this, "Alarm Started", Toast.LENGTH_LONG).show();
        /* Vibrate shortly */
        Vibrator vibrator = (Vibrator) this.getSystemService(Context.VIBRATOR_SERVICE);
        vibrator.vibrate(200);
    }

}

In case you need it, here are the lines of code in my manifest that enable the alarm receiver and the vibrator service:

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

<receiver android:name=".AlarmBroadcastReceiver" />

As mentioned, all works well if the alarm is triggered when the phone is awake: UserResponseActivity is shown on the screen and the vibrator goes off. However, if the alarm triggers when the phone is asleep the vibrator goes off (so the phone is wakened up and UserResponseActivity is called) but the screen stays black. When I subsequently turn on the phone, then the UserResponseActivity is right there on top.

What do I need to do in order for the UserResponseActivity to turn on the screen?

Thanks!

ADDED (after reply from VicJordan):

@VicJordan: I pasted your piece of code into the onCreate of UserResponseActivity.java as below, but get two errors for which I could not find out what it is that I'm doing wrong in these 2 lines:

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
        activity.setTurnScreenOn(true);

a) Android Studio can't resolve symbol 'O_MR1' b) it can resolve 'activity' either on the 2nd line. I assumed that changing activity for 'this' would do the trick, but not. I really can't figure out another way to reference the activity I'm in

public class UserResponseActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_user_response);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
            }
        });

        // Turn on the screen
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
            activity.setTurnScreenOn(true);
        } else {
            final Window window = getWindow();
            window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
        }

        /* Show a success toast*/
        Toast.makeText(this, "Alarm Started", Toast.LENGTH_LONG).show();
        /* Vibrate shortly */
        Vibrator vibrator = (Vibrator) this.getSystemService(Context.VIBRATOR_SERVICE);
        vibrator.vibrate(200);
    }

Would you have any suggestions? Thanks!


Solution

  • To turn on screen in your Activity you can use WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON but FLAG_TURN_SCREEN_ON flag has been deprecated in API level 27 so you can use Activity.setTurnScreenOn(true) from API level 27 onwards.

    Below is code:

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1) {
            this.setTurnScreenOn(true);
        } else {
            final Window window = getWindow();
            window.addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
        }
    

    Check this official information for more information : https://developer.android.com/training/scheduling/wakelock