Added Reply button to incoming chat messages notifications
This commit is contained in:
parent
3bf7537d13
commit
15af61c83a
9 changed files with 340 additions and 106 deletions
19
CHANGELOG.md
19
CHANGELOG.md
|
@ -16,13 +16,22 @@ Group changes to describe their impact on the project, as follows:
|
||||||
- feature: option to automatically download incoming files, either always, never or depending on their sizes.
|
- feature: option to automatically download incoming files, either always, never or depending on their sizes.
|
||||||
|
|
||||||
## [4.1] - 2018-xx-xx
|
## [4.1] - 2018-xx-xx
|
||||||
|
|
||||||
|
### Improvements
|
||||||
- Improved UI.
|
- Improved UI.
|
||||||
|
- Added adaptive icon for Android 8+.
|
||||||
- Use of binary SDK hosted in Maven repository instead of having to build it manually.
|
- Use of binary SDK hosted in Maven repository instead of having to build it manually.
|
||||||
- feature: added new end to end LIME encryption for instant messaging, both for single chat rooms and group ones.
|
- Asynchronous fetch of native contacts.
|
||||||
- feature: send multiple files with text at the same time.
|
- Removed unused graphical resources.
|
||||||
- feature: support of H265 codec.
|
- Updated translations.
|
||||||
- feature: use TextureView instead of GL2JNIView, easier to use and will fix issues.
|
|
||||||
- feature: send SMS to invite your friends in using Linphone.
|
### Features
|
||||||
|
- Added new end to end LIME encryption for instant messaging, both for single chat rooms and group ones.
|
||||||
|
- Send multiple files with text at the same time.
|
||||||
|
- Support of H265 codec.
|
||||||
|
- Use TextureView instead of GL2JNIView, easier to use and will fix issues.
|
||||||
|
- Send SMS to invite your friends in using Linphone.
|
||||||
|
- Reply to received chat message in notification
|
||||||
|
|
||||||
## [4.0.1] - 2018-06-26
|
## [4.0.1] - 2018-06-26
|
||||||
|
|
||||||
|
|
|
@ -293,5 +293,10 @@
|
||||||
|
|
||||||
<activity android:name=".activities.LinphoneGenericActivity"/>
|
<activity android:name=".activities.LinphoneGenericActivity"/>
|
||||||
|
|
||||||
|
<receiver
|
||||||
|
android:name=".receivers.NotificationBroadcastReceiver"
|
||||||
|
android:enabled="true"
|
||||||
|
android:exported="false" />
|
||||||
|
|
||||||
</application>
|
</application>
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|
|
@ -653,7 +653,7 @@ public final class LinphoneService extends Service {
|
||||||
} else {
|
} else {
|
||||||
bm = BitmapFactory.decodeResource(getResources(), R.drawable.topbar_avatar);
|
bm = BitmapFactory.decodeResource(getResources(), R.drawable.topbar_avatar);
|
||||||
}
|
}
|
||||||
Notification notification = Compatibility.createMessageNotification(getApplicationContext(), notif.numberOfUnreadMessage, subject,
|
Notification notification = Compatibility.createMessageNotification(getApplicationContext(), notif.notificationId, notif.numberOfUnreadMessage, subject,
|
||||||
getString(R.string.group_chat_notif).replace("%1", fromName).replace("%2", message), bm, notifContentIntent);
|
getString(R.string.group_chat_notif).replace("%1", fromName).replace("%2", message), bm, notifContentIntent);
|
||||||
|
|
||||||
notifyWrapper(notif.notificationId, notification);
|
notifyWrapper(notif.notificationId, notification);
|
||||||
|
@ -691,11 +691,24 @@ public final class LinphoneService extends Service {
|
||||||
} else {
|
} else {
|
||||||
bm = BitmapFactory.decodeResource(getResources(), R.drawable.topbar_avatar);
|
bm = BitmapFactory.decodeResource(getResources(), R.drawable.topbar_avatar);
|
||||||
}
|
}
|
||||||
Notification notification = Compatibility.createMessageNotification(getApplicationContext(), notif.numberOfUnreadMessage, fromName, message, bm, notifContentIntent);
|
Notification notification = Compatibility.createMessageNotification(getApplicationContext(), notif.notificationId, notif.numberOfUnreadMessage, fromName, message, bm, notifContentIntent);
|
||||||
|
|
||||||
notifyWrapper(notif.notificationId, notification);
|
notifyWrapper(notif.notificationId, notification);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void sendNotification(Notification notif, int notificationId) {
|
||||||
|
notifyWrapper(notificationId, notif);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getSipUriForNotificationId(int notificationId) {
|
||||||
|
for (String addr : mChatNotifMap.keySet()) {
|
||||||
|
if (mChatNotifMap.get(addr).notificationId == notificationId) {
|
||||||
|
return addr;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public void displayInappNotification(String message) {
|
public void displayInappNotification(String message) {
|
||||||
Intent notifIntent = new Intent(this, LinphoneActivity.class);
|
Intent notifIntent = new Intent(this, LinphoneActivity.class);
|
||||||
notifIntent.putExtra("GoToInapp", true);
|
notifIntent.putExtra("GoToInapp", true);
|
||||||
|
@ -706,15 +719,6 @@ public final class LinphoneService extends Service {
|
||||||
notifyWrapper(NOTIF_ID, mNotif);
|
notifyWrapper(NOTIF_ID, mNotif);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void displaySasNotification(String sas) {
|
|
||||||
mSasNotif = Compatibility.createSimpleNotification(getApplicationContext(),
|
|
||||||
getString(R.string.zrtp_notification_title),
|
|
||||||
sas + " " + getString(R.string.zrtp_notification_message),
|
|
||||||
null);
|
|
||||||
|
|
||||||
notifyWrapper(SAS_NOTIF_ID, mSasNotif);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void removeSasNotification() {
|
public void removeSasNotification() {
|
||||||
mNM.cancel(SAS_NOTIF_ID);
|
mNM.cancel(SAS_NOTIF_ID);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,97 @@
|
||||||
|
package org.linphone.compatibility;
|
||||||
|
|
||||||
|
|
||||||
|
import android.annotation.TargetApi;
|
||||||
|
import android.app.FragmentTransaction;
|
||||||
|
import android.app.Notification;
|
||||||
|
import android.app.NotificationChannel;
|
||||||
|
import android.app.NotificationManager;
|
||||||
|
import android.app.PendingIntent;
|
||||||
|
import android.app.RemoteInput;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.view.ViewTreeObserver;
|
||||||
|
|
||||||
|
import org.linphone.R;
|
||||||
|
import org.linphone.receivers.NotificationBroadcastReceiver;
|
||||||
|
|
||||||
|
import static org.linphone.compatibility.Compatibility.INTENT_NOTIF_ID;
|
||||||
|
import static org.linphone.compatibility.Compatibility.KEY_TEXT_REPLY;
|
||||||
|
|
||||||
|
/*
|
||||||
|
ApiTwentyFourPlus.java
|
||||||
|
Copyright (C) 2017 Belledonne Communications, Grenoble, France
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@TargetApi(24)
|
||||||
|
public class ApiTwentyFourPlus {
|
||||||
|
|
||||||
|
public static Notification createRepliedNotification(Context context, String reply) {
|
||||||
|
Notification repliedNotification = new Notification.Builder(context)
|
||||||
|
.setSmallIcon(R.drawable.topbar_chat_notification)
|
||||||
|
.setContentText(context.getString(R.string.notification_replied_label).replace("%s", reply))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
return repliedNotification;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Notification createMessageNotification(Context context, int notificationId, int msgCount, String msgSender, String msg, Bitmap contactIcon, PendingIntent intent) {
|
||||||
|
String title;
|
||||||
|
if (msgCount == 1) {
|
||||||
|
title = msgSender;
|
||||||
|
} else {
|
||||||
|
title = context.getString(R.string.unread_messages).replace("%i", String.valueOf(msgCount));
|
||||||
|
}
|
||||||
|
|
||||||
|
String replyLabel = context.getResources().getString(R.string.notification_reply_label);
|
||||||
|
RemoteInput remoteInput = new RemoteInput.Builder(KEY_TEXT_REPLY).setLabel(replyLabel).build();
|
||||||
|
|
||||||
|
Intent replyIntent = new Intent(context, NotificationBroadcastReceiver.class);
|
||||||
|
replyIntent.setAction(context.getPackageName() + ".REPLY_ACTION");
|
||||||
|
replyIntent.putExtra(INTENT_NOTIF_ID, notificationId);
|
||||||
|
|
||||||
|
PendingIntent replyPendingIntent = PendingIntent.getBroadcast(context,
|
||||||
|
notificationId, replyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
|
|
||||||
|
Notification.Action action = new Notification.Action.Builder(R.drawable.chat_send_over,
|
||||||
|
context.getString(R.string.notification_reply_label), replyPendingIntent)
|
||||||
|
.addRemoteInput(remoteInput)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Notification notif;
|
||||||
|
notif = new Notification.Builder(context)
|
||||||
|
.setContentTitle(title)
|
||||||
|
.setContentText(msg)
|
||||||
|
.setSmallIcon(R.drawable.topbar_chat_notification)
|
||||||
|
.setAutoCancel(true)
|
||||||
|
.setContentIntent(intent)
|
||||||
|
.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE)
|
||||||
|
.setLargeIcon(contactIcon)
|
||||||
|
.setCategory(Notification.CATEGORY_MESSAGE)
|
||||||
|
.setVisibility(Notification.VISIBILITY_PRIVATE)
|
||||||
|
.setPriority(Notification.PRIORITY_HIGH)
|
||||||
|
.setNumber(msgCount)
|
||||||
|
.setWhen(System.currentTimeMillis())
|
||||||
|
.setShowWhen(true)
|
||||||
|
.setColor(context.getColor(R.color.notification_color_led))
|
||||||
|
.addAction(action)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
return notif;
|
||||||
|
}
|
||||||
|
}
|
|
@ -7,6 +7,7 @@ import android.app.Notification;
|
||||||
import android.app.NotificationChannel;
|
import android.app.NotificationChannel;
|
||||||
import android.app.NotificationManager;
|
import android.app.NotificationManager;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
|
import android.app.RemoteInput;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
|
@ -14,9 +15,13 @@ import android.view.ViewTreeObserver;
|
||||||
|
|
||||||
import org.linphone.R;
|
import org.linphone.R;
|
||||||
import org.linphone.mediastream.Log;
|
import org.linphone.mediastream.Log;
|
||||||
|
import org.linphone.receivers.NotificationBroadcastReceiver;
|
||||||
|
|
||||||
|
import static org.linphone.compatibility.Compatibility.INTENT_NOTIF_ID;
|
||||||
|
import static org.linphone.compatibility.Compatibility.KEY_TEXT_REPLY;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ApiTwentyOnePlus.java
|
ApiTwentySixPlus.java
|
||||||
Copyright (C) 2017 Belledonne Communications, Grenoble, France
|
Copyright (C) 2017 Belledonne Communications, Grenoble, France
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or
|
This program is free software; you can redistribute it and/or
|
||||||
|
@ -36,6 +41,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
@TargetApi(26)
|
@TargetApi(26)
|
||||||
public class ApiTwentySixPlus {
|
public class ApiTwentySixPlus {
|
||||||
|
public static Notification createRepliedNotification(Context context, String reply) {
|
||||||
|
Notification repliedNotification = new Notification.Builder(context, context.getString(R.string.notification_channel_id))
|
||||||
|
.setSmallIcon(R.drawable.topbar_chat_notification)
|
||||||
|
.setContentText(context.getString(R.string.notification_replied_label).replace("%s", reply))
|
||||||
|
.build();
|
||||||
|
|
||||||
|
return repliedNotification;
|
||||||
|
}
|
||||||
|
|
||||||
public static void createServiceChannel(Context context) {
|
public static void createServiceChannel(Context context) {
|
||||||
NotificationManager notificationManager =
|
NotificationManager notificationManager =
|
||||||
|
@ -68,9 +81,7 @@ public class ApiTwentySixPlus {
|
||||||
notificationManager.createNotificationChannel(channel);
|
notificationManager.createNotificationChannel(channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Notification createMessageNotification(Context context,
|
public static Notification createMessageNotification(Context context, int notificationId, int msgCount, String msgSender, String msg, Bitmap contactIcon, PendingIntent intent) {
|
||||||
int msgCount, String msgSender, String msg, Bitmap contactIcon,
|
|
||||||
PendingIntent intent) {
|
|
||||||
String title;
|
String title;
|
||||||
if (msgCount == 1) {
|
if (msgCount == 1) {
|
||||||
title = msgSender;
|
title = msgSender;
|
||||||
|
@ -78,24 +89,39 @@ public class ApiTwentySixPlus {
|
||||||
title = context.getString(R.string.unread_messages).replace("%i", String.valueOf(msgCount));
|
title = context.getString(R.string.unread_messages).replace("%i", String.valueOf(msgCount));
|
||||||
}
|
}
|
||||||
|
|
||||||
Notification notif = null;
|
String replyLabel = context.getResources().getString(R.string.notification_reply_label);
|
||||||
|
RemoteInput remoteInput = new RemoteInput.Builder(KEY_TEXT_REPLY).setLabel(replyLabel).build();
|
||||||
|
|
||||||
|
Intent replyIntent = new Intent(context, NotificationBroadcastReceiver.class);
|
||||||
|
replyIntent.setAction(context.getPackageName() + ".REPLY_ACTION");
|
||||||
|
replyIntent.putExtra(INTENT_NOTIF_ID, notificationId);
|
||||||
|
|
||||||
|
PendingIntent replyPendingIntent = PendingIntent.getBroadcast(context,
|
||||||
|
notificationId, replyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
|
|
||||||
|
Notification.Action action = new Notification.Action.Builder(R.drawable.chat_send_over,
|
||||||
|
context.getString(R.string.notification_reply_label), replyPendingIntent)
|
||||||
|
.addRemoteInput(remoteInput)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Notification notif;
|
||||||
notif = new Notification.Builder(context, context.getString(R.string.notification_channel_id))
|
notif = new Notification.Builder(context, context.getString(R.string.notification_channel_id))
|
||||||
.setContentTitle(title)
|
.setContentTitle(title)
|
||||||
.setContentText(msg)
|
.setContentText(msg)
|
||||||
.setSmallIcon(R.drawable.topbar_chat_notification)
|
.setSmallIcon(R.drawable.topbar_chat_notification)
|
||||||
.setAutoCancel(true)
|
.setAutoCancel(true)
|
||||||
.setContentIntent(intent)
|
.setContentIntent(intent)
|
||||||
.setDefaults(Notification.DEFAULT_SOUND
|
.setDefaults(Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE)
|
||||||
| Notification.DEFAULT_VIBRATE)
|
.setLargeIcon(contactIcon)
|
||||||
.setLargeIcon(contactIcon)
|
.setCategory(Notification.CATEGORY_MESSAGE)
|
||||||
.setCategory(Notification.CATEGORY_MESSAGE)
|
.setVisibility(Notification.VISIBILITY_PRIVATE)
|
||||||
.setVisibility(Notification.VISIBILITY_PRIVATE)
|
.setPriority(Notification.PRIORITY_HIGH)
|
||||||
.setPriority(Notification.PRIORITY_HIGH)
|
.setNumber(msgCount)
|
||||||
.setNumber(msgCount)
|
.setWhen(System.currentTimeMillis())
|
||||||
.setWhen(System.currentTimeMillis())
|
.setShowWhen(true)
|
||||||
.setShowWhen(true)
|
.setColor(context.getColor(R.color.notification_color_led))
|
||||||
.setColor(context.getColor(R.color.notification_color_led))
|
.addAction(action)
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
return notif;
|
return notif;
|
||||||
}
|
}
|
||||||
|
@ -105,19 +131,19 @@ public class ApiTwentySixPlus {
|
||||||
String contactName, PendingIntent intent) {
|
String contactName, PendingIntent intent) {
|
||||||
|
|
||||||
Notification notif = new Notification.Builder(context, context.getString(R.string.notification_service_channel_id))
|
Notification notif = new Notification.Builder(context, context.getString(R.string.notification_service_channel_id))
|
||||||
.setContentTitle(contactName)
|
.setContentTitle(contactName)
|
||||||
.setContentText(msg)
|
.setContentText(msg)
|
||||||
.setSmallIcon(iconID)
|
.setSmallIcon(iconID)
|
||||||
.setAutoCancel(false)
|
.setAutoCancel(false)
|
||||||
.setContentIntent(intent)
|
.setContentIntent(intent)
|
||||||
.setLargeIcon(contactIcon)
|
.setLargeIcon(contactIcon)
|
||||||
.setCategory(Notification.CATEGORY_CALL)
|
.setCategory(Notification.CATEGORY_CALL)
|
||||||
.setVisibility(Notification.VISIBILITY_PUBLIC)
|
.setVisibility(Notification.VISIBILITY_PUBLIC)
|
||||||
.setPriority(Notification.PRIORITY_HIGH)
|
.setPriority(Notification.PRIORITY_HIGH)
|
||||||
.setWhen(System.currentTimeMillis())
|
.setWhen(System.currentTimeMillis())
|
||||||
.setShowWhen(true)
|
.setShowWhen(true)
|
||||||
.setColor(context.getColor(R.color.notification_color_led))
|
.setColor(context.getColor(R.color.notification_color_led))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
return notif;
|
return notif;
|
||||||
}
|
}
|
||||||
|
@ -127,31 +153,31 @@ public class ApiTwentySixPlus {
|
||||||
|
|
||||||
if (largeIcon != null) {
|
if (largeIcon != null) {
|
||||||
notif = new Notification.Builder(context, context.getString(R.string.notification_service_channel_id))
|
notif = new Notification.Builder(context, context.getString(R.string.notification_service_channel_id))
|
||||||
.setContentTitle(title)
|
.setContentTitle(title)
|
||||||
.setContentText(message)
|
.setContentText(message)
|
||||||
.setSmallIcon(icon, level)
|
.setSmallIcon(icon, level)
|
||||||
.setLargeIcon(largeIcon)
|
.setLargeIcon(largeIcon)
|
||||||
.setContentIntent(intent)
|
.setContentIntent(intent)
|
||||||
.setCategory(Notification.CATEGORY_SERVICE)
|
.setCategory(Notification.CATEGORY_SERVICE)
|
||||||
.setVisibility(Notification.VISIBILITY_SECRET)
|
.setVisibility(Notification.VISIBILITY_SECRET)
|
||||||
.setPriority(priority)
|
.setPriority(priority)
|
||||||
.setWhen(System.currentTimeMillis())
|
.setWhen(System.currentTimeMillis())
|
||||||
.setShowWhen(true)
|
.setShowWhen(true)
|
||||||
.setColor(context.getColor(R.color.notification_color_led))
|
.setColor(context.getColor(R.color.notification_color_led))
|
||||||
.build();
|
.build();
|
||||||
} else {
|
} else {
|
||||||
notif = new Notification.Builder(context, context.getString(R.string.notification_service_channel_id))
|
notif = new Notification.Builder(context, context.getString(R.string.notification_service_channel_id))
|
||||||
.setContentTitle(title)
|
.setContentTitle(title)
|
||||||
.setContentText(message)
|
.setContentText(message)
|
||||||
.setSmallIcon(icon, level)
|
.setSmallIcon(icon, level)
|
||||||
.setContentIntent(intent)
|
.setContentIntent(intent)
|
||||||
.setCategory(Notification.CATEGORY_SERVICE)
|
.setCategory(Notification.CATEGORY_SERVICE)
|
||||||
.setVisibility(Notification.VISIBILITY_SECRET)
|
.setVisibility(Notification.VISIBILITY_SECRET)
|
||||||
.setPriority(priority)
|
.setPriority(priority)
|
||||||
.setWhen(System.currentTimeMillis())
|
.setWhen(System.currentTimeMillis())
|
||||||
.setShowWhen(true)
|
.setShowWhen(true)
|
||||||
.setColor(context.getColor(R.color.notification_color_led))
|
.setColor(context.getColor(R.color.notification_color_led))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
return notif;
|
return notif;
|
||||||
|
@ -163,41 +189,41 @@ public class ApiTwentySixPlus {
|
||||||
|
|
||||||
public static Notification createMissedCallNotification(Context context, String title, String text, PendingIntent intent) {
|
public static Notification createMissedCallNotification(Context context, String title, String text, PendingIntent intent) {
|
||||||
Notification notif = new Notification.Builder(context, context.getString(R.string.notification_channel_id))
|
Notification notif = new Notification.Builder(context, context.getString(R.string.notification_channel_id))
|
||||||
.setContentTitle(title)
|
.setContentTitle(title)
|
||||||
.setContentText(text)
|
.setContentText(text)
|
||||||
.setSmallIcon(R.drawable.call_status_missed)
|
.setSmallIcon(R.drawable.call_status_missed)
|
||||||
.setAutoCancel(true)
|
.setAutoCancel(true)
|
||||||
.setContentIntent(intent)
|
.setContentIntent(intent)
|
||||||
.setDefaults(Notification.DEFAULT_SOUND
|
.setDefaults(Notification.DEFAULT_SOUND
|
||||||
| Notification.DEFAULT_VIBRATE)
|
| Notification.DEFAULT_VIBRATE)
|
||||||
.setCategory(Notification.CATEGORY_MESSAGE)
|
.setCategory(Notification.CATEGORY_MESSAGE)
|
||||||
.setVisibility(Notification.VISIBILITY_PRIVATE)
|
.setVisibility(Notification.VISIBILITY_PRIVATE)
|
||||||
.setPriority(Notification.PRIORITY_HIGH)
|
.setPriority(Notification.PRIORITY_HIGH)
|
||||||
.setWhen(System.currentTimeMillis())
|
.setWhen(System.currentTimeMillis())
|
||||||
.setShowWhen(true)
|
.setShowWhen(true)
|
||||||
.setColor(context.getColor(R.color.notification_color_led))
|
.setColor(context.getColor(R.color.notification_color_led))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
return notif;
|
return notif;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Notification createSimpleNotification(Context context, String title, String text, PendingIntent intent) {
|
public static Notification createSimpleNotification(Context context, String title, String text, PendingIntent intent) {
|
||||||
Notification notif = new Notification.Builder(context, context.getString(R.string.notification_channel_id))
|
Notification notif = new Notification.Builder(context, context.getString(R.string.notification_channel_id))
|
||||||
.setContentTitle(title)
|
.setContentTitle(title)
|
||||||
.setContentText(text)
|
.setContentText(text)
|
||||||
.setSmallIcon(R.drawable.linphone_logo)
|
.setSmallIcon(R.drawable.linphone_logo)
|
||||||
.setAutoCancel(true)
|
.setAutoCancel(true)
|
||||||
.setContentIntent(intent)
|
.setContentIntent(intent)
|
||||||
.setDefaults(Notification.DEFAULT_SOUND
|
.setDefaults(Notification.DEFAULT_SOUND
|
||||||
| Notification.DEFAULT_VIBRATE)
|
| Notification.DEFAULT_VIBRATE)
|
||||||
.setCategory(Notification.CATEGORY_MESSAGE)
|
.setCategory(Notification.CATEGORY_MESSAGE)
|
||||||
.setVisibility(Notification.VISIBILITY_PRIVATE)
|
.setVisibility(Notification.VISIBILITY_PRIVATE)
|
||||||
.setPriority(Notification.PRIORITY_HIGH)
|
.setPriority(Notification.PRIORITY_HIGH)
|
||||||
.setWhen(System.currentTimeMillis())
|
.setWhen(System.currentTimeMillis())
|
||||||
.setShowWhen(true)
|
.setShowWhen(true)
|
||||||
.setColorized(true)
|
.setColorized(true)
|
||||||
.setColor(context.getColor(R.color.notification_color_led))
|
.setColor(context.getColor(R.color.notification_color_led))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
return notif;
|
return notif;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,9 @@ import android.widget.TextView;
|
||||||
import org.linphone.mediastream.Version;
|
import org.linphone.mediastream.Version;
|
||||||
|
|
||||||
public class Compatibility {
|
public class Compatibility {
|
||||||
|
public static final String KEY_TEXT_REPLY = "key_text_reply";
|
||||||
|
public static final String INTENT_NOTIF_ID = "NOTIFICATION_ID";
|
||||||
|
|
||||||
public static void createNotificationChannels(Context context) {
|
public static void createNotificationChannels(Context context) {
|
||||||
if (Version.sdkAboveOrEqual(Version.API26_O_80)) {
|
if (Version.sdkAboveOrEqual(Version.API26_O_80)) {
|
||||||
ApiTwentySixPlus.createServiceChannel(context);
|
ApiTwentySixPlus.createServiceChannel(context);
|
||||||
|
@ -68,9 +71,11 @@ public class Compatibility {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Notification createMessageNotification(Context context, int msgCount, String msgSender, String msg, Bitmap contactIcon, PendingIntent intent) {
|
public static Notification createMessageNotification(Context context, int notificationId, int msgCount, String msgSender, String msg, Bitmap contactIcon, PendingIntent intent) {
|
||||||
if (Version.sdkAboveOrEqual(Version.API26_O_80)) {
|
if (Version.sdkAboveOrEqual(Version.API26_O_80)) {
|
||||||
return ApiTwentySixPlus.createMessageNotification(context, msgCount, msgSender, msg, contactIcon, intent);
|
return ApiTwentySixPlus.createMessageNotification(context, notificationId, msgCount, msgSender, msg, contactIcon, intent);
|
||||||
|
} else if (Version.sdkAboveOrEqual(Version.API24_NOUGAT_70)) {
|
||||||
|
return ApiTwentyFourPlus.createMessageNotification(context, notificationId, msgCount, msgSender, msg, contactIcon, intent);
|
||||||
} else if (Version.sdkAboveOrEqual(Version.API21_LOLLIPOP_50)) {
|
} else if (Version.sdkAboveOrEqual(Version.API21_LOLLIPOP_50)) {
|
||||||
return ApiTwentyOnePlus.createMessageNotification(context, msgCount, msgSender, msg, contactIcon, intent);
|
return ApiTwentyOnePlus.createMessageNotification(context, msgCount, msgSender, msg, contactIcon, intent);
|
||||||
} else if (Version.sdkAboveOrEqual(Version.API16_JELLY_BEAN_41)) {
|
} else if (Version.sdkAboveOrEqual(Version.API16_JELLY_BEAN_41)) {
|
||||||
|
@ -80,6 +85,15 @@ public class Compatibility {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Notification createRepliedNotification(Context context, String reply) {
|
||||||
|
if (Version.sdkAboveOrEqual(Version.API26_O_80)) {
|
||||||
|
return ApiTwentySixPlus.createRepliedNotification(context, reply);
|
||||||
|
} else if (Version.sdkAboveOrEqual(Version.API24_NOUGAT_70)) {
|
||||||
|
return ApiTwentyFourPlus.createRepliedNotification(context, reply);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
public static Notification createInCallNotification(Context context, String title, String msg, int iconID, Bitmap contactIcon, String contactName, PendingIntent intent) {
|
public static Notification createInCallNotification(Context context, String title, String msg, int iconID, Bitmap contactIcon, String contactName, PendingIntent intent) {
|
||||||
if (Version.sdkAboveOrEqual(Version.API26_O_80)) {
|
if (Version.sdkAboveOrEqual(Version.API26_O_80)) {
|
||||||
return ApiTwentySixPlus.createInCallNotification(context, title, msg, iconID, contactIcon, contactName, intent);
|
return ApiTwentySixPlus.createInCallNotification(context, title, msg, iconID, contactIcon, contactName, intent);
|
||||||
|
|
|
@ -0,0 +1,76 @@
|
||||||
|
package org.linphone.receivers;
|
||||||
|
|
||||||
|
/*
|
||||||
|
NotificationBroadcastReceiver.java
|
||||||
|
Copyright (C) 2018 Belledonne Communications, Grenoble, France
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU General Public License
|
||||||
|
as published by the Free Software Foundation; either version 2
|
||||||
|
of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with this program; if not, write to the Free Software
|
||||||
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import android.annotation.TargetApi;
|
||||||
|
import android.app.Notification;
|
||||||
|
import android.app.RemoteInput;
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
|
||||||
|
import org.linphone.LinphoneManager;
|
||||||
|
import org.linphone.LinphoneService;
|
||||||
|
import org.linphone.compatibility.Compatibility;
|
||||||
|
import org.linphone.core.Address;
|
||||||
|
import org.linphone.core.ChatMessage;
|
||||||
|
import org.linphone.core.ChatRoom;
|
||||||
|
import org.linphone.core.Core;
|
||||||
|
import org.linphone.core.ProxyConfig;
|
||||||
|
|
||||||
|
public class NotificationBroadcastReceiver extends BroadcastReceiver {
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent) {
|
||||||
|
String reply = getMessageText(intent).toString();
|
||||||
|
if (reply != null) {
|
||||||
|
Notification replied = Compatibility.createRepliedNotification(context, reply);
|
||||||
|
if (replied != null) {
|
||||||
|
int notifId = intent.getIntExtra(Compatibility.INTENT_NOTIF_ID, 0);
|
||||||
|
String remoteSipAddr = LinphoneService.instance().getSipUriForNotificationId(notifId);
|
||||||
|
|
||||||
|
Core core = LinphoneManager.getLc();
|
||||||
|
if (core == null) return;
|
||||||
|
ProxyConfig proxyConfig = core.getDefaultProxyConfig();
|
||||||
|
if (proxyConfig == null) return;
|
||||||
|
Address localAddr = proxyConfig.getIdentityAddress();
|
||||||
|
Address remoteAddr = core.interpretUrl(remoteSipAddr);
|
||||||
|
if (localAddr == null || remoteAddr == null) return;
|
||||||
|
ChatRoom room = core.findChatRoom(remoteAddr, localAddr);
|
||||||
|
if (room == null) return;
|
||||||
|
|
||||||
|
room.markAsRead();
|
||||||
|
ChatMessage msg = room.createMessage(reply);
|
||||||
|
msg.send();
|
||||||
|
|
||||||
|
LinphoneService.instance().sendNotification(replied, notifId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@TargetApi(20)
|
||||||
|
private CharSequence getMessageText(Intent intent) {
|
||||||
|
Bundle remoteInput = RemoteInput.getResultsFromIntent(intent);
|
||||||
|
if (remoteInput != null) {
|
||||||
|
return remoteInput.getCharSequence(Compatibility.KEY_TEXT_REPLY);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
|
@ -9,8 +9,7 @@
|
||||||
<entry name="quality_reporting_interval" overwrite="true">180</entry>
|
<entry name="quality_reporting_interval" overwrite="true">180</entry>
|
||||||
<entry name="reg_expires" overwrite="true">31536000</entry>
|
<entry name="reg_expires" overwrite="true">31536000</entry>
|
||||||
<entry name="reg_identity" overwrite="true">sip:?@sip.linphone.org</entry>
|
<entry name="reg_identity" overwrite="true">sip:?@sip.linphone.org</entry>
|
||||||
<entry name="reg_proxy" overwrite="true"><sip:sip-staging.linphone.org:5081;transport=tls></entry>
|
<entry name="reg_proxy" overwrite="true"><sip:sip.linphone.org;transport=tls></entry>
|
||||||
<entry name="reg_route" overwrite="true"><sip:sip-staging.linphone.org:5081;transport=tls></entry>
|
|
||||||
<entry name="reg_sendregister" overwrite="true">1</entry>
|
<entry name="reg_sendregister" overwrite="true">1</entry>
|
||||||
<entry name="nat_policy_ref" overwrite="true">nat_policy_default_values</entry>
|
<entry name="nat_policy_ref" overwrite="true">nat_policy_default_values</entry>
|
||||||
<entry name="realm" overwrite="true">sip.linphone.org</entry>
|
<entry name="realm" overwrite="true">sip.linphone.org</entry>
|
||||||
|
|
|
@ -15,6 +15,10 @@
|
||||||
<string name="about_link">www.linphone.org</string>
|
<string name="about_link">www.linphone.org</string>
|
||||||
<string name="sync_account_name">linphone contacts</string>
|
<string name="sync_account_name">linphone contacts</string>
|
||||||
|
|
||||||
|
<!-- Notifications -->
|
||||||
|
<string name="notification_reply_label">Reply</string>
|
||||||
|
<string name="notification_replied_label">Sent reply: %s</string>
|
||||||
|
|
||||||
<!-- Common -->
|
<!-- Common -->
|
||||||
<string name="username">Username</string>
|
<string name="username">Username</string>
|
||||||
<string name="userid">User-id (optional)</string>
|
<string name="userid">User-id (optional)</string>
|
||||||
|
|
Loading…
Reference in a new issue