避免取消从最近的应用程序列表中删除应用程序的通知

Avoid cancelation of Notification on removing app from recent apps list

我正在使用下面的代码片段来显示来自我的应用内服务的通知:

NotificationCompat.Builder mBuilder =
        new NotificationCompat.Builder(this)
                .setSmallIcon(R.drawable.ic_launcher)
                .setContentTitle(currentNotificaion.getMessageTitle())
                .setContentIntent(contentIntent)
                .setContentText(currentNotificaion.getMessageText())
                .setAutoCancel(true);
int mNotificationId = (int) currentNotificaion.getMessageServerID();
// Gets an instance of the NotificationManager service
NotificationManager mNotifyMgr =
        (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
// Builds the notification and issues it.
mNotifyMgr.notify(mNotificationId, mBuilder.build());

我的服务在清单中是这样声明的:

<service
android:name="com.myapp.services.NotificationService"
android:stopWithTask="false">
</service>

但是当我从最近的应用程序列表中关闭我的应用程序时,通知会消失并从通知栏中删除。另一件事是我不会使用永远不会从通知栏中删除的棒通知。

我怎样才能避免这种情况?

 .setAutoCancel(true);

让我们将其设置为 false,这样通知就不会被取消也不会被删除。 你也可以放

.setOngoing(true)

更新: 如果以上不起作用,并且当服务发送通知时,您需要调用

 startForeground(int, Notification) 

为了在应用程序被杀死时不杀死服务。

来自 Android 文档:

A started service can use the startForeground(int, Notification) API to put the service in a foreground state, where the system considers it to be something the user is actively aware of and thus not a candidate for killing when low on memory.

更多可以在这里找到: Android Service startForeground

在您的清单文件中,将服务的标志 stopWithTask 保持为 true。喜欢:

<service
    android:name="com.myapp.MyService"
    android:stopWithTask="true" />

我刚刚解决了类似的问题。

如果只是在通过从最近的应用程序列表中滑动而终止应用程序时停止服务,您可以执行以下操作。

  1. 在您的清单文件中,将服务的标志 stopWithTask 保持为 true。喜欢:

但是正如您所说,您想要注销监听器并停止通知等,我建议采用这种方法:

Inside your Manifest file, keep flag stopWithTask as false for Service. Like:

    <service
        android:name="com.myapp.MyService"
        android:stopWithTask="false" />
  1. 现在在您的 MyService 服务中,覆盖方法 onTaskRemoved。 (仅当 stopWithTask 设置为 false 时才会触发)。

    public void onTaskRemoved(Intent rootIntent) {
    
    //unregister listeners
    //do any other cleanup if required
    
    //stop service
        stopSelf();  
    }
    

希望对您有所帮助。

如果你想在你的应用程序被杀死后显示你的通知,我建议这样做。

正如所写 当应用程序从设备中被终止时,您可以捕获该事件。

<service
        android:name="com.myapp.MyService"
        android:stopWithTask="false" />

内部服务

public void onTaskRemoved(Intent rootIntent) {
//your code
//stop service
    stopSelf();  
}

但是,在此代码中,您可以收取 AlarmManager 以在几秒钟后重新启动您自己的通知。 把这个放在里面 onTaskRemoved:

AlarmManager am = (AlarmManager) ctx.getSystemService(Activity.ALARM_SERVICE);
Intent intent = new Intent(BRNotificator.INTENT_FILTER);
int somealarmnumber = 10000;//or any numbe your want
long nexttime = System.currentTimeInMillis() + 5000L;
PendingIntent pi =PendingIntent.getBroadcast(ctx, somealarmnumber, intent, PendingIntent.FLAG_CANCEL_CURRENT):
am.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, nexttime, pi);

广播接收者在哪里:

public class BRNotificator extends WakefulBroadcastReceiver {
    public static final String INTENT_FILTER = "com.example.BRNotificator";
    @Override
    public void onReceive(Context ctx, Intent intent) {
//restart your service this notification
        OWakeLocker.acquire(ctx, 0);
        ComponentName comp = new ComponentName(ctx.getPackageName(),
                YourServiceClass.class.getName());
        startWakefulService(ctx, intent.setComponent(comp));

//or just show your notification again:
NotificationCompat.Builder mBuilder = //... your code to show
    }

}

这是一个可以帮助唤醒您的设备的助手:

public class OWakeLocker {
    private static PowerManager.WakeLock[] wakeLocks = new PowerManager.WakeLock[1];//Services count

    @SuppressWarnings("deprecation")
    public static void acquire(Context ctx, int index) {
        WakeLock wakeLock = wakeLocks[index];
        if (wakeLock != null) wakeLock.release();

        PowerManager pm = (PowerManager) ctx.getSystemService(Context.POWER_SERVICE);
            wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK |
                    PowerManager.ACQUIRE_CAUSES_WAKEUP |
                    PowerManager.ON_AFTER_RELEASE, _.APPNAME + Integer.toString(index));
        if (wakeLock != null && wakeLock.isHeld()){
            wakeLock.acquire();
        }
    }

    public static void release(int index) {
        WakeLock wakeLock = wakeLocks[index];
        if (wakeLock != null) 
            wakeLock.release();
            wakeLock = null;
    }
}

如果你想要一个后台服务运行一个前台通知,最好的方法是使用startForeground()函数。您可以查看来自@CommonsWare 的 Android 文档 here and there are some answers about it in SO also like this,其中包含示例。

希望对您有所帮助!

你甚至可以

public static void clearNotifications(Context context) {
    NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
    notificationManager.cancelAll();
}