Android O - однолинейное уведомление - например, "Система Android - USB зарядка этого устройства"
Я хотел бы получать постоянное уведомление для моего ForegroundService
это требует как можно меньшего места. Мне нравится стиль "Android System - USB-зарядка этого устройства", но я не могу найти ни одного примера, как этого добиться.
Может кто-то указать мне верное направление?
Обновить
Стиль присваивается уведомлению, если каналу присвоено значение IMPORTANCE_MIN
,
Похоже, что для уведомлений о IMPORTANCE_MIN
использоваться с ForegroundService
,
Вот описание IMPORTANCE_MIN
:
Минимальное значение уведомления: отображается только в тени, ниже сгиба. Это не должно использоваться с Service.startForeground, так как предполагается, что служба foreground должна быть чем-то, о чем заботится пользователь, поэтому не имеет смысла обозначать свое уведомление как минимальное значение. Если вы сделаете это начиная с версии Android Build.VERSION_CODES.O, система покажет уведомление с более высоким приоритетом о том, что ваше приложение работает в фоновом режиме.
5 ответов
Чтобы ответить на оригинальный вопрос:
Похоже, в Android O нет встроенного способа получить единую строку, постоянное уведомление для ForegroundService
, Можно попытаться добавить индивидуальный дизайн, но, поскольку разные телефоны имеют разные дизайны для уведомлений, это решение вряд ли является хорошим.
Однако есть надежда:)
На Android P уведомление в NotificationChannel
из IMPORTANCE_LOW
с приоритетом PRIORITY_LOW
уплотняется в одну строку даже для ForegroundService
, Да уж!!
Для отображения компактного однострочного уведомления, такого как уведомление о начислении платы, необходимо создать Notification Channel
с приоритетом IMPORTANCE_MIN.
@TargetApi(Build.VERSION_CODES.O)
private static void createFgServiceChannel(Context context) {
NotificationChannel channel = new NotificationChannel("channel_id", "Channel Name", NotificationManager.IMPORTANCE_MIN);
NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.createNotificationChannel(channel);
}
И затем создайте текущее уведомление как это:
public static Notification getServiceNotification(Context context) {
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context, "channel_id");
mBuilder.setContentTitle("One line text");
mBuilder.setSmallIcon(R.drawable.ic_notification);
mBuilder.setProgress(0, 0, true);
mBuilder.setOngoing(true);
return mBuilder.build();
}
НОТА
Обратите внимание, что я проверил это с IntentService
вместо Service
и это работает. Также я только что проверил настройку Thread.sleep()
15 секунд, и уведомление отображается идеально, пока IntentService
останавливается сам
Есть некоторые изображения (извините, некоторые тексты на испанском языке, но я думаю, что изображения все еще полезны):
А если вы перетащите вниз и откроете уведомление, оно будет выглядеть следующим образом:
EXTRA
Если вы заметили, что система Android отображает уведомление, указывающее все приложения, использующие батарею (приложения с текущими службами), вы можете понизить приоритет этого вида уведомлений, и он будет отображаться в виде одной строки уведомлений, таких как уведомление о зарядке.
Взгляните на это:
Просто нажмите на это уведомление и выберите ВСЕ КАТЕГОРИИ:
И установите значение LOW:
В следующий раз это уведомление о "расходе заряда батареи" будет отображаться как уведомление о зарядке.
Вам нужно установить приоритет уведомления на Min, значение Notification Channel на Min и отключить отображение значка канала Notification.
Вот пример того, как я это делаю. Я включил создание полного уведомления, а также для справки
private static final int MYAPP_NOTIFICATION_ID= -793531;
NotificationManager notificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
String CHANNEL_ID = "myapp_ongoing";
CharSequence name = context.getString(R.string.channel_name_ongoing);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, name, NotificationManager.IMPORTANCE_MIN);
channel.setShowBadge(false);
notificationManager.createNotificationChannel(channel);
}
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
context, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_stat_notification_add_reminder)
.setContentTitle(context.getString(R.string.app_name))
.setContentText(context.getString(R.string.create_new))
.setOngoing(true).setWhen(0)
.setChannelId(CHANNEL_ID)
.setPriority(NotificationCompat.PRIORITY_MIN);
// Creates an intent for clicking on notification
Intent resultIntent = new Intent(context, MyActivity.class);
...
// The stack builder object will contain an artificial back stack
// for the
// started Activity.
// This ensures that navigating backward from the Activity leads out
// of
// your application to the Home screen.
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
// Adds the back stack for the Intent (but not the Intent itself)
stackBuilder.addParentStack(MyActivity.class);
// Adds the Intent that starts the Activity to the top of the stack
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent = stackBuilder.getPendingIntent(0,
PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(resultPendingIntent);
notificationManager.notify(MYAPP_NOTIFICATION_ID, mBuilder.build());
Расширяемое уведомление
По умолчанию текстовое содержимое уведомления усекается до одной строки. Если вы хотите, чтобы ваше уведомление было длиннее, вы можете включить большую текстовую область, которую можно расширить, применив дополнительный шаблон.
Кроме того, Android 4.1 поддерживает расширяемые уведомления. В дополнение к обычному представлению уведомлений можно определить большое представление, которое будет отображаться при расширении уведомления. В большом представлении можно использовать три стиля: стиль большого изображения, стиль большого текста, стиль "Входящие". Следующий код демонстрирует использование BigTextStyle(), который позволяет использовать до 256 dp.
Например:
String longText = "...";
Notification noti = new Notification.Builder(this)
.....
.....
.....
.setStyle(new Notification.BigTextStyle().bigText(longText))
Я уменьшил размер уведомления службы переднего плана, создав пустое настраиваемое представление, например:
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
а затем создать уведомление следующим образом:
RemoteViews notifiactionCollapsed = new RemoteViews(getPackageName(),R.layout.notification_collapsed);
Notification notification = new NotificationCompat.Builder(this,CHANNEL_ID)
.setSmallIcon(R.drawable.eq_icon)
.setCustomContentView(notifiactionCollapsed)
.setStyle(new NotificationCompat.DecoratedCustomViewStyle())
.setShowWhen(false)
.setContentIntent(pendingIntent)
.setPriority(NotificationCompat.PRIORITY_LOW)
.setOngoing(true)
.setVisibility(NotificationCompat.VISIBILITY_SECRET)
.build();
startForeground(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE,
notification);
Это помогает уменьшить высоту уведомления, но я не уверен, как скрыть значок уведомления.
Попробуйте это, я уже использовал в приложении ранее.
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothGatt;
import android.bluetooth.BluetoothManager;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.support.v7.app.NotificationCompat;
import android.util.Log;
import java.lang.reflect.Method;
public static Notification getForegroundNotification(Context context) {
Notification notification = new NotificationCompat.Builder(context)
.setContentTitle(context.getString(R.string.app_name))
.setContentText("Notification text")
.setAutoCancel(false)
.setPriority(Notification.PRIORITY_MAX)
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher))
.setOngoing(true)
.build();
return notification;
}