/*************************************************************************** * Copyright 2006-2016 by Christian Ihle * * contact@kouchat.net * * * * This file is part of KouChat. * * * * KouChat is free software; you can redistribute it and/or modify * * it under the terms of the GNU Lesser General Public License as * * published by the Free Software Foundation, either version 3 of * * the License, or (at your option) any later version. * * * * KouChat is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * * Lesser General Public License for more details. * * * * You should have received a copy of the GNU Lesser General Public * * License along with KouChat. * * If not, see <http://www.gnu.org/licenses/>. * ***************************************************************************/ package net.usikkert.kouchat.android.notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.support.v7.app.NotificationCompat; import net.usikkert.kouchat.android.R; import net.usikkert.kouchat.android.controller.ReceiveFileController; import net.usikkert.kouchat.android.service.CancelFileTransferService; import net.usikkert.kouchat.android.settings.AndroidSettings; import net.usikkert.kouchat.net.FileReceiver; import net.usikkert.kouchat.net.FileTransfer; import net.usikkert.kouchat.util.Validate; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; /** * Service for handling file transfer notifications. * * @author Christian Ihle */ public class FileTransferNotificationService { private static final int FILE_TRANSFER_NOTIFICATION_ID = 10000; private final Context context; private final NotificationManager notificationManager; private final NotificationHelper notificationHelper; private final Set<Integer> currentFileTransferIds; private final Map<FileTransfer, NotificationCompat.Builder> currentFileTransfers; public FileTransferNotificationService(final Context context, final NotificationManager notificationManager, final AndroidSettings settings) { this.context = context; this.notificationManager = notificationManager; notificationHelper = new NotificationHelper(context, settings); currentFileTransferIds = new HashSet<>(); currentFileTransfers = new HashMap<>(); } public void notifyNewFileTransfer(final FileReceiver fileReceiver) { Validate.notNull(fileReceiver, "FileReceiver can not be null"); final int notificationId = buildNotificationId(fileReceiver); final NotificationCompat.Builder notification = new NotificationCompat.Builder(context); notification.setSmallIcon(R.drawable.ic_stat_notify_receive); notification.setTicker(context.getText(R.string.notification_new_file_transfer)); notification.setContentTitle(context.getString(R.string.notification_file_transfer_from, fileReceiver.getUser().getNick())); notification.setContentText(fileReceiver.getFileName()); notification.setContentIntent(createIntentForReceiveFileDialog(notificationId, fileReceiver)); notification.setPriority(NotificationCompat.PRIORITY_MAX); notification.setCategory(NotificationCompat.CATEGORY_MESSAGE); notificationHelper.setFeedbackEffects(notification); disableSwipeToCancel(notification); notificationManager.notify(notificationId, notification.build()); currentFileTransferIds.add(fileReceiver.getId()); } public void updateFileTransferProgress(final FileTransfer fileTransfer, final String status) { Validate.notNull(fileTransfer, "FileTransfer can not be null"); Validate.notEmpty(status, "Status can not be empty"); final int notificationId = buildNotificationId(fileTransfer); final NotificationCompat.Builder notification; if (currentFileTransfers.containsKey(fileTransfer)) { notification = currentFileTransfers.get(fileTransfer); } else { notification = new NotificationCompat.Builder(context); if (fileTransfer.getDirection() == FileTransfer.Direction.RECEIVE) { notification.setSmallIcon(R.drawable.ic_stat_notify_receive); notification.setContentTitle(context.getString(R.string.notification_file_transfer_from, fileTransfer.getUser().getNick())); } else { notification.setSmallIcon(R.drawable.ic_stat_notify_send); notification.setContentTitle(context.getString(R.string.notification_file_transfer_to, fileTransfer.getUser().getNick())); } final PendingIntent pendingIntent = createIntentForCancel(notificationId, fileTransfer); notification.addAction(R.drawable.ic_button_cancel, context.getString(R.string.cancel), pendingIntent); notification.setPriority(NotificationCompat.PRIORITY_DEFAULT); notification.setCategory(NotificationCompat.CATEGORY_PROGRESS); disableSwipeToCancel(notification); currentFileTransfers.put(fileTransfer, notification); } final String contentText = status + ": " + fileTransfer.getFileName(); notification.setContentText(contentText); notification.setStyle(new NotificationCompat.BigTextStyle().bigText(contentText)); notification.setProgress(100, fileTransfer.getPercent(), false); notificationManager.notify(notificationId, notification.build()); } public void completeFileTransferProgress(final FileTransfer fileTransfer, final String status) { Validate.notNull(fileTransfer, "FileTransfer can not be null"); Validate.notEmpty(status, "Status can not be empty"); final int notificationId = buildNotificationId(fileTransfer); final NotificationCompat.Builder notification = new NotificationCompat.Builder(context); if (fileTransfer.getDirection() == FileTransfer.Direction.RECEIVE) { notification.setSmallIcon(R.drawable.ic_stat_notify_receive); notification.setContentTitle(context.getString(R.string.notification_file_transfer_from, fileTransfer.getUser().getNick())); } else { notification.setSmallIcon(R.drawable.ic_stat_notify_send); notification.setContentTitle(context.getString(R.string.notification_file_transfer_to, fileTransfer.getUser().getNick())); } notification.setProgress(100, fileTransfer.getPercent(), false); notification.setContentText(status + ": " + fileTransfer.getFileName()); notification.setPriority(NotificationCompat.PRIORITY_LOW); notification.setCategory(NotificationCompat.CATEGORY_PROGRESS); enableSwipeToCancel(notification); currentFileTransferIds.remove(fileTransfer.getId()); currentFileTransfers.remove(fileTransfer); notificationManager.notify(notificationId, notification.build()); } public void cancelFileTransferNotification(final FileReceiver fileReceiver) { Validate.notNull(fileReceiver, "FileReceiver can not be null"); notificationManager.cancel(fileReceiver.getId() + FILE_TRANSFER_NOTIFICATION_ID); currentFileTransferIds.remove(fileReceiver.getId()); currentFileTransfers.remove(fileReceiver); } public Set<Integer> getCurrentFileTransferIds() { return Collections.unmodifiableSet(currentFileTransferIds); } private int buildNotificationId(final FileTransfer fileTransfer) { return fileTransfer.getId() + FILE_TRANSFER_NOTIFICATION_ID; } private PendingIntent createIntentForReceiveFileDialog(final int notificationId, final FileReceiver fileReceiver) { final Intent intent = new Intent(context, ReceiveFileController.class); intent.putExtra("userCode", fileReceiver.getUser().getCode()); intent.putExtra("fileTransferId", fileReceiver.getId()); intent.setAction("openReceiveFileDialog " + System.currentTimeMillis()); // Unique - to avoid it being cached return PendingIntent.getActivity(context, notificationId, intent, 0); } private PendingIntent createIntentForCancel(final int notificationId, final FileTransfer fileTransfer) { final Intent intent = new Intent(context, CancelFileTransferService.class); intent.putExtra("userCode", fileTransfer.getUser().getCode()); intent.putExtra("fileTransferId", fileTransfer.getId()); intent.setAction("cancelFileTransfer " + System.currentTimeMillis()); // Unique - to avoid it being cached return PendingIntent.getService(context, notificationId, intent, 0); } private void enableSwipeToCancel(final NotificationCompat.Builder notification) { notification.setOngoing(false); } private void disableSwipeToCancel(final NotificationCompat.Builder notification) { notification.setOngoing(true); } }