Merge branch 'master' of git.linphone.org:linphone-android
This commit is contained in:
commit
b9b8e5e419
47 changed files with 360 additions and 1576 deletions
|
@ -207,8 +207,8 @@
|
||||||
<intent-filter><action android:name="android.intent.action.PHONE_STATE" /></intent-filter>
|
<intent-filter><action android:name="android.intent.action.PHONE_STATE" /></intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
<receiver android:name="KeepAliveHandler" >
|
<!-- This one needs to be registered from application -->
|
||||||
</receiver>
|
<receiver android:name="KeepAliveReceiver"/>
|
||||||
|
|
||||||
<!-- Needed for push notification -->
|
<!-- Needed for push notification -->
|
||||||
<receiver android:name="org.linphone.gcm.GCMReceiver" android:permission="com.google.android.c2dm.permission.SEND" >
|
<receiver android:name="org.linphone.gcm.GCMReceiver" android:permission="com.google.android.c2dm.permission.SEND" >
|
||||||
|
|
15
README
15
README
|
@ -7,8 +7,8 @@ COMPILATION INSTRUCTIONS
|
||||||
|
|
||||||
To build liblinphone for Android, you must:
|
To build liblinphone for Android, you must:
|
||||||
-------------------------------------------
|
-------------------------------------------
|
||||||
0) download the Android sdk with platform-tools and tools updated to latest revision (at least API 16 is needed), then add both 'tools' and 'platform-tools' folders in your path.
|
0) download the Android sdk (API 23 at least) with platform-tools and tools updated to latest revision, then add both 'tools' and 'platform-tools' folders in your path.
|
||||||
1) download the Android ndk (version r11) from google and add it to your path (no symlink !!!).
|
1) download the Android ndk (version r11c or 12b) from google and add it to your path (no symlink !!!).
|
||||||
2) install yasm, nasm, ant, python, cmake and vim-common
|
2) install yasm, nasm, ant, python, cmake and vim-common
|
||||||
On 64 bits linux systems you'll need the ia32-libs package
|
On 64 bits linux systems you'll need the ia32-libs package
|
||||||
With the latest Debian (multiarch), you need this:
|
With the latest Debian (multiarch), you need this:
|
||||||
|
@ -27,11 +27,12 @@ To build liblinphone for Android, you must:
|
||||||
$ make mediastreamer2-sdk
|
$ make mediastreamer2-sdk
|
||||||
8) (Optional) To generate a signed apk to publish on the Google Play, run
|
8) (Optional) To generate a signed apk to publish on the Google Play, run
|
||||||
$ make release
|
$ make release
|
||||||
Make sure you filled the ant.properties values for version.name, key.store and key.alias in order to correctly sign the generated apk.
|
Make sure you filled the ant.properties values for version.name, key.store and key.alias in order to correctly sign the generated apk.
|
||||||
You also may want to create a file name ant_password.properties with the following:
|
You also may want to create a file name ant_password.properties with the following:
|
||||||
key.store.password=[your_password]
|
key.store.password=[your_password]
|
||||||
key.alias.password=[your_password]
|
key.alias.password=[your_password]
|
||||||
If you don't, the passwords will be asked at the signing phase.
|
If you don't, the passwords will be asked at the signing phase.
|
||||||
|
9) (Optional) Once you compiled the libraries succesfully with 'make', you can reduce the compilation time using 'make quick': it will only generate a new APK from java files.
|
||||||
|
|
||||||
To run the tutorials:
|
To run the tutorials:
|
||||||
--------------------
|
--------------------
|
||||||
|
|
|
@ -48,7 +48,7 @@
|
||||||
</condition>
|
</condition>
|
||||||
<exec executable="bash" unless:set="has.crashed">
|
<exec executable="bash" unless:set="has.crashed">
|
||||||
<arg value="-c"/>
|
<arg value="-c"/>
|
||||||
<arg value="adb shell run-as org.linphone.tester cat /data/data/org.linphone.tester/files/junit-report.xml > liblinphone-junit-report.xml"/>
|
<arg value="adb shell cat /data/data/org.linphone.tester/files/junit-report.xml > liblinphone-junit-report.xml"/>
|
||||||
</exec>
|
</exec>
|
||||||
|
|
||||||
<zip destfile="${archive.name}.zip">
|
<zip destfile="${archive.name}.zip">
|
||||||
|
|
|
@ -136,6 +136,7 @@
|
||||||
android:inputType="textPersonName|textCapWords"/>
|
android:inputType="textPersonName|textCapWords"/>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
|
android:id="@+id/contactOrganizationTitle"
|
||||||
android:text="@string/contact_organization"
|
android:text="@string/contact_organization"
|
||||||
style="@style/font13"
|
style="@style/font13"
|
||||||
android:textAllCaps="true"
|
android:textAllCaps="true"
|
||||||
|
|
|
@ -68,6 +68,8 @@
|
||||||
<bool name="allow_only_one_phone_number">false</bool>
|
<bool name="allow_only_one_phone_number">false</bool>
|
||||||
<bool name="allow_only_one_sip_address">false</bool>
|
<bool name="allow_only_one_sip_address">false</bool>
|
||||||
|
|
||||||
|
<bool name="display_contact_organization">true</bool>
|
||||||
|
|
||||||
<bool name="setup_cancel_move_to_back">false</bool>
|
<bool name="setup_cancel_move_to_back">false</bool>
|
||||||
|
|
||||||
<bool name="enable_call_notification">true</bool>
|
<bool name="enable_call_notification">true</bool>
|
||||||
|
|
|
@ -205,4 +205,5 @@
|
||||||
<string name="pref_use_lime_encryption_key">pref_use_lime_encryption_key</string>
|
<string name="pref_use_lime_encryption_key">pref_use_lime_encryption_key</string>
|
||||||
<string name="pref_device_ringtone_key">pref_device_ringtone_key</string>
|
<string name="pref_device_ringtone_key">pref_device_ringtone_key</string>
|
||||||
<string name="pref_auto_answer_key">pref_auto_answer_key</string>
|
<string name="pref_auto_answer_key">pref_auto_answer_key</string>
|
||||||
|
<string name="pref_android_app_settings_key">pref_android_app_settings_key</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
|
|
@ -313,6 +313,7 @@
|
||||||
<string name="pref_autostart">Start at boot time</string>
|
<string name="pref_autostart">Start at boot time</string>
|
||||||
<string name="pref_incoming_call_timeout_title">Incoming call hangup (in seconds)</string>
|
<string name="pref_incoming_call_timeout_title">Incoming call hangup (in seconds)</string>
|
||||||
<string name="pref_remote_provisioning_title">Remote provisioning</string>
|
<string name="pref_remote_provisioning_title">Remote provisioning</string>
|
||||||
|
<string name="pref_android_app_settings_title">Android app settings</string>
|
||||||
<string name="pref_primary_account_title">Primary account</string>
|
<string name="pref_primary_account_title">Primary account</string>
|
||||||
<string name="pref_display_name_title">Display name</string>
|
<string name="pref_display_name_title">Display name</string>
|
||||||
<string name="pref_user_name_title">Username</string>
|
<string name="pref_user_name_title">Username</string>
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
<ContactsSource
|
<ContactsSource
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
<!-- Change package ! -->
|
<!-- Change package, leave vnd.android.cursor.item/ before and .profile at the end. -->
|
||||||
<ContactsDataKind
|
<ContactsDataKind
|
||||||
android:mimeType="vnd.android.cursor.item/org.linphone.profile"
|
android:mimeType="vnd.android.cursor.item/org.linphone.profile"
|
||||||
android:icon="@drawable/linphone_logo"
|
android:icon="@drawable/linphone_logo"
|
||||||
|
|
|
@ -350,6 +350,11 @@
|
||||||
android:key="@string/pref_remote_provisioning_key"
|
android:key="@string/pref_remote_provisioning_key"
|
||||||
android:inputType="textUri"
|
android:inputType="textUri"
|
||||||
android:persistent="false"/>
|
android:persistent="false"/>
|
||||||
|
|
||||||
|
<Preference
|
||||||
|
android:title="@string/pref_android_app_settings_title"
|
||||||
|
android:key="@string/pref_android_app_settings_key"
|
||||||
|
android:persistent="false"/>
|
||||||
|
|
||||||
</PreferenceCategory>
|
</PreferenceCategory>
|
||||||
|
|
||||||
|
|
|
@ -69,11 +69,11 @@ public class AboutFragment extends Fragment implements OnClickListener {
|
||||||
|
|
||||||
sendLogButton = view.findViewById(R.id.send_log);
|
sendLogButton = view.findViewById(R.id.send_log);
|
||||||
sendLogButton.setOnClickListener(this);
|
sendLogButton.setOnClickListener(this);
|
||||||
sendLogButton.setVisibility(org.linphone.LinphonePreferences.instance().isDebugEnabled() ? View.VISIBLE : View.GONE);
|
sendLogButton.setVisibility(LinphonePreferences.instance().isDebugEnabled() ? View.VISIBLE : View.GONE);
|
||||||
|
|
||||||
resetLogButton = view.findViewById(R.id.reset_log);
|
resetLogButton = view.findViewById(R.id.reset_log);
|
||||||
resetLogButton.setOnClickListener(this);
|
resetLogButton.setOnClickListener(this);
|
||||||
resetLogButton.setVisibility(org.linphone.LinphonePreferences.instance().isDebugEnabled() ? View.VISIBLE : View.GONE);
|
resetLogButton.setVisibility(LinphonePreferences.instance().isDebugEnabled() ? View.VISIBLE : View.GONE);
|
||||||
|
|
||||||
mListener = new LinphoneCoreListenerBase() {
|
mListener = new LinphoneCoreListenerBase() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -145,7 +145,7 @@ public class AboutFragment extends Fragment implements OnClickListener {
|
||||||
lc.addListener(mListener);
|
lc.addListener(mListener);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (org.linphone.LinphoneActivity.isInstanciated()) {
|
if (LinphoneActivity.isInstanciated()) {
|
||||||
LinphoneActivity.instance().selectMenu(FragmentsAvailable.ABOUT);
|
LinphoneActivity.instance().selectMenu(FragmentsAvailable.ABOUT);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -154,8 +154,8 @@ public class AboutFragment extends Fragment implements OnClickListener {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
if (org.linphone.LinphoneActivity.isInstanciated()) {
|
if (LinphoneActivity.isInstanciated()) {
|
||||||
LinphoneCore lc = org.linphone.LinphoneManager.getLcIfManagerNotDestroyedOrNull();
|
LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
|
||||||
if (v == sendLogButton) {
|
if (v == sendLogButton) {
|
||||||
if (lc != null) {
|
if (lc != null) {
|
||||||
lc.uploadLogCollection();
|
lc.uploadLogCollection();
|
||||||
|
@ -174,6 +174,4 @@ public class AboutFragment extends Fragment implements OnClickListener {
|
||||||
public void onDestroy() {
|
public void onDestroy() {
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,8 +53,7 @@ public class AccountPreferencesFragment extends PreferencesListFragment {
|
||||||
mPrefs = LinphonePreferences.instance();
|
mPrefs = LinphonePreferences.instance();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void onCreate(Bundle savedInstanceState)
|
public void onCreate(Bundle savedInstanceState) {
|
||||||
{
|
|
||||||
super.onCreate(savedInstanceState);
|
super.onCreate(savedInstanceState);
|
||||||
|
|
||||||
PreferenceScreen screen = getPreferenceScreen();
|
PreferenceScreen screen = getPreferenceScreen();
|
||||||
|
@ -69,7 +68,7 @@ public class AccountPreferencesFragment extends PreferencesListFragment {
|
||||||
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
|
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean isEditTextEmpty(String s){
|
public static boolean isEditTextEmpty(String s) {
|
||||||
return s.equals(""); // really empty.
|
return s.equals(""); // really empty.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.linphone.compatibility.Compatibility;
|
|
||||||
import org.linphone.mediastream.Log;
|
import org.linphone.mediastream.Log;
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
|
@ -68,31 +67,31 @@ public class BluetoothManager extends BroadcastReceiver {
|
||||||
public BluetoothManager() {
|
public BluetoothManager() {
|
||||||
isBluetoothConnected = false;
|
isBluetoothConnected = false;
|
||||||
if (!ensureInit()) {
|
if (!ensureInit()) {
|
||||||
Log.w("BluetoothManager tried to init but LinphoneService not ready yet...");
|
Log.w("[Bluetooth] Manager tried to init but LinphoneService not ready yet...");
|
||||||
}
|
}
|
||||||
instance = this;
|
instance = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void initBluetooth() {
|
public void initBluetooth() {
|
||||||
if (!ensureInit()) {
|
if (!ensureInit()) {
|
||||||
Log.w("BluetoothManager tried to init bluetooth but LinphoneService not ready yet...");
|
Log.w("[Bluetooth] Manager tried to init bluetooth but LinphoneService not ready yet...");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
IntentFilter filter = new IntentFilter();
|
IntentFilter filter = new IntentFilter();
|
||||||
filter.addCategory(BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID_CATEGORY + "." + BluetoothAssignedNumbers.PLANTRONICS);
|
filter.addCategory(BluetoothHeadset.VENDOR_SPECIFIC_HEADSET_EVENT_COMPANY_ID_CATEGORY + "." + BluetoothAssignedNumbers.PLANTRONICS);
|
||||||
filter.addAction(Compatibility.getAudioManagerEventForBluetoothConnectionStateChangedEvent());
|
filter.addAction(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED);
|
||||||
filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
|
filter.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED);
|
||||||
filter.addAction(BluetoothHeadset.ACTION_VENDOR_SPECIFIC_HEADSET_EVENT);
|
filter.addAction(BluetoothHeadset.ACTION_VENDOR_SPECIFIC_HEADSET_EVENT);
|
||||||
mContext.registerReceiver(this, filter);
|
mContext.registerReceiver(this, filter);
|
||||||
Log.d("Bluetooth receiver started");
|
Log.d("[Bluetooth] Receiver started");
|
||||||
|
|
||||||
startBluetooth();
|
startBluetooth();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void startBluetooth() {
|
private void startBluetooth() {
|
||||||
if (isBluetoothConnected) {
|
if (isBluetoothConnected) {
|
||||||
Log.e("Bluetooth already started");
|
Log.e("[Bluetooth] Already started, skipping...");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,14 +99,14 @@ public class BluetoothManager extends BroadcastReceiver {
|
||||||
|
|
||||||
if (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled()) {
|
if (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled()) {
|
||||||
if (mProfileListener != null) {
|
if (mProfileListener != null) {
|
||||||
Log.w("Bluetooth headset profile was already opened, let's close it");
|
Log.w("[Bluetooth] Headset profile was already opened, let's close it");
|
||||||
mBluetoothAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset);
|
mBluetoothAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mBluetoothHeadset);
|
||||||
}
|
}
|
||||||
|
|
||||||
mProfileListener = new BluetoothProfile.ServiceListener() {
|
mProfileListener = new BluetoothProfile.ServiceListener() {
|
||||||
public void onServiceConnected(int profile, BluetoothProfile proxy) {
|
public void onServiceConnected(int profile, BluetoothProfile proxy) {
|
||||||
if (profile == BluetoothProfile.HEADSET) {
|
if (profile == BluetoothProfile.HEADSET) {
|
||||||
Log.d("Bluetooth headset connected");
|
Log.d("[Bluetooth] Headset connected");
|
||||||
mBluetoothHeadset = (BluetoothHeadset) proxy;
|
mBluetoothHeadset = (BluetoothHeadset) proxy;
|
||||||
isBluetoothConnected = true;
|
isBluetoothConnected = true;
|
||||||
}
|
}
|
||||||
|
@ -116,17 +115,17 @@ public class BluetoothManager extends BroadcastReceiver {
|
||||||
if (profile == BluetoothProfile.HEADSET) {
|
if (profile == BluetoothProfile.HEADSET) {
|
||||||
mBluetoothHeadset = null;
|
mBluetoothHeadset = null;
|
||||||
isBluetoothConnected = false;
|
isBluetoothConnected = false;
|
||||||
Log.d("Bluetooth headset disconnected");
|
Log.d("[Bluetooth] Headset disconnected");
|
||||||
LinphoneManager.getInstance().routeAudioToReceiver();
|
LinphoneManager.getInstance().routeAudioToReceiver();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
boolean success = mBluetoothAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.HEADSET);
|
boolean success = mBluetoothAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.HEADSET);
|
||||||
if (!success) {
|
if (!success) {
|
||||||
Log.e("Bluetooth getProfileProxy failed !");
|
Log.e("[Bluetooth] getProfileProxy failed !");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.w("Bluetooth interface disabled on device");
|
Log.w("[Bluetooth] Interface disabled on device");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -153,7 +152,7 @@ public class BluetoothManager extends BroadcastReceiver {
|
||||||
if (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled() && mAudioManager != null && mAudioManager.isBluetoothScoAvailableOffCall()) {
|
if (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled() && mAudioManager != null && mAudioManager.isBluetoothScoAvailableOffCall()) {
|
||||||
if (isBluetoothHeadsetAvailable()) {
|
if (isBluetoothHeadsetAvailable()) {
|
||||||
if (mAudioManager != null && !mAudioManager.isBluetoothScoOn()) {
|
if (mAudioManager != null && !mAudioManager.isBluetoothScoOn()) {
|
||||||
Log.d("Bluetooth sco off, let's start it");
|
Log.d("[Bluetooth] SCO off, let's start it");
|
||||||
mAudioManager.setBluetoothScoOn(true);
|
mAudioManager.setBluetoothScoOn(true);
|
||||||
mAudioManager.startBluetoothSco();
|
mAudioManager.startBluetoothSco();
|
||||||
}
|
}
|
||||||
|
@ -180,12 +179,12 @@ public class BluetoothManager extends BroadcastReceiver {
|
||||||
}
|
}
|
||||||
if (ok) {
|
if (ok) {
|
||||||
if (retries > 0) {
|
if (retries > 0) {
|
||||||
Log.d("Bluetooth route ok after " + retries + " retries");
|
Log.d("[Bluetooth] Audio route ok after " + retries + " retries");
|
||||||
} else {
|
} else {
|
||||||
Log.d("Bluetooth route ok");
|
Log.d("[Bluetooth] Audio route ok");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Log.d("Bluetooth still not ok...");
|
Log.d("[Bluetooth] Audio route still not ok...");
|
||||||
}
|
}
|
||||||
|
|
||||||
return ok;
|
return ok;
|
||||||
|
@ -212,7 +211,7 @@ public class BluetoothManager extends BroadcastReceiver {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Log.d(isHeadsetConnected ? "Headset found, bluetooth audio route available" : "No headset found, bluetooth audio route unavailable");
|
Log.d(isHeadsetConnected ? "[Bluetooth] Headset found, bluetooth audio route available" : "[Bluetooth] No headset found, bluetooth audio route unavailable");
|
||||||
}
|
}
|
||||||
return isHeadsetConnected;
|
return isHeadsetConnected;
|
||||||
}
|
}
|
||||||
|
@ -237,12 +236,12 @@ public class BluetoothManager extends BroadcastReceiver {
|
||||||
mAudioManager.stopBluetoothSco();
|
mAudioManager.stopBluetoothSco();
|
||||||
mAudioManager.setBluetoothScoOn(false);
|
mAudioManager.setBluetoothScoOn(false);
|
||||||
}
|
}
|
||||||
Log.w("Bluetooth sco disconnected!");
|
Log.w("[Bluetooth] SCO disconnected!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stopBluetooth() {
|
public void stopBluetooth() {
|
||||||
Log.w("Stopping bluetooth...");
|
Log.w("[Bluetooth] Stopping...");
|
||||||
isBluetoothConnected = false;
|
isBluetoothConnected = false;
|
||||||
|
|
||||||
disableBluetoothSCO();
|
disableBluetoothSCO();
|
||||||
|
@ -253,7 +252,7 @@ public class BluetoothManager extends BroadcastReceiver {
|
||||||
}
|
}
|
||||||
mBluetoothDevice = null;
|
mBluetoothDevice = null;
|
||||||
|
|
||||||
Log.w("Bluetooth stopped!");
|
Log.w("[Bluetooth] Stopped!");
|
||||||
|
|
||||||
if (LinphoneManager.isInstanciated()) {
|
if (LinphoneManager.isInstanciated()) {
|
||||||
LinphoneManager.getInstance().routeAudioToReceiver();
|
LinphoneManager.getInstance().routeAudioToReceiver();
|
||||||
|
@ -266,7 +265,7 @@ public class BluetoothManager extends BroadcastReceiver {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
mContext.unregisterReceiver(this);
|
mContext.unregisterReceiver(this);
|
||||||
Log.d("Bluetooth receiver stopped");
|
Log.d("[Bluetooth] Receiver stopped");
|
||||||
} catch (Exception e) {}
|
} catch (Exception e) {}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(e);
|
Log.e(e);
|
||||||
|
@ -278,30 +277,30 @@ public class BluetoothManager extends BroadcastReceiver {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
String action = intent.getAction();
|
String action = intent.getAction();
|
||||||
if (Compatibility.getAudioManagerEventForBluetoothConnectionStateChangedEvent().equals(action)) {
|
if (AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED.equals(action)) {
|
||||||
int state = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, 0);
|
int state = intent.getIntExtra(AudioManager.EXTRA_SCO_AUDIO_STATE, 0);
|
||||||
if (state == AudioManager.SCO_AUDIO_STATE_CONNECTED) {
|
if (state == AudioManager.SCO_AUDIO_STATE_CONNECTED) {
|
||||||
Log.d("Bluetooth sco state => connected");
|
Log.d("[Bluetooth] SCO state: connected");
|
||||||
// LinphoneManager.getInstance().audioStateChanged(AudioState.BLUETOOTH);
|
// LinphoneManager.getInstance().audioStateChanged(AudioState.BLUETOOTH);
|
||||||
isScoConnected = true;
|
isScoConnected = true;
|
||||||
} else if (state == AudioManager.SCO_AUDIO_STATE_DISCONNECTED) {
|
} else if (state == AudioManager.SCO_AUDIO_STATE_DISCONNECTED) {
|
||||||
Log.d("Bluetooth sco state => disconnected");
|
Log.d("[Bluetooth] SCO state: disconnected");
|
||||||
// LinphoneManager.getInstance().audioStateChanged(AudioState.SPEAKER);
|
// LinphoneManager.getInstance().audioStateChanged(AudioState.SPEAKER);
|
||||||
isScoConnected = false;
|
isScoConnected = false;
|
||||||
} else {
|
} else {
|
||||||
Log.d("Bluetooth sco state => " + state);
|
Log.d("[Bluetooth] SCO state: " + state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
|
else if (BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
|
||||||
int state = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, BluetoothAdapter.STATE_DISCONNECTED);
|
int state = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, BluetoothAdapter.STATE_DISCONNECTED);
|
||||||
if (state == 0) {
|
if (state == 0) {
|
||||||
Log.d("Bluetooth state => disconnected");
|
Log.d("[Bluetooth] State: disconnected");
|
||||||
stopBluetooth();
|
stopBluetooth();
|
||||||
} else if (state == 2) {
|
} else if (state == 2) {
|
||||||
Log.d("Bluetooth state => connected");
|
Log.d("[Bluetooth] State: connected");
|
||||||
startBluetooth();
|
startBluetooth();
|
||||||
} else {
|
} else {
|
||||||
Log.d("Bluetooth state => " + state);
|
Log.d("[Bluetooth] State: " + state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (intent.getAction().equals(BluetoothHeadset.ACTION_VENDOR_SPECIFIC_HEADSET_EVENT)) {
|
else if (intent.getAction().equals(BluetoothHeadset.ACTION_VENDOR_SPECIFIC_HEADSET_EVENT)) {
|
||||||
|
@ -314,7 +313,7 @@ public class BluetoothManager extends BroadcastReceiver {
|
||||||
if (eventName.equals("BUTTON") && args.length >= 3) {
|
if (eventName.equals("BUTTON") && args.length >= 3) {
|
||||||
Integer buttonID = (Integer) args[1];
|
Integer buttonID = (Integer) args[1];
|
||||||
Integer mode = (Integer) args[2];
|
Integer mode = (Integer) args[2];
|
||||||
Log.d("Bluetooth event: " + command + " : " + eventName + ", id = " + buttonID + " (" + mode + ")");
|
Log.d("[Bluetooth] Event: " + command + " : " + eventName + ", id = " + buttonID + " (" + mode + ")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -119,6 +119,7 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve
|
||||||
private boolean isConferenceRunning = false;
|
private boolean isConferenceRunning = false;
|
||||||
private LinphoneCoreListenerBase mListener;
|
private LinphoneCoreListenerBase mListener;
|
||||||
private DrawerLayout sideMenu;
|
private DrawerLayout sideMenu;
|
||||||
|
private boolean mProximitySensingEnabled;
|
||||||
|
|
||||||
public static CallActivity instance() {
|
public static CallActivity instance() {
|
||||||
return instance;
|
return instance;
|
||||||
|
@ -800,8 +801,22 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void enableProximitySensing(boolean enable){
|
||||||
|
if (enable){
|
||||||
|
if (!mProximitySensingEnabled){
|
||||||
|
mSensorManager.registerListener(this, mProximity, SensorManager.SENSOR_DELAY_NORMAL);
|
||||||
|
mProximitySensingEnabled = true;
|
||||||
|
}
|
||||||
|
}else{
|
||||||
|
if (mProximitySensingEnabled){
|
||||||
|
mSensorManager.unregisterListener(this);
|
||||||
|
mProximitySensingEnabled = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void showAudioView() {
|
private void showAudioView() {
|
||||||
mSensorManager.registerListener(this, mProximity, SensorManager.SENSOR_DELAY_NORMAL);
|
enableProximitySensing(true);
|
||||||
replaceFragmentVideoByAudio();
|
replaceFragmentVideoByAudio();
|
||||||
displayAudioCall();
|
displayAudioCall();
|
||||||
showStatusBar();
|
showStatusBar();
|
||||||
|
@ -816,7 +831,7 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve
|
||||||
}
|
}
|
||||||
refreshInCallActions();
|
refreshInCallActions();
|
||||||
|
|
||||||
mSensorManager.unregisterListener(this);
|
enableProximitySensing(false);
|
||||||
replaceFragmentAudioByVideo();
|
replaceFragmentAudioByVideo();
|
||||||
hideStatusBar();
|
hideStatusBar();
|
||||||
}
|
}
|
||||||
|
@ -1173,7 +1188,7 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve
|
||||||
handleViewIntent();
|
handleViewIntent();
|
||||||
|
|
||||||
if (!isVideoEnabled(LinphoneManager.getLc().getCurrentCall())) {
|
if (!isVideoEnabled(LinphoneManager.getLc().getCurrentCall())) {
|
||||||
mSensorManager.registerListener(this, mProximity, SensorManager.SENSOR_DELAY_NORMAL);
|
enableProximitySensing(true);
|
||||||
removeCallbacks();
|
removeCallbacks();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1223,10 +1238,7 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve
|
||||||
mControlsHandler.removeCallbacks(mControls);
|
mControlsHandler.removeCallbacks(mControls);
|
||||||
}
|
}
|
||||||
mControls = null;
|
mControls = null;
|
||||||
|
enableProximitySensing(false);
|
||||||
if (!isVideoEnabled(LinphoneManager.getLc().getCurrentCall())) {
|
|
||||||
mSensorManager.unregisterListener(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -1239,7 +1251,7 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve
|
||||||
mControls = null;
|
mControls = null;
|
||||||
mControlsHandler = null;
|
mControlsHandler = null;
|
||||||
|
|
||||||
mSensorManager.unregisterListener(this);
|
enableProximitySensing(false);
|
||||||
|
|
||||||
unbindDrawables(findViewById(R.id.topLayout));
|
unbindDrawables(findViewById(R.id.topLayout));
|
||||||
instance = null;
|
instance = null;
|
||||||
|
@ -1510,7 +1522,7 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve
|
||||||
private void displayConference(boolean isInConf){
|
private void displayConference(boolean isInConf){
|
||||||
if(isInConf) {
|
if(isInConf) {
|
||||||
mControlsLayout.setVisibility(View.VISIBLE);
|
mControlsLayout.setVisibility(View.VISIBLE);
|
||||||
mSensorManager.registerListener(this, mProximity, SensorManager.SENSOR_DELAY_NORMAL);
|
enableProximitySensing(true);
|
||||||
mActiveCallHeader.setVisibility(View.GONE);
|
mActiveCallHeader.setVisibility(View.GONE);
|
||||||
mNoCurrentCall.setVisibility(View.GONE);
|
mNoCurrentCall.setVisibility(View.GONE);
|
||||||
conferenceList.removeAllViews();
|
conferenceList.removeAllViews();
|
||||||
|
|
|
@ -44,6 +44,8 @@ import android.app.Activity;
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
import android.app.Fragment;
|
import android.app.Fragment;
|
||||||
import android.app.ProgressDialog;
|
import android.app.ProgressDialog;
|
||||||
|
import android.content.ClipData;
|
||||||
|
import android.content.ClipboardManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.res.Configuration;
|
import android.content.res.Configuration;
|
||||||
|
@ -387,7 +389,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
||||||
|
|
||||||
if(isEditMode) {
|
if(isEditMode) {
|
||||||
deleteChatBubble.setVisibility(View.VISIBLE);
|
deleteChatBubble.setVisibility(View.VISIBLE);
|
||||||
if(message.isOutgoing()){
|
if (message.isOutgoing()) {
|
||||||
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
|
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
|
||||||
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
|
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
|
||||||
layoutParams.setMargins(100, 10, 10, 10);
|
layoutParams.setMargins(100, 10, 10, 10);
|
||||||
|
@ -419,7 +421,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if(messagesList.isItemChecked(position)) {
|
if (messagesList.isItemChecked(position)) {
|
||||||
deleteChatBubble.setChecked(true);
|
deleteChatBubble.setChecked(true);
|
||||||
} else {
|
} else {
|
||||||
deleteChatBubble.setChecked(false);
|
deleteChatBubble.setChecked(false);
|
||||||
|
@ -427,7 +429,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
||||||
|
|
||||||
rlayout.addView(v);
|
rlayout.addView(v);
|
||||||
} else {
|
} else {
|
||||||
if(message.isOutgoing()){
|
if (message.isOutgoing()) {
|
||||||
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
|
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
|
||||||
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
|
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
|
||||||
layoutParams.setMargins(100, 10, 10, 10);
|
layoutParams.setMargins(100, 10, 10, 10);
|
||||||
|
@ -448,7 +450,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
||||||
LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
|
LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
|
||||||
|
|
||||||
LinphoneAddress lAddress = null;
|
LinphoneAddress lAddress = null;
|
||||||
if(sipUri == null){
|
if (sipUri == null) {
|
||||||
initNewChatConversation();
|
initNewChatConversation();
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
|
@ -477,7 +479,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
||||||
}
|
}
|
||||||
|
|
||||||
private void displayMessageList() {
|
private void displayMessageList() {
|
||||||
if(chatRoom != null) {
|
if (chatRoom != null) {
|
||||||
if (adapter != null) {
|
if (adapter != null) {
|
||||||
adapter.refreshHistory();
|
adapter.refreshHistory();
|
||||||
} else {
|
} else {
|
||||||
|
@ -488,7 +490,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
||||||
}
|
}
|
||||||
|
|
||||||
private void displayChatHeader(LinphoneAddress address) {
|
private void displayChatHeader(LinphoneAddress address) {
|
||||||
if(contact != null) {
|
if (contact != null) {
|
||||||
contactName.setText(contact.getFullName());
|
contactName.setText(contact.getFullName());
|
||||||
} else if(address != null){
|
} else if(address != null){
|
||||||
contactName.setText(LinphoneUtils.getAddressDisplayName(address));
|
contactName.setText(LinphoneUtils.getAddressDisplayName(address));
|
||||||
|
@ -618,7 +620,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
||||||
String draft = getArguments().getString("messageDraft");
|
String draft = getArguments().getString("messageDraft");
|
||||||
message.setText(draft);
|
message.setText(draft);
|
||||||
|
|
||||||
if(!newChatConversation) {
|
if (!newChatConversation) {
|
||||||
initChatRoom(sipUri);
|
initChatRoom(sipUri);
|
||||||
searchContactField.setVisibility(View.GONE);
|
searchContactField.setVisibility(View.GONE);
|
||||||
resultContactsSearch.setVisibility(View.GONE);
|
resultContactsSearch.setVisibility(View.GONE);
|
||||||
|
@ -626,10 +628,10 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void selectAllList(boolean isSelectAll){
|
private void selectAllList(boolean isSelectAll) {
|
||||||
int size = messagesList.getAdapter().getCount();
|
int size = messagesList.getAdapter().getCount();
|
||||||
for(int i=0; i<size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
messagesList.setItemChecked(i,isSelectAll);
|
messagesList.setItemChecked(i, isSelectAll);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -642,8 +644,8 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
||||||
|
|
||||||
private void removeChats(){
|
private void removeChats(){
|
||||||
int size = messagesList.getAdapter().getCount();
|
int size = messagesList.getAdapter().getCount();
|
||||||
for(int i=0; i<size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
if(messagesList.isItemChecked(i)){
|
if (messagesList.isItemChecked(i)) {
|
||||||
LinphoneChatMessage message = (LinphoneChatMessage) messagesList.getAdapter().getItem(i);
|
LinphoneChatMessage message = (LinphoneChatMessage) messagesList.getAdapter().getItem(i);
|
||||||
chatRoom.deleteMessage(message);
|
chatRoom.deleteMessage(message);
|
||||||
}
|
}
|
||||||
|
@ -827,7 +829,9 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
||||||
txt = message.getText();
|
txt = message.getText();
|
||||||
}
|
}
|
||||||
if (txt != null) {
|
if (txt != null) {
|
||||||
Compatibility.copyTextToClipboard(getActivity(), txt);
|
ClipboardManager clipboard = (ClipboardManager) getActivity().getSystemService(Context.CLIPBOARD_SERVICE);
|
||||||
|
ClipData clip = android.content.ClipData.newPlainText("Message", txt);
|
||||||
|
clipboard.setPrimaryClip(clip);
|
||||||
LinphoneActivity.instance().displayCustomToast(getString(R.string.text_copied_to_clipboard), Toast.LENGTH_SHORT);
|
LinphoneActivity.instance().displayCustomToast(getString(R.string.text_copied_to_clipboard), Toast.LENGTH_SHORT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,117 +0,0 @@
|
||||||
package org.linphone;
|
|
||||||
|
|
||||||
import org.linphone.core.LinphoneChatMessage;
|
|
||||||
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.BitmapFactory;
|
|
||||||
/*
|
|
||||||
ChatMessage.java
|
|
||||||
Copyright (C) 2012 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Sylvain Berfini
|
|
||||||
* @deprecated
|
|
||||||
*/
|
|
||||||
public class ChatMessage {
|
|
||||||
private String message;
|
|
||||||
private String timestamp;
|
|
||||||
private String url;
|
|
||||||
private boolean incoming;
|
|
||||||
private int status;
|
|
||||||
private int id;
|
|
||||||
private Bitmap image;
|
|
||||||
private boolean isRead;
|
|
||||||
|
|
||||||
public ChatMessage(int id, String message, byte[] rawImage, String timestamp, boolean incoming, int status, boolean read) {
|
|
||||||
super();
|
|
||||||
this.id = id;
|
|
||||||
this.message = message;
|
|
||||||
this.timestamp = timestamp;
|
|
||||||
this.incoming = incoming;
|
|
||||||
this.status = status;
|
|
||||||
this.image = rawImage != null ? BitmapFactory.decodeByteArray(rawImage, 0, rawImage.length) : null;
|
|
||||||
this.isRead = read;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ChatMessage(int id, String message, Bitmap image, String timestamp, boolean incoming, int status, boolean read) {
|
|
||||||
super();
|
|
||||||
this.id = id;
|
|
||||||
this.message = message;
|
|
||||||
this.timestamp = timestamp;
|
|
||||||
this.incoming = incoming;
|
|
||||||
this.status = status;
|
|
||||||
this.image = image;
|
|
||||||
this.isRead = read;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getId() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getMessage() {
|
|
||||||
return message;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setMessage(String message) {
|
|
||||||
this.message = message;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getTimestamp() {
|
|
||||||
return timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setTimestamp(String timestamp) {
|
|
||||||
this.timestamp = timestamp;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isIncoming() {
|
|
||||||
return incoming;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setIncoming(boolean incoming) {
|
|
||||||
this.incoming = incoming;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setStatus(int status) {
|
|
||||||
this.status = status;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LinphoneChatMessage.State getStatus() {
|
|
||||||
return LinphoneChatMessage.State.fromInt(status);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Bitmap getImage() {
|
|
||||||
return image;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isRead() {
|
|
||||||
return isRead;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getUrl() {
|
|
||||||
return url;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setUrl(String url) {
|
|
||||||
this.url = url;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() {
|
|
||||||
return this.id + " : " + this.message + " (" + this.url + ") @ " + this.timestamp + ", read= " + this.isRead + ", incoming= " + this.incoming + ", status = " + this.status;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,139 +0,0 @@
|
||||||
package org.linphone;
|
|
||||||
/*
|
|
||||||
Contact.java
|
|
||||||
Copyright (C) 2012 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 java.io.Serializable;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.linphone.compatibility.Compatibility;
|
|
||||||
import org.linphone.core.LinphoneAddress;
|
|
||||||
import org.linphone.core.LinphoneCore;
|
|
||||||
import org.linphone.core.LinphoneFriend;
|
|
||||||
|
|
||||||
import android.content.ContentResolver;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.net.Uri;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Sylvain Berfini
|
|
||||||
* @deprecated
|
|
||||||
*/
|
|
||||||
public class Contact implements Serializable {
|
|
||||||
private static final long serialVersionUID = 3790717505065723499L;
|
|
||||||
|
|
||||||
private String id;
|
|
||||||
private String name;
|
|
||||||
private transient Uri photoUri;
|
|
||||||
private transient Uri thumbnailUri;
|
|
||||||
private transient Bitmap photo;
|
|
||||||
private List<String> numbersOrAddresses;
|
|
||||||
private boolean hasFriends;
|
|
||||||
private LinphoneAddress address;
|
|
||||||
|
|
||||||
public Contact(String id, String name) {
|
|
||||||
super();
|
|
||||||
this.id = id;
|
|
||||||
this.name = name;
|
|
||||||
this.photoUri = null;
|
|
||||||
this.thumbnailUri = null;
|
|
||||||
this.hasFriends = false;
|
|
||||||
this.address = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Contact(String id, LinphoneAddress address) {
|
|
||||||
super();
|
|
||||||
this.id = id;
|
|
||||||
this.name = LinphoneUtils.getAddressDisplayName(address);
|
|
||||||
this.photoUri = null;
|
|
||||||
this.thumbnailUri = null;
|
|
||||||
this.address = address;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public Contact(String id, String name, Uri photo, Uri thumbnail) {
|
|
||||||
super();
|
|
||||||
this.id = id;
|
|
||||||
this.name = name;
|
|
||||||
this.photoUri = photo;
|
|
||||||
this.thumbnailUri = thumbnail;
|
|
||||||
this.photo = null;
|
|
||||||
this.hasFriends = false;
|
|
||||||
this.address = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Contact(String id, String name, Uri photo, Uri thumbnail, Bitmap picture) {
|
|
||||||
super();
|
|
||||||
this.id = id;
|
|
||||||
this.name = name;
|
|
||||||
this.photoUri = photo;
|
|
||||||
this.thumbnailUri = thumbnail;
|
|
||||||
this.photo = picture;
|
|
||||||
this.hasFriends = false;
|
|
||||||
this.address = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public boolean hasFriends() {
|
|
||||||
return hasFriends;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getID() {
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
|
|
||||||
public String getName() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public LinphoneAddress getLinphoneAddress() {
|
|
||||||
return address;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Uri getPhotoUri() {
|
|
||||||
return photoUri;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Uri getThumbnailUri() {
|
|
||||||
return thumbnailUri;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Bitmap getPhoto() {
|
|
||||||
return photo;
|
|
||||||
}
|
|
||||||
|
|
||||||
public List<String> getNumbersOrAddresses() {
|
|
||||||
if (numbersOrAddresses == null)
|
|
||||||
numbersOrAddresses = new ArrayList<String>();
|
|
||||||
return numbersOrAddresses;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void refresh(ContentResolver cr) {
|
|
||||||
this.numbersOrAddresses = Compatibility.extractContactNumbersAndAddresses(id, cr);
|
|
||||||
LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
|
|
||||||
if(lc != null && lc.getFriendList() != null) {
|
|
||||||
for (LinphoneFriend friend :lc.getFriendList()){
|
|
||||||
if (id.equals(friend.getRefKey())) {
|
|
||||||
hasFriends = true;
|
|
||||||
this.numbersOrAddresses.add(friend.getAddress().asStringUriOnly());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.name = Compatibility.refreshContactName(cr, id);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -78,8 +78,9 @@ public class ContactDetailsFragment extends Fragment implements OnClickListener
|
||||||
deleteContact.setOnClickListener(this);
|
deleteContact.setOnClickListener(this);
|
||||||
|
|
||||||
organization = (TextView) view.findViewById(R.id.contactOrganization);
|
organization = (TextView) view.findViewById(R.id.contactOrganization);
|
||||||
|
boolean isOrgVisible = getResources().getBoolean(R.bool.display_contact_organization);
|
||||||
String org = contact.getOrganization();
|
String org = contact.getOrganization();
|
||||||
if (org != null && !org.isEmpty()) {
|
if (org != null && !org.isEmpty() && isOrgVisible) {
|
||||||
organization.setText(org);
|
organization.setText(org);
|
||||||
} else {
|
} else {
|
||||||
organization.setVisibility(View.GONE);
|
organization.setVisibility(View.GONE);
|
||||||
|
|
|
@ -204,9 +204,16 @@ public class ContactEditorFragment extends Fragment {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
organization = (EditText) view.findViewById(R.id.contactOrganization);
|
organization = (EditText) view.findViewById(R.id.contactOrganization);
|
||||||
if (!isNewContact) {
|
boolean isOrgVisible = getResources().getBoolean(R.bool.display_contact_organization);
|
||||||
organization.setText(contact.getOrganization());
|
if (!isOrgVisible) {
|
||||||
|
organization.setVisibility(View.GONE);
|
||||||
|
view.findViewById(R.id.contactOrganizationTitle).setVisibility(View.GONE);
|
||||||
|
} else {
|
||||||
|
if (!isNewContact) {
|
||||||
|
organization.setText(contact.getOrganization());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isNewContact) {
|
if (!isNewContact) {
|
||||||
|
|
|
@ -501,8 +501,9 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O
|
||||||
}
|
}
|
||||||
|
|
||||||
TextView organization = (TextView) view.findViewById(R.id.contactOrganization);
|
TextView organization = (TextView) view.findViewById(R.id.contactOrganization);
|
||||||
|
boolean isOrgVisible = getResources().getBoolean(R.bool.display_contact_organization);
|
||||||
String org = contact.getOrganization();
|
String org = contact.getOrganization();
|
||||||
if (org != null && !org.isEmpty()) {
|
if (org != null && !org.isEmpty() && isOrgVisible) {
|
||||||
organization.setText(org);
|
organization.setText(org);
|
||||||
organization.setVisibility(View.VISIBLE);
|
organization.setVisibility(View.VISIBLE);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -21,10 +21,11 @@ package org.linphone;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
import org.linphone.compatibility.Compatibility;
|
|
||||||
import org.linphone.core.LinphoneAddress;
|
import org.linphone.core.LinphoneAddress;
|
||||||
import org.linphone.core.LinphoneCore;
|
import org.linphone.core.LinphoneCore;
|
||||||
import org.linphone.core.LinphoneFriend;
|
import org.linphone.core.LinphoneFriend;
|
||||||
|
@ -38,11 +39,13 @@ import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.database.ContentObserver;
|
import android.database.ContentObserver;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
|
import android.database.MatrixCursor;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.provider.ContactsContract;
|
import android.provider.ContactsContract;
|
||||||
|
import android.provider.ContactsContract.CommonDataKinds;
|
||||||
import android.provider.ContactsContract.Data;
|
import android.provider.ContactsContract.Data;
|
||||||
|
|
||||||
interface ContactsUpdatedListener {
|
interface ContactsUpdatedListener {
|
||||||
|
@ -228,14 +231,13 @@ public class ContactsManager extends ContentObserver {
|
||||||
contactsFetchTask.execute();
|
contactsFetchTask.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private class ContactsFetchTask extends AsyncTask<Void, List<LinphoneContact>, List<LinphoneContact>> {
|
private class ContactsFetchTask extends AsyncTask<Void, List<LinphoneContact>, List<LinphoneContact>> {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected List<LinphoneContact> doInBackground(Void... params) {
|
protected List<LinphoneContact> doInBackground(Void... params) {
|
||||||
List<LinphoneContact> contacts = new ArrayList<LinphoneContact>();
|
List<LinphoneContact> contacts = new ArrayList<LinphoneContact>();
|
||||||
|
|
||||||
if (hasContactsAccess()) {
|
if (hasContactsAccess()) {
|
||||||
Cursor c = Compatibility.getContactsCursor(contentResolver, null);
|
Cursor c = getContactsCursor(contentResolver);
|
||||||
if (c != null) {
|
if (c != null) {
|
||||||
while (c.moveToNext()) {
|
while (c.moveToNext()) {
|
||||||
String id = c.getString(c.getColumnIndex(Data.CONTACT_ID));
|
String id = c.getString(c.getColumnIndex(Data.CONTACT_ID));
|
||||||
|
@ -247,34 +249,37 @@ public class ContactsManager extends ContentObserver {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (LinphoneFriend friend : LinphoneManager.getLc().getFriendList()) {
|
LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
|
||||||
String refkey = friend.getRefKey();
|
if (lc != null) {
|
||||||
if (refkey != null) {
|
for (LinphoneFriend friend : lc.getFriendList()) {
|
||||||
boolean found = false;
|
String refkey = friend.getRefKey();
|
||||||
for (LinphoneContact contact : contacts) {
|
if (refkey != null) {
|
||||||
if (refkey.equals(contact.getAndroidId())) {
|
boolean found = false;
|
||||||
// Native matching contact found, link the friend to it
|
for (LinphoneContact contact : contacts) {
|
||||||
contact.setFriend(friend);
|
if (refkey.equals(contact.getAndroidId())) {
|
||||||
found = true;
|
// Native matching contact found, link the friend to it
|
||||||
break;
|
contact.setFriend(friend);
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
if (!found) {
|
||||||
if (!found) {
|
if (hasContactAccess) {
|
||||||
if (hasContactAccess) {
|
// If refkey != null and hasContactAccess but there isn't a native contact with this value, then this contact has been deleted. Let's do the same with the LinphoneFriend
|
||||||
// If refkey != null and hasContactAccess but there isn't a native contact with this value, then this contact has been deleted. Let's do the same with the LinphoneFriend
|
lc.removeFriend(friend);
|
||||||
LinphoneManager.getLc().removeFriend(friend);
|
} else {
|
||||||
} else {
|
// Refkey not null but no contact access => can't link it to native contact so display it on is own
|
||||||
// Refkey not null but no contact access => can't link it to native contact so display it on is own
|
LinphoneContact contact = new LinphoneContact();
|
||||||
LinphoneContact contact = new LinphoneContact();
|
contact.setFriend(friend);
|
||||||
contact.setFriend(friend);
|
contacts.add(contact);
|
||||||
contacts.add(contact);
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// No refkey so it's a standalone contact
|
||||||
|
LinphoneContact contact = new LinphoneContact();
|
||||||
|
contact.setFriend(friend);
|
||||||
|
contacts.add(contact);
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// No refkey so it's a standalone contact
|
|
||||||
LinphoneContact contact = new LinphoneContact();
|
|
||||||
contact.setFriend(friend);
|
|
||||||
contacts.add(contact);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -364,4 +369,38 @@ public class ContactsManager extends ContentObserver {
|
||||||
public String getString(int resourceID) {
|
public String getString(int resourceID) {
|
||||||
return context.getString(resourceID);
|
return context.getString(resourceID);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Cursor getContactsCursor(ContentResolver cr) {
|
||||||
|
String req = "(" + Data.MIMETYPE + " = '" + CommonDataKinds.Phone.CONTENT_ITEM_TYPE
|
||||||
|
+ "' AND " + CommonDataKinds.Phone.NUMBER + " IS NOT NULL "
|
||||||
|
+ " OR (" + Data.MIMETYPE + " = '" + CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE
|
||||||
|
+ "' AND " + ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS + " IS NOT NULL))";
|
||||||
|
String[] projection = new String[] { Data.CONTACT_ID, Data.DISPLAY_NAME };
|
||||||
|
String query = Data.DISPLAY_NAME + " IS NOT NULL AND (" + req + ")";
|
||||||
|
|
||||||
|
Cursor cursor = cr.query(Data.CONTENT_URI, projection, query, null, " lower(" + Data.DISPLAY_NAME + ") COLLATE UNICODE ASC");
|
||||||
|
if (cursor == null) {
|
||||||
|
return cursor;
|
||||||
|
}
|
||||||
|
|
||||||
|
MatrixCursor result = new MatrixCursor(cursor.getColumnNames());
|
||||||
|
Set<String> groupBy = new HashSet<String>();
|
||||||
|
while (cursor.moveToNext()) {
|
||||||
|
String name = cursor.getString(cursor.getColumnIndex(Data.DISPLAY_NAME));
|
||||||
|
if (!groupBy.contains(name)) {
|
||||||
|
groupBy.add(name);
|
||||||
|
Object[] newRow = new Object[cursor.getColumnCount()];
|
||||||
|
|
||||||
|
int contactID = cursor.getColumnIndex(Data.CONTACT_ID);
|
||||||
|
int displayName = cursor.getColumnIndex(Data.DISPLAY_NAME);
|
||||||
|
|
||||||
|
newRow[contactID] = cursor.getString(contactID);
|
||||||
|
newRow[displayName] = cursor.getString(displayName);
|
||||||
|
|
||||||
|
result.addRow(newRow);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cursor.close();
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,47 +0,0 @@
|
||||||
package org.linphone;
|
|
||||||
/*
|
|
||||||
KeepAliveHandler.java
|
|
||||||
Copyright (C) 2013 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 org.linphone.core.LinphoneCoreFactory;
|
|
||||||
import org.linphone.mediastream.Log;
|
|
||||||
|
|
||||||
import android.content.BroadcastReceiver;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
|
|
||||||
public class KeepAliveHandler extends BroadcastReceiver {
|
|
||||||
@Override
|
|
||||||
public void onReceive(Context context, Intent intent) {
|
|
||||||
boolean isDebugEnabled = LinphonePreferences.instance().isDebugEnabled();
|
|
||||||
LinphoneCoreFactory.instance().enableLogCollection(isDebugEnabled);
|
|
||||||
LinphoneCoreFactory.instance().setDebugMode(isDebugEnabled, context.getString(R.string.app_name));
|
|
||||||
|
|
||||||
Log.i("Keep alive handler invoked");
|
|
||||||
if (LinphoneManager.getLcIfManagerNotDestroyedOrNull() != null) {
|
|
||||||
//first refresh registers
|
|
||||||
LinphoneManager.getLc().refreshRegisters();
|
|
||||||
//make sure iterate will have enough time, device will not sleep until exit from this method
|
|
||||||
try {
|
|
||||||
Thread.sleep(2000);
|
|
||||||
} catch (InterruptedException e) {
|
|
||||||
//Log.e("Cannot sleep for 2s", e); //TODO FIXME Crash since the log rework
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -18,12 +18,16 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
package org.linphone;
|
package org.linphone;
|
||||||
|
|
||||||
|
import org.linphone.core.LinphoneCore;
|
||||||
|
import org.linphone.core.LinphoneCoreFactory;
|
||||||
import org.linphone.mediastream.Log;
|
import org.linphone.mediastream.Log;
|
||||||
|
|
||||||
|
import android.app.AlarmManager;
|
||||||
|
import android.app.PendingIntent;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
|
import android.os.SystemClock;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Purpose of this receiver is to disable keep alives when screen is off
|
* Purpose of this receiver is to disable keep alives when screen is off
|
||||||
|
@ -32,13 +36,37 @@ public class KeepAliveReceiver extends BroadcastReceiver {
|
||||||
@Override
|
@Override
|
||||||
public void onReceive(Context context, Intent intent) {
|
public void onReceive(Context context, Intent intent) {
|
||||||
if (!LinphoneService.isReady()) {
|
if (!LinphoneService.isReady()) {
|
||||||
Log.i("Keep alive broadcast received while Linphone service not ready");
|
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
if (intent.getAction().equalsIgnoreCase(Intent.ACTION_SCREEN_ON)) {
|
boolean isDebugEnabled = LinphonePreferences.instance().isDebugEnabled();
|
||||||
LinphoneManager.getLc().enableKeepAlive(true);
|
LinphoneCoreFactory.instance().enableLogCollection(isDebugEnabled);
|
||||||
} else if (intent.getAction().equalsIgnoreCase(Intent.ACTION_SCREEN_OFF)) {
|
LinphoneCoreFactory.instance().setDebugMode(isDebugEnabled, context.getString(R.string.app_name));
|
||||||
LinphoneManager.getLc().enableKeepAlive(false);
|
LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
|
||||||
|
if (lc == null) return;
|
||||||
|
|
||||||
|
String action = intent.getAction();
|
||||||
|
if (action == null) {
|
||||||
|
Log.i("[KeepAlive] Refresh registers");
|
||||||
|
lc.refreshRegisters();
|
||||||
|
//make sure iterate will have enough time, device will not sleep until exit from this method
|
||||||
|
try {
|
||||||
|
Thread.sleep(2000);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
Log.e("Cannot sleep for 2s", e);
|
||||||
|
} finally {
|
||||||
|
//make sure the application will at least wakes up every 10 mn
|
||||||
|
Intent newIntent = new Intent(context, KeepAliveReceiver.class);
|
||||||
|
PendingIntent keepAlivePendingIntent = PendingIntent.getBroadcast(context, 0, newIntent, PendingIntent.FLAG_ONE_SHOT);
|
||||||
|
((AlarmManager) context.getSystemService(Context.ALARM_SERVICE)).setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP
|
||||||
|
, SystemClock.elapsedRealtime() + 600000
|
||||||
|
, keepAlivePendingIntent);
|
||||||
|
}
|
||||||
|
} else if (action.equalsIgnoreCase(Intent.ACTION_SCREEN_ON)) {
|
||||||
|
Log.i("[KeepAlive] Screen is on, enable");
|
||||||
|
lc.enableKeepAlive(true);
|
||||||
|
} else if (action.equalsIgnoreCase(Intent.ACTION_SCREEN_OFF)) {
|
||||||
|
Log.i("[KeepAlive] Screen is off, disable");
|
||||||
|
lc.enableKeepAlive(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1166,6 +1166,10 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
|
||||||
checkAndRequestPermission(Manifest.permission.READ_CONTACTS, PERMISSIONS_REQUEST_CONTACTS);
|
checkAndRequestPermission(Manifest.permission.READ_CONTACTS, PERMISSIONS_REQUEST_CONTACTS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean willContactsPermissionBeAsked() {
|
||||||
|
return LinphonePreferences.instance().firstTimeAskingForPermission(Manifest.permission.READ_CONTACTS) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_CONTACTS);
|
||||||
|
}
|
||||||
|
|
||||||
public void checkAndRequestWriteContactsPermission() {
|
public void checkAndRequestWriteContactsPermission() {
|
||||||
checkAndRequestPermission(Manifest.permission.WRITE_CONTACTS, 0);
|
checkAndRequestPermission(Manifest.permission.WRITE_CONTACTS, 0);
|
||||||
}
|
}
|
||||||
|
@ -1274,6 +1278,9 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
|
||||||
ContactsManager.getInstance().enableContactsAccess();
|
ContactsManager.getInstance().enableContactsAccess();
|
||||||
ContactsManager.getInstance().fetchContactsAsync();
|
ContactsManager.getInstance().fetchContactsAsync();
|
||||||
fetchedContactsOnce = true;
|
fetchedContactsOnce = true;
|
||||||
|
} else if (contacts != PackageManager.PERMISSION_GRANTED && !willContactsPermissionBeAsked()) {
|
||||||
|
ContactsManager.getInstance().fetchContactsAsync();
|
||||||
|
fetchedContactsOnce = true;
|
||||||
} else {
|
} else {
|
||||||
checkAndRequestReadContactsPermission();
|
checkAndRequestReadContactsPermission();
|
||||||
}
|
}
|
||||||
|
|
|
@ -419,6 +419,7 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
|
||||||
friend.edit();
|
friend.edit();
|
||||||
friend.setFamilyName(lastName);
|
friend.setFamilyName(lastName);
|
||||||
friend.setGivenName(firstName);
|
friend.setGivenName(firstName);
|
||||||
|
friend.setName(fullName);
|
||||||
|
|
||||||
for (LinphoneAddress address : friend.getAddresses()) {
|
for (LinphoneAddress address : friend.getAddresses()) {
|
||||||
friend.removeAddress(address);
|
friend.removeAddress(address);
|
||||||
|
@ -443,23 +444,21 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
|
||||||
friend.addPhoneNumber(noa.getValue());
|
friend.addPhoneNumber(noa.getValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
friend.setName(fullName);
|
|
||||||
friend.done();
|
friend.done();
|
||||||
|
|
||||||
if (friend.getAddress() != null) {
|
if (!friend.isAlreadyPresentInFriendList()) {
|
||||||
if (lc.findFriendByAddress(friend.getAddress().asString()) == null) {
|
try {
|
||||||
try {
|
LinphoneManager.getLcIfManagerNotDestroyedOrNull().addFriend(friend);
|
||||||
lc.addFriend(friend);
|
} catch (LinphoneCoreException e) {
|
||||||
if (!ContactsManager.getInstance().hasContactsAccess()) {
|
Log.e(e);
|
||||||
// This refresh is only needed if app has no contacts permission to refresh the list of LinphoneFriends.
|
|
||||||
// Otherwise contacts will be refreshed due to changes in native contact and the handler in ContactsManager
|
|
||||||
ContactsManager.getInstance().fetchContactsAsync();
|
|
||||||
}
|
|
||||||
} catch (LinphoneCoreException e) {
|
|
||||||
Log.e(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!ContactsManager.getInstance().hasContactsAccess()) {
|
||||||
|
// This refresh is only needed if app has no contacts permission to refresh the list of LinphoneFriends.
|
||||||
|
// Otherwise contacts will be refreshed due to changes in native contact and the handler in ContactsManager
|
||||||
|
ContactsManager.getInstance().fetchContactsAsync();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void save() {
|
public void save() {
|
||||||
|
|
|
@ -36,10 +36,7 @@ import java.util.Set;
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
import java.util.TimerTask;
|
import java.util.TimerTask;
|
||||||
|
|
||||||
import org.linphone.compatibility.Compatibility;
|
|
||||||
import org.linphone.core.CallDirection;
|
import org.linphone.core.CallDirection;
|
||||||
import org.linphone.core.OpenH264DownloadHelperAction;
|
|
||||||
import org.linphone.core.OpenH264DownloadHelperListener;
|
|
||||||
import org.linphone.core.LinphoneAddress;
|
import org.linphone.core.LinphoneAddress;
|
||||||
import org.linphone.core.LinphoneBuffer;
|
import org.linphone.core.LinphoneBuffer;
|
||||||
import org.linphone.core.LinphoneCall;
|
import org.linphone.core.LinphoneCall;
|
||||||
|
@ -57,13 +54,13 @@ import org.linphone.core.LinphoneCore.RegistrationState;
|
||||||
import org.linphone.core.LinphoneCore.RemoteProvisioningState;
|
import org.linphone.core.LinphoneCore.RemoteProvisioningState;
|
||||||
import org.linphone.core.LinphoneCoreException;
|
import org.linphone.core.LinphoneCoreException;
|
||||||
import org.linphone.core.LinphoneCoreFactory;
|
import org.linphone.core.LinphoneCoreFactory;
|
||||||
import org.linphone.core.LinphoneCoreFactoryImpl;
|
|
||||||
import org.linphone.core.LinphoneCoreListener;
|
import org.linphone.core.LinphoneCoreListener;
|
||||||
import org.linphone.core.LinphoneEvent;
|
import org.linphone.core.LinphoneEvent;
|
||||||
import org.linphone.core.LinphoneFriend;
|
import org.linphone.core.LinphoneFriend;
|
||||||
import org.linphone.core.LinphoneFriendList;
|
import org.linphone.core.LinphoneFriendList;
|
||||||
import org.linphone.core.LinphoneInfoMessage;
|
import org.linphone.core.LinphoneInfoMessage;
|
||||||
import org.linphone.core.LinphoneProxyConfig;
|
import org.linphone.core.LinphoneProxyConfig;
|
||||||
|
import org.linphone.core.OpenH264DownloadHelperListener;
|
||||||
import org.linphone.core.PayloadType;
|
import org.linphone.core.PayloadType;
|
||||||
import org.linphone.core.PresenceActivityType;
|
import org.linphone.core.PresenceActivityType;
|
||||||
import org.linphone.core.PresenceModel;
|
import org.linphone.core.PresenceModel;
|
||||||
|
@ -85,7 +82,6 @@ import android.app.ProgressDialog;
|
||||||
import android.content.BroadcastReceiver;
|
import android.content.BroadcastReceiver;
|
||||||
import android.content.ContentResolver;
|
import android.content.ContentResolver;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.IntentFilter;
|
import android.content.IntentFilter;
|
||||||
import android.content.pm.PackageManager.NameNotFoundException;
|
import android.content.pm.PackageManager.NameNotFoundException;
|
||||||
|
@ -105,8 +101,6 @@ import android.os.PowerManager;
|
||||||
import android.os.PowerManager.WakeLock;
|
import android.os.PowerManager.WakeLock;
|
||||||
import android.os.Vibrator;
|
import android.os.Vibrator;
|
||||||
import android.preference.CheckBoxPreference;
|
import android.preference.CheckBoxPreference;
|
||||||
import android.provider.MediaStore;
|
|
||||||
import android.provider.MediaStore.Images;
|
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
import android.provider.Settings.SettingNotFoundException;
|
import android.provider.Settings.SettingNotFoundException;
|
||||||
import android.telephony.TelephonyManager;
|
import android.telephony.TelephonyManager;
|
||||||
|
@ -150,6 +144,8 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag
|
||||||
private boolean echoTesterIsRunning;
|
private boolean echoTesterIsRunning;
|
||||||
private int mLastNetworkType=-1;
|
private int mLastNetworkType=-1;
|
||||||
private ConnectivityManager mConnectivityManager;
|
private ConnectivityManager mConnectivityManager;
|
||||||
|
private BroadcastReceiver mKeepAliveReceiver;
|
||||||
|
private IntentFilter mKeepAliveIntentFilter;
|
||||||
private Handler mHandler = new Handler();
|
private Handler mHandler = new Handler();
|
||||||
private WakeLock mIncallWakeLock;
|
private WakeLock mIncallWakeLock;
|
||||||
private static List<LinphoneChatMessage> mPendingChatFileMessage;
|
private static List<LinphoneChatMessage> mPendingChatFileMessage;
|
||||||
|
@ -210,11 +206,8 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag
|
||||||
private final String mErrorToneFile;
|
private final String mErrorToneFile;
|
||||||
private final String mUserCertificatePath;
|
private final String mUserCertificatePath;
|
||||||
private ByteArrayInputStream mUploadingImageStream;
|
private ByteArrayInputStream mUploadingImageStream;
|
||||||
|
|
||||||
private Timer mTimer;
|
private Timer mTimer;
|
||||||
|
|
||||||
private BroadcastReceiver mKeepAliveReceiver = new KeepAliveReceiver();
|
|
||||||
|
|
||||||
private void routeAudioToSpeakerHelper(boolean speakerOn) {
|
private void routeAudioToSpeakerHelper(boolean speakerOn) {
|
||||||
Log.w("Routing audio to " + (speakerOn ? "speaker" : "earpiece") + ", disabling bluetooth audio route");
|
Log.w("Routing audio to " + (speakerOn ? "speaker" : "earpiece") + ", disabling bluetooth audio route");
|
||||||
BluetoothManager.getInstance().disableBluetoothSCO();
|
BluetoothManager.getInstance().disableBluetoothSCO();
|
||||||
|
@ -661,11 +654,12 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag
|
||||||
public void restartLinphoneCore() {
|
public void restartLinphoneCore() {
|
||||||
destroyLinphoneCore();
|
destroyLinphoneCore();
|
||||||
startLibLinphone(mServiceContext);
|
startLibLinphone(mServiceContext);
|
||||||
|
/*
|
||||||
IntentFilter lFilter = new IntentFilter(Intent.ACTION_SCREEN_ON);
|
You cannot receive this through components declared in manifests, only
|
||||||
lFilter.addAction(Intent.ACTION_SCREEN_OFF);
|
by explicitly registering for it with Context.registerReceiver(). This is a protected intent that can only
|
||||||
mServiceContext.registerReceiver(mKeepAliveReceiver, lFilter);
|
be sent by the system.
|
||||||
|
*/
|
||||||
|
mServiceContext.registerReceiver(mKeepAliveReceiver, mKeepAliveIntentFilter);
|
||||||
sExited = false;
|
sExited = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -698,6 +692,32 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag
|
||||||
Log.e(e, "Cannot start linphone");
|
Log.e(e, "Cannot start linphone");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void initPushNotificationsService() {
|
||||||
|
try {
|
||||||
|
Class<?> GCMRegistrar = Class.forName("com.google.android.gcm.GCMRegistrar");
|
||||||
|
GCMRegistrar.getMethod("checkDevice", Context.class).invoke(null, mServiceContext);
|
||||||
|
try {
|
||||||
|
GCMRegistrar.getMethod("checkManifest", Context.class).invoke(null, mServiceContext);
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
Log.e("[Push Notification] No receiver found", e);
|
||||||
|
}
|
||||||
|
final String regId = (String)GCMRegistrar.getMethod("getRegistrationId", Context.class).invoke(null, mServiceContext);
|
||||||
|
String newPushSenderID = mServiceContext.getString(R.string.push_sender_id);
|
||||||
|
String currentPushSenderID = LinphonePreferences.instance().getPushNotificationRegistrationID();
|
||||||
|
if (regId.equals("") || currentPushSenderID == null || !currentPushSenderID.equals(newPushSenderID)) {
|
||||||
|
GCMRegistrar.getMethod("register", Context.class, String[].class).invoke(null, mServiceContext, new String[]{newPushSenderID});
|
||||||
|
Log.i("[Push Notification] Storing current sender id = " + newPushSenderID);
|
||||||
|
} else {
|
||||||
|
Log.i("[Push Notification] Already registered with id = " + regId);
|
||||||
|
LinphonePreferences.instance().setPushNotificationRegistrationID(regId);
|
||||||
|
}
|
||||||
|
} catch (java.lang.UnsupportedOperationException e) {
|
||||||
|
Log.i("[Push Notification] Not activated");
|
||||||
|
} catch (Exception e1) {
|
||||||
|
Log.i("[Push Notification] Assuming GCM jar is not provided.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private synchronized void initLiblinphone(LinphoneCore lc) throws LinphoneCoreException {
|
private synchronized void initLiblinphone(LinphoneCore lc) throws LinphoneCoreException {
|
||||||
mLc = lc;
|
mLc = lc;
|
||||||
|
@ -752,12 +772,18 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag
|
||||||
mLc.migrateCallLogs();
|
mLc.migrateCallLogs();
|
||||||
|
|
||||||
if (mServiceContext.getResources().getBoolean(R.bool.enable_push_id)) {
|
if (mServiceContext.getResources().getBoolean(R.bool.enable_push_id)) {
|
||||||
Compatibility.initPushNotificationService(mServiceContext);
|
initPushNotificationsService();
|
||||||
}
|
}
|
||||||
|
|
||||||
IntentFilter lFilter = new IntentFilter(Intent.ACTION_SCREEN_ON);
|
/*
|
||||||
lFilter.addAction(Intent.ACTION_SCREEN_OFF);
|
You cannot receive this through components declared in manifests, only
|
||||||
mServiceContext.registerReceiver(mKeepAliveReceiver, lFilter);
|
by explicitly registering for it with Context.registerReceiver(). This is a protected intent that can only
|
||||||
|
be sent by the system.
|
||||||
|
*/
|
||||||
|
mKeepAliveIntentFilter = new IntentFilter(Intent.ACTION_SCREEN_ON);
|
||||||
|
mKeepAliveIntentFilter.addAction(Intent.ACTION_SCREEN_OFF);
|
||||||
|
mKeepAliveReceiver = new KeepAliveReceiver();
|
||||||
|
mServiceContext.registerReceiver(mKeepAliveReceiver, mKeepAliveIntentFilter);
|
||||||
|
|
||||||
updateNetworkReachability();
|
updateNetworkReachability();
|
||||||
|
|
||||||
|
@ -1024,7 +1050,16 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void setAudioManagerInCallMode() {
|
||||||
|
if (mAudioManager.getMode() == AudioManager.MODE_IN_COMMUNICATION) {
|
||||||
|
Log.w("[AudioManager] already in MODE_IN_COMMUNICATION, skipping...");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Log.d("[AudioManager] Mode: MODE_IN_COMMUNICATION");
|
||||||
|
mAudioManager.setMode(AudioManager.MODE_IN_COMMUNICATION);
|
||||||
|
}
|
||||||
|
|
||||||
@SuppressLint("Wakelock")
|
@SuppressLint("Wakelock")
|
||||||
public void callState(final LinphoneCore lc,final LinphoneCall call, final State state, final String message) {
|
public void callState(final LinphoneCore lc,final LinphoneCall call, final State state, final String message) {
|
||||||
Log.i("New call state [",state,"]");
|
Log.i("New call state [",state,"]");
|
||||||
|
@ -1060,7 +1095,7 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag
|
||||||
if (state == State.Connected) {
|
if (state == State.Connected) {
|
||||||
if (mLc.getCallsNb() == 1) {
|
if (mLc.getCallsNb() == 1) {
|
||||||
requestAudioFocus();
|
requestAudioFocus();
|
||||||
Compatibility.setAudioManagerInCallMode(mAudioManager);
|
setAudioManagerInCallMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Hacks.needSoftvolume()) {
|
if (Hacks.needSoftvolume()) {
|
||||||
|
@ -1070,7 +1105,7 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state == State.OutgoingEarlyMedia) {
|
if (state == State.OutgoingEarlyMedia) {
|
||||||
Compatibility.setAudioManagerInCallMode(mAudioManager);
|
setAudioManagerInCallMode();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state == State.CallReleased || state == State.Error) {
|
if (state == State.CallReleased || state == State.Error) {
|
||||||
|
@ -1150,7 +1185,7 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag
|
||||||
|
|
||||||
public void startEcCalibration(LinphoneCoreListener l) throws LinphoneCoreException {
|
public void startEcCalibration(LinphoneCoreListener l) throws LinphoneCoreException {
|
||||||
routeAudioToSpeaker();
|
routeAudioToSpeaker();
|
||||||
Compatibility.setAudioManagerInCallMode((AudioManager)getContext().getSystemService(Context.AUDIO_SERVICE));
|
setAudioManagerInCallMode();
|
||||||
Log.i("Set audio mode on 'Voice Communication'");
|
Log.i("Set audio mode on 'Voice Communication'");
|
||||||
int oldVolume = mAudioManager.getStreamVolume(STREAM_VOICE_CALL);
|
int oldVolume = mAudioManager.getStreamVolume(STREAM_VOICE_CALL);
|
||||||
int maxVolume = mAudioManager.getStreamMaxVolume(STREAM_VOICE_CALL);
|
int maxVolume = mAudioManager.getStreamMaxVolume(STREAM_VOICE_CALL);
|
||||||
|
@ -1161,7 +1196,7 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag
|
||||||
|
|
||||||
public int startEchoTester() throws LinphoneCoreException {
|
public int startEchoTester() throws LinphoneCoreException {
|
||||||
routeAudioToSpeaker();
|
routeAudioToSpeaker();
|
||||||
Compatibility.setAudioManagerInCallMode((AudioManager)getContext().getSystemService(Context.AUDIO_SERVICE));
|
setAudioManagerInCallMode();
|
||||||
Log.i("Set audio mode on 'Voice Communication'");
|
Log.i("Set audio mode on 'Voice Communication'");
|
||||||
int oldVolume = mAudioManager.getStreamVolume(STREAM_VOICE_CALL);
|
int oldVolume = mAudioManager.getStreamVolume(STREAM_VOICE_CALL);
|
||||||
int maxVolume = mAudioManager.getStreamMaxVolume(STREAM_VOICE_CALL);
|
int maxVolume = mAudioManager.getStreamMaxVolume(STREAM_VOICE_CALL);
|
||||||
|
@ -1368,93 +1403,10 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag
|
||||||
mAudioManager.adjustStreamVolume(LINPHONE_VOLUME_STREAM, i < 0 ? AudioManager.ADJUST_LOWER : AudioManager.ADJUST_RAISE, AudioManager.FLAG_SHOW_UI);
|
mAudioManager.adjustStreamVolume(LINPHONE_VOLUME_STREAM, i < 0 ? AudioManager.ADJUST_LOWER : AudioManager.ADJUST_RAISE, AudioManager.FLAG_SHOW_UI);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Boolean isProximitySensorNearby(final SensorEvent event) {
|
|
||||||
float threshold = 4.001f; // <= 4 cm is near
|
|
||||||
|
|
||||||
final float distanceInCm = event.values[0];
|
|
||||||
final float maxDistance = event.sensor.getMaximumRange();
|
|
||||||
Log.d("Proximity sensor report [",distanceInCm,"] , for max range [",maxDistance,"]");
|
|
||||||
|
|
||||||
if (maxDistance <= threshold) {
|
|
||||||
// Case binary 0/1 and short sensors
|
|
||||||
threshold = maxDistance;
|
|
||||||
}
|
|
||||||
|
|
||||||
return distanceInCm < threshold;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean sLastProximitySensorValueNearby;
|
|
||||||
private static Set<Activity> sProximityDependentActivities = new HashSet<Activity>();
|
|
||||||
private static SensorEventListener sProximitySensorListener = new SensorEventListener() {
|
|
||||||
@Override
|
|
||||||
public void onSensorChanged(SensorEvent event) {
|
|
||||||
if (event.timestamp == 0) return; //just ignoring for nexus 1
|
|
||||||
sLastProximitySensorValueNearby = isProximitySensorNearby(event);
|
|
||||||
proximityNearbyChanged();
|
|
||||||
}
|
|
||||||
@Override
|
|
||||||
public void onAccuracyChanged(Sensor sensor, int accuracy) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
private static void simulateProximitySensorNearby(Activity activity, boolean nearby) {
|
|
||||||
final Window window = activity.getWindow();
|
|
||||||
WindowManager.LayoutParams params = window.getAttributes();
|
|
||||||
View view = ((ViewGroup) window.getDecorView().findViewById(android.R.id.content)).getChildAt(0);
|
|
||||||
if (nearby) {
|
|
||||||
params.screenBrightness = 0.1f;
|
|
||||||
view.setVisibility(View.INVISIBLE);
|
|
||||||
Compatibility.hideNavigationBar(activity);
|
|
||||||
} else {
|
|
||||||
params.screenBrightness = WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE;
|
|
||||||
view.setVisibility(View.VISIBLE);
|
|
||||||
Compatibility.showNavigationBar(activity);
|
|
||||||
}
|
|
||||||
window.setAttributes(params);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void proximityNearbyChanged() {
|
|
||||||
boolean nearby = sLastProximitySensorValueNearby;
|
|
||||||
for (Activity activity : sProximityDependentActivities) {
|
|
||||||
simulateProximitySensorNearby(activity, nearby);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static synchronized void startProximitySensorForActivity(Activity activity) {
|
|
||||||
if (sProximityDependentActivities.contains(activity)) {
|
|
||||||
Log.i("proximity sensor already active for " + activity.getLocalClassName());
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (sProximityDependentActivities.isEmpty()) {
|
|
||||||
SensorManager sm = (SensorManager) activity.getSystemService(Context.SENSOR_SERVICE);
|
|
||||||
Sensor s = sm.getDefaultSensor(Sensor.TYPE_PROXIMITY);
|
|
||||||
if (s != null) {
|
|
||||||
sm.registerListener(sProximitySensorListener,s,SensorManager.SENSOR_DELAY_UI);
|
|
||||||
Log.i("Proximity sensor detected, registering");
|
|
||||||
}
|
|
||||||
} else if (sLastProximitySensorValueNearby){
|
|
||||||
simulateProximitySensorNearby(activity, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
sProximityDependentActivities.add(activity);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static synchronized void stopProximitySensorForActivity(Activity activity) {
|
|
||||||
sProximityDependentActivities.remove(activity);
|
|
||||||
simulateProximitySensorNearby(activity, false);
|
|
||||||
if (sProximityDependentActivities.isEmpty()) {
|
|
||||||
SensorManager sm = (SensorManager) activity.getSystemService(Context.SENSOR_SERVICE);
|
|
||||||
sm.unregisterListener(sProximitySensorListener);
|
|
||||||
sLastProximitySensorValueNearby = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public static synchronized LinphoneCore getLcIfManagerNotDestroyedOrNull() {
|
public static synchronized LinphoneCore getLcIfManagerNotDestroyedOrNull() {
|
||||||
if (sExited || instance == null) {
|
if (sExited || instance == null) {
|
||||||
// Can occur if the UI thread play a posted event but in the meantime the LinphoneManager was destroyed
|
// Can occur if the UI thread play a posted event but in the meantime the LinphoneManager was destroyed
|
||||||
// Ex: stop call and quickly terminate application.
|
// Ex: stop call and quickly terminate application.
|
||||||
Log.w("Trying to get linphone core while LinphoneManager already destroyed or not created");
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
return getLc();
|
return getLc();
|
||||||
|
|
|
@ -114,7 +114,6 @@ public final class LinphoneService extends Service {
|
||||||
private Notification mCustomNotif;
|
private Notification mCustomNotif;
|
||||||
private int mMsgNotifCount;
|
private int mMsgNotifCount;
|
||||||
private PendingIntent mNotifContentIntent;
|
private PendingIntent mNotifContentIntent;
|
||||||
private PendingIntent mkeepAlivePendingIntent;
|
|
||||||
private String mNotificationTitle;
|
private String mNotificationTitle;
|
||||||
private boolean mDisableRegistrationStatus;
|
private boolean mDisableRegistrationStatus;
|
||||||
private LinphoneCoreListenerBase mListener;
|
private LinphoneCoreListenerBase mListener;
|
||||||
|
@ -287,12 +286,11 @@ public final class LinphoneService extends Service {
|
||||||
}
|
}
|
||||||
|
|
||||||
//make sure the application will at least wakes up every 10 mn
|
//make sure the application will at least wakes up every 10 mn
|
||||||
Intent intent = new Intent(this, KeepAliveHandler.class);
|
Intent intent = new Intent(this, KeepAliveReceiver.class);
|
||||||
mkeepAlivePendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
|
PendingIntent keepAlivePendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
|
||||||
((AlarmManager) this.getSystemService(Context.ALARM_SERVICE)).setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP
|
((AlarmManager) this.getSystemService(Context.ALARM_SERVICE)).setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP
|
||||||
, SystemClock.elapsedRealtime()+600000
|
, SystemClock.elapsedRealtime() + 600000
|
||||||
, 600000
|
, keepAlivePendingIntent);
|
||||||
, mkeepAlivePendingIntent);
|
|
||||||
|
|
||||||
mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
|
mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
|
||||||
}
|
}
|
||||||
|
@ -622,6 +620,7 @@ public final class LinphoneService extends Service {
|
||||||
}
|
}
|
||||||
|
|
||||||
instance = null;
|
instance = null;
|
||||||
|
getContentResolver().unregisterContentObserver(ContactsManager.getInstance());
|
||||||
LinphoneManager.destroy();
|
LinphoneManager.destroy();
|
||||||
|
|
||||||
// Make sure our notification is gone.
|
// Make sure our notification is gone.
|
||||||
|
@ -629,8 +628,6 @@ public final class LinphoneService extends Service {
|
||||||
mNM.cancel(INCALL_NOTIF_ID);
|
mNM.cancel(INCALL_NOTIF_ID);
|
||||||
mNM.cancel(MESSAGE_NOTIF_ID);
|
mNM.cancel(MESSAGE_NOTIF_ID);
|
||||||
|
|
||||||
((AlarmManager) this.getSystemService(Context.ALARM_SERVICE)).cancel(mkeepAlivePendingIntent);
|
|
||||||
getContentResolver().unregisterContentObserver(ContactsManager.getInstance());
|
|
||||||
super.onDestroy();
|
super.onDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -431,7 +431,7 @@ public final class LinphoneUtils {
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
p = Runtime.getRuntime().exec(new String[] { "logcat", "-d", "|", "grep", "`adb shell ps | grep org.linphone | cut -c10-15`" });
|
p = Runtime.getRuntime().exec(new String[] { "logcat", "-d", "|", "grep", "`adb shell ps | grep " + context.getPackageName() + " | cut -c10-15`" });
|
||||||
br = new BufferedReader(new InputStreamReader(p.getInputStream()), 2048);
|
br = new BufferedReader(new InputStreamReader(p.getInputStream()), 2048);
|
||||||
|
|
||||||
String line;
|
String line;
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
package org.linphone;
|
|
||||||
|
|
||||||
public class OpenGLESDisplay {
|
|
||||||
public static native void init(int ptr, int width, int height);
|
|
||||||
public static native void render(int ptr);
|
|
||||||
}
|
|
|
@ -35,8 +35,8 @@ import org.linphone.core.PayloadType;
|
||||||
import org.linphone.mediastream.Log;
|
import org.linphone.mediastream.Log;
|
||||||
import org.linphone.mediastream.Version;
|
import org.linphone.mediastream.Version;
|
||||||
import org.linphone.mediastream.video.capture.hwconf.AndroidCameraConfiguration;
|
import org.linphone.mediastream.video.capture.hwconf.AndroidCameraConfiguration;
|
||||||
import org.linphone.tools.OpenH264DownloadHelper;
|
|
||||||
import org.linphone.purchase.InAppPurchaseActivity;
|
import org.linphone.purchase.InAppPurchaseActivity;
|
||||||
|
import org.linphone.tools.OpenH264DownloadHelper;
|
||||||
import org.linphone.ui.LedPreference;
|
import org.linphone.ui.LedPreference;
|
||||||
import org.linphone.ui.PreferencesListFragment;
|
import org.linphone.ui.PreferencesListFragment;
|
||||||
|
|
||||||
|
@ -44,11 +44,14 @@ import android.app.AlertDialog;
|
||||||
import android.app.FragmentManager;
|
import android.app.FragmentManager;
|
||||||
import android.content.DialogInterface;
|
import android.content.DialogInterface;
|
||||||
import android.Manifest;
|
import android.Manifest;
|
||||||
|
import android.app.AlertDialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.preference.CheckBoxPreference;
|
import android.preference.CheckBoxPreference;
|
||||||
|
@ -59,6 +62,7 @@ import android.preference.Preference.OnPreferenceChangeListener;
|
||||||
import android.preference.Preference.OnPreferenceClickListener;
|
import android.preference.Preference.OnPreferenceClickListener;
|
||||||
import android.preference.PreferenceCategory;
|
import android.preference.PreferenceCategory;
|
||||||
import android.preference.PreferenceScreen;
|
import android.preference.PreferenceScreen;
|
||||||
|
import android.provider.Settings;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Sylvain Berfini
|
* @author Sylvain Berfini
|
||||||
|
@ -713,7 +717,7 @@ public class SettingsFragment extends PreferencesListFragment {
|
||||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||||
boolean enable = (Boolean) newValue;
|
boolean enable = (Boolean) newValue;
|
||||||
try {
|
try {
|
||||||
if (enable && Version.getCpuAbis().contains("armeabi-v7a") && !Version.getCpuAbis().contains("x86")
|
if (enable && Version.getCpuAbis().contains("armeabi-v7a") && !Version.getCpuAbis().contains("x86")
|
||||||
&& pt.getMime().equals("H264") && !mCodecDownloader.isCodecFound()) {
|
&& pt.getMime().equals("H264") && !mCodecDownloader.isCodecFound()) {
|
||||||
mCodecDownloader.setOpenH264HelperListener(LinphoneManager.getInstance().getOpenH264HelperListener());
|
mCodecDownloader.setOpenH264HelperListener(LinphoneManager.getInstance().getOpenH264HelperListener());
|
||||||
mCodecDownloader.setUserData(0,LinphoneManager.getInstance().getContext());
|
mCodecDownloader.setUserData(0,LinphoneManager.getInstance().getContext());
|
||||||
|
@ -721,18 +725,17 @@ public class SettingsFragment extends PreferencesListFragment {
|
||||||
|
|
||||||
AlertDialog.Builder builder = new AlertDialog.Builder(LinphoneManager.getInstance().getContext());
|
AlertDialog.Builder builder = new AlertDialog.Builder(LinphoneManager.getInstance().getContext());
|
||||||
builder.setCancelable(false);
|
builder.setCancelable(false);
|
||||||
AlertDialog.Builder show = builder.setMessage("Do you agree to download "
|
builder.setMessage("Do you agree to download " + mCodecDownloader.getLicenseMessage()).setPositiveButton("Yes", new DialogInterface.OnClickListener() {
|
||||||
+ mCodecDownloader.getLicenseMessage()).setPositiveButton("Yes", new DialogInterface.OnClickListener(){
|
|
||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
if (which == DialogInterface.BUTTON_POSITIVE)
|
if (which == DialogInterface.BUTTON_POSITIVE)
|
||||||
mCodecDownloader.downloadCodec();
|
mCodecDownloader.downloadCodec();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
builder.setNegativeButton("No", new DialogInterface.OnClickListener(){
|
builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
if (which == DialogInterface.BUTTON_NEGATIVE){
|
if (which == DialogInterface.BUTTON_NEGATIVE) {
|
||||||
// Disable H264
|
// Disable H264
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1025,7 +1028,6 @@ public class SettingsFragment extends PreferencesListFragment {
|
||||||
// Disable UPnP if ICE si enabled, or disable ICE if UPnP is enabled
|
// Disable UPnP if ICE si enabled, or disable ICE if UPnP is enabled
|
||||||
CheckBoxPreference ice = (CheckBoxPreference) findPreference(getString(R.string.pref_ice_enable_key));
|
CheckBoxPreference ice = (CheckBoxPreference) findPreference(getString(R.string.pref_ice_enable_key));
|
||||||
CheckBoxPreference turn = (CheckBoxPreference) findPreference(getString(R.string.pref_turn_enable_key));
|
CheckBoxPreference turn = (CheckBoxPreference) findPreference(getString(R.string.pref_turn_enable_key));
|
||||||
CheckBoxPreference upnp = (CheckBoxPreference) findPreference(getString(R.string.pref_upnp_enable_key));
|
|
||||||
ice.setChecked(mPrefs.isIceEnabled());
|
ice.setChecked(mPrefs.isIceEnabled());
|
||||||
turn.setChecked(mPrefs.isTurnEnabled());
|
turn.setChecked(mPrefs.isTurnEnabled());
|
||||||
|
|
||||||
|
@ -1067,8 +1069,6 @@ public class SettingsFragment extends PreferencesListFragment {
|
||||||
findPreference(getString(R.string.pref_ice_enable_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
|
findPreference(getString(R.string.pref_ice_enable_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||||
CheckBoxPreference upnp = (CheckBoxPreference) findPreference(getString(R.string.pref_upnp_enable_key));
|
|
||||||
boolean value = (Boolean) newValue;
|
|
||||||
mPrefs.setIceEnabled((Boolean) newValue);
|
mPrefs.setIceEnabled((Boolean) newValue);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1077,8 +1077,6 @@ public class SettingsFragment extends PreferencesListFragment {
|
||||||
findPreference(getString(R.string.pref_turn_enable_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
|
findPreference(getString(R.string.pref_turn_enable_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||||
CheckBoxPreference upnp = (CheckBoxPreference) findPreference(getString(R.string.pref_upnp_enable_key));
|
|
||||||
boolean value = (Boolean) newValue;
|
|
||||||
mPrefs.setTurnEnabled((Boolean) newValue);
|
mPrefs.setTurnEnabled((Boolean) newValue);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -1087,7 +1085,6 @@ public class SettingsFragment extends PreferencesListFragment {
|
||||||
findPreference(getString(R.string.pref_upnp_enable_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
|
findPreference(getString(R.string.pref_upnp_enable_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||||
CheckBoxPreference ice = (CheckBoxPreference) findPreference(getString(R.string.pref_ice_enable_key));
|
|
||||||
boolean value = (Boolean) newValue;
|
boolean value = (Boolean) newValue;
|
||||||
mPrefs.setUpnpEnabled(value);
|
mPrefs.setUpnpEnabled(value);
|
||||||
return true;
|
return true;
|
||||||
|
@ -1197,6 +1194,24 @@ public class SettingsFragment extends PreferencesListFragment {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
findPreference(getString(R.string.pref_android_app_settings_key)).setOnPreferenceClickListener(new OnPreferenceClickListener() {
|
||||||
|
@Override
|
||||||
|
public boolean onPreferenceClick(Preference preference) {
|
||||||
|
synchronized (SettingsFragment.this) {
|
||||||
|
Context context = SettingsFragment.this.getActivity();
|
||||||
|
Intent i = new Intent();
|
||||||
|
i.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
|
||||||
|
i.addCategory(Intent.CATEGORY_DEFAULT);
|
||||||
|
i.setData(Uri.parse("package:" + context.getPackageName()));
|
||||||
|
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||||
|
i.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
|
||||||
|
i.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
|
||||||
|
context.startActivity(i);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
findPreference(getString(R.string.pref_display_name_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
|
findPreference(getString(R.string.pref_display_name_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -19,6 +19,13 @@ along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import org.linphone.LinphoneManager;
|
||||||
|
import org.linphone.R;
|
||||||
|
import org.linphone.core.LinphoneCoreException;
|
||||||
|
import org.linphone.core.OpenH264DownloadHelperListener;
|
||||||
|
import org.linphone.core.PayloadType;
|
||||||
|
import org.linphone.tools.OpenH264DownloadHelper;
|
||||||
|
|
||||||
import android.app.Fragment;
|
import android.app.Fragment;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
|
@ -29,15 +36,6 @@ import android.widget.Button;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
|
|
||||||
import org.linphone.LinphoneActivity;
|
|
||||||
import org.linphone.LinphoneManager;
|
|
||||||
import org.linphone.R;
|
|
||||||
import org.linphone.core.LinphoneCoreFactory;
|
|
||||||
import org.linphone.core.OpenH264DownloadHelperListener;
|
|
||||||
import org.linphone.core.LinphoneCoreException;
|
|
||||||
import org.linphone.core.PayloadType;
|
|
||||||
import org.linphone.tools.OpenH264DownloadHelper;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Erwan CROZE
|
* @author Erwan CROZE
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -18,11 +18,11 @@ along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
import org.linphone.R;
|
import org.linphone.R;
|
||||||
|
import org.linphone.compatibility.Compatibility;
|
||||||
|
|
||||||
import android.app.Fragment;
|
import android.app.Fragment;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.text.Html;
|
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
import android.text.method.LinkMovementMethod;
|
import android.text.method.LinkMovementMethod;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
@ -53,7 +53,7 @@ public class LinphoneLoginFragment extends Fragment implements OnClickListener,
|
||||||
password = (EditText) view.findViewById(R.id.assistant_password);
|
password = (EditText) view.findViewById(R.id.assistant_password);
|
||||||
password.addTextChangedListener(this);
|
password.addTextChangedListener(this);
|
||||||
forgotPassword = (TextView) view.findViewById(R.id.forgot_password);
|
forgotPassword = (TextView) view.findViewById(R.id.forgot_password);
|
||||||
forgotPassword.setText(Html.fromHtml("<a href=\"" + url + "\"'>"+ getString(R.string.forgot_password) + "</a>"));
|
forgotPassword.setText(Compatibility.fromHtml("<a href=\"" + url + "\"'>"+ getString(R.string.forgot_password) + "</a>"));
|
||||||
forgotPassword.setMovementMethod(LinkMovementMethod.getInstance());
|
forgotPassword.setMovementMethod(LinkMovementMethod.getInstance());
|
||||||
displayName = (EditText) view.findViewById(R.id.assistant_display_name);
|
displayName = (EditText) view.findViewById(R.id.assistant_display_name);
|
||||||
apply = (Button) view.findViewById(R.id.assistant_apply);
|
apply = (Button) view.findViewById(R.id.assistant_apply);
|
||||||
|
|
|
@ -1,68 +0,0 @@
|
||||||
package org.linphone.compatibility;
|
|
||||||
|
|
||||||
import org.linphone.LinphonePreferences;
|
|
||||||
import org.linphone.R;
|
|
||||||
import org.linphone.mediastream.Log;
|
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.media.AudioManager;
|
|
||||||
|
|
||||||
/*
|
|
||||||
ApiEightPlus.java
|
|
||||||
Copyright (C) 2012 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @author Sylvain Berfini
|
|
||||||
*/
|
|
||||||
|
|
||||||
@TargetApi(8)
|
|
||||||
public class ApiEightPlus {
|
|
||||||
|
|
||||||
public static void initPushNotificationService(Context context) {
|
|
||||||
try {
|
|
||||||
Class<?> GCMRegistrar = Class.forName("com.google.android.gcm.GCMRegistrar");
|
|
||||||
// Starting the push notification service
|
|
||||||
GCMRegistrar.getMethod("checkDevice", Context.class).invoke(null, context);
|
|
||||||
try {
|
|
||||||
GCMRegistrar.getMethod("checkManifest", Context.class).invoke(null, context);
|
|
||||||
} catch (IllegalStateException e){
|
|
||||||
Log.e("Push notification: No receiver found",e);
|
|
||||||
}
|
|
||||||
final String regId = (String)GCMRegistrar.getMethod("getRegistrationId", Context.class).invoke(null, context);
|
|
||||||
String newPushSenderID = context.getString(R.string.push_sender_id);
|
|
||||||
String currentPushSenderID = LinphonePreferences.instance().getPushNotificationRegistrationID();
|
|
||||||
if (regId.equals("") || currentPushSenderID == null || !currentPushSenderID.equals(newPushSenderID)) {
|
|
||||||
GCMRegistrar.getMethod("register", Context.class, String[].class).invoke(null, context, new String[]{newPushSenderID});
|
|
||||||
Log.d("Push Notification: storing current sender id = " + newPushSenderID);
|
|
||||||
} else {
|
|
||||||
Log.d("Push Notification: already registered with id = " + regId);
|
|
||||||
LinphonePreferences.instance().setPushNotificationRegistrationID(regId);
|
|
||||||
}
|
|
||||||
} catch (java.lang.UnsupportedOperationException e) {
|
|
||||||
Log.i("Push Notification: not activated");
|
|
||||||
} catch (Exception e1) {
|
|
||||||
//assume the jar is not provided
|
|
||||||
Log.i("Push Notification: assuming GCM jar is not provided.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
public static String getAudioManagerEventForBluetoothConnectionStateChangedEvent() {
|
|
||||||
return AudioManager.ACTION_SCO_AUDIO_STATE_CHANGED;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,19 +3,15 @@ package org.linphone.compatibility;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import org.linphone.R;
|
import org.linphone.R;
|
||||||
import org.linphone.mediastream.Log;
|
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.content.ClipData;
|
|
||||||
import android.content.ClipboardManager;
|
|
||||||
import android.content.ContentUris;
|
import android.content.ContentUris;
|
||||||
import android.content.ContentValues;
|
import android.content.ContentValues;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.media.AudioManager;
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.provider.ContactsContract;
|
import android.provider.ContactsContract;
|
||||||
import android.provider.ContactsContract.CommonDataKinds.SipAddress;
|
import android.provider.ContactsContract.CommonDataKinds.SipAddress;
|
||||||
|
@ -119,21 +115,6 @@ public class ApiElevenPlus {
|
||||||
|
|
||||||
return notif;
|
return notif;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void copyTextToClipboard(Context context, String msg) {
|
|
||||||
ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
|
|
||||||
ClipData clip = android.content.ClipData.newPlainText("Message", msg);
|
|
||||||
clipboard.setPrimaryClip(clip);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setAudioManagerInCallMode(AudioManager manager) {
|
|
||||||
if (manager.getMode() == AudioManager.MODE_IN_COMMUNICATION) {
|
|
||||||
Log.w("---AudioManager: already in MODE_IN_COMMUNICATION, skipping...");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Log.d("---AudioManager: set mode to MODE_IN_COMMUNICATION");
|
|
||||||
manager.setMode(AudioManager.MODE_IN_COMMUNICATION);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Intent prepareAddContactIntent(String displayName, String sipUri) {
|
public static Intent prepareAddContactIntent(String displayName, String sipUri) {
|
||||||
Intent intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI);
|
Intent intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI);
|
||||||
|
|
|
@ -1,406 +0,0 @@
|
||||||
package org.linphone.compatibility;
|
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.linphone.LinphoneContact;
|
|
||||||
import org.linphone.R;
|
|
||||||
import org.linphone.core.LinphoneAddress;
|
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.Notification;
|
|
||||||
import android.app.PendingIntent;
|
|
||||||
import android.content.ContentProviderOperation;
|
|
||||||
import android.content.ContentResolver;
|
|
||||||
import android.content.ContentUris;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.database.Cursor;
|
|
||||||
import android.database.MatrixCursor;
|
|
||||||
import android.media.AudioManager;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.preference.CheckBoxPreference;
|
|
||||||
import android.preference.Preference;
|
|
||||||
import android.provider.ContactsContract;
|
|
||||||
import android.provider.ContactsContract.CommonDataKinds;
|
|
||||||
import android.provider.ContactsContract.CommonDataKinds.Phone;
|
|
||||||
import android.provider.ContactsContract.Contacts;
|
|
||||||
import android.provider.ContactsContract.Data;
|
|
||||||
import android.support.v4.app.NotificationCompat;
|
|
||||||
import android.text.ClipboardManager;
|
|
||||||
import android.text.TextUtils;
|
|
||||||
import android.view.ViewTreeObserver;
|
|
||||||
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
|
|
||||||
|
|
||||||
/*
|
|
||||||
ApiFivePlus.java
|
|
||||||
Copyright (C) 2012 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.
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @author Sylvain Berfini
|
|
||||||
*/
|
|
||||||
@SuppressWarnings("deprecation")
|
|
||||||
@TargetApi(5)
|
|
||||||
public class ApiFivePlus {
|
|
||||||
public static void overridePendingTransition(Activity activity, int idAnimIn, int idAnimOut) {
|
|
||||||
activity.overridePendingTransition(idAnimIn, idAnimOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Intent prepareAddContactIntent(String displayName, String sipUri) {
|
|
||||||
Intent intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI);
|
|
||||||
intent.putExtra(ContactsContract.Intents.Insert.NAME, displayName);
|
|
||||||
|
|
||||||
// VoIP field not available, we store the address in the IM field
|
|
||||||
intent.putExtra(ContactsContract.Intents.Insert.IM_HANDLE, sipUri);
|
|
||||||
intent.putExtra(ContactsContract.Intents.Insert.IM_PROTOCOL, "sip");
|
|
||||||
|
|
||||||
return intent;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Intent prepareEditContactIntent(int id) {
|
|
||||||
Intent intent = new Intent(Intent.ACTION_EDIT, Contacts.CONTENT_URI);
|
|
||||||
Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, id);
|
|
||||||
intent.setData(contactUri);
|
|
||||||
|
|
||||||
return intent;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Intent prepareEditContactIntentWithSipAddress(int id, String sipUri) {
|
|
||||||
Intent intent = new Intent(Intent.ACTION_EDIT, Contacts.CONTENT_URI);
|
|
||||||
Uri contactUri = ContentUris.withAppendedId(Contacts.CONTENT_URI, id);
|
|
||||||
intent.setData(contactUri);
|
|
||||||
|
|
||||||
// VoIP field not available, we store the address in the IM field
|
|
||||||
intent.putExtra(ContactsContract.Intents.Insert.IM_HANDLE, sipUri);
|
|
||||||
intent.putExtra(ContactsContract.Intents.Insert.IM_PROTOCOL, "sip");
|
|
||||||
|
|
||||||
return intent;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<String> extractContactNumbersAndAddresses(String id, ContentResolver cr) {
|
|
||||||
List<String> list = new ArrayList<String>();
|
|
||||||
|
|
||||||
Uri uri = Data.CONTENT_URI;
|
|
||||||
String[] projection = {ContactsContract.CommonDataKinds.Im.DATA};
|
|
||||||
|
|
||||||
// IM addresses
|
|
||||||
String selection = new StringBuilder()
|
|
||||||
.append(Data.CONTACT_ID).append(" = ? AND ")
|
|
||||||
.append(Data.MIMETYPE).append(" = '")
|
|
||||||
.append(ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE)
|
|
||||||
.append("' AND lower(")
|
|
||||||
.append(ContactsContract.CommonDataKinds.Im.CUSTOM_PROTOCOL)
|
|
||||||
.append(") = 'sip'")
|
|
||||||
.toString();
|
|
||||||
Cursor c = cr.query(uri, projection, selection, new String[]{id}, null);
|
|
||||||
if (c != null) {
|
|
||||||
int nbId = c.getColumnIndex(ContactsContract.CommonDataKinds.Im.DATA);
|
|
||||||
while (c.moveToNext()) {
|
|
||||||
list.add("sip:" + c.getString(nbId));
|
|
||||||
}
|
|
||||||
c.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Phone Numbers
|
|
||||||
c = cr.query(Phone.CONTENT_URI, new String[]{Phone.NUMBER}, Phone.CONTACT_ID + " = " + id, null, null);
|
|
||||||
if (c != null) {
|
|
||||||
while (c.moveToNext()) {
|
|
||||||
String number = c.getString(c.getColumnIndex(Phone.NUMBER));
|
|
||||||
list.add(number);
|
|
||||||
}
|
|
||||||
c.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Cursor getContactsCursor(ContentResolver cr, List<String> ids) {
|
|
||||||
String req = Data.MIMETYPE + " = '" + CommonDataKinds.Phone.CONTENT_ITEM_TYPE
|
|
||||||
+ "' AND " + CommonDataKinds.Phone.NUMBER + " IS NOT NULL";
|
|
||||||
|
|
||||||
req += " OR (" + Contacts.Data.MIMETYPE + " = '" + CommonDataKinds.Im.CONTENT_ITEM_TYPE
|
|
||||||
+ "' AND lower(" + CommonDataKinds.Im.CUSTOM_PROTOCOL + ") = 'sip')";
|
|
||||||
|
|
||||||
if(ids != null){
|
|
||||||
String s = TextUtils.join(",", ids);
|
|
||||||
req += " OR (" + Data.CONTACT_ID + " IN (" + s + "))";
|
|
||||||
}
|
|
||||||
|
|
||||||
return getGeneralContactCursor(cr, req, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Cursor getSIPContactsCursor(ContentResolver cr, List<String> ids) {
|
|
||||||
String req = null;
|
|
||||||
req = Contacts.Data.MIMETYPE + " = '" + CommonDataKinds.Im.CONTENT_ITEM_TYPE
|
|
||||||
+ "' AND lower(" + CommonDataKinds.Im.CUSTOM_PROTOCOL + ") = 'sip'";
|
|
||||||
|
|
||||||
if(ids != null){
|
|
||||||
String s = TextUtils.join(",", ids);
|
|
||||||
req += " OR (" + Data.CONTACT_ID + " IN (" + s + "))";
|
|
||||||
}
|
|
||||||
|
|
||||||
return getGeneralContactCursor(cr, req, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Cursor getSIPContactCursor(ContentResolver cr, String id) {
|
|
||||||
String req = null;
|
|
||||||
req = Contacts.Data.MIMETYPE + " = '" + CommonDataKinds.Im.CONTENT_ITEM_TYPE
|
|
||||||
+ " AND lower(" + CommonDataKinds.Im.CUSTOM_PROTOCOL + ") = 'sip' AND "
|
|
||||||
+ android.provider.ContactsContract.CommonDataKinds.Im.DATA + " LIKE '" + id + "'";
|
|
||||||
|
|
||||||
return getGeneralContactCursor(cr, req, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Cursor getGeneralContactCursor(ContentResolver cr, String select, boolean shouldGroupBy) {
|
|
||||||
String[] projection = new String[] { Data.CONTACT_ID, Data.DISPLAY_NAME };
|
|
||||||
String query;
|
|
||||||
|
|
||||||
query = Data.DISPLAY_NAME + " IS NOT NULL AND (" + select + ")";
|
|
||||||
|
|
||||||
Cursor cursor = cr.query(Data.CONTENT_URI, projection, query, null, " lower(" + Data.DISPLAY_NAME + ") COLLATE UNICODE ASC");
|
|
||||||
|
|
||||||
if (!shouldGroupBy || cursor == null) {
|
|
||||||
return cursor;
|
|
||||||
}
|
|
||||||
|
|
||||||
MatrixCursor result = new MatrixCursor(cursor.getColumnNames());
|
|
||||||
Set<String> groupBy = new HashSet<String>();
|
|
||||||
while (cursor.moveToNext()) {
|
|
||||||
String name = cursor.getString(getCursorDisplayNameColumnIndex(cursor));
|
|
||||||
if (!groupBy.contains(name)) {
|
|
||||||
groupBy.add(name);
|
|
||||||
Object[] newRow = new Object[cursor.getColumnCount()];
|
|
||||||
|
|
||||||
int contactID = cursor.getColumnIndex(Data.CONTACT_ID);
|
|
||||||
int displayName = cursor.getColumnIndex(Data.DISPLAY_NAME);
|
|
||||||
|
|
||||||
newRow[contactID] = cursor.getString(contactID);
|
|
||||||
newRow[displayName] = cursor.getString(displayName);
|
|
||||||
|
|
||||||
result.addRow(newRow);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cursor.close();
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getCursorDisplayNameColumnIndex(Cursor cursor) {
|
|
||||||
return cursor.getColumnIndex(Data.DISPLAY_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static LinphoneContact getContact(ContentResolver cr, Cursor cursor, int position) {
|
|
||||||
try {
|
|
||||||
if(cursor != null) {
|
|
||||||
cursor.moveToFirst();
|
|
||||||
boolean success = cursor.move(position);
|
|
||||||
if (!success)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
String id = cursor.getString(cursor.getColumnIndex(Data.CONTACT_ID));
|
|
||||||
String name = getContactDisplayName(cursor);
|
|
||||||
Uri thumbnail = getContactPictureUri(id);
|
|
||||||
Uri photo = getContactPhotoUri(id);
|
|
||||||
InputStream input = getContactPictureInputStream(cr, id);
|
|
||||||
|
|
||||||
LinphoneContact contact = new LinphoneContact();
|
|
||||||
contact.setAndroidId(id);
|
|
||||||
contact.setFullName(name);
|
|
||||||
if (input != null) {
|
|
||||||
contact.setPhotoUri(photo);
|
|
||||||
contact.setThumbnailUri(thumbnail);
|
|
||||||
}
|
|
||||||
|
|
||||||
return contact;
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
} catch (Exception e) {
|
|
||||||
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static InputStream getContactPictureInputStream(ContentResolver cr, String id) {
|
|
||||||
Uri person = ContentUris.withAppendedId(Contacts.CONTENT_URI, Long.parseLong(id));
|
|
||||||
return Contacts.openContactPhotoInputStream(cr, person);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String getContactDisplayName(Cursor cursor) {
|
|
||||||
return cursor.getString(cursor.getColumnIndex(Data.DISPLAY_NAME));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Uri getContactPictureUri(String id) {
|
|
||||||
Uri person = ContentUris.withAppendedId(Contacts.CONTENT_URI, Long.parseLong(id));
|
|
||||||
return Uri.withAppendedPath(person, Contacts.Photo.CONTENT_DIRECTORY);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Uri getContactPhotoUri(String id) {
|
|
||||||
Uri person = ContentUris.withAppendedId(Contacts.CONTENT_URI, Long.parseLong(id));
|
|
||||||
return Uri.withAppendedPath(person, Contacts.Photo.DISPLAY_PHOTO);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Uri findUriPictureOfContactAndSetDisplayName(LinphoneAddress address, ContentResolver cr) {
|
|
||||||
String username = address.getUserName();
|
|
||||||
String domain = address.getDomain();
|
|
||||||
String sipUri = username + "@" + domain;
|
|
||||||
|
|
||||||
Cursor cursor = getSIPContactCursor(cr, sipUri);
|
|
||||||
if(cursor != null) {
|
|
||||||
LinphoneContact contact = getContact(cr, cursor, 0);
|
|
||||||
if (contact != null && contact.getNumbersOrAddresses().contains(sipUri)) {
|
|
||||||
address.setDisplayName(contact.getFullName());
|
|
||||||
cursor.close();
|
|
||||||
return contact.getPhotoUri();
|
|
||||||
}
|
|
||||||
cursor.close();
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String refreshContactName(ContentResolver cr, String id) {
|
|
||||||
Cursor cursor = getGeneralContactCursor(cr, Data.CONTACT_ID + " = '" + id + "'", false);
|
|
||||||
if (cursor != null && cursor.moveToFirst()) {
|
|
||||||
String contactDisplayName = getContactDisplayName(cursor);
|
|
||||||
cursor.close();
|
|
||||||
return contactDisplayName;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Notification createMessageNotification(Context context, String title, String msg, PendingIntent intent) {
|
|
||||||
Notification notif = new Notification();
|
|
||||||
notif.icon = R.drawable.topbar_chat_notification;
|
|
||||||
notif.iconLevel = 0;
|
|
||||||
notif.when = System.currentTimeMillis();
|
|
||||||
notif.flags &= Notification.FLAG_ONGOING_EVENT;
|
|
||||||
|
|
||||||
notif.defaults |= Notification.DEFAULT_VIBRATE;
|
|
||||||
notif.defaults |= Notification.DEFAULT_SOUND;
|
|
||||||
notif.defaults |= Notification.DEFAULT_LIGHTS;
|
|
||||||
|
|
||||||
return notif;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Notification createInCallNotification(Context context, String title, String msg, int iconID, PendingIntent intent) {
|
|
||||||
NotificationCompat.Builder notifBuilder = new NotificationCompat.Builder(context)
|
|
||||||
.setSmallIcon(iconID)
|
|
||||||
.setContentTitle(title)
|
|
||||||
.setContentText(msg)
|
|
||||||
.setContentIntent(intent);
|
|
||||||
|
|
||||||
return notifBuilder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setPreferenceChecked(Preference preference, boolean checked) {
|
|
||||||
((CheckBoxPreference) preference).setChecked(checked);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isPreferenceChecked(Preference preference) {
|
|
||||||
return ((CheckBoxPreference) preference).isChecked();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void copyTextToClipboard(Context context, String msg) {
|
|
||||||
ClipboardManager clipboard = (ClipboardManager) context.getSystemService(Context.CLIPBOARD_SERVICE);
|
|
||||||
clipboard.setText(msg);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void addSipAddressToContact(Context context, ArrayList<ContentProviderOperation> ops, String sipAddress) {
|
|
||||||
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
|
||||||
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
|
|
||||||
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE)
|
|
||||||
.withValue(ContactsContract.CommonDataKinds.Im.DATA, sipAddress)
|
|
||||||
.withValue(ContactsContract.CommonDataKinds.Im.TYPE, ContactsContract.CommonDataKinds.Im.TYPE_CUSTOM)
|
|
||||||
.withValue(ContactsContract.CommonDataKinds.Im.LABEL, context.getString(R.string.addressbook_label))
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void addSipAddressToContact(Context context, ArrayList<ContentProviderOperation> ops, String sipAddress, String rawContactID) {
|
|
||||||
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
|
||||||
.withValue(ContactsContract.Data.RAW_CONTACT_ID, rawContactID)
|
|
||||||
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE)
|
|
||||||
.withValue(ContactsContract.CommonDataKinds.Im.DATA, sipAddress)
|
|
||||||
.withValue(ContactsContract.CommonDataKinds.Im.TYPE, ContactsContract.CommonDataKinds.Im.TYPE_CUSTOM)
|
|
||||||
.withValue(ContactsContract.CommonDataKinds.Im.LABEL, context.getString(R.string.addressbook_label))
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void updateSipAddressForContact(ArrayList<ContentProviderOperation> ops, String oldSipAddress, String newSipAddress, String contactID) {
|
|
||||||
String select = ContactsContract.Data.CONTACT_ID + "=? AND "
|
|
||||||
+ ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE + "' AND "
|
|
||||||
+ ContactsContract.CommonDataKinds.Im.DATA + "=?";
|
|
||||||
String[] args = new String[] { String.valueOf(contactID), oldSipAddress };
|
|
||||||
|
|
||||||
ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
|
|
||||||
.withSelection(select, args)
|
|
||||||
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE)
|
|
||||||
.withValue(ContactsContract.CommonDataKinds.Im.DATA, newSipAddress)
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void deleteSipAddressFromContact(ArrayList<ContentProviderOperation> ops, String oldSipAddress, String contactID) {
|
|
||||||
String select = ContactsContract.Data.CONTACT_ID + "=? AND "
|
|
||||||
+ ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.Im.CONTENT_ITEM_TYPE + "' AND "
|
|
||||||
+ ContactsContract.CommonDataKinds.Im.DATA + "=?";
|
|
||||||
String[] args = new String[] { String.valueOf(contactID), oldSipAddress };
|
|
||||||
|
|
||||||
ops.add(ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI)
|
|
||||||
.withSelection(select, args)
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void removeGlobalLayoutListener(ViewTreeObserver viewTreeObserver, OnGlobalLayoutListener keyboardListener) {
|
|
||||||
viewTreeObserver.removeGlobalOnLayoutListener(keyboardListener);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setAudioManagerInCallMode(AudioManager manager) {
|
|
||||||
/* Do not use MODE_IN_CALL, because it is reserved to GSM. This is causing conflicts on audio system resulting in silenced audio.*/
|
|
||||||
//manager.setMode(AudioManager.MODE_IN_CALL);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Notification createNotification(Context context, String title, String message, int icon, int level, PendingIntent intent, boolean isOngoingEvent) {
|
|
||||||
NotificationCompat.Builder notifBuilder = new NotificationCompat.Builder(context)
|
|
||||||
.setSmallIcon(icon, level)
|
|
||||||
.setContentTitle(title)
|
|
||||||
.setContentText(message)
|
|
||||||
.setContentIntent(intent);
|
|
||||||
|
|
||||||
return notifBuilder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Notification createSimpleNotification(Context context, String title, String text, PendingIntent intent) {
|
|
||||||
NotificationCompat.Builder notifBuilder = new NotificationCompat.Builder(context)
|
|
||||||
.setSmallIcon(R.drawable.linphone_logo)
|
|
||||||
.setContentTitle(title)
|
|
||||||
.setContentText(text)
|
|
||||||
.setContentIntent(intent);
|
|
||||||
|
|
||||||
Notification notif = notifBuilder.build();
|
|
||||||
notif.defaults |= Notification.DEFAULT_VIBRATE;
|
|
||||||
notif.defaults |= Notification.DEFAULT_SOUND;
|
|
||||||
notif.defaults |= Notification.DEFAULT_LIGHTS;
|
|
||||||
|
|
||||||
return notif;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
package org.linphone.compatibility;
|
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.media.AudioManager;
|
|
||||||
import android.preference.Preference;
|
|
||||||
import android.preference.TwoStatePreference;
|
|
||||||
import android.view.View;
|
|
||||||
|
|
||||||
/*
|
|
||||||
ApiFourteenPlus.java
|
|
||||||
Copyright (C) 2012 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.
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @author Sylvain Berfini
|
|
||||||
*/
|
|
||||||
@TargetApi(14)
|
|
||||||
public class ApiFourteenPlus {
|
|
||||||
|
|
||||||
public static void setPreferenceChecked(Preference preference, boolean checked) {
|
|
||||||
((TwoStatePreference) preference).setChecked(checked);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isPreferenceChecked(Preference preference) {
|
|
||||||
return ((TwoStatePreference) preference).isChecked();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void hideNavigationBar(Activity activity) {
|
|
||||||
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void showNavigationBar(Activity activity) {
|
|
||||||
activity.getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getAudioManagerEventForBluetoothConnectionStateChangedEvent() {
|
|
||||||
return AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,195 +0,0 @@
|
||||||
package org.linphone.compatibility;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.linphone.LinphoneContact;
|
|
||||||
import org.linphone.R;
|
|
||||||
import org.linphone.core.LinphoneAddress;
|
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
|
||||||
import android.content.ContentProviderOperation;
|
|
||||||
import android.content.ContentResolver;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.database.Cursor;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.provider.ContactsContract;
|
|
||||||
import android.provider.ContactsContract.CommonDataKinds;
|
|
||||||
import android.provider.ContactsContract.CommonDataKinds.Phone;
|
|
||||||
import android.provider.ContactsContract.Contacts;
|
|
||||||
import android.provider.ContactsContract.Data;
|
|
||||||
import android.text.TextUtils;
|
|
||||||
|
|
||||||
/*
|
|
||||||
ApiNinePlus.java
|
|
||||||
Copyright (C) 2012 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.
|
|
||||||
*/
|
|
||||||
/**
|
|
||||||
* @author Sylvain Berfini
|
|
||||||
*/
|
|
||||||
@TargetApi(9)
|
|
||||||
public class ApiNinePlus {
|
|
||||||
|
|
||||||
public static void addSipAddressToContact(Context context, ArrayList<ContentProviderOperation> ops, String sipAddress) {
|
|
||||||
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
|
||||||
.withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
|
|
||||||
.withValue(ContactsContract.Data.MIMETYPE, CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE)
|
|
||||||
.withValue(ContactsContract.CommonDataKinds.SipAddress.DATA, sipAddress)
|
|
||||||
.withValue(CommonDataKinds.SipAddress.TYPE, CommonDataKinds.SipAddress.TYPE_CUSTOM)
|
|
||||||
.withValue(CommonDataKinds.SipAddress.LABEL, context.getString(R.string.addressbook_label))
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void addSipAddressToContact(Context context, ArrayList<ContentProviderOperation> ops, String sipAddress, String rawContactID) {
|
|
||||||
ops.add(ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
|
|
||||||
.withValue(ContactsContract.Data.RAW_CONTACT_ID, rawContactID)
|
|
||||||
.withValue(ContactsContract.Data.MIMETYPE, CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE)
|
|
||||||
.withValue(ContactsContract.CommonDataKinds.SipAddress.DATA, sipAddress)
|
|
||||||
.withValue(CommonDataKinds.SipAddress.TYPE, CommonDataKinds.SipAddress.TYPE_CUSTOM)
|
|
||||||
.withValue(CommonDataKinds.SipAddress.LABEL, context.getString(R.string.addressbook_label))
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void updateSipAddressForContact(ArrayList<ContentProviderOperation> ops, String oldSipAddress, String newSipAddress, String contactID) {
|
|
||||||
String select = ContactsContract.Data.CONTACT_ID + "=? AND "
|
|
||||||
+ ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE + "' AND "
|
|
||||||
+ ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS + "=?";
|
|
||||||
String[] args = new String[] { String.valueOf(contactID), oldSipAddress };
|
|
||||||
|
|
||||||
ops.add(ContentProviderOperation.newUpdate(ContactsContract.Data.CONTENT_URI)
|
|
||||||
.withSelection(select, args)
|
|
||||||
.withValue(ContactsContract.Data.MIMETYPE, ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE)
|
|
||||||
.withValue(ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS, newSipAddress)
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void deleteSipAddressFromContact(ArrayList<ContentProviderOperation> ops, String oldSipAddress, String contactID) {
|
|
||||||
String select = ContactsContract.Data.CONTACT_ID + "=? AND "
|
|
||||||
+ ContactsContract.Data.MIMETYPE + "='" + ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE + "' AND "
|
|
||||||
+ ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS + "=? ";
|
|
||||||
String[] args = new String[] { String.valueOf(contactID), oldSipAddress };
|
|
||||||
|
|
||||||
ops.add(ContentProviderOperation.newDelete(ContactsContract.Data.CONTENT_URI)
|
|
||||||
.withSelection(select, args)
|
|
||||||
.build()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<String> extractContactNumbersAndAddresses(String id, ContentResolver cr) {
|
|
||||||
List<String> list = new ArrayList<String>();
|
|
||||||
|
|
||||||
Uri uri = Data.CONTENT_URI;
|
|
||||||
String[] projection;
|
|
||||||
|
|
||||||
// SIP addresses
|
|
||||||
String selection2 = new StringBuilder()
|
|
||||||
.append(Data.CONTACT_ID)
|
|
||||||
.append(" = ? AND ")
|
|
||||||
.append(Data.MIMETYPE)
|
|
||||||
.append(" = '")
|
|
||||||
.append(ContactsContract.CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE)
|
|
||||||
.append("'")
|
|
||||||
.toString();
|
|
||||||
projection = new String[] {ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS};
|
|
||||||
Cursor c = cr.query(uri, projection, selection2, new String[]{id}, null);
|
|
||||||
if (c != null) {
|
|
||||||
int nbid = c.getColumnIndex(ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS);
|
|
||||||
while (c.moveToNext()) {
|
|
||||||
list.add("sip:" + c.getString(nbid));
|
|
||||||
}
|
|
||||||
c.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Phone Numbers
|
|
||||||
c = cr.query(Phone.CONTENT_URI, new String[] { Phone.NUMBER }, Phone.CONTACT_ID + " = " + id, null, null);
|
|
||||||
if (c != null) {
|
|
||||||
while (c.moveToNext()) {
|
|
||||||
String number = c.getString(c.getColumnIndex(Phone.NUMBER));
|
|
||||||
list.add(number);
|
|
||||||
}
|
|
||||||
c.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
return list;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Cursor getContactsCursor(ContentResolver cr, String search, List<String> ids) {
|
|
||||||
String req;
|
|
||||||
if(ids != null && ids.size() > 0) {
|
|
||||||
req = "(" + Data.MIMETYPE + " = '" + CommonDataKinds.Phone.CONTENT_ITEM_TYPE
|
|
||||||
+ "' AND " + CommonDataKinds.Phone.NUMBER + " IS NOT NULL "
|
|
||||||
+ " OR (" + Data.MIMETYPE + " = '" + CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE
|
|
||||||
+ "' AND " + ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS + " IS NOT NULL)"
|
|
||||||
+ " OR (" + Data.CONTACT_ID + " IN (" + TextUtils.join(" , ", ids) + ")))";
|
|
||||||
} else {
|
|
||||||
req = "(" + Data.MIMETYPE + " = '" + CommonDataKinds.Phone.CONTENT_ITEM_TYPE
|
|
||||||
+ "' AND " + CommonDataKinds.Phone.NUMBER + " IS NOT NULL "
|
|
||||||
+ " OR (" + Data.MIMETYPE + " = '" + CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE
|
|
||||||
+ "' AND " + ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS + " IS NOT NULL))";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (search != null) {
|
|
||||||
req += " AND " + Data.DISPLAY_NAME + " LIKE '%" + search + "%'";
|
|
||||||
}
|
|
||||||
|
|
||||||
return ApiFivePlus.getGeneralContactCursor(cr, req, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Cursor getSIPContactsCursor(ContentResolver cr, String search, List<String> ids) {
|
|
||||||
|
|
||||||
String req = "(" + Data.MIMETYPE + " = '" + CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE
|
|
||||||
+ "' AND " + ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS + " IS NOT NULL) ";
|
|
||||||
|
|
||||||
if(ids != null && ids.size() > 0) {
|
|
||||||
req += " OR (" + Data.CONTACT_ID + " IN (" + TextUtils.join(" , ", ids) + "))";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (search != null) {
|
|
||||||
req += " AND " + Data.DISPLAY_NAME + " LIKE '%" + search + "%'";
|
|
||||||
}
|
|
||||||
|
|
||||||
return ApiFivePlus.getGeneralContactCursor(cr, req, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static Cursor getSIPContactCursor(ContentResolver cr, String id) {
|
|
||||||
String req = null;
|
|
||||||
req = Contacts.Data.MIMETYPE + " = '" + CommonDataKinds.SipAddress.CONTENT_ITEM_TYPE
|
|
||||||
+ "' AND " + ContactsContract.CommonDataKinds.SipAddress.SIP_ADDRESS + " LIKE '" + id + "'";
|
|
||||||
|
|
||||||
return ApiFivePlus.getGeneralContactCursor(cr, req, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Uri findUriPictureOfContactAndSetDisplayName(LinphoneAddress address, ContentResolver cr) {
|
|
||||||
String username = address.getUserName();
|
|
||||||
String domain = address.getDomain();
|
|
||||||
String sipUri = username + "@" + domain;
|
|
||||||
|
|
||||||
Cursor cursor = getSIPContactCursor(cr, sipUri);
|
|
||||||
LinphoneContact contact = ApiFivePlus.getContact(cr, cursor, 0);
|
|
||||||
if (contact != null && contact.getNumbersOrAddresses().contains(sipUri)) {
|
|
||||||
address.setDisplayName(contact.getFullName());
|
|
||||||
cursor.close();
|
|
||||||
return contact.getPhotoUri();
|
|
||||||
}
|
|
||||||
|
|
||||||
cursor.close();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -33,6 +33,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
@TargetApi(16)
|
@TargetApi(16)
|
||||||
public class ApiSixteenPlus {
|
public class ApiSixteenPlus {
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
public static Notification createMessageNotification(Context context,
|
public static Notification createMessageNotification(Context context,
|
||||||
int msgCount, String msgSender, String msg, Bitmap contactIcon,
|
int msgCount, String msgSender, String msg, Bitmap contactIcon,
|
||||||
PendingIntent intent) {
|
PendingIntent intent) {
|
||||||
|
|
|
@ -33,6 +33,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
@TargetApi(21)
|
@TargetApi(21)
|
||||||
public class ApiTwentyOnePlus {
|
public class ApiTwentyOnePlus {
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
public static Notification createMessageNotification(Context context,
|
public static Notification createMessageNotification(Context context,
|
||||||
int msgCount, String msgSender, String msg, Bitmap contactIcon,
|
int msgCount, String msgSender, String msg, Bitmap contactIcon,
|
||||||
PendingIntent intent) {
|
PendingIntent intent) {
|
||||||
|
|
|
@ -17,191 +17,54 @@ You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software
|
along with this program; if not, write to the Free Software
|
||||||
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
*/
|
*/
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import org.linphone.LinphoneContact;
|
|
||||||
import org.linphone.core.LinphoneAddress;
|
|
||||||
import org.linphone.mediastream.Version;
|
import org.linphone.mediastream.Version;
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.content.ContentProviderOperation;
|
|
||||||
import android.content.ContentResolver;
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.Intent;
|
|
||||||
import android.database.Cursor;
|
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.media.AudioManager;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.PowerManager;
|
import android.os.PowerManager;
|
||||||
import android.preference.Preference;
|
|
||||||
import android.provider.Settings;
|
import android.provider.Settings;
|
||||||
|
import android.text.Html;
|
||||||
|
import android.text.Spanned;
|
||||||
import android.view.ViewTreeObserver;
|
import android.view.ViewTreeObserver;
|
||||||
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
|
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
|
||||||
/**
|
/**
|
||||||
* @author Sylvain Berfini
|
* @author Sylvain Berfini
|
||||||
*/
|
*/
|
||||||
public class Compatibility {
|
public class Compatibility {
|
||||||
public static void overridePendingTransition(Activity activity, int idAnimIn, int idAnimOut) {
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API05_ECLAIR_20)) {
|
|
||||||
ApiFivePlus.overridePendingTransition(activity, idAnimIn, idAnimOut);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Intent prepareAddContactIntent(String displayName, String sipUri) {
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) {
|
|
||||||
return ApiElevenPlus.prepareAddContactIntent(displayName, sipUri);
|
|
||||||
} else {
|
|
||||||
return ApiFivePlus.prepareAddContactIntent(displayName, sipUri);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Intent prepareEditContactIntent(int id) {
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API05_ECLAIR_20)) {
|
|
||||||
return ApiFivePlus.prepareEditContactIntent(id);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Intent prepareEditContactIntentWithSipAddress(int id, String sipAddress) {
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) {
|
|
||||||
return ApiElevenPlus.prepareEditContactIntentWithSipAddress(id, sipAddress);
|
|
||||||
} else {
|
|
||||||
return ApiFivePlus.prepareEditContactIntent(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<String> extractContactNumbersAndAddresses(String id, ContentResolver cr) {
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) {
|
|
||||||
return ApiNinePlus.extractContactNumbersAndAddresses(id, cr);
|
|
||||||
} else {
|
|
||||||
return ApiFivePlus.extractContactNumbersAndAddresses(id, cr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<String> extractContactImAddresses(String id, ContentResolver cr) {
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) {
|
|
||||||
return ApiFivePlus.extractContactNumbersAndAddresses(id, cr);
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Cursor getContactsCursor(ContentResolver cr, List<String> contactsId) {
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) {
|
|
||||||
return ApiNinePlus.getContactsCursor(cr, null, contactsId);
|
|
||||||
} else {
|
|
||||||
return ApiFivePlus.getContactsCursor(cr, contactsId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Cursor getContactsCursor(ContentResolver cr, String search, List<String> contactsId) {
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) {
|
|
||||||
return ApiNinePlus.getContactsCursor(cr, search, contactsId);
|
|
||||||
} else {
|
|
||||||
return ApiFivePlus.getContactsCursor(cr, contactsId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Cursor getSIPContactsCursor(ContentResolver cr, List<String> contactsId) {
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) {
|
|
||||||
return ApiNinePlus.getSIPContactsCursor(cr, null, contactsId);
|
|
||||||
} else {
|
|
||||||
return ApiFivePlus.getSIPContactsCursor(cr, contactsId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Cursor getSIPContactsCursor(ContentResolver cr, String search, List<String> contactsId) {
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) {
|
|
||||||
return ApiNinePlus.getSIPContactsCursor(cr, search, contactsId);
|
|
||||||
} else {
|
|
||||||
return ApiFivePlus.getSIPContactsCursor(cr, contactsId);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Cursor getImContactsCursor(ContentResolver cr) {
|
|
||||||
return ApiFivePlus.getSIPContactsCursor(cr,null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getCursorDisplayNameColumnIndex(Cursor cursor) {
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API05_ECLAIR_20)) {
|
|
||||||
return ApiFivePlus.getCursorDisplayNameColumnIndex(cursor);
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static LinphoneContact getContact(ContentResolver cr, Cursor cursor, int position) {
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API05_ECLAIR_20)) {
|
|
||||||
return ApiFivePlus.getContact(cr, cursor, position);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static InputStream getContactPictureInputStream(ContentResolver cr, String id) {
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API05_ECLAIR_20)) {
|
|
||||||
return ApiFivePlus.getContactPictureInputStream(cr, id);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Uri findUriPictureOfContactAndSetDisplayName(LinphoneAddress address, ContentResolver cr) {
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) {
|
|
||||||
return ApiNinePlus.findUriPictureOfContactAndSetDisplayName(address, cr);
|
|
||||||
} else {
|
|
||||||
return ApiFivePlus.findUriPictureOfContactAndSetDisplayName(address, cr);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 = null;
|
Notification notif = null;
|
||||||
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API21_LOLLIPOP_50)) {
|
if (Version.sdkAboveOrEqual(Version.API21_LOLLIPOP_50)) {
|
||||||
return ApiTwentyOnePlus.createSimpleNotification(context, title, text, intent);
|
return ApiTwentyOnePlus.createSimpleNotification(context, title, text, intent);
|
||||||
} else if (Version.sdkAboveOrEqual(Version.API16_JELLY_BEAN_41)) {
|
} else if (Version.sdkAboveOrEqual(Version.API16_JELLY_BEAN_41)) {
|
||||||
notif = ApiSixteenPlus.createSimpleNotification(context, title, text, intent);
|
notif = ApiSixteenPlus.createSimpleNotification(context, title, text, intent);
|
||||||
} else if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) {
|
|
||||||
notif = ApiElevenPlus.createSimpleNotification(context, title, text, intent);
|
|
||||||
} else {
|
} else {
|
||||||
notif = ApiFivePlus.createSimpleNotification(context, title, text, intent);
|
notif = ApiElevenPlus.createSimpleNotification(context, title, text, intent);
|
||||||
}
|
}
|
||||||
return notif;
|
return notif;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Notification createMessageNotification(Context context, int msgCount, String msgSender, String msg, Bitmap contactIcon, PendingIntent intent) {
|
public static Notification createMessageNotification(Context context, int msgCount, String msgSender, String msg, Bitmap contactIcon, PendingIntent intent) {
|
||||||
Notification notif = null;
|
Notification notif = null;
|
||||||
String title;
|
|
||||||
if (msgCount == 1) {
|
|
||||||
title = "Unread message from %s".replace("%s", msgSender);
|
|
||||||
} else {
|
|
||||||
title = "%i unread messages".replace("%i", String.valueOf(msgCount));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API21_LOLLIPOP_50)) {
|
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)) {
|
||||||
notif = ApiSixteenPlus.createMessageNotification(context, msgCount, msgSender, msg, contactIcon, intent);
|
notif = ApiSixteenPlus.createMessageNotification(context, msgCount, msgSender, msg, contactIcon, intent);
|
||||||
} else if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) {
|
|
||||||
notif = ApiElevenPlus.createMessageNotification(context, msgCount, msgSender, msg, contactIcon, intent);
|
|
||||||
} else {
|
} else {
|
||||||
notif = ApiFivePlus.createMessageNotification(context, title, msg, intent);
|
notif = ApiElevenPlus.createMessageNotification(context, msgCount, msgSender, msg, contactIcon, intent);
|
||||||
}
|
}
|
||||||
return notif;
|
return notif;
|
||||||
}
|
}
|
||||||
|
|
||||||
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) {
|
||||||
Notification notif = null;
|
Notification notif = null;
|
||||||
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API21_LOLLIPOP_50)) {
|
if (Version.sdkAboveOrEqual(Version.API21_LOLLIPOP_50)) {
|
||||||
return ApiTwentyOnePlus.createInCallNotification(context, title, msg, iconID, contactIcon, contactName, intent);
|
return ApiTwentyOnePlus.createInCallNotification(context, title, msg, iconID, contactIcon, contactName, intent);
|
||||||
} else if (Version.sdkAboveOrEqual(Version.API16_JELLY_BEAN_41)) {
|
} else if (Version.sdkAboveOrEqual(Version.API16_JELLY_BEAN_41)) {
|
||||||
notif = ApiSixteenPlus.createInCallNotification(context, title, msg, iconID, contactIcon, contactName, intent);
|
notif = ApiSixteenPlus.createInCallNotification(context, title, msg, iconID, contactIcon, contactName, intent);
|
||||||
} else if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) {
|
|
||||||
notif = ApiElevenPlus.createInCallNotification(context, title, msg, iconID, contactIcon, contactName, intent);
|
|
||||||
} else {
|
} else {
|
||||||
notif = ApiFivePlus.createInCallNotification(context, title, msg, iconID, intent);
|
notif = ApiElevenPlus.createInCallNotification(context, title, msg, iconID, contactIcon, contactName, intent);
|
||||||
}
|
}
|
||||||
return notif;
|
return notif;
|
||||||
}
|
}
|
||||||
|
@ -211,20 +74,11 @@ public class Compatibility {
|
||||||
return ApiTwentyOnePlus.createNotification(context, title, message, icon, iconLevel, largeIcon, intent, isOngoingEvent,priority);
|
return ApiTwentyOnePlus.createNotification(context, title, message, icon, iconLevel, largeIcon, intent, isOngoingEvent,priority);
|
||||||
} else if (Version.sdkAboveOrEqual(Version.API16_JELLY_BEAN_41)) {
|
} else if (Version.sdkAboveOrEqual(Version.API16_JELLY_BEAN_41)) {
|
||||||
return ApiSixteenPlus.createNotification(context, title, message, icon, iconLevel, largeIcon, intent, isOngoingEvent,priority);
|
return ApiSixteenPlus.createNotification(context, title, message, icon, iconLevel, largeIcon, intent, isOngoingEvent,priority);
|
||||||
} else if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) {
|
|
||||||
return ApiElevenPlus.createNotification(context, title, message, icon, iconLevel, largeIcon, intent, isOngoingEvent);
|
|
||||||
} else {
|
} else {
|
||||||
return ApiFivePlus.createNotification(context, title, message, icon, iconLevel, intent, isOngoingEvent);
|
return ApiElevenPlus.createNotification(context, title, message, icon, iconLevel, largeIcon, intent, isOngoingEvent);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String refreshContactName(ContentResolver cr, String id) {
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API05_ECLAIR_20)) {
|
|
||||||
return ApiFivePlus.refreshContactName(cr, id);
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static CompatibilityScaleGestureDetector getScaleGestureDetector(Context context, CompatibilityScaleGestureListener listener) {
|
public static CompatibilityScaleGestureDetector getScaleGestureDetector(Context context, CompatibilityScaleGestureListener listener) {
|
||||||
if (Version.sdkAboveOrEqual(Version.API08_FROYO_22)) {
|
if (Version.sdkAboveOrEqual(Version.API08_FROYO_22)) {
|
||||||
CompatibilityScaleGestureDetector csgd = new CompatibilityScaleGestureDetector(context);
|
CompatibilityScaleGestureDetector csgd = new CompatibilityScaleGestureDetector(context);
|
||||||
|
@ -233,109 +87,13 @@ public class Compatibility {
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public static void setPreferenceChecked(Preference preference, boolean checked) {
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API14_ICE_CREAM_SANDWICH_40)) {
|
|
||||||
ApiFourteenPlus.setPreferenceChecked(preference, checked);
|
|
||||||
} else {
|
|
||||||
ApiFivePlus.setPreferenceChecked(preference, checked);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isPreferenceChecked(Preference preference) {
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API14_ICE_CREAM_SANDWICH_40)) {
|
|
||||||
return ApiFourteenPlus.isPreferenceChecked(preference);
|
|
||||||
} else {
|
|
||||||
return ApiFivePlus.isPreferenceChecked(preference);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void initPushNotificationService(Context context) {
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API08_FROYO_22)) {
|
|
||||||
ApiEightPlus.initPushNotificationService(context);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void copyTextToClipboard(Context context, String msg) {
|
|
||||||
if(Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) {
|
|
||||||
ApiElevenPlus.copyTextToClipboard(context, msg);
|
|
||||||
} else {
|
|
||||||
ApiFivePlus.copyTextToClipboard(context, msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void addSipAddressToContact(Context context, ArrayList<ContentProviderOperation> ops, String sipAddress) {
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) {
|
|
||||||
ApiNinePlus.addSipAddressToContact(context, ops, sipAddress);
|
|
||||||
} else {
|
|
||||||
ApiFivePlus.addSipAddressToContact(context, ops, sipAddress);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void addSipAddressToContact(Context context, ArrayList<ContentProviderOperation> ops, String sipAddress, String rawContactID) {
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) {
|
|
||||||
ApiNinePlus.addSipAddressToContact(context, ops, sipAddress, rawContactID);
|
|
||||||
} else {
|
|
||||||
ApiFivePlus.addSipAddressToContact(context, ops, sipAddress, rawContactID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void updateSipAddressForContact(ArrayList<ContentProviderOperation> ops, String oldSipAddress, String newSipAddress, String contactID) {
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) {
|
|
||||||
ApiNinePlus.updateSipAddressForContact(ops, oldSipAddress, newSipAddress, contactID);
|
|
||||||
} else {
|
|
||||||
ApiFivePlus.updateSipAddressForContact(ops, oldSipAddress, newSipAddress, contactID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void deleteSipAddressFromContact(ArrayList<ContentProviderOperation> ops, String oldSipAddress, String contactID) {
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) {
|
|
||||||
ApiNinePlus.deleteSipAddressFromContact(ops, oldSipAddress, contactID);
|
|
||||||
} else {
|
|
||||||
ApiFivePlus.deleteSipAddressFromContact(ops, oldSipAddress, contactID);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void deleteImAddressFromContact(ArrayList<ContentProviderOperation> ops, String oldSipAddress, String contactID) {
|
|
||||||
ApiFivePlus.deleteSipAddressFromContact(ops, oldSipAddress, contactID);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
public static void removeGlobalLayoutListener(ViewTreeObserver viewTreeObserver, OnGlobalLayoutListener keyboardListener) {
|
public static void removeGlobalLayoutListener(ViewTreeObserver viewTreeObserver, OnGlobalLayoutListener keyboardListener) {
|
||||||
if (Version.sdkAboveOrEqual(Version.API16_JELLY_BEAN_41)) {
|
if (Version.sdkAboveOrEqual(Version.API16_JELLY_BEAN_41)) {
|
||||||
ApiSixteenPlus.removeGlobalLayoutListener(viewTreeObserver, keyboardListener);
|
ApiSixteenPlus.removeGlobalLayoutListener(viewTreeObserver, keyboardListener);
|
||||||
} else {
|
} else {
|
||||||
ApiFivePlus.removeGlobalLayoutListener(viewTreeObserver, keyboardListener);
|
viewTreeObserver.removeGlobalOnLayoutListener(keyboardListener);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void hideNavigationBar(Activity activity)
|
|
||||||
{
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API14_ICE_CREAM_SANDWICH_40)) {
|
|
||||||
ApiFourteenPlus.hideNavigationBar(activity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void showNavigationBar(Activity activity)
|
|
||||||
{
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API14_ICE_CREAM_SANDWICH_40)) {
|
|
||||||
ApiFourteenPlus.showNavigationBar(activity);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void setAudioManagerInCallMode(AudioManager manager) {
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) {
|
|
||||||
ApiElevenPlus.setAudioManagerInCallMode(manager);
|
|
||||||
} else {
|
|
||||||
ApiFivePlus.setAudioManagerInCallMode(manager);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getAudioManagerEventForBluetoothConnectionStateChangedEvent() {
|
|
||||||
if (Version.sdkAboveOrEqual(Version.API14_ICE_CREAM_SANDWICH_40)) {
|
|
||||||
return ApiFourteenPlus.getAudioManagerEventForBluetoothConnectionStateChangedEvent();
|
|
||||||
} else {
|
|
||||||
return ApiEightPlus.getAudioManagerEventForBluetoothConnectionStateChangedEvent();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,4 +112,12 @@ public class Compatibility {
|
||||||
return pm.isScreenOn();
|
return pm.isScreenOn();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("deprecation")
|
||||||
|
public static Spanned fromHtml(String text) {
|
||||||
|
/*if (Version.sdkAboveOrEqual(Version.API24_NOUGAT_70)) {
|
||||||
|
return Html.fromHtml(text, Html.FROM_HTML_MODE_LEGACY);
|
||||||
|
}*/
|
||||||
|
return Html.fromHtml(text);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,13 +53,13 @@ public class GCMService extends GCMBaseIntentService {
|
||||||
@Override
|
@Override
|
||||||
protected void onError(Context context, String errorId) {
|
protected void onError(Context context, String errorId) {
|
||||||
initLogger(context);
|
initLogger(context);
|
||||||
Log.e("Error while registering push notification : " + errorId);
|
Log.e("[Push Notification] Error while registering: " + errorId);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onMessage(Context context, Intent intent) {
|
protected void onMessage(Context context, Intent intent) {
|
||||||
initLogger(context);
|
initLogger(context);
|
||||||
Log.d("Push notification received");
|
Log.d("[Push Notification] Received");
|
||||||
|
|
||||||
if (!LinphoneService.isReady()) {
|
if (!LinphoneService.isReady()) {
|
||||||
startService(new Intent(ACTION_MAIN).setClass(this, LinphoneService.class));
|
startService(new Intent(ACTION_MAIN).setClass(this, LinphoneService.class));
|
||||||
|
@ -79,7 +79,7 @@ public class GCMService extends GCMBaseIntentService {
|
||||||
@Override
|
@Override
|
||||||
protected void onRegistered(Context context, String regId) {
|
protected void onRegistered(Context context, String regId) {
|
||||||
initLogger(context);
|
initLogger(context);
|
||||||
Log.d("Registered push notification : " + regId);
|
Log.d("[Push Notification] Registered: " + regId);
|
||||||
|
|
||||||
LinphonePreferences.instance().setPushNotificationRegistrationID(regId);
|
LinphonePreferences.instance().setPushNotificationRegistrationID(regId);
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ public class GCMService extends GCMBaseIntentService {
|
||||||
@Override
|
@Override
|
||||||
protected void onUnregistered(Context context, String regId) {
|
protected void onUnregistered(Context context, String regId) {
|
||||||
initLogger(context);
|
initLogger(context);
|
||||||
Log.w("Unregistered push notification : " + regId);
|
Log.w("[Push Notification] Unregistered: " + regId);
|
||||||
|
|
||||||
LinphonePreferences.instance().setPushNotificationRegistrationID(null);
|
LinphonePreferences.instance().setPushNotificationRegistrationID(null);
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,8 +162,7 @@ public class TutorialCardDavSync extends Activity implements OnClickListener, Li
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onLinphoneFriendSyncStatusChanged(LinphoneFriendList list,
|
public void onLinphoneFriendSyncStatusChanged(LinphoneFriendList list, LinphoneFriendList.State status, String message) {
|
||||||
org.linphone.core.LinphoneFriendList.State status, String message) {
|
|
||||||
// TODO Auto-generated method stub
|
// TODO Auto-generated method stub
|
||||||
String msg = "Sync status changed: " + status.toString() + " (" + message + ")";
|
String msg = "Sync status changed: " + status.toString() + " (" + message + ")";
|
||||||
myLog(msg);
|
myLog(msg);
|
||||||
|
|
|
@ -31,6 +31,7 @@ import org.linphone.LinphoneContact;
|
||||||
import org.linphone.LinphoneManager;
|
import org.linphone.LinphoneManager;
|
||||||
import org.linphone.LinphoneUtils;
|
import org.linphone.LinphoneUtils;
|
||||||
import org.linphone.R;
|
import org.linphone.R;
|
||||||
|
import org.linphone.compatibility.Compatibility;
|
||||||
import org.linphone.core.LinphoneBuffer;
|
import org.linphone.core.LinphoneBuffer;
|
||||||
import org.linphone.core.LinphoneChatMessage;
|
import org.linphone.core.LinphoneChatMessage;
|
||||||
import org.linphone.core.LinphoneChatMessage.State;
|
import org.linphone.core.LinphoneChatMessage.State;
|
||||||
|
@ -52,7 +53,6 @@ import android.net.Uri;
|
||||||
import android.os.AsyncTask;
|
import android.os.AsyncTask;
|
||||||
import android.os.Environment;
|
import android.os.Environment;
|
||||||
import android.provider.MediaStore;
|
import android.provider.MediaStore;
|
||||||
import android.text.Html;
|
|
||||||
import android.text.Spannable;
|
import android.text.Spannable;
|
||||||
import android.text.SpannableStringBuilder;
|
import android.text.SpannableStringBuilder;
|
||||||
import android.text.Spanned;
|
import android.text.Spanned;
|
||||||
|
@ -312,7 +312,7 @@ public class BubbleChat implements LinphoneChatMessage.LinphoneChatMessageListen
|
||||||
text = text.replaceFirst(link, "<a href=\"" + link + "\">" + linkWithoutScheme + "</a>");
|
text = text.replaceFirst(link, "<a href=\"" + link + "\">" + linkWithoutScheme + "</a>");
|
||||||
}
|
}
|
||||||
|
|
||||||
return Html.fromHtml(text);
|
return Compatibility.fromHtml(text);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTextMessage() {
|
public String getTextMessage() {
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 9daabd3dbfc72d6799f6bd54474a8f262e6716f2
|
Subproject commit 921a21332c327ae99900267950be0bfd2d7c6126
|
|
@ -1 +1 @@
|
||||||
Subproject commit 086bb16bd79180265136ed9d4a89661049c95016
|
Subproject commit b553f58c3f23633b9c183af5784b2170b6b4aa91
|
|
@ -1 +1 @@
|
||||||
Subproject commit 6d4281181addb913e851622e6d9b04d093c869d4
|
Subproject commit f4eac4803eee43de3efa96ecca9450ba4f2bc7dc
|
|
@ -1 +1 @@
|
||||||
Subproject commit 976f38cc0865e106a27b6f74bdfde0fb368624b7
|
Subproject commit 6f1e96c8f60576fb1cfe9750612f9fdb7c134c54
|
|
@ -40,7 +40,7 @@
|
||||||
</condition>
|
</condition>
|
||||||
<exec executable="bash" unless:set="has.crashed">
|
<exec executable="bash" unless:set="has.crashed">
|
||||||
<arg value="-c"/>
|
<arg value="-c"/>
|
||||||
<arg value="adb shell run-as org.linphone cat /data/data/org.linphone/files/junit-report.xml > linphone-junit-report-${test.size}.xml"/>
|
<arg value="adb shell cat /data/data/org.linphone/files/junit-report.xml > linphone-junit-report-${test.size}.xml"/>
|
||||||
</exec>
|
</exec>
|
||||||
|
|
||||||
<zip destfile="${archive.name}.zip">
|
<zip destfile="${archive.name}.zip">
|
||||||
|
|
Loading…
Reference in a new issue