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

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

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

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

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

Ответ 1

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

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


Изменить

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

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

введите описание изображения здесь

Ответ 2

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

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

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

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

Ответ 4

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

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

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

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

Ответ 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;
    }
}