0

I am creating a simple SMS app just to start with developing for Android. I want my inbox show the contacts name rather than their number.

The following code is from my onCreate() method:

        // Create adapter and set it to the list view.
    final String[] fromFields = new String[] {
           SmsQuery.PROJECTION[SmsQuery.ADDRESS], SmsQuery.PROJECTION[SmsQuery.BODY] };
    final int[] toViews = new int[] { R.id.text_view_name, R.id.text_view_message };
    mAdapter = new SimpleCursorAdapter(this, R.layout.convo_list,
            null, fromFields, toViews, 0);
    listView.setAdapter(mAdapter);

    // Simple query to show the most recent SMS messages in the inbox.
    getSupportLoaderManager().initLoader(SmsQuery.TOKEN, null, this);

Then I have the following in the onCreateLoader method:

    public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
    if (i == SmsQuery.TOKEN) {
        // Fetch all SMS messages in the inbox, date desc.
        return new CursorLoader(this, SmsQuery.CONTENT_URI, SmsQuery.PROJECTION,
                null, null, SmsQuery.SORT_ORDER);
    }
    return null;
}

This code uses a LoaderManager with a CursorLoader to get the number and body of the messages in the inbox. I however would like to display the contacts name with the body of the message.

I've looked at various tutorials and suggestions like: How do i get the SMS Sender Contact (Person) saved name using "content://sms/inbox" but these show how to do it with a SimpleCursorAdapter in the UI thread which is not the recommended way to get the SMS inbox according to the documentation (Public Constructors - http://developer.android.com/reference/android/widget/SimpleCursorAdapter.html)

I was hoping to use a PhoneLookup in the onCreateLoader method but that doesn't seem to work.

The SmsQuery interface that is used is as follows:

/**
 * A basic SmsQuery on android.provider.Telephony.Sms.Inbox
 */
private interface SmsQuery {
    int TOKEN = 1;

    static final Uri CONTENT_URI = Telephony.Sms.Inbox.CONTENT_URI;

    static final String[] PROJECTION = {
            Inbox._ID,
            Inbox.THREAD_ID,
            Inbox.ADDRESS,
            Inbox.BODY,
            Inbox.PERSON,
    };

    static final String SORT_ORDER = Telephony.Sms.Inbox.DEFAULT_SORT_ORDER;

    int ID = 0;
    int THREAD_ID = 1;
    int ADDRESS = 2;
    int BODY = 3;
    int PERSON = 4;
}

Any help would be greatly appreciated. Thank you.

Community
  • 1
  • 1
Callum
  • 141
  • 6

2 Answers2

2

i use this code:

private class AllSMSLoader implements LoaderManager.LoaderCallbacks<Cursor> {
    private Context context;

    private AllSMSLoader(Context context) {
        this.context = context;
    }

    @Override
    public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
        final String SMS_ALL = "content://sms/";
        Uri uri = Uri.parse(SMS_ALL);
        String[] projection = new String[]{"_id", "thread_id", "address", "person", "body", "date", "type"};
        return new CursorLoader(context, uri, projection, null, null, "date desc");
    }

    @Override
    public void onLoadFinished(Loader<Cursor> cursorLoader, Cursor cursor) {
        MyLog.v("LoadFinished");
        List<SMS> sms_All = new ArrayList<SMS>();
        List<String> phoneNumbers = new ArrayList<String>();
        while (cursor.moveToNext()) {
            String phoneNumber = cursor.getString(cursor.getColumnIndexOrThrow("address"));
            MyLog.v(phoneNumber);
            int type = cursor.getInt(cursor.getColumnIndexOrThrow("type"));
            if ((!phoneNumbers.contains(phoneNumber)) && (type != 3) && (phoneNumber.length()>=1)) {
                String name = null;
                String person = cursor.getString(cursor.getColumnIndexOrThrow("person"));
                String smsContent = cursor.getString(cursor.getColumnIndexOrThrow("body"));
                Date date = new Date(Long.parseLong(cursor.getString(cursor.getColumnIndexOrThrow("date"))));
                Uri personUri = Uri.withAppendedPath(ContactsContract.PhoneLookup.CONTENT_FILTER_URI, phoneNumber);
                ContentResolver cr = context.getContentResolver();
                Cursor localCursor = cr.query(personUri,
                        new String[]{ContactsContract.Contacts.DISPLAY_NAME},
                        null, null, null);//use phonenumber find contact name
                if (localCursor.getCount() != 0) {
                    localCursor.moveToFirst();
                    name = localCursor.getString(localCursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
                }
                MyLog.v("person:" + person + "  name:" + name + "  phoneNumber:" + phoneNumber);
                localCursor.close();
                phoneNumbers.add(phoneNumber);
                SMS sms = new SMS(name, phoneNumber, smsContent, type, date);
                sms_All.add(sms);
            }
        }
        myadapter.notifyDataSetChanged();
        //simpleCursorAdapter.swapCursor(cursor);
    }

    @Override
    public void onLoaderReset(Loader<Cursor> cursorLoader) {
        //simpleCursorAdapter.swapCursor(null);
    }
}

i use baseadapter,if you use simplecursoradapter,you better bind custom viewbinder. simpleCursorAdapter.setViewBinder();//add you custom viewbinder Hope it works for you.

Dirkkk
  • 21
  • 2
  • That does get what I want, however I don't understand how to bind the data to my `ListView`. Where do I have to use the `setViewBinder`? or how can I do it using the `BaseAdapter`? Thank you. – Callum May 19 '14 at 08:58
0

a simpleadapter ex:

    simpleCursorAdapter.setViewBinder(new SimpleCursorAdapter.ViewBinder() {
        @Override
        public boolean setViewValue(View view, Cursor cursor, int i) {
            //get data from curosr
            //bind data to your view
            return false;
        }
    });
    yourListView.setAdapter(simpleCursorAdapter);

override setViewBinder

Dirkkk
  • 21
  • 2
  • I still can't seem to get it to work; so in my `onCreate` I define my `SimpleCursorAdapter` as stated in the question. So how do I swap the phone number for the name in the list? – Callum May 19 '14 at 13:07