mirror of
https://github.com/nerzhul/ownCloud-SMS-App.git
synced 2025-06-06 23:46:13 +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
|
- oraclejdk8
|
||||||
|
|
||||||
before_install:
|
before_install:
|
||||||
- yes | sdkmanager "platforms;android-27"
|
- yes | sdkmanager "platforms;android-28"
|
||||||
|
|
||||||
android:
|
android:
|
||||||
components:
|
components:
|
||||||
- tools
|
- tools
|
||||||
- platform-tools
|
- platform-tools
|
||||||
- extra
|
- extra
|
||||||
- build-tools-27.0.3
|
- build-tools-28.0.3
|
||||||
- android-27
|
- android-28
|
||||||
licenses:
|
licenses:
|
||||||
- 'android-sdk-license-.+'
|
- 'android-sdk-license-.+'
|
||||||
- 'google-gdk-license-.+'
|
- 'google-gdk-license-.+'
|
||||||
|
@ -93,12 +93,16 @@ public interface ASyncSMSSync {
|
|||||||
|
|
||||||
if (prefs.showSyncNotifications()) {
|
if (prefs.showSyncNotifications()) {
|
||||||
OCSMSNotificationUI.notify(_context, _context.getString(R.string.sync_title),
|
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();
|
try {
|
||||||
performSync(smsBuffer);
|
syncStartupDate = smsBuffer.getLastMessageDate();
|
||||||
hasSyncSomething = true;
|
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
|
// Fetch API version first to do some early verifications
|
||||||
Log.i(ASyncSMSSync.TAG, "Server API version: " + _client.getServerAPIVersion());
|
Log.i(ASyncSMSSync.TAG, "Server API version: " + _client.getServerAPIVersion());
|
||||||
_client.doPushRequest(smsBuffer);
|
_client.doPushRequest(smsBuffer);
|
||||||
OCSMSNotificationUI.cancel(_context);
|
OCSMSNotificationUI.cancel(_context, OCSMSNotificationType.SYNC_FAILED);
|
||||||
} catch (IllegalStateException e) { // Fail to read account data
|
} catch (IllegalStateException e) { // Fail to read account data
|
||||||
OCSMSNotificationUI.notify(_context, _context.getString(R.string.fatal_error),
|
OCSMSNotificationUI.notify(_context, _context.getString(R.string.fatal_error),
|
||||||
e.getMessage(), OCSMSNotificationType.SYNC_FAILED.ordinal());
|
e.getMessage(), OCSMSNotificationType.SYNC_FAILED);
|
||||||
} catch (OCSyncException e) {
|
} catch (OCSyncException e) {
|
||||||
Log.e(ASyncSMSSync.TAG, _context.getString(e.getErrorId()));
|
Log.e(ASyncSMSSync.TAG, _context.getString(e.getErrorId()));
|
||||||
OCSMSNotificationUI.notify(_context, _context.getString(R.string.fatal_error),
|
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();
|
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 {
|
public enum OCSMSNotificationType {
|
||||||
SYNC,
|
SYNC(OCSMSNotificationChannel.SYNC, 0),
|
||||||
SYNC_FAILED,
|
SYNC_FAILED(OCSMSNotificationChannel.DEFAULT, 1),
|
||||||
DEBUG,
|
PERMISSION(OCSMSNotificationChannel.DEFAULT, 2);
|
||||||
PERMISSION,
|
|
||||||
|
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/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
|
import android.app.NotificationChannel;
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.res.Resources;
|
import android.content.res.Resources;
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.BitmapFactory;
|
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.support.v4.app.NotificationCompat;
|
import android.support.v4.app.NotificationCompat;
|
||||||
|
|
||||||
import fr.unix_experience.owncloud_sms.R;
|
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
|
* Helper class for showing and canceling ui
|
||||||
@ -42,25 +42,30 @@ public class OCSMSNotificationUI {
|
|||||||
*/
|
*/
|
||||||
private static final String NOTIFICATION_TAG = "OCSMS_NOTIFICATION";
|
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
|
* Shows the notification, or updates a previously shown notification of
|
||||||
* this type, with the given parameters.
|
* this type, with the given parameters.
|
||||||
*
|
*
|
||||||
* @see #cancel(Context)
|
* @see #cancel(Context, OCSMSNotificationType)
|
||||||
*/
|
*/
|
||||||
public static void notify(Context context, String titleString,
|
public static void notify(Context context, String titleString, String contentString,
|
||||||
String contentString, int number) {
|
String channelId, int notificationId) {
|
||||||
Resources res = context.getResources();
|
Resources res = context.getResources();
|
||||||
|
|
||||||
// This image is used as the notification's large icon (thumbnail).
|
// This image is used as the notification's large icon (thumbnail).
|
||||||
// TODO: Remove this if your notification has no relevant 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);
|
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,
|
// Set appropriate defaults for the notification light, sound,
|
||||||
// and vibration.
|
// and vibration.
|
||||||
@ -77,9 +82,6 @@ public class OCSMSNotificationUI {
|
|||||||
// Set ticker text (preview) information for this notification.
|
// Set ticker text (preview) information for this notification.
|
||||||
//.setTicker(ticker)
|
//.setTicker(ticker)
|
||||||
|
|
||||||
// Show a number. This is useful when stacking notifications of
|
|
||||||
// a single type.
|
|
||||||
.setNumber(number)
|
|
||||||
.setStyle(new NotificationCompat.BigTextStyle()
|
.setStyle(new NotificationCompat.BigTextStyle()
|
||||||
.bigText(contentString)
|
.bigText(contentString)
|
||||||
.setBigContentTitle(title)
|
.setBigContentTitle(title)
|
||||||
@ -87,24 +89,45 @@ public class OCSMSNotificationUI {
|
|||||||
.setAutoCancel(true)
|
.setAutoCancel(true)
|
||||||
.setColor(context.getResources().getColor(R.color.oc_primary));
|
.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, int notificationId) {
|
||||||
private static void notify(Context context, Notification notification) {
|
|
||||||
NotificationManager nm = (NotificationManager) context
|
NotificationManager nm = (NotificationManager) context
|
||||||
.getSystemService(Context.NOTIFICATION_SERVICE);
|
.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
|
* 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, OCSMSNotificationType type) {
|
||||||
public static void cancel(Context context) {
|
cancel(context, type.getNotificationId());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void cancel(Context context, int notificationId) {
|
||||||
NotificationManager nm = (NotificationManager) context
|
NotificationManager nm = (NotificationManager) context
|
||||||
.getSystemService(Context.NOTIFICATION_SERVICE);
|
.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
|
// For context only show a notification
|
||||||
OCSMSNotificationUI.notify(context, context.getString(R.string.notif_permission_required),
|
OCSMSNotificationUI.notify(context, context.getString(R.string.notif_permission_required),
|
||||||
context.getString(R.string.notif_permission_required_content),
|
context.getString(R.string.notif_permission_required_content),
|
||||||
OCSMSNotificationType.PERMISSION.ordinal());
|
OCSMSNotificationType.PERMISSION);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -45,7 +45,7 @@ class SmsSyncAdapter extends AbstractThreadedSyncAdapter {
|
|||||||
|
|
||||||
if (new OCSMSSharedPrefs(getContext()).showSyncNotifications()) {
|
if (new OCSMSSharedPrefs(getContext()).showSyncNotifications()) {
|
||||||
OCSMSNotificationUI.notify(getContext(), getContext().getString(R.string.sync_title),
|
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 {
|
try {
|
||||||
@ -56,14 +56,13 @@ class SmsSyncAdapter extends AbstractThreadedSyncAdapter {
|
|||||||
|
|
||||||
// and push datas
|
// and push datas
|
||||||
_client.doPushRequest(null);
|
_client.doPushRequest(null);
|
||||||
OCSMSNotificationUI.cancel(getContext());
|
OCSMSNotificationUI.cancel(getContext(), OCSMSNotificationType.SYNC_FAILED);
|
||||||
} catch (IllegalStateException e) {
|
} catch (IllegalStateException e) {
|
||||||
OCSMSNotificationUI.notify(getContext(), getContext().getString(R.string.fatal_error),
|
OCSMSNotificationUI.notify(getContext(), getContext().getString(R.string.fatal_error),
|
||||||
e.getMessage(), OCSMSNotificationType.SYNC_FAILED.ordinal());
|
e.getMessage(), OCSMSNotificationType.SYNC_FAILED);
|
||||||
} catch (OCSyncException e) {
|
} catch (OCSyncException e) {
|
||||||
OCSMSNotificationUI.cancel(getContext());
|
|
||||||
OCSMSNotificationUI.notify(getContext(), getContext().getString(R.string.fatal_error),
|
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) {
|
if (e.getErrorType() == OCSyncErrorType.IO) {
|
||||||
syncResult.stats.numIoExceptions++;
|
syncResult.stats.numIoExceptions++;
|
||||||
}
|
}
|
||||||
@ -76,6 +75,8 @@ class SmsSyncAdapter extends AbstractThreadedSyncAdapter {
|
|||||||
else {
|
else {
|
||||||
Log.w(SmsSyncAdapter.TAG, "onPerformSync: unhandled response");
|
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_title">Sync process</string>
|
||||||
<string name="sync_inprogress">Sync in progress …</string>
|
<string name="sync_inprogress">Sync in progress …</string>
|
||||||
<string name="fatal_error">Fatal error ! </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 -->
|
<!-- Errors -->
|
||||||
<string name="err_sync_get_smslist">Error #1: Invalid data received from server when getting previous messages</string>
|
<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