Android 5.0 Lollipopにアップグレードした後、ロック画面に自動的に進行中の通知が表示され始めました。
ユーザーがすべてを表示したくない場合があるため、ステータス領域で通知を許可し、ロック画面で非表示にする方法を開発者に求めています。
私が見つけた唯一の方法は、ユーザーに画面ロック(GestureやPINなど)を強制的に使用させ、プログラムで setVisibility() to VISIBILITY_SECRET にすることです。しかし、すべての人が画面ロックを使用したいとは限りません。
通知を通知するフラグ(またはフラグの組み合わせ)はありますか:ロック画面には表示されませんが、通知領域には表示されますか?
この回答 で説明されているように、 VISIBILITY_SECRET
を使用すると、ユーザーが安全なキーガードを持っている場合(スワイプするだけでなく、キーガードがない場合でも)、ロック画面での通知を抑制することができます。 )および機密通知が抑制されています。
残りのケースをカバーするために、キーガードが存在するときはいつでも通知の優先度を PRIORITY_MIN
に設定して、ロック画面とステータスバーから通知をプログラムで非表示にし、いつでも優先度をリセットできます。キーガードがありません。
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));
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が現在実行できる最善の方法です。
通知の優先度を PRIORITY_MIN に設定できます。これにより、ロック画面の通知が非表示になります。また、ステータスバーからアイコンを非表示にしますが(必要かどうかはわかりません)、通知自体は引き続き通知領域に表示されます。
次のような進行中の通知用に「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で動作することが確認されています。
それに応じてレシーバーを登録および登録解除することを忘れないでください。