Android O - 单行通知 - 就像 "Android System - USB charging this device"

Android O - Single line Notification - like the "Android System - USB charging this device"

我想为我的 ForegroundService 发送一个持续通知,它需要尽可能小的地方。我喜欢“Android System - USB charging this device”风格,但我找不到任何实现这一点的例子。

谁能给我指出正确的方向?

更新

如果为频道分配了重要性 IMPORTANCE_MIN,则通知的样式会被赋予 IMPORTANCE_MIN

似乎无法使用 Android 的内置样式通知 IMPORTANCE_MINForegroundService 一起使用。

这里是IMPORTANCE_MIN的描述:

Min notification importance: only shows in the shade, below the fold. This should not be used with Service.startForeground since a foreground service is supposed to be something the user cares about so it does not make semantic sense to mark its notification as minimum importance. If you do this as of Android version Build.VERSION_CODES.O, the system will show a higher-priority notification about your app running in the background.

您需要将通知优先级设置为最低,通知渠道重要性设置为最低,并禁止显示通知渠道徽章。

这是我如何操作的示例。我也包括创建完整的通知以供参考

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());

要显示像充电通知这样紧凑的单行通知,您必须创建一个 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 自行停止。

有一些图片(抱歉有些文字是西班牙语,但我认为这些图片仍然有用):

而如果你向下拖动打开通知,则显示如下:

额外

如果您注意到 Android 系统显示一条通知,指示所有正在使用电池的应用程序(具有持续服务的应用程序),您可以降低此类通知的优先级,它将显示为单行通知喜欢充电通知

看看这个:

只需长按此通知,select 所有类别:

并将重要性设置为低:

下次,此 "battery consumption" 通知将显示为充电通知。

回答原题:

在 Android O 上似乎没有内置方法来获取单行,持续通知 ForegroundService。可以尝试添加自定义设计,但由于不同的手机有不同的通知设计,这种解决方案很难说是好的。

不过还是有希望的:)

On Android P NotificationChannel of IMPORTANCE_LOW 优先级的通知PRIORITY_LOW 被压缩为一行,即使 ForegroundService 也是如此。是的!!

我通过创建一个空的自定义视图来缩小前台服务通知的大小:

<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);

这有助于降低通知的高度,但我仍然不确定如何隐藏通知图标。