7

キャンセルも可能な通知バーにファイルの複数のダウンロードを表示できるようにしたいと思います。

AsyncTasksを使用して複数のダウンロードを並行して実行するカスタムサービスを実装しました。OnPublishProgress通知バーの個々の行を更新して、各ファイルのダウンロードの進行状況を表示しようとしています。私は2日間、行のちらつき、順序の入れ替え、場合によっては空白または1行のみの更新の問題を修正しようとしてきました。また、行をタップしてルーチンをキャンセルしても、常に機能するとは限りません。

これが私のコードです:

    protected void showProgressNotification(final File item, int progress, boolean isDownloading) {
    String message = null;
    int smallIcon = 0;
    Bitmap largeIcon = null;
    int flags = 0;
    flags |= Notification.FLAG_ONGOING_EVENT; 
    //flags |= Notification.FLAG_FOREGROUND_SERVICE;
    //flags |= Notification.FLAG_ONLY_ALERT_ONCE;
    //flags |= Notification.FLAG_AUTO_CANCEL; 

    NotificationCompat.Builder builder =
            new NotificationCompat.Builder(getApplicationContext());
    builder.setAutoCancel(true);

    if (progress == 100) {
        largeIcon = BitmapFactory.decodeResource(getResources(),
                O2FolderListAdapter.getIconForItem(item, false));
        smallIcon = R.drawable.ic_cloud_upto_date;

        if (isDownloading) {
            message = "Download completed. Tap to clear.";
        } else {
            message = "Upload completed. Tap to clear.";
        }
    } else if (progress >= 0) {
        largeIcon = BitmapFactory.decodeResource(getResources(),
                O2FolderListAdapter.getIconForItem(item, true));
        if (isDownloading) {
            smallIcon = R.drawable.ic_cloud_downloading;
            message = "Downloading: " + progress + "%. Tap to cancel.";
        } else {
            smallIcon = R.drawable.ic_cloud_uploading;
            message = "Uploading: " + progress + "%. Tap to cancel.";
        }
        builder.setProgress(100, progress, false);
    } else {
        largeIcon = BitmapFactory.decodeResource(getResources(),
                O2FolderListAdapter.getIconForItem(item, true));
        smallIcon = R.drawable.ic_cloud_conflict;
        if (isDownloading)
            message = "Cancelled download. Tap to clear.";
        else
            message = "Cancelled upload. Tap to clear.";
    }

    if (mResultIntent == null) {
        mResultIntent = new Intent(getApplicationContext(), CustomDownloadService.class);
        mResultIntent.addFlags(Notification.FLAG_ONGOING_EVENT);
    }
    mResultIntent.putExtra("cancel", item.getPath().hashCode());
    Log.d("O2AbstractDownloadService", "Setup task id " + item.GetPath().hashCode());
    if (mContentIntent == null)
        mContentIntent = PendingIntent.getService(getApplicationContext(), PI_REQ_CODE, mResultIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    builder.setContentIntent(mContentIntent);

    builder.setLargeIcon(largeIcon);
    builder.setSmallIcon(smallIcon);
    builder.setContentTitle(item.GetName());
    builder.setContentText(message);

    //if (progress != 100)
        //builder.addAction(R.drawable.ic_action_dark_cancel, "Cancel", contentIntent);

    final Notification notification = builder.build();
    notification.flags = flags;
    notification.defaults = Notification.DEFAULT_LIGHTS;

    NotificationManager mNotificationManager =
        (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    // Id allows you to update the notification later on.
    //mNotificationManager.notify(item.getPath().hashCode(), notification);
    //startForeground(item.getPath().hashCode(), notification);

    // only update notification every 100ms (unless cancel or complete)
    long notificationDelay = 100;
    long now = System.currentTimeMillis();
    if (mFutureCallTime == 0 || now > mFutureCallTime || progress == -1 || progress == 100) {
        startForeground(item.getPath().hashCode(), notification);
            //mNotificationManager.notify(item.GetPath().hashCode(), notification);
    } else
        Log.d("CustomDownloadService", "Called too often to notification");

    mFutureCallTime = now + notificationDelay;
}

そのため、通知をタップしたときにサービスを呼び出すアクションを設定し、ファイルのIDを渡してダウンロードをキャンセルしようとしています。誰かが私が間違っていることを見ることができますか?私が実際に求めていることは可能ですか?Xoomタブレットでは通知が頻繁に点滅しますが、Nexus 7ではそれほど頻繁ではありません。すべてのデバイスで行が頻繁に入れ替わるため、必要なダウンロードをキャンセルすることは事実上不可能です。

アドバイスをいただければ幸いです。

更新1:これが私の問題の1つを引き起こしている可能性があると思います: AndroidService.startForegroundは通知IDの一意性を尊重しません

更新2: builder.setWhen(fixedTime)を呼び出すことにより、スワップアウトの問題が修正されました。明らかに、新しいdateTimeにより、更新されるたびに行が並べ替えられていました。Xoomのちらつきと「タップしてキャンセル」機能を修正する必要があります。

更新3: Xoomのちらつきは、更新の呼び出しを制限することで修正されました。最後のコードは、通知が100ミリ秒に2回以上更新されるのを防ぎます。残りの問題はキャンセルに関係しています。キャンセルするためのタップは最初は機能しますが、それ以降のファイルでは機能しません。また、行をクリアできません。

更新4:単一のキャンセルの問題は、resultIntentフィールドがクラスレベルであることが原因でした。通知を更新するたびに新しいIDを作成すると、IDが拘束されました。また、フラグをNotification.FLAG_ONLY_ALERT_ONCEのみに変更し、.notify()のみを使用し、startForeground()は使用しませんでした。

4

1 に答える 1

2

すべての問題が修正されました。元の投稿に更新を追加しました。要約:1)builder.setWhen(fixedTime)に注意してください。2)100msごとに2回以上更新しないでください。3)正しいフラグを設定してください。

于 2013-03-13T13:42:31.017 に答える