40

In Android settings users can turn off notification if they don't want to. So is there any method that like isNotificationAllowed() to check is my app is allowed to show notification? And how to open android setting page to guide my users to turn on notification?

Vikasdeep Singh
  • 19,490
  • 9
  • 75
  • 99
Yunpeng Lee
  • 425
  • 1
  • 4
  • 6
  • This could help you: http://stackoverflow.com/questions/24145343/checking-android-system-security-notification-access-setting-programmatically – TheTanic Jan 07 '15 at 09:16
  • 3
    Possible duplicate of [Android 4.1: How to check notifications are disabled for the application?](http://stackoverflow.com/questions/11649151/android-4-1-how-to-check-notifications-are-disabled-for-the-application) – Sam Jan 09 '17 at 20:23
  • You can checkout my answer here https://stackoverflow.com/a/57769424/4655711 The same solution applies. – ljtomev Sep 03 '19 at 10:32

7 Answers7

92

EDIT - New Answer:

Seems like google added the proper API call: NotificationManagerCompat.from(context).areNotificationsEnabled()


OLD ANSWER:

For anyone who is looking at this question, note that NotificationListenerService is different from "Show Notification". These two are different things! If an app has access to NotificationListenerService does not mean that its notifications are shown and vice versa. In order to check if user has blocked notification from your app or not, you can use reflection:

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

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

Kasra
  • 2,895
  • 2
  • 15
  • 32
  • AppOpsManager was added in API level 19 (Android 4.4), so this can only be used for API level 19+ – nibarius Dec 08 '16 at 08:32
  • @nibarius Yes, you are correct. But: starting 4.4 users are allowed to kill the notification on app level. So below 4.4, it is safe to assume that notifications are enabled (unless running on a tampered ROM) – Kasra Dec 20 '16 at 17:28
  • @Kasra I just tested with a Samsung Galaxy Grand which runs Android 4.2.2 and I can kill notifications on the app level there as well. This SO question also say that it can be done on the app level from 4.1: http://stackoverflow.com/questions/11649151/android-4-1-how-to-check-notifications-are-disabled-for-the-application – nibarius Jan 19 '17 at 13:56
  • 1
    @nibarius my bad. 4.1-4.4 is where things get a bit blurry. Please see my updated answer. If you look into the source code for NotificationManagerCompat.from(context).areNotificationsEnabled(), you will see that it uses a different logic for each android version (it uses AppOpsManager internally as well). Anyways, this should be the most reliable way as it's made by android team. – Kasra Jan 19 '17 at 20:12
  • Hi @kasra, this method is working fine less than Android 8. but this method is always returning true in latest android-8(Android - Oreo). – sham.y Sep 20 '17 at 11:34
54
NotificationManagerCompat.from(context).areNotificationsEnabled()

seems like a way to go.

asamoylenko
  • 1,757
  • 2
  • 15
  • 12
  • I tested this by manually changing the notifications permissions in settings and it worked fine, boolean was returned correctly in both cases. Great one-line solution. And just in time .. I was searching for the solution only a few hours after this answer was posted .. so good timing :) Thanks! – Gene Bo Oct 28 '16 at 01:51
  • @gnB nice! glad it helped ;) – asamoylenko Oct 31 '16 at 11:18
  • NotificationManagerCompat.From(context).AreNotificationsEnabled(); – Gerry Jul 09 '18 at 20:23
9

Here is more complete answer to this question

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
}
Abhishek Bansal
  • 5,039
  • 3
  • 39
  • 66
0

Try this:

Is there a way an app can check if it is allowed to access notifications?

And there's a bit more explaination here:

Check for access to notifications using NotificationListenerService

Community
  • 1
  • 1
adurian
  • 43
  • 4
0

Try this:

if (Settings.Secure.getString(getActivity().getContentResolver(), "enabled_notification_listeners").contains(getActivity().getPackageName())) {
    // Notification access service already enabled
    Toast.makeText(getActivity(),"notification enabled",Toast.LENGTH_LONG).show();
} else {
    Intent intent = new Intent();
    intent.setClassName("com.android.settings", "com.android.settings.Settings$AppNotificationSettingsActivity");
    intent.putExtra("app_package", getPackageName());
    intent.putExtra("app_uid", getApplicationInfo().uid);
    startActivity(intent);
}
0
if(NotificationManagerCompat.from(context).areNotificationsEnabled())
{
 //Do your Work
}
else
{
     //Ask for permission
}
0
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();
       }
   }

}
  • Your answer could be improved with additional supporting information. Please [edit] to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers [in the help center](/help/how-to-answer). – Community Jun 03 '22 at 11:55