NotificationCompat.Builder устарел в Android O

161

После обновления моего проекта до Android O

buildToolsVersion "26.0.1"

Lint в Android Studio показывает устаревшее предупреждение для следующего метода построения уведомлений:

new NotificationCompat.Builder(context)

Проблема в том, что разработчики Android обновляют свою Документацию с описанием NotificationChannel для поддержки уведомлений в 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.Builder. Но это решение не является многоразовым.

new Notification.Builder(MainActivity.this, "channel_id")
GuilhermeFGL
источник
4
Но это решение не является многоразовым. как так?
Тим
5
NotificationCompat.Builder устарела, а не Notification.Builder. Обратите внимание, что часть Compat исчезла. Уведомление - это их новый класс, где они оптимизируют все
Kapil G
1
@kapsym это наоборот. Notification.Builder старше
Тим
Плюс я не вижу, что это устарело здесь developer.android.com/reference/android/support/v4/app/… . Может быть, ошибка в Lint
Kapil G
Идентификатор канала передается в конструкторе или может быть размещен с использованием notificationBuild.setChannelId("channel_id"). В моем случае это последнее решение более пригодно для повторного использования, так как my NotificationCompat.Builderиспользуется в нескольких методах, сохраняя параметры для значков, звуков и вибраций.
GuilhermeFGL

Ответы:

167

В документации упоминается, что метод NotificationCompat.Builder(Context context)построения устарел. И мы должны использовать конструктор, который имеет channelIdпараметр:

NotificationCompat.Builder(Context context, String channelId)

NotificationCompat.Builder Документация:

Этот конструктор устарел на уровне API 26.0.0-бета1. используйте взамен NotificationCompat.Builder (Context, String). Во всех опубликованных уведомлениях должен быть указан NotificationChannel Id.

Notification.Builder Документация:

Этот конструктор устарел на уровне API 26. Вместо этого используйте Notification.Builder (Context, String). Во всех опубликованных уведомлениях должен быть указан NotificationChannel Id.

Если вы хотите повторно использовать установщики компоновщика, вы можете создать компоновщик с помощью channelIdи передать его компоновщику вспомогательному методу и установить в нем предпочтительные параметры.

боб
источник
3
Кажется, они противоречат сами себе при публикации Notification.Builder(context)решения в сеансе NotificationChannel. Но, по крайней мере, вы нашли сообщение, уведомляющее об этом как об устаревшем =)
GuilhermeFGL
23
Какой канал? Не могли бы вы объяснить?
Сантану-сюр-
15
что такое channelId?
RoundTwo
3
Вы также можете по-прежнему использовать NotificationCompat.Builder(Context context), а затем назначить канал следующим образом:builder.setChannelId(String channelId)
deyanm
36
Идентификатор канала может быть любой строкой, он слишком велик для обсуждения в комментариях, но он используется для разделения ваших уведомлений по категориям, чтобы пользователь мог отключить то, что он считает для него не важным, вместо того, чтобы блокировать все уведомления из вашего приложения.
Yehyatt
110

введите описание изображения здесь

Вот рабочий код для всех версий Android от API LEVEL 26+ с обратной совместимостью.

 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());
Aks4125
источник
Как сделать так, чтобы уведомление отображалось на экране в приложении или в другом приложении?
BlueBoy
@BlueBoy Я не получаю ваш вопрос. не могли бы вы объяснить, что именно вам нужно?
Aks4125
@ Aks4125 Уведомление не скользит вниз и отображается в верхней части экрана. Вы слышите тональный сигнал, и в строке состояния появляется крошечный значок уведомления, но ничего не скользит и не показывает, как будто вы получили текстовое сообщение.
BlueBoy
@BlueBoy вам нужно установить приоритет HIGH для этого поведения. дайте мне знать, если вам нужно, чтобы я обновил этот код. если вы подойдете к уведомлению с высоким приоритетом, вы получите ответ.
Aks4125
2
@BlueBoy проверить обновленный ответ. если вы не нацеливаетесь на API 26, просто используйте тот же код, а в .setPriority(Notification.PRIORITY_MAX)противном случае используйте обновленный код для API 26. `
Aks4125
31

Вызов конструктора с двумя аргументами. Для совместимости с Android O вызовите support-v4 NotificationCompat.Builder(Context context, String channelId). При работе на Android N или более ранних channelIdверсиях будет игнорироваться. При запуске на Android O, также создайте NotificationChannelс тем же channelId.

Пример кода с устаревшей версией : Пример кода на нескольких страницах JavaDoc, например, вызов Notification.Buildernew Notification.Builder(mContext) , устарел.

Устаревшие конструкторы: Notification.Builder(Context context) и v4 NotificationCompat.Builder(Context context) устарели в пользу Notification[Compat].Builder(Context context, String channelId). (См. Notification.Builder (android.content.Context) и v4 NotificationCompat.Builder (Контекстный контекст) .)

Устаревший класс: весь класс v7 NotificationCompat.Builder устарел. (См. V7 NotificationCompat.Builder .) Ранее NotificationCompat.Builderдля поддержки требовался v7 NotificationCompat.MediaStyle. В Android O, есть v4 NotificationCompat.MediaStyleв медиа-библиотеке Compat «s android.support.v4.mediaпакет. Используйте это, если вам нужно MediaStyle.

API 14+: в библиотеке поддержки от 26.0.0 и выше пакеты support-v4 и support-v7 поддерживают минимальный уровень API 14. Имена v # являются историческими.

Смотрите последние версии библиотеки поддержки .

Jerry101
источник
22

Вместо того, чтобы проверять Build.VERSION.SDK_INT >= Build.VERSION_CODES.Oтак много ответов, есть несколько более простой способ -

Добавьте следующую строку в applicationраздел файла AndroidManifest.xml, как описано в разделе « Настройка клиентского приложения Firebase Cloud Messaging для Android» :

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

Затем добавьте строку с именем канала в файл values ​​/ strings.xml :

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

После этого вы сможете использовать новую версию конструктора NotificationCompat.Builder с 2 параметрами (поскольку старый конструктор с 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());
}
Александр Фарбер
источник
1
как это проще? : S
Nactus
17

Вот пример кода, который работает в Android Oreo и меньше, чем 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());
Arpit
источник
8

Простой образец

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

    }
Mehul
источник
4
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 of = вы будете использовать какой-либо метод, то тот же метод будет использоваться в правой части = для выделения с новым.

Попробуйте этот код ... Он обязательно будет работать

Прадип Шеоран
источник
1

Этот конструктор устарел на уровне API 26.1.0. используйте взамен NotificationCompat.Builder (Context, String). Во всех опубликованных уведомлениях должен быть указан NotificationChannel Id.

Сандип Сингх
источник
Может быть, лучше добавить комментарий со ссылкой на документацию, а не копировать кошку и размещать в качестве ответа.
JacksOnF1re
0
  1. Необходимо объявить канал уведомлений с Notification_Channel_ID
  2. Создайте уведомление с этим идентификатором канала. Например,

...
 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());
...
Заман
источник