From: Thomas Keller Date: Wed, 12 Feb 2014 21:43:37 +0000 (+0100) Subject: Notification improvements: X-Git-Tag: oc-android-1.5.5~5^2~5^2 X-Git-Url: http://git.linex4red.de/pub/Android/ownCloud.git/commitdiff_plain/5eccd08bc7e8783bf9908d3b861516a2e84dacbb?hp=--cc Notification improvements: - use NotificationCompat.Builder from the support library and remove the custom progressbar layout; this will give platform users the expected look and feel of a notificati - remove OCNotificationManager (it contained the old layout references, but was unused) - add new notification icons that follow the Android style guidelines (http://developer.android.com/design/style/iconography.html#notification) --- 5eccd08bc7e8783bf9908d3b861516a2e84dacbb diff --git a/res/drawable-hdpi/notification_icon.png b/res/drawable-hdpi/notification_icon.png new file mode 100644 index 00000000..9e634a8c Binary files /dev/null and b/res/drawable-hdpi/notification_icon.png differ diff --git a/res/drawable-mdpi/notification_icon.png b/res/drawable-mdpi/notification_icon.png new file mode 100644 index 00000000..e33e6535 Binary files /dev/null and b/res/drawable-mdpi/notification_icon.png differ diff --git a/res/drawable-xhdpi/notification_icon.png b/res/drawable-xhdpi/notification_icon.png new file mode 100644 index 00000000..1ad49714 Binary files /dev/null and b/res/drawable-xhdpi/notification_icon.png differ diff --git a/res/layout/progressbar_layout.xml b/res/layout/progressbar_layout.xml deleted file mode 100644 index e5a5afed..00000000 --- a/res/layout/progressbar_layout.xml +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - - - - - - - - \ No newline at end of file diff --git a/src/com/owncloud/android/files/managers/OCNotificationManager.java b/src/com/owncloud/android/files/managers/OCNotificationManager.java deleted file mode 100644 index 47fb491d..00000000 --- a/src/com/owncloud/android/files/managers/OCNotificationManager.java +++ /dev/null @@ -1,156 +0,0 @@ -/* ownCloud Android client application - * Copyright (C) 2012 Bartek Przybylski - * Copyright (C) 2012-2013 ownCloud Inc. - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2, - * as published by the Free Software Foundation. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - * - */ - -package com.owncloud.android.files.managers; - -import java.util.HashMap; -import java.util.Map; - -import com.owncloud.android.R; -import com.owncloud.android.utils.DisplayUtils; - -import android.app.Notification; -import android.app.NotificationManager; -import android.content.Context; -import android.widget.RemoteViews; - - -public class OCNotificationManager { - - enum NotificationType { - NOTIFICATION_SIMPLE, - NOTIFICATION_PROGRESS - } - - static public class NotificationData { - private String mText, mSubtitle; - private int mPercent; - private boolean mOngoing; - - public NotificationData(String text, String subtitle, boolean ongoing) { - this(text, subtitle, -1, ongoing); - } - - public NotificationData(int percent, boolean ongoing) { - this(null, null, percent, ongoing); - } - - public NotificationData(String text, int percent, boolean ongoing) { - this(text, null, percent, ongoing); - } - - public NotificationData(String text, String subtitle, int percent, boolean ongoing) { - mText = text; - mPercent = percent; - mSubtitle = subtitle; - mOngoing = ongoing; - } - - public String getText() { return mText; } - public int getPercent() { return mPercent; } - public String getSubtitle() { return mSubtitle; } - public boolean getOngoing() { return mOngoing; } - } - - static private OCNotificationManager mInstance = null; - - private class NotificationTypePair { - public Notification mNotificaiton; - public NotificationType mType; - public NotificationTypePair(Notification n, NotificationType type) { - mNotificaiton = n; - mType = type; - } - } - - private Context mContext; - private Map mNotificationMap; - private int mNotificationCounter; - NotificationManager mNM; - - static OCNotificationManager getInstance(Context context) { - if (mInstance == null) - mInstance = new OCNotificationManager(context); - return mInstance; - } - - OCNotificationManager(Context context) { - mContext = context; - mNotificationMap = new HashMap(); - mNM = (NotificationManager)mContext.getSystemService(Context.NOTIFICATION_SERVICE); - mNotificationCounter = 0; - } - - public int postNotification(NotificationType type, NotificationData data) { - mNotificationCounter++; - Notification notification = null; - - switch (type) { - case NOTIFICATION_SIMPLE: - notification = new Notification(DisplayUtils.getSeasonalIconId(), data.getText(), System.currentTimeMillis()); - break; - case NOTIFICATION_PROGRESS: - notification = new Notification(); - notification.contentView = new RemoteViews(mContext.getPackageName(), R.layout.progressbar_layout); - notification.contentView.setTextViewText(R.id.status_text, - data.getText()); - notification.contentView.setImageViewResource(R.id.status_icon, - R.id.icon); - notification.contentView.setProgressBar(R.id.status_progress, - 100, - data.getPercent(), - false); - break; - default: - return -1; - } - if (data.getOngoing()) { - notification.flags |= notification.flags | Notification.FLAG_ONGOING_EVENT; - } - - mNotificationMap.put(mNotificationCounter, new NotificationTypePair(notification, type)); - return mNotificationCounter; - } - - public boolean updateNotification(int notification_id, NotificationData data) { - if (!mNotificationMap.containsKey(notification_id)) { - return false; - } - NotificationTypePair pair = mNotificationMap.get(notification_id); - switch (pair.mType) { - case NOTIFICATION_PROGRESS: - pair.mNotificaiton.contentView.setProgressBar(R.id.status_text, - 100, - data.getPercent(), - false); - return true; - case NOTIFICATION_SIMPLE: - pair.mNotificaiton = new Notification(DisplayUtils.getSeasonalIconId(), - data.getText(), System.currentTimeMillis()); - mNM.notify(notification_id, pair.mNotificaiton); - return true; - default: - return false; - } - } - - public void discardNotification(int notification_id) { - mNM.cancel(notification_id); - mNotificationMap.remove(notification_id); - } -} diff --git a/src/com/owncloud/android/files/services/FileDownloader.java b/src/com/owncloud/android/files/services/FileDownloader.java index e59e37d9..c05f7a52 100644 --- a/src/com/owncloud/android/files/services/FileDownloader.java +++ b/src/com/owncloud/android/files/services/FileDownloader.java @@ -61,6 +61,7 @@ import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.Process; +import android.support.v4.app.NotificationCompat; import android.widget.RemoteViews; public class FileDownloader extends Service implements OnDatatransferProgressListener { @@ -88,7 +89,7 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis private DownloadFileOperation mCurrentDownload = null; private NotificationManager mNotificationManager; - private Notification mNotification; + private NotificationCompat.Builder mNotificationBuilder; private int mLastPercent; @@ -404,13 +405,18 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis private void notifyDownloadStart(DownloadFileOperation download) { /// create status notification with a progress bar mLastPercent = 0; - mNotification = new Notification(DisplayUtils.getSeasonalIconId(), getString(R.string.downloader_download_in_progress_ticker), System.currentTimeMillis()); - mNotification.flags |= Notification.FLAG_ONGOING_EVENT; - mNotification.contentView = new RemoteViews(getApplicationContext().getPackageName(), R.layout.progressbar_layout); - mNotification.contentView.setProgressBar(R.id.status_progress, 100, 0, download.getSize() < 0); - mNotification.contentView.setTextViewText(R.id.status_text, String.format(getString(R.string.downloader_download_in_progress_content), 0, new File(download.getSavePath()).getName())); - mNotification.contentView.setImageViewResource(R.id.status_icon, DisplayUtils.getSeasonalIconId()); - + mNotificationBuilder = new NotificationCompat.Builder(this); + mNotificationBuilder + .setSmallIcon(R.drawable.notification_icon) + .setTicker(getString(R.string.downloader_download_in_progress_ticker)) + .setContentTitle(getString(R.string.downloader_download_in_progress_ticker)) + .setOngoing(true) + .setProgress(100, 0, download.getSize() < 0) + .setContentText( + String.format(getString(R.string.downloader_download_in_progress_content), 0, + new File(download.getSavePath()).getName()) + ); + /// includes a pending intent in the notification showing the details view of the file Intent showDetailsIntent = null; if (PreviewImageFragment.canBePreviewed(download.getFile())) { @@ -421,9 +427,12 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis showDetailsIntent.putExtra(FileActivity.EXTRA_FILE, download.getFile()); showDetailsIntent.putExtra(FileActivity.EXTRA_ACCOUNT, download.getAccount()); showDetailsIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - mNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), (int)System.currentTimeMillis(), showDetailsIntent, 0); - mNotificationManager.notify(R.string.downloader_download_in_progress_ticker, mNotification); + mNotificationBuilder.setContentIntent(PendingIntent.getActivity( + this, (int) System.currentTimeMillis(), showDetailsIntent, 0 + )); + + mNotificationManager.notify(R.string.downloader_download_in_progress_ticker, mNotificationBuilder.build()); } @@ -434,11 +443,11 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis public void onTransferProgress(long progressRate, long totalTransferredSoFar, long totalToTransfer, String filePath) { int percent = (int)(100.0*((double)totalTransferredSoFar)/((double)totalToTransfer)); if (percent != mLastPercent) { - mNotification.contentView.setProgressBar(R.id.status_progress, 100, percent, totalToTransfer < 0); + mNotificationBuilder.setProgress(100, percent, totalToTransfer < 0); String fileName = filePath.substring(filePath.lastIndexOf(FileUtils.PATH_SEPARATOR) + 1); String text = String.format(getString(R.string.downloader_download_in_progress_content), percent, fileName); - mNotification.contentView.setTextViewText(R.id.status_text, text); - mNotificationManager.notify(R.string.downloader_download_in_progress_ticker, mNotification); + mNotificationBuilder.setContentText(text); + mNotificationManager.notify(R.string.downloader_download_in_progress_ticker, mNotificationBuilder.build()); } mLastPercent = percent; } @@ -455,8 +464,10 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis if (!downloadResult.isCancelled()) { int tickerId = (downloadResult.isSuccess()) ? R.string.downloader_download_succeeded_ticker : R.string.downloader_download_failed_ticker; int contentId = (downloadResult.isSuccess()) ? R.string.downloader_download_succeeded_content : R.string.downloader_download_failed_content; - Notification finalNotification = new Notification(DisplayUtils.getSeasonalIconId(), getString(tickerId), System.currentTimeMillis()); - finalNotification.flags |= Notification.FLAG_AUTO_CANCEL; + mNotificationBuilder + .setTicker(getString(tickerId)) + .setContentTitle(getString(tickerId)) + .setAutoCancel(true); boolean needsToUpdateCredentials = (downloadResult.getCode() == ResultCode.UNAUTHORIZED || // (downloadResult.isTemporalRedirection() && downloadResult.isIdPRedirection() (downloadResult.isIdPRedirection() @@ -471,11 +482,11 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis updateAccountCredentials.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); updateAccountCredentials.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); updateAccountCredentials.addFlags(Intent.FLAG_FROM_BACKGROUND); - finalNotification.contentIntent = PendingIntent.getActivity(this, (int)System.currentTimeMillis(), updateAccountCredentials, PendingIntent.FLAG_ONE_SHOT); - finalNotification.setLatestEventInfo( getApplicationContext(), - getString(tickerId), - String.format(getString(contentId), new File(download.getSavePath()).getName()), - finalNotification.contentIntent); + mNotificationBuilder + .setContentIntent(PendingIntent.getActivity( + this, (int) System.currentTimeMillis(), updateAccountCredentials, PendingIntent.FLAG_ONE_SHOT + )) + .setContentText(String.format(getString(contentId), new File(download.getSavePath()).getName())); mDownloadClient = null; // grant that future retries on the same account will get the fresh credentials } else { @@ -494,10 +505,13 @@ public class FileDownloader extends Service implements OnDatatransferProgressLis // TODO put something smart in showDetailsIntent showDetailsIntent = new Intent(); } - finalNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), (int)System.currentTimeMillis(), showDetailsIntent, 0); - finalNotification.setLatestEventInfo(getApplicationContext(), getString(tickerId), String.format(getString(contentId), new File(download.getSavePath()).getName()), finalNotification.contentIntent); + mNotificationBuilder + .setContentIntent(PendingIntent.getActivity( + this, (int) System.currentTimeMillis(), showDetailsIntent, 0 + )) + .setContentText(String.format(getString(contentId), new File(download.getSavePath()).getName())); } - mNotificationManager.notify(tickerId, finalNotification); + mNotificationManager.notify(tickerId, mNotificationBuilder.build()); } } diff --git a/src/com/owncloud/android/files/services/FileUploader.java b/src/com/owncloud/android/files/services/FileUploader.java index 2f963562..722b0655 100644 --- a/src/com/owncloud/android/files/services/FileUploader.java +++ b/src/com/owncloud/android/files/services/FileUploader.java @@ -71,6 +71,7 @@ import android.os.IBinder; import android.os.Looper; import android.os.Message; import android.os.Process; +import android.support.v4.app.NotificationCompat; import android.webkit.MimeTypeMap; import android.widget.RemoteViews; @@ -117,7 +118,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe private UploadFileOperation mCurrentUpload = null; private NotificationManager mNotificationManager; - private Notification mNotification; + private NotificationCompat.Builder mNotificationBuilder; private int mLastPercent; private RemoteViews mDefaultNotificationContentView; @@ -682,26 +683,26 @@ public class FileUploader extends Service implements OnDatatransferProgressListe private void notifyUploadStart(UploadFileOperation upload) { // / create status notification with a progress bar mLastPercent = 0; - mNotification = new Notification(DisplayUtils.getSeasonalIconId(), getString(R.string.uploader_upload_in_progress_ticker), - System.currentTimeMillis()); - mNotification.flags |= Notification.FLAG_ONGOING_EVENT; - mDefaultNotificationContentView = mNotification.contentView; - mNotification.contentView = new RemoteViews(getApplicationContext().getPackageName(), - R.layout.progressbar_layout); - mNotification.contentView.setProgressBar(R.id.status_progress, 100, 0, false); - mNotification.contentView.setTextViewText(R.id.status_text, - String.format(getString(R.string.uploader_upload_in_progress_content), 0, upload.getFileName())); - mNotification.contentView.setImageViewResource(R.id.status_icon, DisplayUtils.getSeasonalIconId()); - + mNotificationBuilder = new NotificationCompat.Builder(this); + mNotificationBuilder + .setOngoing(true) + .setSmallIcon(R.drawable.notification_icon) + .setTicker(getString(R.string.uploader_upload_in_progress_ticker)) + .setContentTitle(getString(R.string.uploader_upload_in_progress_ticker)) + .setProgress(100, 0, false) + .setContentText( + String.format(getString(R.string.uploader_upload_in_progress_content), 0, upload.getFileName())); + /// includes a pending intent in the notification showing the details view of the file Intent showDetailsIntent = new Intent(this, FileDisplayActivity.class); showDetailsIntent.putExtra(FileActivity.EXTRA_FILE, upload.getFile()); showDetailsIntent.putExtra(FileActivity.EXTRA_ACCOUNT, upload.getAccount()); showDetailsIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - mNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), - (int) System.currentTimeMillis(), showDetailsIntent, 0); + mNotificationBuilder.setContentIntent(PendingIntent.getActivity( + this, (int) System.currentTimeMillis(), showDetailsIntent, 0 + )); - mNotificationManager.notify(R.string.uploader_upload_in_progress_ticker, mNotification); + mNotificationManager.notify(R.string.uploader_upload_in_progress_ticker, mNotificationBuilder.build()); } /** @@ -711,11 +712,11 @@ public class FileUploader extends Service implements OnDatatransferProgressListe public void onTransferProgress(long progressRate, long totalTransferredSoFar, long totalToTransfer, String filePath) { int percent = (int) (100.0 * ((double) totalTransferredSoFar) / ((double) totalToTransfer)); if (percent != mLastPercent) { - mNotification.contentView.setProgressBar(R.id.status_progress, 100, percent, false); + mNotificationBuilder.setProgress(100, percent, false); String fileName = filePath.substring(filePath.lastIndexOf(FileUtils.PATH_SEPARATOR) + 1); String text = String.format(getString(R.string.uploader_upload_in_progress_content), percent, fileName); - mNotification.contentView.setTextViewText(R.id.status_text, text); - mNotificationManager.notify(R.string.uploader_upload_in_progress_ticker, mNotification); + mNotificationBuilder.setContentText(text); + mNotificationManager.notify(R.string.uploader_upload_in_progress_ticker, mNotificationBuilder.build()); } mLastPercent = percent; } @@ -735,12 +736,7 @@ public class FileUploader extends Service implements OnDatatransferProgressListe } else if (uploadResult.isSuccess()) { // / success -> silent update of progress notification to success // message - mNotification.flags ^= Notification.FLAG_ONGOING_EVENT; // remove - // the - // ongoing - // flag - mNotification.flags |= Notification.FLAG_AUTO_CANCEL; - mNotification.contentView = mDefaultNotificationContentView; + mNotificationBuilder.setOngoing(false).setAutoCancel(true); /// includes a pending intent in the notification showing the details view of the file Intent showDetailsIntent = null; @@ -751,18 +747,20 @@ public class FileUploader extends Service implements OnDatatransferProgressListe } showDetailsIntent.putExtra(FileActivity.EXTRA_FILE, upload.getFile()); showDetailsIntent.putExtra(FileActivity.EXTRA_ACCOUNT, upload.getAccount()); - showDetailsIntent.putExtra(FileActivity.EXTRA_FROM_NOTIFICATION, true); - showDetailsIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - mNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), - (int) System.currentTimeMillis(), showDetailsIntent, 0); - - mNotification.setLatestEventInfo(getApplicationContext(), - getString(R.string.uploader_upload_succeeded_ticker), - String.format(getString(R.string.uploader_upload_succeeded_content_single), upload.getFileName()), - mNotification.contentIntent); - - mNotificationManager.notify(R.string.uploader_upload_in_progress_ticker, mNotification); // NOT - // AN + showDetailsIntent.putExtra(FileActivity.EXTRA_FROM_NOTIFICATION, true);; + mNotificationBuilder + .setContentIntent(PendingIntent.getActivity( + this, (int) System.currentTimeMillis(), showDetailsIntent, 0 + )) + .setTicker(getString(R.string.uploader_upload_succeeded_ticker)) + .setContentTitle(getString(R.string.uploader_upload_succeeded_ticker)) + .setContentText( + String.format(getString(R.string.uploader_upload_succeeded_content_single), + upload.getFileName()) + ); + + mNotificationManager.notify(R.string.uploader_upload_in_progress_ticker, mNotificationBuilder.build()); // NOT + // AN DbHandler db = new DbHandler(this.getBaseContext()); db.removeIUPendingFile(mCurrentUpload.getOriginalStoragePath()); db.close(); @@ -771,9 +769,12 @@ public class FileUploader extends Service implements OnDatatransferProgressListe // / fail -> explicit failure notification mNotificationManager.cancel(R.string.uploader_upload_in_progress_ticker); - Notification finalNotification = new Notification(DisplayUtils.getSeasonalIconId(), - getString(R.string.uploader_upload_failed_ticker), System.currentTimeMillis()); - finalNotification.flags |= Notification.FLAG_AUTO_CANCEL; + NotificationCompat.Builder errorBuilder = new NotificationCompat.Builder(this); + errorBuilder + .setSmallIcon(R.drawable.notification_icon) + .setTicker(getString(R.string.uploader_upload_failed_ticker)) + .setContentTitle(getString(R.string.uploader_upload_failed_ticker)) + .setAutoCancel(true); String content = null; boolean needsToUpdateCredentials = (uploadResult.getCode() == ResultCode.UNAUTHORIZED || @@ -790,15 +791,13 @@ public class FileUploader extends Service implements OnDatatransferProgressListe updateAccountCredentials.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); updateAccountCredentials.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); updateAccountCredentials.addFlags(Intent.FLAG_FROM_BACKGROUND); - finalNotification.contentIntent = PendingIntent.getActivity(this, (int)System.currentTimeMillis(), updateAccountCredentials, PendingIntent.FLAG_ONE_SHOT); + errorBuilder.setContentIntent(PendingIntent.getActivity( + this, (int) System.currentTimeMillis(), updateAccountCredentials, PendingIntent.FLAG_ONE_SHOT + )); content = String.format(getString(R.string.uploader_upload_failed_content_single), upload.getFileName()); - finalNotification.setLatestEventInfo(getApplicationContext(), - getString(R.string.uploader_upload_failed_ticker), content, finalNotification.contentIntent); mUploadClient = null; // grant that future retries on the same account will get the fresh credentials } else { // TODO put something smart in the contentIntent below - // finalNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), (int)System.currentTimeMillis(), new Intent(), 0); - //} if (uploadResult.getCode() == ResultCode.LOCAL_STORAGE_FULL || uploadResult.getCode() == ResultCode.LOCAL_STORAGE_NOT_COPIED) { @@ -823,10 +822,12 @@ public class FileUploader extends Service implements OnDatatransferProgressListe detailUploadIntent = new Intent(this, FailedUploadActivity.class); detailUploadIntent.putExtra(FailedUploadActivity.MESSAGE, content); } - finalNotification.contentIntent = PendingIntent.getActivity(getApplicationContext(), - (int) System.currentTimeMillis(), detailUploadIntent, PendingIntent.FLAG_UPDATE_CURRENT - | PendingIntent.FLAG_ONE_SHOT); - + errorBuilder + .setContentIntent(PendingIntent.getActivity( + this, (int) System.currentTimeMillis(), detailUploadIntent, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_ONE_SHOT + )) + .setContentText(content); + if (upload.isInstant()) { DbHandler db = null; try { @@ -847,10 +848,8 @@ public class FileUploader extends Service implements OnDatatransferProgressListe } } } - finalNotification.setLatestEventInfo(getApplicationContext(), - getString(R.string.uploader_upload_failed_ticker), content, finalNotification.contentIntent); - mNotificationManager.notify(R.string.uploader_upload_failed_ticker, finalNotification); + mNotificationManager.notify(R.string.uploader_upload_failed_ticker, errorBuilder.build()); } } diff --git a/src/com/owncloud/android/syncadapter/FileSyncAdapter.java b/src/com/owncloud/android/syncadapter/FileSyncAdapter.java index fe6c7c74..59e7754c 100644 --- a/src/com/owncloud/android/syncadapter/FileSyncAdapter.java +++ b/src/com/owncloud/android/syncadapter/FileSyncAdapter.java @@ -36,14 +36,11 @@ import com.owncloud.android.operations.SynchronizeFolderOperation; import com.owncloud.android.operations.UpdateOCVersionOperation; import com.owncloud.android.lib.common.operations.RemoteOperationResult.ResultCode; import com.owncloud.android.ui.activity.ErrorsWhileCopyingHandlerActivity; -import com.owncloud.android.utils.DisplayUtils; import com.owncloud.android.utils.Log_OC; - import android.accounts.Account; import android.accounts.AccountManager; import android.accounts.AccountsException; -import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.AbstractThreadedSyncAdapter; @@ -53,7 +50,7 @@ import android.content.Context; import android.content.Intent; import android.content.SyncResult; import android.os.Bundle; -//import android.support.v4.content.LocalBroadcastManager; +import android.support.v4.app.NotificationCompat; /** * Implementation of {@link AbstractThreadedSyncAdapter} responsible for synchronizing @@ -387,8 +384,8 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter { * Notifies the user about a failed synchronization through the status notification bar */ private void notifyFailedSynchronization() { - Notification notification = new Notification(DisplayUtils.getSeasonalIconId(), getContext().getString(R.string.sync_fail_ticker), System.currentTimeMillis()); - notification.flags |= Notification.FLAG_AUTO_CANCEL; + NotificationCompat.Builder notificationBuilder = createNotificationBuilder(); + notificationBuilder.setTicker(i18n(R.string.sync_fail_ticker)); boolean needsToUpdateCredentials = (mLastFailedResult != null && ( mLastFailedResult.getCode() == ResultCode.UNAUTHORIZED || ( mLastFailedResult.isIdPRedirection() && @@ -397,7 +394,7 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter { ) ); // TODO put something smart in the contentIntent below for all the possible errors - notification.contentIntent = PendingIntent.getActivity(getContext().getApplicationContext(), (int)System.currentTimeMillis(), new Intent(), 0); + notificationBuilder.setContentTitle(i18n(R.string.sync_fail_ticker)); if (needsToUpdateCredentials) { // let the user update credentials with one click Intent updateAccountCredentials = new Intent(getContext(), AuthenticatorActivity.class); @@ -407,18 +404,17 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter { updateAccountCredentials.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); updateAccountCredentials.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS); updateAccountCredentials.addFlags(Intent.FLAG_FROM_BACKGROUND); - notification.contentIntent = PendingIntent.getActivity(getContext(), (int)System.currentTimeMillis(), updateAccountCredentials, PendingIntent.FLAG_ONE_SHOT); - notification.setLatestEventInfo(getContext().getApplicationContext(), - getContext().getString(R.string.sync_fail_ticker), - String.format(getContext().getString(R.string.sync_fail_content_unauthorized), getAccount().name), - notification.contentIntent); + notificationBuilder + .setContentIntent(PendingIntent.getActivity( + getContext(), (int)System.currentTimeMillis(), updateAccountCredentials, PendingIntent.FLAG_ONE_SHOT + )) + .setContentText(i18n(R.string.sync_fail_content_unauthorized, getAccount().name)); } else { - notification.setLatestEventInfo(getContext().getApplicationContext(), - getContext().getString(R.string.sync_fail_ticker), - String.format(getContext().getString(R.string.sync_fail_content), getAccount().name), - notification.contentIntent); + notificationBuilder + .setContentText(i18n(R.string.sync_fail_content, getAccount().name)); } - ((NotificationManager) getContext().getSystemService(Context.NOTIFICATION_SERVICE)).notify(R.string.sync_fail_ticker, notification); + + showNotification(R.string.sync_fail_ticker, notificationBuilder); } @@ -429,26 +425,31 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter { */ private void notifyFailsInFavourites() { if (mFailedResultsCounter > 0) { - Notification notification = new Notification(DisplayUtils.getSeasonalIconId(), getContext().getString(R.string.sync_fail_in_favourites_ticker), System.currentTimeMillis()); - notification.flags |= Notification.FLAG_AUTO_CANCEL; + NotificationCompat.Builder notificationBuilder = createNotificationBuilder(); + notificationBuilder.setTicker(i18n(R.string.sync_fail_in_favourites_ticker)); + // TODO put something smart in the contentIntent below - notification.contentIntent = PendingIntent.getActivity(getContext().getApplicationContext(), (int)System.currentTimeMillis(), new Intent(), 0); - notification.setLatestEventInfo(getContext().getApplicationContext(), - getContext().getString(R.string.sync_fail_in_favourites_ticker), - String.format(getContext().getString(R.string.sync_fail_in_favourites_content), mFailedResultsCounter + mConflictsFound, mConflictsFound), - notification.contentIntent); - ((NotificationManager) getContext().getSystemService(Context.NOTIFICATION_SERVICE)).notify(R.string.sync_fail_in_favourites_ticker, notification); + notificationBuilder + .setContentIntent(PendingIntent.getActivity( + getContext(), (int) System.currentTimeMillis(), new Intent(), 0 + )) + .setContentTitle(i18n(R.string.sync_fail_in_favourites_ticker)) + .setContentText(i18n(R.string.sync_fail_in_favourites_content, mFailedResultsCounter + mConflictsFound, mConflictsFound)); + showNotification(R.string.sync_fail_in_favourites_ticker, notificationBuilder); } else { - Notification notification = new Notification(DisplayUtils.getSeasonalIconId(), getContext().getString(R.string.sync_conflicts_in_favourites_ticker), System.currentTimeMillis()); - notification.flags |= Notification.FLAG_AUTO_CANCEL; + NotificationCompat.Builder notificationBuilder = createNotificationBuilder(); + notificationBuilder.setTicker(i18n(R.string.sync_conflicts_in_favourites_ticker)); + // TODO put something smart in the contentIntent below - notification.contentIntent = PendingIntent.getActivity(getContext().getApplicationContext(), (int)System.currentTimeMillis(), new Intent(), 0); - notification.setLatestEventInfo(getContext().getApplicationContext(), - getContext().getString(R.string.sync_conflicts_in_favourites_ticker), - String.format(getContext().getString(R.string.sync_conflicts_in_favourites_content), mConflictsFound), - notification.contentIntent); - ((NotificationManager) getContext().getSystemService(Context.NOTIFICATION_SERVICE)).notify(R.string.sync_conflicts_in_favourites_ticker, notification); + notificationBuilder + .setContentIntent(PendingIntent.getActivity( + getContext(), (int) System.currentTimeMillis(), new Intent(), 0 + )) + .setContentTitle(i18n(R.string.sync_conflicts_in_favourites_ticker)) + .setContentText(i18n(R.string.sync_conflicts_in_favourites_ticker, mConflictsFound)); + + showNotification(R.string.sync_conflicts_in_favourites_ticker, notificationBuilder); } } @@ -462,9 +463,9 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter { * We won't consider a synchronization as failed when foreign files can not be copied to the ownCloud local directory. */ private void notifyForgottenLocalFiles() { - Notification notification = new Notification(DisplayUtils.getSeasonalIconId(), getContext().getString(R.string.sync_foreign_files_forgotten_ticker), System.currentTimeMillis()); - notification.flags |= Notification.FLAG_AUTO_CANCEL; - + NotificationCompat.Builder notificationBuilder = createNotificationBuilder(); + notificationBuilder.setTicker(i18n(R.string.sync_foreign_files_forgotten_ticker)); + /// includes a pending intent in the notification showing a more detailed explanation Intent explanationIntent = new Intent(getContext(), ErrorsWhileCopyingHandlerActivity.class); explanationIntent.putExtra(ErrorsWhileCopyingHandlerActivity.EXTRA_ACCOUNT, getAccount()); @@ -476,14 +477,45 @@ public class FileSyncAdapter extends AbstractOwnCloudSyncAdapter { explanationIntent.putExtra(ErrorsWhileCopyingHandlerActivity.EXTRA_REMOTE_PATHS, remotePaths); explanationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); - notification.contentIntent = PendingIntent.getActivity(getContext().getApplicationContext(), (int)System.currentTimeMillis(), explanationIntent, 0); - notification.setLatestEventInfo(getContext().getApplicationContext(), - getContext().getString(R.string.sync_foreign_files_forgotten_ticker), - String.format(getContext().getString(R.string.sync_foreign_files_forgotten_content), mForgottenLocalFiles.size(), getContext().getString(R.string.app_name)), - notification.contentIntent); - ((NotificationManager) getContext().getSystemService(Context.NOTIFICATION_SERVICE)).notify(R.string.sync_foreign_files_forgotten_ticker, notification); + notificationBuilder + .setContentIntent(PendingIntent.getActivity( + getContext(), (int) System.currentTimeMillis(), explanationIntent, 0 + )) + .setContentTitle(i18n(R.string.sync_foreign_files_forgotten_ticker)) + .setContentText(i18n(R.string.sync_foreign_files_forgotten_content, mForgottenLocalFiles.size(), i18n(R.string.app_name))); + showNotification(R.string.sync_foreign_files_forgotten_ticker, notificationBuilder); } + /** + * Creates a notification builder with some commonly used settings + * + * @return + */ + private NotificationCompat.Builder createNotificationBuilder() { + NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(getContext()); + notificationBuilder.setSmallIcon(R.drawable.notification_icon).setAutoCancel(true); + return notificationBuilder; + } + /** + * Builds and shows the notification + * + * @param id + * @param builder + */ + private void showNotification(int id, NotificationCompat.Builder builder) { + ((NotificationManager) getContext().getSystemService(Context.NOTIFICATION_SERVICE)) + .notify(id, builder.build()); + } + /** + * Shorthand translation + * + * @param key + * @param args + * @return + */ + private String i18n(int key, Object... args) { + return getContext().getString(key, args); + } }