如何在锁定屏幕上执行通知操作(单击)?
How to perform notification-action (click) on lock-screen?
TL;DR
如何在不解锁的情况下发出在锁定屏幕上执行某些操作的通知?单击一个操作、通知上的一个按钮或只是完整的通知后,我想进行 API 调用(无需输入我的解锁代码)
详情
目标
根据 this question 上的回答,我尝试发出一个通知,其中包含一个在锁定屏幕上有效的操作,而无需解锁设备。该操作不需要任何进一步的界面或交互(想想'send an API request')。
状态
通知和点击适用于解锁的设备。然而,当锁定时我仍然需要先输入解锁码,所以要么发生了新的事情,要么我只是误解了它应该工作的方式。
如果我理解正确,我可以将我的可见性设置为 'public' 以显示内容(这有效),而不是定义一个动作(这似乎不是 public)我可以处理对(现在可见的)布局的点击。我用下面的代码试过了,但显然它不起作用。
我已经尝试将意图发送到我的应用程序和服务,正如 florian 在下面所建议的那样。
代码
这是我开始通知的代码(它存在于 Activity 中,为方便起见已缩短代码)
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());
}
如前所述,我也尝试了 florian 建议的服务,并将其作为调用:
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);
锁定屏幕上没有显示该操作,所以我将其更改为您在上面看到的 setContentIntent
。结果是一样的,我没有采取任何行动:(
尝试使用 IntentService。
将您的意图目标替换为您的意图服务:
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);
在清单中注册您的服务:
<service
android:name="app.great.mypackage.MyIntentService"
android:exported="false"/>
您的服务可能如下所示:
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
}
}
根据 Nanne 的反馈进行更新
这个技巧似乎是为了
- 使用服务
- 不是将意图添加为动作或内容意图,而是使用 RemoteViews 方法。
合并后为:
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);
结合我链接的问题的答案 (Notification action button not clickable in lock screen) 和上面@florian_barth 给出的答案,我成功了
这个技巧似乎是
- 使用服务
- 添加意图不是作为动作或内容意图,而是使用
RemoteViews
方法。
合并后将是:
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);
它也适用于广播接收器和 setAction
PendingIntent pendingIntent = PendingIntent.getBroadcast(..
builder.addAction(..
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
在锁定屏幕上向下滑动通知以展开它,然后点击操作区域以调用广播接收器而无需解锁 phone。
TL;DR
如何在不解锁的情况下发出在锁定屏幕上执行某些操作的通知?单击一个操作、通知上的一个按钮或只是完整的通知后,我想进行 API 调用(无需输入我的解锁代码)
详情
目标
根据 this question 上的回答,我尝试发出一个通知,其中包含一个在锁定屏幕上有效的操作,而无需解锁设备。该操作不需要任何进一步的界面或交互(想想'send an API request')。
状态
通知和点击适用于解锁的设备。然而,当锁定时我仍然需要先输入解锁码,所以要么发生了新的事情,要么我只是误解了它应该工作的方式。
如果我理解正确,我可以将我的可见性设置为 'public' 以显示内容(这有效),而不是定义一个动作(这似乎不是 public)我可以处理对(现在可见的)布局的点击。我用下面的代码试过了,但显然它不起作用。
我已经尝试将意图发送到我的应用程序和服务,正如 florian 在下面所建议的那样。
代码
这是我开始通知的代码(它存在于 Activity 中,为方便起见已缩短代码)
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());
}
如前所述,我也尝试了 florian 建议的服务,并将其作为调用:
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);
锁定屏幕上没有显示该操作,所以我将其更改为您在上面看到的 setContentIntent
。结果是一样的,我没有采取任何行动:(
尝试使用 IntentService。 将您的意图目标替换为您的意图服务:
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);
在清单中注册您的服务:
<service
android:name="app.great.mypackage.MyIntentService"
android:exported="false"/>
您的服务可能如下所示:
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
}
}
根据 Nanne 的反馈进行更新
这个技巧似乎是为了
- 使用服务
- 不是将意图添加为动作或内容意图,而是使用 RemoteViews 方法。
合并后为:
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);
结合我链接的问题的答案 (Notification action button not clickable in lock screen) 和上面@florian_barth 给出的答案,我成功了
这个技巧似乎是
- 使用服务
- 添加意图不是作为动作或内容意图,而是使用
RemoteViews
方法。
合并后将是:
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);
它也适用于广播接收器和 setAction
PendingIntent pendingIntent = PendingIntent.getBroadcast(..
builder.addAction(..
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
在锁定屏幕上向下滑动通知以展开它,然后点击操作区域以调用广播接收器而无需解锁 phone。