NotificationCompat.Builder descontinuado no Android O

161

Depois de atualizar meu projeto para o Android O

buildToolsVersion "26.0.1"

O Lint no Android Studio está mostrando um aviso preterido para o método do construtor de notificações a seguir:

new NotificationCompat.Builder(context)

O problema é: os desenvolvedores do Android atualizam sua documentação descrevendo o NotificationChannel para oferecer suporte a notificações no Android O e nos fornecem um snippet, mas com o mesmo aviso preterido:

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

Visão geral das notificações

Minha pergunta: Existe outra solução para criar notificações e ainda suporta o Android O?

Uma solução que encontrei é passar o ID do canal como parâmetro no construtor Notification.Builder. Mas essa solução não é exatamente reutilizável.

new Notification.Builder(MainActivity.this, "channel_id")
GuilhermeFGL
fonte
4
Mas esta solução não é exatamente reutilizável. como assim?
Tim
5
NotificationCompat.Builder está obsoleto, não Notification.Builder. Observe que a parte Compat foi removida. Notificação é a sua nova classe onde eles estão racionalizando tudo
Kapil G
1
@kapsym é realmente o contrário. O Notification.Builder é mais antigo
Tim
Além disso, eu não o vejo obsoleto aqui developer.android.com/reference/android/support/v4/app/… . Talvez um bug no Lint
Kapil G
O ID do canal é passado no construtor ou pode ser colocado usando notificationBuild.setChannelId("channel_id"). No meu caso, essa última solução é mais reutilizada, pois NotificationCompat.Builderé reutilizada em alguns métodos, economizando parâmetros para ícones, sons e vibrações.
GuilhermeFGL

Respostas:

167

É mencionado na documentação que o método do construtor NotificationCompat.Builder(Context context)foi descontinuado. E nós temos que usar o construtor que tem o channelIdparâmetro:

NotificationCompat.Builder(Context context, String channelId)

Documentação de NotificationCompat.Builder:

Este construtor foi descontinuado no nível da API 26.0.0-beta1. use NotificationCompat.Builder (Context, String). Todas as notificações publicadas devem especificar um ID NotificationChannel.

Documentação do Notification.Builder:

Este construtor foi descontinuado no nível da API 26. use Notification.Builder (Context, String). Todas as notificações publicadas devem especificar um ID NotificationChannel.

Se desejar reutilizar os setters do construtor, você pode criar o construtor com o channelId, e passar esse construtor para um método auxiliar e definir suas configurações preferidas nesse método.

Prumo
fonte
3
Parece que eles estão se contradizendo ao postar a Notification.Builder(context)solução na sessão NotificationChannel. Mas bom, pelo menos você encontrou um post notificando isso = =)
GuilhermeFGL
23
Qual é o channelId, você pode explicar?
Santanu Sur 26/01
15
o que é channelId?
precisa saber é o seguinte
3
Você também pode ainda usar NotificationCompat.Builder(Context context), e depois atribuir o canal assim:builder.setChannelId(String channelId)
deyanm
36
O ID do canal pode ser qualquer string, é muito grande para ser discutido nos comentários, mas é usado para separar suas notificações em categorias, para que o usuário possa desativar o que ele acha que não é importante para ele, em vez de bloquear todas as notificações do seu aplicativo.
22818 Yeyattatt
110

insira a descrição da imagem aqui

Aqui está o código de trabalho para todas as versões do Android a partir do API LEVEL 26+ com compatibilidade com versões anteriores.

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

UPDATE para API 26 para definir prioridade máxima

    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
fonte
Como você pode fazer a notificação realmente aparecer na tela do aplicativo ou se estiver em outro aplicativo?
blueboy
@BlueBoy eu não estou recebendo sua pergunta. você poderia explicar o que exatamente você precisa?
Aks4125
@ Aks4125 A notificação não desliza para baixo e é exibida na parte superior da tela. Você ouve um tom e um pequeno ícone de notificação aparece na barra de status - mas nada desliza para baixo e é exibido como se você recebesse uma mensagem txt.
blueboy
@BlueBoy, você precisa definir a prioridade como HIGH para esse comportamento. informe-me se você precisar atualizar meu código. se você procurar uma notificação de alta prioridade, receberá sua resposta.
Aks4125
2
@BlueBoy verificar resposta atualizada. se você não está segmentando a 26 API, basta usar o mesmo código, caso .setPriority(Notification.PRIORITY_MAX)contrário, use o código atualizado da 26 API. `
Aks4125
31

Ligue para o construtor 2-arg: Para compatibilidade com o Android O, ligue para support-v4 NotificationCompat.Builder(Context context, String channelId). Ao executar no Android N ou anterior, o channelIdserá ignorado. Ao executar no Android O, também crie um NotificationChannelcom o mesmo channelId.

Código de amostra desatualizado: o código de amostra em várias páginas JavaDoc, como a chamada Notification.Builder,new Notification.Builder(mContext) está desatualizado.

Construtores preteridos: Notification.Builder(Context context) e v4 NotificationCompat.Builder(Context context) foram preteridos em favor de Notification[Compat].Builder(Context context, String channelId). (Consulte Notification.Builder (android.content.Context) e v4 NotificationCompat.Builder (contexto de contexto) .)

Classe descontinuada: a classe inteira v7 NotificationCompat.Builder foi descontinuada. (Consulte v7 NotificationCompat.Builder .) Anteriormente, a v7 NotificationCompat.Builderera necessária para dar suporte NotificationCompat.MediaStyle. Em Android O, há um v4 NotificationCompat.MediaStylena biblioteca de mídia-compat 's android.support.v4.mediapacote. Use esse se você precisar MediaStyle.

API 14+: na Biblioteca de suporte da 26.0.0 e superior, os pacotes support-v4 e support-v7 suportam um nível mínimo de API de 14. Os nomes de v # são históricos.

Consulte Revisões recentes da biblioteca de suporte .

Jerry101
fonte
22

Em vez de procurar o Build.VERSION.SDK_INT >= Build.VERSION_CODES.Omáximo de respostas sugeridas, existe uma maneira um pouco mais simples:

Adicione a seguinte linha à applicationseção do arquivo AndroidManifest.xml, conforme explicado no documento Configurar um aplicativo cliente do Firebase Cloud Messaging no Android :

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

Em seguida, inclua uma linha com um nome de canal no arquivo values ​​/ strings.xml :

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

Depois disso, você poderá usar a nova versão do construtor NotificationCompat.Builder com 2 parâmetros (já que o construtor antigo com 1 parâmetro foi preterido no 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());
}
Alexander Farber
fonte
1
como isso é mais simples? : S
Nactus 20/01/19
17

Aqui está o código de exemplo, que está funcionando no Android Oreo e menos que o 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
fonte
8

Amostra Simples

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

O código correto será:

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

com dependência 26.0.1 e novas dependências atualizadas, como 28.0.0.

Alguns usuários usam esse código no formato a seguir:

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

Portanto, a lógica é o método que você declarará ou iniciará; o mesmo método no lado direito será usado para alocação. se em Leftside of = você usar algum método, o mesmo método será usado no lado direito de = for Allocation with new.

Experimente este código ... Certamente funcionará

Pradeep Sheoran
fonte
1

Este construtor foi descontinuado no nível da API 26.1.0. use NotificationCompat.Builder (Context, String). Todas as notificações publicadas devem especificar um ID NotificationChannel.

Sandeep Singh
fonte
Talvez adicione um comentário com um link para a documentação em vez de copiar gato e postar como resposta.
precisa saber é o seguinte
0
  1. Precisa declarar um canal de notificação com Notification_Channel_ID
  2. Crie uma notificação com esse ID do canal. Por exemplo,

...
 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());
...
Zaman
fonte