系列文章:

  1. 联系人项目(知识预热)
  2. 联系人项目(ViewPager和底部联动)
  3. 联系人项目(查询联系人数据)
  4. 联系人项目(显示联系人数据)
  5. 联系人项目(显示通话记录)
  6. 联系人项目(显示拨号界面)
  7. 联系人项目(短信显示)
  8. 联系人项目(短信详情显示)
  9. 联系人项目(总)

MVP流程

interface IContactView{
setData(List<Contact> cs);//设置数据源
showList();//显示列表数据
}
 ContactFragment implements IContactView {
onCreateView(){
加载所有的联系人数据
IcontactPresenter p = new IcontactPresenter(this);
p.loadAllContacts();
return view;
}
setData(List<Contact> cs){}//设置数据源
showList(){}//显示列表数据
}
iterface IcontactPresenter{
void loadAllContacts();
}
ContactPresenter{
private IContactView view;
public ContactPresenter(IContactView view){
this.view = view;
}
loadAllContacts(){
model.findAll(callback);
view.setData(list);
view.showLisr();
}
}
interface IContactModel{
void findAll(Callback callback);
}
ContactModel{
findAll(){
查询数据库-->List<Contact>
}
}

此时查询到联系人的数据,需要给presenter返回,返回数据有两种方式
1、findAll方法返回值 List findAll
2、回调 findAll(callback)(异步)

要知道,需要耗时的操作需要异步,不能在工作线程做。查询联系人数据库的时候最耗时的是close操作

ContactModel{
findAll(Callback callback){
AsyncTask
查询数据库-->List<Contact>
}
}

开始做
复制​知识预热里的Contact类到entity包

View包中新建IContactView

public interface IContactView {
public void setData(List<Contact> list);

/**
* 在界面中显示列表
* 调用该方法时,必须先调用setData设置数据源
*/
public void showList();
}

presenter包中新建

public interface IContactPresenter {
/**
* 加载所有联系人数据,并显示在界面
*/
public void loadAllContacts();
}

model包中新建IContactModel

/**
* 联系人相关业务层接口
*/
public interface IContactModel {

/**
* 查询所有联系人业务
* @param commonCallback 当联系人查询结束后
* 需要在主线程中调用回调方法
*/
public void findAll(CommonCallback commonCallback);

/**
* 通用回调接口
*/
public interface CommonCallback{
/**
* 数据加载完毕后执行
*/
void onDataLoaded(Object object);
}
}

根目录下新建MyApplication方便获取Context

public class Myapplication extends Application {
private static Myapplication app;
@Override
public void onCreate() {
super.onCreate();
app = this;
}

public static Myapplication getApp(){
return app;
}
}

记得在AndroidManifest中注册,并且加权限

    <uses-permission android:name="android.permission.READ_CONTACTS"/>
<application
android:name=".Myapplication"
android:allowBackup="true"
......
</application>

在model下新建以下文件
【达内课程】联系人项目(查询联系人数据)_android

public class ContactModelImpl implements IContactModel{

@Override
public void findAll(final CommonCallback commonCallback) {
AsyncTask<String,String,List<Contact>> task = new AsyncTask<String, String, List<Contact>>() {
@Override
protected List<Contact> doInBackground(String... strings) {
List<Contact> list = loadContacts();
return list;
}

@Override
protected void onPostExecute(List<Contact> contacts) {
//把数据给presenter传回去
commonCallback.onDataLoaded(contacts);
}
};

task.execute();
}

/**
* 查询联系人
* 先查contacts表,获取所有人id
* 再查data表,通过id查询这个人的其他信息
*/
private List<Contact> loadContacts() {
ContentResolver r = Myapplication.getApp().getContentResolver();
Uri uri = ContactsContract.Contacts.CONTENT_URI;
String[] projection = {
ContactsContract.Contacts._ID,
ContactsContract.Contacts.PHOTO_ID
};

String[] column = {
ContactsContract.Data._ID,//0
ContactsContract.Data.MIMETYPE,//1
ContactsContract.Data.DATA1//2
};

Cursor c = r.query(uri, projection, null, null, null);

//准备集合
List<Contact> contacts = new ArrayList<Contact>();

while (c.moveToNext()) {
Contact contact = new Contact();

int id = c.getInt(0);
int photo_id = c.getInt(1);

contact.setId(id);
contact.setPhotoId(photo_id);

//通过id查data表,获取这个人的其他信息
Uri dataUri = ContactsContract.Data.CONTENT_URI;
Cursor c1 = r.query(dataUri, column, ContactsContract.Data.RAW_CONTACT_ID + "=?", new String[]{id + ""}, null);
while (c1.moveToNext()) {
int dataId = c1.getInt(0);
String mm = c1.getString(1);
String data1 = c1.getString(2);

//data表里的字段是mimetype_id,而这里查询的是mimetype,返回的是字符串
//通过contentprovider查到的就是字符串,拿不到id
if (mm.equals(ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)) {
//描述的是Email
contact.setEmail(data1);
} else if (mm.equals(ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)) {
//描述的是Phone
contact.setPhone(data1);
} else if (mm.equals("vnd.android.cursor.item/name")) {
//描述的是Name
contact.setName(data1);
} else if (mm.equals("vnd.android.cursor.item/sip_address")) {
//描述的是Address
contact.setAddress(data1);
}
}
contacts.add(contact);
c1.close();
}
c.close();
return contacts;
}
}

新建以下文件
【达内课程】联系人项目(查询联系人数据)_android_02

public class ContactPresenterImpl implements IContactPresenter{
private IContactModel model;
private IContactView view;
public ContactPresenterImpl(IContactView view) {
model = new ContactModelImpl();
this.view = view;
}

@Override
public void loadAllContacts() {
model.findAll(new IContactModel.CommonCallback() {
@Override
public void onDataLoaded(Object object) {
List<Contact> cs = (List<Contact>) object;
//更新界面
view.setData(cs);
view.showList();
}
});
}
}

ContactFragment修改

public class ContactFragment extends Fragment implements IContactView{
private List<Contact> list;
private IContactPresenter presenter;
public ContactFragment() {
this.presenter = new ContactPresenterImpl(this);
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
//调用presenter方法,记载所有联系人
presenter.loadAllContacts();
View view = inflater.inflate(R.layout.fragment_contactfragment,null);
return view;
}

@Override
public void setData(List<Contact> list) {
this.list = list;
}

@Override
public void showList() {
//自定义adapter 更新界面
Log.d("info",list.toString());
}
}

最后运行程序,可以打印结果
【达内课程】联系人项目(查询联系人数据)_ico_03