gpt4 book ai didi

android - 以编程方式取消(和隐藏)Android 通知

转载 作者:太空狗 更新时间:2023-10-29 13:46:08 25 4
gpt4 key购买 nike

我有一个与通知(系统)一起运行的服务。当服务停止(和/或应用程序停止)时,应取消通知(即不再显示在状态栏上)。

正在通过提供 Android Dev guide of Notifications ,我没有找到有关如何关闭通知的任何信息。

去SO,我发现了一些问题。

1.

总结 @nipun.birlaanswer应该如何取消 Android 通知:

取消通知 ,按顺序尝试:

  • NotifcationManager.cancel(int)notificationID
  • NotificationManager.cancel(String, int)notificationIDnotificationTag
  • NotificationManager.cancelAll()作为最后的尝试

  • 但是没有提到的是,如果这些都不起作用,应该怎么做。

    2.

    应该使用 cancelAll suggestion

    3.

    This SO thread包含启动服务示例的一个很好的示例,其中包含在服务生命周期中实现的关联通知(通知也被终止) - 请参阅此处了解 Started Service details

    4.

    Here有人建议删除 PendingIntent与通知相关

    5.

    还有几个问题和解决方案反射(reflect)了上述相同的信息:
    this , 和 this , 还有很多...

    6.

    very interesting question and solution以编程方式在状态栏中隐藏通知图标

    我的问题

    现在应该是相当明显的,我的通知并没有取消自己要求这样做。

    实现:

    完整的实现见下文,虽然我会发布辅助类和核心函数的一般用法

    - 创建通知
    private Context context;
    private NotificationManager notificationManager;
    private NotificationChannel notificationChannel;
    private NotificationCompat.Builder notificationBuilder;

    public NotificationHelper(Context context) {
    this.context = context;

    // Init notification

    // onNotificationCreate()
    {
    // get notification manager system service
    notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    // Create notification channel
    createNotificationChannel();

    //Register notification channel with notification manager
    notificationManager.createNotificationChannel(notificationChannel);
    }

    }

    // Init Notification Builder

    // createNotificationChannel()
    {
    Log.d(TAG, "createNotificationChannel: Creating notification channel");

    // Define notification channel ID, Channel Name and description
    String channelName = BuildConfig.FLAVOR.concat(" Notifier");
    String channelDescription = context.getString(R.string.notification_description);

    // Create notification channel
    notificationChannel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_LOW);
    // Set description of notification channel
    notificationChannel.setDescription(channelDescription);
    }
    }

    这是由 new NotificationHelper(getApplicationContext) 调用的其中上下文是 Application使用的上下文(也用作许多其他功能的上下文)

    我的助手类背后的方法是简单地使用 method chaining允许使用更吸引人的方法来创建、修改和取消通知。

    - NotificationHelper 用法:

    设置通知 contentText调用 setTextContent(String) :
    public NotificationHelper setTextContent(String text){
    notificationBuilder.setContentText(text);
    return this;
    }

    设置 contentTitle通过`setTitle(字符串):
    public NotificationHelper setTitle(String format) {
    notificationBuilder.setContentTitle(format);
    return this;
    }

    并设置 smallIcon (状态图标)通过拨打 setStatusIcon(int) :
    public NotificationHelper setStatusIcon(int res_id) {
    notificationBuilder.setSmallIcon(res_id);
    return this;
    }

    最后,通过以下方式更新通知以显示结果设置:
    public void update() {
    Log.d(TAG, "update: Updating notification");
    Notification notification = notificationBuilder.build();

    // Set notification flags
    notification.flags |= Notification.FLAG_NO_CLEAR;
    notification.flags |= Notification.FLAG_ONGOING_EVENT;
    notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;

    // Notify update
    notificationManager.notify(TAG, notificationId, notification);
    }

    - 取消通知

    正如预期的那样,取消通知就像拨打 cancelNotification() 一样简单。 :
    public void cancelNotification() {
    Log.d(TAG, "cancelNotification: Cancelling notification");
    notificationManager.cancel(TAG, notificationId);
    }

    但是,这对取消通知没有影响。

    通知取消时 ,在取消之前发生了以下情况。
  • 应用程序导出已启动。
  • Bound Service未绑定(bind) - 确保没有客户端绑定(bind)到它。unbindServicegetApplicationContext() 调用在拥有上下文如 unbindService(ServiceConnection)使用相同的 ServiceConnection作为原来的绑定(bind)。

  • 完成所有这些后,通知仍然存在。

    我试过什么
  • notificationManger.cancel(int)
  • notificationManger.cancel(String, int)
  • notificationManger.cancelAll

  • 这不起作用,所以我有创意:

    此外:
    创建一个单独的 NotificationManager发布这些更新的方法(即这里没有设置标志,但使用了相同的 notificationmanager)
    public void updateCancelable() {
    Log.d(TAG, "update: Updating notification to cancel");
    Notification notification = notificationBuilder
    .setContentIntent(null)
    .setOngoing(false)
    .setAutoCancel(true)
    .build();
    // Notify update
    notificationManager.notify(TAG, notificationId, notification);
    }
  • 清除 setContentIntent()调用 setContentIntent(null)并重新通知更新
  • 我也试过创建一个新的通知 cancelablesetAutoCancel(true) ,并设置 ongoing statesetOngoing(false)并重新通知更新

  • 这也没有帮助。有什么我可能会遗漏的吗?

    我还应该提到这一点:在调试我的应用程序时,我注意到当我退出应用程序时(绑定(bind)服务停止并调用 cancelNotification() ,尽管 Android Studio 仍然保持 Activity 的调试 session ,但应用程序绝不应该再运行当应用程序仍在运行时,像人们期望的那样打开。不确定这是否与它有关

    NotificationHelper 类(完整实现)
    import android.app.Notification;
    import android.app.NotificationChannel;
    import android.app.NotificationManager;
    import android.app.PendingIntent;
    import android.content.Context;
    import android.os.Build;
    import android.support.annotation.RequiresApi;
    import android.support.v4.app.NotificationCompat;
    import android.util.Log;

    import com.connectedover.BuildConfig;
    import com.connectedover.R;
    import com.connectedover.listeners.NotificationUpdateListener;

    /**
    * Class aimed at providing helper method for creating, maintaining and destroying notifications in conjunction with {@link de.blinkt.openvpn.core.OpenVPNService}
    *
    * @author cybex
    * @since 1.5.1
    */
    public class NotificationHelper implements NotificationUpdateListener {

    private static final String TAG = NotificationManager.class.getSimpleName();
    private static final String channelId = BuildConfig.APPLICATION_ID.concat(".").concat(TAG);
    private static final int notificationId = 42;

    private Context context;
    private NotificationManager notificationManager;
    private NotificationChannel notificationChannel;

    private NotificationCompat.Builder notificationBuilder;

    public NotificationHelper(Context context) {
    this.context = context;

    // Init notification
    onNotificationCreate();

    // Init Notification Builder
    createBasicNotification();
    }

    /**
    * Initialize {@link NotificationChannel} and register channel with {@link NotificationManager} service if API is Android Orea (API 26 or higher), else initializes the notification manager
    */
    private void onNotificationCreate() {
    Log.d(TAG, "onNotificationCreate: Initializing notification helper");

    // get notification manager system service
    notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
    // Create notification channel
    createNotificationChannel();

    //Register notification channel with notification manager
    notificationManager.createNotificationChannel(notificationChannel);
    }
    }

    /**
    * Creates a notification channel required by devices running Android SDK 26 and higher.
    * The notification channel is set to {@link NotificationManager#IMPORTANCE_LOW} which should have no sound and appear right at the top of the status bar
    */
    @RequiresApi(api = Build.VERSION_CODES.O)
    private void createNotificationChannel() {
    Log.d(TAG, "createNotificationChannel: Creating notification channel");

    // Define notification channel ID, Channel Name and description
    String channelName = BuildConfig.FLAVOR.concat(" Notifier");
    String channelDescription = context.getString(R.string.notification_description);

    // Create notification channel
    notificationChannel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_LOW);
    // Set description of notification channel
    notificationChannel.setDescription(channelDescription);
    }

    /**
    * Creates a basic notification using {@link android.support.v4.app.NotificationCompatBuilder} for use throughout the application
    */
    private void createBasicNotification() {
    // Instantiate Notification Builder
    notificationBuilder = new NotificationCompat
    .Builder(context, channelId)
    .setContentTitle(context.getString(R.string.app_name))
    .setSmallIcon(R.drawable.ic_logo_disconnected)
    .setWhen(System.currentTimeMillis())
    .setAutoCancel(false)
    .setOngoing(true);
    }

    /**
    * Set the pending intent of a clickable {@link android.app.Notification} held by {@link NotificationHelper#notificationBuilder}
    * @param pendingIntent Pending intent to connect to activity
    * @return returns an instance of {@link NotificationHelper}
    */
    public NotificationHelper setPendingIntent(PendingIntent pendingIntent){
    Log.d(TAG, "setPendingIntent: Setting notification Pending intent");
    notificationBuilder.setContentIntent(pendingIntent);
    return this;
    }

    /**
    * Updates the notification which is displayed for the user.
    */
    public void update() {
    Log.d(TAG, "update: Updating notification");
    Notification notification = notificationBuilder.build();

    // Set notification flags
    notification.flags |= Notification.FLAG_NO_CLEAR;
    notification.flags |= Notification.FLAG_ONGOING_EVENT;
    notification.flags |= Notification.FLAG_FOREGROUND_SERVICE;

    // Notify update
    notificationManager.notify(TAG, notificationId, notification);
    }

    /**
    * Updates the notification {@link NotificationHelper#notificationBuilder} with new text and displays it to the user
    *
    * @param text new text to display
    * @return returns current {@link NotificationHelper} instance for method chaining.
    */
    public NotificationHelper setTextContent(String text){
    notificationBuilder.setContentText(text);
    return this;
    }

    @Override
    public void onUpdate(String update) {
    Log.d(TAG, "onUpdate: updating notification via callback");
    this.setTextContent(update)
    .update();
    }

    /**
    * Sets a new icon for the notification displayed to the user
    * @param res_id icon resource
    * @return current instance
    */
    public NotificationHelper setLargeIcon(int res_id) {
    notificationBuilder.setLargeIcon(ImageUtils.toBitmap(context, res_id));
    return this;
    }

    /**
    * Sets a new icon for the notification displayed to the user show in the status bar (i.e. the small icon)
    * @param res_id icon resource
    * @return current instance
    */
    public NotificationHelper setStatusIcon(int res_id) {
    notificationBuilder.setSmallIcon(res_id);
    return this;
    }

    public NotificationHelper setTitle(String format) {
    notificationBuilder.setContentTitle(format);
    return this;
    }

    /**
    * Cancels the application notification
    */
    public void cancelNotification() {
    Log.d(TAG, "cancelNotification: Cancelling notification");
    notificationManager.cancelAll();
    }
    }

    最佳答案

    如果您想使用您的 Notification作为前台服务的一部分,不要直接操作标志,使用 startForeground()stopForeground()在您的 Service .

    关于android - 以编程方式取消(和隐藏)Android 通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54066289/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com