如何在锁定屏幕上执行通知操作(单击)?

时间:2015-11-15 20:20:48

标签: android notifications android-service android-5.0-lollipop lockscreen

TL; DR

如何在没有解锁的情况下从锁定屏幕发出一些有效的通知?点击操作,通知上的按钮或完整通知后,我想进行API调用(无需键入解锁代码)

详细

目标

根据this question上的答案,我尝试使用可在锁定屏幕上运行的操作发出通知,而无需解锁设备。该操作不需要任何进一步的界面或交互(想想'发送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());

}

如上所述,我也尝试过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。结果是一样的,对我没有任何动作:(

3 个答案:

答案 0 :(得分:15)

尝试使用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);

在Manifest中注册您的服务:

  <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的反馈

诀窍似乎是

  1. 使用服务
  2. 不要将intent作为action或contentIntent添加,而是使用RemoteViews方法。
  3. 结合起来将是:

    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);
    

答案 1 :(得分:4)

结合我链接的问题(Notification action button not clickable in lock screen)和上面提到的@florian_barth的答案,我得到了它的工作

诀窍似乎是

  1. 使用服务
  2. 不是将动作添加为动作或contentIntent,而是使用RemoteViews方法。
  3. 结合起来将是:

        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 :(得分:1)

它也适用于Broadcast receiver和setAction

PendingIntent pendingIntent = PendingIntent.getBroadcast(..
builder.addAction(..
   .setVisibility(NotificationCompat.VISIBILITY_PUBLIC)

在锁定屏幕上向下滑动通知以展开它,然后点按操作区域以调用广播接收器而不解锁手机。