在 Android O 中不推荐使用 NotificationCompat.Builder

在我的项目升级到 仿生人 O之后

buildToolsVersion "26.0.1"

Android Studio 中的 Lint 对以下通知构建器方法显示了一个不推荐的警告:

new NotificationCompat.Builder(context)

问题是: Android 开发人员更新了描述 通知频道的文档,以支持 Android O 中的通知,并为我们提供了一个代码片段,但是提供了同样不推荐的警告:

Notification notification = new Notification.Builder(MainActivity.this)
.setContentTitle("New Message")
.setContentText("You've received new messages.")
.setSmallIcon(R.drawable.ic_notify_status)
.setChannelId(CHANNEL_ID)
.build();

通知概览

我的问题: 是否还有其他解决方案来构建通知,并且仍然支持 Android O?

我发现的一个解决方案是在 Notification 中将通道 ID 作为参数传递。生成器构造函数。但是这个解决方案并不完全可重用。

new Notification.Builder(MainActivity.this, "channel_id")
180026 次浏览

文档中提到,构建器方法 NotificationCompat.Builder(Context context)已被弃用。我们必须使用具有 channelId参数的构造函数:

NotificationCompat.Builder(Context context, String channelId)

NotificationCompat. Builder 文档:

在 API 级别26.0.0-beta1. use 中不推荐使用此构造函数 取而代之的是 NotificationCompat.Builder (Context,String) 通知必须指定 NotificationChannel Id。

建筑工程文件:

此构造函数在 API 级别26中不推荐使用 取而代之的是 Notificy.Builder (Context,String) 通知必须指定 NotificationChannel Id。

如果希望重用生成器设置器,可以使用 channelId创建生成器,然后将该生成器传递给助手方法,并在该方法中设置首选设置。

调用2-arg 构造函数: 为了与 Android O 兼容,调用 support-v4 NotificationCompat.Builder(Context context, String channelId)。当在 Android N 或更早版本上运行时,channelId将被忽略。在 Android O 上运行时,也创建一个具有相同 channelIdNotificationChannel

过期示例代码: 几个 JavaDoc 页面(如 通知,建造者调用 new Notification.Builder(mContext))上的示例代码已经过期。

不推荐的构造函数: 不推荐使用 Notification.Builder(Context context)V4 NotificationCompat.Builder(Context context),支持使用 Notification[Compat].Builder(Context context, String channelId)(参见 Notificy.Builder (android.content. Context)和 v4 NotificationCompat.Builder (上下文))

废弃类: 整个类 V7 NotificationCompat.Builder被废弃。(见 V7 NotificationCompat. Builder)以前,需要 v7 NotificationCompat.Builder来支持 NotificationCompat.MediaStyle。在 Android O 中,在 Media-compat 库android.support.v4.media包中有一个 v4 NotificationCompat.MediaStyle。如果你需要 MediaStyle就用那个。

API 14 + : 在26.0.0及更高版本的 Support Library 中,Support-v4和 Support-v7包都支持最低 API 级别为14。V # 的名字是历史性的。

参见 最近的支持库修订

enter image description here

下面是所有 android 版本的向下兼容代码。

 NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(getContext(), "M_CH_ID");


notificationBuilder.setAutoCancel(true)
.setDefaults(Notification.DEFAULT_ALL)
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.drawable.ic_launcher)
.setTicker("Hearty365")
.setPriority(Notification.PRIORITY_MAX) // this is deprecated in API 26 but you can still use for below 26. check below update for 26 API
.setContentTitle("Default notification")
.setContentText("Lorem ipsum dolor sit amet, consectetur adipiscing elit.")
.setContentInfo("Info");


NotificationManager notificationManager = (NotificationManager) getContext().getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(1, notificationBuilder.build());

更新 API 26以设置最大优先级

    NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
String NOTIFICATION_CHANNEL_ID = "my_channel_id_01";


if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "My Notifications", NotificationManager.IMPORTANCE_MAX);


// Configure the notification channel.
notificationChannel.setDescription("Channel description");
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.RED);
notificationChannel.setVibrationPattern(new long[]{0, 1000, 500, 1000});
notificationChannel.enableVibration(true);
notificationManager.createNotificationChannel(notificationChannel);
}




NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);


notificationBuilder.setAutoCancel(true)
.setDefaults(Notification.DEFAULT_ALL)
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.drawable.ic_launcher)
.setTicker("Hearty365")
//     .setPriority(Notification.PRIORITY_MAX)
.setContentTitle("Default notification")
.setContentText("Lorem ipsum dolor sit amet, consectetur adipiscing elit.")
.setContentInfo("Info");


notificationManager.notify(/*notification id*/1, notificationBuilder.build());

下面是示例代码,它在 Android Oreo 运行良好,不如奥利奥。

  NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder builder = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel notificationChannel = new NotificationChannel("ID", "Name", importance);
notificationManager.createNotificationChannel(notificationChannel);
builder = new NotificationCompat.Builder(getApplicationContext(), notificationChannel.getId());
} else {
builder = new NotificationCompat.Builder(getApplicationContext());
}


builder = builder
.setSmallIcon(R.drawable.ic_notification_icon)
.setColor(ContextCompat.getColor(context, R.color.color))
.setContentTitle(context.getString(R.string.getTitel))
.setTicker(context.getString(R.string.text))
.setContentText(message)
.setDefaults(Notification.DEFAULT_ALL)
.setAutoCancel(true);
notificationManager.notify(requestCode, builder.build());

不像许多答案所显示的那样检查 Build.VERSION.SDK_INT >= Build.VERSION_CODES.O,有一种稍微简单一些的方法-

按照 在 Android 上设置一个 Firebase 云消息客户端应用程序文档中的解释,在 AndroidManifest.xml文件的 application部分添加以下代码行:

    <meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="@string/default_notification_channel_id" />

然后在 Value/strings.xml文件中添加一行通道名:

<string name="default_notification_channel_id">default</string>

之后,你就可以使用新版本的带有2个参数的 NotificationCompat. Builder构造函数了(因为带有1个参数的旧构造函数在 Android Oreo 中已经被废弃了) :

private void sendNotification(String title, String body) {
Intent i = new Intent(this, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pi = PendingIntent.getActivity(this,
0 /* Request code */,
i,
PendingIntent.FLAG_ONE_SHOT);


Uri sound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);


NotificationCompat.Builder builder = new NotificationCompat.Builder(this,
getString(R.string.default_notification_channel_id))
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(title)
.setContentText(body)
.setAutoCancel(true)
.setSound(sound)
.setContentIntent(pi);


NotificationManager manager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);


manager.notify(0, builder.build());
}

简单样本

    public void showNotification (String from, String notification, Intent intent) {
PendingIntent pendingIntent = PendingIntent.getActivity(
context,
Notification_ID,
intent,
PendingIntent.FLAG_UPDATE_CURRENT
);




String NOTIFICATION_CHANNEL_ID = "my_channel_id_01";
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);




if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "My Notifications", NotificationManager.IMPORTANCE_DEFAULT);


// Configure the notification channel.
notificationChannel.setDescription("Channel description");
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.RED);
notificationChannel.setVibrationPattern(new long[]{0, 1000, 500, 1000});
notificationChannel.enableVibration(true);
notificationManager.createNotificationChannel(notificationChannel);
}




NotificationCompat.Builder builder = new NotificationCompat.Builder(context, NOTIFICATION_CHANNEL_ID);
Notification mNotification = builder
.setContentTitle(from)
.setContentText(notification)


//                .setTicker("Hearty365")
//                .setContentInfo("Info")
//     .setPriority(Notification.PRIORITY_MAX)


.setContentIntent(pendingIntent)


.setAutoCancel(true)
//                .setDefaults(Notification.DEFAULT_ALL)
//                .setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.mipmap.ic_launcher))
.build();


notificationManager.notify(/*notification id*/Notification_ID, mNotification);


}

此构造函数在 API 级别26.1.0中已被弃用。 使用 NotificationCompat.Builder (Context,String)。所有发布的通知必须指定 NotificationChannel Id。

Notification notification = new Notification.Builder(MainActivity.this)
.setContentTitle("New Message")
.setContentText("You've received new messages.")
.setSmallIcon(R.drawable.ic_notify_status)
.setChannelId(CHANNEL_ID)
.build();

正确的代码是:

Notification.Builder notification=new Notification.Builder(this)

具有依赖项26.0.1和新的更新的依赖项,如28.0.0。

有些用户使用以下形式的代码:

Notification notification=new NotificationCompat.Builder(this)//this is also wrong code.

所以逻辑就是声明或初始化哪个方法,然后右边的相同方法将用于分配。如果你在 Leftside 使用了某个方法,那么同样的方法将会在 = for 的右侧使用 new。

试试这个代码... 它一定会工作

  1. 需要使用 Notification _ Channel _ ID 声明 Notification 通道
  2. 使用该通道 ID 构建通知。 比如说,

...
public static final String NOTIFICATION_CHANNEL_ID = MyLocationService.class.getSimpleName();
...
...
NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID,
NOTIFICATION_CHANNEL_ID+"_name",
NotificationManager.IMPORTANCE_HIGH);


NotificationManager notifManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);


notifManager.createNotificationChannel(channel);




NotificationCompat.Builder builder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
.setContentTitle(getString(R.string.app_name))
.setContentText(getString(R.string.notification_text))
.setOngoing(true)
.setContentIntent(broadcastIntent)
.setSmallIcon(R.drawable.ic_tracker)
.setPriority(PRIORITY_HIGH)
.setCategory(Notification.CATEGORY_SERVICE);


startForeground(1, builder.build());
...


我构建了这个代码,它允许您向 android api 级别 < 26或 api 级别 > = 26显示通知

  private void showNotifcation(String title, String body) {
//Este método muestra notificaciones compatibles con Android Api Level < 26 o >=26
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
//Mostrar notificacion en Android Api level >=26
final String CHANNEL_ID = "HEADS_UP_NOTIFICATIONS";
NotificationChannel channel = new NotificationChannel(
CHANNEL_ID,
"MyNotification",
NotificationManager.IMPORTANCE_HIGH);


getSystemService(NotificationManager.class).createNotificationChannel(channel);
Notification.Builder notification = new Notification.Builder(this, CHANNEL_ID)
.setContentTitle(title)
.setContentText(body)
.setSmallIcon(R.drawable.ic_launcher_background)
.setAutoCancel(true);
NotificationManagerCompat.from(this).notify(1, notification.build());


}else{
//Mostrar notificación para Android Api Level Menor a 26
String NOTIFICATION_CHANNEL_ID = "my_channel_id_01";
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
.setContentTitle(title)
.setContentText(body)
.setSmallIcon(R.drawable.ic_launcher_background)
.setAutoCancel(true);


NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(/*notification id*/1, notificationBuilder.build());


}


}

干杯!