From 5eccd08bc7e8783bf9908d3b861516a2e84dacbb Mon Sep 17 00:00:00 2001 From: Thomas Keller Date: Wed, 12 Feb 2014 22:43:37 +0100 Subject: [PATCH] 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) --- res/drawable-hdpi/notification_icon.png | Bin 0 -> 861 bytes res/drawable-mdpi/notification_icon.png | Bin 0 -> 498 bytes res/drawable-xhdpi/notification_icon.png | Bin 0 -> 1270 bytes res/layout/progressbar_layout.xml | 40 ------ .../files/managers/OCNotificationManager.java | 156 --------------------- .../android/files/services/FileDownloader.java | 60 +++++--- .../android/files/services/FileUploader.java | 101 +++++++------ .../android/syncadapter/FileSyncAdapter.java | 116 +++++++++------ 8 files changed, 161 insertions(+), 312 deletions(-) create mode 100644 res/drawable-hdpi/notification_icon.png create mode 100644 res/drawable-mdpi/notification_icon.png create mode 100644 res/drawable-xhdpi/notification_icon.png delete mode 100644 res/layout/progressbar_layout.xml delete mode 100644 src/com/owncloud/android/files/managers/OCNotificationManager.java diff --git a/res/drawable-hdpi/notification_icon.png b/res/drawable-hdpi/notification_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..9e634a8cc35321e30fff3ff3c53afc2ce6c31c00 GIT binary patch literal 861 zcmV-j1ETziP)mnQ&8l_erBkJ z({Kb9LRvhda1Ww>rB!Aro0Or^VcOJ#ZZyII7%kk&1{U#+v=3pX-pGsQaIZMm|z9pD62sY2Y>tK#03!Uc+~o4#VK&gD@5B z(+)G?BxH)Q)VoElxCTn#q|f0IEQMw;bj^BWKAeNSFbi66>2lT^IO>)$$PxxS1@l1R zlVKa2fhO?ETPC62{94!zouEj|Rzs#pI}ZiKOr-Y-2o8k7ddW-yoeO=P)a`U}@v;Ye z_rN0XiFgM-2{&=eXCgI5whR%TgEnyW*I*qa;|T?=5Vpu$6dzns3N~E>4`CMsp|;(} zT!#?#l6+N^1<}Ak-1ik=nYYWs7?00<=$w-oUqN^5Yq>6Yz@5}K;=y*jAjrHzk1=Np zqN?7jF!%u)`PR7Kc2?K`#KRTUMFsv{IGAF>go;vtV}$Sl9SR>&>YR$&k|-~K20>f- z3VADhd+wWwqMx(}-bUYwQMe+Kp-WIa+`=HnI^VIhcGfBMETS&LN(+qOirbNl4HP^DooEKHze3+Y=$AYLZl$4f zwu^6{mi(zo#d~8p&0*8JlwkCp*K~8<6egykQN`J zLKkb>Du+5Lyc0EwC!QtWlMvoMx1|FV;Gs5j#(`ac0EF1TI2&=0!d&F~$%3d3N%H)R=kn+CzQx4{R{vF+Ccb)cJla0$FHw%-i? n4c&k|atCq;atCq;(j52=*R;i(@o}&H00000NkvXXu0mjf^l6n4 literal 0 HcmV?d00001 diff --git a/res/drawable-mdpi/notification_icon.png b/res/drawable-mdpi/notification_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..e33e65355f771d8be041d4083bcd149c7f6d7a3b GIT binary patch literal 498 zcmVS-9H8&I}2piKQgr-ZrAUO_9! z@ea%oL}xwOHyC9$3+`6ESW$gbDa;&V6p&9(rkBh;A7HxoaO^oEM z4yr&8d=2-Yi_Zr2TfgQKs=-R@Ix8PdkS==#TfzE4n`)1G-3A-52vKMORdNbTPyr3l o2~f;QrvLx|07*qoM6N<$g8yLLBLDyZ literal 0 HcmV?d00001 diff --git a/res/drawable-xhdpi/notification_icon.png b/res/drawable-xhdpi/notification_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..1ad49714c9a5dfa4199fcda19a6ddb6e70fff3c6 GIT binary patch literal 1270 zcmVu%)SxAUyrxz!RvecMV zwNurB2RPsYFmt0|56p&6WG0-u5-0j$4fJ-hu-%+WCB#N!vds?Aeg@m%p=>N|yu7>N zn{03@?bR?EE(S0CI9PxaUhpRu4Il)ikr7#J+xIe)qpv=f?V0lf1NuYFA zLkHm|h;uEyyTEnNLuHxPjzpx4+$vZEep%EX@FpyU0r&(gvkSpFv48XrGqw(^}F9g?+S@6bH0jgz-k|W$<7xVXV_I$B)8|Fc-WV5n;Mb`iCdk3SYx=Q10^-4s0BL zs_-WwaIz&Um@oq@jWFId_Px~B_B_zJGUItQ{LVdY$@*qZhb+tAp|VnAS{4)ei1vrP z)X2R2j6MU8gJqM-sCqFy!>r_`!K-0BTnAoqGyNs(fK6n?{oAU=fz0S-tm=U&@EE)T zEpr*`&&C%g?=}1{@Jp0RC(`nAp6kunt>FIRI`Io;S$#oUs-_acc%!f$9)($81gAog z@eFtEgd39g8s&x50QWYcV&A>eh`Oiu<_EB>%(ipwTb7pWT5P(Uwp0xVm}n%P0~ekT zZs@lQ32pM^$A?^_lgn^!+lOfmcjfY(8+OhB?wv`32@fmZiKS)Nzg{eH; zi&iAZBM6at%Ot;t257wFsWGlKV`cKazpiIs& zOKCvTj1;ZYY0I=w5j|g)O}d+RZ^1z)q4lr<_JY|t1R?iJ_l)sqb-=q2a_wdD(59V6 z8TG*i(4L0Uh#zl^Hg`tz_z1iN9ySlAfRWRHL6`&XmF~x5i^BMD(zVlDX0;Cd!jQk* zeyUgD#3;T_{s+($tz8Zj$iuvBx500q@m_GFeX)4LL{LPwa1og>W(* zVS@i}Sx$Z&mcg*xDAXUFf;Q^<3f^gaXbheC@J2S^1@(UX2~q1BYIfrb73*EI2=YIG z3^mESb|u8+x1AU>@(v8di-L9}>Alx5_2YPeZ(%;6K@$A`H+Tw1lyq(mV);ty|5Z>7LS4-fe+wU z=z*J|NIx^!2cGMGp~G}ujE5%gxg1Ws7On?3o(vxTBfJM5Y{@(bSHU3kgSD)2*MRAs z4Xzbs#Kd3jJ@7r44bNH(v$DQpyWlH$8+OA9SOPP_yRZd5 - - - - - - - - - - - - \ 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); + } } -- 2.11.0