“Mã yêu cầu” được sử dụng để làm gì trên PendingIntent?


110

Lý lịch:

Tôi đang sử dụng PendingIntent để báo thức qua AlarmManager.

Vấn đề:

Lúc đầu, tôi nghĩ rằng để hủy những cái trước đó, tôi phải cung cấp mã yêu cầu chính xác mà tôi đã sử dụng trước đó để bắt đầu báo thức.

Nhưng sau đó tôi phát hiện ra mình đã sai, như API hủy cho biết:

Loại bỏ mọi báo thức có Mục đích phù hợp. Mọi báo thức, thuộc bất kỳ loại nào, có Ý định khớp với báo thức này (như được định nghĩa bởi filterEquals (Ý định)), sẽ bị hủy.

nhìn vào " filterEquals ", tài liệu cho biết:

Xác định xem hai ý định có giống nhau cho mục đích phân giải ý định (lọc) hay không. Nghĩa là, nếu hành động, dữ liệu, kiểu, lớp và danh mục của chúng giống nhau. Điều này không so sánh bất kỳ dữ liệu bổ sung nào có trong ý định.

vì vậy tôi không hiểu "Mã yêu cầu" dùng cho ...

Câu hỏi:

"Mã yêu cầu" được sử dụng để làm gì?

Điều gì sẽ xảy ra nếu tôi tạo nhiều báo thức với cùng một "Mã yêu cầu"? họ có đè lên nhau không?


nếu bạn sử dụng cùng một Mã yêu cầu, bạn sẽ nhận được cùng một PendingIntent
pskink

3
Đối với PendingIntent.getBroadcast (), Mã yêu cầu dường như bị Android bỏ qua. Kể từ API 22, nó sẽ không làm cho Ý định đang chờ xử lý của bạn là duy nhất. Có cho getActivity () (và có lẽ getService () nhưng tôi chưa thử nghiệm). stackoverflow.com/a/33203752/2301224
Baker

@Baker Đây không phải là một lỗi? Nếu đó là một lỗi, bạn nên viết về nó tại đây: code.google.com/p/android/issues/list
nhà phát triển android

1
Thực ra, tài liệu chỉ định usaga của Mã yêu cầu: If you truly need multiple distinct PendingIntent objects active at the same time (such as to use as two notifications that are both shown at the same time), then you will need to ensure there is something that is different about them to associate them with different PendingIntents. This may be any of the Intent attributes considered by Intent#filterEquals(Intent), or different request code integers supplied.
Eir

@Eir Right, vậy mục đích sử dụng Mã yêu cầu là gì? nó có thể được sử dụng ở đâu?
nhà phát triển android

Câu trả lời:


77
  1. requestCode được sử dụng để truy xuất cùng một phiên bản ý định đang chờ xử lý sau này (để hủy, v.v.).
  2. Có, tôi đoán là các báo thức sẽ ghi đè lên nhau. Tôi sẽ giữ các mã yêu cầu duy nhất.

5
có đặt Mã yêu cầu là duy nhất cần thiết ngay cả trong trường hợp ý định của cảnh báo rất khác nhau (ví dụ: một cho dịch vụ A và một cho dịch vụ B) không? Ngoài ra, tại sao tài liệu không nói bất cứ điều gì về nó? Có thể xóa tất cả các cảnh báo thuộc một loại nhất định, bất kể Mã yêu cầu là gì không?
nhà phát triển android

1
Không, nó không cần thiết cho các ý định khác nhau. Và tôi không biết tại sao tài liệu không nói gì về nó, nhưng tôi đã học được điều này khi đặt báo thức lặp lại và cả khi sử dụng cùng mục đích.
Minhaj Arfin

2
Tôi đã nói về PendingIntent. startActivityForResult sử dụng một ý định bình thường.
nhà phát triển android

2
mục đích của "startActivityForResult với PendingIntent sử dụng hoạt động proxy" là gì? bạn có thể đưa ra một ví dụ không?
nhà phát triển android

3
Tôi đồng ý; tài liệu cho PendingIntent và AlarmManager là hoàn toàn không có - tệ hơn là không thể liệt kê các cảnh báo theo chương trình.
Ai đó ở đâu đó

33

Tôi chỉ muốn thêm vào câu trả lời của @Minhaj Arfin

1- Mã yêu cầu được sử dụng để có được cùng một mục đích đang chờ xử lý sau này (để hủy, v.v.)

2- Có, chúng sẽ được ghi đè miễn là bạn chỉ định cùng Người nhận cho Ý định của bạn mà bạn chỉ định trên PendingIntent của mình

thí dụ:

Intent startIntent1 = new Intent(context, AlarmReceiverFirst.class);
PendingIntent pendingIntent1 = PendingIntent.getBroadcast(context, 0, startIntent1, 0);

Intent startIntent2 = new Intent(context, AlarmReceiverSecond.class);
PendingIntent pendingIntent2 = PendingIntent.getBroadcast(context, 0, startIntent2, 0);

Từ ví dụ trên, chúng sẽ không ghi đè lẫn nhau vì bộ thu khác nhau (AlarmReceiverFirst và AlarmReceiverSecond)

Intent startIntent2 = new Intent(context, AlarmReceiverSecond.class);
PendingIntent pendingIntent2 = PendingIntent.getBroadcast(context, 0, startIntent2, 0);

Intent startIntent3 = new Intent(context, AlarmReceiverSecond.class);
PendingIntent pendingIntent3 = PendingIntent.getBroadcast(context, 0, startIntent3, 0);

Từ ví dụ trên, họ sẽ ghi đè lẫn nhau, vì bộ thu giống nhau (AlarmReceiverSecond)


Intent startIntent4 = new Intent (context, AlarmReceiverSecond.class); PendingIntent pendingIntent4 = PendingIntent.getService (context, 0, startIntent4, 0); sau đó sẽ ổn chứ? Ý tôi là, điều này sẽ không ghi đè vì nó đang gọi getService () thay vì getBroadcast ()?
Jenix

Rất tiếc khi đặt câu hỏi khác nhưng vì stackoverflow không cho phép tôi viết câu hỏi mà không có một dòng mã nào .. Đối số cuối cùng của các phương thức của PendingIntent như getBroadcast () có liên quan gì đến ghi đè không? Tôi sử dụng để đặt 0 có giống như mã ví dụ của bạn ở trên nhưng tôi cũng thấy nhiều người đã đặt một số giá trị tùy chọn cụ thể thay vì 0.
Jenix

1
@Jenix bạn sử dụng AlarmReceiverSecond.classtheo ý định và sau đó sử dụng PendingIntent.getService(). Nó sẽ không làm việc, kể từ khi AlarmReceiverSecond.classlà một BroadcastReceiver, không phải là mộtService
HendraWD

1
Về các cờ, đó là các thuộc tính mà bạn có thể đặt, sẽ thực hiện hành vi của PendingIntent theo các cờ bạn đã cung cấp. 0 có nghĩa là tất cả các lá cờ tắt
HendraWD

Ah Tôi thật ngu ngốc haha ​​Tôi đang nghĩ cái quái gì vậy .. Tôi hơi bối rối về PendingIntent và câu trả lời của bạn thực sự hữu ích. Và tôi chỉ muốn làm cho nó rõ ràng hơn nhưng bây giờ nhận ra câu hỏi của tôi không có ý nghĩa gì ban đầu. Cảm ơn!
Jenix

2

trong trường hợp của tôi, tôi muốn mở cùng một hoạt động với hai ý định khác nhau, vì vậy nếu có hai hoặc nhiều FCMS trong khay, bất kỳ FCMS nào trong số đó sẽ chỉ mở còn lại thì không, vì vậy tôi đã thay đổi mã yêu cầu của ý định đang chờ xử lý thì nó hoạt động.

 PendingIntent pendingIntent =
                            PendingIntent.getActivity(this, **Some unique id for all GCMS** /* Request code */, intent,
                                    PendingIntent.FLAG_ONE_SHOT);

không cần phải kiểm tra mã thêm cho trường hợp của tôi, bạn có thể cho biết trường hợp nào trường hợp ý định đang chờ xử lý sẽ được yêu cầu không. Đối với câu hỏi thay đổi mã theo yêu cầu với giúp tôi goto màn hình chính xác, tôi không biết liệu đây là cách chính xác và cho tôi lỗi chỉ xảy ra khi nhiều FCMs có trong khay
JSONParser

Vậy tại sao phải đặt một mã yêu cầu khác, nếu bạn không cần?
nhà phát triển Android

được rồi tôi sẽ giải thích chi tiết, tôi đã có một số KÍCH HOẠT A, nó có nghĩa là để hiển thị các câu hỏi, tôi sẽ chuyển id từ các thông báo thông qua ý định và sau đó thực hiện một yêu cầu mạng cho id đó và tìm nạp câu hỏi cụ thể, vậy điều gì đã xảy ra khi ở đó có nhiều hơn 1 thông báo trong khay thông báo và sau đó tôi nhấp vào bất kỳ thông báo nào trong số đó mà tôi nhận được id câu hỏi trong GCM đầu tiên, sau khi thay đổi mã yêu cầu ý định đang chờ xử lý thành một số giá trị duy nhất mà nó hoạt động. Tôi hy vọng tôi đã làm cho nó rõ ràng bây giờ, nếu bất kỳ cuộc thảo luận hơn là yêu cầu tôi ở đó, tôi cũng muốn tìm hiểu thêm, cảm ơn bạn
JSONParser

Ồ, ý bạn là nếu không thì nó sẽ không hoạt động chút nào, phải không? Xin lỗi về sự nhầm lẫn. Câu hỏi này đã được hỏi một thời gian dài trước đây và tôi không nhớ nó tốt ở tất cả các ...
android phát triển

1

một điều quan trọng về điều requestCodeđó sẽ gây rắc rối nghiêm trọng cho ứng dụng của bạn là khi sử dụng các widget. widget sẽ không hoạt động sau khi điện thoại khởi động lại nếu chúng requestCodegiống nhau. điều đó có nghĩa là pendingIndentbạn đặt trên remoteViewswidget của mình phải được đặt Mã yêu cầu duy nhất, thường là widgetId kèm theo một số.


0

Trên thực tế, tài liệu nêu rõ mã yêu cầu được sử dụng để làm gì:

Nếu bạn thực sự cần nhiều đối tượng PendingIntent khác biệt hoạt động cùng một lúc (chẳng hạn như để sử dụng làm hai thông báo được hiển thị cùng một lúc), thì bạn sẽ cần đảm bảo có điều gì đó khác biệt về chúng để liên kết chúng với các Đang chờ xử lý. Đây có thể là bất kỳ thuộc tính Intent nào được Intent # filterEquals (Ý định) xem xét hoặc các số nguyên mã yêu cầu khác được cung cấp cho getActivity (Context, int, Intent, int), getActictivity (Context, int, Intent [], int), getBroadcast ( Context, int, Intent, int) hoặc getService (Context, int, Intent, int).

Vì có vẻ như nó vẫn chưa rõ ràng, hãy để tôi cố gắng giải thích:

Khi bạn muốn sử dụng một PendingIntentđối tượng, bạn không chỉ khởi tạo một đối tượng. Thay vào đó, bạn có được một từ hệ thống bằng cách sử dụng PendingIntentphương pháp tĩnh ( getActivity, getBroadcast, getServicevv). Hệ thống giữ một loạt các phiên bản PendingIntent và cung cấp cho bạn một phiên bản. Nó cung cấp cho bạn cái nào, nó phụ thuộc vào các tham số đầu vào mà bạn chuyển cho các phương thức getter này. Các tham số đầu vào đó Contextlà:, tức là người nhận mục tiêu của ý định, mục đích Intentsử dụng requestCodeflags. Khi bạn vượt qua cùng Context, giống nhau requestCodevà giống nhau Ý định (có nghĩa là một ý định đó filterEqualsvới mục đích khác), bạn nhận được cùng một PendingIntentđối tượng. Vấn đề là hệ thống muốn có càng ít PendingIntentđối tượng càng tốt, vì vậy nó có xu hướng sử dụng lại những đối tượng hiện có, càng nhiều càng tốt.

Ví dụ: bạn có hai thông báo lịch, cho hai ngày khác nhau. Khi bạn nhấp vào một trong số chúng, bạn muốn ứng dụng của mình mở đến ngày tương ứng của thông báo đó. Trong trường hợp đó, bạn có cùng một Contextmục tiêu và Intentđối tượng bạn đang chuyển chỉ khác nhau trong EXTRA_DATA (chỉ định ngày sẽ mở). Nếu bạn cung cấp giống nhau requestCodekhi lấy được PendingIntentđối tượng, thì bạn sẽ kết thúc với cùng một PendingIntentđối tượng. Vì vậy, khi tạo thông báo thứ hai, bạn sẽ thay thế Intentđối tượng cũ bằng EXTRA_DATA mới và kết thúc bằng hai thông báo trỏ đến cùng một ngày.

Nếu bạn muốn có hai PendingIntentđối tượng khác nhau , như trong trường hợp này, bạn nên chỉ định một đối tượng khác requestCodekhi lấy PendingIntentđối tượng.


Nhưng như tôi đã đề cập, để hủy báo thức, bạn không thể chỉ sử dụng Mã yêu cầu. Nó không có ý nghĩa gì đối với nó. Bạn sẽ phải đặt thêm dữ liệu để phân biệt giữa chúng. Tôi không nhớ nhưng tôi nghĩ bạn thậm chí có thể sử dụng cùng một Mã yêu cầu cho nhiều cảnh báo.
nhà phát triển android

@androiddeveloper những gì bạn vừa nói không chính xác. Thử nó.
Eir
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.