Added shortcuts to most recent 1-1 chat rooms
This commit is contained in:
parent
20c32ccdab
commit
fdb1e0ed60
22 changed files with 318 additions and 52 deletions
|
@ -10,6 +10,11 @@ Group changes to describe their impact on the project, as follows:
|
||||||
Fixed for any bug fixes.
|
Fixed for any bug fixes.
|
||||||
Security to invite users to upgrade in case of vulnerabilities.
|
Security to invite users to upgrade in case of vulnerabilities.
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
- Added shortcuts to calls history & chat rooms list
|
||||||
|
|
||||||
## [4.1.0] - 2019-05-03
|
## [4.1.0] - 2019-05-03
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
|
@ -7,5 +7,5 @@
|
||||||
android:icon="@drawable/linphone_logo"
|
android:icon="@drawable/linphone_logo"
|
||||||
android:mimeType="vnd.android.cursor.item/vnd.%%PACKAGE_NAME%%.provider.sip_address"
|
android:mimeType="vnd.android.cursor.item/vnd.%%PACKAGE_NAME%%.provider.sip_address"
|
||||||
android:summaryColumn="data2" />
|
android:summaryColumn="data2" />
|
||||||
<!-- You can use @string/linphone_address_mime_type above ! You have to hardcode it... -->
|
<!-- You can't use @string/linphone_address_mime_type above ! You have to hardcode it... -->
|
||||||
</ContactsSource>
|
</ContactsSource>
|
||||||
|
|
|
@ -134,6 +134,9 @@
|
||||||
android:name=".chat.ChatActivity"
|
android:name=".chat.ChatActivity"
|
||||||
android:launchMode="singleTop"
|
android:launchMode="singleTop"
|
||||||
android:theme="@style/LinphoneStyleLight">
|
android:theme="@style/LinphoneStyleLight">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
</intent-filter>
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.SEND" />
|
<action android:name="android.intent.action.SEND" />
|
||||||
|
|
||||||
|
@ -172,6 +175,9 @@
|
||||||
android:name=".history.HistoryActivity"
|
android:name=".history.HistoryActivity"
|
||||||
android:launchMode="singleTop"
|
android:launchMode="singleTop"
|
||||||
android:theme="@style/LinphoneStyleLight">
|
android:theme="@style/LinphoneStyleLight">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.MAIN" />
|
||||||
|
</intent-filter>
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<!-- Call activities -->
|
<!-- Call activities -->
|
||||||
|
|
|
@ -93,7 +93,7 @@ public class LinphoneManager implements SensorEventListener {
|
||||||
private final String mFriendsDatabaseFile;
|
private final String mFriendsDatabaseFile;
|
||||||
private final String mUserCertsPath;
|
private final String mUserCertsPath;
|
||||||
|
|
||||||
private final Context mServiceContext;
|
private final Context mContext;
|
||||||
private AndroidAudioManager mAudioManager;
|
private AndroidAudioManager mAudioManager;
|
||||||
private CallManager mCallManager;
|
private CallManager mCallManager;
|
||||||
private final PowerManager mPowerManager;
|
private final PowerManager mPowerManager;
|
||||||
|
@ -120,7 +120,7 @@ public class LinphoneManager implements SensorEventListener {
|
||||||
|
|
||||||
public LinphoneManager(Context c) {
|
public LinphoneManager(Context c) {
|
||||||
mExited = false;
|
mExited = false;
|
||||||
mServiceContext = c;
|
mContext = c;
|
||||||
mBasePath = c.getFilesDir().getAbsolutePath();
|
mBasePath = c.getFilesDir().getAbsolutePath();
|
||||||
mLPConfigXsd = mBasePath + "/lpconfig.xsd";
|
mLPConfigXsd = mBasePath + "/lpconfig.xsd";
|
||||||
mLinphoneFactoryConfigFile = mBasePath + "/linphonerc";
|
mLinphoneFactoryConfigFile = mBasePath + "/linphonerc";
|
||||||
|
@ -260,7 +260,7 @@ public class LinphoneManager implements SensorEventListener {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
AlertDialog.Builder builder =
|
AlertDialog.Builder builder =
|
||||||
new AlertDialog.Builder(mServiceContext);
|
new AlertDialog.Builder(mContext);
|
||||||
builder.setMessage(
|
builder.setMessage(
|
||||||
getString(R.string.update_available)
|
getString(R.string.update_available)
|
||||||
+ ": "
|
+ ": "
|
||||||
|
@ -279,8 +279,7 @@ public class LinphoneManager implements SensorEventListener {
|
||||||
Intent.ACTION_VIEW);
|
Intent.ACTION_VIEW);
|
||||||
urlIntent.setData(
|
urlIntent.setData(
|
||||||
Uri.parse(urlToUse));
|
Uri.parse(urlToUse));
|
||||||
mServiceContext.startActivity(
|
mContext.startActivity(urlIntent);
|
||||||
urlIntent);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -416,12 +415,12 @@ public class LinphoneManager implements SensorEventListener {
|
||||||
Log.e("[Manager] Destroy Core Runtime Exception: " + e);
|
Log.e("[Manager] Destroy Core Runtime Exception: " + e);
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
try {
|
||||||
mServiceContext.unregisterReceiver(mHookReceiver);
|
mContext.unregisterReceiver(mHookReceiver);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e("[Manager] unregister receiver exception: " + e);
|
Log.e("[Manager] unregister receiver exception: " + e);
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
mServiceContext.unregisterReceiver(mCallReceiver);
|
mContext.unregisterReceiver(mCallReceiver);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e("[Manager] unregister receiver exception: " + e);
|
Log.e("[Manager] unregister receiver exception: " + e);
|
||||||
}
|
}
|
||||||
|
@ -436,7 +435,7 @@ public class LinphoneManager implements SensorEventListener {
|
||||||
// traces alway start with traces enable to not missed first initialization
|
// traces alway start with traces enable to not missed first initialization
|
||||||
mCore =
|
mCore =
|
||||||
Factory.instance()
|
Factory.instance()
|
||||||
.createCore(mConfigFile, mLinphoneFactoryConfigFile, mServiceContext);
|
.createCore(mConfigFile, mLinphoneFactoryConfigFile, mContext);
|
||||||
mCore.addListener(mCoreListener);
|
mCore.addListener(mCoreListener);
|
||||||
if (isPush) {
|
if (isPush) {
|
||||||
Log.w(
|
Log.w(
|
||||||
|
@ -472,12 +471,12 @@ public class LinphoneManager implements SensorEventListener {
|
||||||
|
|
||||||
private synchronized void initLiblinphone(Core core) {
|
private synchronized void initLiblinphone(Core core) {
|
||||||
mCore = core;
|
mCore = core;
|
||||||
mAudioManager = new AndroidAudioManager(mServiceContext);
|
mAudioManager = new AndroidAudioManager(mContext);
|
||||||
|
|
||||||
mCore.setZrtpSecretsFile(mBasePath + "/zrtp_secrets");
|
mCore.setZrtpSecretsFile(mBasePath + "/zrtp_secrets");
|
||||||
|
|
||||||
String deviceName = mPrefs.getDeviceName(mServiceContext);
|
String deviceName = mPrefs.getDeviceName(mContext);
|
||||||
String appName = mServiceContext.getResources().getString(R.string.user_agent);
|
String appName = mContext.getResources().getString(R.string.user_agent);
|
||||||
String androidVersion = BuildConfig.VERSION_NAME;
|
String androidVersion = BuildConfig.VERSION_NAME;
|
||||||
String userAgent = appName + "/" + androidVersion + " (" + deviceName + ") LinphoneSDK";
|
String userAgent = appName + "/" + androidVersion + " (" + deviceName + ") LinphoneSDK";
|
||||||
|
|
||||||
|
@ -526,8 +525,8 @@ public class LinphoneManager implements SensorEventListener {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mServiceContext.getResources().getBoolean(R.bool.enable_push_id)) {
|
if (mContext.getResources().getBoolean(R.bool.enable_push_id)) {
|
||||||
PushNotificationUtils.init(mServiceContext);
|
PushNotificationUtils.init(mContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
IntentFilter mCallIntentFilter =
|
IntentFilter mCallIntentFilter =
|
||||||
|
@ -535,19 +534,19 @@ public class LinphoneManager implements SensorEventListener {
|
||||||
mCallIntentFilter.setPriority(99999999);
|
mCallIntentFilter.setPriority(99999999);
|
||||||
mCallReceiver = new OutgoingCallReceiver();
|
mCallReceiver = new OutgoingCallReceiver();
|
||||||
try {
|
try {
|
||||||
mServiceContext.registerReceiver(mCallReceiver, mCallIntentFilter);
|
mContext.registerReceiver(mCallReceiver, mCallIntentFilter);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
mProximityWakelock =
|
mProximityWakelock =
|
||||||
mPowerManager.newWakeLock(
|
mPowerManager.newWakeLock(
|
||||||
PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK,
|
PowerManager.PROXIMITY_SCREEN_OFF_WAKE_LOCK,
|
||||||
mServiceContext.getPackageName() + ";manager_proximity_sensor");
|
mContext.getPackageName() + ";manager_proximity_sensor");
|
||||||
|
|
||||||
IntentFilter mHookIntentFilter = new IntentFilter("com.base.module.phone.HOOKEVENT");
|
IntentFilter mHookIntentFilter = new IntentFilter("com.base.module.phone.HOOKEVENT");
|
||||||
mHookIntentFilter.setPriority(999);
|
mHookIntentFilter.setPriority(999);
|
||||||
mHookReceiver = new HookReceiver();
|
mHookReceiver = new HookReceiver();
|
||||||
mServiceContext.registerReceiver(mHookReceiver, mHookIntentFilter);
|
mContext.registerReceiver(mHookReceiver, mHookIntentFilter);
|
||||||
|
|
||||||
resetCameraFromPreferences();
|
resetCameraFromPreferences();
|
||||||
|
|
||||||
|
@ -603,8 +602,7 @@ public class LinphoneManager implements SensorEventListener {
|
||||||
|
|
||||||
long future =
|
long future =
|
||||||
new Timestamp(
|
new Timestamp(
|
||||||
mServiceContext
|
mContext.getResources()
|
||||||
.getResources()
|
|
||||||
.getInteger(
|
.getInteger(
|
||||||
R.integer.phone_number_linking_popup_time_interval))
|
R.integer.phone_number_linking_popup_time_interval))
|
||||||
.getTime();
|
.getTime();
|
||||||
|
@ -614,7 +612,7 @@ public class LinphoneManager implements SensorEventListener {
|
||||||
|
|
||||||
final Dialog dialog =
|
final Dialog dialog =
|
||||||
LinphoneUtils.getDialog(
|
LinphoneUtils.getDialog(
|
||||||
mServiceContext,
|
mContext,
|
||||||
String.format(
|
String.format(
|
||||||
getString(R.string.link_account_popup),
|
getString(R.string.link_account_popup),
|
||||||
mCore.getDefaultProxyConfig()
|
mCore.getDefaultProxyConfig()
|
||||||
|
@ -644,9 +642,8 @@ public class LinphoneManager implements SensorEventListener {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View view) {
|
public void onClick(View view) {
|
||||||
Intent assistant = new Intent();
|
Intent assistant = new Intent();
|
||||||
assistant.setClass(
|
assistant.setClass(mContext, PhoneAccountLinkingAssistantActivity.class);
|
||||||
mServiceContext, PhoneAccountLinkingAssistantActivity.class);
|
mContext.startActivity(assistant);
|
||||||
mServiceContext.startActivity(assistant);
|
|
||||||
dialog.dismiss();
|
dialog.dismiss();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -684,8 +681,8 @@ public class LinphoneManager implements SensorEventListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void copyFromPackage(int ressourceId, String target) throws IOException {
|
private void copyFromPackage(int ressourceId, String target) throws IOException {
|
||||||
FileOutputStream lOutputStream = mServiceContext.openFileOutput(target, 0);
|
FileOutputStream lOutputStream = mContext.openFileOutput(target, 0);
|
||||||
InputStream lInputStream = mServiceContext.getResources().openRawResource(ressourceId);
|
InputStream lInputStream = mContext.getResources().openRawResource(ressourceId);
|
||||||
int readByte;
|
int readByte;
|
||||||
byte[] buff = new byte[8048];
|
byte[] buff = new byte[8048];
|
||||||
while ((readByte = lInputStream.read(buff)) != -1) {
|
while ((readByte = lInputStream.read(buff)) != -1) {
|
||||||
|
@ -855,9 +852,7 @@ public class LinphoneManager implements SensorEventListener {
|
||||||
int lastTimestamp = LinphonePreferences.instance().getLastCheckReleaseTimestamp();
|
int lastTimestamp = LinphonePreferences.instance().getLastCheckReleaseTimestamp();
|
||||||
int currentTimeStamp = (int) System.currentTimeMillis();
|
int currentTimeStamp = (int) System.currentTimeMillis();
|
||||||
int interval =
|
int interval =
|
||||||
mServiceContext
|
mContext.getResources().getInteger(R.integer.time_between_update_check); // 24h
|
||||||
.getResources()
|
|
||||||
.getInteger(R.integer.time_between_update_check); // 24h
|
|
||||||
if (lastTimestamp == 0 || currentTimeStamp - lastTimestamp >= interval) {
|
if (lastTimestamp == 0 || currentTimeStamp - lastTimestamp >= interval) {
|
||||||
mCore.checkForUpdate(BuildConfig.VERSION_NAME);
|
mCore.checkForUpdate(BuildConfig.VERSION_NAME);
|
||||||
LinphonePreferences.instance().setLastCheckReleaseTimestamp(currentTimeStamp);
|
LinphonePreferences.instance().setLastCheckReleaseTimestamp(currentTimeStamp);
|
||||||
|
@ -894,7 +889,7 @@ public class LinphoneManager implements SensorEventListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getString(int key) {
|
private String getString(int key) {
|
||||||
return mServiceContext.getString(key);
|
return mContext.getString(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasLastCallSasBeenRejected() {
|
public boolean hasLastCallSasBeenRejected() {
|
||||||
|
|
|
@ -32,18 +32,16 @@ import android.provider.ContactsContract;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import org.linphone.call.CallIncomingActivity;
|
import org.linphone.call.CallIncomingActivity;
|
||||||
import org.linphone.call.CallOutgoingActivity;
|
import org.linphone.call.CallOutgoingActivity;
|
||||||
|
import org.linphone.compatibility.Compatibility;
|
||||||
import org.linphone.contacts.ContactsManager;
|
import org.linphone.contacts.ContactsManager;
|
||||||
import org.linphone.core.Call;
|
import org.linphone.core.Call;
|
||||||
import org.linphone.core.Call.State;
|
import org.linphone.core.Call.State;
|
||||||
import org.linphone.core.Core;
|
import org.linphone.core.Core;
|
||||||
import org.linphone.core.CoreListenerStub;
|
import org.linphone.core.CoreListenerStub;
|
||||||
import org.linphone.core.Factory;
|
import org.linphone.core.Factory;
|
||||||
import org.linphone.core.GlobalState;
|
|
||||||
import org.linphone.core.LogLevel;
|
import org.linphone.core.LogLevel;
|
||||||
import org.linphone.core.LoggingService;
|
import org.linphone.core.LoggingService;
|
||||||
import org.linphone.core.LoggingServiceListener;
|
import org.linphone.core.LoggingServiceListener;
|
||||||
import org.linphone.core.ProxyConfig;
|
|
||||||
import org.linphone.core.RegistrationState;
|
|
||||||
import org.linphone.core.tools.Log;
|
import org.linphone.core.tools.Log;
|
||||||
import org.linphone.mediastream.Version;
|
import org.linphone.mediastream.Version;
|
||||||
import org.linphone.notifications.NotificationsManager;
|
import org.linphone.notifications.NotificationsManager;
|
||||||
|
@ -173,14 +171,6 @@ public final class LinphoneService extends Service {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onGlobalStateChanged(
|
|
||||||
Core core, GlobalState state, String message) {}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onRegistrationStateChanged(
|
|
||||||
Core core, ProxyConfig cfg, RegistrationState state, String smessage) {}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -222,6 +212,8 @@ public final class LinphoneService extends Service {
|
||||||
|
|
||||||
mBluetoothManager = new BluetoothManager();
|
mBluetoothManager = new BluetoothManager();
|
||||||
|
|
||||||
|
Compatibility.createChatShortcuts(this);
|
||||||
|
|
||||||
return START_STICKY;
|
return START_STICKY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,7 @@ import org.linphone.LinphoneService;
|
||||||
import org.linphone.R;
|
import org.linphone.R;
|
||||||
import org.linphone.assistant.MenuAssistantActivity;
|
import org.linphone.assistant.MenuAssistantActivity;
|
||||||
import org.linphone.chat.ChatActivity;
|
import org.linphone.chat.ChatActivity;
|
||||||
|
import org.linphone.history.HistoryActivity;
|
||||||
import org.linphone.settings.LinphonePreferences;
|
import org.linphone.settings.LinphonePreferences;
|
||||||
|
|
||||||
/** Creates LinphoneService and wait until Core is ready to start main Activity */
|
/** Creates LinphoneService and wait until Core is ready to start main Activity */
|
||||||
|
@ -66,9 +67,15 @@ public class LinphoneLauncherActivity extends Activity {
|
||||||
if (useFirstLoginActivity && LinphonePreferences.instance().isFirstLaunch()) {
|
if (useFirstLoginActivity && LinphonePreferences.instance().isFirstLaunch()) {
|
||||||
classToStart = MenuAssistantActivity.class;
|
classToStart = MenuAssistantActivity.class;
|
||||||
} else {
|
} else {
|
||||||
if (getIntent().getExtras() != null
|
if (getIntent().getExtras() != null) {
|
||||||
&& "Chat".equals(getIntent().getExtras().getString("Activity", null))) {
|
String activity = getIntent().getExtras().getString("Activity", null);
|
||||||
classToStart = ChatActivity.class;
|
if (ChatActivity.NAME.equals(activity)) {
|
||||||
|
classToStart = ChatActivity.class;
|
||||||
|
} else if (HistoryActivity.NAME.equals(activity)) {
|
||||||
|
classToStart = HistoryActivity.class;
|
||||||
|
} else {
|
||||||
|
classToStart = DialerActivity.class;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
classToStart = DialerActivity.class;
|
classToStart = DialerActivity.class;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,11 +35,13 @@ import org.linphone.core.tools.Log;
|
||||||
import org.linphone.utils.FileUtils;
|
import org.linphone.utils.FileUtils;
|
||||||
|
|
||||||
public class ChatActivity extends MainActivity {
|
public class ChatActivity extends MainActivity {
|
||||||
|
public static final String NAME = "Chat";
|
||||||
|
|
||||||
private String mSharedText, mSharedFiles;
|
private String mSharedText, mSharedFiles;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
getIntent().putExtra("Activity", "Chat");
|
getIntent().putExtra("Activity", NAME);
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,7 +2,7 @@ package org.linphone.compatibility;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ApiTwentyEightPlus.java
|
ApiTwentyEightPlus.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
|
||||||
modify it under the terms of the GNU General Public License
|
modify it under the terms of the GNU General Public License
|
||||||
|
|
|
@ -0,0 +1,100 @@
|
||||||
|
package org.linphone.compatibility;
|
||||||
|
|
||||||
|
/*
|
||||||
|
ApiTwentyFivePlus.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 java.lang.Math.min;
|
||||||
|
|
||||||
|
import android.annotation.TargetApi;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.pm.ShortcutInfo;
|
||||||
|
import android.content.pm.ShortcutManager;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import org.linphone.LinphoneManager;
|
||||||
|
import org.linphone.R;
|
||||||
|
import org.linphone.core.ChatRoom;
|
||||||
|
import org.linphone.core.ChatRoomCapabilities;
|
||||||
|
import org.linphone.utils.LinphoneShortcutManager;
|
||||||
|
|
||||||
|
@TargetApi(25)
|
||||||
|
class ApiTwentyFivePlus {
|
||||||
|
|
||||||
|
public static void createChatShortcuts(Context context) {
|
||||||
|
if (!context.getResources().getBoolean(R.bool.create_most_recent_chat_rooms_shortcuts))
|
||||||
|
return;
|
||||||
|
|
||||||
|
ShortcutManager shortcutManager =
|
||||||
|
(ShortcutManager) context.getSystemService(Context.SHORTCUT_SERVICE);
|
||||||
|
ArrayList<ShortcutInfo> shortcuts = new ArrayList<>();
|
||||||
|
|
||||||
|
ChatRoom[] rooms = LinphoneManager.getCore().getChatRooms();
|
||||||
|
ArrayList<ChatRoom> notEmptyOneToOneRooms = new ArrayList<>();
|
||||||
|
for (ChatRoom room : rooms) {
|
||||||
|
if (room.hasCapability(ChatRoomCapabilities.OneToOne.toInt())
|
||||||
|
&& room.getHistorySize() > 0) {
|
||||||
|
notEmptyOneToOneRooms.add(room);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Collections.sort(
|
||||||
|
notEmptyOneToOneRooms,
|
||||||
|
new Comparator<ChatRoom>() {
|
||||||
|
public int compare(ChatRoom cr1, ChatRoom cr2) {
|
||||||
|
long timeDiff = cr1.getLastUpdateTime() - cr2.getLastUpdateTime();
|
||||||
|
if (timeDiff > 0) return -1;
|
||||||
|
else if (timeDiff == 0) return 0;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
LinphoneShortcutManager manager = new LinphoneShortcutManager(context);
|
||||||
|
int maxShortcuts =
|
||||||
|
min(notEmptyOneToOneRooms.size(), shortcutManager.getMaxShortcutCountPerActivity());
|
||||||
|
for (int i = 0; i < maxShortcuts; i++) {
|
||||||
|
// Android can only have around 4-5 shortcuts at a time
|
||||||
|
ChatRoom room = notEmptyOneToOneRooms.get(i);
|
||||||
|
ShortcutInfo shortcut = manager.createChatRoomShortcutInfo(room);
|
||||||
|
if (shortcut != null) {
|
||||||
|
shortcuts.add(shortcut);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
shortcutManager.setDynamicShortcuts(shortcuts);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void updateShortcuts(Context context) {
|
||||||
|
if (!context.getResources().getBoolean(R.bool.create_most_recent_chat_rooms_shortcuts))
|
||||||
|
return;
|
||||||
|
|
||||||
|
ShortcutManager shortcutManager =
|
||||||
|
(ShortcutManager) context.getSystemService(Context.SHORTCUT_SERVICE);
|
||||||
|
ArrayList<ShortcutInfo> shortcuts = new ArrayList<>();
|
||||||
|
LinphoneShortcutManager manager = new LinphoneShortcutManager(context);
|
||||||
|
|
||||||
|
for (ShortcutInfo shortcutInfo : shortcutManager.getDynamicShortcuts()) {
|
||||||
|
ShortcutInfo shortcut = manager.updateShortcutInfo(shortcutInfo);
|
||||||
|
if (shortcut != null) {
|
||||||
|
shortcuts.add(shortcut);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
shortcutManager.updateShortcuts(shortcuts);
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,7 +2,7 @@ package org.linphone.compatibility;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ApiTwentyFourPlus.java
|
ApiTwentyFourPlus.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
|
||||||
modify it under the terms of the GNU General Public License
|
modify it under the terms of the GNU General Public License
|
||||||
|
|
|
@ -2,7 +2,7 @@ package org.linphone.compatibility;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ApiTwentyOnePlus.java
|
ApiTwentyOnePlus.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
|
||||||
modify it under the terms of the GNU General Public License
|
modify it under the terms of the GNU General Public License
|
||||||
|
|
|
@ -2,7 +2,7 @@ package org.linphone.compatibility;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ApiTwentySixPlus.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
|
||||||
modify it under the terms of the GNU General Public License
|
modify it under the terms of the GNU General Public License
|
||||||
|
|
|
@ -2,7 +2,7 @@ package org.linphone.compatibility;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
ApiTwentyThreePlus.java
|
ApiTwentyThreePlus.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
|
||||||
modify it under the terms of the GNU General Public License
|
modify it under the terms of the GNU General Public License
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
package org.linphone.compatibility;
|
package org.linphone.compatibility;
|
||||||
/*
|
/*
|
||||||
Compatibility.java
|
Compatibility.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
|
||||||
modify it under the terms of the GNU General Public License
|
modify it under the terms of the GNU General Public License
|
||||||
|
@ -244,4 +244,16 @@ public class Compatibility {
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void createChatShortcuts(Context context) {
|
||||||
|
if (Version.sdkAboveOrEqual(Version.API25_NOUGAT_71)) {
|
||||||
|
ApiTwentyFivePlus.createChatShortcuts(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void updateShortcuts(Context context) {
|
||||||
|
if (Version.sdkAboveOrEqual(Version.API25_NOUGAT_71)) {
|
||||||
|
ApiTwentyFivePlus.updateShortcuts(context);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ package org.linphone.compatibility;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
CompatibilityScaleGestureDetector.java
|
CompatibilityScaleGestureDetector.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
|
||||||
modify it under the terms of the GNU General Public License
|
modify it under the terms of the GNU General Public License
|
||||||
|
|
|
@ -2,7 +2,7 @@ package org.linphone.compatibility;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
CompatibilityScaleGestureListener.java
|
CompatibilityScaleGestureListener.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
|
||||||
modify it under the terms of the GNU General Public License
|
modify it under the terms of the GNU General Public License
|
||||||
|
|
|
@ -475,5 +475,7 @@ public class ContactsManager extends ContentObserver implements FriendListListen
|
||||||
for (ContactsUpdatedListener listener : mContactsUpdatedListeners) {
|
for (ContactsUpdatedListener listener : mContactsUpdatedListeners) {
|
||||||
listener.onContactsUpdated();
|
listener.onContactsUpdated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Compatibility.updateShortcuts(mContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,8 +32,11 @@ import org.linphone.core.Address;
|
||||||
import org.linphone.utils.LinphoneUtils;
|
import org.linphone.utils.LinphoneUtils;
|
||||||
|
|
||||||
public class HistoryActivity extends MainActivity {
|
public class HistoryActivity extends MainActivity {
|
||||||
|
public static final String NAME = "History";
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState) {
|
protected void onCreate(Bundle savedInstanceState) {
|
||||||
|
getIntent().putExtra("Activity", NAME);
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -118,6 +118,12 @@ public class NotificationsManager {
|
||||||
|
|
||||||
mListener =
|
mListener =
|
||||||
new CoreListenerStub() {
|
new CoreListenerStub() {
|
||||||
|
@Override
|
||||||
|
public void onMessageSent(Core core, ChatRoom room, ChatMessage message) {
|
||||||
|
if (room.hasCapability(ChatRoomCapabilities.OneToOne.toInt())) {
|
||||||
|
Compatibility.createChatShortcuts(mContext);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onMessageReceived(
|
public void onMessageReceived(
|
||||||
|
@ -191,6 +197,10 @@ public class NotificationsManager {
|
||||||
createNotification(
|
createNotification(
|
||||||
cr, contact, from, textMessage, message.getTime(), null, null);
|
cr, contact, from, textMessage, message.getTime(), null, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cr.hasCapability(ChatRoomCapabilities.OneToOne.toInt())) {
|
||||||
|
Compatibility.createChatShortcuts(mContext);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,131 @@
|
||||||
|
package org.linphone.utils;
|
||||||
|
|
||||||
|
/*
|
||||||
|
LinphoneShortcutManager.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 android.annotation.TargetApi;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.pm.ShortcutInfo;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.graphics.drawable.Icon;
|
||||||
|
import android.util.ArraySet;
|
||||||
|
import java.util.Set;
|
||||||
|
import org.linphone.LinphoneService;
|
||||||
|
import org.linphone.R;
|
||||||
|
import org.linphone.chat.ChatActivity;
|
||||||
|
import org.linphone.contacts.ContactsManager;
|
||||||
|
import org.linphone.contacts.LinphoneContact;
|
||||||
|
import org.linphone.core.Address;
|
||||||
|
import org.linphone.core.ChatRoom;
|
||||||
|
import org.linphone.core.ChatRoomCapabilities;
|
||||||
|
import org.linphone.core.Factory;
|
||||||
|
import org.linphone.core.tools.Log;
|
||||||
|
|
||||||
|
@TargetApi(25)
|
||||||
|
public class LinphoneShortcutManager {
|
||||||
|
private Context mContext;
|
||||||
|
private Set<String> mCategories;
|
||||||
|
|
||||||
|
public LinphoneShortcutManager(Context context) {
|
||||||
|
mContext = context;
|
||||||
|
mCategories = new ArraySet<>();
|
||||||
|
mCategories.add(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ShortcutInfo createChatRoomShortcutInfo(ChatRoom room) {
|
||||||
|
Address peerAddress =
|
||||||
|
room.hasCapability(ChatRoomCapabilities.Basic.toInt())
|
||||||
|
? room.getPeerAddress()
|
||||||
|
: room.getParticipants()[0].getAddress();
|
||||||
|
LinphoneContact contact = ContactsManager.getInstance().findContactFromAddress(peerAddress);
|
||||||
|
String address = peerAddress.asStringUriOnly();
|
||||||
|
|
||||||
|
Bitmap bm = null;
|
||||||
|
if (contact != null && contact.getThumbnailUri() != null) {
|
||||||
|
bm =
|
||||||
|
ImageUtils.getRoundBitmapFromUri(
|
||||||
|
LinphoneService.instance(), contact.getThumbnailUri());
|
||||||
|
}
|
||||||
|
Icon icon =
|
||||||
|
bm == null
|
||||||
|
? Icon.createWithResource(mContext, R.drawable.avatar)
|
||||||
|
: Icon.createWithBitmap(bm);
|
||||||
|
|
||||||
|
String name =
|
||||||
|
contact == null
|
||||||
|
? LinphoneUtils.getAddressDisplayName(peerAddress)
|
||||||
|
: contact.getFullName();
|
||||||
|
|
||||||
|
try {
|
||||||
|
Intent intent = new Intent(Intent.ACTION_MAIN);
|
||||||
|
intent.setClass(mContext, ChatActivity.class);
|
||||||
|
intent.addFlags(
|
||||||
|
Intent.FLAG_ACTIVITY_NO_ANIMATION | Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
|
||||||
|
intent.putExtra("RemoteSipUri", room.getPeerAddress().asStringUriOnly());
|
||||||
|
|
||||||
|
return new ShortcutInfo.Builder(mContext, address)
|
||||||
|
.setShortLabel(name)
|
||||||
|
.setIcon(icon)
|
||||||
|
.setCategories(mCategories)
|
||||||
|
.setIntent(intent)
|
||||||
|
.build();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e("[Shortcuts Manager] ShortcutInfo.Builder exception: " + e);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ShortcutInfo updateShortcutInfo(ShortcutInfo shortcutInfo) {
|
||||||
|
String address = shortcutInfo.getId();
|
||||||
|
Address peerAddress = Factory.instance().createAddress(address);
|
||||||
|
LinphoneContact contact = ContactsManager.getInstance().findContactFromAddress(peerAddress);
|
||||||
|
|
||||||
|
if (contact != null) {
|
||||||
|
Bitmap bm = null;
|
||||||
|
if (contact != null && contact.getThumbnailUri() != null) {
|
||||||
|
bm =
|
||||||
|
ImageUtils.getRoundBitmapFromUri(
|
||||||
|
LinphoneService.instance(), contact.getThumbnailUri());
|
||||||
|
}
|
||||||
|
Icon icon =
|
||||||
|
bm == null
|
||||||
|
? Icon.createWithResource(mContext, R.drawable.avatar)
|
||||||
|
: Icon.createWithBitmap(bm);
|
||||||
|
|
||||||
|
String name =
|
||||||
|
contact == null
|
||||||
|
? LinphoneUtils.getAddressDisplayName(peerAddress)
|
||||||
|
: contact.getFullName();
|
||||||
|
|
||||||
|
try {
|
||||||
|
return new ShortcutInfo.Builder(mContext, address)
|
||||||
|
.setShortLabel(name)
|
||||||
|
.setIcon(icon)
|
||||||
|
.setCategories(mCategories)
|
||||||
|
.setIntent(shortcutInfo.getIntent())
|
||||||
|
.build();
|
||||||
|
} catch (Exception e) {
|
||||||
|
Log.e("[Shortcuts Manager] ShortcutInfo.Builder exception: " + e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return shortcutInfo;
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
Before Width: | Height: | Size: 27 KiB After Width: | Height: | Size: 26 KiB |
|
@ -96,6 +96,7 @@
|
||||||
<bool name="use_big_pictures_to_preview_images_file_transfers">true</bool>
|
<bool name="use_big_pictures_to_preview_images_file_transfers">true</bool>
|
||||||
<bool name="show_sip_uri_in_chat">false</bool>
|
<bool name="show_sip_uri_in_chat">false</bool>
|
||||||
<bool name="hide_empty_one_to_one_chat_rooms">true</bool>
|
<bool name="hide_empty_one_to_one_chat_rooms">true</bool>
|
||||||
|
<bool name="create_most_recent_chat_rooms_shortcuts">true</bool>
|
||||||
|
|
||||||
<!-- Contacts -->
|
<!-- Contacts -->
|
||||||
<bool name="hide_contact_phone_numbers">false</bool>
|
<bool name="hide_contact_phone_numbers">false</bool>
|
||||||
|
|
Loading…
Reference in a new issue