एंड्रॉइड 4.1: एप्लिकेशन के लिए नोटिफिकेशन को कैसे निष्क्रिय किया जाए?


98

एंड्रॉइड 4.1 एक विशिष्ट एप्लिकेशन के लिए सूचनाओं को अक्षम करने के लिए उपयोगकर्ता को एक चेक बॉक्स प्रदान करता है।

हालांकि, एक डेवलपर के रूप में हमारे पास यह जानने का कोई तरीका नहीं है कि सूचित करने के लिए कॉल प्रभावी था या नहीं।

मुझे वास्तव में यह जांचने की आवश्यकता है कि क्या वर्तमान एप्लिकेशन के लिए सूचनाएं अक्षम हैं, लेकिन मुझे एपीआई में इसके लिए कोई सेटिंग नहीं मिल सकती है।

क्या कोड में इस सेटिंग की जांच करने का कोई तरीका है?


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

मैंने पहले अन्वेषक की टिप्पणियों में इसका कारण बताया।
गिलाउम पेरोट

1
यहाँ स्टार के लिए मुद्दा है / ट्रैक code.google.com/p/android/issues/detail?id=38482 वाकई इस .... जरूरत है
brandall

जवाबों:


147

आप 100% नहीं कर सकते।

यह Google I / O 2012 वीडियो में पूछा गया है और नई सूचनाओं के लिए प्रोजेक्ट लीड घोषित करता है कि आप नहीं कर सकते।


संपादित करें

2016 अपडेट: अब आप इसे जांच सकते हैं, जैसा कि इस Google I / O 2016 वीडियो में कहा गया है ।

NotificationManagerCompat.areNotificationsEnabled()API 19+ पर सूचनाएँ अवरुद्ध हैं या नहीं, यह जाँचने के लिए, समर्थन लाइब्रेरी से उपयोग करें । एपीआई 19 से नीचे के संस्करण सही होंगे (सूचनाएं सक्षम हैं)।

यहां छवि विवरण दर्ज करें


2
वीडियो में ऐसा कुछ भी नहीं दिखाया गया है जिसे हम इस सेटिंग को नहीं पढ़ सकते। बस स्पष्ट होना चाहिए: मैं सिर्फ चेक बॉक्स की वर्तमान स्थिति को पढ़ने में सक्षम होना चाहता हूं, इसे बदलना नहीं। मुझे डर है कि आपने मेरे सवाल को नहीं समझा।
गिलाउम पेरोट

2
हमें इसकी आवश्यकता है क्योंकि हम एक बार में 1 सूचना दिखाते हैं (जो इन-ऐप या सिस्टम बार में हो सकती है)। यदि सिस्टम नोटिफिकेशन प्रदर्शित होता है, तो हम ऐप बैनर और इसके विपरीत में नहीं दिखाते हैं। यदि हम यह नहीं जान सकते कि कोई सूचना प्रदर्शित की गई है या नहीं, तो हम उसके जीवन चक्र का प्रबंधन नहीं कर सकते हैं। मुझे लगता है कि हमें अब पूरी तरह से सूचनाओं को प्रबंधित करने के तरीके को बदलना होगा ...
पेरोट

9
FYI करें, सवाल पूछा गया है (और उत्तर दिया गया) 48:05 पर वीडियो में (प्रश्नोत्तर के दौरान) एक छोटे शब्द के साथ ... नहीं। youtube.com/…
Devunwired

2
पूर्ण लिंक के साथ @Stavros_S अपडेटेड उत्तर। NotificationManagerCompat.areNotificationsEnabled ()
सूफियान

17
@Stavros_S आपको उपयोग करने की आवश्यकता हैNotificationManagerCompat.from(ctx).areNotificationsEnabled()
AlexAndro

39

@Blundell से उत्तर सही है लेकिन नए संस्करणों में एक मामूली बदलाव है।

NotificationManagerCompat.from(context).areNotificationsEnabled()

38

वास्तव में यह करना बहुत आसान है:

/**
 * Created by desgraci on 5/7/15.
*/
public class NotificationsUtils {

    private static final String CHECK_OP_NO_THROW = "checkOpNoThrow";
    private static final String OP_POST_NOTIFICATION = "OP_POST_NOTIFICATION";

    public static boolean isNotificationEnabled(Context context) {

        AppOpsManager mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);

        ApplicationInfo appInfo = context.getApplicationInfo();

        String pkg = context.getApplicationContext().getPackageName();

        int uid = appInfo.uid;

        Class appOpsClass = null; /* Context.APP_OPS_MANAGER */

        try {

            appOpsClass = Class.forName(AppOpsManager.class.getName());

            Method checkOpNoThrowMethod = appOpsClass.getMethod(CHECK_OP_NO_THROW, Integer.TYPE, Integer.TYPE, String.class);

            Field opPostNotificationValue = appOpsClass.getDeclaredField(OP_POST_NOTIFICATION);
            int value = (int)opPostNotificationValue.get(Integer.class);

            return ((int)checkOpNoThrowMethod.invoke(mAppOps,value, uid, pkg) == AppOpsManager.MODE_ALLOWED);

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
        return false;
    }
}

3
जिस समय प्रश्न पोस्ट किया गया था, एंड्रॉइड 4.1 चालू था, यह केवल एंड्रॉइड 4.4+ के लिए है और प्रतिबिंब का उपयोग करने के लिए लगता है और दस्तावेज़ीकरण इसे गैर-सिस्टम ऐप के लिए उपयोग करने की अनुशंसा नहीं करता है।
गिलोय पेरोट

@GuillaumePerrot वास्तव में, आप प्रतिबिंब के बारे में सही हैं, लेकिन फिर से, Android से प्रलेखन और आधिकारिक बयान कहते हैं कि आप ऐसा नहीं कर सकते, आप भी उससे चिपक सकते हैं। संस्करण की समस्या के बारे में क्षमा करें, मैं आपकी मदद नहीं कर सकता। यदि आपके क्लाइंट / समाधान को इसकी आवश्यकता है, ठीक है, तो आप आवश्यक संस्करण को थोड़ा बढ़ाने पर विचार कर सकते हैं क्योंकि एसडीके उस बिंदु पर आपको सीमित कर रहा है। अगर आपको कोई वैकल्पिक रास्ता मिल जाए तो मुझे बताएं।
डेसग्रासी

1
यदि आप जानकारी प्राप्त नहीं कर सकते, तो उचित मानें, लेकिन आपको सही होना चाहिए। कम से कम मेरे उपयोग के मामले में यह अधिक समझ में आता है। या इसे फिर से उपयोग करने योग्य बनाने के लिए स्थैतिक फ़ंक्शन में एक पैरामीटर के रूप में डिफ़ॉल्ट मान है।
गिलियूम पेरोट

1
@Rahul मैट, GlobalContext सिर्फ एक उपयोगिता वर्ग है जिसका उपयोग मैं एक संदर्भ के संदर्भ में रखने के लिए करता हूं, आप उस संरचना के माध्यम से एक संदर्भ पारित कर सकते हैं यदि आप उस संरचना का उपयोग करने के लिए / या उपयोग करने के लिए तैयार नहीं हैं। उम्मीद है की यह मदद करेगा!
डेसग्रासी

1
मुझे उम्मीद है कि वे नहीं: p लेकिन google XD से आ रहे हैं, क्योंकि यह प्रतिबिंब का उपयोग करता है, OP_POST_NOTIFICATION खुद को उसी मुद्दे से जूझते हुए खोजने के बाद grep पर कोड के माध्यम से पढ़ रहा था।
desgraci

5

यदि आप Xamarin का उपयोग कर रहे हैं और आपको इस उत्तर की आवश्यकता है तो आप इस कोड का उपयोग कर सकते हैं:

//return true if this option is not supported.
public class NotificationsUtils 
{
    private const String CHECK_OP_NO_THROW = "checkOpNoThrow";
    private const String OP_POST_NOTIFICATION = "OP_POST_NOTIFICATION";

    public static bool IsNotificationEnabled(global::Android.Content.Context context) {

        AppOpsManager mAppOps = (AppOpsManager) context.GetSystemService(global::Android.Content.Context.AppOpsService);

        ApplicationInfo appInfo = context.ApplicationInfo;

        String pkg = context.ApplicationContext.PackageName;

        int uid = appInfo.Uid;

        try {

            var appOpsClass = Java.Lang.Class.ForName("android.app.AppOpsManager");
            var checkOpNoThrowMethod = appOpsClass.GetMethod(CHECK_OP_NO_THROW,Java.Lang.Integer.Type,Java.Lang.Integer.Type,new Java.Lang.String().Class);//need to add String.Type

            var opPostNotificationValue = appOpsClass.GetDeclaredField (OP_POST_NOTIFICATION);
            var value = (int)opPostNotificationValue.GetInt(Java.Lang.Integer.Type);
            var mode = (int)checkOpNoThrowMethod.Invoke(mAppOps,value, uid, pkg);
            return (mode == (int)AppOpsManagerMode.Allowed);

        } catch (Exception) 
        {
            System.Diagnostics.Debug.WriteLine  ("Notification services is off or not supported");
        } 
        return true;
    }
}

@AdamPedley AreNotificationsEnabled () को एपीआई 24 डेवलपर
Sune Kjærgård

आप सही हैं, पहले इसे गलत समझना चाहिए था। मैंने अपनी मूल टिप्पणी को हटा दिया, ताकि किसी को भ्रमित न करूं।
एडम पेडली

5

ऐसा लगता है कि अधिसूचना राज्य को क्वेरी करने का कोई तरीका नहीं है।

मैं यह सलाह देता हूं:

  • आप सूचनाओं के साथ आवेदन डिजाइन करें।
  • उपयोगकर्ता को एप्लिकेशन की सेटिंग से सूचनाएं अक्षम करने दें।
  • जांचें कि क्या सूचनाएं क्लिक की जाती हैं। यदि उपयोगकर्ता अधिसूचना पर क्लिक करता है, तो इसे वरीयताओं पर सहेजें।
  • आपके एप्लिकेशन में, यदि अधिसूचना सेटिंग चालू है, और यदि उपयोगकर्ता Android 4.1+ (एपीआई 16) है, लेकिन यदि उपयोगकर्ता कुछ दिनों / हफ्तों के लिए अधिसूचना पर क्लिक नहीं करता है, तो मान लें कि उपयोगकर्ता अक्षम सूचनाएं हैं।

100% सही नहीं है। लेकिन यह एक राय देता है।
उदाहरण के लिए, यदि उपयोगकर्ता 10-15 दिनों के लिए किसी एप्लिकेशन सूचना पर क्लिक नहीं करता है, तो संभवत: उसने इसे अक्षम कर दिया है


1
यह एक बहुत व्यापक और सारगर्भित दृष्टिकोण है।
इगोरगानापोलस्की

यह सबसे अच्छा तरीका है! हम अपने आवेदन में ऐसा कर रहे हैं और यदि अधिसूचनाएं अक्षम हैं तो आप ठीक-ठीक कह सकते हैं। हर क्रिया के लिए लंबित और वरीयता में सहेजें। अगर स्मार्टफोन फिर से चालू हो जाए तो रीसेट करना न भूलें।
जैकसनऑफ 1

2

मैं इस पद्धति का उपयोग यह जांचने के लिए करता हूं कि सूचनाएं सक्षम हैं या नहीं, उपर्युक्त तरीके यह जांचने के लिए काम करेंगे कि सूचनाएं सक्षम हैं या नहीं। लेकिन एंड्रॉइड 8 से सूचनाओं को बनाने के लिए हमें पहले एक चैनल बनाना होगा , इसलिए ओरेओ से, हमें आपके नोटिफिकेशन चैनल को सक्षम या नहीं के लिए जांचना होगा

    /**
     * Checking Whether notifications are enabled or not
     * @return true if notifications are enabled otherwise false
     */
    public static final String CHANNEL_ID = "your_channel_id";

    private boolean isNotificationChannelEnabled(){
        if(NotificationManagerCompat.from(this).areNotificationsEnabled()) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
                NotificationChannel channel = manager.getNotificationChannel(CHANNEL_ID);
                if (channel == null)
                    return true; //channel is not yet created so return boolean
                // by only checking whether notifications enabled or not
                return channel.getImportance() != NotificationManager.IMPORTANCE_NONE;
            }
            return true;
        }
        return false;
    }

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