Simple search function for contacts
This commit is contained in:
parent
4774e9dd71
commit
63343b607e
5 changed files with 152 additions and 24 deletions
|
@ -67,6 +67,36 @@
|
|||
|
||||
</LinearLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<ImageView
|
||||
android:contentDescription="@string/content_description_cancel"
|
||||
android:id="@+id/clearSearchField"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:adjustViewBounds="true"
|
||||
android:src="@drawable/list_delete"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:paddingLeft="5dp"
|
||||
android:paddingRight="5dp"/>
|
||||
|
||||
<EditText
|
||||
android:textCursorDrawable="@null"
|
||||
android:id="@+id/searchField"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@android:color/black"
|
||||
android:background="@drawable/chat_fast_address_background"
|
||||
android:gravity="center"
|
||||
android:layout_toLeftOf="@id/clearSearchField"
|
||||
android:paddingRight="5dp"
|
||||
android:inputType="textPersonName"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
@ -100,6 +108,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);
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue