it-swarm.com.ru

Android 4.1: Как проверить, отключены ли уведомления для приложения?

Android 4.1 предлагает пользователю флажок для отключения уведомлений для определенного приложения.

Однако, как разработчик, мы не можем знать, был ли эффективен вызов для уведомления.

Мне действительно нужно проверить, отключены ли уведомления для текущего приложения, но я не могу найти никаких настроек для этого в API.

Есть ли способ проверить этот параметр в коде?

84
Guillaume Perrot

Вы не можете на 100% не можете.

Это спрашивается в это видео Google I/O 2012 , и руководитель проекта для новых уведомлений заявляет, что вы не можете.


Правка

Обновление 2016 года: Теперь вы можете проверить его, как сказано в это видео Google I/O 2016 .

Используйте NotificationManagerCompat.areNotificationsEnabled() из библиотеки поддержки, чтобы проверить, не заблокированы ли уведомления в API 19+. Версии ниже API 19 вернут истину (уведомления включены).

enter image description here

130
Blundell

На самом деле это довольно легко сделать:

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

Ответ от @blundell правильный, но в новых версиях есть небольшие изменения.

NotificationManagerCompat.from(context).areNotificationsEnabled(‌​)
28
Prakash

Если вы используете 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;
    }
}
4
user3030630

Похоже, что нет способа запросить состояние уведомления.

Я рекомендую это:

  • Дизайн вашего приложения с уведомлениями.
  • Позвольте пользователю отключить уведомления из настроек приложения.
  • Проверьте, нажимаются ли уведомления. Если пользователь нажимает на уведомление, сохраните его в настройках.
  • Если в вашем приложении включена настройка уведомлений, а пользователь - Android 4.1+ (API 16), но если пользователь не нажимает на уведомления в течение нескольких дней/недель, предположите, что пользователь отключил уведомления.

Не на 100% правильно. Но это дает мнение.
Например, если пользователь не щелкает уведомление о приложении в течение 10-15 дней, возможно, он отключил его.

4
trante