¿Cómo verifico si mi aplicación puede publicar notificaciones?

6 minutos de lectura

Avatar de usuario de Yunpeng Lee
Yun Peng Lee

Los usuarios pueden desactivar las notificaciones de aplicaciones individuales en la configuración de Android. ¿Hay un método como isNotificationsAllowed() que me permite verificar si mi aplicación puede publicar notificaciones? Además, ¿cómo abro la pantalla de configuración de Android para guiar a mis usuarios a activar las notificaciones?

  • Esto podría ayudarte: stackoverflow.com/questions/24145343/…

    – El Tánico

    7 de enero de 2015 a las 9:16

  • Posible duplicado de Android 4.1: ¿Cómo comprobar que las notificaciones están deshabilitadas para la aplicación?

    – sam

    9 de enero de 2017 a las 20:23

  • Puede consultar mi respuesta aquí stackoverflow.com/a/57769424/4655711 Se aplica la misma solución.

    – ljtomev

    3 sep 2019 a las 10:32

Avatar de usuario de Kasra
kasra

EDITAR – Nueva respuesta:

Parece que Google agregó la llamada API adecuada:
NotificationManagerCompat.from(context).areNotificationsEnabled()


RESPUESTA ANTIGUA:

Para cualquiera que esté viendo esta pregunta, tenga en cuenta que NotificationListenerService es diferente de “Mostrar notificación”. Estos dos son cosas diferentes! Si una aplicación tiene acceso a NotificationListenerService no significa que se muestren sus notificaciones y viceversa. Para verificar si el usuario ha bloqueado la notificación de su aplicación o no, puede usar la reflexión:

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() {

    AppOpsManager mAppOps = (AppOpsManager) GlobalContext.getContext().getSystemService(Context.APP_OPS_SERVICE);

    ApplicationInfo appInfo = GlobalContext.getContext().getApplicationInfo();

    String pkg = GlobalContext.getContext().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;
}
}

Fuente: https://code.google.com/p/android/issues/detail?id=38482

  • AppOpsManager se agregó en el nivel de API 19 (Android 4.4), por lo que solo se puede usar para el nivel de API 19+

    – nibario

    8 de diciembre de 2016 a las 8:32

  • @nibarius Sí, tienes razón. Pero: a partir de 4.4, los usuarios pueden eliminar la notificación en el nivel de la aplicación. Entonces, debajo de 4.4, es seguro asumir que las notificaciones están habilitadas (a menos que se ejecute en una ROM manipulada)

    – Kasra

    20 de diciembre de 2016 a las 17:28

  • @Kasra Acabo de probar con un Samsung Galaxy Grand que ejecuta Android 4.2.2 y también puedo eliminar las notificaciones en el nivel de la aplicación. Esta pregunta SO también dice que se puede hacer en el nivel de la aplicación desde 4.1: stackoverflow.com/questions/11649151/…

    – nibario

    19 de enero de 2017 a las 13:56

  • @nibarius mi culpa. 4.1-4.4 es donde las cosas se vuelven un poco borrosas. Por favor, vea mi respuesta actualizada. Si observa el código fuente de NotificationManagerCompat.from(context).areNotificationsEnabled(), verá que usa una lógica diferente para cada versión de Android (también usa AppOpsManager internamente). De todos modos, esta debería ser la forma más confiable, ya que está hecha por el equipo de Android.

    – Kasra

    19 de enero de 2017 a las 20:12


  • Hola @kasra, este método funciona bien menos que Android 8. pero este método siempre se vuelve verdadero en el último Android-8 (Android – Oreo).

    – shyam.y

    20 de septiembre de 2017 a las 11:34

NotificationManagerCompat.from(context).areNotificationsEnabled()

parece un camino a seguir.

  • Probé esto cambiando manualmente los permisos de notificaciones en la configuración y funcionó bien, el valor booleano se devolvió correctamente en ambos casos. Gran solución de una sola línea. Y justo a tiempo … Estaba buscando la solución solo unas pocas horas después de que se publicó esta respuesta … muy buen momento 🙂 ¡Gracias!

    – Gen Bo

    28 de octubre de 2016 a las 1:51


  • @gnB genial! me alegro de que haya ayudado 😉

    – asamoylenko

    31 de octubre de 2016 a las 11:18

  • NotificationManagerCompat.From(contexto).AreNotificationsEnabled();

    – Gerry

    9 de julio de 2018 a las 20:23

Aquí hay una respuesta más completa a esta pregunta.

fun areNotificationsEnabled(context: Context, channelId: String = "fcm_fallback_notification_channel"): Boolean {
    // check if global notification switch is ON or OFF
    if (NotificationManagerCompat.from(context).areNotificationsEnabled())
        // if its ON then we need to check for individual channels in OREO
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val manager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            val channel = manager.getNotificationChannel(channelId)
            return channel?.importance != NotificationManager.IMPORTANCE_NONE
        } else {
            // if this less then OREO it means that notifications are enabled
            true
        }
    // if this is less then OREO it means that notifications are disabled
    return false
}

avatar de usuario de adurian
aduriano

Prueba esto:

¿Hay alguna forma en que una aplicación pueda comprobar si tiene permiso para acceder a las notificaciones?

Y hay un poco más de explicación aquí:

Verifique el acceso a las notificaciones usando NotificationListenerService

if(NotificationManagerCompat.from(context).areNotificationsEnabled())
{
 //Do your Work
}
else
{
     //Ask for permission
}

Avatar de usuario de Anand Nishad
Anand Nishad

public class MainActivity extends AppCompatActivity {

   @Override
   protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);

//Main Code Below-
//NotificationManagerCompat.from(context).areNotificationsEnabled()
       if(NotificationManagerCompat.from(this).areNotificationsEnabled())
       {
           Toast.makeText(this, "Notification is on for this Application", Toast.LENGTH_SHORT).show();
       }
       else
       {
           Toast.makeText(this, "Notification is off for this Application", Toast.LENGTH_SHORT).show();
       }
   }

}

2023-03-18: Android 13 (SDK 33 TIRAMISU) ha introducido un nuevo permiso de tiempo de ejecución (android.permiso.POST_NOTIFICACIONES) para que la aplicación publique notificaciones (lo que estaba permitido de forma predeterminada antes de Android 13).

Si el SDK de destino de su aplicación es inferior a 33 y se ejecuta en un dispositivo con Android 13, la primera vez que el usuario abra el sistema de su aplicación solicitará automáticamente este permiso, entonces depende del usuario decidir si su aplicación puede publicar notificaciones.

Si su aplicación se dirige a SDK 33 y en ejecución y dispositivo Android 13, la notificación de publicación es NO PERMITIDO por defecto, hasta que lo solicite explícitamente y el usuario lo permita.

Y tenga en cuenta que el usuario puede permitir que su aplicación publique notificaciones, pero mientras tanto deshabilita un canal de notificación específico, por lo tanto, no es lo suficientemente bueno para probar solo si se otorga el permiso, sino que también debe probar si el canal de notificación está habilitado.

A continuación se muestra una función de ayuda de muestra (en Kotlin) para verificar si se permite la notificación:

fun isPermissionGranted(context: Context, permission: String): Boolean =
    ActivityCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED

fun isNotificationAllowed(context: Context, channelId: String? = null): Boolean {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        if (!isPermissionGranted(Manifest.permission.POST_NOTIFICATIONS)) return false
    }
    if (!NotificationManagerCompat.from(context).areNotificationsEnabled()) return false

    if (channelId == null) return true
    runCatching {
        val mgr = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        val channel = mgr.getNotificationChannel(channelId)
        return channel.importance != NotificationManager.IMPORTANCE_NONE
    }
    return false
}

¿Ha sido útil esta solución?