使用Loader获取Android联系人列表

来源:互联网 发布:雷锋的故事 知乎 编辑:程序博客网 时间:2024/05/21 07:49

简书地址:http://www.jianshu.com/p/b5147124590e

步骤

  1. 实现 LoaderManager.LoaderCallbacks 接口
  2. 在onCreateLoader(int id, Bundle args)中创建需要的Loader
  3. 在onLoadFinished(Loader loader, final Cursor data)中获取联系人列表,并组装成Json格式返回。

代码:

/** 利用Loader获取通讯录列表* */public class ContactsActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<Cursor> {    private static final int LOAD_ID = 0;    private static final String TAG = ContactsActivity.class.getSimpleName();    private JSONObject result;    public static void launch(Context context, Bundle bundle) {        Intent intent = new Intent(context, ContactsActivity.class);        if (bundle != null) {            intent.putExtras(bundle);        }        context.startActivity(intent);    }    private LoaderManager loaderManager;    private QueryListener listener;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);//        setContentView(R.layout.activity_contacts);        initVar();    }    private void initVar() {        loaderManager = getLoaderManager();        loaderManager.initLoader(LOAD_ID, null, this);        listener = new QueryListener() {            @Override            public void success(final JSONObject object) {                runOnUiThread(new Runnable() {                    @Override                    public void run() {                        new AlertDialog.Builder(ContactsActivity.this)                                .setTitle("通讯录")                                .setMessage(object.toString())                                .show();                    }                });            }        };    }    @Override    public Loader<Cursor> onCreateLoader(int id, Bundle args) {        CursorLoader loader = new CursorLoader(                this,                ContactsContract.Contacts.CONTENT_URI,                null,                null,                null,                null        );        return loader;    }    @Override    public void onLoadFinished(Loader<Cursor> loader, final Cursor data) {        new Thread(new Runnable() {            @Override            public void run() {                JSONArray jsonArray = new JSONArray();                while (data.moveToNext()) {                    String name;                    name = data.getString(                            data.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)                    );                    int id = data.getInt(                            data.getColumnIndex(ContactsContract.Contacts._ID)                    );                    Cursor cursor = getContentResolver().query(                            ContactsContract.CommonDataKinds.Phone.CONTENT_URI,                            null,                            ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + id,                            null,                            null                    );                    while (cursor.moveToNext()) {                        String number = cursor.getString(                                cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)                        );                        jsonArray.put(                                new JsonGenerator()                                        .put("name", name)                                        .put("tel", number)                                        .gen()                        );                    }                    cursor.close();                }                result = new JsonGenerator()                        .put("list",jsonArray)                        .gen();                data.close();                if (listener != null){                    listener.success(result);                }                Log.d(TAG, "onLoadFinished: result =\n" + result.toString());            }        }).start();    }    @Override    public void onLoaderReset(Loader<Cursor> loader) {    }    public void setQueryListener(QueryListener listener) {        this.listener = listener;    }    interface QueryListener{        void success(JSONObject object);    }

初步封装

思路:将回调接口的实现类独立出去,这样就不需要在Activity里实现处理逻辑了。

public class ContactsLoaderCallback implements LoaderManager.LoaderCallbacks<Cursor> {    private static final String TAG = "ContactsLoaderCallback";    private JSONObject result;    private Context context;    private QueryListener listener;    public ContactsLoaderCallback(Context context) {        this.context = context;    }    @Override    public Loader<Cursor> onCreateLoader(int id, Bundle args) {        //指定获取_id和display_name两列数据,display_name即为姓名        String[] projection = new String[]{                ContactsContract.Contacts._ID,                ContactsContract.Contacts.DISPLAY_NAME        };        CursorLoader loader = new CursorLoader(                context,                ContactsContract.Contacts.CONTENT_URI,                projection,                null,                null,                null        );        return loader;    }    @Override    public void onLoadFinished(Loader<Cursor> loader, final Cursor data) {        if (data.isClosed()) {            return;        }        new Thread(new Runnable() {            @Override            public void run() {                JSONArray jsonArray = new JSONArray();                if (data != null && data.moveToFirst()) {                    do {                        String name = data.getString(                                data.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME)                        );                        int id = data.getInt(                                data.getColumnIndex(ContactsContract.Contacts._ID)                        );                        //指定获取NUMBER这一列数据                        String[] phoneProjection = new String[]{                                ContactsContract.CommonDataKinds.Phone.NUMBER                        };                        Cursor cursor = context.getContentResolver().query(                                ContactsContract.CommonDataKinds.Phone.CONTENT_URI,                                phoneProjection,                                ContactsContract.CommonDataKinds.Phone.CONTACT_ID + "=" + id,                                null,                                null                        );                        if (cursor != null && cursor.moveToFirst()) {                            do {                                String number = cursor.getString(                                        cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)                                );                                jsonArray.put(                                        new JsonGenerator()                                                .put("name", name)                                                .put("tel", number)                                                .gen()                                );                            } while (cursor.moveToNext());                        }                    } while (data.moveToNext());                }                result = new JsonGenerator()                        .put("list", jsonArray)                        .gen();                if (listener != null) {                    listener.success(result);                }                Log.d(TAG, "onLoadFinished: result =\n" + result.toString());            }        }).start();    }    @Override    public void onLoaderReset(Loader<Cursor> loader) {    }    public void setQueryListener(QueryListener listener) {        this.listener = listener;    }    public interface QueryListener {        void success(JSONObject object);    }

使用方法:

 ContactsLoaderCallback callback = new ContactsLoaderCallback(this);        callback.setQueryListener(new ContactsLoaderCallback.QueryListener() {            @Override            public void success(final JSONObject object) {                runOnUiThread(new Runnable() {                    @Override                    public void run() {                        new AlertDialog.Builder(SystemActivity.this)                                .setTitle("通讯录")                                .setMessage(object.toString())                                .show();                    }                });            }        });        getLoaderManager().initLoader(0,null,callback);

在Activity使用上述代码就可以了,但是似乎还是有点麻烦。

再次封装

新建一个Helper类

public class ContactHelper {    private static final String TAG = "ContactHelper";    private Activity context;    private JSONObject contacts;    public ContactHelper(Activity context) {        this.context = context;    }    public JSONObject queryContactList(){        final CountDownLatch latch = new CountDownLatch(1);        ContactsLoaderCallback callback = new ContactsLoaderCallback(context);        callback.setQueryListener(new ContactsLoaderCallback.QueryListener() {            @Override            public void success(final JSONObject object) {                contacts = object;                latch.countDown();            }        });        context.getLoaderManager().restartLoader(0,null,callback);        try {            latch.await();        } catch (InterruptedException e) {            e.printStackTrace();        }        return contacts;    }}

使用方法:

final ContactHelper helper = new ContactHelper(this);new Thread(new Runnable() {            @Override            public void run() {                 //获取联系人列表数据                jsonObject = helper.queryContactList();            }        }).start();

git地址

Github地址
https://github.com/jiangkang/KTools.git

注意

实例代码省略了运行时权限判断和获取的代码,用的时候要自己添加。