diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index f04586a0..556dfb11 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -27,7 +27,7 @@ Before creating a new issue make sure to **search the tracker** for similar ones ## Compiling -Due to the app's integration with Firebase, a `google-services.json` is required inside the `app` directory. To get one, either [set up your own Firebase project][firebase-console] (with or without a self hosted [backend][sisyphus], or ask us to provide you the one we use for development. +Due to the app's integration with Firebase, a `google-services.json` is required inside the `app` directory. To get one, either [set up your own Firebase project][firebase-console] (with or without a self hosted [backend][sisyphus]), or ask us to provide you the one we use for development. ## Pull requests diff --git a/app/src/main/java/gr/thmmy/mthmmy/receiver/Receiver.java b/app/src/main/java/gr/thmmy/mthmmy/receiver/Receiver.java index 3430ead9..8d805922 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/receiver/Receiver.java +++ b/app/src/main/java/gr/thmmy/mthmmy/receiver/Receiver.java @@ -1,12 +1,13 @@ package gr.thmmy.mthmmy.receiver; -import android.app.Notification; +import android.app.NotificationChannel; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.net.Uri; +import android.os.Build; import android.os.Bundle; import android.support.v4.app.NotificationCompat; import android.webkit.MimeTypeMap; @@ -27,12 +28,14 @@ import static gr.thmmy.mthmmy.services.DownloadService.SAVE_DIR; import static gr.thmmy.mthmmy.services.DownloadService.STARTED; public class Receiver extends BroadcastReceiver { + private static final String DOWNLOADS_CHANNEL_ID = "Downloads"; + private static final String DOWNLOADS_CHANNEL_NAME = "Downloads"; public Receiver() {} @Override public void onReceive(Context context, Intent intent) { - NotificationCompat.Builder builder = new NotificationCompat.Builder(context); + NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context, DOWNLOADS_CHANNEL_ID); NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE); if (intent.getAction().equals(ACTION_DOWNLOAD)) { @@ -43,13 +46,13 @@ public class Receiver extends BroadcastReceiver { String text = extras.getString(EXTRA_NOTIFICATION_TEXT); String ticker = extras.getString(EXTRA_NOTIFICATION_TICKER); - builder.setContentTitle(title) + notificationBuilder.setContentTitle(title) .setContentText(text) .setTicker(ticker) .setAutoCancel(true); if (state.equals(STARTED)) - builder.setOngoing(true) + notificationBuilder.setOngoing(true) .setSmallIcon(android.R.drawable.stat_sys_download); else if (state.equals(COMPLETED)) { String fileName = extras.getString(EXTRA_FILE_NAME, "NONE"); @@ -66,14 +69,18 @@ public class Receiver extends BroadcastReceiver { Intent chooser = Intent.createChooser(chooserIntent, "Open With..."); PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, chooser, PendingIntent.FLAG_CANCEL_CURRENT); - builder.setContentIntent(pendingIntent) + notificationBuilder.setContentIntent(pendingIntent) .setSmallIcon(android.R.drawable.stat_sys_download_done); } else Timber.w("File doesn't exist."); } - Notification notification = builder.build(); - notificationManager.notify(id, notification); + + // Since Android Oreo notification channel is needed. + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) + notificationManager.createNotificationChannel(new NotificationChannel(DOWNLOADS_CHANNEL_ID, DOWNLOADS_CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH)); + + notificationManager.notify(id, notificationBuilder.build()); } } diff --git a/app/src/main/java/gr/thmmy/mthmmy/services/DownloadService.java b/app/src/main/java/gr/thmmy/mthmmy/services/DownloadService.java index a00cffb0..15aa0d98 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/services/DownloadService.java +++ b/app/src/main/java/gr/thmmy/mthmmy/services/DownloadService.java @@ -134,9 +134,8 @@ public class DownloadService extends IntentService { File file = new File(dirPath, fileName); for (int i = 1; ; i++) { - if (!file.exists()) { + if (!file.exists()) break; - } file = new File(dirPath, String.format(nameFormat, i)); } @@ -155,7 +154,7 @@ public class DownloadService extends IntentService { // Register download DownloadManager mManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE); long length = file.length(); - mManager.addCompletedDownload(fileName, "edo mporei na mpei ena description", false, getMimeType(file), SAVE_DIR +File.separator+ fileName, length, false); + mManager.addCompletedDownload(fileName, fileName, false, getMimeType(file), SAVE_DIR +File.separator+ fileName, length, false); } else Timber.e("No attachment in response!"); @@ -182,20 +181,20 @@ public class DownloadService extends IntentService { Intent intent = new Intent(ACTION_DOWNLOAD); switch (type) { case STARTED: { - intent.putExtra(EXTRA_NOTIFICATION_TITLE, "Download Started"); - intent.putExtra(EXTRA_NOTIFICATION_TEXT, "\"" + fileName + "\" downloading..."); + intent.putExtra(EXTRA_NOTIFICATION_TITLE, "\"" + fileName + "\" downloading..."); + intent.putExtra(EXTRA_NOTIFICATION_TEXT, "Download Started"); intent.putExtra(EXTRA_NOTIFICATION_TICKER, "Downloading..."); break; } case COMPLETED: { - intent.putExtra(EXTRA_NOTIFICATION_TITLE, "Download Completed"); - intent.putExtra(EXTRA_NOTIFICATION_TEXT, "\"" + fileName + "\" finished downloading."); + intent.putExtra(EXTRA_NOTIFICATION_TITLE, "\"" + fileName + "\" finished downloading."); + intent.putExtra(EXTRA_NOTIFICATION_TEXT, "Download Completed"); intent.putExtra(EXTRA_NOTIFICATION_TICKER, "Download Completed"); break; } case FAILED: { - intent.putExtra(EXTRA_NOTIFICATION_TITLE, "Download Failed"); - intent.putExtra(EXTRA_NOTIFICATION_TEXT, "\"" + fileName + "\" failed."); + intent.putExtra(EXTRA_NOTIFICATION_TITLE, "\"" + fileName + "\" failed."); + intent.putExtra(EXTRA_NOTIFICATION_TEXT, "Download Failed"); intent.putExtra(EXTRA_NOTIFICATION_TICKER, "Download Failed"); break; } @@ -216,12 +215,11 @@ public class DownloadService extends IntentService { String type = null; final String url = file.toString(); final String extension = MimeTypeMap.getFileExtensionFromUrl(url); - if (extension != null) { + if (extension != null) type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.toLowerCase()); - } - if (type == null) { - type = ""; // fallback type. You might set it to */* - } + if (type == null) + type = "*/*"; + return type; } diff --git a/app/src/main/java/gr/thmmy/mthmmy/services/NotificationService.java b/app/src/main/java/gr/thmmy/mthmmy/services/NotificationService.java index 64e8e1a2..3bf9b658 100644 --- a/app/src/main/java/gr/thmmy/mthmmy/services/NotificationService.java +++ b/app/src/main/java/gr/thmmy/mthmmy/services/NotificationService.java @@ -6,8 +6,6 @@ import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; -import android.media.RingtoneManager; -import android.net.Uri; import android.os.Build; import android.os.Bundle; import android.service.notification.StatusBarNotification; @@ -26,7 +24,7 @@ import gr.thmmy.mthmmy.base.BaseApplication; import gr.thmmy.mthmmy.model.PostNotification; import timber.log.Timber; -import static android.support.v4.app.NotificationCompat.PRIORITY_HIGH; +import static android.support.v4.app.NotificationCompat.PRIORITY_MAX; import static gr.thmmy.mthmmy.activities.topic.TopicActivity.BUNDLE_TOPIC_TITLE; import static gr.thmmy.mthmmy.activities.topic.TopicActivity.BUNDLE_TOPIC_URL; @@ -49,6 +47,8 @@ public class NotificationService extends FirebaseMessagingService { String poster = json.getString("poster"); sendNotification(new PostNotification(postId, topicId, topicTitle, poster)); } + else + Timber.v("Notification suppressed (own userID)."); } catch (JSONException e) { Timber.e(e, "JSON Exception"); } @@ -56,17 +56,20 @@ public class NotificationService extends FirebaseMessagingService { } private static final String CHANNEL_ID = "Posts"; + private static final String CHANNEL_NAME = "New Posts"; private static final String GROUP_KEY = "PostsGroup"; private static int requestCode = 0; private static final String NEW_POSTS_COUNT = "newPostsCount"; private static final String NEW_POST_TAG = "NEW_POST"; //notification tag private static final String SUMMARY_TAG = "SUMMARY"; + private static final String DELETED_MESSAGES_TAG = "DELETED_MESSAGES_TAG"; //notification tag /** * Create and show a new post notification. */ private void sendNotification(PostNotification postNotification) { + Timber.i("Creating a notification..."); String topicUrl = "https://www.thmmy.gr/smf/index.php?topic=" + postNotification.getTopicId() + "." + postNotification.getPostId(); Intent intent = new Intent(this, TopicActivity.class); Bundle extras = new Bundle(); @@ -93,19 +96,19 @@ public class NotificationService extends FirebaseMessagingService { Bundle notificationExtras = new Bundle(); notificationExtras.putInt(NEW_POSTS_COUNT, newPostsCount); - Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, CHANNEL_ID) .setSmallIcon(R.mipmap.ic_launcher) .setContentTitle(postNotification.getTopicTitle()) .setContentText(contentText) .setAutoCancel(true) - .setSound(defaultSoundUri) .setContentIntent(pendingIntent) + .setDefaults(Notification.DEFAULT_ALL) + .setGroup(GROUP_KEY) .addExtras(notificationExtras); if (buildVersion < Build.VERSION_CODES.O) - notificationBuilder.setPriority(PRIORITY_HIGH); + notificationBuilder.setPriority(PRIORITY_MAX); boolean createSummaryNotification = false; if(buildVersion >= Build.VERSION_CODES.LOLLIPOP) @@ -115,9 +118,6 @@ public class NotificationService extends FirebaseMessagingService { createSummaryNotification = otherNotificationsExist(topicId); } - notificationBuilder.setVibrate(new long[0]); - notificationBuilder.setGroup(GROUP_KEY); - NotificationCompat.Builder summaryNotificationBuilder = null; if(createSummaryNotification) { @@ -129,7 +129,7 @@ public class NotificationService extends FirebaseMessagingService { .setAutoCancel(true) .setStyle(new NotificationCompat.InboxStyle() .setSummaryText("New Posts")) - .setSound(defaultSoundUri); + .setDefaults(Notification.DEFAULT_ALL); } @@ -138,15 +138,11 @@ public class NotificationService extends FirebaseMessagingService { NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); // Since Android Oreo notification channel is needed. - if (buildVersion >= Build.VERSION_CODES.O) { - NotificationChannel channel = new NotificationChannel(CHANNEL_ID, "Topic Updates", NotificationManager.IMPORTANCE_HIGH); - notificationManager.createNotificationChannel(channel); - } - + if (buildVersion >= Build.VERSION_CODES.O) + notificationManager.createNotificationChannel(new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH)); notificationManager.notify(NEW_POST_TAG, topicId, notificationBuilder.build()); - if(createSummaryNotification) notificationManager.notify(SUMMARY_TAG,0, summaryNotificationBuilder.build()); } @@ -172,12 +168,35 @@ public class NotificationService extends FirebaseMessagingService { if(notificationManager!=null) { StatusBarNotification[] barNotifications = notificationManager.getActiveNotifications(); for (StatusBarNotification notification : barNotifications) { - if (notification.getTag().equals(NEW_POST_TAG) && notification.getId() != notificationId) + String tag = notification.getTag(); + if (tag!=null && tag.equals(NEW_POST_TAG) && notification.getId() != notificationId) return true; } } return false; } + @Override + public void onDeletedMessages() { + super.onDeletedMessages(); + NotificationCompat.Builder notificationBuilder = + new NotificationCompat.Builder(this, CHANNEL_ID) + .setSmallIcon(R.mipmap.ic_launcher) + .setContentTitle("Error fetching notifications!") + .setContentText("Some notifications may not have arrived successfully either due to" + + "the amount of pending messages (>100) or if the device hasn't come online for more than a month.") + .setAutoCancel(true) + .setDefaults(Notification.DEFAULT_ALL); + + if (buildVersion < Build.VERSION_CODES.O) + notificationBuilder.setPriority(Notification.PRIORITY_MAX); + + NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE); + + // Since Android Oreo notification channel is needed. + if (buildVersion >= Build.VERSION_CODES.O) + notificationManager.createNotificationChannel(new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_HIGH)); + notificationManager.notify(DELETED_MESSAGES_TAG, 0, notificationBuilder.build()); + } } diff --git a/build.gradle b/build.gradle index 731a4e70..3a61f691 100644 --- a/build.gradle +++ b/build.gradle @@ -9,9 +9,9 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:3.1.2' - classpath 'com.google.gms:google-services:3.3.0' - classpath 'io.fabric.tools:gradle:1.25.1' + classpath 'com.android.tools.build:gradle:3.1.3' + classpath 'com.google.gms:google-services:4.0.1' + classpath 'io.fabric.tools:gradle:1.25.4' } }