diff --git a/res/layout/contacts_list.xml b/res/layout/contacts_list.xml
index ff9a324e5..7d9eb902b 100644
--- a/res/layout/contacts_list.xml
+++ b/res/layout/contacts_list.xml
@@ -67,6 +67,36 @@
+
+
+
+
+
+
+
+
diff --git a/src/org/linphone/ContactsFragment.java b/src/org/linphone/ContactsFragment.java
index 617241844..3378569e5 100644
--- a/src/org/linphone/ContactsFragment.java
+++ b/src/org/linphone/ContactsFragment.java
@@ -23,12 +23,15 @@ import org.linphone.compatibility.Compatibility;
import org.linphone.core.LinphoneFriend;
import org.linphone.core.PresenceActivityType;
+import android.annotation.SuppressLint;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.support.v4.app.Fragment;
+import android.text.Editable;
+import android.text.TextWatcher;
import android.view.LayoutInflater;
import android.view.View;
import android.view.View.OnClickListener;
@@ -37,6 +40,7 @@ import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AlphabetIndexer;
import android.widget.BaseAdapter;
+import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
@@ -46,6 +50,7 @@ import android.widget.TextView;
/**
* @author Sylvain Berfini
*/
+@SuppressLint("DefaultLocale")
public class ContactsFragment extends Fragment implements OnClickListener, OnItemClickListener {
private Handler mHandler = new Handler();
@@ -57,6 +62,9 @@ public class ContactsFragment extends Fragment implements OnClickListener, OnIte
private AlphabetIndexer indexer;
private boolean editOnClick = false, editConsumed = false, onlyDisplayChatAddress = false;
private String sipAddressToAdd;
+ private ImageView clearSearchField;
+ private EditText searchField;
+ private Cursor searchCursor;
private static ContactsFragment instance;
@@ -99,6 +107,29 @@ public class ContactsFragment extends Fragment implements OnClickListener, OnIte
allContacts.setEnabled(onlyDisplayLinphoneContacts);
linphoneContacts.setEnabled(!allContacts.isEnabled());
+
+
+ clearSearchField = (ImageView) view.findViewById(R.id.clearSearchField);
+ clearSearchField.setOnClickListener(this);
+
+ searchField = (EditText) view.findViewById(R.id.searchField);
+ searchField.addTextChangedListener(new TextWatcher() {
+ @Override
+ public void onTextChanged(CharSequence s, int start, int before, int count) {
+
+ }
+
+ @Override
+ public void beforeTextChanged(CharSequence s, int start, int count,
+ int after) {
+
+ }
+
+ @Override
+ public void afterTextChanged(Editable s) {
+ searchContacts(searchField.getText().toString());
+ }
+ });
return view;
}
@@ -109,22 +140,63 @@ public class ContactsFragment extends Fragment implements OnClickListener, OnIte
if (id == R.id.allContacts) {
onlyDisplayLinphoneContacts = false;
- changeContactsAdapter();
+ if (searchField.getText().toString().length() > 0) {
+ searchContacts();
+ } else {
+ changeContactsAdapter();
+ }
}
else if (id == R.id.linphoneContacts) {
onlyDisplayLinphoneContacts = true;
- changeContactsAdapter();
-
+ if (searchField.getText().toString().length() > 0) {
+ searchContacts();
+ } else {
+ changeContactsAdapter();
+ }
}
else if (id == R.id.newContact) {
editConsumed = true;
LinphoneActivity.instance().addContact(null, sipAddressToAdd);
}
+ else if (id == R.id.clearSearchField) {
+ searchField.setText("");
+ }
+ }
+
+ private void searchContacts() {
+ searchContacts(searchField.getText().toString());
+ }
+
+ private void searchContacts(String search) {
+ if (search == null || search.length() == 0) {
+ changeContactsAdapter();
+ return;
+ }
+
+ changeContactsToggle();
+
+ if (searchCursor != null) {
+ searchCursor.close();
+ }
+
+ if (onlyDisplayLinphoneContacts) {
+ searchCursor = Compatibility.getSIPContactsCursor(getActivity().getContentResolver(), search);
+ indexer = new AlphabetIndexer(searchCursor, Compatibility.getCursorDisplayNameColumnIndex(searchCursor), " ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+ contactsList.setAdapter(new ContactsListAdapter(null, searchCursor));
+ } else {
+ searchCursor = Compatibility.getContactsCursor(getActivity().getContentResolver(), search);
+ indexer = new AlphabetIndexer(searchCursor, Compatibility.getCursorDisplayNameColumnIndex(searchCursor), " ABCDEFGHIJKLMNOPQRSTUVWXYZ");
+ contactsList.setAdapter(new ContactsListAdapter(null, searchCursor));
+ }
}
private void changeContactsAdapter() {
changeContactsToggle();
+ if (searchCursor != null) {
+ searchCursor.close();
+ }
+
Cursor allContactsCursor = LinphoneActivity.instance().getAllContactsCursor();
Cursor sipContactsCursor = LinphoneActivity.instance().getSIPContactsCursor();
@@ -199,6 +271,9 @@ public class ContactsFragment extends Fragment implements OnClickListener, OnIte
@Override
public void onPause() {
instance = null;
+ if (searchCursor != null) {
+ searchCursor.close();
+ }
super.onPause();
}
@@ -206,7 +281,11 @@ public class ContactsFragment extends Fragment implements OnClickListener, OnIte
mHandler.post(new Runnable() {
@Override
public void run() {
- changeContactsAdapter();
+ if (searchField != null && searchField.getText().toString().length() > 0) {
+ searchContacts(searchField.getText().toString());
+ } else {
+ changeContactsAdapter();
+ }
contactsList.setSelectionFromTop(lastKnownPosition, 0);
}
});
@@ -231,7 +310,7 @@ public class ContactsFragment extends Fragment implements OnClickListener, OnIte
}
public Object getItem(int position) {
- if (position >= contacts.size()) {
+ if (contacts == null || position >= contacts.size()) {
return Compatibility.getContact(getActivity().getContentResolver(), cursor, position);
} else {
return contacts.get(position);
diff --git a/src/org/linphone/LinphoneManager.java b/src/org/linphone/LinphoneManager.java
index 4f4ee6996..8099edee5 100644
--- a/src/org/linphone/LinphoneManager.java
+++ b/src/org/linphone/LinphoneManager.java
@@ -21,9 +21,6 @@ package org.linphone;
import static android.media.AudioManager.MODE_RINGTONE;
import static android.media.AudioManager.STREAM_RING;
import static android.media.AudioManager.STREAM_VOICE_CALL;
-import static org.linphone.core.LinphoneCall.State.CallEnd;
-import static org.linphone.core.LinphoneCall.State.Error;
-import static org.linphone.core.LinphoneCall.State.IncomingReceived;
import java.io.File;
import java.io.FileInputStream;
@@ -71,7 +68,6 @@ import org.linphone.core.PayloadType;
import org.linphone.core.PresenceActivityType;
import org.linphone.core.PresenceModel;
import org.linphone.core.PublishState;
-import org.linphone.core.Reason;
import org.linphone.core.SubscriptionState;
import org.linphone.mediastream.Log;
import org.linphone.mediastream.Version;
@@ -184,7 +180,7 @@ public class LinphoneManager implements LinphoneCoreListener {
mRingbackSoundFile = basePath + "/ringback.wav";
mPauseSoundFile = basePath + "/toy_mono.wav";
mChatDatabaseFile = basePath + "/linphone-history.db";
- mErrorToneFile = basePath + "/error_tone.wav";
+ mErrorToneFile = basePath + "/error.wav";
mPrefs = LinphonePreferences.instance();
mAudioManager = ((AudioManager) c.getSystemService(Context.AUDIO_SERVICE));
@@ -964,7 +960,7 @@ public class LinphoneManager implements LinphoneCoreListener {
@SuppressLint("Wakelock")
public void callState(final LinphoneCore lc,final LinphoneCall call, final State state, final String message) {
Log.i("new state [",state,"]");
- if (state == IncomingReceived && !call.equals(lc.getCurrentCall())) {
+ if (state == State.IncomingReceived && !call.equals(lc.getCurrentCall())) {
if (call.getReplacedCall()!=null){
// attended transfer
// it will be accepted automatically.
@@ -972,14 +968,14 @@ public class LinphoneManager implements LinphoneCoreListener {
}
}
- if (state == IncomingReceived && mR.getBoolean(R.bool.auto_answer_calls)) {
+ if (state == State.IncomingReceived && mR.getBoolean(R.bool.auto_answer_calls)) {
try {
mLc.acceptCall(call);
} catch (LinphoneCoreException e) {
e.printStackTrace();
}
}
- else if (state == IncomingReceived || (state == State.CallIncomingEarlyMedia && mR.getBoolean(R.bool.allow_ringing_while_early_media))) {
+ else if (state == State.IncomingReceived || (state == State.CallIncomingEarlyMedia && mR.getBoolean(R.bool.allow_ringing_while_early_media))) {
// Brighten screen for at least 10 seconds
if (mLc.getCallsNb() == 1) {
ringingCall = call;
@@ -991,7 +987,7 @@ public class LinphoneManager implements LinphoneCoreListener {
stopRinging();
}
- if (state == LinphoneCall.State.Connected) {
+ if (state == State.Connected) {
if (mLc.getCallsNb() == 1) {
requestAudioFocus();
Compatibility.setAudioManagerInCallMode(mAudioManager);
@@ -1002,7 +998,7 @@ public class LinphoneManager implements LinphoneCoreListener {
}
}
- if (state == CallEnd || state == Error) {
+ if (state == State.CallReleased || state == State.Error) {
if (mLc.getCallsNb() == 0) {
if (mAudioFocused){
int res=mAudioManager.abandonAudioFocus(null);
@@ -1021,7 +1017,7 @@ public class LinphoneManager implements LinphoneCoreListener {
}
}
- if (state == CallEnd) {
+ if (state == State.CallEnd) {
if (mLc.getCallsNb() == 0) {
if (mIncallWakeLock != null && mIncallWakeLock.isHeld()) {
mIncallWakeLock.release();
diff --git a/src/org/linphone/compatibility/ApiNinePlus.java b/src/org/linphone/compatibility/ApiNinePlus.java
index 2018647c7..b56b1714c 100644
--- a/src/org/linphone/compatibility/ApiNinePlus.java
+++ b/src/org/linphone/compatibility/ApiNinePlus.java
@@ -128,21 +128,28 @@ public class ApiNinePlus {
return list;
}
- public static Cursor getContactsCursor(ContentResolver cr) {
- String req = Data.MIMETYPE + " = '" + CommonDataKinds.Phone.CONTENT_ITEM_TYPE
- + "' AND " + CommonDataKinds.Phone.NUMBER + " IS NOT NULL";
+ public static Cursor getContactsCursor(ContentResolver cr, String search) {
+ 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))";
- req += " 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) {
+ public static Cursor getSIPContactsCursor(ContentResolver cr, String search) {
String req = null;
req = 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);
}
diff --git a/src/org/linphone/compatibility/Compatibility.java b/src/org/linphone/compatibility/Compatibility.java
index 277a65ac6..3bd970992 100644
--- a/src/org/linphone/compatibility/Compatibility.java
+++ b/src/org/linphone/compatibility/Compatibility.java
@@ -82,7 +82,15 @@ public class Compatibility {
public static Cursor getContactsCursor(ContentResolver cr) {
if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) {
- return ApiNinePlus.getContactsCursor(cr);
+ return ApiNinePlus.getContactsCursor(cr, null);
+ } else {
+ return ApiFivePlus.getContactsCursor(cr);
+ }
+ }
+
+ public static Cursor getContactsCursor(ContentResolver cr, String search) {
+ if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) {
+ return ApiNinePlus.getContactsCursor(cr, search);
} else {
return ApiFivePlus.getContactsCursor(cr);
}
@@ -90,7 +98,15 @@ public class Compatibility {
public static Cursor getSIPContactsCursor(ContentResolver cr) {
if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) {
- return ApiNinePlus.getSIPContactsCursor(cr);
+ return ApiNinePlus.getSIPContactsCursor(cr, null);
+ } else {
+ return ApiFivePlus.getSIPContactsCursor(cr);
+ }
+ }
+
+ public static Cursor getSIPContactsCursor(ContentResolver cr, String search) {
+ if (Version.sdkAboveOrEqual(Version.API09_GINGERBREAD_23)) {
+ return ApiNinePlus.getSIPContactsCursor(cr, search);
} else {
return ApiFivePlus.getSIPContactsCursor(cr);
}