В Android O застаріле повідомлення NotificationCompat.Builder


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

4
Але це рішення точно не можна використовувати повторно. як так?
Тім

5
NotificationCompat.Builder застаріло, не Notification.Builder. Зауважте, що частина Compat пішла. Повідомлення - це їх новий клас, де вони упорядковують все
Kapil G

1
@kapsym насправді навпаки. Повідомлення.
Тім

Крім того, я не бачу цього застарілого тут developer.android.com/reference/android/support/v4/app/… . Можливо помилка в Лінт
Капіль G

Ідентифікатор каналу передається у конструкторі або може бути розміщений за допомогою notificationBuild.setChannelId("channel_id"). У моєму випадку це останнє рішення є більш повторним використання, оскільки моє NotificationCompat.Builderповторне використання у двох методах, зберігаючи параметри для піктограм, звуків та вібрувань.
GuilhermeFGL

Відповіді:


167

У документації зазначається, що метод забудовника NotificationCompat.Builder(Context context)був застарілим. І ми повинні використовувати конструктор, у якого є channelIdпараметр:

NotificationCompat.Builder(Context context, String channelId)

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

Цей конструктор був застарілий на рівні API 26.0.0-beta1. використовуйте замість NotificationCompat.Builder (контекст, рядок). Усі опубліковані сповіщення повинні вказувати ідентифікатор NotificationChannel.

Документація сповіщення.

Цей конструктор був застарілий на рівні 26 API, замість цього використовуйте Notification.Builder (контекст, рядок). Усі опубліковані сповіщення повинні вказувати ідентифікатор NotificationChannel.

Якщо ви хочете повторно використати налаштування для будівельників, ви можете створити конструктора за допомогою channelIdі передати його в допоміжний метод і встановити бажані налаштування в цьому методі.


3
Здається, вони суперечать собі, коли розміщують Notification.Builder(context)рішення в сесії NotificationChannel. Але добре, принаймні, ви знайшли публікацію, в якій сповіщали про це зневажливо =)
GuilhermeFGL

23
Що таке каналId, ви можете пояснити, будь ласка?
Сантану Сур

15
що таке каналId?
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());

Як ви можете зробити сповіщення фактично відображатися на екрані в додатку чи в іншому додатку?
BlueBoy

@BlueBoy Я не отримую вашого питання. Ви можете, будь ласка, пояснити, що саме вам потрібно?
Aks4125

@ Aks4125 Повідомлення не ковзає вниз і не відображається вгорі екрана. Ви чуєте тон, і на панелі стану з’являється крихітний значок сповіщення, але нічого не сповзає вниз і не показує, якби у вас було повідомлення з txt.
BlueBoy

@BlueBoy для цієї поведінки потрібно встановити пріоритет HIGH. дайте мені знати, якщо вам потрібно мені оновити цей код. якщо ви підкрадаєтесь до сповіщення про високий пріоритет, ви отримаєте свою відповідь.
Aks4125

2
@BlueBoy перевірити оновлену відповідь. якщо ви не орієнтуєтесь на 26 API, тоді просто використовуйте той самий код з .setPriority(Notification.PRIORITY_MAX)іншим оновленим кодом для 26 API. `
Aks4125

31

Викличте конструктор 2-arg: Для сумісності з Android O зателефонуйте support-v4 NotificationCompat.Builder(Context context, String channelId). Під час роботи на Android N або новішої версії, channelIdігнорування буде ігноровано. Під час роботи на Android O також створюйте NotificationChannelте ж самеchannelId .

Застарілий зразок коду: зразок коду на декількох сторінках JavaDoc, таких як Notification.Builder, виклик new 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 .) Раніше v7 NotificationCompat.Builderбула потрібна для підтримки 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 # є історичними.

Див. Останні редакції бібліотеки підтримки .


22

Замість того, щоб перевірити, Build.VERSION.SDK_INT >= Build.VERSION_CODES.Oнаскільки пропонують відповіді, існує трохи простіший спосіб -

Додайте наступний рядок до applicationрозділу файлу AndroidManifest.xml, як пояснено у програмі Налаштування клієнтського додатка Firebase Cloud Messaging для Android doc:

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

Потім додайте рядок з назвою каналу до файлу значень / strings.xml :

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

Після цього ви зможете використовувати нову версію конструктора 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());
}

1
як це простіше? : S
Нактус

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

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

    }

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

Спробуйте цей код ... Він обов'язково спрацює


1

Цей конструктор був застарілий на рівні API 26.1.0. використовуйте замість NotificationCompat.Builder (контекст, рядок). Усі опубліковані сповіщення повинні вказувати ідентифікатор NotificationChannel.


Можливо, скоріше додайте коментар із посиланням на документацію замість копіювання кота та публікації як відповідь.
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());
...
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.