从最近的应用列表中删除应用时,请避免取消通知

时间:2016-10-21 09:14:07

标签: android notifications android-service

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

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>

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

我该如何避免这种情况?

5 个答案:

答案 0 :(得分:5)

在Manifest文件中,将service stopWithTask保持为true。像:

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

我刚解决了类似的问题。

如果通过从最近的应用列表中滑动来杀死应用程序,那么您可以执行以下操作。

  1. 在Manifest文件中,将service stopWithTask标记为true。像:

  2. 但正如你所说,你想取消注册听众并停止通知等,我建议采用这种方法:

    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();  
      }
      
    2. 希望它会对你有所帮助。

答案 1 :(得分:4)

如果您希望后台服务与前台通知一起运行,最好的方法是使用startForeground()函数。您可以查看Android文档here,并在SO中有一些答案,例如来自@CommonsWare的this,其中包含示例。

希望它有所帮助!

答案 2 :(得分:2)

如果您想在申请被杀后显示通知,我会建议您这样做。

正如写@JamilHasnineTamim,您可以在应用程序从设备中被杀死时捕获该事件。

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

答案 3 :(得分:0)

你甚至可以

- name: Configuring Auto Scaling Group and perform rolling deploy
  ec2_asg:
    region: "ap-southeast-1a"
    name: "MY-ASG"
    vpc_zone_identifier: [ "{{ services_1_subnet_id }}", "{{ services_2_subnet_id }}" ]
    launch_config_name: "{{ service_group }}-{{ current_datetime }}"
    health_check_type: "{{ health_check_type }}"
    health_check_period: "{{ health_check_period }}"
    desired_capacity: "{{ min_instances }}"
    replace_all_instances: yes
    replace_batch_size: "{{ replace_batch_size }}"
    min_size: "{{ min_instances }}"
    max_size: "{{ max_instances }}"
    wait_for_instances: yes
    wait_timeout: 600
    tags:
      - Name: "{{ service_group }}"
      - deploy_colour: "{{ deploy_colour }}"
      - Type: "ABC"
      - Env: "{{ env }}"
    state: present
  register: asg_result

答案 4 :(得分:-1)

 .setAutoCancel(true);

我们将此设置为false,因此通知不会被取消而不会被删除。 你也可以把

.setOngoing(true)

<强>更新 如果以上不起作用,并且从服务发送通知,则需要致电

 startForeground(int, Notification) 

为了在app被杀死时不杀死服务。

来自Android文档:

  

已启动的服务可以使用startForeground(int,Notification)API将服务置于前台状态,系统认为该服务是用户主动了解的内容,因此在内存不足时不会成为查杀的候选者

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