PendingIntent पहली सूचना के लिए सही ढंग से काम करता है लेकिन बाकी के लिए गलत है


87
  protected void displayNotification(String response) {
    Intent intent = new Intent(context, testActivity.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK);

    Notification notification = new Notification(R.drawable.icon, "Upload Started", System.currentTimeMillis());
    notification.setLatestEventInfo(context, "Upload", response, pendingIntent);

    nManager.notify((int)System.currentTimeMillis(), notification);
}

यह फ़ंक्शन कई बार कहा जाएगा। मैं प्रत्येक notificationके लिए गवाही देना चाहूंगा जब क्लिक किया जाए। दुर्भाग्य से, केवल पहली अधिसूचना में परीक्षणशीलता की शुरूआत हुई। बाकी पर क्लिक करने से अधिसूचना विंडो कम से कम हो जाती है।

अतिरिक्त जानकारी: फ़ंक्शन displayNotification()नामक एक वर्ग में है UploadManager। उस तात्कालिकता से Contextपारित किया UploadManagerगया activityहै। फ़ंक्शन displayNotification()को फ़ंक्शन से कई बार कहा जाता है, यह भी UploadManager में है, जो एक में चल रहा है AsyncTask

संपादन 1: मैं यह उल्लेख करना भूल गया कि मैं स्ट्रिंग प्रतिक्रिया Intent intentको एक के रूप में पारित कर रहा हूं extra

  protected void displayNotification(String response) {
    Intent intent = new Intent(context, testActivity.class);
    intent.putExtra("response", response);
    PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

इससे एक बड़ा अंतर पड़ता है क्योंकि मुझे स्ट्रिंग "प्रतिक्रिया" को प्रतिबिंबित करने के लिए अतिरिक्त "प्रतिक्रिया" की आवश्यकता है, जब अधिसूचना बनाई गई थी। इसके बजाय, उपयोग करते हुए PendingIntent.FLAG_UPDATE_CURRENT, अतिरिक्त "प्रतिक्रिया" दर्शाता है कि स्ट्रिंग कॉल अंतिम प्रतिक्रिया किस पर थी displayNotification()

मुझे पता है कि यह दस्तावेज़ीकरण को पढ़ने से क्यों है FLAG_UPDATE_CURRENT। हालांकि, मुझे यकीन नहीं है कि इस समय इसके आसपास कैसे काम किया जाए।

जवाबों:


125

Intent.FLAG_ACTIVITY_NEW_TASKPendingIntent.getActivity के लिए उपयोग न करें , इसके बजाय FLAG_ONE_SHOT का उपयोग करें


टिप्पणियों से कॉपी किया गया:

फिर इरादे पर कुछ डमी कार्रवाई निर्धारित करें, अन्यथा अतिरिक्त गिराए जाते हैं। उदाहरण के लिए

intent.setAction(Long.toString(System.currentTimeMillis()))

यह ध्वज वास्तव में एक ही कारण के लिए काम नहीं करता था, मुझे लगता है, कि मेरा अतिरिक्त सही ढंग से काम नहीं कर रहा है (मेरे संपादन 1 की जांच करें)।

32
फिर इरादे पर कुछ डमी कार्रवाई निर्धारित करें, अन्यथा अतिरिक्त गिराए जाते हैं। उदाहरण के लिए अभिप्रेरित करें। शुरुआत ("फू")
ognian

20
अति उत्कृष्ट। वह काम किया। मैंने mAauer द्वारा सुझाए गए FLAG_UPDATE_CURRENT का उपयोग करने के साथ संयोजन में setAction (Long.toString (System.currentTimeMillis ()))। FLAG_ONE_SHOT का उपयोग करने से मुझे केवल एक बार अधिसूचना पर क्लिक करने की अनुमति मिली (जो समझ में आता है)। बहुत बहुत धन्यवाद।

5
"फिर इंटेंट पर कुछ डमी कार्रवाई सेट करें, अन्यथा एक्स्ट्रा को गिरा दिया जाता है" - क्या यह कहीं दस्तावेज है?
Mr_and_Mrs_D

SetAction तंत्र ने मेरे लिए काम किया। जहाँ तक प्रलेखित है, निश्चित नहीं है, लेकिन Android के लिए स्रोत android.googlesource.com ;-) पर उपलब्ध है
नॉर्मन एच

62

विजेट पर प्रत्येक के लिए RemoteViewsऔर कई अलग अलग के साथ संघर्ष कर रहा था । इन्हें जोड़ने पर काम किया गया:IntentsButtonHomeScreen

1। intent.setAction(Long.toString(System.currentTimeMillis()));

2। PendingIntent.FLAG_UPDATE_CURRENT

        PackageManager pm = context.getPackageManager();

        Intent intent = new Intent(context, MyOwnActivity.class);
        intent.putExtra("foo_bar_extra_key", "foo_bar_extra_value");
        intent.setAction(Long.toString(System.currentTimeMillis()));
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
                intent, PendingIntent.FLAG_UPDATE_CURRENT);
        RemoteViews views = new RemoteViews(context.getPackageName(),
                R.layout.widget_layout);
        views.setOnClickPendingIntent(my_button_r_id_received_in_parameter, pendingIntent);

+1 कूल धन्यवाद। कोई भी विचार क्यों आशय जोड़ रहा है। शुरुआत () यह काम किया है?
AjOnFire

setAction काम करता है लेकिन क्या होगा अगर मुझे वास्तव में कुछ और करने के लिए मेरे इरादे एक्शन सेट करना है? चौखट इतनी छोटी क्यों है?
b.lit

2
मुझे सिर्फ इतना पसंद है कि एंड्रॉइड एसडीके डेवलपर्स के लिए कितना सहज है ... (: ♥ read BTW पढ़ें @ObjectiveTruth जवाब के कारण के बारे में स्पष्टीकरण के लिए नीचेsetAction
Aviel सकल

1
विचित्र व्यवहार हो रहा था, बिना सेटएक्शन पद्धति के कॉल आशय एक्स्ट्रा कलाकार डिबगिंग के दौरान काम करेंगे, लेकिन जब डिबगिंग नहीं होती है तो एक्सट्रा एक्स्ट्रा हमेशा वैसा ही होगा जैसा कि शुरुआती कॉल पहले कॉल में पास हुआ था। मैंने पाया कि डीबगिंग के दौरान, ऑनक्रिएट को हमेशा ऐप से बाहर नेविगेट करते समय कॉल किया जाता था, लेकिन डीबगिंग नहीं होने पर, ऑनक्रिएट को ऑनस्टार्ट नहीं कहा जाता था। कॉलिंग सेटेशन विधि ने इस मुद्दे को हल कर दिया है, मैं अनुमान लगा रहा हूं कि यह कुछ ऐसा है जिसमें इंटेंट्स को 'अलग' नहीं किया जा सकता है यदि केवल अतिरिक्त मूल्य बदल गए हैं।
मैक्सजे

@clu चूंकि मैं पहले से ही उपयोग कर रहा हूं setAction, आप क्या कर सकते हैं addCategory। क्रिया, डेटा, प्रकार, वर्ग और श्रेणियों की समानता के लिए जाँच करने के लिए PendingIntentउपयोग करता Intent.filterEqualsहै। डेवलपर
.android.com

43

सेट एक्शन ने मेरे लिए इसे हल किया। यहाँ स्थिति की मेरी समझ है:


मेरे पास कई विगेट्स हैं, जिनमें से प्रत्येक के लिए एक लंबित लंबित है। जब भी कोई अपडेट हुआ तो वे सभी अपडेट हो गए। Flags वर्णन करने के लिए हैं कि PendingIntents के साथ क्या होता है जो बिल्कुल समान हैं।

FLAG_UPDATE_CURRENT विवरण अब बहुत बेहतर है:

यदि वही PendingIntent जो आप पहले से बना रहे हैं, तो सभी पुराने को उस नए PendingIntent में अपडेट करें जिसे आप बना रहे हैं।

ठीक वैसी ही परिभाषा पूरे PendingIntent EXCEPT एक्स्ट्रा कलाकार पर दिखती है। इस प्रकार यहां तक ​​कि अगर आपके पास प्रत्येक इरादे पर अलग-अलग एक्स्ट्रा कलाकार हैं (मेरे लिए मैं appWidgetId जोड़ रहा था) तो Android के लिए, वे एक ही हैं।

कुछ डमी अद्वितीय स्ट्रिंग के साथ .setAction जोड़ना OS को बताता है। ये पूरी तरह से अलग हैं और कुछ भी अपडेट नहीं करते हैं। अंत में यहाँ मेरा कार्यान्वयन जो मैं चाहता था के रूप में काम करता है, जहाँ प्रत्येक विजेट का अपना कॉन्फ़िगरेशन होता है।

Intent configureIntent = new Intent(context, ActivityPreferences.class);

configureIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);

configureIntent.setAction("dummy_unique_action_identifyer" + appWidgetId);

PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, configureIntent,
    PendingIntent.FLAG_UPDATE_CURRENT);

अपडेट करें


प्रसारण के साथ काम करने के मामले में भी बेहतर समाधान। विशिष्ट अनुरोध कोड द्वारा अद्वितीय लंबित भी परिभाषित किए गए हैं। यहाँ मेरा समाधान है:

//Weee, magic number, just want it to be positive nextInt(int r) means between 0 and r
int dummyuniqueInt = new Random().nextInt(543254); 
PendingIntent pendingClearScreenIntent = PendingIntent.getBroadcast(context, 
    dummyuniqueInt, clearScreenIntent, PendingIntent.FLAG_UPDATE_CURRENT);

1
अच्छा स्वच्छ समाधान
वरुण गर्ग

1
मेरे लिए अद्वितीय आईडी और लंबित इरादे के लिए PendingIntent.FLAG_ONE_SHOT होने के साथ-साथ इरादे पर काम करने के लिए।
कौस्तुव

यह थोड़ा अजीब है कि यह आशय परिवर्तन के लिए अतिरिक्त परिवर्तनों पर विचार नहीं कर रहा है, लेकिन यह सच प्रतीत होता है: /
जीरो डिवाइडर

20

मैं जवाब देखता हूं लेकिन कोई स्पष्टीकरण नहीं। इसके अलावा कोई भी उत्तर सभी संभावित समाधानों को संबोधित नहीं करता है, इसलिए मैं इसे स्पष्ट करने की कोशिश करूंगा।

प्रलेखन:

यदि आपको वास्तव में एक ही समय में सक्रिय कई अलग-अलग लंबित वस्तुओं की आवश्यकता होती है (जैसे कि दो सूचनाओं के रूप में उपयोग करने के लिए जो दोनों एक ही समय में दिखाए जाते हैं), तो आपको यह सुनिश्चित करने की आवश्यकता होगी कि कुछ अलग है जो उन्हें अलग से संबद्ध करने के बारे में है PendingIntents। यह Intent.filterEquals, या getActivity (Context, int, Intent, int), getActivities (Context, int, Intent [], int), getBroadcast (Context, int) द्वारा दिए गए अलग-अलग अनुरोध कोड इंटीरियर्स में से कोई भी हो सकता है। , आशय, int), या getService (संदर्भ, int, आशय, int)।

समस्या का कारण:

आप 2 लंबित इरादों के साथ 2 सूचनाएं बनाते हैं। प्रत्येक लंबित इरादा एक इरादे से जुड़ा हुआ है:

Intent intent = new Intent(context, testActivity.class);

हालाँकि, ये 2 इरादे बराबर हैं, इसलिए जब आपका दूसरा नोटिफिकेशन आएगा तो यह पहला इरादा लॉन्च करेगा।

समाधान:

आपको प्रत्येक इरादे को विशिष्ट बनाना होगा, ताकि कोई भी लंबित इरादा कभी भी बराबर न हो। आप इरादों को अद्वितीय कैसे बनाते हैं? आपके द्वारा डाले गए अतिरिक्त से नहीं putExtra()। यहां तक ​​कि अगर एक्स्ट्रा अलग हैं, तो इंटेंट्स अभी भी समान हो सकते हैं। प्रत्येक आशय को विशिष्ट बनाने के लिए, आपको आशय क्रिया, या डेटा, या प्रकार, या वर्ग, या श्रेणी या अनुरोध कोड के लिए एक अद्वितीय मान सेट करना होगा: (उनमें से कोई भी काम करेगा)

  • कार्रवाई: intent.setAction(...)
  • डेटा: intent.setData(...)
  • प्रकार: intent.setType(...)
  • वर्ग: intent.setClass(...)
  • वर्ग: intent.addCategory(...)
  • अनुरोध कोड: PendingIntent.getActivity(context, YOUR_UNIQUE_CODE, intent, Intent.FLAG_ONE_SHOT);

नोट : एक अद्वितीय अनुरोध कोड सेट करना मुश्किल हो सकता है क्योंकि आपको एक इंट की आवश्यकता होती है, जबकि System.currentTimeMillis()लंबी रिटर्न, जिसका अर्थ है कि कुछ अंक हटा दिए जाएंगे। इसलिए मैं या तो श्रेणी या कार्रवाई और एक अद्वितीय स्ट्रिंग सेट करने के साथ जाने की सलाह दूंगा।


यह वही है जो अंततः मेरे लिए काम करता था, प्रत्येक अधिसूचना के लिए एक अद्वितीय आईडी का उपयोग करके (रद्द करने की आवश्यकता के लिए वैसे भी) और एक कस्टम श्रेणी प्रति क्रिया (एक ही अधिसूचना पर एक ही प्रकार के कई कार्य नहीं होंगे)।
मंडिसा डब्ल्यूडब्ल्यू

हाँ, मैं प्रत्येक इरादे के लिए एक अनूठी श्रेणी का उपयोग कर रहा हूं, यह बहुत अच्छा काम करता है।
स्टेलियोसेफ

एक ही समस्या है। एक ही समय में दो सूचनाएँ ट्रिगर हुईं। जब मैं दूसरी अधिसूचना पर क्लिक करता हूं तो कुछ नहीं हुआ। इस सेट के बाद सेट करें (Long.toString (System.currentTimeMillis ())); । आकर्षण की तरह काम कर रहा है। अच्छी व्याख्या के लिए धन्यवाद @MScott
अनंत बाबू

13

मेरे पास एक ही समस्या थी, और ध्वज को बदलकर इसे ठीक करने में सक्षम था:

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

आपके लिए समस्या को ठीक करने के लिए समय निकालने के लिए बहुत धन्यवाद। मैं यह उल्लेख करना भूल गया कि मैं इरादे में एक अतिरिक्त गुजर रहा हूं। इससे समस्या थोड़ी और जटिल हो जाती है। मेरे संपादन की जाँच करें 1.

9

जैसा कि प्रलेखन ने कहा कि अद्वितीय अनुरोध कोड का उपयोग करें:

यदि आपको वास्तव में एक ही समय में सक्रिय कई अलग-अलग लंबित वस्तुओं की आवश्यकता होती है (जैसे कि दो सूचनाओं के रूप में उपयोग करने के लिए जो दोनों एक ही समय में दिखाए जाते हैं), तो आपको यह सुनिश्चित करने की आवश्यकता होगी कि कुछ अलग है जो उन्हें अलग से संबद्ध करने के लिए है PendingIntents। यह Intent.filterEquals, या getActivity (Context, int, Intent, int), getActivities (Context, int, Intent [], int), getBroadcast (Context, int) के लिए आपूर्ति किए गए अलग-अलग अनुरोध कोड इंटीरियर्स में से कोई भी हो सकता है। , आशय, int), या getService (संदर्भ, int, आशय, int)।


1
बिंदु उत्तर के लिए केवल यही सही और सही है। इसके लिए देख रहा था, क्योंकि मैं एक ही बात पोस्ट करना चाहता था। :-)
सेवस्तन सवणुक

7

Fwiw, मैं के साथ की PendingIntent.FLAG_CANCEL_CURRENTतुलना में बेहतर भाग्य पड़ा है PendingIntent.FLAG_UPDATE_CURRENT


मैं इससे पूरी तरह सहमत हूं। यदि हम इसे पुराने को रद्द कर सकते हैं और फिर एक नया निर्माण कर सकते हैं, तो बेकार एक्स्ट्रा के साथ इंटेंट्स को भरने की कोई आवश्यकता नहीं है। यह सच है कि अगर कभी कुछ नहीं बदला तो यह बेकार हो सकता है, लेकिन अब सवाल "स्मृति को बचाने या समय बचाने के लिए" है।
जीरो डिवाइडर 24'18

4

मेरे पास एक ही समस्या थी और मैंने इसे नीचे के चरणों से तय किया

1) इरादे के लिए कोई भी झंडा साफ़ करें

intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);

2) नीचे दिए गए कोड द्वारा आशय .setAction डालें

 intent.setAction(Long.toString(System.currentTimeMillis()));

3) लंबित के लिए, नीचे दिए गए कोड डालें

   PendingIntent Pintent = PendingIntent.getActivity(ctx,0, intent,PendingIntent.FLAG_UPDATE_CURRENT);

मुझे तुम्हारे साथ काम करने की उम्मीद है


1
किसी भी एक कारण की व्याख्या करने के लिए कि क्यों इस जवाब को नीचा दिखाया गया था। इसने मेरे लिए काम किया। मुझे नहीं पता कि यह कानूनी जवाब है, लेकिन यह समाधान सही समाधान है। कम से कम मेरे लिए।
संदीप आर

मेरे लिए भी काम किया! धन्यवाद!
एंड्रेस

2
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK);

PendingIntent में दो int पैरामीटर हैं, दूसरा एक और अंतिम एक। दूसरा एक "अनुरोध कोड" है और यह यूनिक्यू नंबर होना चाहिए (उदाहरण के लिए आपके नोटिफिकेशन का आईडी), अन्यथा यदि (आपके उदाहरण में यह शून्य के बराबर है, तो यह हमेशा ओवरराइट किया जाएगा)।


0
// Use pending Intent and  also use unique id for display notification....
// Get a PendingIntent containing the entire back stack
PendingIntent notificationPendingIntent = stackBuilder.getPendingIntent(0,PendingIntent.FLAG_UPDATE_CURRENT);
NotificationManager mNotificationManager = (NotificationManager)  sqlitewraper.context.getSystemService(Context.NOTIFICATION_SERVICE);
// Issue the notification
mNotificationManager.notify(id, builder.build());

0

डेटा को सही तरीके से भेजने के लिए आपको इस तरह से लंबित आशय की अधिसूचना आईडी के साथ भेजना चाहिए: लंबित लंबित = लंबित = लंबित.गतिउपलब्धता (संदर्भ, (int) System.currentTimeMillis () , आशय, PIIIntent.FLAG_UPDATE_CURRENT);


0

मेरे पास एक ही समस्या है, और इसे ठीक करने के लिए PendingIntent.html.FLAG_UPDATE_CURRENT का उपयोग करें ।

मैंने सोर्स कोड चेक किया है। में ActivityManagerService.java , कुंजी विधि के रूप में इस प्रकार है। जब ध्वज PendingIntent.FLAG_UPDATE_CURRENT है और अद्यतन सही है। कुछ एक्स्ट्रा को नए द्वारा बदल दिया जाएगा और हमें एक बदला हुआ लंबन मिलेगा।

    IIntentSender getIntentSenderLocked(int type, String packageName,
            int callingUid, int userId, IBinder token, String resultWho,
            int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
            Bundle bOptions) {

// ... omitted

        final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
        final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
        final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
        flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
                |PendingIntent.FLAG_UPDATE_CURRENT);

        PendingIntentRecord.Key key = new PendingIntentRecord.Key(
                type, packageName, activity, resultWho,
                requestCode, intents, resolvedTypes, flags, bOptions, userId);
        WeakReference<PendingIntentRecord> ref;
        ref = mIntentSenderRecords.get(key);
        PendingIntentRecord rec = ref != null ? ref.get() : null;
        if (rec != null) {
            if (!cancelCurrent) {
                if (updateCurrent) {
                    if (rec.key.requestIntent != null) {
                        rec.key.requestIntent.replaceExtras(intents != null ?
                                intents[intents.length - 1] : null);
                    }
                    if (intents != null) {
                        intents[intents.length-1] = rec.key.requestIntent;
                        rec.key.allIntents = intents;
                        rec.key.allResolvedTypes = resolvedTypes;
                    } else {
                        rec.key.allIntents = null;
                        rec.key.allResolvedTypes = null;
                    }
                }
                return rec;
            }
            rec.canceled = true;
            mIntentSenderRecords.remove(key);
        }


-5

मेरे पास एक ही समस्या थी, और ध्वज को बदलकर इसे ठीक करने में सक्षम था:

LayoutInflater factory = LayoutInflater.from(this);            
      final View textEntryView = factory.inflate(R.layout.appointment, null);
      AlertDialog.Builder bulider= new AlertDialog.Builder(PatientDetail.this);
      final AlertDialog alert=bulider.create();


        bulider.setTitle("Enter Date/Time");
        bulider.setView(textEntryView);
        bulider.setPositiveButton("Save", new DialogInterface.OnClickListener() {

                public void onClick(DialogInterface dialog, int which) {
                      EditText typeText=(EditText) textEntryView.findViewById(R.id.Editdate);
                      EditText input1 =(EditText) textEntryView.findViewById(R.id.Edittime);
                      getDateAndTime(typeText.getText().toString(),input1.getText().toString());
                }
            });
        bulider.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {

                public void onClick(DialogInterface dialog, int which) {
                    dialog.cancel();
                }
            });

        bulider.show();

    }

4
इससे पूछे गए सवाल का कोई लेना देना नहीं है।
पॉल तुर्चेंको

यह स्पष्ट करने की आवश्यकता है कि यह इस प्रश्न से कैसे संबंधित है।
नॉर्मन एच
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.