I want to show the distinct sms sender mobile numbers in Autocomplete textview.
when user selects a particular number. I need to display a number of messages of that number.I know how to get the contacts from the mobile I am displaying it in autocomplete textview but I need sms sender numbers to the autocomplete text.
Here is my code :
public class contactapp extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.autocomplete_4);
ContentResolver content = getContentResolver();
Cursor cursor = content.query(Contacts.People.CONTENT_URI,
PEOPLE_PROJECTION, null, null, Contacts.People.DEFAULT_SORT_ORDER);
ContactListAdapter adapter = new ContactListAdapter(this, cursor);
AutoCompleteTextView textView = (AutoCompleteTextView)
findViewById(R.id.edit);
textView.setAdapter(adapter);
}
public static class ContactListAdapter extends CursorAdapter implements Filterable {
Cursor cu;
public ContactListAdapter(Context context, Cursor c) {
super(context, c);
mContent = context.getContentResolver();
cu=c;
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
final LayoutInflater inflater = LayoutInflater.from(context);
final TextView view = (TextView) inflater.inflate(
android.R.layout.simple_dropdown_item_1line, parent, false);
view.setText(cursor.getString(5));
return view;
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
((TextView) view).setText(cursor.getString(5));
}
#Override
public String convertToString(Cursor cursor) {
return cursor.getString(5);
}
#Override
public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
if (getFilterQueryProvider() != null) {
return getFilterQueryProvider().runQuery(constraint);
}
StringBuilder buffer = null;
String[] args = null;
if (constraint != null) {
buffer = new StringBuilder();
buffer.append("UPPER(");
buffer.append(Contacts.ContactMethods.NAME);
buffer.append(") GLOB ?");
args = new String[] { constraint.toString().toUpperCase() + "*" };
}
return mContent.query(Contacts.People.CONTENT_URI, PEOPLE_PROJECTION,
buffer == null ? null : buffer.toString(), args,
Contacts.People.DEFAULT_SORT_ORDER);
}
private ContentResolver mContent;
}
private static final String[] PEOPLE_PROJECTION = new String[] {
Contacts.People._ID,
Contacts.People.PRIMARY_PHONE_ID,
Contacts.People.TYPE,
Contacts.People.NUMBER,
Contacts.People.LABEL,
Contacts.People.NAME,
};
}
Related
I am creting music player app and I got music files from device but it is not in shorted order.
It is displaying like this (Not in sorted order)
Code which displays songs in ListView :
public class songlist extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
private ListView lv_songlist;
public Cursor cursor;
private MediaCursorAdapter mediaAdapter = null;
private String currentFile;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.songlist);
lv_songlist = (ListView) findViewById(R.id.songlist);
cursor = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, null);
if (null != cursor) {
cursor.moveToFirst();
mediaAdapter = new MediaCursorAdapter(this, R.layout.listitem, cursor);
}
}
private class MediaCursorAdapter extends SimpleCursorAdapter {
public MediaCursorAdapter(Context context, int layout, Cursor c) {
super(context, layout, c,
new String[]{MediaStore.MediaColumns.DISPLAY_NAME, MediaStore.MediaColumns.TITLE, MediaStore.Audio.AudioColumns.DURATION},
new int[]{R.id.displayname, R.id.title, R.id.duration});
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
TextView title = (TextView) view.findViewById(R.id.title);
TextView name = (TextView) view.findViewById(R.id.displayname);
TextView duration = (TextView) view.findViewById(R.id.duration);
name.setText(cursor.getString(
cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME)));
title.setText(cursor.getString(
cursor.getColumnIndex(MediaStore.MediaColumns.TITLE)));
long durationInMs = Long.parseLong(cursor.getString(
cursor.getColumnIndex(MediaStore.Audio.AudioColumns.DURATION)));
Duration d = new Duration();
String durationInMin = d.convertDuration(durationInMs);
duration.setText("" + durationInMin);
view.setTag(cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.DATA)));
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
LayoutInflater inflater = LayoutInflater.from(context);
View v = inflater.inflate(R.layout.listitem, parent, false);
bindView(v, context, cursor);
return v;
}
}
}
Create string like this :
private String sortOrder = MediaStore.MediaColumns.DISPLAY_NAME+"";
And pass this string to last argument in contentResolver.query method's last parameter :
cursor = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, sortOrder);
I'm in some trouble with custom cursorAdapter and AsyncTask. I wanted to setup listView and adapter first and after that in asyctask to query data from database. But for a first time cursor in adapter is null and it throws an a exception. How can be handled this such on situation in my custom cursor adapter? Relocation of setAdapter to onPostExecute didn't helped also. Any suggestions will be also great.
Main activity:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ConversationsListCursorAdapter conversationsListCursorAdapter = new ConversationsListCursorAdapter(context, R.layout.conversations_list_item, null, 0);
conversationsListView = (ListView) findViewById(android.R.id.list);
conversationsListView.setAdapter(conversationsListCursorAdapter);
}
#Override
protected void onResume() {
super.onResume();
new GetConversationsTask().execute((Object[]) null);
}
#Override
protected void onStop() {
Cursor cursor = conversationsListCursorAdapter.getCursor();
if (cursor != null) {
cursor.close();
}
conversationsListCursorAdapter.changeCursor(null);
super.onStop();
}
private class GetConversationsTask extends AsyncTask<Object, Object, Cursor> {
#SuppressLint("NewApi")
#Override
protected Cursor doInBackground(Object... params) {
Uri uri = ClouContentProvider.CONVERSATIONS_CONTENT_URI;
Cursor cursor = null;
if (android.os.Build.VERSION.SDK_INT < 11) {
cursor = getContentResolver().query(uri, null, null, null, null);
} else {
CursorLoader cursorLoader = new CursorLoader(context, uri, null, null, null, null);
cursor = cursorLoader.loadInBackground();
}
return cursor;
}
#Override
protected void onPostExecute(Cursor cursor) {
conversationsListCursorAdapter.changeCursor(cursor);
cursor.close();
}
}
Cursor adapter:
public class ConversationsListCursorAdapter extends CursorAdapter {
private final Cursor mCursor;
private final Context mContext;
private final int mLayout;
private final int mSnippetIndex;
private final int mDateIndex;
private final int mMessageCount;
private final int mRead;
private final LayoutInflater mLayoutInflater;
//private static final String TAG = ConversationsListCursorAdapter.class.getSimpleName();
static class ViewHolder {
TextView tvBody;
TextView tvPerson;
TextView tvCount;
TextView tvDate;
QuickContactBadge ivPhoto;
View vRead;
}
public ConversationsListCursorAdapter(Context context, int layout, Cursor cursor, int flags) {
super(context, cursor, flags);
this.mContext = context;
this.mLayout = layout;
this.mCursor = cursor;
this.mSnippetIndex = mCursor.getColumnIndex(ConversationsProviderMetaData.ConversationsTableMetaData.SNIPPET);
this.mDateIndex = mCursor.getColumnIndex(ConversationsProviderMetaData.ConversationsTableMetaData.DATE);
this.mMessageCount = mCursor.getColumnIndex(ConversationsProviderMetaData.ConversationsTableMetaData.MESSAGE_COUNT);
this.mRead = mCursor.getColumnIndex(ConversationsProviderMetaData.ConversationsTableMetaData.READ);
this.mLayoutInflater = LayoutInflater.from(mContext);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
View rowView = mLayoutInflater.inflate(mLayout, parent, false);
ViewHolder holder = new ViewHolder();
holder.tvBody = (TextView) rowView.findViewById(R.id.body);
holder.tvPerson = (TextView) rowView.findViewById(R.id.addr);
holder.tvCount = (TextView) rowView.findViewById(R.id.count);
holder.tvDate = (TextView) rowView.findViewById(R.id.date);
holder.ivPhoto = (QuickContactBadge) rowView.findViewById(R.id.photo);
holder.vRead = (View) rowView.findViewById(R.id.read);
rowView.setTag(holder);
return rowView;
}
#Override
public void bindView(View v, Context context, Cursor cursor) {
ViewHolder holder = (ViewHolder) v.getTag();
String cBody = cursor.getString(mSnippetIndex);
Integer cCount = cursor.getInt(mMessageCount);
Long cDate = cursor.getLong(mDateIndex);
Integer cRead = cursor.getInt(mRead);
holder.tvBody.setText(cBody);
if (cCount < 0) {
holder.tvCount.setText("");
} else {
holder.tvCount.setText("(" + cCount + ")");
}
if (cRead == 0) {
holder.vRead.setVisibility(View.VISIBLE);
} else {
holder.vRead.setVisibility(View.INVISIBLE);
}
holder.tvDate.setText(ClouUtils.getDate(context, cDate));
holder.tvPerson.setText(cursor.getString(mCursor.getColumnIndex(ConversationsProviderMetaData.ConversationsTableMetaData.CANONICAL)));
holder.ivPhoto.setImageResource(R.drawable.ic_contact_picture);
holder.ivPhoto.setVisibility(View.VISIBLE);
}
#Override
protected void onPostExecute(Cursor cursor) {
// First check if it's null
if(cursor !=null){
// use swap to get the old cursor and close it
Cursor oldC = conversationsListCursorAdapter.swapCursor(cursor);
if(oldC != null){
oldC.close();
}
// DO NOT CLOSE THE NEW CURSOR
// this one you must close whenever the list goes onPause(); but not before
}
}
Good day all, please been having this trouble and i can't seem to see why. Basically what am trying to do is pick a contact via the contact api, save in database, and then display in a listview. but for some reason, after i get the contacts details, my custom adapter is not called anymore, its only called on when the activity is first created, and hence empty. Please what could i have missed. Thank you.
heres my code:
public class GroupDetails extends FragmentActivity implements OnClickListener, LoaderCallbacks<Cursor> {
//variable for debugging the application
public static final String TAG = "MyApp.Debug";
//request code for using with action pick intent
static final int PICK_CONTACT = 1;
//initial variables
Button add_button;
TextView label;
ListView list;
ResponderDB dbadapter;
DueCustomCursorAdapter cursoradapter;
//DueCustomCursorLoader loader;
//cursor to retrieve contact details
private Cursor contactsCursor;
String groupname;
long rowId;
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.group_detail_list);
//only intialize here. database will be open in custom cursor loader
dbadapter = new ResponderDB(this);
getSupportLoaderManager().initLoader(0, null, this);
/*Read intent and the extras passed*/
Bundle extra = getIntent().getExtras();
if(!extra.isEmpty() || extra.equals(null)){
groupname = extra.getString("group_name");
rowId = extra.getLong("rowId");
}
list = (ListView)findViewById(android.R.id.list);
add_button = (Button)findViewById(R.id.add_button_id);
label = (TextView)findViewById(R.id.group_label_id);
Log.d(TAG, "calling custom adapter here now");
cursoradapter = new DueCustomCursorAdapter(GroupDetails.this, null, CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER );
list.setAdapter(cursoradapter);
add_button.setOnClickListener(this);
}
#Override
public void onClick(View view) {
int selection = view.getId();
if(selection == R.id.add_button_id){
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(intent, PICK_CONTACT);
}
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data){
if(requestCode == PICK_CONTACT){
getContactInfo(data);
}
}
private void getContactInfo(Intent intent) {
String number = null;
String name = null;
String[] projection = {ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME,
ContactsContract.CommonDataKinds.Phone.NUMBER};
CursorLoader loader = new CursorLoader(this,intent.getData(),
null,null,null,null);
contactsCursor = loader.loadInBackground();
if(contactsCursor.moveToFirst()){
String id = contactsCursor.getString(contactsCursor.getColumnIndex(ContactsContract.Contacts._ID));
name = contactsCursor.getString(contactsCursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
//get the Phone Number
Cursor numberCursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI
, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = ?", new String[] {id}, null);
while(numberCursor.moveToNext()){
number = numberCursor.getString(numberCursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
}
}
Log.d(TAG, "Successfully added contacts for group");
//dbadapter.updateGroup(rowId, values);
dbadapter.saveContacts(name, number, String.valueOf(rowId));
cursoradapter.notifyDataSetChanged();
getSupportLoaderManager().getLoader(0).onContentChanged();
}
public static final class DueCustomCursorLoader extends SimpleCursorLoader {
public static final String TAG = "MyApp.Debug";
public static int RETRIEVE_CODE = 1;
ResponderDB dbadapter1;
int retrieveCode;
public DueCustomCursorLoader(Context context, ResponderDB dbadapter) {
super(context);
this.dbadapter1= dbadapter;
}
public DueCustomCursorLoader(Context context, ResponderDB dbadapter, int retrieveCode){
super(context);
this.dbadapter1 = dbadapter;
this.retrieveCode = retrieveCode;
}
#Override
public Cursor loadInBackground() {
Cursor cursor = null;
dbadapter1.open();
cursor = dbadapter1.readContact(retrieveCode);
return cursor;
}
}
public class DueCustomCursorAdapter extends CursorAdapter {
public static final String TAG = "SmsResponder.Debug";
private Context myContext;
public DueCustomCursorAdapter(Context context,Cursor c, int flags) {
super(context, c, flags);
myContext = context;
}
//never seem to get here
#Override
public void bindView(View view, Context context, Cursor cursor) {
ViewHolder holder = (ViewHolder)view.getTag();
String contactName = cursor.getString(cursor.getColumnIndexOrThrow(ResponderDB.NAME));
String contactNumber = cursor.getString(cursor.getColumnIndex(ResponderDB.NUMBER));
Log.d(TAG, "contact name is " + contactName);
Log.d(TAG, "contact number is " + contactNumber);
holder.contact_name.setText(contactName);
holder.contact_number.setText(contactNumber);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
ViewHolder holder = new ViewHolder();
View view = LayoutInflater.from(myContext).inflate(R.layout.group_detail_item, parent,false);
holder.contact_name = (TextView)view.findViewById(R.id.group_item_id);
holder.contact_number = (TextView)view.findViewById(R.id.group_subitem_id);
view.setTag(holder);
return view;
}
}
static class ViewHolder {
TextView text;
TextView contact_name;
TextView contact_number;
CheckBox checkbox;
}
#Override
public Loader<Cursor> onCreateLoader(int id, Bundle arg1) {
return new DueCustomCursorLoader(GroupDetails.this, dbadapter, (int)rowId);
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
cursoradapter.swapCursor(data);
}
#Override
public void onLoaderReset(Loader<Cursor> arg0) {
cursoradapter.swapCursor(null);
}
}
Am not getting any issue from the database, so code not added here.
After saving contact to the database You need to restartLoader() to get yours database requery and let onLoadFinished to be called again to allow adapter work with new data.
I would try reversing these two lines (it looks to me like your telling the list to update itself before you update the cursor):
cursoradapter.notifyDataSetChanged();
getSupportLoaderManager().getLoader(0).onContentChanged();
To this:
getSupportLoaderManager().getLoader(0).onContentChanged();
cursoradapter.notifyDataSetChanged();
I'm trying to fill a grid view using data from a db cursor using a custom SimpleCursorAdapter.
My cursor has data (I checked), but nothing is shown in the GridView, and the getView() method is not even called.
Anybody can help? Why is getView() not called?
Thanks
Activity
dbAdapter = new DBAdapter(this);
dbAdapter.open();
Cursor c;
c = dbAdapter.fetchPCList();
startManagingCursor(c);
String[] from = new String[] {};
int[] to = new int[] {};
GridView gridview = (GridView) findViewById(R.id.gridview);
gridview.setAdapter(new PCIconAdapter(this, R.layout.pc_icon, c, from, to));
c.close();
dbAdapter.close();
Adapter
public class PCIconAdapter extends SimpleCursorAdapter {
private final Context mContext;
private final int mLayout;
private final Cursor mCursor;
private final int mPCIDIndex;
private final int mClassNameIndex;
private final LayoutInflater mLayoutInflater;
private final class ViewHolder {
public TextView pc_id_view;
public TextView clas_name_view;
}
public PCIconAdapter(Context context, int layout, Cursor c, String[] from, int[] to) {
super(context, layout, c, from, to);
this.mContext = context;
this.mLayout = layout;
this.mCursor = c;
this.mPCIDIndex = mCursor.getColumnIndex(DBAdapter.KEY_PC_LM_ID);
this.mClassNameIndex = mCursor.getColumnIndex(DBAdapter.KEY_PC_CLAS_NAME);
this.mLayoutInflater = LayoutInflater.from(mContext);
}
public View getView(int position, View convertView, ViewGroup parent) {
if (mCursor.moveToPosition(position)) {
ViewHolder viewHolder;
if (convertView == null) {
convertView = mLayoutInflater.inflate(mLayout, null);
viewHolder = new ViewHolder();
viewHolder.pc_id_view = (TextView) convertView.findViewById(R.id.pc_id);
viewHolder.clas_name_view = (TextView) convertView.findViewById(R.id.clas_name);
convertView.setTag(viewHolder);
}
else {
viewHolder = (ViewHolder) convertView.getTag();
}
String pc_id = mCursor.getString(mPCIDIndex);
String clas_name = mCursor.getString(mClassNameIndex);
viewHolder.pc_id_view.setText(pc_id);
viewHolder.clas_name_view.setText(clas_name);
}
return convertView;
}
}
I had the same problem. I was using an ArrayAdapter and then I changed to a SimpleCursorAdapter, but it doesn't show anything on screen.
I removed
c.close();
dbAdapter.close();
and now its working fine.
because CursorAdapter does not have getView method . it have newView method .
so extend SimpleCursorAdapter and overRide newWiev and other methods like
public class ContactListCursorAdapter extends SimpleCursorAdapter implements Filterable {
private Context context;
private int layout;
public ContactListCursorAdapter (Context context, int layout, Cursor c, String[] from, int[] to) {
super(context, layout, c, from, to);
this.context = context;
this.layout = layout;
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
Cursor c = getCursor();
final LayoutInflater inflater = LayoutInflater.from(context);
View v = inflater.inflate(layout, parent, false);
int nameCol = c.getColumnIndex(People.NAME);
String name = c.getString(nameCol);
/**
* Next set the name of the entry.
*/
TextView name_text = (TextView) v.findViewById(R.id.name_entry);
if (name_text != null) {
name_text.setText(name);
}
return v;
}
#Override
public void bindView(View v, Context context, Cursor c) {
int nameCol = c.getColumnIndex(People.NAME);
String name = c.getString(nameCol);
/**
* Next set the name of the entry.
*/
TextView name_text = (TextView) v.findViewById(R.id.name_entry);
if (name_text != null) {
name_text.setText(name);
}
}
#Override
public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
if (getFilterQueryProvider() != null) { return getFilterQueryProvider().runQuery(constraint); }
StringBuilder buffer = null;
String[] args = null;
if (constraint != null) {
buffer = new StringBuilder();
buffer.append("UPPER(");
buffer.append(People.NAME);
buffer.append(") GLOB ?");
args = new String[] { constraint.toString().toUpperCase() + "*" };
}
return context.getContentResolver().query(People.CONTENT_URI, null,
buffer == null ? null : buffer.toString(), args, People.NAME + " ASC");
}
}
Your column names array and Views array are empty. So column name to views mapping will never occur. That maybe the reason you are not getting callback on getView
If I remove
c.close();
dbAdapter.close();
it works...
So where am I supposed to close this cursor?...
I have implemented an autocomplete feature in my application, but it picks up only the name of the contact instead of the number. Whenever i select a field in the autocomplete textbox, the number should be picked from the phone's contact list and placed in the text box...please help me out! :)
public class AutoMultipleContacts extends Activity {
private static final int PICK_CONTACT = 1;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.multipleselect);
Cursor peopleCursor = getContentResolver().query(Contacts.People.CONTENT_URI, PEOPLE_PROJECTION, null, null, Contacts.People.DEFAULT_SORT_ORDER);
ContactListAdapter contactadapter = new ContactListAdapter(this,peopleCursor);
MultiAutoCompleteTextView textView = (MultiAutoCompleteTextView) findViewById(R.id.contacts);
textView.setAdapter(contactadapter);
textView.setTokenizer(new MultiAutoCompleteTextView.CommaTokenizer());
}
public static class ContactListAdapter extends CursorAdapter implements Filterable {
public ContactListAdapter(Context context, Cursor c) {
super(context, c);
mContent = context.getContentResolver();
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
final LayoutInflater inflater = LayoutInflater.from(context);
final TextView view = (TextView) inflater.inflate(
android.R.layout.simple_dropdown_item_1line, parent, false);
view.setText(cursor.getString(5));
return view;
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
((TextView) view).setText(cursor.getString(5));
}
#Override
public String convertToString(Cursor cursor) {
return cursor.getString(5);
}
#Override
public Cursor runQueryOnBackgroundThread(CharSequence constraint) {
if (getFilterQueryProvider() != null) {
return getFilterQueryProvider().runQuery(constraint);
}
StringBuilder buffer = null;
String[] args = null;
if (constraint != null) {
buffer = new StringBuilder();
buffer.append("UPPER(");
buffer.append(Contacts.ContactMethods.NAME);
buffer.append(") GLOB ?");
args = new String[] { constraint.toString().toUpperCase() + "*" };
}
return mContent.query(Contacts.People.CONTENT_URI, PEOPLE_PROJECTION,
buffer == null ? null : buffer.toString(), args,
Contacts.People.DEFAULT_SORT_ORDER);
}
private ContentResolver mContent;
}
private static final String[] PEOPLE_PROJECTION = new String[] {
Contacts.People._ID,
Contacts.People.PRIMARY_PHONE_ID,
Contacts.People.TYPE,
Contacts.People.NUMBER,
Contacts.People.LABEL,
Contacts.People.NAME,
};
}
Try changing
#Override
public String convertToString(Cursor cursor) {
return cursor.getString(5);
}
To
#Override
public String convertToString(Cursor cursor) {
return cursor.getString(3);
}
Append PhoneNumber to the buffer instead of Name and return cursor.getString(3) and setText(cursor.getString(3)). Also People is deprecated now. Use ContactsContracts instead.