notification improvements (#522)

* correctly filter notifications on Api >= 26, other fixes and refactoring

* use correct areNotificationsEnabled method in MainActivity

* change notification led color
This commit is contained in:
Konrad Pozniak 2018-02-12 22:03:08 +01:00 committed by GitHub
parent ac581052c1
commit 167c460c08
7 changed files with 78 additions and 55 deletions

View File

@ -201,11 +201,11 @@ public abstract class BaseActivity extends AppCompatActivity {
}
protected void setPullNotificationCheckInterval(long minutes) {
JobManager.instance().cancelAllForTag(NotificationPullJobCreator.NOTIFICATIONS_JOB_TAG);
long checkInterval = 1000 * 60 * minutes;
new JobRequest.Builder(NotificationPullJobCreator.NOTIFICATIONS_JOB_TAG)
.setPeriodic(checkInterval)
.setUpdateCurrent(true)
.setRequiredNetworkType(JobRequest.NetworkType.CONNECTED)
.build()
.schedule();

View File

@ -42,7 +42,7 @@ import com.keylesspalace.tusky.entity.Account;
import com.keylesspalace.tusky.interfaces.ActionButtonActivity;
import com.keylesspalace.tusky.pager.TimelinePagerAdapter;
import com.keylesspalace.tusky.receiver.TimelineReceiver;
import com.keylesspalace.tusky.util.NotificationManager;
import com.keylesspalace.tusky.util.NotificationHelper;
import com.keylesspalace.tusky.util.ThemeUtils;
import com.mikepenz.google_material_typeface_library.GoogleMaterial;
import com.mikepenz.materialdrawer.AccountHeader;
@ -98,7 +98,7 @@ public class MainActivity extends BaseActivity implements ActionButtonActivity {
int tabPosition = 0;
if (intent != null) {
long accountId = intent.getLongExtra(NotificationManager.ACCOUNT_ID, -1);
long accountId = intent.getLongExtra(NotificationHelper.ACCOUNT_ID, -1);
if(accountId != -1) {
// user clicked a notification, show notification tab and switch user if necessary
@ -181,7 +181,7 @@ public class MainActivity extends BaseActivity implements ActionButtonActivity {
tintTab(tab, true);
if(tab.getPosition() == 1) {
NotificationManager.clearNotificationsForActiveAccount(MainActivity.this);
NotificationHelper.clearNotificationsForActiveAccount(MainActivity.this);
}
}
@ -199,7 +199,7 @@ public class MainActivity extends BaseActivity implements ActionButtonActivity {
}
// Setup push notifications
if (TuskyApplication.getAccountManager().notificationsEnabled()) {
if (NotificationHelper.areNotificationsEnabled(this)) {
enablePushNotifications();
} else {
disablePushNotifications();
@ -212,7 +212,7 @@ public class MainActivity extends BaseActivity implements ActionButtonActivity {
protected void onResume() {
super.onResume();
NotificationManager.clearNotificationsForActiveAccount(this);
NotificationHelper.clearNotificationsForActiveAccount(this);
/* After editing a profile, the profile header in the navigation drawer needs to be
* refreshed */
@ -437,11 +437,11 @@ public class MainActivity extends BaseActivity implements ActionButtonActivity {
AccountManager accountManager = TuskyApplication.getAccountManager();
NotificationManager.deleteNotificationChannelsForAccount(accountManager.getActiveAccount(), MainActivity.this);
NotificationHelper.deleteNotificationChannelsForAccount(accountManager.getActiveAccount(), MainActivity.this);
AccountEntity newAccount = accountManager.logActiveAccountOut();
if (!accountManager.notificationsEnabled()) disablePushNotifications();
if (!NotificationHelper.areNotificationsEnabled(MainActivity.this)) disablePushNotifications();
Intent intent;
if (newAccount == null) {
@ -490,7 +490,7 @@ public class MainActivity extends BaseActivity implements ActionButtonActivity {
am.updateActiveAccount(me);
NotificationManager.createNotificationChannelsForAccount(am.getActiveAccount(), this);
NotificationHelper.createNotificationChannelsForAccount(am.getActiveAccount(), this);
List<AccountEntity> allAccounts = am.getAllAccountsOrderedByActive();

View File

@ -30,7 +30,7 @@ import com.keylesspalace.tusky.db.AccountEntity;
import com.keylesspalace.tusky.entity.Notification;
import com.keylesspalace.tusky.json.SpannedTypeAdapter;
import com.keylesspalace.tusky.network.MastodonApi;
import com.keylesspalace.tusky.util.NotificationManager;
import com.keylesspalace.tusky.util.NotificationHelper;
import com.keylesspalace.tusky.util.OkHttpUtils;
import java.io.IOException;
@ -98,7 +98,7 @@ public final class NotificationPullJobCreator implements JobCreator {
@NonNull
@Override
protected Result onRunJob(Params params) {
protected Result onRunJob(@NonNull Params params) {
List<AccountEntity> accountList = new ArrayList<>(TuskyApplication.getAccountManager().getAllAccountsOrderedByActive());
@ -144,7 +144,7 @@ public final class NotificationPullJobCreator implements JobCreator {
if (isBiggerThan(currentId, newId)) {
account.setLastNotificationId(notification.id);
NotificationManager.make(context, notification, account);
NotificationHelper.make(context, notification, account);
}
}

View File

@ -20,7 +20,7 @@ import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import com.keylesspalace.tusky.db.AccountEntity;
import com.keylesspalace.tusky.util.NotificationManager;
import com.keylesspalace.tusky.util.NotificationHelper;
public class SplashActivity extends AppCompatActivity {
@Override
@ -30,7 +30,7 @@ public class SplashActivity extends AppCompatActivity {
/* Determine whether the user is currently logged in, and if so go ahead and load the
* timeline. Otherwise, start the activity_login screen. */
NotificationManager.deleteLegacyNotificationChannels(this);
NotificationHelper.deleteLegacyNotificationChannels(this);
AccountEntity activeAccount = TuskyApplication.getAccountManager().getActiveAccount();

View File

@ -24,6 +24,8 @@ import com.keylesspalace.tusky.entity.Account
* @author ConnyDuck
*/
private const val TAG = "AccountManager"
class AccountManager {
@Volatile var activeAccount: AccountEntity? = null
@ -50,7 +52,7 @@ class AccountManager {
activeAccount?.let{
it.isActive = false
Log.d("AccountManager", "saving account with id "+it.id)
Log.d(TAG, "addAccount: saving account with id "+it.id)
accountDao.insertOrReplace(it)
}
@ -66,13 +68,7 @@ class AccountManager {
*/
fun saveAccount(account: AccountEntity) {
if(account.id != 0L) {
Log.d("AccountManager", "saving account with id "+account.id)
val index = accounts.indexOf(account)
if (index != -1) {
accounts.removeAt(index)
accounts.add(account)
}
Log.d(TAG, "saveAccount: saving account with id "+account.id)
accountDao.insertOrReplace(account)
}
@ -93,6 +89,7 @@ class AccountManager {
if(accounts.size > 0) {
accounts[0].isActive = true
activeAccount = accounts[0]
Log.d(TAG, "logActiveAccountOut: saving account with id "+accounts[0].id)
accountDao.insertOrReplace(accounts[0])
} else {
activeAccount = null
@ -115,10 +112,8 @@ class AccountManager {
it.displayName = account.getDisplayName()
it.profilePictureUrl = account.avatar
Log.d("AccountManager", "id before save "+it.id)
Log.d(TAG, "updateActiveAccount: saving account with id "+it.id)
it.id = accountDao.insertOrReplace(it)
Log.d("AccountManager", "id after save "+it.id)
val accountIndex = accounts.indexOf(it)
@ -140,6 +135,7 @@ class AccountManager {
fun setActiveAccount(accountId: Long) {
activeAccount?.let{
Log.d(TAG, "setActiveAccount: saving account with id "+it.id)
it.isActive = false
accountDao.insertOrReplace(it)
}
@ -172,7 +168,7 @@ class AccountManager {
/**
* @return true if at least one account has notifications enabled
*/
fun notificationsEnabled(): Boolean {
fun areNotificationsEnabled(): Boolean {
return accounts.any { it.notificationsEnabled }
}

View File

@ -20,12 +20,12 @@ import android.content.Context
import android.content.Intent
import com.keylesspalace.tusky.TuskyApplication
import com.keylesspalace.tusky.util.NotificationManager
import com.keylesspalace.tusky.util.NotificationHelper
class NotificationClearBroadcastReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
val accountId = intent.getLongExtra(NotificationManager.ACCOUNT_ID, -1)
val accountId = intent.getLongExtra(NotificationHelper.ACCOUNT_ID, -1)
val accountManager = TuskyApplication.getAccountManager()
val account = accountManager.getAccountById(accountId)

View File

@ -17,6 +17,7 @@ package com.keylesspalace.tusky.util;
import android.app.NotificationChannel;
import android.app.NotificationChannelGroup;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
@ -47,12 +48,12 @@ import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class NotificationManager {
public class NotificationHelper {
/** constants used in Intents */
public static final String ACCOUNT_ID = "account_id";
private static final String TAG = "NotificationManager";
private static final String TAG = "NotificationHelper";
/** notification channels used on Android O+ **/
private static final String CHANNEL_MENTION = "CHANNEL_MENTION";
@ -71,7 +72,7 @@ public class NotificationManager {
public static void make(final Context context, Notification body, AccountEntity account) {
if (!filterNotification(account, body)) {
if (!filterNotification(account, body, context)) {
return;
}
@ -166,8 +167,7 @@ public class NotificationManager {
builder.setVisibility(NotificationCompat.VISIBILITY_PRIVATE);
builder.setCategory(NotificationCompat.CATEGORY_SOCIAL);
android.app.NotificationManager notificationManager = (android.app.NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
//noinspection ConstantConditions
notificationManager.notify((int)account.getId(), builder.build());
@ -176,8 +176,7 @@ public class NotificationManager {
public static void createNotificationChannelsForAccount(AccountEntity account, Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
android.app.NotificationManager mNotificationManager =
(android.app.NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
String[] channelIds = new String[]{
CHANNEL_MENTION+account.getIdentifier(),
@ -202,17 +201,18 @@ public class NotificationManager {
NotificationChannelGroup channelGroup = new NotificationChannelGroup(account.getIdentifier(), account.getFullName());
//noinspection ConstantConditions
mNotificationManager.createNotificationChannelGroup(channelGroup);
notificationManager.createNotificationChannelGroup(channelGroup);
for (int i = 0; i < channelIds.length; i++) {
String id = channelIds[i];
String name = context.getString(channelNames[i]);
String description = context.getString(channelDescriptions[i]);
int importance = android.app.NotificationManager.IMPORTANCE_DEFAULT;
int importance = NotificationManager.IMPORTANCE_DEFAULT;
NotificationChannel channel = new NotificationChannel(id, name, importance);
channel.setDescription(description);
channel.enableLights(true);
channel.setLightColor(0xFF2B90D9);
channel.enableVibration(true);
channel.setShowBadge(true);
channel.setGroup(account.getIdentifier());
@ -220,7 +220,7 @@ public class NotificationManager {
}
//noinspection ConstantConditions
mNotificationManager.createNotificationChannels(channels);
notificationManager.createNotificationChannels(channels);
}
}
@ -228,11 +228,10 @@ public class NotificationManager {
public static void deleteNotificationChannelsForAccount(AccountEntity account, Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
android.app.NotificationManager mNotificationManager =
(android.app.NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
//noinspection ConstantConditions
mNotificationManager.deleteNotificationChannelGroup(account.getIdentifier());
notificationManager.deleteNotificationChannelGroup(account.getIdentifier());
}
}
@ -241,17 +240,42 @@ public class NotificationManager {
// delete the notification channels that where used before the multi account mode was introduced to avoid confusion
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
android.app.NotificationManager mNotificationManager =
(android.app.NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
//noinspection ConstantConditions
mNotificationManager.deleteNotificationChannel(CHANNEL_MENTION);
mNotificationManager.deleteNotificationChannel(CHANNEL_FAVOURITE);
mNotificationManager.deleteNotificationChannel(CHANNEL_BOOST);
mNotificationManager.deleteNotificationChannel(CHANNEL_FOLLOW);
notificationManager.deleteNotificationChannel(CHANNEL_MENTION);
notificationManager.deleteNotificationChannel(CHANNEL_FAVOURITE);
notificationManager.deleteNotificationChannel(CHANNEL_BOOST);
notificationManager.deleteNotificationChannel(CHANNEL_FOLLOW);
}
}
public static boolean areNotificationsEnabled(Context context) {
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
// on Android >= O, notifications are enabled, if at least one channel is enabled
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
//noinspection ConstantConditions
if(notificationManager.areNotificationsEnabled()) {
for(NotificationChannel channel: notificationManager.getNotificationChannels()) {
if(channel.getImportance() > NotificationManager.IMPORTANCE_NONE) {
Log.d(TAG, "NotificationsEnabled");
return true;
}
}
}
Log.d(TAG, "NotificationsDisabled");
return false;
} else {
// on Android < O, notifications are enabled, if at least one account has notification enabled
return TuskyApplication.getAccountManager().areNotificationsEnabled();
}
}
public static void clearNotificationsForActiveAccount(Context context) {
AccountManager accountManager = TuskyApplication.getAccountManager();
AccountEntity account = accountManager.getActiveAccount();
@ -259,18 +283,21 @@ public class NotificationManager {
account.setActiveNotifications("[]");
accountManager.saveAccount(account);
android.app.NotificationManager manager = (android.app.NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
//noinspection ConstantConditions
manager.cancel((int)account.getId());
notificationManager.cancel((int)account.getId());
}
}
private static boolean filterNotification(AccountEntity account,
Notification notification) {
private static boolean filterNotification(AccountEntity account, Notification notification,
Context context) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
return true; //do not filter on Android O or newer, the system does it for us
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
//noinspection ConstantConditions
NotificationChannel channel = notificationManager.getNotificationChannel(getChannelId(account, notification));
return channel.getImportance() > NotificationManager.IMPORTANCE_NONE;
}
switch (notification.type) {
@ -317,7 +344,7 @@ public class NotificationManager {
}
if (account.getNotificationLight()) {
builder.setLights(0xFF00FF8F, 300, 1000);
builder.setLights(0xFF2B90D9, 300, 1000);
}
}