【问题标题】:How do I get sms inbox contacts number using a LoaderManager with a CursorLoader如何使用带有 CursorLoader 的 LoaderManager 获取短信收件箱联系人号码
【发布时间】:2014-05-13 08:34:08
【问题描述】:

我正在创建一个简单的 SMS 应用程序,以开始为 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;
}

任何帮助将不胜感激。谢谢。

【问题讨论】:

    标签: android sms android-cursorloader


    【解决方案1】:

    我使用这个代码:

    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,你最好绑定自定义viewbinder。 simpleCursorAdapter.setViewBinder();//添加你自定义的viewbinder 希望它对你有用。

    【讨论】:

    • 这确实得到了我想要的,但是我不明白如何将数据绑定到我的ListView。我必须在哪里使用setViewBinder?或者我如何使用BaseAdapter 来做到这一点?谢谢。
    【解决方案2】:

    一个简单的适配器,例如:

        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

    【讨论】:

    • 我似乎仍然无法让它工作;所以在我的onCreate 中,我定义了我的SimpleCursorAdapter,如问题中所述。那么如何将电话号码换成列表中的姓名呢?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-13
    • 2017-04-09
    • 1970-01-01
    • 1970-01-01
    • 2011-07-25
    • 2012-11-28
    • 2017-11-26
    相关资源
    最近更新 更多