web-dev-qa-db-ja.com

ロック画面で通知アクション(クリック)を実行する方法

TL; DR

ロック画面からロック解除せずに一部が機能することを通知するにはどうすればよいですか?アクション、通知のボタン、または通知全体をクリックした後、APIロックを解除したい(ロック解除コードを入力しない)

細部

ゴール

この質問 の回答に基づいて、デバイスのロックを解除せずにロック画面で機能するアクションで通知を作成しようとしました。アクションは、それ以上のインターフェースや相互作用を必要としないものです(「APIリクエストを送信する」と考えてください)。

状態

通知とクリックは、ロックされていないデバイスで機能します。ただし、ロックされている場合でも、最初にロック解除コードを入力する必要があるため、何か新しいことが起こっているか、または機能するはずの方法を誤解しています。

正しく理解できれば、可視性を「公開」に設定してコンテンツを表示でき(これは機能します)、アクションを定義する代わりに(公開されていないように見えます)、(現在表示されている)レイアウトのクリックを処理できます。私は以下のコードでこれを試しましたが、明らかに機能しません。

Florianが以下に提案するように、アプリとサービスの両方にインテントを送信しようとしました。

コード

これは私が通知を開始するコードです(これはアクティビティにあります。コードはあなたの便宜のために短縮されました)

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に変更しました。結果は同じですが、私のためのアクションはありません:(

25
Nanne

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からのフィードバックで更新

トリックはするようです

  1. サービスを利用する
  2. アクションまたは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);
16
Florian Barth

私がリンクした質問( ロック画面では通知アクションボタンをクリックできない )の回答と@florian_barthが上記で与えた回答を組み合わせて、うまくいきました

トリックはするようです

  1. サービスを利用する
  2. アクションまたは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);
5
Nanne

ブロードキャストレシーバーおよびsetActionとも連携します。

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

ロック画面で通知を下にスワイプして通知を展開し、アクション領域をタップして、電話のロックを解除せずにブロードキャストレシーバーを呼び出します。

1
farid_z