harisk92
harisk92

Reputation: 1128

Starting activity from Service when phone is locked Android 9.0(Pie)

Hello I'm working on VoIP feature for the app and I'm trying to handle cases when app is killed. My idea is to go with FCM notification and run activity which will show user incoming call screen. It works as expected when phone is unlocked but not the case when phone is locked.

I tried this :

  if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O_MR1) {
      setShowWhenLocked(true);
      setTurnScreenOn(true);
    }else{
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_DISMISS_KEYGUARD);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    }

I tried adding flags to activity in manifest but no luck. Also I tried putting it before super.onCreate() after on super.onCreate() and also after setContentView() but no luck.

I just want same behaviour as with Viber and WhatsApp. But currently I'm out of ideas how they do it.

I tested above code on PocoPhone F1 with latest update.

EDIT

Here is part of FirebaseMessagingService where I receive and handle push notification

public class NotificationService extends FirebaseMessagingService {
  private static final String TYPE = "type";
  private static final String VIDEO_CALL = "video_call";

  @Override public void onMessageReceived(RemoteMessage remoteMessage){
       Map<String,String> data = remoteMessage.getData();

       if(data.containsKey(TYPE) && data.get(TYPE).equals(VIDEO_CALL)){
        Intent videoCallIntent = new Intent(this, VideoCallActivity.class);
        videoCallIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        startActivity(videoCallIntent);
       }
  }

}

and here is push notification payload

{
    "to": "...",
    "data" : {
     "type" : "video_call"
     },
    "priority":"high",
    "ttl": 3600
 }

UPDATE:

I managed to resolve this issue.Alex answer was correct one but Xiaomi devices have option "Show on Lock screen" in settings which I needed to enable. This is one of the reasons I'm kinda frustrated with Android OS.

Upvotes: 3

Views: 3100

Answers (2)

Alex
Alex

Reputation: 1730

Also request the KEYGUARD_SERVICE for dismissal for the higher API levels by adding this request inside the if-statement (after setTurnScreenOn(true);):

    KeyguardManager keyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);
    if (keyguardManager!= null) {
        keyguardManager.requestDismissKeyguard(this, null);
    }

Upvotes: 3

Prasad Pawar
Prasad Pawar

Reputation: 1711

In the onCreate() of your activity you will need to make these changes. The activity here displays a red empty activity even if the device is locked.

public class LockScreenActivity extends AppCompatActivity {

    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        //modify window flags so as to display it on lock screen
        Window window = getWindow();
        window.addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON
                | WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

        // to wake up screen
        PowerManager pm = (PowerManager) getApplicationContext().getSystemService(Context.POWER_SERVICE);
        int wakeFlags = PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP;
        if (Build.VERSION.SDK_INT <= 15) {
            wakeFlags |= PowerManager.SCREEN_BRIGHT_WAKE_LOCK;
        }

        PowerManager.WakeLock wakeLock = pm.newWakeLock(wakeFlags, "MyApp:Call");
        wakeLock.acquire(30000); //wakelock for 30 sec

        View view = new View(this);
        view.setBackgroundColor(Color.RED);
        setContentView(view);
    }

}

Remember to add WAKE_LOCK permission in the manifest.

Upvotes: 1

Related Questions