mirror of
https://github.com/nerzhul/ownCloud-SMS-App.git
synced 2025-06-05 23:16:27 +00:00
Fix notifications not being shown on modern Androids (#221)
* Add notification channels support * Update Travis CI config
This commit is contained in:
parent
5ea03be8d6
commit
7d677a9fe2
@ -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-.+'
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -17,17 +17,17 @@ package fr.unix_experience.owncloud_sms.notifications;
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -206,6 +206,8 @@
|
||||
<string name="sync_title">Sync process</string>
|
||||
<string name="sync_inprogress">Sync in progress …</string>
|
||||
<string name="fatal_error">Fatal error ! </string>
|
||||
<string name="notification_channel_name_default">Default</string>
|
||||
<string name="notification_channel_name_sync">Sync</string>
|
||||
|
||||
<!-- Errors -->
|
||||
<string name="err_sync_get_smslist">Error #1: Invalid data received from server when getting previous messages</string>
|
||||
|
Loading…
x
Reference in New Issue
Block a user