कार्रवाई पर क्लिक करने के बाद अधिसूचना को कैसे खारिज किया जाए


142

एपीआई स्तर 16 (जेली बीन) के साथ, एक अधिसूचना के साथ क्रियाओं को जोड़ने की संभावना है

builder.addAction(iconId, title, intent);

लेकिन जब मैं एक अधिसूचना में एक क्रिया जोड़ता हूं और कार्रवाई को दबाया जाता है, तो अधिसूचना को खारिज नहीं किया जाएगा। जब अधिसूचना को ही क्लिक किया जा रहा है, तो इसे खारिज किया जा सकता है

notification.flags = Notification.FLAG_AUTO_CANCEL;

या

builder.setAutoCancel(true);

लेकिन जाहिर है, यह अधिसूचना से जुड़े कार्यों के साथ कुछ भी नहीं है।

कोई संकेत? या यह अभी तक एपीआई का हिस्सा नहीं है? मुझे कुछ नहीं मिला।

जवाबों:


154

जब आप सूचना प्रबंधक को सूचित करते हैं, तो आपने उसे एक आईडी दी है - वह विशिष्ट आईडी है जिसे आप बाद में एक्सेस करने के लिए उपयोग कर सकते हैं (यह अधिसूचना प्रबंधक से है:

notify(int id, Notification notification)

रद्द करने के लिए, आप कॉल करेंगे:

cancel(int id)

उसी आईडी के साथ। तो, मूल रूप से, आपको आईडी का ट्रैक रखने की आवश्यकता है या संभवतः आईडी को एक बंडल में डाल दें जिसे आप लंबवत के अंदर इरादा में जोड़ते हैं?


25
धन्यवाद, इससे मेरी समस्या हल हो गई। हालांकि, मुझे अभी भी लगता है कि यह थोड़ा अधिक जटिल है। किसी कार्रवाई को दबाने पर अधिसूचना को केवल एक एपीआई प्रदान करने के बजाय, आपको इसे प्राप्त करने के लिए इरादे और अधिसूचना आईडी के साथ काम करना होगा।
एंडोवोज़नर

2
यदि आपको लगता है कि यह जटिल है, तो एक अधिसूचना को अपडेट करने पर ध्यान न दें (उस आईडी का ट्रैक न खोएं), या यह जांचना कि यह प्रदर्शित है या नहीं (एपीआई इसे ट्रैक नहीं करता है, आपको) ...: पी
ट्रैविस

2
@Daksh: मूल रूप से, आप अपने इरादे के लिए सूचना टैग और आईडी जोड़ते हैं जो तब शुरू होती है जब आपकी कार्रवाई दबा दी जाती है। उस अतिरिक्त जानकारी के साथ, आप प्रारंभिक गतिविधि में देख सकते हैं कि क्या यह नोटिफिकेशन कार्रवाई के माध्यम से शुरू किया गया था।
एंडोवोज़नर

5
OnCreate से कोड नमूना (): बंडल एक्स्ट्रा = getIntent ()। GetExtras (); अगर (एक्स्ट्रा कलाकार! = null) {स्ट्रिंग टैग = extras.getString (NotificationReceiver.INTENT_EXTRA_NOTIFICATION_TAG); int id = extras.getInt (NotificationReceiver.INTENT_EXTRA_NOTIFICATION_ID); if (NotificationReceiver.NOTIFICATION_ID == id && NotificationReceiver.NOTIFICATION_TAG.equals (टैग)) {// गतिविधि को अधिसूचना कार्रवाई के माध्यम से शुरू किया गया है, खारिज करें / अधिसूचना NotificationManager प्रबंधक = (NotificationManager) getSystemService (Service.NOTIFICATION_SERVICE); manager.cancel (टैग, आईडी); }}
एंडोवोज़नर

1
नए एपीआई में आपने सूचित किया है (स्ट्रिंग टैग, इंट आईडी, अधिसूचना अधिसूचना) और इसके अनुरूप रद्द करें (स्ट्रिंग टैग, इंट आईडी)
मालचीज़ १४'१ notify

64

लॉलीपॉप के हेड्स अप डिस्प्ले नोटिफिकेशन का उपयोग करते समय इसे एक मुद्दा पाया गया। डिजाइन दिशानिर्देश देखें । यहां लागू करने के लिए पूरा (ईश) कोड है।

अब तक, 'डिसमिस' बटन का होना कम महत्वपूर्ण नहीं था, लेकिन अब यह आपके चेहरे पर अधिक है।

अधिसूचना जारी

अधिसूचना का निर्माण

int notificationId = new Random().nextInt(); // just use a counter in some util class...
PendingIntent dismissIntent = NotificationActivity.getDismissIntent(notificationId, context);

NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
builder.setPriority(NotificationCompat.PRIORITY_MAX) //HIGH, MAX, FULL_SCREEN and setDefaults(Notification.DEFAULT_ALL) will make it a Heads Up Display Style
        .setDefaults(Notification.DEFAULT_ALL) // also requires VIBRATE permission
        .setSmallIcon(R.drawable.ic_action_refresh) // Required!
        .setContentTitle("Message from test")
        .setContentText("message")
        .setAutoCancel(true)
        .addAction(R.drawable.ic_action_cancel, "Dismiss", dismissIntent)
        .addAction(R.drawable.ic_action_boom, "Action!", someOtherPendingIntent);

// Gets an instance of the NotificationManager service
NotificationManager notifyMgr = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

// Builds the notification and issues it.
notifyMgr.notify(notificationId, builder.build());

NotificationActivity

public class NotificationActivity extends Activity {

    public static final String NOTIFICATION_ID = "NOTIFICATION_ID";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        manager.cancel(getIntent().getIntExtra(NOTIFICATION_ID, -1));
        finish(); // since finish() is called in onCreate(), onDestroy() will be called immediately
    }

    public static PendingIntent getDismissIntent(int notificationId, Context context) {
        Intent intent = new Intent(context, NotificationActivity.class);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
        intent.putExtra(NOTIFICATION_ID, notificationId);
        PendingIntent dismissIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
        return dismissIntent;
    }

}

AndroidManifest.xml (बैक को स्टैक करने के लिए सिस्टमयूआई को रोकने के लिए आवश्यक विशेषताएँ)

<activity
    android:name=".NotificationActivity"
    android:taskAffinity=""
    android:excludeFromRecents="true">
</activity>

मेरे पास एक आवेदन से कई सूचनाएं हैं और नोटिफ़िकेशन चल रहे अधिसूचना पर सेट हैं। जब अधिसूचना लंबवत अधिसूचना पर प्रदर्शन करती है, तो मैं अधिसूचना को साफ करना चाहता हूं
प्रसाद

3
इसके बजाय सूचना को खारिज करने के लिए यहां ब्रॉडकास्टर का उपयोग करना अधिक प्रभावी नहीं होगा? यहाँ एक अच्छा उदाहरण है जो कार्यान्वयन को दर्शाता है, लेकिन इसे और भी कम किया जा सकता है: stackoverflow.com/a/19745745/793150
alice.harrison

1
समाधान कार्य, एक्स्ट्रा सेट को छोड़कर इरादे से आगे बढ़ाए जाते हैं। इन्हें onCreate पर अग्रेषित नहीं किया जाता है। एक तरीका है स्थैतिक चर का उपयोग करना। क्या किसी को पता है, इरादे एक्स्ट्रा को आगे क्यों नहीं बढ़ाया जाता है?
बसची

NotDismissIntent केवल तभी काम करता है जब NotificationActivity में रखा गया हो? बर्खास्तगी का इरादा काम नहीं करता है यदि PendingIntent निर्माण कोड को अधिसूचना बिल्डर वर्ग में रखा गया है। मैंने इस मुद्दे पर सिर्फ 2 घंटे बिताए हैं और मैं यह पता नहीं लगा सकता कि गतिविधि में लंबित आशय क्यों बनाया जाना चाहिए। क्या कोई समझा सकता है कि ऐसा क्यों है?
रे ली

getDismissIntent () एक स्टैटिक "हेल्पर" फंक्शन है जो NotificationActivity के साथ संवाद करने के लिए सही इरादे का निर्माण करता है। जैसे, ये आमतौर पर गतिविधि के साथ बंडल किए जाते हैं। लेकिन मैं यह नहीं देखता कि इस स्थिर फ़ंक्शन को सूचना बिल्डर वर्ग में क्यों नहीं रखा जा सकता, जब तक आप NOTIFICATION_ID और संदर्भ को सही ढंग से सेट करने के लिए सावधान हैं।
माइक

17

मैंने पाया कि जब आप विस्तारित सूचनाओं में एक्शन बटन का उपयोग करते हैं, तो आपको अतिरिक्त कोड लिखना होता है और आप अधिक विवश होते हैं।

जब उपयोगकर्ता कार्रवाई बटन क्लिक करता है, तो आपको मैन्युअल रूप से अपनी अधिसूचना रद्द करनी होगी। अधिसूचना केवल डिफ़ॉल्ट कार्रवाई के लिए स्वचालित रूप से रद्द कर दी जाती है।

यदि आप बटन से एक प्रसारण रिसीवर शुरू करते हैं, तो सूचना दराज बंद नहीं होता है।

मैंने इन मुद्दों पर ध्यान देने के लिए एक नई अधिसूचना बनाने का काम किया। बिना किसी यूआई के यह मध्यस्थ गतिविधि अधिसूचना को रद्द कर देती है और फिर उस गतिविधि को शुरू करता है जिसे मैं वास्तव में अधिसूचना से शुरू करना चाहता था।

मैंने संबंधित पोस्ट में नमूना कोड पोस्ट किया है एंड्रॉइड नोटिफिकेशन एक्ट्स पर क्लिक करने से अधिसूचना ड्रॉअर बंद नहीं होता है


2
बहुत बुरा वे अभी भी एपीआई में यह पके हुए नहीं है ... यह इस तरह से यह करने के लिए बहुत hackish है। लेकिन फिर भी एकमात्र तरीका है, खासकर यदि आपके पास गंतव्य इरादे पर कोई नियंत्रण नहीं है, जैसे कि URL देखना।
बोगदान जुरैक 20

जानकारी के लिए धन्यवाद, आप सही हैं। हालाँकि मैं एक मध्यस्थ गतिविधि के बजाय एक अंतर-सेवा का उपयोग करेगा
टिम

7

तुम हमेशा कर सकते हैं से जो कुछ भी (में, उदाहरण के लिए कार्रवाई द्वारा लाया जा रहा है गतिविधि से बंधा की आप के लिए आपूर्ति )।cancel()NotificationonCreate()PendingIntentaddAction()


2
लेकिन जिस गतिविधि को कहा गया है, उसमें मुझे अधिसूचना तक पहुंच कैसे मिलेगी?
१२:५० पर एंडोवोज़नर

@ फ्लेश वाउंड: cancel()की आईडी लेता है Notification, जिसे आपने कॉल किया था notify()। आपको Notificationवस्तु की आवश्यकता नहीं है ।
कॉमन्सवेयर

यदि सेटग्रुप सेट किया गया है और समूह सारांश सूचना है तो @CommonsWare कैंसिल (आईडी) ने काम करना बंद कर दिया है। इस मामले में, रद्द किसी कारण के लिए कुछ भी नहीं करता है। समूह सारांश के बिना, हालांकि काम ठीक हो जाता है
कुशन

अगर मेरा लंबित इरादा है ACTION_VIEWऔर प्रकार है image/jpeg(किसी अन्य ऐप के साथ एक छवि साझा करने के लिए) तो उस रद्द को कैसे ट्रिगर किया जाना चाहिए? IMO एंड्रॉइड को ऑटो-रद्द करना चाहिए, मैं इस बात से हैरान हूं कि एंड्रॉइड इसका ख्याल क्यों नहीं रखता है!
किसी ने

@SomeoneSomewhere: "तो उस रद्द को ट्रिगर कैसे माना जाता है?" - यह नहीं हो सकता। हालांकि इसमें एक में एक तीसरे पक्ष के अनुप्रयोग की ओर इशारा करते से आप को रोकने के लिए कुछ भी नहीं है Notificationसे संबंधित PendingIntent, जो वास्तव में यह कैसे काम करने के लिए डिजाइन किया गया था नहीं है, और इसलिए आप इस तरह के मुद्दों में चलेंगे। "आईएमओ एंड्रॉइड को ऑटो-रद्द करना चाहिए" - मैं उस पर कार्रवाई के लिए एक ध्वज की पेशकश कर सकता था, लेकिन यह एक सर्वकालिक चीज नहीं होनी चाहिए। अगर ऐसा होता, तो म्यूजिक प्लेयर के नोटिफिकेशन में किसी ट्रैक को स्किप करने से नोटिफिकेशन बंद हो जाता।
कॉमन्सवेयर

7

BroadcastReceiverनोटिफिकेशन को रद्द करने के लिए एक क्लीनर तरीका है मेरी राय में :

AndroidManifest.xml में:

<receiver 
    android:name=.NotificationCancelReceiver" >
    <intent-filter android:priority="999" >
         <action android:name="com.example.cancel" />
    </intent-filter>
</receiver>

जावा फ़ाइल में:

Intent cancel = new Intent("com.example.cancel");
PendingIntent cancelP = PendingIntent.getBroadcast(context, 0, cancel, PendingIntent.FLAG_CANCEL_CURRENT);

NotificationCompat.Action actions[] = new NotificationCompat.Action[1];

NotificationCancelReceiver

public class NotificationCancelReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        //Cancel your ongoing Notification
    };
}

1
यही मैं करता हूं लेकिन आपको ऑनरसीव विधि से अधिसूचना आईडी (इस उदाहरण में, 0) कैसे मिलती है? यह इंटेंट में नहीं है, क्योंकि इसे इसमें जोड़ा नहीं गया है। मैंने इसे एक अतिरिक्त के रूप में जोड़ने की कोशिश की, लेकिन ऐसा लगता है कि असली अधिसूचना आईडी वह नहीं है जिसे मैं एक अतिरिक्त गतिविधि के रूप में जोड़ रहा था ...: - /
Marco Zanetti

मैं वास्तव में गतिविधियों के बजाय प्रसारण सेवाओं का उपयोग करने के इस दृष्टिकोण को पसंद करता हूं, यह बहुत हल्का दृष्टिकोण imho है।
क्रिस्टोफ मोईन

लेकिन मुझे दिखाए गए किसी भी नोटिफिकेशन को खारिज करने में सक्षम होने के लिए <इरादे। एज (इंटेगर.टोस्ट्रिंग (नोटिफिकेशन));> का उपयोग करना था।
क्रिस्टोफ मोइन

1
@MarcoZanetti आपको एक अधिसूचना आईडी जनरेट करनी होगी जिसे आप लंबित आशय के पास भेजते हैं और अधिसूचना भेजते समय सूचना विधि को भी भेजते हैं। यदि आप ऐसा करते हैं, तो जब उपयोगकर्ता इसे रद्द करने के लिए कार्रवाई पर क्लिक करता है, तो वह प्रसारण रिसीवर को कॉल करेगा और फिर आप एक्स्ट्रा कलाकार से अधिसूचना आईडी प्राप्त कर सकते हैं।
रे हंटर

@ChristopheMoine के माध्यम से आप आईडी डाल सकते हैं intent.putExtra()और इसे प्राप्त कर सकते हैंBroadcastReceiver
वादिम कोटोव

5

नए API में TAG के बारे में मत भूलना:

notify(String tag, int id, Notification notification)

और इसी के साथ

cancel(String tag, int id) 

के बजाय:

cancel(int id)

https://developer.android.com/reference/android/app/NotificationManager


तुम सही थे! हालाँकि cancel()फ़ंक्शन में 2 कार्यान्वयन हैं; एक TAG के साथ और एक बिना। लेकिन हमें प्रदान करना होगा TAG। यहाँ cancelडॉक्स से फ़ंक्शन है public void cancel(@Nullable String tag, int id)। अंतिम बार Android Q
sud007

1

बस यह लाइन लगाएं:

 builder.setAutoCancel(true);

और पूर्ण कोड है:

NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
    builder.setSmallIcon(android.R.drawable.ic_dialog_alert);
    Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://www.google.co.in/"));
    PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
    builder.setContentIntent(pendingIntent);
    builder.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.misti_ic));
    builder.setContentTitle("Notifications Title");
    builder.setContentText("Your notification content here.");
    builder.setSubText("Tap to view the website.");
    Toast.makeText(getApplicationContext(), "The notification has been created!!", Toast.LENGTH_LONG).show();

    NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
    builder.setAutoCancel(true);
    // Will display the notification in the notification bar
    notificationManager.notify(1, builder.build());

Android 9 को टारगेट करते समय AutoCancel का कोई प्रभाव नहीं पड़ता है (Android 8.1 को टारगेट करते समय ठीक काम करता है)
Alix

यहाँ भेद कार्रवाई के साथ है
कोई कहीं

0

अधिसूचना को हटाने के आपके इरादे के बाद आपको निम्नलिखित कोड चलाने की आवश्यकता होगी।

NotificationManagerCompat.from(this).cancel(null, notificationId);

NB: नोटिफिकेशन वही है जो आपकी अधिसूचना को चलाने के लिए पारित किया गया है


-3

builder.setAutoCancel (सही);

Android 9 पर भी परीक्षण किया गया।

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