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>
|
||||
</receiver>
|
||||
|
||||
<receiver android:name="KeepAliveHandler" >
|
||||
</receiver>
|
||||
<!-- This one needs to be registered from application -->
|
||||
<receiver android:name="KeepAliveReceiver"/>
|
||||
|
||||
<!-- Needed for push notification -->
|
||||
<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:
|
||||
-------------------------------------------
|
||||
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.
|
||||
1) download the Android ndk (version r11) from google and add it to your path (no symlink !!!).
|
||||
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 r11c or 12b) from google and add it to your path (no symlink !!!).
|
||||
2) install yasm, nasm, ant, python, cmake and vim-common
|
||||
On 64 bits linux systems you'll need the ia32-libs package
|
||||
With the latest Debian (multiarch), you need this:
|
||||
|
@ -27,11 +27,12 @@ To build liblinphone for Android, you must:
|
|||
$ make mediastreamer2-sdk
|
||||
8) (Optional) To generate a signed apk to publish on the Google Play, run
|
||||
$ 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.
|
||||
You also may want to create a file name ant_password.properties with the following:
|
||||
key.store.password=[your_password]
|
||||
key.alias.password=[your_password]
|
||||
If you don't, the passwords will be asked at the signing phase.
|
||||
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:
|
||||
key.store.password=[your_password]
|
||||
key.alias.password=[your_password]
|
||||
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:
|
||||
--------------------
|
||||
|
|
|
@ -48,7 +48,7 @@
|
|||
</condition>
|
||||
<exec executable="bash" unless:set="has.crashed">
|
||||
<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>
|
||||
|
||||
<zip destfile="${archive.name}.zip">
|
||||
|
|
|
@ -136,6 +136,7 @@
|
|||
android:inputType="textPersonName|textCapWords"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/contactOrganizationTitle"
|
||||
android:text="@string/contact_organization"
|
||||
style="@style/font13"
|
||||
android:textAllCaps="true"
|
||||
|
|
|
@ -68,6 +68,8 @@
|
|||
<bool name="allow_only_one_phone_number">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="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_device_ringtone_key">pref_device_ringtone_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>
|
||||
|
|
|
@ -313,6 +313,7 @@
|
|||
<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_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_display_name_title">Display name</string>
|
||||
<string name="pref_user_name_title">Username</string>
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<ContactsSource
|
||||
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
|
||||
android:mimeType="vnd.android.cursor.item/org.linphone.profile"
|
||||
android:icon="@drawable/linphone_logo"
|
||||
|
|
|
@ -351,6 +351,11 @@
|
|||
android:inputType="textUri"
|
||||
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.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.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() {
|
||||
@Override
|
||||
|
@ -145,7 +145,7 @@ public class AboutFragment extends Fragment implements OnClickListener {
|
|||
lc.addListener(mListener);
|
||||
}
|
||||
|
||||
if (org.linphone.LinphoneActivity.isInstanciated()) {
|
||||
if (LinphoneActivity.isInstanciated()) {
|
||||
LinphoneActivity.instance().selectMenu(FragmentsAvailable.ABOUT);
|
||||
}
|
||||
|
||||
|
@ -154,8 +154,8 @@ public class AboutFragment extends Fragment implements OnClickListener {
|
|||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (org.linphone.LinphoneActivity.isInstanciated()) {
|
||||
LinphoneCore lc = org.linphone.LinphoneManager.getLcIfManagerNotDestroyedOrNull();
|
||||
if (LinphoneActivity.isInstanciated()) {
|
||||
LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
|
||||
if (v == sendLogButton) {
|
||||
if (lc != null) {
|
||||
lc.uploadLogCollection();
|
||||
|
@ -174,6 +174,4 @@ public class AboutFragment extends Fragment implements OnClickListener {
|
|||
public void onDestroy() {
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -53,8 +53,7 @@ public class AccountPreferencesFragment extends PreferencesListFragment {
|
|||
mPrefs = LinphonePreferences.instance();
|
||||
}
|
||||
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
PreferenceScreen screen = getPreferenceScreen();
|
||||
|
@ -69,7 +68,7 @@ public class AccountPreferencesFragment extends PreferencesListFragment {
|
|||
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.
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
*/
|
||||
import java.util.List;
|
||||
|
||||
import org.linphone.compatibility.Compatibility;
|
||||
import org.linphone.mediastream.Log;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
|
@ -68,31 +67,31 @@ public class BluetoothManager extends BroadcastReceiver {
|
|||
public BluetoothManager() {
|
||||
isBluetoothConnected = false;
|
||||
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;
|
||||
}
|
||||
|
||||
public void initBluetooth() {
|
||||
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;
|
||||
}
|
||||
|
||||
IntentFilter filter = new IntentFilter();
|
||||
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(BluetoothHeadset.ACTION_VENDOR_SPECIFIC_HEADSET_EVENT);
|
||||
mContext.registerReceiver(this, filter);
|
||||
Log.d("Bluetooth receiver started");
|
||||
Log.d("[Bluetooth] Receiver started");
|
||||
|
||||
startBluetooth();
|
||||
}
|
||||
|
||||
private void startBluetooth() {
|
||||
if (isBluetoothConnected) {
|
||||
Log.e("Bluetooth already started");
|
||||
Log.e("[Bluetooth] Already started, skipping...");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -100,14 +99,14 @@ public class BluetoothManager extends BroadcastReceiver {
|
|||
|
||||
if (mBluetoothAdapter != null && mBluetoothAdapter.isEnabled()) {
|
||||
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);
|
||||
}
|
||||
|
||||
mProfileListener = new BluetoothProfile.ServiceListener() {
|
||||
public void onServiceConnected(int profile, BluetoothProfile proxy) {
|
||||
if (profile == BluetoothProfile.HEADSET) {
|
||||
Log.d("Bluetooth headset connected");
|
||||
Log.d("[Bluetooth] Headset connected");
|
||||
mBluetoothHeadset = (BluetoothHeadset) proxy;
|
||||
isBluetoothConnected = true;
|
||||
}
|
||||
|
@ -116,17 +115,17 @@ public class BluetoothManager extends BroadcastReceiver {
|
|||
if (profile == BluetoothProfile.HEADSET) {
|
||||
mBluetoothHeadset = null;
|
||||
isBluetoothConnected = false;
|
||||
Log.d("Bluetooth headset disconnected");
|
||||
Log.d("[Bluetooth] Headset disconnected");
|
||||
LinphoneManager.getInstance().routeAudioToReceiver();
|
||||
}
|
||||
}
|
||||
};
|
||||
boolean success = mBluetoothAdapter.getProfileProxy(mContext, mProfileListener, BluetoothProfile.HEADSET);
|
||||
if (!success) {
|
||||
Log.e("Bluetooth getProfileProxy failed !");
|
||||
Log.e("[Bluetooth] getProfileProxy failed !");
|
||||
}
|
||||
} 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 (isBluetoothHeadsetAvailable()) {
|
||||
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.startBluetoothSco();
|
||||
}
|
||||
|
@ -180,12 +179,12 @@ public class BluetoothManager extends BroadcastReceiver {
|
|||
}
|
||||
if (ok) {
|
||||
if (retries > 0) {
|
||||
Log.d("Bluetooth route ok after " + retries + " retries");
|
||||
Log.d("[Bluetooth] Audio route ok after " + retries + " retries");
|
||||
} else {
|
||||
Log.d("Bluetooth route ok");
|
||||
Log.d("[Bluetooth] Audio route ok");
|
||||
}
|
||||
} else {
|
||||
Log.d("Bluetooth still not ok...");
|
||||
Log.d("[Bluetooth] Audio route still not ok...");
|
||||
}
|
||||
|
||||
return ok;
|
||||
|
@ -212,7 +211,7 @@ public class BluetoothManager extends BroadcastReceiver {
|
|||
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;
|
||||
}
|
||||
|
@ -237,12 +236,12 @@ public class BluetoothManager extends BroadcastReceiver {
|
|||
mAudioManager.stopBluetoothSco();
|
||||
mAudioManager.setBluetoothScoOn(false);
|
||||
}
|
||||
Log.w("Bluetooth sco disconnected!");
|
||||
Log.w("[Bluetooth] SCO disconnected!");
|
||||
}
|
||||
}
|
||||
|
||||
public void stopBluetooth() {
|
||||
Log.w("Stopping bluetooth...");
|
||||
Log.w("[Bluetooth] Stopping...");
|
||||
isBluetoothConnected = false;
|
||||
|
||||
disableBluetoothSCO();
|
||||
|
@ -253,7 +252,7 @@ public class BluetoothManager extends BroadcastReceiver {
|
|||
}
|
||||
mBluetoothDevice = null;
|
||||
|
||||
Log.w("Bluetooth stopped!");
|
||||
Log.w("[Bluetooth] Stopped!");
|
||||
|
||||
if (LinphoneManager.isInstanciated()) {
|
||||
LinphoneManager.getInstance().routeAudioToReceiver();
|
||||
|
@ -266,7 +265,7 @@ public class BluetoothManager extends BroadcastReceiver {
|
|||
|
||||
try {
|
||||
mContext.unregisterReceiver(this);
|
||||
Log.d("Bluetooth receiver stopped");
|
||||
Log.d("[Bluetooth] Receiver stopped");
|
||||
} catch (Exception e) {}
|
||||
} catch (Exception e) {
|
||||
Log.e(e);
|
||||
|
@ -278,30 +277,30 @@ public class BluetoothManager extends BroadcastReceiver {
|
|||
return;
|
||||
|
||||
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);
|
||||
if (state == AudioManager.SCO_AUDIO_STATE_CONNECTED) {
|
||||
Log.d("Bluetooth sco state => connected");
|
||||
Log.d("[Bluetooth] SCO state: connected");
|
||||
// LinphoneManager.getInstance().audioStateChanged(AudioState.BLUETOOTH);
|
||||
isScoConnected = true;
|
||||
} 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);
|
||||
isScoConnected = false;
|
||||
} else {
|
||||
Log.d("Bluetooth sco state => " + state);
|
||||
Log.d("[Bluetooth] SCO state: " + state);
|
||||
}
|
||||
}
|
||||
else if (BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED.equals(action)) {
|
||||
int state = intent.getIntExtra(BluetoothAdapter.EXTRA_CONNECTION_STATE, BluetoothAdapter.STATE_DISCONNECTED);
|
||||
if (state == 0) {
|
||||
Log.d("Bluetooth state => disconnected");
|
||||
Log.d("[Bluetooth] State: disconnected");
|
||||
stopBluetooth();
|
||||
} else if (state == 2) {
|
||||
Log.d("Bluetooth state => connected");
|
||||
Log.d("[Bluetooth] State: connected");
|
||||
startBluetooth();
|
||||
} else {
|
||||
Log.d("Bluetooth state => " + state);
|
||||
Log.d("[Bluetooth] State: " + state);
|
||||
}
|
||||
}
|
||||
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) {
|
||||
Integer buttonID = (Integer) args[1];
|
||||
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 LinphoneCoreListenerBase mListener;
|
||||
private DrawerLayout sideMenu;
|
||||
private boolean mProximitySensingEnabled;
|
||||
|
||||
public static CallActivity instance() {
|
||||
return instance;
|
||||
|
@ -800,8 +801,22 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve
|
|||
}
|
||||
}
|
||||
|
||||
private void showAudioView() {
|
||||
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() {
|
||||
enableProximitySensing(true);
|
||||
replaceFragmentVideoByAudio();
|
||||
displayAudioCall();
|
||||
showStatusBar();
|
||||
|
@ -816,7 +831,7 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve
|
|||
}
|
||||
refreshInCallActions();
|
||||
|
||||
mSensorManager.unregisterListener(this);
|
||||
enableProximitySensing(false);
|
||||
replaceFragmentAudioByVideo();
|
||||
hideStatusBar();
|
||||
}
|
||||
|
@ -1173,7 +1188,7 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve
|
|||
handleViewIntent();
|
||||
|
||||
if (!isVideoEnabled(LinphoneManager.getLc().getCurrentCall())) {
|
||||
mSensorManager.registerListener(this, mProximity, SensorManager.SENSOR_DELAY_NORMAL);
|
||||
enableProximitySensing(true);
|
||||
removeCallbacks();
|
||||
}
|
||||
}
|
||||
|
@ -1223,10 +1238,7 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve
|
|||
mControlsHandler.removeCallbacks(mControls);
|
||||
}
|
||||
mControls = null;
|
||||
|
||||
if (!isVideoEnabled(LinphoneManager.getLc().getCurrentCall())) {
|
||||
mSensorManager.unregisterListener(this);
|
||||
}
|
||||
enableProximitySensing(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -1239,7 +1251,7 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve
|
|||
mControls = null;
|
||||
mControlsHandler = null;
|
||||
|
||||
mSensorManager.unregisterListener(this);
|
||||
enableProximitySensing(false);
|
||||
|
||||
unbindDrawables(findViewById(R.id.topLayout));
|
||||
instance = null;
|
||||
|
@ -1510,7 +1522,7 @@ public class CallActivity extends Activity implements OnClickListener, SensorEve
|
|||
private void displayConference(boolean isInConf){
|
||||
if(isInConf) {
|
||||
mControlsLayout.setVisibility(View.VISIBLE);
|
||||
mSensorManager.registerListener(this, mProximity, SensorManager.SENSOR_DELAY_NORMAL);
|
||||
enableProximitySensing(true);
|
||||
mActiveCallHeader.setVisibility(View.GONE);
|
||||
mNoCurrentCall.setVisibility(View.GONE);
|
||||
conferenceList.removeAllViews();
|
||||
|
|
|
@ -44,6 +44,8 @@ import android.app.Activity;
|
|||
import android.app.Dialog;
|
||||
import android.app.Fragment;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.res.Configuration;
|
||||
|
@ -387,7 +389,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
|
||||
if(isEditMode) {
|
||||
deleteChatBubble.setVisibility(View.VISIBLE);
|
||||
if(message.isOutgoing()){
|
||||
if (message.isOutgoing()) {
|
||||
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
|
||||
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
|
||||
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);
|
||||
} else {
|
||||
deleteChatBubble.setChecked(false);
|
||||
|
@ -427,7 +429,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
|
||||
rlayout.addView(v);
|
||||
} else {
|
||||
if(message.isOutgoing()){
|
||||
if (message.isOutgoing()) {
|
||||
RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
|
||||
layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
|
||||
layoutParams.setMargins(100, 10, 10, 10);
|
||||
|
@ -448,7 +450,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
|
||||
|
||||
LinphoneAddress lAddress = null;
|
||||
if(sipUri == null){
|
||||
if (sipUri == null) {
|
||||
initNewChatConversation();
|
||||
} else {
|
||||
try {
|
||||
|
@ -477,7 +479,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
}
|
||||
|
||||
private void displayMessageList() {
|
||||
if(chatRoom != null) {
|
||||
if (chatRoom != null) {
|
||||
if (adapter != null) {
|
||||
adapter.refreshHistory();
|
||||
} else {
|
||||
|
@ -488,7 +490,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
}
|
||||
|
||||
private void displayChatHeader(LinphoneAddress address) {
|
||||
if(contact != null) {
|
||||
if (contact != null) {
|
||||
contactName.setText(contact.getFullName());
|
||||
} else if(address != null){
|
||||
contactName.setText(LinphoneUtils.getAddressDisplayName(address));
|
||||
|
@ -618,7 +620,7 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
String draft = getArguments().getString("messageDraft");
|
||||
message.setText(draft);
|
||||
|
||||
if(!newChatConversation) {
|
||||
if (!newChatConversation) {
|
||||
initChatRoom(sipUri);
|
||||
searchContactField.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();
|
||||
for(int i=0; i<size; i++) {
|
||||
messagesList.setItemChecked(i,isSelectAll);
|
||||
for (int i = 0; i < size; i++) {
|
||||
messagesList.setItemChecked(i, isSelectAll);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -642,8 +644,8 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
|
||||
private void removeChats(){
|
||||
int size = messagesList.getAdapter().getCount();
|
||||
for(int i=0; i<size; i++) {
|
||||
if(messagesList.isItemChecked(i)){
|
||||
for (int i = 0; i < size; i++) {
|
||||
if (messagesList.isItemChecked(i)) {
|
||||
LinphoneChatMessage message = (LinphoneChatMessage) messagesList.getAdapter().getItem(i);
|
||||
chatRoom.deleteMessage(message);
|
||||
}
|
||||
|
@ -827,7 +829,9 @@ public class ChatFragment extends Fragment implements OnClickListener, LinphoneC
|
|||
txt = message.getText();
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
||||
organization = (TextView) view.findViewById(R.id.contactOrganization);
|
||||
boolean isOrgVisible = getResources().getBoolean(R.bool.display_contact_organization);
|
||||
String org = contact.getOrganization();
|
||||
if (org != null && !org.isEmpty()) {
|
||||
if (org != null && !org.isEmpty() && isOrgVisible) {
|
||||
organization.setText(org);
|
||||
} else {
|
||||
organization.setVisibility(View.GONE);
|
||||
|
|
|
@ -204,10 +204,17 @@ public class ContactEditorFragment extends Fragment {
|
|||
}
|
||||
});
|
||||
|
||||
|
||||
organization = (EditText) view.findViewById(R.id.contactOrganization);
|
||||
boolean isOrgVisible = getResources().getBoolean(R.bool.display_contact_organization);
|
||||
if (!isOrgVisible) {
|
||||
organization.setVisibility(View.GONE);
|
||||
view.findViewById(R.id.contactOrganizationTitle).setVisibility(View.GONE);
|
||||
} else {
|
||||
if (!isNewContact) {
|
||||
organization.setText(contact.getOrganization());
|
||||
}
|
||||
}
|
||||
|
||||
if (!isNewContact) {
|
||||
String fn = contact.getFirstName();
|
||||
|
|
|
@ -501,8 +501,9 @@ public class ContactsListFragment extends Fragment implements OnClickListener, O
|
|||
}
|
||||
|
||||
TextView organization = (TextView) view.findViewById(R.id.contactOrganization);
|
||||
boolean isOrgVisible = getResources().getBoolean(R.bool.display_contact_organization);
|
||||
String org = contact.getOrganization();
|
||||
if (org != null && !org.isEmpty()) {
|
||||
if (org != null && !org.isEmpty() && isOrgVisible) {
|
||||
organization.setText(org);
|
||||
organization.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
|
|
|
@ -21,10 +21,11 @@ package org.linphone;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
|
||||
import org.linphone.compatibility.Compatibility;
|
||||
import org.linphone.core.LinphoneAddress;
|
||||
import org.linphone.core.LinphoneCore;
|
||||
import org.linphone.core.LinphoneFriend;
|
||||
|
@ -38,11 +39,13 @@ import android.content.ContentResolver;
|
|||
import android.content.Context;
|
||||
import android.database.ContentObserver;
|
||||
import android.database.Cursor;
|
||||
import android.database.MatrixCursor;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.provider.ContactsContract;
|
||||
import android.provider.ContactsContract.CommonDataKinds;
|
||||
import android.provider.ContactsContract.Data;
|
||||
|
||||
interface ContactsUpdatedListener {
|
||||
|
@ -228,14 +231,13 @@ public class ContactsManager extends ContentObserver {
|
|||
contactsFetchTask.execute();
|
||||
}
|
||||
|
||||
|
||||
private class ContactsFetchTask extends AsyncTask<Void, List<LinphoneContact>, List<LinphoneContact>> {
|
||||
@SuppressWarnings("unchecked")
|
||||
protected List<LinphoneContact> doInBackground(Void... params) {
|
||||
List<LinphoneContact> contacts = new ArrayList<LinphoneContact>();
|
||||
|
||||
if (hasContactsAccess()) {
|
||||
Cursor c = Compatibility.getContactsCursor(contentResolver, null);
|
||||
Cursor c = getContactsCursor(contentResolver);
|
||||
if (c != null) {
|
||||
while (c.moveToNext()) {
|
||||
String id = c.getString(c.getColumnIndex(Data.CONTACT_ID));
|
||||
|
@ -247,7 +249,9 @@ public class ContactsManager extends ContentObserver {
|
|||
}
|
||||
}
|
||||
|
||||
for (LinphoneFriend friend : LinphoneManager.getLc().getFriendList()) {
|
||||
LinphoneCore lc = LinphoneManager.getLcIfManagerNotDestroyedOrNull();
|
||||
if (lc != null) {
|
||||
for (LinphoneFriend friend : lc.getFriendList()) {
|
||||
String refkey = friend.getRefKey();
|
||||
if (refkey != null) {
|
||||
boolean found = false;
|
||||
|
@ -262,7 +266,7 @@ public class ContactsManager extends ContentObserver {
|
|||
if (!found) {
|
||||
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
|
||||
LinphoneManager.getLc().removeFriend(friend);
|
||||
lc.removeFriend(friend);
|
||||
} else {
|
||||
// Refkey not null but no contact access => can't link it to native contact so display it on is own
|
||||
LinphoneContact contact = new LinphoneContact();
|
||||
|
@ -277,6 +281,7 @@ public class ContactsManager extends ContentObserver {
|
|||
contacts.add(contact);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (LinphoneContact contact : contacts) {
|
||||
// This will only get name & picture informations to be able to quickly display contacts list
|
||||
|
@ -364,4 +369,38 @@ public class ContactsManager extends ContentObserver {
|
|||
public String getString(int 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;
|
||||
|
||||
import org.linphone.core.LinphoneCore;
|
||||
import org.linphone.core.LinphoneCoreFactory;
|
||||
import org.linphone.mediastream.Log;
|
||||
|
||||
import android.app.AlarmManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
import android.os.SystemClock;
|
||||
|
||||
/*
|
||||
* Purpose of this receiver is to disable keep alives when screen is off
|
||||
|
@ -32,13 +36,37 @@ public class KeepAliveReceiver extends BroadcastReceiver {
|
|||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (!LinphoneService.isReady()) {
|
||||
Log.i("Keep alive broadcast received while Linphone service not ready");
|
||||
return;
|
||||
} else {
|
||||
if (intent.getAction().equalsIgnoreCase(Intent.ACTION_SCREEN_ON)) {
|
||||
LinphoneManager.getLc().enableKeepAlive(true);
|
||||
} else if (intent.getAction().equalsIgnoreCase(Intent.ACTION_SCREEN_OFF)) {
|
||||
LinphoneManager.getLc().enableKeepAlive(false);
|
||||
boolean isDebugEnabled = LinphonePreferences.instance().isDebugEnabled();
|
||||
LinphoneCoreFactory.instance().enableLogCollection(isDebugEnabled);
|
||||
LinphoneCoreFactory.instance().setDebugMode(isDebugEnabled, context.getString(R.string.app_name));
|
||||
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);
|
||||
}
|
||||
|
||||
private boolean willContactsPermissionBeAsked() {
|
||||
return LinphonePreferences.instance().firstTimeAskingForPermission(Manifest.permission.READ_CONTACTS) || ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.READ_CONTACTS);
|
||||
}
|
||||
|
||||
public void checkAndRequestWriteContactsPermission() {
|
||||
checkAndRequestPermission(Manifest.permission.WRITE_CONTACTS, 0);
|
||||
}
|
||||
|
@ -1274,6 +1278,9 @@ public class LinphoneActivity extends Activity implements OnClickListener, Conta
|
|||
ContactsManager.getInstance().enableContactsAccess();
|
||||
ContactsManager.getInstance().fetchContactsAsync();
|
||||
fetchedContactsOnce = true;
|
||||
} else if (contacts != PackageManager.PERMISSION_GRANTED && !willContactsPermissionBeAsked()) {
|
||||
ContactsManager.getInstance().fetchContactsAsync();
|
||||
fetchedContactsOnce = true;
|
||||
} else {
|
||||
checkAndRequestReadContactsPermission();
|
||||
}
|
||||
|
|
|
@ -419,6 +419,7 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
|
|||
friend.edit();
|
||||
friend.setFamilyName(lastName);
|
||||
friend.setGivenName(firstName);
|
||||
friend.setName(fullName);
|
||||
|
||||
for (LinphoneAddress address : friend.getAddresses()) {
|
||||
friend.removeAddress(address);
|
||||
|
@ -443,22 +444,20 @@ public class LinphoneContact implements Serializable, Comparable<LinphoneContact
|
|||
friend.addPhoneNumber(noa.getValue());
|
||||
}
|
||||
}
|
||||
friend.setName(fullName);
|
||||
friend.done();
|
||||
|
||||
if (friend.getAddress() != null) {
|
||||
if (lc.findFriendByAddress(friend.getAddress().asString()) == null) {
|
||||
if (!friend.isAlreadyPresentInFriendList()) {
|
||||
try {
|
||||
lc.addFriend(friend);
|
||||
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();
|
||||
}
|
||||
LinphoneManager.getLcIfManagerNotDestroyedOrNull().addFriend(friend);
|
||||
} 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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -36,10 +36,7 @@ import java.util.Set;
|
|||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
import org.linphone.compatibility.Compatibility;
|
||||
import org.linphone.core.CallDirection;
|
||||
import org.linphone.core.OpenH264DownloadHelperAction;
|
||||
import org.linphone.core.OpenH264DownloadHelperListener;
|
||||
import org.linphone.core.LinphoneAddress;
|
||||
import org.linphone.core.LinphoneBuffer;
|
||||
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.LinphoneCoreException;
|
||||
import org.linphone.core.LinphoneCoreFactory;
|
||||
import org.linphone.core.LinphoneCoreFactoryImpl;
|
||||
import org.linphone.core.LinphoneCoreListener;
|
||||
import org.linphone.core.LinphoneEvent;
|
||||
import org.linphone.core.LinphoneFriend;
|
||||
import org.linphone.core.LinphoneFriendList;
|
||||
import org.linphone.core.LinphoneInfoMessage;
|
||||
import org.linphone.core.LinphoneProxyConfig;
|
||||
import org.linphone.core.OpenH264DownloadHelperListener;
|
||||
import org.linphone.core.PayloadType;
|
||||
import org.linphone.core.PresenceActivityType;
|
||||
import org.linphone.core.PresenceModel;
|
||||
|
@ -85,7 +82,6 @@ import android.app.ProgressDialog;
|
|||
import android.content.BroadcastReceiver;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.PackageManager.NameNotFoundException;
|
||||
|
@ -105,8 +101,6 @@ import android.os.PowerManager;
|
|||
import android.os.PowerManager.WakeLock;
|
||||
import android.os.Vibrator;
|
||||
import android.preference.CheckBoxPreference;
|
||||
import android.provider.MediaStore;
|
||||
import android.provider.MediaStore.Images;
|
||||
import android.provider.Settings;
|
||||
import android.provider.Settings.SettingNotFoundException;
|
||||
import android.telephony.TelephonyManager;
|
||||
|
@ -150,6 +144,8 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag
|
|||
private boolean echoTesterIsRunning;
|
||||
private int mLastNetworkType=-1;
|
||||
private ConnectivityManager mConnectivityManager;
|
||||
private BroadcastReceiver mKeepAliveReceiver;
|
||||
private IntentFilter mKeepAliveIntentFilter;
|
||||
private Handler mHandler = new Handler();
|
||||
private WakeLock mIncallWakeLock;
|
||||
private static List<LinphoneChatMessage> mPendingChatFileMessage;
|
||||
|
@ -210,11 +206,8 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag
|
|||
private final String mErrorToneFile;
|
||||
private final String mUserCertificatePath;
|
||||
private ByteArrayInputStream mUploadingImageStream;
|
||||
|
||||
private Timer mTimer;
|
||||
|
||||
private BroadcastReceiver mKeepAliveReceiver = new KeepAliveReceiver();
|
||||
|
||||
private void routeAudioToSpeakerHelper(boolean speakerOn) {
|
||||
Log.w("Routing audio to " + (speakerOn ? "speaker" : "earpiece") + ", disabling bluetooth audio route");
|
||||
BluetoothManager.getInstance().disableBluetoothSCO();
|
||||
|
@ -661,11 +654,12 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag
|
|||
public void restartLinphoneCore() {
|
||||
destroyLinphoneCore();
|
||||
startLibLinphone(mServiceContext);
|
||||
|
||||
IntentFilter lFilter = new IntentFilter(Intent.ACTION_SCREEN_ON);
|
||||
lFilter.addAction(Intent.ACTION_SCREEN_OFF);
|
||||
mServiceContext.registerReceiver(mKeepAliveReceiver, lFilter);
|
||||
|
||||
/*
|
||||
You cannot receive this through components declared in manifests, only
|
||||
by explicitly registering for it with Context.registerReceiver(). This is a protected intent that can only
|
||||
be sent by the system.
|
||||
*/
|
||||
mServiceContext.registerReceiver(mKeepAliveReceiver, mKeepAliveIntentFilter);
|
||||
sExited = false;
|
||||
}
|
||||
|
||||
|
@ -699,6 +693,32 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag
|
|||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
mLc = lc;
|
||||
|
||||
|
@ -752,12 +772,18 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag
|
|||
mLc.migrateCallLogs();
|
||||
|
||||
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);
|
||||
mServiceContext.registerReceiver(mKeepAliveReceiver, lFilter);
|
||||
/*
|
||||
You cannot receive this through components declared in manifests, only
|
||||
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();
|
||||
|
||||
|
@ -1025,6 +1051,15 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag
|
|||
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")
|
||||
public void callState(final LinphoneCore lc,final LinphoneCall call, final State state, final String message) {
|
||||
Log.i("New call state [",state,"]");
|
||||
|
@ -1060,7 +1095,7 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag
|
|||
if (state == State.Connected) {
|
||||
if (mLc.getCallsNb() == 1) {
|
||||
requestAudioFocus();
|
||||
Compatibility.setAudioManagerInCallMode(mAudioManager);
|
||||
setAudioManagerInCallMode();
|
||||
}
|
||||
|
||||
if (Hacks.needSoftvolume()) {
|
||||
|
@ -1070,7 +1105,7 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag
|
|||
}
|
||||
|
||||
if (state == State.OutgoingEarlyMedia) {
|
||||
Compatibility.setAudioManagerInCallMode(mAudioManager);
|
||||
setAudioManagerInCallMode();
|
||||
}
|
||||
|
||||
if (state == State.CallReleased || state == State.Error) {
|
||||
|
@ -1150,7 +1185,7 @@ public class LinphoneManager implements LinphoneCoreListener, LinphoneChatMessag
|
|||
|
||||
public void startEcCalibration(LinphoneCoreListener l) throws LinphoneCoreException {
|
||||
routeAudioToSpeaker();
|
||||
Compatibility.setAudioManagerInCallMode((AudioManager)getContext().getSystemService(Context.AUDIO_SERVICE));
|
||||
setAudioManagerInCallMode();
|
||||
Log.i("Set audio mode on 'Voice Communication'");
|
||||
int oldVolume = mAudioManager.getStreamVolume(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 {
|
||||
routeAudioToSpeaker();
|
||||
Compatibility.setAudioManagerInCallMode((AudioManager)getContext().getSystemService(Context.AUDIO_SERVICE));
|
||||
setAudioManagerInCallMode();
|
||||
Log.i("Set audio mode on 'Voice Communication'");
|
||||
int oldVolume = mAudioManager.getStreamVolume(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);
|
||||
}
|
||||
|
||||
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() {
|
||||
if (sExited || instance == null) {
|
||||
// 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.
|
||||
Log.w("Trying to get linphone core while LinphoneManager already destroyed or not created");
|
||||
return null;
|
||||
}
|
||||
return getLc();
|
||||
|
|
|
@ -114,7 +114,6 @@ public final class LinphoneService extends Service {
|
|||
private Notification mCustomNotif;
|
||||
private int mMsgNotifCount;
|
||||
private PendingIntent mNotifContentIntent;
|
||||
private PendingIntent mkeepAlivePendingIntent;
|
||||
private String mNotificationTitle;
|
||||
private boolean mDisableRegistrationStatus;
|
||||
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
|
||||
Intent intent = new Intent(this, KeepAliveHandler.class);
|
||||
mkeepAlivePendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
|
||||
((AlarmManager) this.getSystemService(Context.ALARM_SERVICE)).setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP
|
||||
, SystemClock.elapsedRealtime()+600000
|
||||
, 600000
|
||||
, mkeepAlivePendingIntent);
|
||||
Intent intent = new Intent(this, KeepAliveReceiver.class);
|
||||
PendingIntent keepAlivePendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
|
||||
((AlarmManager) this.getSystemService(Context.ALARM_SERVICE)).setExact(AlarmManager.ELAPSED_REALTIME_WAKEUP
|
||||
, SystemClock.elapsedRealtime() + 600000
|
||||
, keepAlivePendingIntent);
|
||||
|
||||
mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
|
||||
}
|
||||
|
@ -622,6 +620,7 @@ public final class LinphoneService extends Service {
|
|||
}
|
||||
|
||||
instance = null;
|
||||
getContentResolver().unregisterContentObserver(ContactsManager.getInstance());
|
||||
LinphoneManager.destroy();
|
||||
|
||||
// Make sure our notification is gone.
|
||||
|
@ -629,8 +628,6 @@ public final class LinphoneService extends Service {
|
|||
mNM.cancel(INCALL_NOTIF_ID);
|
||||
mNM.cancel(MESSAGE_NOTIF_ID);
|
||||
|
||||
((AlarmManager) this.getSystemService(Context.ALARM_SERVICE)).cancel(mkeepAlivePendingIntent);
|
||||
getContentResolver().unregisterContentObserver(ContactsManager.getInstance());
|
||||
super.onDestroy();
|
||||
}
|
||||
|
||||
|
|
|
@ -431,7 +431,7 @@ public final class LinphoneUtils {
|
|||
StringBuilder sb = new StringBuilder();
|
||||
|
||||
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);
|
||||
|
||||
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.Version;
|
||||
import org.linphone.mediastream.video.capture.hwconf.AndroidCameraConfiguration;
|
||||
import org.linphone.tools.OpenH264DownloadHelper;
|
||||
import org.linphone.purchase.InAppPurchaseActivity;
|
||||
import org.linphone.tools.OpenH264DownloadHelper;
|
||||
import org.linphone.ui.LedPreference;
|
||||
import org.linphone.ui.PreferencesListFragment;
|
||||
|
||||
|
@ -44,11 +44,14 @@ import android.app.AlertDialog;
|
|||
import android.app.FragmentManager;
|
||||
import android.content.DialogInterface;
|
||||
import android.Manifest;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.media.AudioManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.preference.CheckBoxPreference;
|
||||
|
@ -59,6 +62,7 @@ import android.preference.Preference.OnPreferenceChangeListener;
|
|||
import android.preference.Preference.OnPreferenceClickListener;
|
||||
import android.preference.PreferenceCategory;
|
||||
import android.preference.PreferenceScreen;
|
||||
import android.provider.Settings;
|
||||
|
||||
/**
|
||||
* @author Sylvain Berfini
|
||||
|
@ -721,18 +725,17 @@ public class SettingsFragment extends PreferencesListFragment {
|
|||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(LinphoneManager.getInstance().getContext());
|
||||
builder.setCancelable(false);
|
||||
AlertDialog.Builder show = builder.setMessage("Do you agree to download "
|
||||
+ mCodecDownloader.getLicenseMessage()).setPositiveButton("Yes", new DialogInterface.OnClickListener(){
|
||||
builder.setMessage("Do you agree to download " + mCodecDownloader.getLicenseMessage()).setPositiveButton("Yes", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
if (which == DialogInterface.BUTTON_POSITIVE)
|
||||
mCodecDownloader.downloadCodec();
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton("No", new DialogInterface.OnClickListener(){
|
||||
builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
if (which == DialogInterface.BUTTON_NEGATIVE){
|
||||
if (which == DialogInterface.BUTTON_NEGATIVE) {
|
||||
// Disable H264
|
||||
}
|
||||
}
|
||||
|
@ -1025,7 +1028,6 @@ public class SettingsFragment extends PreferencesListFragment {
|
|||
// 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 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());
|
||||
turn.setChecked(mPrefs.isTurnEnabled());
|
||||
|
||||
|
@ -1067,8 +1069,6 @@ public class SettingsFragment extends PreferencesListFragment {
|
|||
findPreference(getString(R.string.pref_ice_enable_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
|
||||
@Override
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
|
@ -1077,8 +1077,6 @@ public class SettingsFragment extends PreferencesListFragment {
|
|||
findPreference(getString(R.string.pref_turn_enable_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
|
||||
@Override
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
|
@ -1087,7 +1085,6 @@ public class SettingsFragment extends PreferencesListFragment {
|
|||
findPreference(getString(R.string.pref_upnp_enable_key)).setOnPreferenceChangeListener(new OnPreferenceChangeListener() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
CheckBoxPreference ice = (CheckBoxPreference) findPreference(getString(R.string.pref_ice_enable_key));
|
||||
boolean value = (Boolean) newValue;
|
||||
mPrefs.setUpnpEnabled(value);
|
||||
return true;
|
||||
|
@ -1198,6 +1195,24 @@ public class SettingsFragment extends PreferencesListFragment {
|
|||
}
|
||||
});
|
||||
|
||||
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() {
|
||||
@Override
|
||||
public boolean onPreferenceChange(Preference preference, Object newValue) {
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
||||
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.os.Bundle;
|
||||
import android.os.Handler;
|
||||
|
@ -29,15 +36,6 @@ import android.widget.Button;
|
|||
import android.widget.ProgressBar;
|
||||
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
|
||||
*/
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
import org.linphone.R;
|
||||
import org.linphone.compatibility.Compatibility;
|
||||
|
||||
import android.app.Fragment;
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.Html;
|
||||
import android.text.TextWatcher;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.view.LayoutInflater;
|
||||
|
@ -53,7 +53,7 @@ public class LinphoneLoginFragment extends Fragment implements OnClickListener,
|
|||
password = (EditText) view.findViewById(R.id.assistant_password);
|
||||
password.addTextChangedListener(this);
|
||||
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());
|
||||
displayName = (EditText) view.findViewById(R.id.assistant_display_name);
|
||||
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 org.linphone.R;
|
||||
import org.linphone.mediastream.Log;
|
||||
|
||||
import android.annotation.TargetApi;
|
||||
import android.app.Notification;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.ContentUris;
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Bitmap;
|
||||
import android.media.AudioManager;
|
||||
import android.net.Uri;
|
||||
import android.provider.ContactsContract;
|
||||
import android.provider.ContactsContract.CommonDataKinds.SipAddress;
|
||||
|
@ -120,21 +116,6 @@ public class ApiElevenPlus {
|
|||
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) {
|
||||
Intent intent = new Intent(Intent.ACTION_INSERT, Contacts.CONTENT_URI);
|
||||
intent.putExtra(ContactsContract.Intents.Insert.NAME, displayName);
|
||||
|
|
|
@ -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)
|
||||
public class ApiSixteenPlus {
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static Notification createMessageNotification(Context context,
|
||||
int msgCount, String msgSender, String msg, Bitmap contactIcon,
|
||||
PendingIntent intent) {
|
||||
|
|
|
@ -33,6 +33,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
@TargetApi(21)
|
||||
public class ApiTwentyOnePlus {
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
public static Notification createMessageNotification(Context context,
|
||||
int msgCount, String msgSender, String msg, Bitmap contactIcon,
|
||||
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
|
||||
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 android.app.Activity;
|
||||
import android.app.Notification;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.ContentProviderOperation;
|
||||
import android.content.ContentResolver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.graphics.Bitmap;
|
||||
import android.media.AudioManager;
|
||||
import android.net.Uri;
|
||||
import android.os.PowerManager;
|
||||
import android.preference.Preference;
|
||||
import android.provider.Settings;
|
||||
import android.text.Html;
|
||||
import android.text.Spanned;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
|
||||
/**
|
||||
* @author Sylvain Berfini
|
||||
*/
|
||||
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) {
|
||||
Notification notif = null;
|
||||
|
||||
if (Version.sdkAboveOrEqual(Version.API21_LOLLIPOP_50)) {
|
||||
return ApiTwentyOnePlus.createSimpleNotification(context, title, text, intent);
|
||||
} else if (Version.sdkAboveOrEqual(Version.API16_JELLY_BEAN_41)) {
|
||||
notif = ApiSixteenPlus.createSimpleNotification(context, title, text, intent);
|
||||
} else if (Version.sdkAboveOrEqual(Version.API11_HONEYCOMB_30)) {
|
||||
notif = ApiElevenPlus.createSimpleNotification(context, title, text, intent);
|
||||
} else {
|
||||
notif = ApiFivePlus.createSimpleNotification(context, title, text, intent);
|
||||
notif = ApiElevenPlus.createSimpleNotification(context, title, text, intent);
|
||||
}
|
||||
return notif;
|
||||
}
|
||||
|
||||
public static Notification createMessageNotification(Context context, int msgCount, String msgSender, String msg, Bitmap contactIcon, PendingIntent intent) {
|
||||
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)) {
|
||||
return ApiTwentyOnePlus.createMessageNotification(context, msgCount, msgSender, msg, contactIcon, intent);
|
||||
} else if (Version.sdkAboveOrEqual(Version.API16_JELLY_BEAN_41)) {
|
||||
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 {
|
||||
notif = ApiFivePlus.createMessageNotification(context, title, msg, intent);
|
||||
notif = ApiElevenPlus.createMessageNotification(context, msgCount, msgSender, msg, contactIcon, intent);
|
||||
}
|
||||
return notif;
|
||||
}
|
||||
|
||||
public static Notification createInCallNotification(Context context, String title, String msg, int iconID, Bitmap contactIcon, String contactName, PendingIntent intent) {
|
||||
Notification notif = null;
|
||||
|
||||
if (Version.sdkAboveOrEqual(Version.API21_LOLLIPOP_50)) {
|
||||
return ApiTwentyOnePlus.createInCallNotification(context, title, msg, iconID, contactIcon, contactName, intent);
|
||||
} else if (Version.sdkAboveOrEqual(Version.API16_JELLY_BEAN_41)) {
|
||||
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 {
|
||||
notif = ApiFivePlus.createInCallNotification(context, title, msg, iconID, intent);
|
||||
notif = ApiElevenPlus.createInCallNotification(context, title, msg, iconID, contactIcon, contactName, intent);
|
||||
}
|
||||
return notif;
|
||||
}
|
||||
|
@ -211,20 +74,11 @@ public class Compatibility {
|
|||
return ApiTwentyOnePlus.createNotification(context, title, message, icon, iconLevel, largeIcon, intent, isOngoingEvent,priority);
|
||||
} else if (Version.sdkAboveOrEqual(Version.API16_JELLY_BEAN_41)) {
|
||||
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 {
|
||||
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) {
|
||||
if (Version.sdkAboveOrEqual(Version.API08_FROYO_22)) {
|
||||
CompatibilityScaleGestureDetector csgd = new CompatibilityScaleGestureDetector(context);
|
||||
|
@ -234,108 +88,12 @@ public class Compatibility {
|
|||
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) {
|
||||
if (Version.sdkAboveOrEqual(Version.API16_JELLY_BEAN_41)) {
|
||||
ApiSixteenPlus.removeGlobalLayoutListener(viewTreeObserver, keyboardListener);
|
||||
} else {
|
||||
ApiFivePlus.removeGlobalLayoutListener(viewTreeObserver, 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();
|
||||
viewTreeObserver.removeGlobalOnLayoutListener(keyboardListener);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -354,4 +112,12 @@ public class Compatibility {
|
|||
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
|
||||
protected void onError(Context context, String errorId) {
|
||||
initLogger(context);
|
||||
Log.e("Error while registering push notification : " + errorId);
|
||||
Log.e("[Push Notification] Error while registering: " + errorId);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMessage(Context context, Intent intent) {
|
||||
initLogger(context);
|
||||
Log.d("Push notification received");
|
||||
Log.d("[Push Notification] Received");
|
||||
|
||||
if (!LinphoneService.isReady()) {
|
||||
startService(new Intent(ACTION_MAIN).setClass(this, LinphoneService.class));
|
||||
|
@ -79,7 +79,7 @@ public class GCMService extends GCMBaseIntentService {
|
|||
@Override
|
||||
protected void onRegistered(Context context, String regId) {
|
||||
initLogger(context);
|
||||
Log.d("Registered push notification : " + regId);
|
||||
Log.d("[Push Notification] Registered: " + regId);
|
||||
|
||||
LinphonePreferences.instance().setPushNotificationRegistrationID(regId);
|
||||
}
|
||||
|
@ -87,7 +87,7 @@ public class GCMService extends GCMBaseIntentService {
|
|||
@Override
|
||||
protected void onUnregistered(Context context, String regId) {
|
||||
initLogger(context);
|
||||
Log.w("Unregistered push notification : " + regId);
|
||||
Log.w("[Push Notification] Unregistered: " + regId);
|
||||
|
||||
LinphonePreferences.instance().setPushNotificationRegistrationID(null);
|
||||
}
|
||||
|
|
|
@ -162,8 +162,7 @@ public class TutorialCardDavSync extends Activity implements OnClickListener, Li
|
|||
}
|
||||
|
||||
@Override
|
||||
public void onLinphoneFriendSyncStatusChanged(LinphoneFriendList list,
|
||||
org.linphone.core.LinphoneFriendList.State status, String message) {
|
||||
public void onLinphoneFriendSyncStatusChanged(LinphoneFriendList list, LinphoneFriendList.State status, String message) {
|
||||
// TODO Auto-generated method stub
|
||||
String msg = "Sync status changed: " + status.toString() + " (" + message + ")";
|
||||
myLog(msg);
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.linphone.LinphoneContact;
|
|||
import org.linphone.LinphoneManager;
|
||||
import org.linphone.LinphoneUtils;
|
||||
import org.linphone.R;
|
||||
import org.linphone.compatibility.Compatibility;
|
||||
import org.linphone.core.LinphoneBuffer;
|
||||
import org.linphone.core.LinphoneChatMessage;
|
||||
import org.linphone.core.LinphoneChatMessage.State;
|
||||
|
@ -52,7 +53,6 @@ import android.net.Uri;
|
|||
import android.os.AsyncTask;
|
||||
import android.os.Environment;
|
||||
import android.provider.MediaStore;
|
||||
import android.text.Html;
|
||||
import android.text.Spannable;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.Spanned;
|
||||
|
@ -312,7 +312,7 @@ public class BubbleChat implements LinphoneChatMessage.LinphoneChatMessageListen
|
|||
text = text.replaceFirst(link, "<a href=\"" + link + "\">" + linkWithoutScheme + "</a>");
|
||||
}
|
||||
|
||||
return Html.fromHtml(text);
|
||||
return Compatibility.fromHtml(text);
|
||||
}
|
||||
|
||||
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>
|
||||
<exec executable="bash" unless:set="has.crashed">
|
||||
<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>
|
||||
|
||||
<zip destfile="${archive.name}.zip">
|
||||
|
|
Loading…
Reference in a new issue