如何在安卓中以编程方式打开/关闭“显示通知”功能

4

我有一个需求,需要在应用信息中通过编程方式启用/禁用“显示通知”。我搜索了很长时间,但没有找到合适的解决方案。在Android中是否有可能通过编程方式打开/关闭“显示通知”?谢谢。

enter image description here

1
你的意思是只从你的应用程序启用/禁用通知,还是从整个设备启用/禁用? - OShiffer
1
是的,@OShiffer你是正确的。 - Vinod Pattanshetti
@VinodPattanshetti 但是你想要什么?只是你的应用程序通知还是整个设备的通知? - Bruno Bieri
这与我预期的不同。 - Vinod Pattanshetti
你正在使用哪个服务来显示通知?闹钟管理器吗? - Pavel Poley
显示剩余3条评论
4个回答

5

实际上,目前没有办法通过程序来开启/关闭通知,我们唯一的方法是使用以下代码:

public class CustomToast {

  private static final String CHECK_OP_NO_THROW = "checkOpNoThrow";
  private static final String OP_POST_NOTIFICATION = "OP_POST_NOTIFICATION";

  public static void makeText(Context mContext, String message, int time) {
    if (isNotificationEnabled(mContext)) {
      //Show Toast message 
      Toast.makeText(mContext, message, time).show();
    } else {
      // Or show own custom alert dialog
      showCustomAlertDialog(mContext, message);
    }
  }

  private static boolean isNotificationEnabled(Context mContext) {
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
      AppOpsManager mAppOps = (AppOpsManager) mContext.getSystemService(Context.APP_OPS_SERVICE);
      ApplicationInfo appInfo = mContext.getApplicationInfo();
      String pkg = mContext.getApplicationContext().getPackageName();
      int uid = appInfo.uid;
      Class appOpsClass;
      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 | NoSuchMethodException | NoSuchFieldException
          | InvocationTargetException | IllegalAccessException ex) {
        Utils.logExceptionCrashLytics(ex);
      }
      return false;
    } else {
      return false;
    }
  }

  private static void showCustomAlertDialog(Context mContext, String message) {
      if (!(mContext instanceof Activity && ((Activity)mContext).isFinishing())) {
          AlertDialog.Builder mBuilder = new AlertDialog.Builder(mContext);
          mBuilder.setMessage(message);
          mBuilder.setPositiveButton(mContext.getString(R.string.ok),
                  new DialogInterface.OnClickListener() {
                      @Override
                      public void onClick(DialogInterface dialog, int which) {
                          dialog.dismiss();
                      }
                  });
          mBuilder.setCancelable(true);
          AlertDialog alertDialog = mBuilder.create();
          alertDialog.show();
      }
    }
}

1

在您的应用程序中发布通知之前,您需要保留一个布尔标志并进行检查。将该布尔标志保存在SharedPreferences中。一旦用户或您的应用程序禁用/启用通知,就要在SharedPreferences中反映出来。

此外,您可以创建一个实用程序类来发布通知,以便您不必在许多不同的位置添加检查。

public class NotificationUtil {

    public static void showNotification(
            Context context,
            int notificationId,
            int iconId,
            Class parentStackClass,
            String notificationTitle,
            String notificationText
    ) {
        boolean showNotification = PreferenceManager
                .getDefaultSharedPreferences(context)
                .getBoolean("SHOW_NOTIFICATION", true);

        if (!showNotification) return;

        android.support.v4.app.NotificationCompat.Builder mBuilder =
                new NotificationCompat.Builder(context)
                        .setSmallIcon(iconId)
                        .setContentTitle(notificationTitle)
                        .setContentText(notificationText);

        Intent resultIntent = new Intent(context, parentStackClass);


        TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
        stackBuilder.addParentStack(parentStackClass);
        stackBuilder.addNextIntent(resultIntent);
        PendingIntent resultPendingIntent =
                stackBuilder.getPendingIntent(
                        0,
                        PendingIntent.FLAG_UPDATE_CURRENT
                );
        mBuilder.setContentIntent(resultPendingIntent);

        NotificationManager mNotificationManager =
                (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

        mNotificationManager.notify(notificationId, mBuilder.build());
    }

}

请查看我附加的屏幕截图。在那里,我如何通过编程启用/禁用“显示通知”? - Vinod Pattanshetti

1
我们无法通过编程打开或关闭通知。我们可以使用以下片段检查通知的状态。
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
     AppOpsManager mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
     ApplicationInfo appInfo = context.getApplicationInfo();
     String pkg = context.getApplicationContext().getPackageName();
     int uid = appInfo.uid;
     Class appOpsClass;
     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 | NoSuchMethodException | NoSuchFieldException
         | InvocationTargetException | IllegalAccessException ex) {
       Utils.logExceptionCrashLytics(ex);
     }
     // checked
   } else {
     // unchecked
   }

-4

你可以将它保存在SharedPreferences中,每次您想要显示通知时,您都可以检查它。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接