diff --git a/.travis.yml b/.travis.yml index 559dfcd..7bc9fa1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -12,15 +12,15 @@ jdk: - oraclejdk8 before_install: - - yes | sdkmanager "platforms;android-27" + - yes | sdkmanager "platforms;android-28" android: components: - tools - platform-tools - extra - - build-tools-27.0.3 - - android-27 + - build-tools-28.0.3 + - android-28 licenses: - 'android-sdk-license-.+' - 'google-gdk-license-.+' diff --git a/src/main/java/fr/unix_experience/owncloud_sms/engine/ASyncSMSSync.java b/src/main/java/fr/unix_experience/owncloud_sms/engine/ASyncSMSSync.java index 77ca15a..9c312c4 100644 --- a/src/main/java/fr/unix_experience/owncloud_sms/engine/ASyncSMSSync.java +++ b/src/main/java/fr/unix_experience/owncloud_sms/engine/ASyncSMSSync.java @@ -93,12 +93,16 @@ public interface ASyncSMSSync { if (prefs.showSyncNotifications()) { OCSMSNotificationUI.notify(_context, _context.getString(R.string.sync_title), - _context.getString(R.string.sync_inprogress), OCSMSNotificationType.SYNC.ordinal()); + _context.getString(R.string.sync_inprogress), OCSMSNotificationType.SYNC); } - syncStartupDate = smsBuffer.getLastMessageDate(); - performSync(smsBuffer); - hasSyncSomething = true; + try { + syncStartupDate = smsBuffer.getLastMessageDate(); + performSync(smsBuffer); + hasSyncSomething = true; + } finally { + OCSMSNotificationUI.cancel(_context, OCSMSNotificationType.SYNC); + } } } @@ -114,17 +118,16 @@ public interface ASyncSMSSync { // Fetch API version first to do some early verifications Log.i(ASyncSMSSync.TAG, "Server API version: " + _client.getServerAPIVersion()); _client.doPushRequest(smsBuffer); - OCSMSNotificationUI.cancel(_context); + OCSMSNotificationUI.cancel(_context, OCSMSNotificationType.SYNC_FAILED); } catch (IllegalStateException e) { // Fail to read account data OCSMSNotificationUI.notify(_context, _context.getString(R.string.fatal_error), - e.getMessage(), OCSMSNotificationType.SYNC_FAILED.ordinal()); + e.getMessage(), OCSMSNotificationType.SYNC_FAILED); } catch (OCSyncException e) { Log.e(ASyncSMSSync.TAG, _context.getString(e.getErrorId())); OCSMSNotificationUI.notify(_context, _context.getString(R.string.fatal_error), - e.getMessage(), OCSMSNotificationType.SYNC_FAILED.ordinal()); + e.getMessage(), OCSMSNotificationType.SYNC_FAILED); } } - OCSMSNotificationUI.cancel(_context); smsBuffer.clear(); } diff --git a/src/main/java/fr/unix_experience/owncloud_sms/enums/OCSMSNotificationChannel.java b/src/main/java/fr/unix_experience/owncloud_sms/enums/OCSMSNotificationChannel.java new file mode 100644 index 0000000..aec103c --- /dev/null +++ b/src/main/java/fr/unix_experience/owncloud_sms/enums/OCSMSNotificationChannel.java @@ -0,0 +1,48 @@ +package fr.unix_experience.owncloud_sms.enums; + +import android.app.NotificationManager; +import android.os.Build; +import android.support.annotation.StringRes; + +import fr.unix_experience.owncloud_sms.R; + +public enum OCSMSNotificationChannel { + DEFAULT("OCSMS_DEFAULT", R.string.notification_channel_name_default, null), + SYNC("OCSMS_SYNC", R.string.notification_channel_name_sync, null); + + static { + // well, that's a bit of a hack :/ + // can be inlined in the future + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { + DEFAULT.importance = NotificationManager.IMPORTANCE_DEFAULT; + SYNC.importance = NotificationManager.IMPORTANCE_LOW; + } + } + + private final String channelId; + private final int nameResId; + private final Integer descResId; + private int importance; + + OCSMSNotificationChannel(String channelId, @StringRes int nameResId, @StringRes Integer descResId) { + this.channelId = channelId; + this.nameResId = nameResId; + this.descResId = descResId; + } + + public String getChannelId() { + return channelId; + } + + public int getNameResId() { + return nameResId; + } + + public Integer getDescResId() { + return descResId; + } + + public int getImportance() { + return importance; + } +} diff --git a/src/main/java/fr/unix_experience/owncloud_sms/enums/OCSMSNotificationType.java b/src/main/java/fr/unix_experience/owncloud_sms/enums/OCSMSNotificationType.java index 096711c..15ee321 100644 --- a/src/main/java/fr/unix_experience/owncloud_sms/enums/OCSMSNotificationType.java +++ b/src/main/java/fr/unix_experience/owncloud_sms/enums/OCSMSNotificationType.java @@ -18,8 +18,23 @@ package fr.unix_experience.owncloud_sms.enums; */ public enum OCSMSNotificationType { - SYNC, - SYNC_FAILED, - DEBUG, - PERMISSION, + SYNC(OCSMSNotificationChannel.SYNC, 0), + SYNC_FAILED(OCSMSNotificationChannel.DEFAULT, 1), + PERMISSION(OCSMSNotificationChannel.DEFAULT, 2); + + private final OCSMSNotificationChannel channel; + private final int notificationId; + + OCSMSNotificationType(OCSMSNotificationChannel channel, int notificationId) { + this.channel = channel; + this.notificationId = notificationId; + } + + public OCSMSNotificationChannel getChannel() { + return channel; + } + + public int getNotificationId() { + return notificationId; + } } diff --git a/src/main/java/fr/unix_experience/owncloud_sms/notifications/OCSMSNotificationUI.java b/src/main/java/fr/unix_experience/owncloud_sms/notifications/OCSMSNotificationUI.java index 40141c5..1fbc4ab 100644 --- a/src/main/java/fr/unix_experience/owncloud_sms/notifications/OCSMSNotificationUI.java +++ b/src/main/java/fr/unix_experience/owncloud_sms/notifications/OCSMSNotificationUI.java @@ -17,17 +17,17 @@ package fr.unix_experience.owncloud_sms.notifications; * along with this program. If not, see . */ -import android.annotation.TargetApi; import android.app.Notification; +import android.app.NotificationChannel; import android.app.NotificationManager; import android.content.Context; import android.content.res.Resources; -import android.graphics.Bitmap; -import android.graphics.BitmapFactory; import android.os.Build; import android.support.v4.app.NotificationCompat; import fr.unix_experience.owncloud_sms.R; +import fr.unix_experience.owncloud_sms.enums.OCSMSNotificationChannel; +import fr.unix_experience.owncloud_sms.enums.OCSMSNotificationType; /** * Helper class for showing and canceling ui @@ -42,25 +42,30 @@ public class OCSMSNotificationUI { */ private static final String NOTIFICATION_TAG = "OCSMS_NOTIFICATION"; + public static void notify(Context context, String titleString, + String contentString, OCSMSNotificationType type) { + notify(context, titleString, contentString, + type.getChannel().getChannelId(), type.getNotificationId()); + } + /** * Shows the notification, or updates a previously shown notification of * this type, with the given parameters. * - * @see #cancel(Context) + * @see #cancel(Context, OCSMSNotificationType) */ - public static void notify(Context context, String titleString, - String contentString, int number) { + public static void notify(Context context, String titleString, String contentString, + String channelId, int notificationId) { Resources res = context.getResources(); // This image is used as the notification's large icon (thumbnail). // TODO: Remove this if your notification has no relevant thumbnail. - Bitmap picture = BitmapFactory.decodeResource(res, R.mipmap.ic_launcher); +// Bitmap picture = BitmapFactory.decodeResource(res, R.mipmap.ic_launcher); - - String ticker = (titleString.length() > 20) ? titleString.substring(0, 20) : titleString; +// String ticker = (titleString.length() > 20) ? titleString.substring(0, 20) : titleString; String title = res.getString(R.string.ui_notification_title_template, titleString); - NotificationCompat.Builder builder = new NotificationCompat.Builder(context) + NotificationCompat.Builder builder = new NotificationCompat.Builder(context, channelId) // Set appropriate defaults for the notification light, sound, // and vibration. @@ -77,9 +82,6 @@ public class OCSMSNotificationUI { // Set ticker text (preview) information for this notification. //.setTicker(ticker) - // Show a number. This is useful when stacking notifications of - // a single type. - .setNumber(number) .setStyle(new NotificationCompat.BigTextStyle() .bigText(contentString) .setBigContentTitle(title) @@ -87,24 +89,45 @@ public class OCSMSNotificationUI { .setAutoCancel(true) .setColor(context.getResources().getColor(R.color.oc_primary)); - OCSMSNotificationUI.notify(context, builder.build()); + notify(context, builder.build(), notificationId); } - @TargetApi(Build.VERSION_CODES.ECLAIR) - private static void notify(Context context, Notification notification) { + private static void notify(Context context, Notification notification, int notificationId) { NotificationManager nm = (NotificationManager) context .getSystemService(Context.NOTIFICATION_SERVICE); - nm.notify(OCSMSNotificationUI.NOTIFICATION_TAG, 0, notification); + createNotificationChannels(context, nm); + nm.notify(OCSMSNotificationUI.NOTIFICATION_TAG, notificationId, notification); } /** * Cancels any notifications of this type previously shown using - * {@link #notify(Context, String, String, int)}. + * {@link #notify(Context, String, String, OCSMSNotificationType)}. */ - @TargetApi(Build.VERSION_CODES.ECLAIR) - public static void cancel(Context context) { + public static void cancel(Context context, OCSMSNotificationType type) { + cancel(context, type.getNotificationId()); + } + + public static void cancel(Context context, int notificationId) { NotificationManager nm = (NotificationManager) context .getSystemService(Context.NOTIFICATION_SERVICE); - nm.cancel(OCSMSNotificationUI.NOTIFICATION_TAG, 0); + nm.cancel(OCSMSNotificationUI.NOTIFICATION_TAG, notificationId); } + + private static void createNotificationChannels(Context context, NotificationManager nm) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + for (OCSMSNotificationChannel ocsmsChannel : OCSMSNotificationChannel.values()) { + NotificationChannel channel = new NotificationChannel( + ocsmsChannel.getChannelId(), + context.getString(ocsmsChannel.getNameResId()), + ocsmsChannel.getImportance()); + + if (ocsmsChannel.getDescResId() != null) { + channel.setDescription(context.getString(ocsmsChannel.getDescResId())); + } + + nm.createNotificationChannel(channel); + } + } + } + } diff --git a/src/main/java/fr/unix_experience/owncloud_sms/prefs/PermissionChecker.java b/src/main/java/fr/unix_experience/owncloud_sms/prefs/PermissionChecker.java index d7159b9..cb7ffd0 100644 --- a/src/main/java/fr/unix_experience/owncloud_sms/prefs/PermissionChecker.java +++ b/src/main/java/fr/unix_experience/owncloud_sms/prefs/PermissionChecker.java @@ -67,7 +67,7 @@ public class PermissionChecker { // For context only show a notification OCSMSNotificationUI.notify(context, context.getString(R.string.notif_permission_required), context.getString(R.string.notif_permission_required_content), - OCSMSNotificationType.PERMISSION.ordinal()); + OCSMSNotificationType.PERMISSION); return false; } diff --git a/src/main/java/fr/unix_experience/owncloud_sms/sync_adapters/SmsSyncAdapter.java b/src/main/java/fr/unix_experience/owncloud_sms/sync_adapters/SmsSyncAdapter.java index b7116a9..e06cd1d 100644 --- a/src/main/java/fr/unix_experience/owncloud_sms/sync_adapters/SmsSyncAdapter.java +++ b/src/main/java/fr/unix_experience/owncloud_sms/sync_adapters/SmsSyncAdapter.java @@ -45,7 +45,7 @@ class SmsSyncAdapter extends AbstractThreadedSyncAdapter { if (new OCSMSSharedPrefs(getContext()).showSyncNotifications()) { OCSMSNotificationUI.notify(getContext(), getContext().getString(R.string.sync_title), - getContext().getString(R.string.sync_inprogress), OCSMSNotificationType.SYNC.ordinal()); + getContext().getString(R.string.sync_inprogress), OCSMSNotificationType.SYNC); } try { @@ -56,14 +56,13 @@ class SmsSyncAdapter extends AbstractThreadedSyncAdapter { // and push datas _client.doPushRequest(null); - OCSMSNotificationUI.cancel(getContext()); + OCSMSNotificationUI.cancel(getContext(), OCSMSNotificationType.SYNC_FAILED); } catch (IllegalStateException e) { OCSMSNotificationUI.notify(getContext(), getContext().getString(R.string.fatal_error), - e.getMessage(), OCSMSNotificationType.SYNC_FAILED.ordinal()); + e.getMessage(), OCSMSNotificationType.SYNC_FAILED); } catch (OCSyncException e) { - OCSMSNotificationUI.cancel(getContext()); OCSMSNotificationUI.notify(getContext(), getContext().getString(R.string.fatal_error), - getContext().getString(e.getErrorId()), OCSMSNotificationType.SYNC_FAILED.ordinal()); + getContext().getString(e.getErrorId()), OCSMSNotificationType.SYNC_FAILED); if (e.getErrorType() == OCSyncErrorType.IO) { syncResult.stats.numIoExceptions++; } @@ -76,6 +75,8 @@ class SmsSyncAdapter extends AbstractThreadedSyncAdapter { else { Log.w(SmsSyncAdapter.TAG, "onPerformSync: unhandled response"); } + } finally { + OCSMSNotificationUI.cancel(getContext(), OCSMSNotificationType.SYNC); } } diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 6bed7e0..87d7fe7 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -206,6 +206,8 @@ Sync process Sync in progress … Fatal error ! + Default + Sync Error #1: Invalid data received from server when getting previous messages