使用Loader获取Android联系人列表

步骤

  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 {

    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 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 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 loader) {

    }

    public void setQueryListener(QueryListener listener) {
        this.listener = listener;
    }

    interface QueryListener{
        void success(JSONObject object);
    }

初步封装

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

public class ContactsLoaderCallback implements LoaderManager.LoaderCallbacks {

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

注意

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

你可能感兴趣的:(使用Loader获取Android联系人列表)