mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 18:59:06 +01:00
Merge branch '734-notifications-for-private-group-messages' into 'master'
Show Notifications for Group Messages Closes #734 See merge request !391
This commit is contained in:
@@ -52,6 +52,10 @@
|
||||
<item quantity="one">New private message.</item>
|
||||
<item quantity="other">%d new private messages.</item>
|
||||
</plurals>
|
||||
<plurals name="group_message_notification_text">
|
||||
<item quantity="one">New group message.</item>
|
||||
<item quantity="other">%d new group messages.</item>
|
||||
</plurals>
|
||||
<plurals name="forum_post_notification_text">
|
||||
<item quantity="one">New forum post.</item>
|
||||
<item quantity="other">%d new forum posts.</item>
|
||||
@@ -328,6 +332,7 @@
|
||||
<!-- Settings Notifications -->
|
||||
<string name="notification_settings_title">Notifications</string>
|
||||
<string name="notify_private_messages_setting">Show alerts for private messages</string>
|
||||
<string name="notify_group_messages_setting">Show alerts for group messages</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>
|
||||
|
||||
@@ -63,6 +63,12 @@
|
||||
android:persistent="false"
|
||||
android:title="@string/notify_private_messages_setting"/>
|
||||
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="true"
|
||||
android:key="pref_key_notify_group_messages"
|
||||
android:persistent="false"
|
||||
android:title="@string/notify_group_messages_setting"/>
|
||||
|
||||
<CheckBoxPreference
|
||||
android:defaultValue="true"
|
||||
android:key="pref_key_notify_forum_posts"
|
||||
|
||||
@@ -18,6 +18,7 @@ import org.briarproject.android.api.AndroidExecutor;
|
||||
import org.briarproject.android.api.AndroidNotificationManager;
|
||||
import org.briarproject.android.contact.ConversationActivity;
|
||||
import org.briarproject.android.forum.ForumActivity;
|
||||
import org.briarproject.android.privategroup.conversation.GroupActivity;
|
||||
import org.briarproject.api.contact.ContactId;
|
||||
import org.briarproject.api.db.DatabaseExecutor;
|
||||
import org.briarproject.api.db.DbException;
|
||||
@@ -25,6 +26,7 @@ import org.briarproject.api.event.BlogPostAddedEvent;
|
||||
import org.briarproject.api.event.Event;
|
||||
import org.briarproject.api.event.EventListener;
|
||||
import org.briarproject.api.event.ForumPostReceivedEvent;
|
||||
import org.briarproject.api.event.GroupMessageAddedEvent;
|
||||
import org.briarproject.api.event.IntroductionRequestReceivedEvent;
|
||||
import org.briarproject.api.event.IntroductionResponseReceivedEvent;
|
||||
import org.briarproject.api.event.IntroductionSucceededEvent;
|
||||
@@ -64,8 +66,10 @@ import static org.briarproject.android.BriarActivity.GROUP_ID;
|
||||
import static org.briarproject.android.NavDrawerActivity.INTENT_BLOGS;
|
||||
import static org.briarproject.android.NavDrawerActivity.INTENT_CONTACTS;
|
||||
import static org.briarproject.android.NavDrawerActivity.INTENT_FORUMS;
|
||||
import static org.briarproject.android.NavDrawerActivity.INTENT_GROUPS;
|
||||
import static org.briarproject.android.contact.ConversationActivity.CONTACT_ID;
|
||||
import static org.briarproject.android.fragment.SettingsFragment.PREF_NOTIFY_BLOG;
|
||||
import static org.briarproject.android.fragment.SettingsFragment.PREF_NOTIFY_GROUP;
|
||||
import static org.briarproject.android.fragment.SettingsFragment.SETTINGS_NAMESPACE;
|
||||
|
||||
class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
||||
@@ -73,13 +77,16 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
||||
|
||||
// Notification IDs
|
||||
private static final int PRIVATE_MESSAGE_NOTIFICATION_ID = 3;
|
||||
private static final int FORUM_POST_NOTIFICATION_ID = 4;
|
||||
private static final int BLOG_POST_NOTIFICATION_ID = 5;
|
||||
private static final int INTRODUCTION_SUCCESS_NOTIFICATION_ID = 6;
|
||||
private static final int GROUP_MESSAGE_NOTIFICATION_ID = 4;
|
||||
private static final int FORUM_POST_NOTIFICATION_ID = 5;
|
||||
private static final int BLOG_POST_NOTIFICATION_ID = 6;
|
||||
private static final int INTRODUCTION_SUCCESS_NOTIFICATION_ID = 7;
|
||||
|
||||
// Content URIs to differentiate between pending intents
|
||||
private static final String CONTACT_URI =
|
||||
"content://org.briarproject/contact";
|
||||
private static final String GROUP_URI =
|
||||
"content://org.briarproject/group";
|
||||
private static final String FORUM_URI =
|
||||
"content://org.briarproject/forum";
|
||||
private static final String BLOG_URI =
|
||||
@@ -88,6 +95,8 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
||||
// Actions for intents that are broadcast when notifications are dismissed
|
||||
private static final String CLEAR_PRIVATE_MESSAGE_ACTION =
|
||||
"org.briarproject.briar.CLEAR_PRIVATE_MESSAGE_NOTIFICATION";
|
||||
private static final String CLEAR_GROUP_ACTION =
|
||||
"org.briarproject.briar.CLEAR_GROUP_NOTIFICATION";
|
||||
private static final String CLEAR_FORUM_ACTION =
|
||||
"org.briarproject.briar.CLEAR_FORUM_NOTIFICATION";
|
||||
private static final String CLEAR_BLOG_ACTION =
|
||||
@@ -107,15 +116,17 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
||||
|
||||
// The following must only be accessed on the main UI thread
|
||||
private final Map<ContactId, Integer> contactCounts = new HashMap<>();
|
||||
private final Map<GroupId, Integer> groupCounts = new HashMap<>();
|
||||
private final Map<GroupId, Integer> forumCounts = new HashMap<>();
|
||||
private final Map<GroupId, Integer> blogCounts = new HashMap<>();
|
||||
private int contactTotal = 0, forumTotal = 0, blogTotal = 0;
|
||||
private int contactTotal = 0, groupTotal = 0, forumTotal = 0, blogTotal = 0;
|
||||
private int introductionTotal = 0;
|
||||
private int nextRequestId = 0;
|
||||
private ContactId blockedContact = null;
|
||||
private GroupId blockedGroup = null;
|
||||
private boolean blockContacts = false, blockForums = false;
|
||||
private boolean blockBlogs = false, blockIntroductions = false;
|
||||
private boolean blockContacts = false, blockGroups = false;
|
||||
private boolean blockForums = false, blockBlogs = false;
|
||||
private boolean blockIntroductions = false;
|
||||
|
||||
private volatile Settings settings = new Settings();
|
||||
|
||||
@@ -144,6 +155,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
||||
public Void call() {
|
||||
IntentFilter filter = new IntentFilter();
|
||||
filter.addAction(CLEAR_PRIVATE_MESSAGE_ACTION);
|
||||
filter.addAction(CLEAR_GROUP_ACTION);
|
||||
filter.addAction(CLEAR_FORUM_ACTION);
|
||||
filter.addAction(CLEAR_BLOG_ACTION);
|
||||
filter.addAction(CLEAR_INTRODUCTION_ACTION);
|
||||
@@ -165,6 +177,7 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
||||
@Override
|
||||
public Void call() {
|
||||
clearContactNotification();
|
||||
clearGroupMessageNotification();
|
||||
clearForumPostNotification();
|
||||
clearBlogPostNotification();
|
||||
clearIntroductionSuccessNotification();
|
||||
@@ -188,6 +201,15 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
||||
nm.cancel(PRIVATE_MESSAGE_NOTIFICATION_ID);
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void clearGroupMessageNotification() {
|
||||
groupCounts.clear();
|
||||
groupTotal = 0;
|
||||
Object o = appContext.getSystemService(NOTIFICATION_SERVICE);
|
||||
NotificationManager nm = (NotificationManager) o;
|
||||
nm.cancel(GROUP_MESSAGE_NOTIFICATION_ID);
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void clearForumPostNotification() {
|
||||
forumCounts.clear();
|
||||
@@ -222,6 +244,9 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
||||
} else if (e instanceof PrivateMessageReceivedEvent) {
|
||||
PrivateMessageReceivedEvent p = (PrivateMessageReceivedEvent) e;
|
||||
showContactNotification(p.getContactId());
|
||||
} else if (e instanceof GroupMessageAddedEvent) {
|
||||
GroupMessageAddedEvent g = (GroupMessageAddedEvent) e;
|
||||
showGroupMessageNotification(g.getGroupId());
|
||||
} else if (e instanceof ForumPostReceivedEvent) {
|
||||
ForumPostReceivedEvent f = (ForumPostReceivedEvent) e;
|
||||
showForumPostNotification(f.getGroupId());
|
||||
@@ -367,6 +392,101 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
||||
});
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void showGroupMessageNotification(final GroupId g) {
|
||||
androidExecutor.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (blockGroups) return;
|
||||
if (g.equals(blockedGroup)) return;
|
||||
Integer count = groupCounts.get(g);
|
||||
if (count == null) groupCounts.put(g, 1);
|
||||
else groupCounts.put(g, count + 1);
|
||||
groupTotal++;
|
||||
updateGroupMessageNotification();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearGroupMessageNotification(final GroupId g) {
|
||||
androidExecutor.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Integer count = groupCounts.remove(g);
|
||||
if (count == null) return; // Already cleared
|
||||
groupTotal -= count;
|
||||
updateGroupMessageNotification();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void updateGroupMessageNotification() {
|
||||
if (groupTotal == 0) {
|
||||
clearGroupMessageNotification();
|
||||
} else if (settings.getBoolean(PREF_NOTIFY_GROUP, 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.group_message_notification_text, groupTotal,
|
||||
groupTotal));
|
||||
String ringtoneUri = settings.get("notifyRingtoneUri");
|
||||
if (!StringUtils.isNullOrEmpty(ringtoneUri))
|
||||
b.setSound(Uri.parse(ringtoneUri));
|
||||
b.setDefaults(getDefaults());
|
||||
b.setOnlyAlertOnce(true);
|
||||
b.setAutoCancel(true);
|
||||
// Clear the counters if the notification is dismissed
|
||||
Intent clear = new Intent(CLEAR_GROUP_ACTION);
|
||||
PendingIntent delete = PendingIntent.getBroadcast(appContext, 0,
|
||||
clear, 0);
|
||||
b.setDeleteIntent(delete);
|
||||
if (groupCounts.size() == 1) {
|
||||
// Touching the notification shows the relevant group
|
||||
Intent i = new Intent(appContext, GroupActivity.class);
|
||||
GroupId g = groupCounts.keySet().iterator().next();
|
||||
i.putExtra(GROUP_ID, g.getBytes());
|
||||
String idHex = StringUtils.toHexString(g.getBytes());
|
||||
i.setData(Uri.parse(GROUP_URI + "/" + idHex));
|
||||
i.setFlags(FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP);
|
||||
TaskStackBuilder t = TaskStackBuilder.create(appContext);
|
||||
t.addParentStack(GroupActivity.class);
|
||||
t.addNextIntent(i);
|
||||
b.setContentIntent(t.getPendingIntent(nextRequestId++, 0));
|
||||
} else {
|
||||
// Touching the notification shows the group list
|
||||
Intent i = new Intent(appContext, NavDrawerActivity.class);
|
||||
i.putExtra(INTENT_GROUPS, true);
|
||||
i.setFlags(FLAG_ACTIVITY_CLEAR_TOP | FLAG_ACTIVITY_SINGLE_TOP);
|
||||
i.setData(Uri.parse(GROUP_URI));
|
||||
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(GROUP_MESSAGE_NOTIFICATION_ID, b.build());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void clearAllGroupMessageNotifications() {
|
||||
androidExecutor.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
clearGroupMessageNotification();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@UiThread
|
||||
private void showForumPostNotification(final GroupId g) {
|
||||
androidExecutor.runOnUiThread(new Runnable() {
|
||||
@@ -654,6 +774,26 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void blockAllGroupMessageNotifications() {
|
||||
androidExecutor.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
blockGroups = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unblockAllGroupMessageNotifications() {
|
||||
androidExecutor.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
blockGroups = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void blockAllForumPostNotifications() {
|
||||
androidExecutor.runOnUiThread(new Runnable() {
|
||||
@@ -704,6 +844,8 @@ class AndroidNotificationManagerImpl implements AndroidNotificationManager,
|
||||
public void run() {
|
||||
if (CLEAR_PRIVATE_MESSAGE_ACTION.equals(action)) {
|
||||
clearContactNotification();
|
||||
} else if (CLEAR_GROUP_ACTION.equals(action)) {
|
||||
clearGroupMessageNotification();
|
||||
} else if (CLEAR_FORUM_ACTION.equals(action)) {
|
||||
clearForumPostNotification();
|
||||
} else if (CLEAR_BLOG_ACTION.equals(action)) {
|
||||
|
||||
@@ -46,6 +46,7 @@ public class NavDrawerActivity extends BriarFragmentActivity implements
|
||||
OnNavigationItemSelectedListener {
|
||||
|
||||
static final String INTENT_CONTACTS = "intent_contacts";
|
||||
static final String INTENT_GROUPS = "intent_groups";
|
||||
static final String INTENT_FORUMS = "intent_forums";
|
||||
static final String INTENT_BLOGS = "intent_blogs";
|
||||
|
||||
@@ -70,10 +71,10 @@ public class NavDrawerActivity extends BriarFragmentActivity implements
|
||||
protected void onNewIntent(Intent intent) {
|
||||
super.onNewIntent(intent);
|
||||
exitIfStartupFailed(intent);
|
||||
// FIXME why was the stack cleared here?
|
||||
// This prevents state from being restored properly
|
||||
// clearBackStack();
|
||||
if (intent.getBooleanExtra(INTENT_FORUMS, false)) {
|
||||
// TODO don't create new instances if they are on the stack (#606)
|
||||
if (intent.getBooleanExtra(INTENT_GROUPS, false)) {
|
||||
startFragment(GroupListFragment.newInstance());
|
||||
} else if (intent.getBooleanExtra(INTENT_FORUMS, false)) {
|
||||
startFragment(ForumListFragment.newInstance());
|
||||
} else if (intent.getBooleanExtra(INTENT_CONTACTS, false)) {
|
||||
startFragment(ContactListFragment.newInstance());
|
||||
|
||||
@@ -13,6 +13,10 @@ public interface AndroidNotificationManager {
|
||||
|
||||
void clearAllContactNotifications();
|
||||
|
||||
void clearGroupMessageNotification(GroupId g);
|
||||
|
||||
void clearAllGroupMessageNotifications();
|
||||
|
||||
void clearForumPostNotification(GroupId g);
|
||||
|
||||
void clearAllForumPostNotifications();
|
||||
@@ -33,6 +37,10 @@ public interface AndroidNotificationManager {
|
||||
|
||||
void unblockAllContactNotifications();
|
||||
|
||||
void blockAllGroupMessageNotifications();
|
||||
|
||||
void unblockAllGroupMessageNotifications();
|
||||
|
||||
void blockAllForumPostNotifications();
|
||||
|
||||
void unblockAllForumPostNotifications();
|
||||
|
||||
@@ -50,6 +50,7 @@ public class SettingsFragment extends PreferenceFragmentCompat
|
||||
|
||||
private static final int REQUEST_RINGTONE = 2;
|
||||
public static final String SETTINGS_NAMESPACE = "android-ui";
|
||||
public static final String PREF_NOTIFY_GROUP = "notifyGroupMessages";
|
||||
public static final String PREF_NOTIFY_BLOG = "notifyBlogPosts";
|
||||
|
||||
private static final Logger LOG =
|
||||
@@ -60,6 +61,7 @@ public class SettingsFragment extends PreferenceFragmentCompat
|
||||
private ListPreference enableBluetooth;
|
||||
private ListPreference torOverMobile;
|
||||
private CheckBoxPreference notifyPrivateMessages;
|
||||
private CheckBoxPreference notifyGroupMessages;
|
||||
private CheckBoxPreference notifyForumPosts;
|
||||
private CheckBoxPreference notifyBlogPosts;
|
||||
private CheckBoxPreference notifyVibration;
|
||||
@@ -91,6 +93,8 @@ public class SettingsFragment extends PreferenceFragmentCompat
|
||||
(ListPreference) findPreference("pref_key_tor_mobile");
|
||||
notifyPrivateMessages = (CheckBoxPreference) findPreference(
|
||||
"pref_key_notify_private_messages");
|
||||
notifyGroupMessages = (CheckBoxPreference) findPreference(
|
||||
"pref_key_notify_group_messages");
|
||||
notifyForumPosts = (CheckBoxPreference) findPreference(
|
||||
"pref_key_notify_forum_posts");
|
||||
notifyBlogPosts = (CheckBoxPreference) findPreference(
|
||||
@@ -102,6 +106,7 @@ public class SettingsFragment extends PreferenceFragmentCompat
|
||||
enableBluetooth.setOnPreferenceChangeListener(this);
|
||||
torOverMobile.setOnPreferenceChangeListener(this);
|
||||
notifyPrivateMessages.setOnPreferenceChangeListener(this);
|
||||
notifyGroupMessages.setOnPreferenceChangeListener(this);
|
||||
notifyForumPosts.setOnPreferenceChangeListener(this);
|
||||
notifyBlogPosts.setOnPreferenceChangeListener(this);
|
||||
notifyVibration.setOnPreferenceChangeListener(this);
|
||||
@@ -199,6 +204,9 @@ public class SettingsFragment extends PreferenceFragmentCompat
|
||||
notifyPrivateMessages.setChecked(settings.getBoolean(
|
||||
"notifyPrivateMessages", true));
|
||||
|
||||
notifyGroupMessages.setChecked(settings.getBoolean(
|
||||
PREF_NOTIFY_GROUP, true));
|
||||
|
||||
notifyForumPosts.setChecked(settings.getBoolean(
|
||||
"notifyForumPosts", true));
|
||||
|
||||
@@ -247,6 +255,10 @@ public class SettingsFragment extends PreferenceFragmentCompat
|
||||
Settings s = new Settings();
|
||||
s.putBoolean("notifyPrivateMessages", (Boolean) o);
|
||||
storeSettings(s);
|
||||
} else if (preference == notifyGroupMessages) {
|
||||
Settings s = new Settings();
|
||||
s.putBoolean(PREF_NOTIFY_GROUP, (Boolean) o);
|
||||
storeSettings(s);
|
||||
} else if (preference == notifyForumPosts) {
|
||||
Settings s = new Settings();
|
||||
s.putBoolean("notifyForumPosts", (Boolean) o);
|
||||
|
||||
@@ -59,7 +59,7 @@ public class GroupControllerImpl extends
|
||||
@Override
|
||||
public void onActivityStart() {
|
||||
super.onActivityStart();
|
||||
// TODO: Add new notification manager methods for private groups
|
||||
notificationManager.clearGroupMessageNotification(getGroupId());
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.briarproject.android.privategroup.list;
|
||||
|
||||
import android.support.annotation.CallSuper;
|
||||
|
||||
import org.briarproject.android.api.AndroidNotificationManager;
|
||||
import org.briarproject.android.controller.DbControllerImpl;
|
||||
import org.briarproject.android.controller.handler.ResultExceptionHandler;
|
||||
import org.briarproject.api.clients.MessageTracker.GroupCount;
|
||||
@@ -41,6 +42,7 @@ public class GroupListControllerImpl extends DbControllerImpl
|
||||
|
||||
private final PrivateGroupManager groupManager;
|
||||
private final GroupInvitationManager groupInvitationManager;
|
||||
private final AndroidNotificationManager notificationManager;
|
||||
private final EventBus eventBus;
|
||||
|
||||
protected volatile GroupListListener listener;
|
||||
@@ -48,10 +50,12 @@ public class GroupListControllerImpl extends DbControllerImpl
|
||||
@Inject
|
||||
GroupListControllerImpl(@DatabaseExecutor Executor dbExecutor,
|
||||
LifecycleManager lifecycleManager, PrivateGroupManager groupManager,
|
||||
GroupInvitationManager groupInvitationManager, EventBus eventBus) {
|
||||
GroupInvitationManager groupInvitationManager,
|
||||
AndroidNotificationManager notificationManager, EventBus eventBus) {
|
||||
super(dbExecutor, lifecycleManager);
|
||||
this.groupManager = groupManager;
|
||||
this.groupInvitationManager = groupInvitationManager;
|
||||
this.notificationManager = notificationManager;
|
||||
this.eventBus = eventBus;
|
||||
}
|
||||
|
||||
@@ -67,13 +71,15 @@ public class GroupListControllerImpl extends DbControllerImpl
|
||||
throw new IllegalStateException(
|
||||
"GroupListListener needs to be attached");
|
||||
eventBus.addListener(this);
|
||||
// TODO: Add new notification manager methods for private groups
|
||||
notificationManager.blockAllGroupMessageNotifications();
|
||||
notificationManager.clearAllGroupMessageNotifications();
|
||||
}
|
||||
|
||||
@Override
|
||||
@CallSuper
|
||||
public void onStop() {
|
||||
eventBus.removeListener(this);
|
||||
notificationManager.unblockAllGroupMessageNotifications();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Reference in New Issue
Block a user