Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to perform notification-action (click) on lock-screen?

Tags:

TL;DR

How can I make a notification that does some work from the lock-screen without unlocking? After clicking an action, a button on the notification or just the complete notification, I want to do an API call (without typing my unlock code)

Details

Goal

Based on the answer on this question I tried to make a notification with an action that works on the lockscreen without unlocking the device. The action is something that doesn't need any further interface or interaction (think 'send an API request').

Status

The notification and click do work with an unlocked device. However, when locked I still need to enter the unlock code first, so either there is something new going on, or I just misunderstood the way it is supposed to work.

If I understand correctly I can set my visibility to 'public' to show the content (this works), and instead of defining an action (which does't seem to be public) I can handle clicks on the (now visible) layout. I tried this with the below code, but obviously it doesn't work.

I have tried both sending the intent to my app and to a service, as florian suggested below.

Code

This is code where I start the notification (this lives in an Activity, code was shortened for your convenience )

private void startNotification() {      NotificationCompat.Builder builder =              new NotificationCompat.Builder(this)             .setVisibility(Notification.VISIBILITY_PUBLIC)             .setOngoing(true)             .setSmallIcon(R.drawable.abc_ic_menu_share_mtrl_alpha)             .setContentTitle("title text")             .setContentText("content text");      Intent openIntent = new Intent(MyMainActivity.this, MyMainActivity.class);     openIntent.setAction("some_string");     PendingIntent pOpenIntent = PendingIntent.getActivity(this, 0, openIntent, 0);     builder.setContentIntent(pOpenIntent);      RemoteViews view = new RemoteViews(getPackageName(), R.layout.notification);     builder.setContent(view);      NotificationManager mNotificationManager =             (NotificationManager) getSystemService(NOTIFICATION_SERVICE);     mNotificationManager.notify(id, builder.build());  } 

As said, I also tried with the service as florian suggested, with this as a call:

    Intent yepIntent = new Intent(this, MyIntentService.class);     yepIntent.setAction("test");     yepIntent.putExtra("foo", true);     yepIntent.putExtra("bar", "more info");     PendingIntent yepPendingIntent = PendingIntent.getService(this, notificationId, yepIntent, PendingIntent.FLAG_CANCEL_CURRENT);     //builder.addAction(R.drawable.abc_ic_menu_share_mtrl_alpha, "My Action", yepPendingIntent);     builder.setContentIntent(yepPendingIntent); 

The action didn't show up on the lock-screen, so I changed it to the setContentIntent you see above. The result is the same though, no action for me :(

like image 877
Nanne Avatar asked Nov 15 '15 20:11

Nanne


People also ask

How do I get my notifications to pop up on my Lock screen?

Open your phone's Settings app. Notifications. Under "Lock screen," tap Notifications on lock screen or On lock screen. Choose Show alerting and silent notifications.


1 Answers

Try using an IntentService. Replace your intent target with your intent service:

    Intent yepIntent = new Intent(context, MyIntentService.class);     yepIntent.putExtra("foo", true);     yepIntent.putExtra("bar", "more info");     PendingIntent yepPendingIntent = PendingIntent.getService(context, notificationId, yepIntent, PendingIntent.FLAG_CANCEL_CURRENT);     notificationBuilder.addAction(R.drawable.icon_of_choice, "My Action", yepPendingIntent); 

Register your service in the Manifest:

  <service         android:name="app.great.mypackage.MyIntentService"         android:exported="false"/> 

Your Service could look like this:

public class MyIntentSerice extends IntentService {     @Override     protected void onHandleIntent(Intent intent) {         Log.d("myapp", "I got this awesome intent and will now do stuff in the background!");         // .... do what you like     } } 

UPDATE with feedback from Nanne

The trick seems to be to

  1. Use a service
  2. Add the intent not as an action or a contentIntent, but with the RemoteViews method.

Combined it will be:

NotificationCompat.Builder builder = new NotificationCompat.Builder(this)         .setVisibility(Notification.VISIBILITY_PUBLIC)         .setOngoing(true)         .setSmallIcon(R.drawable.abc_ic_menu_share_mtrl_alpha)         .setContentTitle("My notification")         .setContentText("Hello World!");  int notificationId = 1; Intent yepIntent = new Intent(this, MyIntentService.class); yepIntent.setAction("test"); yepIntent.putExtra("foo", true); yepIntent.putExtra("bar", "more info"); PendingIntent yepPendingIntent = PendingIntent.getService(this, notificationId, yepIntent, PendingIntent.FLAG_CANCEL_CURRENT);  // doesn't show up on my lock-screen //builder.addAction(R.drawable.abc_ic_menu_share_mtrl_alpha, "My Action", yepPendingIntent);  // asks for unlock code for some reason //builder.setContentIntent(yepPendingIntent);  // Bingo RemoteViews view = new RemoteViews(getPackageName(), R.layout.notification); view.setOnClickPendingIntent(R.id.notification_closebtn_ib, yepPendingIntent); builder.setContent(view); 
like image 115
Florian Barth Avatar answered Oct 03 '22 21:10

Florian Barth