Search code examples
androidnotificationslockscreen

Prompt to unlock lock screen on custom notification click


I have a custom notification shown in the lock screen. I am using a broadcast pending intent to send a message to my app once the notification is clicked. Which later starts an activity in the broadcast receiver.

The problem is, once I click on the notification, it disappears from the lock-screen and the activity is launched behind the lock-screen. It does not ask the user to unlock the screen.

My requirement is to ask the user to unlock the screen as soon as the broadcast is sent by the notification's click event. How do I do that?

I could find this question which looks like my problem. But unfortunately there is no answer.

Here is some code that explains the notification creation I did.

/**
 * Method to render Notification
 */
private void showNotification() {
    NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
    /* set mandatory stuff on builder */

    Notification notification = builder.build();
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
        notification.bigContentView = createCustomView(context);
    }

    NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    manager.notify(getNotificationId(), notification);
}

/**
 * Method to return notification click's PendingIntent
 */
private PendingIntent getNotificationClickIntent() {
    Intent bcIntent = new Intent(OPEN_APP);
    bcIntent.putExtra(EXTRA_DEEP_LINK_URL, getDeepLinkUrl());

    return PendingIntent.getBroadcast(
        context, getReqCode(), bcIntent, PendingIntent.FLAG_ONE_SHOT);
}

/**
 * Method to create custom view for notification
 */
private RemoteViews createCustomView(Context context) {
   RemoteViews customView = new RemoteViews(context.getPackageName(), R.layout.custom_layout);

   if (customView != null) {
        // set dat on views

        customView.setOnClickPendingIntent(R.id.my_view, getNotificationClickIntent());
   }

   return customView;
}

Solution

  • Use Activity intent in pending intent instead of Service or Broadcast

    PendingIntent.getActivity(context, 0, intent,
                                     PendingIntent.FLAG_UPDATE_CURRENT);
    

    Update:

    In my case i use service.

    private fun activityPendingIntent(context: Context, action: String? = null): PendingIntent {
        Timber.d("activityPendingIntent")
        val intent = Intent(context, DummyBackgroundActivity::class.java)
        action?.let { intent.action = action }
        return PendingIntent.getActivity(context, ACTIVITY_NOTIFICATION_ID, intent, PendingIntent.FLAG_CANCEL_CURRENT)
    }
    

    DummyBackgroundActivity

    class DummyBackgroundActivity : AppCompatActivity() {
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            val service = Intent(this, BackgroundService::class.java)
            service.action = intent.action
            startService(service)
        }
    
        override fun onResume() {
            super.onResume()
            finish()
        }
    }
    

    Service:

    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        Timber.d("onStartCommand intent = %s", intent?.action)
        when (intent?.action) {
           //Handle it 
        }
    
        return Service.START_NOT_STICKY
    }
    

    I hope you replicate the same using Broadcast.