步骤
- 实现 LoaderManager.LoaderCallbacks
接口 - 在onCreateLoader(int id, Bundle args)中创建需要的Loader
- 在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
注意
实例代码省略了运行时权限判断和获取的代码,用的时候要自己添加。