9

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

例子:

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

据我了解,上图中的持续通知(没有进度条的通知)被放在那里,因为它在前台运行(服务文档)。如果你问我,那很好,我明白为什么。但是,我不需要显示两个通知,而且我很确定大多数人也不希望两个通知弄乱通知区域。我想知道如何正确处理通知,以便只显示一个通知并且不会弄乱通知区域。

我能够解决这个问题的唯一方法是将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,这将不起作用。更新:看起来将 ID 设置为 0 won',所以现在我回到第一方。

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

更新/解决方案: 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
    }                       

....

}
4

2 回答 2

2

首先,根据您的描述,您可能能够摆脱常规服务,认识到内存不足的杀手不会来电话,除非设备上的事情变得很糟糕并且您的服务确实一直在运行很长时间。

也就是说,如果您必须将服务置于前台,这里的典型策略是使用您将服务置于前台状态时使用的通知来显示您的进度。使用NotificationManager.notify您可以发布任意数量的通知更新,Notification.Builder.setProgress例如通过 调整进度条。

这样,您只向用户显示一个通知,这是startForeground.

于 2013-08-05T05:24:41.447 回答
0

当您想更新由 startForeground() 设置的通知时,只需构建一个新通知,然后使用 NotificationManager 通知它。

关键点是使用相同的通知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);
}
于 2013-11-22T10:43:04.750 回答