Как выполнить уведомление-действие (щелчок) на экране блокировки?
TL; DR
Как я могу сделать уведомление, которое выполняет некоторую работу с блокировки без разблокировки? После нажатия на действие, кнопку уведомления или только полное уведомление, я хочу выполнить вызов API (без ввода кода разблокировки)
Подробнее
Цель
Основываясь на ответе на этот вопрос, я попытался сделать уведомление с действием, которое работает на lockscreen без разблокировки устройства. Действие - это то, что не требует никакого дополнительного интерфейса или взаимодействия (подумайте "отправьте запрос API" ).
Состояние
Уведомление и щелчок работают с разблокированным устройством. Однако, когда я заблокирован, мне все равно нужно сначала ввести код разблокировки, так что либо происходит что-то новое, либо я просто неправильно понял, как он должен работать.
Если я правильно понимаю, я могу установить видимость для публики, чтобы показать содержимое (это работает), и вместо определения действия (которое, похоже, не является общедоступным) я могу обрабатывать клики на (теперь видимом ) макет. Я попробовал это с приведенным ниже кодом, но, очевидно, он не работает.
Я попробовал как отправить намерение своему приложению, так и службе, как показано ниже.
код
Это код, в котором я начинаю уведомление (это живет в 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());
}
Как уже было сказано, я также пробовал использовать эту услугу, как предложил флориан, причем это как звонок:
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
, который вы видите выше. Результат тот же, хотя для меня нет действий: (
Ответы
Ответ 1
Попробуйте использовать 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);
Ответ 2
Объединив ответ с вопросом, который я связал (кнопка действия уведомления, не щелкнув по экрану блокировки), а один @florian_barth дал выше, я получил его работу
Кажется, что трюк должен быть
- Использовать службу
- Добавить намерение не как действие или contentIntent, а с помощью метода
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);
Ответ 3
Он также работает с широковещательным приемником и setAction
PendingIntent pendingIntent = PendingIntent.getBroadcast(..
builder.addAction(..
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
На экране блокировки проведите пальцем по уведомлению, чтобы развернуть его, и коснитесь области действия, чтобы вызвать широковещательный приемник, не отпирая телефон.