Thông báoCompat.Builder không dùng nữa trong Android O


161

Sau khi nâng cấp dự án của tôi lên Android O

buildToolsVersion "26.0.1"

Lint trong Android Studio đang hiển thị cảnh báo không dùng cho phương thức xây dựng thông báo theo sau:

new NotificationCompat.Builder(context)

Vấn đề là: Các nhà phát triển Android cập nhật Tài liệu mô tả NotificationChannel để hỗ trợ các thông báo trong Android O và cung cấp cho chúng tôi một đoạn trích, nhưng với cùng một cảnh báo không dùng nữa:

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

Thông báo Tổng quan

Câu hỏi của tôi: Có giải pháp nào khác để xây dựng thông báo và vẫn hỗ trợ Android O không?

Một giải pháp tôi tìm thấy là truyền ID kênh dưới dạng tham số trong hàm tạo Thông báo. Nhưng giải pháp này không chính xác có thể tái sử dụng.

new Notification.Builder(MainActivity.this, "channel_id")

4
Nhưng giải pháp này không chính xác có thể tái sử dụng. làm sao vậy
Tim

5
Thông báoCompat.Builder bị phản đối không thông báo.Builder. Chú ý phần Compat đi. Thông báo là lớp mới của họ, nơi họ đang hợp lý hóa mọi thứ
Kapil G

1
@kapsym đó là cách khác xung quanh thực sự. Thông báo. Người lớn tuổi hơn
Tim

Thêm vào đó, tôi không thấy nó bị phản đối ở đây developer.android.com/reference/android/support/v4/app/ mẹo . Có thể một lỗi trong Lint
Kapil G

Id kênh được truyền tại hàm tạo hoặc có thể được đặt bằng cách sử dụng notificationBuild.setChannelId("channel_id"). Trong trường hợp của tôi, giải pháp cuối cùng này được sử dụng lại nhiều hơn vì tôi NotificationCompat.Builderđược sử dụng lại trong một vài phương thức, lưu lại các tham số cho các biểu tượng, âm thanh và rung.
GuilhermeFGL

Câu trả lời:


167

Nó được đề cập trong tài liệu rằng phương pháp xây dựng NotificationCompat.Builder(Context context)đã bị phản đối. Và chúng ta phải sử dụng hàm tạo có channelIdtham số:

NotificationCompat.Builder(Context context, String channelId)

Thông báoCompat.Builder Tài liệu:

Hàm tạo này không được dùng trong cấp API 26.0.0-beta1. thay vào đó, hãy sử dụng NotificationCompat.Builder (Ngữ cảnh, Chuỗi). Tất cả các Thông báo đã đăng phải chỉ định Id Thông báo.

Thông báo. Tài liệu hướng dẫn:

Hàm tạo này không được dùng trong API cấp 26. thay vào đó, hãy sử dụng Notification.Builder (Ngữ cảnh, Chuỗi). Tất cả các Thông báo đã đăng phải chỉ định Id Thông báo.

Nếu bạn muốn sử dụng lại setters của trình xây dựng, bạn có thể tạo trình tạo với channelId, và chuyển trình xây dựng đó sang một phương thức của trình trợ giúp và đặt các cài đặt ưa thích của bạn trong phương thức đó.


3
Có vẻ như họ đang mâu thuẫn với chính mình khi đăng Notification.Builder(context)giải pháp trong phiên Thông báo. Nhưng tốt, ít nhất bạn đã tìm thấy một bài đăng thông báo sự phản đối này =)
GuilhermeFGL

23
Bạn có thể giải thích về channelId là gì?
Santanu Sur

15
channelId là gì?
RoundTwo

3
Bạn cũng vẫn có thể sử dụng NotificationCompat.Builder(Context context)và sau đó chỉ định kênh như sau:builder.setChannelId(String channelId)
deyanm

36
Id kênh có thể là bất kỳ chuỗi nào, quá lớn để thảo luận trong các nhận xét, nhưng nó được sử dụng để phân tách thông báo của bạn thành các danh mục để người dùng có thể vô hiệu hóa những gì anh ta cho là không quan trọng đối với anh ta thay vì chặn tất cả thông báo khỏi ứng dụng của bạn.
yehyatt

110

nhập mô tả hình ảnh ở đây

Đây là mã làm việc cho tất cả các phiên bản Android kể từ API LEVEL 26+ với khả năng tương thích ngược.

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

CẬP NHẬT cho API 26 để đặt mức ưu tiên tối đa

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

Làm thế nào bạn có thể làm cho thông báo thực sự hiển thị trên màn hình trong ứng dụng hoặc nếu trong một ứng dụng khác?
BlueBoy

@BlueBoy tôi không nhận được câu hỏi của bạn. bạn có thể vui lòng giải thích chính xác những gì bạn cần?
Aks4125

@ Aks4125 Thông báo không trượt xuống và hiển thị ở trên cùng của màn hình. Bạn nghe thấy một âm báo và một biểu tượng thông báo nhỏ xuất hiện trên thanh trạng thái - nhưng không có gì trượt xuống và hiển thị như nếu bạn nhận được một tin nhắn txt.
BlueBoy

@BlueBoy bạn cần đặt mức độ ưu tiên thành CAO cho hành vi đó. cho tôi biết nếu bạn cần tôi cập nhật mã này. nếu bạn lén lút tìm kiếm thông báo ưu tiên cao, bạn sẽ nhận được câu trả lời.
Aks4125

2
@BlueBoy kiểm tra câu trả lời cập nhật. nếu bạn không nhắm mục tiêu 26 API thì chỉ cần sử dụng cùng một mã với .setPriority(Notification.PRIORITY_MAX)người khác sử dụng mã được cập nhật cho 26 API. `
Aks4125

31

Gọi hàm tạo 2-arg: Để tương thích với Android O, hãy gọi support-v4 NotificationCompat.Builder(Context context, String channelId). Khi chạy trên Android N hoặc sớm hơn, channelIdsẽ bị bỏ qua. Khi chạy trên Android O, cũng tạo một NotificationChannelcái tương tự channelId.

Mã mẫu đã hết hạn: Mã mẫu trên một số trang JavaDoc như Thông báo . Cuộc gọi new Notification.Builder(mContext)của người dùng đã hết hạn.

Các nhà xây dựng không dùng nữa :Notification.Builder(Context context)v4 NotificationCompat.Builder(Context context) không được ủng hộ Notification[Compat].Builder(Context context, String channelId). (Xem Thông báo.Builder (android.content.Context) và v4 NotificationCompat.Builder (Ngữ cảnh ngữ cảnh) .)

Lớp không dùng nữa: Toàn bộ lớp v7 NotificationCompat.Builder không được dùng nữa. (Xem v7 NotificationCompat.Builder .) Trước đây, v7 NotificationCompat.Builderlà cần thiết để hỗ trợ NotificationCompat.MediaStyle. Trong Android O, có một v4 NotificationCompat.MediaStyletrong phương tiện truyền thông-compat thư viện của android.support.v4.mediagói. Sử dụng cái đó nếu bạn cần MediaStyle.

API 14+: Trong Thư viện hỗ trợ từ 26.0.0 trở lên, các gói support-v4 và support-v7 đều hỗ trợ mức API tối thiểu là 14. Tên v # là lịch sử.

Xem các sửa đổi thư viện hỗ trợ gần đây .


22

Thay vì kiểm tra Build.VERSION.SDK_INT >= Build.VERSION_CODES.Onhư nhiều câu trả lời gợi ý, có một cách đơn giản hơn một chút -

Thêm dòng sau vào applicationphần của tệp AndroidManifest.xml như được giải thích trong Thiết lập ứng dụng khách nhắn tin trên đám mây Firebase trên tài liệu Android :

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

Sau đó, thêm một dòng có tên kênh vào tệp value / String.xml :

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

Sau đó, bạn sẽ có thể sử dụng phiên bản mới của hàm tạo NotificationCompat.Builder với 2 tham số (vì hàm tạo cũ với 1 tham số đã không được dùng trong 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
Làm thế nào đơn giản hơn? : S
Nactus

17

Đây là mã mẫu, đang hoạt động trong Android Oreo và ít hơn 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

Mẫu đơn giản

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

Mã bên phải sẽ là:

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

với phụ thuộc 26.0.1 và các phụ thuộc được cập nhật mới, chẳng hạn như 28.0.0.

Một số người dùng sử dụng mã này dưới dạng này:

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

Vì vậy, Logic là phương thức mà bạn sẽ khai báo hoặc khởi tạo thì cùng một phương thức ở bên phải sẽ được sử dụng cho Phân bổ. nếu trong Leftside of = bạn sẽ sử dụng một số phương thức thì phương thức tương tự sẽ được sử dụng ở bên phải của = cho Phân bổ với mới.

Hãy thử mã này ... Nó chắc chắn sẽ hoạt động


1

Hàm tạo này không được dùng trong API cấp 26.1.0. thay vào đó, hãy sử dụng NotificationCompat.Builder (Ngữ cảnh, Chuỗi). Tất cả các Thông báo đã đăng phải chỉ định Id Thông báo.


Có thể thay vì thêm một bình luận với liên kết đến tài liệu thay vì sao chép con mèo và đăng lên như một câu trả lời.
JacksOnF1re

0
  1. Cần khai báo kênh Thông báo bằng Thông báo_Channel_ID
  2. Xây dựng thông báo với ID kênh đó. Ví dụ,

...
 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());
...
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.