ステータスバーに3秒ぐらい出る、あのテキストです。
Android 5.0 Lollipopではこれが表示されなくなりましたが、同じくLollipopで新設されたHeads Up Notificationで、ある程度は代替できます。
うっとうしいですけど。
Ticker Textが異なる場合は割合単純です。今回は、Ticker Textが同一の場合でも強制表示させるパターンについて、その方法を探りました。
ソースコードはhttps://github.com/af-not-found/NotifTestにあります。
Heads Up Notificationにすると、10秒ぐらい表示されてしまって邪魔です。2.5秒後に通常のNotificationに変更することで、表示時間を擬似的に短縮できます。
public void doNotify() {
final NotificationManager nman
= (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Intent notificationIntent = new Intent(this, clazz);
PendingIntent contentIntent
= PendingIntent.getActivity(this, 0, notificationIntent, 0);
if (builder == null) {
builder = new NotificationCompat.Builder(getApplicationContext());
builder.setContentIntent(contentIntent);
builder.setSmallIcon(android.R.drawable.ic_dialog_info);
builder.setContentTitle(getString(R.string.app_name));
builder.setWhen(System.currentTimeMillis());
}
String text = "notification from action";
builder.setTicker(text);
builder.setContentText(text);
// Android5.0以上
if (Build.VERSION.SDK_INT > 20) {
// Heads Up Notification
builder.setCategory(Notification.CATEGORY_SERVICE);
builder.setPriority(Notification.PRIORITY_HIGH);
// 実行されないように遅延されたバイブレーション
builder.setVibrate(new long[]{60000, 100});
// 2.5秒後に通常のNotificationに変更
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
builder.setPriority(Notification.PRIORITY_DEFAULT);
builder.setVibrate(null);
nman.notify(NOTIF_ID, builder.build());
}
}, 2500);
}
// 強制再表示させるために一旦キャンセル
nman.cancel(NOTIF_ID);
nman.notify(NOTIF_ID, builder.build());
}
setVibrate(new long[]{60000, 100});
していますが、2.5秒後にsetVibrate(null);
してますので、実際にはバイブレーションは実行されません。
Android 4.4 KitKatまでは、フォアグラウンドを一旦キャンセルしてから再度フォアグラウンド化することで、同一のTicker Textでも強制表示できました。
Android 5.0 Lollipopでも同じ方法が使えますが、割り切って別のNotification IDで表示する方法が良さそうです。単発の場合と異なり、2.5秒後にキャンセルします。
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent.getStringExtra("start") != null) {
final NotificationManager nman
= (NotificationManager)
getSystemService(Context.NOTIFICATION_SERVICE);
// Android4.4以下
if (Build.VERSION.SDK_INT <= 20) {
// 強制再表示させるためにフォアグラウンドをキャンセル
stopForeground(true);
startForeground(NOTIF_ID, createNotification(false));
}
// Android5.0以上
else {
// 初回の場合
if (builder == null) {
startForeground(NOTIF_ID, createNotification(false));
}
// 内容の更新
else {
nman.notify(NOTIF_ID, createNotification(false));
}
// Heads Up Notificationを表示
nman.notify(NOTIF_ID_HEADSUP, createNotification(true));
// 2.5秒後にキャンセル
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
nman.cancel(NOTIF_ID_HEADSUP);
}
}, 2500);
}
}
return super.onStartCommand(intent, flags, startId);
}
private Notification createNotification(boolean headsUp) {
NotificationCompat.Builder b = null;
if (builder != null) {
b = builder;
}
else {
Intent notificationIntent = new Intent(this, clazz);
PendingIntent contentIntent
= PendingIntent.getActivity(this, 0, notificationIntent, 0);
b = new NotificationCompat.Builder(getApplicationContext());
b.setContentIntent(contentIntent);
b.setSmallIcon(android.R.drawable.ic_dialog_info);
b.setContentTitle(getString(R.string.app_name));
b.setWhen(System.currentTimeMillis());
builder = b;
}
if (headsUp) {
// Heads Up Notification
b.setCategory(Notification.CATEGORY_SERVICE);
b.setPriority(Notification.PRIORITY_HIGH);
// 実行されないように遅延されたバイブレーション
b.setVibrate(new long[]{60000, 100});
}
else {
b.setCategory(null);
b.setPriority(Notification.PRIORITY_DEFAULT);
b.setVibrate(null);
}
String text = "notification from service";
b.setTicker(text);
b.setContentText(text);
b.setTicker(text);
b.setContentText(text);
return b.build();
}
new Handler().postDelayed(new Runnable(){...})
ですが、UIスレッド以外から実行する場合は、Looper.getMainLooper()
を使う必要があります。
これでミスってtwawm2に不具合出してもーた。
https://github.com/af-not-found/twawm2/commit/3fe71d6fcfccebd1831ae3487dd86b13427b0f05