Merge branch '488-show-notifications-for-new-blog-posts' into 'master'

Show notifications for new blog posts

This also adds a setting allowing people to turn blog post notifications off.

As instructed, this does not yet improve upon the current notification mechanism, but rather follows it, leaving the improvements for  #289.

Closes #488

See merge request !258
This commit is contained in:
akwizgran
2016-08-01 12:36:16 +00:00
9 changed files with 140 additions and 11 deletions

View File

@@ -133,6 +133,10 @@
<item quantity="one">New forum post.</item> <item quantity="one">New forum post.</item>
<item quantity="other">%d new forum posts.</item> <item quantity="other">%d new forum posts.</item>
</plurals> </plurals>
<plurals name="blog_post_notification_text">
<item quantity="one">New blog post.</item>
<item quantity="other">%d new blog posts.</item>
</plurals>
<!-- Settings --> <!-- Settings -->
<string name="settings_title">Settings</string> <string name="settings_title">Settings</string>
@@ -151,6 +155,7 @@
<string name="notification_settings_title">Notifications</string> <string name="notification_settings_title">Notifications</string>
<string name="notify_private_messages_setting">Show alerts for private messages</string> <string name="notify_private_messages_setting">Show alerts for private messages</string>
<string name="notify_forum_posts_setting">Show alerts for forum posts</string> <string name="notify_forum_posts_setting">Show alerts for forum posts</string>
<string name="notify_blog_posts_setting">Show alerts for blog posts</string>
<string name="notify_vibration_setting">Vibrate</string> <string name="notify_vibration_setting">Vibrate</string>
<string name="notify_sound_setting">Sound</string> <string name="notify_sound_setting">Sound</string>
<string name="notify_sound_setting_default">Default ringtone</string> <string name="notify_sound_setting_default">Default ringtone</string>

View File

@@ -69,6 +69,12 @@
android:persistent="false" android:persistent="false"
android:title="@string/notify_forum_posts_setting"/> android:title="@string/notify_forum_posts_setting"/>
<CheckBoxPreference
android:defaultValue="true"
android:key="pref_key_notify_blog_posts"
android:persistent="false"
android:title="@string/notify_blog_posts_setting"/>
<CheckBoxPreference <CheckBoxPreference
android:defaultValue="true" android:defaultValue="true"
android:key="pref_key_notify_vibration" android:key="pref_key_notify_vibration"

View File

@@ -18,6 +18,7 @@ import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.db.DatabaseExecutor; import org.briarproject.api.db.DatabaseExecutor;
import org.briarproject.api.db.DbException; import org.briarproject.api.db.DbException;
import org.briarproject.api.event.BlogPostAddedEvent;
import org.briarproject.api.event.Event; import org.briarproject.api.event.Event;
import org.briarproject.api.event.EventListener; import org.briarproject.api.event.EventListener;
import org.briarproject.api.event.ForumInvitationReceivedEvent; import org.briarproject.api.event.ForumInvitationReceivedEvent;
@@ -57,6 +58,7 @@ import static android.support.v4.app.NotificationCompat.CATEGORY_SOCIAL;
import static android.support.v4.app.NotificationCompat.VISIBILITY_SECRET; import static android.support.v4.app.NotificationCompat.VISIBILITY_SECRET;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.android.BriarActivity.GROUP_ID; import static org.briarproject.android.BriarActivity.GROUP_ID;
import static org.briarproject.android.fragment.SettingsFragment.PREF_NOTIFY_BLOG;
import static org.briarproject.android.fragment.SettingsFragment.SETTINGS_NAMESPACE; import static org.briarproject.android.fragment.SettingsFragment.SETTINGS_NAMESPACE;
class AndroidNotificationManagerImpl implements AndroidNotificationManager, class AndroidNotificationManagerImpl implements AndroidNotificationManager,
@@ -64,7 +66,8 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
private static final int PRIVATE_MESSAGE_NOTIFICATION_ID = 3; private static final int PRIVATE_MESSAGE_NOTIFICATION_ID = 3;
private static final int FORUM_POST_NOTIFICATION_ID = 4; private static final int FORUM_POST_NOTIFICATION_ID = 4;
private static final int INTRODUCTION_SUCCESS_NOTIFICATION_ID = 5; private static final int BLOG_POST_NOTIFICATION_ID = 5;
private static final int INTRODUCTION_SUCCESS_NOTIFICATION_ID = 6;
private static final String CONTACT_URI = private static final String CONTACT_URI =
"content://org.briarproject/contact"; "content://org.briarproject/contact";
private static final String FORUM_URI = private static final String FORUM_URI =
@@ -84,9 +87,10 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
private final Map<GroupId, Integer> forumCounts = new HashMap<>(); private final Map<GroupId, Integer> forumCounts = new HashMap<>();
private final AtomicBoolean used = new AtomicBoolean(false); private final AtomicBoolean used = new AtomicBoolean(false);
private int contactTotal = 0, forumTotal = 0; private int contactTotal = 0, forumTotal = 0, blogTotal = 0;
private int nextRequestId = 0; private int nextRequestId = 0;
private GroupId visibleGroup = null; private GroupId visibleGroup = null;
private boolean blogBlocked = false;
private volatile Settings settings = new Settings(); private volatile Settings settings = new Settings();
@@ -158,6 +162,9 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
} else if (e instanceof ForumPostReceivedEvent) { } else if (e instanceof ForumPostReceivedEvent) {
ForumPostReceivedEvent m = (ForumPostReceivedEvent) e; ForumPostReceivedEvent m = (ForumPostReceivedEvent) e;
showForumPostNotification(m.getGroupId()); showForumPostNotification(m.getGroupId());
} else if (e instanceof BlogPostAddedEvent) {
BlogPostAddedEvent be = (BlogPostAddedEvent) e;
showBlogPostNotification(be.getGroupId());
} else if (e instanceof IntroductionRequestReceivedEvent) { } else if (e instanceof IntroductionRequestReceivedEvent) {
ContactId c = ((IntroductionRequestReceivedEvent) e).getContactId(); ContactId c = ((IntroductionRequestReceivedEvent) e).getContactId();
showNotificationForPrivateConversation(c); showNotificationForPrivateConversation(c);
@@ -351,6 +358,61 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
} }
} }
@Override
public void showBlogPostNotification(final GroupId g) {
androidExecutor.execute(new Runnable() {
@Override
public void run() {
if (!blogBlocked) {
blogTotal++;
updateBlogPostNotification();
}
}
});
}
@Override
public void clearBlogPostNotification() {
blogTotal = 0;
Object o = appContext.getSystemService(NOTIFICATION_SERVICE);
NotificationManager nm = (NotificationManager) o;
nm.cancel(BLOG_POST_NOTIFICATION_ID);
}
private void updateBlogPostNotification() {
if (settings.getBoolean(PREF_NOTIFY_BLOG, true)) {
NotificationCompat.Builder b =
new NotificationCompat.Builder(appContext);
b.setSmallIcon(R.drawable.message_notification_icon);
b.setContentTitle(appContext.getText(R.string.app_name));
b.setContentText(appContext.getResources().getQuantityString(
R.plurals.blog_post_notification_text, blogTotal,
blogTotal));
String ringtoneUri = settings.get("notifyRingtoneUri");
if (!StringUtils.isNullOrEmpty(ringtoneUri))
b.setSound(Uri.parse(ringtoneUri));
b.setDefaults(getDefaults());
b.setOnlyAlertOnce(true);
b.setAutoCancel(true);
Intent i = new Intent(appContext, NavDrawerActivity.class);
i.putExtra(NavDrawerActivity.INTENT_BLOGS, true);
i.setFlags(FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP);
TaskStackBuilder t = TaskStackBuilder.create(appContext);
t.addParentStack(NavDrawerActivity.class);
t.addNextIntent(i);
b.setContentIntent(t.getPendingIntent(nextRequestId++, 0));
if (Build.VERSION.SDK_INT >= 21) {
b.setCategory(CATEGORY_SOCIAL);
b.setVisibility(VISIBILITY_SECRET);
}
Object o = appContext.getSystemService(NOTIFICATION_SERVICE);
NotificationManager nm = (NotificationManager) o;
nm.notify(BLOG_POST_NOTIFICATION_ID, b.build());
}
}
@Override @Override
public void blockNotification(final GroupId g) { public void blockNotification(final GroupId g) {
androidExecutor.execute(new Runnable() { androidExecutor.execute(new Runnable() {
@@ -371,6 +433,26 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
}); });
} }
@Override
public void blockBlogNotification() {
androidExecutor.execute(new Runnable() {
@Override
public void run() {
blogBlocked = true;
}
});
}
@Override
public void unblockBlogNotification() {
androidExecutor.execute(new Runnable() {
@Override
public void run() {
blogBlocked = false;
}
});
}
private void showNotificationForPrivateConversation(final ContactId c) { private void showNotificationForPrivateConversation(final ContactId c) {
androidExecutor.execute(new Runnable() { androidExecutor.execute(new Runnable() {
@Override @Override

View File

@@ -32,7 +32,7 @@ public abstract class BriarFragmentActivity extends BriarActivity {
} }
} }
protected void clearBackStack() { void clearBackStack() {
getSupportFragmentManager() getSupportFragmentManager()
.popBackStackImmediate( .popBackStackImmediate(
null, null,
@@ -69,7 +69,7 @@ public abstract class BriarFragmentActivity extends BriarActivity {
else startFragment(fragment, true); else startFragment(fragment, true);
} }
protected void showMessageDialog(int titleStringId, int msgStringId) { void showMessageDialog(int titleStringId, int msgStringId) {
// TODO replace with custom dialog fragment ? // TODO replace with custom dialog fragment ?
AlertDialog.Builder builder = new AlertDialog.Builder(this, AlertDialog.Builder builder = new AlertDialog.Builder(this,
R.style.BriarDialogTheme); R.style.BriarDialogTheme);
@@ -80,12 +80,12 @@ public abstract class BriarFragmentActivity extends BriarActivity {
dialog.show(); dialog.show();
} }
protected void startFragment(BaseFragment fragment, private void startFragment(BaseFragment fragment,
boolean isAddedToBackStack) { boolean isAddedToBackStack) {
startFragment(fragment, 0, 0, isAddedToBackStack); startFragment(fragment, 0, 0, isAddedToBackStack);
} }
protected void startFragment(BaseFragment fragment, private void startFragment(BaseFragment fragment,
@AnimRes int inAnimation, @AnimRes int outAnimation, @AnimRes int inAnimation, @AnimRes int outAnimation,
boolean isAddedToBackStack) { boolean isAddedToBackStack) {
FragmentTransaction trans = FragmentTransaction trans =

View File

@@ -47,14 +47,15 @@ public class NavDrawerActivity extends BriarFragmentActivity implements
BaseFragment.BaseFragmentListener, TransportStateListener, BaseFragment.BaseFragmentListener, TransportStateListener,
OnNavigationItemSelectedListener { OnNavigationItemSelectedListener {
public final static String PREF_SEEN_WELCOME_MESSAGE = "welcome_message"; static final String INTENT_CONTACTS = "intent_contacts";
static final String INTENT_FORUMS = "intent_forums";
public static final String INTENT_CONTACTS = "intent_contacts"; static final String INTENT_BLOGS = "intent_blogs";
public static final String INTENT_FORUMS = "intent_forums";
private static final Logger LOG = private static final Logger LOG =
Logger.getLogger(NavDrawerActivity.class.getName()); Logger.getLogger(NavDrawerActivity.class.getName());
private final static String PREF_SEEN_WELCOME_MESSAGE = "welcome_message";
private ActionBarDrawerToggle drawerToggle; private ActionBarDrawerToggle drawerToggle;
@Inject @Inject
@@ -80,6 +81,10 @@ public class NavDrawerActivity extends BriarFragmentActivity implements
else if (intent.getBooleanExtra(INTENT_CONTACTS, false)) { else if (intent.getBooleanExtra(INTENT_CONTACTS, false)) {
startFragment(ContactListFragment.newInstance()); startFragment(ContactListFragment.newInstance());
} }
else if (intent.getBooleanExtra(INTENT_BLOGS, false)) {
startFragment(BlogsFragment.newInstance());
}
setIntent(null);
} }
@Override @Override
@@ -122,6 +127,9 @@ public class NavDrawerActivity extends BriarFragmentActivity implements
navigation.setCheckedItem(R.id.nav_btn_contacts); navigation.setCheckedItem(R.id.nav_btn_contacts);
startFragment(ContactListFragment.newInstance()); startFragment(ContactListFragment.newInstance());
} }
if (getIntent() != null) {
onNewIntent(getIntent());
}
} }
private void welcomeMessageCheck() { private void welcomeMessageCheck() {

View File

@@ -13,7 +13,15 @@ public interface AndroidNotificationManager {
void clearForumPostNotification(GroupId g); void clearForumPostNotification(GroupId g);
void showBlogPostNotification(GroupId g);
void clearBlogPostNotification();
void blockNotification(GroupId g); void blockNotification(GroupId g);
void unblockNotification(GroupId g); void unblockNotification(GroupId g);
void blockBlogNotification();
void unblockBlogNotification();
} }

View File

@@ -1,5 +1,6 @@
package org.briarproject.android.blogs; package org.briarproject.android.blogs;
import org.briarproject.android.api.AndroidNotificationManager;
import org.briarproject.android.controller.DbControllerImpl; import org.briarproject.android.controller.DbControllerImpl;
import org.briarproject.android.controller.handler.ResultHandler; import org.briarproject.android.controller.handler.ResultHandler;
import org.briarproject.api.blogs.Blog; import org.briarproject.api.blogs.Blog;
@@ -29,6 +30,9 @@ public class FeedControllerImpl extends DbControllerImpl
private static final Logger LOG = private static final Logger LOG =
Logger.getLogger(FeedControllerImpl.class.getName()); Logger.getLogger(FeedControllerImpl.class.getName());
@SuppressWarnings("WeakerAccess")
@Inject
AndroidNotificationManager notificationManager;
@Inject @Inject
protected volatile BlogManager blogManager; protected volatile BlogManager blogManager;
@Inject @Inject
@@ -44,11 +48,14 @@ public class FeedControllerImpl extends DbControllerImpl
@Override @Override
public void onResume() { public void onResume() {
notificationManager.blockBlogNotification();
notificationManager.clearBlogPostNotification();
eventBus.addListener(this); eventBus.addListener(this);
} }
@Override @Override
public void onPause() { public void onPause() {
notificationManager.unblockBlogNotification();
eventBus.removeListener(this); eventBus.removeListener(this);
} }

View File

@@ -17,6 +17,7 @@ import android.view.ViewGroup;
import org.briarproject.R; import org.briarproject.R;
import org.briarproject.android.ActivityComponent; import org.briarproject.android.ActivityComponent;
import org.briarproject.android.api.AndroidNotificationManager;
import org.briarproject.android.blogs.BlogPostAdapter.OnBlogPostClickListener; import org.briarproject.android.blogs.BlogPostAdapter.OnBlogPostClickListener;
import org.briarproject.android.controller.handler.UiResultHandler; import org.briarproject.android.controller.handler.UiResultHandler;
import org.briarproject.android.fragment.BaseFragment; import org.briarproject.android.fragment.BaseFragment;

View File

@@ -48,8 +48,9 @@ import static java.util.logging.Level.WARNING;
public class SettingsFragment extends PreferenceFragmentCompat public class SettingsFragment extends PreferenceFragmentCompat
implements EventListener, Preference.OnPreferenceChangeListener { implements EventListener, Preference.OnPreferenceChangeListener {
public static final int REQUEST_RINGTONE = 2; private static final int REQUEST_RINGTONE = 2;
public static final String SETTINGS_NAMESPACE = "android-ui"; public static final String SETTINGS_NAMESPACE = "android-ui";
public static final String PREF_NOTIFY_BLOG = "notifyBlogPosts";
private static final Logger LOG = private static final Logger LOG =
Logger.getLogger(SettingsFragment.class.getName()); Logger.getLogger(SettingsFragment.class.getName());
@@ -60,6 +61,7 @@ public class SettingsFragment extends PreferenceFragmentCompat
private ListPreference torOverMobile; private ListPreference torOverMobile;
private CheckBoxPreference notifyPrivateMessages; private CheckBoxPreference notifyPrivateMessages;
private CheckBoxPreference notifyForumPosts; private CheckBoxPreference notifyForumPosts;
private CheckBoxPreference notifyBlogPosts;
private CheckBoxPreference notifyVibration; private CheckBoxPreference notifyVibration;
private Preference notifySound; private Preference notifySound;
@@ -96,6 +98,8 @@ public class SettingsFragment extends PreferenceFragmentCompat
"pref_key_notify_private_messages"); "pref_key_notify_private_messages");
notifyForumPosts = (CheckBoxPreference) findPreference( notifyForumPosts = (CheckBoxPreference) findPreference(
"pref_key_notify_forum_posts"); "pref_key_notify_forum_posts");
notifyBlogPosts = (CheckBoxPreference) findPreference(
"pref_key_notify_blog_posts");
notifyVibration = (CheckBoxPreference) findPreference( notifyVibration = (CheckBoxPreference) findPreference(
"pref_key_notify_vibration"); "pref_key_notify_vibration");
notifySound = findPreference("pref_key_notify_sound"); notifySound = findPreference("pref_key_notify_sound");
@@ -104,6 +108,7 @@ public class SettingsFragment extends PreferenceFragmentCompat
torOverMobile.setOnPreferenceChangeListener(this); torOverMobile.setOnPreferenceChangeListener(this);
notifyPrivateMessages.setOnPreferenceChangeListener(this); notifyPrivateMessages.setOnPreferenceChangeListener(this);
notifyForumPosts.setOnPreferenceChangeListener(this); notifyForumPosts.setOnPreferenceChangeListener(this);
notifyBlogPosts.setOnPreferenceChangeListener(this);
notifyVibration.setOnPreferenceChangeListener(this); notifyVibration.setOnPreferenceChangeListener(this);
notifySound.setOnPreferenceClickListener( notifySound.setOnPreferenceClickListener(
@@ -200,6 +205,9 @@ public class SettingsFragment extends PreferenceFragmentCompat
notifyForumPosts.setChecked(settings.getBoolean( notifyForumPosts.setChecked(settings.getBoolean(
"notifyForumPosts", true)); "notifyForumPosts", true));
notifyBlogPosts.setChecked(settings.getBoolean(
PREF_NOTIFY_BLOG, true));
notifyVibration.setChecked(settings.getBoolean( notifyVibration.setChecked(settings.getBoolean(
"notifyVibration", true)); "notifyVibration", true));
@@ -245,6 +253,10 @@ public class SettingsFragment extends PreferenceFragmentCompat
Settings s = new Settings(); Settings s = new Settings();
s.putBoolean("notifyForumPosts", (Boolean) o); s.putBoolean("notifyForumPosts", (Boolean) o);
storeSettings(s); storeSettings(s);
} else if (preference == notifyBlogPosts) {
Settings s = new Settings();
s.putBoolean(PREF_NOTIFY_BLOG, (Boolean) o);
storeSettings(s);
} else if (preference == notifyVibration) { } else if (preference == notifyVibration) {
Settings s = new Settings(); Settings s = new Settings();
s.putBoolean("notifyVibration", (Boolean) o); s.putBoolean("notifyVibration", (Boolean) o);