android - quitar - ¿Cómo realizar una acción de notificación(clic) en la pantalla de bloqueo?
notificaciones en pantalla de bloqueo samsung galaxy j7 (3)
TL; DR
¿Cómo puedo hacer una notificación que funcione desde la pantalla de bloqueo sin desbloquear? Después de hacer clic en una acción, un botón en la notificación o solo la notificación completa, quiero hacer una llamada a la API (sin escribir mi código de desbloqueo)
Detalles
Gol
Basándome en la respuesta a esta pregunta , intenté hacer una notificación con una acción que funciona en la pantalla de bloqueo sin desbloquear el dispositivo. La acción es algo que no necesita más interfaz o interacción (piense ''enviar una solicitud de API'').
Estado
La notificación y haga clic en trabajar con un dispositivo desbloqueado. Sin embargo, cuando estoy bloqueado, todavía tengo que ingresar el código de desbloqueo primero, así que o algo nuevo está sucediendo, o simplemente entendí mal la forma en que se supone que funciona.
Si comprendo correctamente, puedo configurar mi visibilidad como ''pública'' para mostrar el contenido (esto funciona), y en lugar de definir una acción (que no parece ser pública) puedo manejar los clics en el diseño (ahora visible). Intenté esto con el siguiente código, pero obviamente no funciona.
He intentado enviar la intención a mi aplicación y a un servicio, como sugirió Florian a continuación.
Código
Este es el código donde comienzo la notificación (esto vive en una Actividad, el código se acortó para su conveniencia)
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());
}
Como dije, también probé con el servicio como sugirió Florian, con esto como una llamada:
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);
La acción no se mostró en la pantalla de bloqueo, así que la cambié al setContentIntent
que ves arriba. El resultado es el mismo, sin embargo, no hay acción para mí :(
Combinando la respuesta de la pregunta que vinculé (el botón de acción de Notificación no se puede hacer clic en la pantalla de bloqueo ) y el que @florian_barth dio arriba, lo tengo funcionando
El truco parece ser
- Usar un servicio
- Agregue la intención no como una acción o un contentIntent, sino con el método
RemoteViews
.
Combinado será:
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);
También funciona con receptor Broadcast y setAction.
PendingIntent pendingIntent = PendingIntent.getBroadcast(..
builder.addAction(..
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
En la pantalla de bloqueo, deslice hacia abajo la notificación para expandirla y toque el área de acción para invocar el receptor de difusión sin desbloquear el teléfono.
Trate de usar un IntentService . Reemplace su objetivo de intención con su servicio de intención:
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);
Registre su servicio en el Manifiesto:
<service
android:name="app.great.mypackage.MyIntentService"
android:exported="false"/>
Su servicio podría verse así:
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
}
}
ACTUALIZACIÓN con comentarios de Nanne
El truco parece ser
- Usar un servicio
- Agregue la intención no como una acción o un contentIntent, sino con el método RemoteViews.
Combinado será:
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);