1 content provider是Android的四大组件之一
主要用于不同的应用程序或者不同包之间实现数据共享功能
2ContentResolver:是数据调用者,ContentProvider将数据发布出来,通过ContentResolver对象结合Uri进行调用
通过ContentResolver对象可以调用ContentProvider的增删改查
3Uri(通用资源标识符 Universal Resource Identifer),代表数据操作的地址,每一个ContentProvider发布数据时都会有唯一的地址。
比如:content://(固定写法)+com.android.contacts(包名,可变)+/contacts(path路径)
在开始写代码之前先介绍一下小知识点;
1
Cursor cursor = contentResolver.query(URI,null, null, null, null);
这是一个查询语句,
第一个参数:URI;
第二个参数是一个字符串数组,就是我们要查询那些东西如name,id,
第三个参数相当于SQL语句中的where
第四个参数这个参数是要配合第三个参数使用的,如果你在第三个参数里面有?,那么你在selectionArgs写的数据就会替换掉?,
Cursor cursor = contentResolver.query(android.provider.ContactsContract.Contacts.CONTENT_URI,
new String[]{android.provider.ContactsContract.Contacts.DISPLAY_NAME},
android.provider.ContactsContract.Contacts.DISPLAY_NAME + "=?",
new String[]{"张三"}, null);
第五个参数;按照什么进行排序,相当于SQL语句中的Order by。如果想要结果按照ID的降序排列:“DESC”降序。" ASC"升序(默认)。
4 Cursor 游标
mainfest.xml中添加权限。
<uses-permission android:name="android.permission.READ_CONTACTS"></uses-permission>
<!--读取短信的权限-->
<uses-permission android:name="android.permission.READ_SMS"></uses-permission>
<uses-permission android:name="android.permission.WRITE_SMS"></uses-permission>
整体代码:
<?xml version="1.0" encoding="utf-8"?>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
main.xml 布局
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:orientation="vertical"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity"
android:weightSum="1">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content">
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="获取联系人"
android:onClick="readperson"
/>
<Button android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="获取短信"
android:onClick="readmessage"
/>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="220dp">
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/lv_listview_person"
>
</ListView>
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
>
<ListView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/lv_listview_message"
>
</ListView>
</LinearLayout>
</LinearLayout>
.java
import android.app.Application;
import android.app.ListActivity;
import android.content.ContentResolver;
import android.content.CursorLoader;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.provider.ContactsContract;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.CursorAdapter;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.SimpleCursorAdapter;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.jar.Manifest;
public class MainActivity extends AppCompatActivity {
private ContentResolver contentResolver;
private ListView lv_listview_person;
private ListView lv_listview_message;
private List<Map<String, Object>> persondata;
private List<Map<String, Object>> messagedata;
private SimpleAdapter personsa;
private SimpleAdapter messagesa;
private Map<String, Object> personmap;
private Map<String, Object> messagemap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取xml中的展示联系人ListView的id
lv_listview_person = (ListView) findViewById(R.id.lv_listview_person);
//获取xml中的展示短信ListView的id
lv_listview_message = (ListView) findViewById(R.id.lv_listview_message);
//获取内容访问者
//ContentProvider共享数据是通过定义一个对外开放的统一的接口来实现的。
// 然而,应用程序并不直接调用这些方法,而是使用一个 ContentResolver 对象,
// 调用它的方法作为替代。ContentResolver可以与任意内容提供者进行会话,与其合作来对所有相关交互通讯进行管理
contentResolver = getContentResolver();
//实例化一个集合用来保存联系人的信息
persondata = new ArrayList<Map<String, Object>>();
//高级控件的运用了简单适配器
personsa = new SimpleAdapter(this, persondata, android.R.layout.simple_list_item_2, new String[]{"names", "phones"}, new int[]{android.R.id.text1, android.R.id.text2});
//给listview添加适配器
lv_listview_person.setAdapter(personsa);
//这个是获取短信的集合
messagedata = new ArrayList<Map<String, Object>>();
messagesa = new SimpleAdapter(this, messagedata, android.R.layout.simple_list_item_2, new String[]{"myphones", "content"}, new int[]{android.R.id.text1, android.R.id.text2});
lv_listview_message.setAdapter(messagesa);
}
//获取联系人列表的方法
public void readperson(View view) {
//协议:content://com.android.contacts/raw_contacts(获得联系人的id,姓名)
Cursor cursor = contentResolver.query(Uri.parse("content://com.android.contacts/raw_contacts"), null, null, null, null);
while (cursor.moveToNext()) {
personmap = new HashMap<String, Object>();
//得到的联系人的id
int id = cursor.getInt(cursor.getColumnIndex("_id"));
//得到联系人的名字
String displayname = cursor.getString(cursor.getColumnIndex("display_name"));
//把名字添加到集合中
personmap.put("names", displayname);
// 协议:content://com.android.contacts/raw_contacts/"+id+"/data(根据联系人的id获得联系人的信息)
//Cursor是游标,
Cursor cursordate = contentResolver.query(Uri.parse("content://com.android.contacts/raw_contacts/" + id + "/data"), null, null, null, null);
while (cursordate.moveToNext()) {
//如果用了这个会报这样的错( Failed to read row 0, column -1 from 所以用下面这个字段)
//int type= cursordate.getInt(cursor.getColumnIndex("mimetype_id"));
//得到联系人的类型
String type = cursordate.getString(cursordate.getColumnIndex("mimetype"));
//得到联系人的电话号码
String dates = cursordate.getString(cursordate.getColumnIndex("data1"));
//给personmap集合添加值
personmap.put("phones", dates);
}
//将personmap集合添加到persondata大的集合中显示
persondata.add(personmap);
}
//通知适配器发生改变
personsa.notifyDataSetChanged();
}
//获取短信的方法
public void readmessage(View view) {
Cursor cursor = contentResolver.query(Uri.parse("content://sms/"), new String[]{"_id", "address", "body", "date", "type"}, null, null, null);
if (cursor != null && cursor.getCount() > 0) {
int _id;
String address;
String body;
String date;
int type;
while (cursor.moveToNext()) {
//实例化一个messagemap集合放电话号码跟短信内容的值
messagemap = new HashMap<String, Object>();
_id = cursor.getInt(0);
address = cursor.getString(1);
body = cursor.getString(2);
date = cursor.getString(3);
type = cursor.getInt(4);
//给messagemap集合里设值
messagemap.put("myphones",address);
messagemap.put("content",body);
//将messagemap集合添加到messagedata大的集合中
messagedata.add(messagemap);
Log.i("test", "_id=" + _id + " address=" + address + " body=" + body + " date=" + date + " type=" + type);
}
}
//通知适配器发生改变
messagesa.notifyDataSetChanged();
}
}