Improved notifications: start call activity after answering from notification + show reply in message notification like SMS app + improved compatibility methods to fully used available APIs + updated target api to 29

This commit is contained in:
Sylvain Berfini 2019-09-11 16:17:53 +02:00
parent d6d46e19fa
commit 74261a1830
14 changed files with 374 additions and 81 deletions

View file

@ -2,7 +2,7 @@ job-android:
stage: build
tags: [ "docker-android" ]
image: gitlab.linphone.org:4567/bc/public/linphone-android/bc-dev-android:28
image: gitlab.linphone.org:4567/bc/public/linphone-android/bc-dev-android:29
before_script:
- if ! [ -z ${SCP_PRIVATE_KEY+x} ]; then eval $(ssh-agent -s); fi
@ -30,4 +30,4 @@ job-android:
.scheduled-job-android:
extends: job-android
only:
- schedules
- schedules

View file

@ -24,6 +24,7 @@ Group changes to describe their impact on the project, as follows:
- Call statistics are now available for each call & conference
- Added our own devices in LIME encrypted chatrooms' security view
- No longer display incoming call activity from Service, instead use incoming call notification with full screen intent
- Improved reply notification when replying to a chat message from the notification
## [4.1.0] - 2019-05-03

View file

@ -74,10 +74,10 @@ android {
abortOnError false
}
compileSdkVersion 28
compileSdkVersion 29
defaultConfig {
minSdkVersion 21
targetSdkVersion 28
targetSdkVersion 29
versionCode 4126
versionName "${project.version}"
applicationId getPackageName()

View file

@ -30,6 +30,7 @@ import android.os.Handler;
import android.os.IBinder;
import android.provider.ContactsContract;
import android.view.WindowManager;
import org.linphone.call.CallActivity;
import org.linphone.call.CallIncomingActivity;
import org.linphone.call.CallOutgoingActivity;
import org.linphone.contacts.ContactsManager;
@ -159,6 +160,8 @@ public final class LinphoneService extends Service {
// if (!mLinphoneManager.getCallGsmON()) onIncomingReceived();
} else if (state == State.OutgoingInit) {
onOutgoingStarted();
} else if (state == State.Connected) {
onCallStarted();
} else if (state == State.End
|| state == State.Released
|| state == State.Error) {
@ -384,4 +387,11 @@ public final class LinphoneService extends Service {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
private void onCallStarted() {
Intent intent = new Intent(LinphoneService.this, CallActivity.class);
// This flag is required to start an Activity from a Service context
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
}

View file

@ -22,7 +22,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
import android.Manifest;
import android.app.KeyguardManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.KeyEvent;
@ -126,8 +125,9 @@ public class CallIncomingActivity extends LinphoneGenericActivity {
Core core, Call call, State state, String message) {
if (call == mCall) {
if (state == State.Connected) {
startActivity(
new Intent(CallIncomingActivity.this, CallActivity.class));
// This is done by the Service listener now
// startActivity(new Intent(CallOutgoingActivity.this,
// CallActivity.class));
}
}

View file

@ -20,7 +20,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.KeyEvent;
@ -129,8 +128,9 @@ public class CallOutgoingActivity extends LinphoneGenericActivity implements OnC
.show();
}
} else if (state == State.Connected) {
startActivity(
new Intent(CallOutgoingActivity.this, CallActivity.class));
// This is done by the Service listener now
// startActivity(new Intent(CallOutgoingActivity.this,
// CallActivity.class));
}
if (LinphoneManager.getCore().getCallsNb() == 0) {

View file

@ -20,19 +20,27 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import static org.linphone.compatibility.Compatibility.CHAT_NOTIFICATIONS_GROUP;
import static org.linphone.compatibility.Compatibility.INTENT_LOCAL_IDENTITY;
import static org.linphone.compatibility.Compatibility.INTENT_MARK_AS_READ_ACTION;
import static org.linphone.compatibility.Compatibility.INTENT_NOTIF_ID;
import static org.linphone.compatibility.Compatibility.INTENT_REPLY_NOTIF_ACTION;
import static org.linphone.compatibility.Compatibility.KEY_TEXT_REPLY;
import android.annotation.TargetApi;
import android.app.ActivityManager;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Person;
import android.app.RemoteInput;
import android.app.usage.UsageStatsManager;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.drawable.Icon;
import org.linphone.R;
import org.linphone.notifications.Notifiable;
import org.linphone.notifications.NotifiableMessage;
import org.linphone.notifications.NotificationBroadcastReceiver;
@TargetApi(28)
class ApiTwentyEightPlus {
@ -84,8 +92,8 @@ class ApiTwentyEightPlus {
.setShowWhen(true)
.setColor(context.getColor(R.color.notification_led_color))
.setStyle(style)
.addAction(ApiTwentyFourPlus.getReplyMessageAction(context, notif))
.addAction(ApiTwentyFourPlus.getMarkMessageAsReadAction(context, notif))
.addAction(Compatibility.getReplyMessageAction(context, notif))
.addAction(Compatibility.getMarkMessageAsReadAction(context, notif))
.build();
}
@ -114,4 +122,53 @@ class ApiTwentyEightPlus {
}
return null;
}
public static Notification.Action getReplyMessageAction(Context context, Notifiable notif) {
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(INTENT_REPLY_NOTIF_ACTION);
replyIntent.putExtra(INTENT_NOTIF_ID, notif.getNotificationId());
replyIntent.putExtra(INTENT_LOCAL_IDENTITY, notif.getLocalIdentity());
PendingIntent replyPendingIntent =
PendingIntent.getBroadcast(
context,
notif.getNotificationId(),
replyIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
return new Notification.Action.Builder(
R.drawable.chat_send_over,
context.getString(R.string.notification_reply_label),
replyPendingIntent)
.addRemoteInput(remoteInput)
.setAllowGeneratedReplies(true)
.setSemanticAction(Notification.Action.SEMANTIC_ACTION_REPLY)
.build();
}
public static Notification.Action getMarkMessageAsReadAction(
Context context, Notifiable notif) {
Intent markAsReadIntent = new Intent(context, NotificationBroadcastReceiver.class);
markAsReadIntent.setAction(INTENT_MARK_AS_READ_ACTION);
markAsReadIntent.putExtra(INTENT_NOTIF_ID, notif.getNotificationId());
markAsReadIntent.putExtra(INTENT_LOCAL_IDENTITY, notif.getLocalIdentity());
PendingIntent markAsReadPendingIntent =
PendingIntent.getBroadcast(
context,
notif.getNotificationId(),
markAsReadIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
return new Notification.Action.Builder(
R.drawable.chat_send_over,
context.getString(R.string.notification_mark_as_read_label),
markAsReadPendingIntent)
.setSemanticAction(Notification.Action.SEMANTIC_ACTION_MARK_AS_READ)
.build();
}
}

View file

@ -86,8 +86,8 @@ class ApiTwentyFourPlus {
.setShowWhen(true)
.setColor(context.getColor(R.color.notification_led_color))
.setStyle(style)
.addAction(getReplyMessageAction(context, notif))
.addAction(getMarkMessageAsReadAction(context, notif))
.addAction(Compatibility.getReplyMessageAction(context, notif))
.addAction(Compatibility.getMarkMessageAsReadAction(context, notif))
.build();
}
@ -116,11 +116,11 @@ class ApiTwentyFourPlus {
.setShowWhen(true)
.setOngoing(true)
.setColor(context.getColor(R.color.notification_led_color))
.addAction(getCallDeclineAction(context, callId));
.addAction(Compatibility.getCallDeclineAction(context, callId));
if (showAnswerAction) {
builder.setFullScreenIntent(intent, true);
builder.addAction(getCallAnswerAction(context, callId));
builder.addAction(Compatibility.getCallAnswerAction(context, callId));
}
return builder.build();

View file

@ -0,0 +1,126 @@
package org.linphone.compatibility;
/*
ApiTwentyNinePlus.java
Copyright (C) 2019 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 static org.linphone.compatibility.Compatibility.INTENT_ANSWER_CALL_NOTIF_ACTION;
import static org.linphone.compatibility.Compatibility.INTENT_HANGUP_CALL_NOTIF_ACTION;
import static org.linphone.compatibility.Compatibility.INTENT_LOCAL_IDENTITY;
import static org.linphone.compatibility.Compatibility.INTENT_MARK_AS_READ_ACTION;
import static org.linphone.compatibility.Compatibility.INTENT_NOTIF_ID;
import static org.linphone.compatibility.Compatibility.INTENT_REPLY_NOTIF_ACTION;
import static org.linphone.compatibility.Compatibility.KEY_TEXT_REPLY;
import android.annotation.TargetApi;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.RemoteInput;
import android.content.Context;
import android.content.Intent;
import org.linphone.R;
import org.linphone.notifications.Notifiable;
import org.linphone.notifications.NotificationBroadcastReceiver;
@TargetApi(29)
public class ApiTwentyNinePlus {
public static Notification.Action getReplyMessageAction(Context context, Notifiable notif) {
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(INTENT_REPLY_NOTIF_ACTION);
replyIntent.putExtra(INTENT_NOTIF_ID, notif.getNotificationId());
replyIntent.putExtra(INTENT_LOCAL_IDENTITY, notif.getLocalIdentity());
PendingIntent replyPendingIntent =
PendingIntent.getBroadcast(
context,
notif.getNotificationId(),
replyIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
return new Notification.Action.Builder(
R.drawable.chat_send_over,
context.getString(R.string.notification_reply_label),
replyPendingIntent)
.addRemoteInput(remoteInput)
.setAllowGeneratedReplies(true)
.setSemanticAction(Notification.Action.SEMANTIC_ACTION_REPLY)
.setContextual(true)
.build();
}
public static Notification.Action getMarkMessageAsReadAction(
Context context, Notifiable notif) {
Intent markAsReadIntent = new Intent(context, NotificationBroadcastReceiver.class);
markAsReadIntent.setAction(INTENT_MARK_AS_READ_ACTION);
markAsReadIntent.putExtra(INTENT_NOTIF_ID, notif.getNotificationId());
markAsReadIntent.putExtra(INTENT_LOCAL_IDENTITY, notif.getLocalIdentity());
PendingIntent markAsReadPendingIntent =
PendingIntent.getBroadcast(
context,
notif.getNotificationId(),
markAsReadIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
return new Notification.Action.Builder(
R.drawable.chat_send_over,
context.getString(R.string.notification_mark_as_read_label),
markAsReadPendingIntent)
.setSemanticAction(Notification.Action.SEMANTIC_ACTION_MARK_AS_READ)
.setContextual(true)
.build();
}
public static Notification.Action getCallAnswerAction(Context context, int callId) {
Intent answerIntent = new Intent(context, NotificationBroadcastReceiver.class);
answerIntent.setAction(INTENT_ANSWER_CALL_NOTIF_ACTION);
answerIntent.putExtra(INTENT_NOTIF_ID, callId);
PendingIntent answerPendingIntent =
PendingIntent.getBroadcast(
context, callId, answerIntent, PendingIntent.FLAG_UPDATE_CURRENT);
return new Notification.Action.Builder(
R.drawable.call_audio_start,
context.getString(R.string.notification_call_answer_label),
answerPendingIntent)
.setContextual(true)
.build();
}
public static Notification.Action getCallDeclineAction(Context context, int callId) {
Intent hangupIntent = new Intent(context, NotificationBroadcastReceiver.class);
hangupIntent.setAction(INTENT_HANGUP_CALL_NOTIF_ACTION);
hangupIntent.putExtra(INTENT_NOTIF_ID, callId);
PendingIntent hangupPendingIntent =
PendingIntent.getBroadcast(
context, callId, hangupIntent, PendingIntent.FLAG_UPDATE_CURRENT);
return new Notification.Action.Builder(
R.drawable.call_hangup,
context.getString(R.string.notification_call_hangup_label),
hangupPendingIntent)
.setContextual(true)
.build();
}
}

View file

@ -135,8 +135,8 @@ class ApiTwentySixPlus {
.setShowWhen(true)
.setColor(context.getColor(R.color.notification_led_color))
.setStyle(style)
.addAction(ApiTwentyFourPlus.getReplyMessageAction(context, notif))
.addAction(ApiTwentyFourPlus.getMarkMessageAsReadAction(context, notif))
.addAction(Compatibility.getReplyMessageAction(context, notif))
.addAction(Compatibility.getMarkMessageAsReadAction(context, notif))
.build();
}
@ -171,11 +171,11 @@ class ApiTwentySixPlus {
.setShowWhen(true)
.setOngoing(true)
.setColor(context.getColor(R.color.notification_led_color))
.addAction(ApiTwentyFourPlus.getCallDeclineAction(context, callId));
.addAction(Compatibility.getCallDeclineAction(context, callId));
if (isIncoming) {
builder.setFullScreenIntent(intent, true);
builder.addAction(ApiTwentyFourPlus.getCallAnswerAction(context, callId));
builder.addAction(Compatibility.getCallAnswerAction(context, callId));
}
return builder.build();
}

View file

@ -249,4 +249,45 @@ public class Compatibility {
ApiTwentySixPlus.enterPipMode(activity);
}
}
public static Notification.Action getReplyMessageAction(Context context, Notifiable notif) {
if (Version.sdkAboveOrEqual(Version.API29_ANDROID_10)) {
return ApiTwentyNinePlus.getReplyMessageAction(context, notif);
} else if (Version.sdkAboveOrEqual(Version.API28_PIE_90)) {
return ApiTwentyEightPlus.getReplyMessageAction(context, notif);
} else if (Version.sdkAboveOrEqual(Version.API24_NOUGAT_70)) {
return ApiTwentyFourPlus.getReplyMessageAction(context, notif);
}
return null;
}
public static Notification.Action getMarkMessageAsReadAction(
Context context, Notifiable notif) {
if (Version.sdkAboveOrEqual(Version.API29_ANDROID_10)) {
return ApiTwentyNinePlus.getMarkMessageAsReadAction(context, notif);
} else if (Version.sdkAboveOrEqual(Version.API28_PIE_90)) {
return ApiTwentyEightPlus.getMarkMessageAsReadAction(context, notif);
} else if (Version.sdkAboveOrEqual(Version.API24_NOUGAT_70)) {
return ApiTwentyFourPlus.getMarkMessageAsReadAction(context, notif);
}
return null;
}
public static Notification.Action getCallAnswerAction(Context context, int callId) {
if (Version.sdkAboveOrEqual(Version.API29_ANDROID_10)) {
return ApiTwentyNinePlus.getCallAnswerAction(context, callId);
} else if (Version.sdkAboveOrEqual(Version.API24_NOUGAT_70)) {
return ApiTwentyFourPlus.getCallAnswerAction(context, callId);
}
return null;
}
public static Notification.Action getCallDeclineAction(Context context, int callId) {
if (Version.sdkAboveOrEqual(Version.API29_ANDROID_10)) {
return ApiTwentyNinePlus.getCallDeclineAction(context, callId);
} else if (Version.sdkAboveOrEqual(Version.API24_NOUGAT_70)) {
return ApiTwentyFourPlus.getCallDeclineAction(context, callId);
}
return null;
}
}

View file

@ -32,7 +32,6 @@ import org.linphone.compatibility.Compatibility;
import org.linphone.core.Address;
import org.linphone.core.Call;
import org.linphone.core.ChatMessage;
import org.linphone.core.ChatMessageListenerStub;
import org.linphone.core.ChatRoom;
import org.linphone.core.Core;
import org.linphone.core.tools.Log;
@ -97,25 +96,11 @@ public class NotificationBroadcastReceiver extends BroadcastReceiver {
}
ChatMessage msg = room.createMessage(reply);
msg.send();
msg.setUserData(notifId);
msg.addListener(
new ChatMessageListenerStub() {
@Override
public void onMsgStateChanged(
ChatMessage msg, ChatMessage.State state) {
if (state == ChatMessage.State.Delivered) {
Notification replied =
Compatibility.createRepliedNotification(context, reply);
LinphoneService.instance()
.getNotificationManager()
.sendNotification(notifId, replied);
} else if (state == ChatMessage.State.NotDelivered) {
Log.e(
"[Notification Broadcast Receiver] Couldn't send reply, message is not delivered");
onError(context, notifId);
}
}
});
LinphoneService.instance().getNotificationManager().getMessageListener());
msg.send();
Log.i("[Notification Broadcast Receiver] Reply sent for notif id " + notifId);
} else {
LinphoneService.instance().getNotificationManager().dismissNotification(notifId);
}

View file

@ -45,6 +45,7 @@ import org.linphone.contacts.LinphoneContact;
import org.linphone.core.Address;
import org.linphone.core.Call;
import org.linphone.core.ChatMessage;
import org.linphone.core.ChatMessageListenerStub;
import org.linphone.core.ChatRoom;
import org.linphone.core.ChatRoomCapabilities;
import org.linphone.core.Content;
@ -73,6 +74,7 @@ public class NotificationsManager {
private int mCurrentForegroundServiceNotification;
private String mCurrentChatRoomAddress;
private CoreListenerStub mListener;
private ChatMessageListenerStub mMessageListener;
public NotificationsManager(Context context) {
mContext = context;
@ -207,6 +209,53 @@ public class NotificationsManager {
}
}
};
mMessageListener =
new ChatMessageListenerStub() {
@Override
public void onMsgStateChanged(ChatMessage msg, ChatMessage.State state) {
if (msg.getUserData() == null) return;
int notifId = (int) msg.getUserData();
Log.i(
"[Notifications Manager] Reply message state changed ("
+ state.name()
+ ") for notif id "
+ notifId);
if (state != ChatMessage.State.InProgress) {
// There is no need to be called here twice
msg.removeListener(this);
}
if (state == ChatMessage.State.Delivered
|| state == ChatMessage.State.Displayed) {
Notifiable notif =
mChatNotifMap.get(
msg.getChatRoom().getPeerAddress().asStringUriOnly());
if (notif == null) {
Log.e(
"[Notifications Manager] Couldn't find message notification for SIP URI "
+ msg.getChatRoom()
.getPeerAddress()
.asStringUriOnly());
dismissNotification(notifId);
return;
} else if (notif.getNotificationId() != notifId) {
Log.w(
"[Notifications Manager] Notif ID doesn't match: "
+ notifId
+ " != "
+ notif.getNotificationId());
}
displayReplyMessageNotification(msg, notif);
} else if (state == ChatMessage.State.NotDelivered) {
Log.e(
"[Notifications Manager] Couldn't send reply, message is not delivered");
dismissNotification(notifId);
}
}
};
}
public void onCoreReady() {
@ -294,6 +343,10 @@ public class NotificationsManager {
}
}
public ChatMessageListenerStub getMessageListener() {
return mMessageListener;
}
private boolean isServiceNotificationDisplayed() {
return LinphonePreferences.instance().getServiceNotificationVisibility();
}
@ -307,6 +360,61 @@ public class NotificationsManager {
return null;
}
private void displayMessageNotificationFromNotifiable(
Notifiable notif, String remoteSipUri, String localSipUri) {
Intent notifIntent = new Intent(mContext, ChatActivity.class);
notifIntent.putExtra("RemoteSipUri", remoteSipUri);
notifIntent.putExtra("LocalSipUri", localSipUri);
addFlagsToIntent(notifIntent);
PendingIntent pendingIntent =
PendingIntent.getActivity(
mContext,
notif.getNotificationId(),
notifIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
NotifiableMessage lastNotifiable = notif.getMessages().get(notif.getMessages().size() - 1);
String from = lastNotifiable.getSender();
String message = lastNotifiable.getMessage();
Bitmap bm = lastNotifiable.getSenderBitmap();
if (notif.isGroup()) {
message =
mContext.getString(R.string.group_chat_notif)
.replace("%1", from)
.replace("%2", message);
from = notif.getGroupTitle();
}
Notification notification =
Compatibility.createMessageNotification(
mContext, notif, from, message, bm, pendingIntent);
sendNotification(notif.getNotificationId(), notification);
}
private void displayReplyMessageNotification(ChatMessage msg, Notifiable notif) {
if (msg == null || notif == null) return;
Log.i(
"[Notifications Manager] Updating message notification with reply for notif "
+ notif.getNotificationId());
NotifiableMessage notifMessage =
new NotifiableMessage(
msg.getTextContent(),
notif.getMyself(),
System.currentTimeMillis(),
null,
null);
notif.addMessage(notifMessage);
ChatRoom cr = msg.getChatRoom();
displayMessageNotificationFromNotifiable(
notif,
cr.getPeerAddress().asStringUriOnly(),
cr.getLocalAddress().asStringUriOnly());
}
public void displayGroupChatMessageNotification(
String subject,
String conferenceAddress,
@ -336,29 +444,8 @@ public class NotificationsManager {
notif.setMyself(LinphoneUtils.getAddressDisplayName(localIdentity));
notif.setLocalIdentity(localIdentity.asString());
Intent notifIntent = new Intent(mContext, ChatActivity.class);
notifIntent.putExtra("RemoteSipUri", conferenceAddress);
notifIntent.putExtra("LocalSipUri", localIdentity.asStringUriOnly());
addFlagsToIntent(notifIntent);
PendingIntent pendingIntent =
PendingIntent.getActivity(
mContext,
notif.getNotificationId(),
notifIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification =
Compatibility.createMessageNotification(
mContext,
notif,
subject,
mContext.getString(R.string.group_chat_notif)
.replace("%1", fromName)
.replace("%2", message),
bm,
pendingIntent);
sendNotification(notif.getNotificationId(), notification);
displayMessageNotificationFromNotifiable(
notif, conferenceAddress, localIdentity.asStringUriOnly());
}
public void displayMessageNotification(
@ -391,22 +478,8 @@ public class NotificationsManager {
notif.setMyself(LinphoneUtils.getAddressDisplayName(localIdentity));
notif.setLocalIdentity(localIdentity.asString());
Intent notifIntent = new Intent(mContext, ChatActivity.class);
notifIntent.putExtra("RemoteSipUri", fromSipUri);
notifIntent.putExtra("LocalSipUri", localIdentity.asStringUriOnly());
addFlagsToIntent(notifIntent);
PendingIntent pendingIntent =
PendingIntent.getActivity(
mContext,
notif.getNotificationId(),
notifIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification =
Compatibility.createMessageNotification(
mContext, notif, fromName, message, bm, pendingIntent);
sendNotification(notif.getNotificationId(), notification);
displayMessageNotificationFromNotifiable(
notif, fromSipUri, localIdentity.asStringUriOnly());
}
public void displayMissedCallNotification(Call call) {

View file

@ -29,15 +29,15 @@ RUN wget https://dl.google.com/android/repository/tools_r$ANDROID_SDK-linux.zip
ENV PATH $ANDROID_HOME/tools:$ANDROID_HOME/tools/bin:$ANDROID_HOME/platform-tools:$PATH
# Get the Android SDK
RUN echo "y" | sdkmanager "platforms;android-28" "build-tools;28.0.3" "extras;android;m2repository" "extras;google;m2repository" "platform-tools" "tools"
RUN echo "y" | sdkmanager "platforms;android-29" "build-tools;29.0.2" "extras;android;m2repository" "extras;google;m2repository" "platform-tools" "tools"
# Accept Android SDK licenses
RUN yes | sdkmanager --licenses
# Update if needed
RUN echo y | android update sdk --no-ui --all --filter platform-tools
RUN echo y | android update sdk --no-ui --all --filter android-28
RUN echo y | android update sdk --no-ui --all --filter build-tools-28.0.3
RUN echo y | android update sdk --no-ui --all --filter android-29
RUN echo y | android update sdk --no-ui --all --filter build-tools-29.0.2
# Configure user bc
RUN useradd -ms /bin/bash bc && \