如何正确处理startForegrounds两个通知

时间:2013-08-03 05:00:32

标签: android android-service android-notifications intentservice

我有一个上传文件的IntentService。一切正常,但我对如何处理通知有点困惑。当我开始通知时,我使用startForeground(),因为文件可能相当大,除非绝对必要,否则我不希望上传被杀死。当我使用startForeground()时,它会在通知区域显示两个通知(一个在正在进行,一个在通知下):

Example:

我已经阅读了许多不同的Stack Overflow帖子和网络文章,但没有一个回答我的问题...希望我没有错过任何一个谈论这个问题。

我的理解是,上图中的持续通知(没有进度条的通知)放在那里,因为它在前台运行(Services documentation)。如果你问我,这一切都很好,我理解为什么。但是,我不需要显示两个通知,我很确定大多数人不希望两个通知混乱通知区域。我想知道如何正确处理通知,以便只有一个显示并且不会使通知区域混乱。

我能解决这个问题的唯一方法是,如果我将startForeground (int id, Notification notification)(我的代码中的ONGOING_NOTIFICATION_ID)的整数ID设置为零。但是,我上面引用的文档说:

Caution: The integer ID you give to startForeground() must not be 0

将其设置为0会禁用正在进行的通知,然后只显示进度条的常规通知。我想通过设置.setOngoing(true)直到完成上传文件然后设置.setOngoing(false)一旦完成就可以“解决”这个问题,因此可以将其解除。我不确定将整数ID设置为0对于“谨慎”是多么重要。对我而言,这似乎是一种懒惰的方式来解决我遇到的问题,但我不知道知道是否有其他后果将其设置为0.此外,这只有在我只有一个我正在处理的通知时才有效。如果我有多个不同的通知,那么每个我都需要不同的ID,这不起作用。 更新:它看起来像setting the ID to 0 won't work in Android 4.3,所以现在我回到原点。

绕过显示两种通知的有效方法是什么?

更新/解决方案:Duh,休息一段时间然后回到这里并根据@dsandler的建议仔细检查我所做的事情帮助我弄清楚我做错了什么。我在进行进度更新时没有设置正确的ID,所以这就是为什么它创建两个通知而另一个没有更新。对所有通知使用相同的ID(ONGOING_NOTIFICATION_ID)解决了我的问题。请参阅下面的代码,了解我之前没有包含的其他部分以及我犯错的地方。

UploadFile.java的相关代码:

public class UploadFile extends IntentService {

    private static final int ONGOING_NOTIFICATION_ID = 1;

    @Override
    protected void onHandleIntent(Intent intent) {
        mNotifyManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        mBuilder = new NotificationCompat.Builder(this);
        mBuilder.setContentTitle(getText(R.string.upload))
            .setContentText("0% " + getText(R.string.upload_in_progress))
            .setSmallIcon(android.R.drawable.stat_sys_upload);

        startForeground(ONGOING_NOTIFICATION_ID, mBuilder.build());


....

    if (progress > 0){
        percent = (Long.valueOf(progress) * 100) / totalSize;
        mBuilder.setProgress(100, percent.intValue(), false);
        mBuilder.setContentText(percent.intValue() + "% " + getText(R.string.upload_in_progress));
        mNotifyManager.notify(ONGOING_NOTIFICATION_ID, mBuilder.build()); // <-- My problem was that I had set the ID here to 0 and did not make it the same as the ID I set above
    }                       

....

}

2 个答案:

答案 0 :(得分:2)

首先,根据您的描述判断,您可能能够获得常规服务,认识到内存不足的杀手不会来电,除非设备上的事情变得严峻并且您的服务确实存在已经运行了很长时间。

也就是说,如果您必须使服务成为前台,那么此处的典型策略是使用您将服务置于前台状态时使用的通知来显示您的进度。使用NotificationManager.notify,您可以根据需要发布任意数量的通知,包括通过Notification.Builder.setProgress调整进度条。

通过这种方式,您只向用户显示一条通知,而这是startForeground所需的通知。

答案 1 :(得分:0)

如果要更新startForeground()设置的通知,只需构建一个新的通知,然后使用NotificationManager通知它。

KEY点是使用相同的通知ID。

我没有测试反复调用startForeground()来更新Notification的场景,但我认为使用NotificationManager.notify会更好。

更新通知不会将服务从前台状态中删除(这只能通过调用stopForground来完成);

示例:

private static final int notif_id=1;

@Override
public void onCreate (){
    this.startForeground();
}

private void startForeground() {
        startForeground(notif_id, getMyActivityNotification(""));
}

private Notification getMyActivityNotification(String text){
        // The PendingIntent to launch our activity if the user selects
        // this notification
        CharSequence title = getText(R.string.title_activity);
        PendingIntent contentIntent = PendingIntent.getActivity(this,
                0, new Intent(this, MyActivity.class), 0);

        return new Notification.Builder(this)
                .setContentTitle(title)
                .setContentText(text)
                .setSmallIcon(R.drawable.ic_launcher_b3)
                .setContentIntent(contentIntent).getNotification();     
}
/**
this is the method that can be called to update the Notification
*/
private void updateNotification() {

                String text = "Some text that will update the notification";

                Notification notification = getMyActivityNotification(text);

                NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
                mNotificationManager.notify(notif_id, notification);
}