如何检查我的应用程序是否允许发布通知?

问题描述 投票:0回答:9

用户可以在 Android 设置中关闭各个应用程序的通知。有没有像

isNotificationsAllowed()
这样的方法可以让我检查我的应用程序是否允许发布通知?另外,如何打开 Android 设置屏幕来引导我的用户打开通知?

android notifications android-notifications
9个回答
108
投票

编辑 - 新答案:

似乎谷歌添加了正确的 API 调用:

NotificationManagerCompat.from(context).areNotificationsEnabled()


旧答案:

对于任何正在查看此问题的人,请注意,NotificationListenerService 与“显示通知”不同。 这两个是不同的东西!如果应用程序有权访问

NotificationListenerService
并不意味着会显示其通知,反之亦然。为了检查用户是否阻止了您的应用程序的通知,您可以使用反射:

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

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


66
投票
NotificationManagerCompat.from(context).areNotificationsEnabled()

似乎是一条路要走。


12
投票

这是这个问题更完整的答案

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
}


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

}

0
投票

2023-03-18:Android 13 (SDK 33 TIRAMISU) 引入了新的运行时权限 (android.permission.POST_NOTIFICATIONS),供应用程序发布通知(Android 13 之前默认允许)。

如果您的应用的目标 SDK 低于 33 并且在 Android 13 设备上运行,用户第一次打开您的应用系统将自动请求此权限,然后由用户决定是否允许您的应用发布通知。

如果您的应用面向 SDK 33 并运行 Android 13 设备,则默认情况下不允许发布通知,直到您明确请求且用户允许。

请注意,用户可能允许您的应用程序发布通知,但同时禁用特定的通知通道,因此仅测试是否授予权限是不够的,还需要测试通知通道是否启用。

下面是一个示例辅助函数(Kotlin 中),用于检查是否允许通知:

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
}

0
投票
fun Context.areNotificationsEnabled(): Boolean {
    return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
        ContextCompat.checkSelfPermission(
            this,
            Manifest.permission.POST_NOTIFICATIONS,
        ) == PackageManager.PERMISSION_GRANTED
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val manager =
            this.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        if (!manager.areNotificationsEnabled()) {
            return false
        }
        val channels = manager.notificationChannels
        for (channel in channels) {
            if (channel.importance == NotificationManager.IMPORTANCE_NONE) {
                return false
            }
        }
        true
    } else {
        NotificationManagerCompat.from(this).areNotificationsEnabled()
    }
}

-1
投票

试试这个:

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);
}
© www.soinside.com 2019 - 2024. All rights reserved.