mirror of
https://github.com/ChronosX88/Influence.git
synced 2024-11-09 20:11:01 +00:00
Added notifications for new messages
This commit is contained in:
parent
18bce5605f
commit
6936c0127e
@ -57,6 +57,7 @@ android {
|
|||||||
dependencies {
|
dependencies {
|
||||||
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
implementation fileTree(include: ['*.jar'], dir: 'libs')
|
||||||
implementation 'androidx.appcompat:appcompat:1.1.0-alpha02'
|
implementation 'androidx.appcompat:appcompat:1.1.0-alpha02'
|
||||||
|
implementation "com.android.support:support-compat:28.0.0"
|
||||||
implementation "androidx.room:room-runtime:2.1.0-alpha04"
|
implementation "androidx.room:room-runtime:2.1.0-alpha04"
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
||||||
annotationProcessor "androidx.room:room-compiler:2.1.0-alpha04"
|
annotationProcessor "androidx.room:room-compiler:2.1.0-alpha04"
|
||||||
|
@ -52,6 +52,7 @@ public class AppHelper extends MultiDexApplication {
|
|||||||
private static Handler mainUIThreadHandler;
|
private static Handler mainUIThreadHandler;
|
||||||
private static ServiceConnection serviceConnection;
|
private static ServiceConnection serviceConnection;
|
||||||
private static boolean isMainActivityDestroyed = true;
|
private static boolean isMainActivityDestroyed = true;
|
||||||
|
private static String currentChatActivity = "";
|
||||||
public final static Map<String, byte[]> avatarsCache = new ConcurrentHashMap<>();
|
public final static Map<String, byte[]> avatarsCache = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -150,4 +151,12 @@ public class AppHelper extends MultiDexApplication {
|
|||||||
public static void setIsMainActivityDestroyed(boolean isMainActivityDestroyed) {
|
public static void setIsMainActivityDestroyed(boolean isMainActivityDestroyed) {
|
||||||
AppHelper.isMainActivityDestroyed = isMainActivityDestroyed;
|
AppHelper.isMainActivityDestroyed = isMainActivityDestroyed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static String getCurrentChatActivity() {
|
||||||
|
return currentChatActivity;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void setCurrentChatActivity(String currentChatActivity) {
|
||||||
|
AppHelper.currentChatActivity = currentChatActivity;
|
||||||
|
}
|
||||||
}
|
}
|
@ -16,6 +16,20 @@
|
|||||||
|
|
||||||
package io.github.chronosx88.influence.helpers;
|
package io.github.chronosx88.influence.helpers;
|
||||||
|
|
||||||
|
import android.app.NotificationChannel;
|
||||||
|
import android.app.NotificationManager;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.BitmapFactory;
|
||||||
|
import android.graphics.Canvas;
|
||||||
|
import android.graphics.drawable.BitmapDrawable;
|
||||||
|
import android.graphics.drawable.Drawable;
|
||||||
|
import android.os.Build;
|
||||||
|
|
||||||
|
import androidx.core.app.NotificationCompat;
|
||||||
|
import androidx.core.app.NotificationManagerCompat;
|
||||||
|
|
||||||
|
import com.amulyakhare.textdrawable.TextDrawable;
|
||||||
|
import com.amulyakhare.textdrawable.util.ColorGenerator;
|
||||||
import com.instacart.library.truetime.TrueTime;
|
import com.instacart.library.truetime.TrueTime;
|
||||||
|
|
||||||
import org.greenrobot.eventbus.EventBus;
|
import org.greenrobot.eventbus.EventBus;
|
||||||
@ -28,14 +42,28 @@ import org.jxmpp.jid.BareJid;
|
|||||||
import org.jxmpp.jid.EntityBareJid;
|
import org.jxmpp.jid.EntityBareJid;
|
||||||
import org.jxmpp.jid.FullJid;
|
import org.jxmpp.jid.FullJid;
|
||||||
import org.jxmpp.jid.Jid;
|
import org.jxmpp.jid.Jid;
|
||||||
|
import org.jxmpp.jid.impl.JidCreate;
|
||||||
|
import org.jxmpp.stringprep.XmppStringprepException;
|
||||||
|
|
||||||
|
import java.util.Random;
|
||||||
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
|
import io.github.chronosx88.influence.R;
|
||||||
import io.github.chronosx88.influence.models.GenericMessage;
|
import io.github.chronosx88.influence.models.GenericMessage;
|
||||||
import io.github.chronosx88.influence.models.appEvents.LastMessageEvent;
|
import io.github.chronosx88.influence.models.appEvents.LastMessageEvent;
|
||||||
import io.github.chronosx88.influence.models.appEvents.NewMessageEvent;
|
import io.github.chronosx88.influence.models.appEvents.NewMessageEvent;
|
||||||
import io.github.chronosx88.influence.models.appEvents.UserPresenceChangedEvent;
|
import io.github.chronosx88.influence.models.appEvents.UserPresenceChangedEvent;
|
||||||
|
import java9.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
public class NetworkHandler implements IncomingChatMessageListener, PresenceEventListener {
|
public class NetworkHandler implements IncomingChatMessageListener, PresenceEventListener {
|
||||||
private final static String LOG_TAG = "NetworkHandler";
|
private final static String LOG_TAG = "NetworkHandler";
|
||||||
|
private final static String NOTIFICATION_CHANNEL_ID = "InfluenceNotificationsChannel";
|
||||||
|
|
||||||
|
private NotificationManagerCompat notificationManager = NotificationManagerCompat.from(AppHelper.getContext());
|
||||||
|
|
||||||
|
public NetworkHandler() {
|
||||||
|
createNotificationChannel();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void newIncomingMessage(EntityBareJid from, Message message, Chat chat) {
|
public void newIncomingMessage(EntityBareJid from, Message message, Chat chat) {
|
||||||
@ -49,8 +77,68 @@ public class NetworkHandler implements IncomingChatMessageListener, PresenceEven
|
|||||||
|
|
||||||
EventBus.getDefault().post(new NewMessageEvent(chatID, messageID));
|
EventBus.getDefault().post(new NewMessageEvent(chatID, messageID));
|
||||||
EventBus.getDefault().post(new LastMessageEvent(chatID, new GenericMessage(LocalDBWrapper.getMessageByID(messageID))));
|
EventBus.getDefault().post(new LastMessageEvent(chatID, new GenericMessage(LocalDBWrapper.getMessageByID(messageID))));
|
||||||
|
if(!AppHelper.getCurrentChatActivity().equals(chatID)) {
|
||||||
|
byte[] avatarBytes = new byte[0];
|
||||||
|
try {
|
||||||
|
CompletableFuture<byte[]> future = loadAvatar(chatID);
|
||||||
|
if(future != null) {
|
||||||
|
avatarBytes = future.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
} catch (ExecutionException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
Bitmap avatar = null;
|
||||||
|
if(avatarBytes != null) {
|
||||||
|
avatar = BitmapFactory.decodeByteArray(avatarBytes, 0, avatarBytes.length);
|
||||||
|
}
|
||||||
|
NotificationCompat.Builder notification = new NotificationCompat.Builder(AppHelper.getContext(), NOTIFICATION_CHANNEL_ID)
|
||||||
|
.setSmallIcon(R.drawable.ic_message_white_24dp)
|
||||||
|
.setContentTitle(chatID)
|
||||||
|
.setContentText(message.getBody())
|
||||||
|
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
|
||||||
|
if(avatar != null) {
|
||||||
|
notification.setLargeIcon(avatar);
|
||||||
|
} else {
|
||||||
|
String firstLetter = Character.toString(Character.toUpperCase(chatID.charAt(0)));
|
||||||
|
Drawable avatarText = TextDrawable.builder()
|
||||||
|
.beginConfig()
|
||||||
|
.width(64)
|
||||||
|
.height(64)
|
||||||
|
.endConfig()
|
||||||
|
.buildRound(firstLetter, ColorGenerator.MATERIAL.getColor(firstLetter));
|
||||||
|
notification.setLargeIcon(drawableToBitmap(avatarText));
|
||||||
|
}
|
||||||
|
notificationManager.notify(new Random().nextInt(), notification.build());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Bitmap drawableToBitmap(Drawable drawable) {
|
||||||
|
Bitmap bitmap;
|
||||||
|
|
||||||
|
if (drawable instanceof BitmapDrawable) {
|
||||||
|
BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
|
||||||
|
if(bitmapDrawable.getBitmap() != null) {
|
||||||
|
return bitmapDrawable.getBitmap();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
|
||||||
|
bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
|
||||||
|
} else {
|
||||||
|
bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
|
||||||
|
}
|
||||||
|
|
||||||
|
Canvas canvas = new Canvas(bitmap);
|
||||||
|
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
|
||||||
|
drawable.draw(canvas);
|
||||||
|
return bitmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void presenceAvailable(FullJid address, Presence availablePresence) {
|
public void presenceAvailable(FullJid address, Presence availablePresence) {
|
||||||
EventBus.getDefault().post(new UserPresenceChangedEvent(address.asBareJid().asUnescapedString(), availablePresence.isAvailable()));
|
EventBus.getDefault().post(new UserPresenceChangedEvent(address.asBareJid().asUnescapedString(), availablePresence.isAvailable()));
|
||||||
@ -75,4 +163,41 @@ public class NetworkHandler implements IncomingChatMessageListener, PresenceEven
|
|||||||
public void presenceUnsubscribed(BareJid address, Presence unsubscribedPresence) {
|
public void presenceUnsubscribed(BareJid address, Presence unsubscribedPresence) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void createNotificationChannel() {
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||||
|
String name = AppHelper.getContext().getString(R.string.notification_channel_name);
|
||||||
|
String description = AppHelper.getContext().getString(R.string.notification_channel_desc);
|
||||||
|
NotificationChannel channel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, name, NotificationManager.IMPORTANCE_DEFAULT);
|
||||||
|
channel.setDescription(description);
|
||||||
|
NotificationManager notificationManager = AppHelper.getContext().getSystemService(NotificationManager.class);
|
||||||
|
notificationManager.createNotificationChannel(channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private CompletableFuture<byte[]> loadAvatar(String senderID) {
|
||||||
|
if(senderID.length() != 0) {
|
||||||
|
if(AppHelper.avatarsCache.containsKey(senderID)) {
|
||||||
|
return CompletableFuture.completedFuture(AppHelper.avatarsCache.get(senderID));
|
||||||
|
}
|
||||||
|
CompletableFuture<byte[]> completableFuture = CompletableFuture.supplyAsync(() -> {
|
||||||
|
while (AppHelper.getXmppConnection() == null);
|
||||||
|
while (AppHelper.getXmppConnection().isConnectionAlive() != true);
|
||||||
|
EntityBareJid jid = null;
|
||||||
|
try {
|
||||||
|
jid = JidCreate.entityBareFrom(senderID);
|
||||||
|
} catch (XmppStringprepException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
return AppHelper.getXmppConnection().getAvatar(jid);
|
||||||
|
}).thenApply((avatarBytes) -> {
|
||||||
|
if(avatarBytes != null) {
|
||||||
|
AppHelper.avatarsCache.put(senderID, avatarBytes);
|
||||||
|
}
|
||||||
|
return avatarBytes;
|
||||||
|
});
|
||||||
|
return completableFuture;
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
@ -60,6 +60,7 @@ class ChatPresenter(private val view: CoreContracts.IChatViewContract, private v
|
|||||||
view.setAdapter(chatAdapter)
|
view.setAdapter(chatAdapter)
|
||||||
getUserStatus()
|
getUserStatus()
|
||||||
EventBus.getDefault().register(this)
|
EventBus.getDefault().register(this)
|
||||||
|
AppHelper.setCurrentChatActivity(chatID)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun sendMessage(text: String): Boolean {
|
override fun sendMessage(text: String): Boolean {
|
||||||
@ -87,6 +88,7 @@ class ChatPresenter(private val view: CoreContracts.IChatViewContract, private v
|
|||||||
|
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
EventBus.getDefault().unregister(this)
|
EventBus.getDefault().unregister(this)
|
||||||
|
AppHelper.setCurrentChatActivity("")
|
||||||
}
|
}
|
||||||
|
|
||||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||||
|
21
app/src/main/res/drawable/ic_message_white_24dp.xml
Normal file
21
app/src/main/res/drawable/ic_message_white_24dp.xml
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<!--
|
||||||
|
~ Copyright 2019 ChronosX88
|
||||||
|
~
|
||||||
|
~ Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
~ you may not use this file except in compliance with the License.
|
||||||
|
~ You may obtain a copy of the License at
|
||||||
|
~
|
||||||
|
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
~
|
||||||
|
~ Unless required by applicable law or agreed to in writing, software
|
||||||
|
~ distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
~ See the License for the specific language governing permissions and
|
||||||
|
~ limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||||
|
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||||
|
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
<path android:fillColor="#FF000000" android:pathData="M20,2L4,2c-1.1,0 -1.99,0.9 -1.99,2L2,22l4,-4h14c1.1,0 2,-0.9 2,-2L22,4c0,-1.1 -0.9,-2 -2,-2zM18,14L6,14v-2h12v2zM18,11L6,11L6,9h12v2zM18,8L6,8L6,6h12v2z"/>
|
||||||
|
</vector>
|
@ -27,4 +27,6 @@
|
|||||||
<string name="offline">Не в сети</string>
|
<string name="offline">Не в сети</string>
|
||||||
<string name="online">В сети</string>
|
<string name="online">В сети</string>
|
||||||
<string name="clear_chat">Очистить чат</string>
|
<string name="clear_chat">Очистить чат</string>
|
||||||
|
<string name="notification_channel_name">Уведомления Influence</string>
|
||||||
|
<string name="notification_channel_desc">Уведомления чатов Influence</string>
|
||||||
</resources>
|
</resources>
|
@ -26,4 +26,6 @@
|
|||||||
<string name="offline">Offline</string>
|
<string name="offline">Offline</string>
|
||||||
<string name="online">Online</string>
|
<string name="online">Online</string>
|
||||||
<string name="clear_chat">Clear chat</string>
|
<string name="clear_chat">Clear chat</string>
|
||||||
|
<string name="notification_channel_name">Influence Notifications</string>
|
||||||
|
<string name="notification_channel_desc">Influence chat notifications</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
Loading…
Reference in New Issue
Block a user