Android 4.1: hoe controleer ik of meldingen zijn uitgeschakeld voor de applicatie?

Android 4.1 biedt de gebruiker een selectievakje om meldingen voor een specifieke applicatie uit te schakelen.

Als ontwikkelaar kunnen we echter niet weten of een oproep tot melding effectief was of niet.

Ik moet echt controleren of de meldingen zijn uitgeschakeld voor de huidige applicatie, maar ik kan daar geen instelling voor vinden in de API.

Is er ooit een manier om deze instelling in de code te controleren?


Antwoord 1, autoriteit 100%

Je kunt niet 100% niet.

Het wordt gevraagd in deze Google I/O 2012-videoen de projectleider voor de nieuwe meldingen verklaart dat je dat niet kunt.


Bewerken

2016 update:nu kun je het controleren, zoals gezegd in deze Google I/O 2016-video.

Gebruik NotificationManagerCompat.areNotificationsEnabled(), uit de ondersteuningsbibliotheek, om te controleren of meldingen worden geblokkeerd op API 19+. De versies onder API 19 zullen true retourneren (meldingen zijn ingeschakeld).


Antwoord 2, autoriteit 30%

Antwoord van @blundell is correct, maar er is een kleine wijziging in nieuwere versies.

NotificationManagerCompat.from(context).areNotificationsEnabled()

Antwoord 3, autoriteit 25%

Eigenlijk is dit vrij eenvoudig om te doen:

/**
 * 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;
    }
}

Antwoord 4, autoriteit 3%

Als u Xamarin gebruikt en u dit antwoord nodig heeft, kunt u deze code gebruiken:

//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;
    }
}

Antwoord 5, autoriteit 3%

Het lijkt erop dat er geen manier is om de meldingsstatus op te vragen.

Ik raad dit aan:

  • Ontwerp je applicatie met meldingen.
  • Laat de gebruiker meldingen uitschakelen via de instellingen van de applicatie.
  • Controleer of er op meldingen wordt geklikt. Als de gebruiker op melding klikt, sla dit dan op in voorkeuren.
  • Als de meldingsinstelling in uw app is ingeschakeld en de gebruiker Android 4.1+ (API 16) is, maar als de gebruiker een aantal dagen/weken niet op de melding klikt, neem dan aan dat de gebruiker de meldingen heeft uitgeschakeld.

Niet 100% correct. Maar dit geeft een mening.
Als de gebruiker bijvoorbeeld gedurende 10-15 dagen niet op een app-melding klikt, heeft hij deze waarschijnlijk uitgeschakeld


Antwoord 6, autoriteit 2%

Ik gebruik deze methode om te controleren of de meldingen zijn ingeschakeld of niet,
de bovengenoemde methoden werken om te controleren of meldingen zijn ingeschakeld of niet. Maar vanaf Android 8en verder voor het maken van meldingen we moeten eerst een kanaal maken, dus vanaf Oreo we moeten controleren of je meldingskanaal is ingeschakeld of niet.

   /**
     * 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;
    }

Other episodes