web-dev-qa-db-ja.com

Android 5(Lollipop)のロック画面での通知を抑制し、通知領域に入れるにはどうすればよいですか?

Android 5.0 Lollipopにアップグレードした後、ロック画面に自動的に進行中の通知が表示され始めました。

ユーザーがすべてを表示したくない場合があるため、ステータス領域で通知を許可し、ロック画面で非表示にする方法を開発者に求めています。

私が見つけた唯一の方法は、ユーザーに画面ロック(GestureやPINなど)を強制的に使用させ、プログラムで setVisibility() to VISIBILITY_SECRET にすることです。しかし、すべての人が画面ロックを使用したいとは限りません。

通知を通知するフラグ(またはフラグの組み合わせ)はありますか:ロック画面には表示されませんが、通知領域には表示されますか?

18

可視性と優先度を使用する

この回答 で説明されているように、 VISIBILITY_SECRET を使用すると、ユーザーが安全なキーガードを持っている場合(スワイプするだけでなく、キーガードがない場合でも)、ロック画面での通知を抑制することができます。 )および機密通知が抑制されています。

残りのケースをカバーするために、キーガードが存在するときはいつでも通知の優先度を PRIORITY_MIN に設定して、ロック画面とステータスバーから通知をプログラムで非表示にし、いつでも優先度をリセットできます。キーガードがありません。

短所

  • Android 5エミュレーターを使用すると、通知がロック画面に非常に短時間表示された後、消えてしまうようです。
  • 通知の優先順位は非推奨 であるため、ユーザーが安全なロック画面(スワイプのみなど)を持っていない場合、Android O Developer Preview 2)以降は機能しなくなりました。

final BroadcastReceiver notificationUpdateReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        NotificationManager notificationManager =
            (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);

        NotificationCompat.Builder builder =
            new NotificationCompat.Builder(context);
            .setVisibility(NotificationCompat.VISIBILITY_SECRET);

        KeyguardManager keyguardManager =
            (KeyguardManager)context.getSystemService(Context.KEYGUARD_SERVICE);

        if (keyguardManager.isKeyguardLocked())
            builder.setPriority(NotificationCompat.PRIORITY_MIN);

        notificationManager.notify(YOUR_NOTIFICATION_ID, builder.build());
    }
};

//For when the screen might have been locked
context.registerReceiver(notificationUpdateReceiver,
    new IntentFilter(Intent.ACTION_SCREEN_OFF));

//Just in case the screen didn't get a chance to finish turning off but still locked
context.registerReceiver(notificationUpdateReceiver,
    new IntentFilter(Intent.ACTION_SCREEN_ON));

//For when the user unlocks the device
context.registerReceiver(notificationUpdateReceiver,
    new IntentFilter(Intent.ACTION_USER_PRESENT));

//For when the user changes users
context.registerReceiver(notificationUpdateReceiver,
    new IntentFilter(Intent.ACTION_USER_BACKGROUND));
context.registerReceiver(notificationUpdateReceiver,
    new IntentFilter(Intent.ACTION_USER_FOREGROUND));
14
Sam

VISIBILITY_SECRET が最もクリーンなアプローチを実行しているようです。ドキュメントによると:

vISIBILITY_SECRETで通知を行うことができます。これにより、ユーザーがロック画面をバイパスするまで、アイコンとティッカーが抑制されます。

ソース(SystemUI AOSPプロジェクトのNotificationData)によると、VISIBILITY_SECRETがそれを行う唯一の方法です。

boolean shouldFilterOut(StatusBarNotification sbn) {
    if (!(mEnvironment.isDeviceProvisioned() ||
            showNotificationEvenIfUnprovisioned(sbn))) {
        return true;
    }

    if (!mEnvironment.isNotificationForCurrentProfiles(sbn)) {
        return true;
    }

    if (sbn.getNotification().visibility == Notification.VISIBILITY_SECRET &&
            mEnvironment.shouldHideSensitiveContents(sbn.getUserId())) {
        return true;
    }
    return false;
}

除外されているように見える他のタイプの通知は、要約が存在するグループ内の子通知のみです。したがって、要約の正当な理由がある複数のものがない限り、VISIBILITY_SECRETが現在実行できる最善の方法です。

6
Jim Vitek

通知の優先度を PRIORITY_MIN に設定できます。これにより、ロック画面の通知が非表示になります。また、ステータスバーからアイコンを非表示にしますが(必要かどうかはわかりません)、通知自体は引き続き通知領域に表示されます。

4
Floern

次のような進行中の通知用に「LockscreenIntentReceiver」を作成しました。


    private class LockscreenIntentReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        try { 
            String action = intent.getAction();
            if (action.equals(Intent.ACTION_SCREEN_OFF)) {
                Log.d(TAG, "LockscreenIntentReceiver: ACTION_SCREEN_OFF");
                disableNotification();
            } else if (action.equals(Intent.ACTION_USER_PRESENT)){
                Log.d(TAG, "LockscreenIntentReceiver: ACTION_USER_PRESENT");
                // NOTE: Swipe unlocks don't have an official Intent/API in Android for detection yet,
                // and if we set ungoing control without a delay, it will get negated before it's created
                // when pressing the lock/unlock button too fast consequently.
                Handler handler = new Handler();
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        if (NotificationService.this.isNotificationAllowed()) {
                            enableNotification((Context)NotificationService.this);
                        }
                    }
                }, 800);
            }
        } catch (Exception e) {
            Log.e(TAG, "LockscreenIntentReceiver exception: " + e.toString());
        }
    }
}

このコードは基本的に、ユーザーが電話をロックしたときに進行中の通知を削除します(削除は非常に短時間表示されます)。また、ユーザーが電話のロックを解除すると、進行中の通知は遅延時間(ここでは800ミリ秒)後に復元されます。 enableNotification()は通知を作成するメソッドであり、startForeground()を呼び出します。現在、Android 7.1.1で動作することが確認されています。

それに応じてレシーバーを登録および登録解除することを忘れないでください。

0
ItWillDo