Thông báo vượt qua Intras Extras cũ


134

tôi đang tạo một thông báo bên trong BroadcastReceiver thông qua mã này:

String ns = Context.NOTIFICATION_SERVICE;
        NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(ns);
        int icon = R.drawable.ic_stat_notification;
        CharSequence tickerText = "New Notification";
        long when = System.currentTimeMillis();

        Notification notification = new Notification(icon, tickerText, when);
        notification.defaults |= Notification.DEFAULT_VIBRATE;
        long[] vibrate = {0,100,200,200,200,200};
        notification.vibrate = vibrate;
        notification.flags |= Notification.FLAG_AUTO_CANCEL;

        CharSequence contentTitle = "Title";
        CharSequence contentText = "Text";
        Intent notificationIntent = new Intent(context, NotificationActivity.class);
        notificationIntent.putExtra(Global.INTENT_EXTRA_FOO_ID, foo_id);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);

        notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);

        int mynotification_id = 1;

        mNotificationManager.notify(mynotification_id, notification);

Khi tôi nhấp vào thông báo, nó sẽ mở Thông báo và bên trong Hoạt động tôi có thể truy xuất foo_id từ Gói ý định (ví dụ 1)

Tuy nhiên, nếu một thông báo khác được kích hoạt và tôi nhấp vào nó một lần nữa, hoạt động vẫn nhận được giá trị "cũ" (1) từ Gói ý định. Tôi đã cố gắng xóa gói với Clear (), nhưng đang nhận được hiệu quả tương tự. Tôi nghĩ rằng sth là sai với mã của tôi ..


xin vui lòng cho tôi biết làm thế nào để bạn có được dữ liệu từ ý định đang chờ xử lý
user49557

để nhận ra rằng nó đã gửi các tính năng bổ sung cũ, giúp việc xử lý của tôi dễ dàng hơn.
Utsav Gupta

Câu trả lời:


267

Bạn đang gửi cùng một mã yêu cầu cho cường độ chờ xử lý của bạn. Thay đổi điều này:

PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);

Đến:

PendingIntent contentIntent = PendingIntent.getActivity(context, UNIQUE_INT_PER_CALL, notificationIntent, 0);

ý định không được tạo nếu bạn gửi cùng một thông số. Chúng được tái sử dụng.


1
vậy UNIQUE_INT_PER_CALL là một số nguyên tôi phải cung cấp? hoặc đây là một biến tĩnh được khai báo ở đâu đó?
BrianM

23
android Gotcha # 147 - vì vậy một Intentkhác nhau extras (thông qua putExtra) được coi là giống nhau và tái sử dụng, vì tôi đã không cung cấp một id duy nhất để một số người gọi ý định cấp phát - khủng khiếp api
wal

bạn biết không, tôi đã rất bất cẩn. Chỉ cần suy nghĩ làm thế nào nó có thể vẫn là 0 trong một khối (trong trường hợp của tôi) :(
Exigente05

3
Điều này cực kỳ hữu ích đối với tôi, chỉ là một mẹo cho người khác, có khả năng là bạn đang xây dựng thông báo của mình theo cùng một phương thức và vì vậy bạn chỉ có thể đặt id cho mục đích chờ xử lý mới giống như ý định của bạn sử dụng cho id thông báo duy nhất!
James McNee

1
@IncrediApp, giống với PendingIntent.getBroadcast (); ?
Shruti

138

Ngoài ra, bạn có thể sử dụng mã sau đây để tạo PendingIntent của mình:

PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

Từ tài liệu cho PendingIntent.FLAG_UPDATE_CURRENT:

Nếu PendingIntent được mô tả đã tồn tại, thì hãy giữ nó nhưng thay thế dữ liệu bổ sung của nó bằng những gì có trong Ý định mới này. Điều này có thể được sử dụng nếu bạn đang tạo ý định trong đó chỉ có các tính năng bổ sung thay đổi và không quan tâm rằng bất kỳ thực thể nào nhận được PendingIntent trước đó của bạn sẽ có thể khởi chạy nó với các tính năng bổ sung mới của bạn ngay cả khi chúng không được cung cấp rõ ràng cho nó.


Cảm ơn ... hoạt động hoàn hảo cho lá cờ này có thêm "PendingIntent.FLAG_UPDATE_CURRENT" :)
Najib Ahmed Puthawala

1
Làm việc cho tôi, sử dụng ý định đang chờ xử lý để chuyển trạng thái từ đặt báo thức sang máy thu phát.
William T. Mallard

Tôi chỉ ước tôi biết về những lá cờ này thực sự đã làm gì trước khi tôi gửi thông báo cho người dùng của mình (!) Vui mừng vì điều này giải quyết được tai ương của tôi ...
James Andrew

42

Bạn đang vượt qua cùng một ID. Trong loại tình huống này, tạo một id duy nhất theo thời gian như thế này:

int iUniqueId = (int) (System.currentTimeMillis() & 0xfffffff);

Và đặt nó như thế này:

PendingIntent contentIntent = PendingIntent.getActivity(getApplicationContext(),iUniqueId, intentForNotification, 0);

3
tại sao không sử dụng Random (). nextInt ()
exloong

@hderanga thêm "& 0xfffffff" vào int ở trên là gì?
AJW

3
@AJW System.currentTimeMillis()trả về một khoảng thời gian dài, trong khi requestIdtham số PendingIntent.getActivity()mất một int. 0xfffffffflà một bitmask. Mặc dù có nhiều hơn một chút, nhưng lời giải thích đơn giản là việc thực hiện 'long & 0xffffffff' mang lại 32 bit thấp nhất từ ​​dài và loại bỏ 32 bit cao nhất, về cơ bản là bạn có int 32 bit. Điều này tốt hơn là chỉ đơn giản là truyền tới một int vì nó sẽ không làm hỏng bit dấu (nếu bạn tạo một khoảng dài lớn hơn int cho một int thì bit dấu sẽ tràn ra và bạn có khả năng sẽ có giá trị âm )
Jordan Bondo

8

Đối với bất kỳ ai đang tìm kiếm cách tiếp cận tốt nhất sau một thời gian dài, bạn cần phải vượt qua PendingIntent.FLAG_UPDATE_CURRENT làm đối số cuối cùng như được hiển thị bên dưới

PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);

bạn thậm chí không cần cung cấp một id duy nhất mới.

Bạn cần làm điều này cho lần sau trở đi không phải lần đầu tiên


1
Điều đó không hiệu quả, tôi đã đến đây vì đó là những gì tôi đang làm.
Brill Pappin

Bạn cần phải làm điều này cho lần tiếp theo không phải lần đầu tiên, nó sẽ hoạt động.
Nhẹ nhàng

0

Mã yêu cầu của bạn là 0 cho tất cả các thông báo. Thay đổi dòng sau:

PendingIntent contentIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);

Với:

PendingIntent contentIntent = PendingIntent.getActivity(context, new Random().nextInt(), notificationIntent, 0);

1
Có bất kỳ lợi ích nào khi sử dụng "new Random (). NextInt ()" thay vì "System.cienTimeMillis ()" không?
AJW

sử dụng ngẫu nhiên có thể dễ dàng tạo lại cùng một giá trị số nguyên một cách tình cờ, do đó gây ra một lỗi rất khó tìm thấy các ý định cũ được thông qua.
Sam

@AJW đã có trong trường hợp của tôi. Tôi đã tạo 2 thông báo khác nhau trong cùng một phần nghìn giây, vì vậy một trong số chúng có các phần bổ sung sai.
nghệ nhân

0

Chỉ muốn thêm tùy chọn khác

 PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_ONE_SHOT | PendingIntent.FLAG_IMMUTABLE);
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.