如何使用带有CursorLoader的LoaderManager获取短信收件箱联系人号码

时间:2014-05-13 08:34:09

标签: android sms android-cursorloader

我正在创建一个简单的短信应用程序,开始为Android开发。我希望我的收件箱显示联系人姓名而不是他们的号码。

以下代码来自我的onCreate()方法:

        // 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);

然后我在onCreateLoader方法中有以下内容:

    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;
}

此代码使用带有CursorLoader的LoaderManager来获取收件箱中邮件的编号和正文。但是,我希望在邮件正文中显示联系人姓名。

我已经查看了各种教程和建议,例如:How do i get the SMS Sender Contact (Person) saved name using "content://sms/inbox"但是这些教程和建议显示了如何在UI线程中使用SimpleCursorAdapter,这不是根据文档获取SMS收件箱的推荐方法(公共建筑师 - http://developer.android.com/reference/android/widget/SimpleCursorAdapter.html

我希望在onCreateLoader方法中使用PhoneLookup,但这似乎不起作用。

使用的SmsQuery接口如下:

/**
 * 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;
}

非常感谢任何帮助。谢谢。

2 个答案:

答案 0 :(得分:2)

我使用此代码:

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);
    }
}

我使用baseadapter,如果你使用simplecursoradapter,你最好绑定自定义视图。 simpleCursorAdapter.setViewBinder(); //添加自定义视图绑定器 希望它适合你。

答案 1 :(得分:0)

简单的改编者:

    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);

覆盖setViewBinder