ContentProvider 内容提供者

来源:互联网 发布:山西统计局2016年数据 编辑:程序博客网 时间:2024/05/21 20:27
ContentProvider 内容提供器

Android 四大组件之一  ,是使数据暴露的方法。   (不同应用间数据交流方式)

原理 :





B:ContentProvider 内容提供者    (制定规则)
A:ContentResolver内容解析者
URI:统一资源标识符 ,资源的路径     (A、 B间的纽带)   Url 统一资源定位符(Uri的一个子集 ,一个特例 )

business : 业务层
Data  Access Layer   :数据访问层
DataLayer :数据层




ContentResolver  实现对系统数据的操作

1.ContentReslover 实现系统数据的操作(联系人[查询]、媒体库文件、通话记录、短信记录)



ContentProvider对外共享数据:

步骤

1. 定义一个类 继承 ContentProvider
2. 定义匹配规则 指定主机名 + path code urimatcher content://
3. 通过静态代码块添加匹配规则
4. 一定要记得在清单文件配置内容提供者 不要忘记加authorities
说明: 第一步继承ContentProvider需要重写下面方法:
public class PersonContentProvider extends ContentProvider{
public boolean onCreate()
public Uri insert(Uri uri, ContentValues values)
public int delete(Uri uri, String selection, String[] selectionArgs)
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
public String getType(Uri uri)}

第四步需要在AndroidManifest.xml使用对该ContentProvider进行配置,为了能让其他应用找到该ContentProvider , ContentProvider

采用了authorities(主机名/域名)对它进行唯一标识,你可以把 ContentProvider看作是一个网站(想想,网站也是提供数据者),authorities 就是他的域名:
 

ContentProvider类主要方法的作用:

public boolean onCreate()
该方法在ContentProvider创建后就会被调用, Android开机后, ContentProvider在其它应用第一次访问它时才会被创建。
public Uri insert(Uri uri, ContentValues values)
该方法用于供外部应用往ContentProvider添加数据。
public int delete(Uri uri, String selection, String[] selectionArgs)
该方法用于供外部应用从ContentProvider删除数据。
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
该方法用于供外部应用更新ContentProvider中的数据。
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
该方法用于供外部应用从ContentProvider中获取数据。
public String getType(Uri uri)
该方法用于返回当前Url所代表数据的MIME类型。如果操作的数据属于集合类型,那么MIME类型字符串应该以vnd.android.cursor.dir/开头,

 

例如:要得到所有person记录的Uri为content://cn.itcast.provider.personprovider/person,那么返回的MIME类型字符串应该为:“vnd.android.cursor.dir/person”。如果要操作的数据属于非集合类型数据,那么MIME类型字符串应该以vnd.android.cursor.item/开头,例如:得到id为10的person记录,Uri为content://cn.itcast.provider.personprovider/person/10,那么返回的MIME类型字符串应该为:“vnd.android.cursor.item/person”。

 

Uri介绍

Uri代表了要操作的数据,Uri主要包含了两部分信息:1》需要操作的ContentProvider ,2》对ContentProvider中的什么数据进行操作,一个Uri由以下几部分组成:


ContentProvider(内容提供者)的scheme已经由Android所规定, scheme为:content://
主机名(或叫Authority)用于唯一标识这个ContentProvider,外部调用者可以根据这个标识来找到它。
路径(path)可以用来表示我们要操作的数据,路径的构建应根据业务而定,如下:
要操作person表中id为10的记录,可以构建这样的路径:/person/10
要操作person表中id为10的记录的name字段, person/10/name
要操作person表中的所有记录,可以构建这样的路径:/person
要操作xxx表中的记录,可以构建这样的路径:/xxx
当然要操作的数据不一定来自数据库,也可以是文件、xml或网络等其他存储方式,如下:
要操作xml文件中person节点下的name节点,可以构建这样的路径:/person/name
如果要把一个字符串转换成Uri,可以使用Uri类中的parse()方法,如下:
Uri uri = Uri.parse("content://cn.itcast.provider.personprovider/person")

UriMatcher类使用介绍

因为Uri代表了要操作的数据,所以我们经常需要解析Uri,并从Uri中获取数据。Android系统提供了两个用于操作Uri的工具类,分别为UriMatcher 和ContentUris 。

 

掌握它们的使用,会便于我们的开发工作。
UriMatcher类用于匹配Uri,它的用法如下:
首先第一步把你需要匹配Uri路径全部给注册上,如下:


//常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码
UriMatcher sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
//如果match()方法匹配content://cn.itcast.provider.personprovider/person路径,返回匹配码为1
sMatcher.addURI(“cn.itcast.provider.personprovider”, “person”, 1);//添加需要匹配uri,如果匹配就会返回匹配码
//如果match()方法匹配content://cn.itcast.provider.personprovider/person/230路径,返回匹配码为2
sMatcher.addURI(“cn.itcast.provider.personprovider”, “person/#”, 2);//#号为通配符
switch (sMatcher.match(Uri.parse("content://cn.itcast.provider.personprovider/person/10"))) {
case 1
break;
case 2
break;
default://不匹配
break;
}
注册完需要匹配的Uri后,就可以使用sMatcher.match(uri)方法对输入的Uri进行匹配,如果匹配就返回匹配码,匹配码是调用addURI()方法传入的第三个参数,

假设匹配content://cn.itcast.provider.personprovider/person路径,返回的匹配码为1

代码示例

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
packagecom.itheima.transaction;
 
importandroid.content.ContentProvider;
importandroid.content.ContentValues;
importandroid.content.UriMatcher;
importandroid.database.Cursor;
importandroid.database.sqlite.SQLiteDatabase;
importandroid.net.Uri;
 
publicclass AccountProvider extends ContentProvider {
 
    privatestatic final int QUEYSUCESS = 0// ctrl + shift + X(变大写)   变小写  + y 
    privatestatic final int INSERTSUCESS = 1;
     
    privatestatic final int UPDATESUCESS  = 2;
     
    privatestatic final int DELSUCESS  = 3;
     
    //1 想使用内容提供者 必须定义 匹配规则   code:定义的匹配规则 如果 匹配不上  有一个返回码  -1
     staticUriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
 
    privateMyOpenHelper helper;
     
    //2 我要添加匹配规则
      
     static{
         //开始添加匹配规则
         /**
          * authority   主机名  通过主机名来访问我暴露的数据
          * path   你也可以随意 写 com.itheima.contentprovider/query
          * code 匹配码
          */
         matcher.addURI("com.itheima.contentprovider","query", QUEYSUCESS);
         //添加插入匹配规则
         matcher.addURI("com.itheima.contentprovider","insert", INSERTSUCESS);
         //添加更新匹配规则
         matcher.addURI("com.itheima.contentprovider","update", UPDATESUCESS);
         //添加删除匹配规则
         matcher.addURI("com.itheima.contentprovider","delete", DELSUCESS);
          
          
     }
      
     
    @Override
    publicboolean onCreate() {
        helper = new MyOpenHelper(getContext());
         
         
         
        returnfalse;
    }
 
    //Uri 范围比较大  不但可以指定  tel:   可以定义很多语法
    @Override
    publicCursor query(Uri uri, String[] projection, String selection,
            String[] selectionArgs, String sortOrder) {
        //传递过来的uri 是否和我们定义的匹配规则 匹配
        intmatch = matcher.match(uri);
        if(match == QUEYSUCESS ) {
            //说明匹配成功
            SQLiteDatabase db = helper.getReadableDatabase();  //获取数据库对象
            Cursor cursor = db.query("info", projection, selection, selectionArgs, null,null, sortOrder);
             
            //注意  这个地方 不要关闭 cursor 和  db
             
            //大吼一声 数据库发生了改变
            getContext().getContentResolver().notifyChange(uri,null);
             
            returncursor;
             
        }else{
            //匹配失败
            thrownew IllegalArgumentException("路径匹配失败");
             
        }
         
         
    }
 
    @Override
    publicString getType(Uri uri) {
        returnnull;
    }
 
    @Override
    publicUri insert(Uri uri, ContentValues values) {
         
        intmatch = matcher.match(uri);
        if(match == INSERTSUCESS) {
            //说明匹配成功
            SQLiteDatabase db = helper.getReadableDatabase();
            longinsert = db.insert("info",null, values);
             
            //执行上面这句话 说明我的数据库内容 发生了变化   首先 要发送一条通知 说明 我发生改变
             
            if(insert>0) {
 
                //数据库发生变化  发送一个通知
                getContext().getContentResolver().notifyChange(uri,null);
            }
             
             
             
             
            Uri uri2 = Uri.parse("com.itheima.contentprovider/"+insert);
            returnuri2;
        }else{
            //匹配失败
            thrownew IllegalArgumentException("路径匹配失败");
             
        }
                 
    }
 
    @Override
    publicint delete(Uri uri, String selection, String[] selectionArgs) {
        intmatch = matcher.match(uri);
        if(match == DELSUCESS) {
            //匹配成功
            SQLiteDatabase db = helper.getReadableDatabase();
            intdelete = db.delete("info", selection, selectionArgs);
             
            if(delete>0) {
                //大吼一声 数据库发生了改变
                getContext().getContentResolver().notifyChange(uri,null);
                 
            }
             
             
            returndelete;
             
        }else{
             
            //匹配失败
            thrownew IllegalArgumentException("路径匹配失败");
             
        }
         
    }
 
    @Override
    publicint update(Uri uri, ContentValues values, String selection,
            String[] selectionArgs) {
         
        intmatch = matcher.match(uri);
        if(match == UPDATESUCESS) {
            //匹配成功
            SQLiteDatabase db = helper.getReadableDatabase();
            intupdate = db.update("info", values, selection, selectionArgs);
             
            if(update>0) {
                //大吼一声 数据库发生了改变
                getContext().getContentResolver().notifyChange(uri,null);
            }
             
            returnupdate;
        }else{
            //匹配失败
            thrownew IllegalArgumentException("路径匹配失败");
        }
         
    }
 
}

内容解析者ContentResolver

使用ContentResolver调用ContentProvider提供的接口,操作数据

当外部应用需要对ContentProvider中的数据进行添加、删除、修改和查询操作时,可以使用ContentResolver 类来完成,要获取ContentResolver 对象,

 

可以使用Activity提供的getContentResolver()方法。 ContentResolver 类提供了与ContentProvider类相同签名的四个方法:
public Uri insert(Uri uri, ContentValues values)
该方法用于往ContentProvider添加数据。
public int delete(Uri uri, String selection, String[] selectionArgs)
该方法用于从ContentProvider删除数据。
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
该方法用于更新ContentProvider中的数据。
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
该方法用于从ContentProvider中获取数据。


这些方法的第一个参数为Uri,代表要操作的ContentProvider和对其中的什么数据进行操作,假设给定的是: Uri.parse(“content://cn.itcast.providers.personprovider/person/10”),那么将会对主机名为cn.itcast.providers.personprovider的ContentProvider进行操作,操作的数据为person表中id为10的记录。
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
使用ContentResolver对ContentProvider中的数据进行添加、删除、修改和查询操作:
    ContentResolver resolver =  getContentResolver();
    Uri uri = Uri.parse("content://cn.itcast.provider.personprovider/person");
    //添加一条记录
    ContentValues values = new ContentValues();
    values.put("name","itcast");
    values.put("age",25);
    resolver.insert(uri, values);      
    //获取person表中所有记录
    Cursor cursor = resolver.query(uri, null,null,null,"personid desc");
    while(cursor.moveToNext()){
        Log.i("ContentTest","personid="+ cursor.getInt(0)+",name="+ cursor.getString(1));
    }
    //把id为1的记录的name字段值更改新为liming
    ContentValues updateValues = new ContentValues();
    updateValues.put("name","liming");
    resolver.update(updateIdUri, updateValues, null,null);

 

监听ContentProvider中数据的变化

如果ContentProvider的访问者需要知道ContentProvider中的数据发生变化,可以在ContentProvider 发生数据变化时调用

 

getContentResolver().notifyChange(uri, null)来通知注册在此URI上的访问者,例子如下:

?
1
2
3
4
5
6
publicclass PersonContentProvider extends ContentProvider {
    publicUri insert(Uri uri, ContentValues values) {
        db.insert("person","personid", values);
        getContext().getContentResolver().notifyChange(uri,null);
    }
    }
如果ContentProvider的访问者需要得到数据变化通知,必须使用ContentObserver对数据(数据采用uri描述)进行监听,当监听到数据变化通知时,

 

系统就会调用ContentObserver的onChange()方法:

?
1
2
3
4
5
6
7
8
9
10
11
getContentResolver().registerContentObserver(Uri.parse("content://cn.itcast.providers.personprovider/person"),
            true,//true表示只要发出通知的Uri以方法第一个参数开头都能被监听到,否侧监听uri必须与发出通知的uri完全匹配才能被监听到
                                       newPersonObserver(newHandler()));
publicclass PersonObserver extends ContentObserver{
publicPersonObserver(Handler handler) {
    super(handler);
}
publicvoid onChange(booleanselfChange) {
    //此处可以进行相应的业务处理
}
}

 

实例代码

利用内容解析者备份短信

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
packagecom.itheima.backupsms;
 
importjava.io.File;
importjava.io.FileNotFoundException;
importjava.io.FileOutputStream;
importjava.io.IOException;
 
importorg.xmlpull.v1.XmlSerializer;
 
importandroid.net.Uri;
importandroid.os.Bundle;
importandroid.os.Environment;
importandroid.os.FileObserver;
importandroid.app.Activity;
importandroid.database.Cursor;
importandroid.util.Xml;
importandroid.view.Menu;
importandroid.view.View;
 
publicclass MainActivity extends Activity {
 
    @Override
    protectedvoid onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }
 
    /**
     * 点击按钮备份短信
     *
     * @param v
     */
    publicvoid backup(View v) {
 
        try{
            // 1 初始化xml 序列化器
            XmlSerializer serializer = Xml.newSerializer();
            // 2初始化xml序列化器的 参数
            File file = new File(Environment.getExternalStorageDirectory()
                    .getPath(),"smsbackup.xml");
            FileOutputStream fos = new FileOutputStream(file);
            serializer.setOutput(fos,"utf-8");
 
            // 3 开始写 xml 头
            serializer.startDocument("utf-8",true);
 
            // 开始写 xml 根节点 smss
            serializer.startTag(null,"smss");
            // 1 把我们关系的短信数据库里的内容 给 获取出来 我们要做的操作 就是通过内容解析者 把数据给查询出来
            Uri uri = Uri.parse("content://sms");
 
            Cursor cursor = getContentResolver().query(uri,
                    newString[] { "address","date","body" }, null,null,
                    null);
            while(cursor.moveToNext()) {
                // 写sms 节点
                serializer.startTag(null,"sms");
                String address = cursor.getString(0);
                String date = cursor.getString(1);
                String body = cursor.getString(2);
 
                //开始写 address 节点
                serializer.startTag(null,"address");
                serializer.text(address);
                serializer.endTag(null,"address");
                 
                //开始写 date 节点
                serializer.startTag(null,"date");
                serializer.text(date);
                serializer.endTag(null,"date");
                 
                 
                //开始写 body 节点
                serializer.startTag(null,"body");
                serializer.text(body);
                serializer.endTag(null,"body");
                 
                serializer.endTag(null,"sms");
            }
 
            // 开始写 address date body
 
            serializer.endTag(null,"smss");
 
            // 文档结束
            serializer.endDocument();
 
        }catch (Exception e) {
            e.printStackTrace();
        }
 
    }
 
}

利用内容解析者插入短信

?
1
2
3
4
5
6
7
//1 先拿到 内容解析器
        Uri uri = Uri.parse("content://sms");
        ContentValues values = new ContentValues();
        values.put("address","110");
        values.put("date", System.currentTimeMillis());
        values.put("body","您的事犯了 请您马上来一趟");
        getContentResolver().insert(uri, values);

利用内容解析者获取联系人数据

1. 首先 我要查询raw_contacts表 获取到 contact_id
2. 去data表 根据 contact_id 去获取 mimetype data1的数据
3. 然后根据 mimetype_id 来区分数据类型
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
packagecom.itheima.getcontactinfo.utils;
 
importjava.util.ArrayList;
importjava.util.List;
 
importandroid.content.ContentResolver;
importandroid.content.Context;
importandroid.database.Cursor;
importandroid.net.Uri;
 
importcom.itheima.getcontactinfo.domain.ContactInfo;
 
publicclass ContactUtils {
 
    publicstatic List<contactinfo> getContactInfos(Context context) {
 
        List<contactinfo> contactLists = new ArrayList<contactinfo>();
        // 1 首先 我要查询raw_contacts表 获取到 contact_id列
        // (1)我如何查询 ?用 内容解析者 path
        Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");
        Uri datauri = Uri.parse("content://com.android.contacts/data");
 
        ContentResolver resolver = context.getContentResolver();
        Cursor cursor = resolver.query(uri, new String[] { "contact_id" },
                null,null,null);
        while(cursor.moveToNext()) {
            // 获取到contact_id 的值
            String contact_id = cursor.getString(0);
            System.out.println("contact_id--"+ contact_id);
 
            // 有个小细节注意一下 我要判断 contact_id 是否为空
            if(contact_id != null) {
 
                ContactInfo info = new ContactInfo();
                info.setId(contact_id);
 
                // 2去data表 根据 contact_id 去获取 mimetyple_id列 data1 列
 
                Cursor dataCursor = resolver.query(datauri, new String[] {
                        "mimetype","data1" }, "raw_contact_id=?",
                        newString[] { contact_id }, null);
                while(dataCursor.moveToNext()) {
                    String mimetype = dataCursor.getString(0);// 获取到mimeytype
                    String data1 = dataCursor.getString(1);
 
                    // 3 然后根据 mimetype类型 来区分数据类型
                    if("vnd.android.cursor.item/email_v2".equals(mimetype)) {
                        info.setEmail(data1);
 
                    }else if ("vnd.android.cursor.item/name".equals(mimetype)) {
 
                        info.setName(data1);
 
                    }else if ("vnd.android.cursor.item/phone_v2"
                            .equals(mimetype)) {
                        System.out.println("data---电话号码-"+ data1);
                        info.setPhone(data1);
                    }
 
                }
                dataCursor.close();
                contactLists.add(info);// 把info信息存到集合中
 
            }
 
        }
        cursor.close();
 
        returncontactLists;
 
    }
 
}
</contactinfo></contactinfo></contactinfo>
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
packagecom.itheima.getcontactinfo.domain;
 
publicclass ContactInfo {
 
    privateString id;
    privateString name;
    privateString phone;
    privateString email;
     
     
     
    publicString getId() {
        returnid;
    }
    publicvoid setId(String id) {
        this.id = id;
    }
    publicString getName() {
        returnname;
    }
    publicvoid setName(String name) {
        this.name = name;
    }
    publicString getPhone() {
        returnphone;
    }
    publicvoid setPhone(String phone) {
        this.phone = phone;
    }
    publicString getEmail() {
        returnemail;
    }
    publicvoid setEmail(String email) {
        this.email = email;
    }
    @Override
    publicString toString() {
        return"ContactInfo [id=" + id + ", name=" + name + ", phone=" + phone
                +", email=" + email + "]";
    }
 
     
     
     
     
}

利用内容解析者插入联系人

1. 先往raw_contacts 插入一条数据
2. 往data表插入数据 根据mimetype contact_id 往里插入数据
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
packagecom.itheima.insert.contact;
 
importandroid.net.Uri;
importandroid.os.Bundle;
importandroid.app.Activity;
importandroid.content.ContentValues;
importandroid.database.Cursor;
importandroid.view.Menu;
importandroid.view.View;
importandroid.widget.EditText;
 
publicclass MainActivity extends Activity {
 
    privateEditText et_name;
    privateEditText et_phone;
    privateEditText et_email;
 
    @Override
    protectedvoid onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //1找到我们关心的控件
         
        et_name = (EditText) findViewById(R.id.et_name);
        et_phone = (EditText) findViewById(R.id.et_phone);
        et_email = (EditText) findViewById(R.id.et_email);
         
         
         
         
    }
     
    /**
     * 保存联系人的信息
     * @param v
     */
    publicvoid click(View v){
         
        //1 要先拿到  edittext的值
        String name = et_name.getText().toString().trim();
        String phone = et_phone.getText().toString().trim();
        String email = et_email.getText().toString().trim();
         
        //2 往 raw_contacts里插入一条数据   拿到内容解析者
        Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");
        Uri datauri = Uri.parse("content://com.android.contacts/data");
         
        ContentValues values = new ContentValues();
        // 插入数据之前  我要先查询 一下  raw_contacts 表一共有多少行的数据
        Cursor cursor = getContentResolver().query(uri, null,null,null,null);
        intcount = cursor.getCount();  //获取到一共有多少行
        intcontact_id =  count + 1
         
        values.put("contact_id", contact_id);
        getContentResolver().insert(uri, values);
         
        // 3 往data 表插入数据
         
        ContentValues nameValues = new ContentValues();
        nameValues.put("data1", name);
        nameValues.put("mimetype","vnd.android.cursor.item/name");
        nameValues.put("raw_contact_id", contact_id);
        getContentResolver().insert(datauri, nameValues);
 
        ContentValues phoneValues = new ContentValues();
        phoneValues.put("data1", phone);
        phoneValues.put("mimetype","vnd.android.cursor.item/phone_v2");
        phoneValues.put("raw_contact_id", contact_id);
        getContentResolver().insert(datauri, phoneValues);
         
        ContentValues emailValues = new ContentValues();
        emailValues.put("data1", email);
        emailValues.put("mimetype","vnd.android.cursor.item/email_v2");
        emailValues.put("raw_contact_id", contact_id);
        getContentResolver().insert(datauri, emailValues);
         
         
         
         
         
    }
 
     
}

利用监听和内容解析者监听短信

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
packagecom.itheima.smslistener;
 
importandroid.net.Uri;
importandroid.os.Bundle;
importandroid.os.Handler;
importandroid.app.Activity;
importandroid.database.ContentObserver;
importandroid.database.Cursor;
importandroid.view.Menu;
 
publicclass MainActivity extends Activity {
 
    privateUri uri;
    @Override
    protectedvoid onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
         
         
        //1注册一个内容观察者
        uri = Uri.parse("content://sms");
        getContentResolver().registerContentObserver(uri,true,new MyObserver(newHandler()));
         
    }
 
     
     
    private class MyObserver  extends ContentObserver{
 
        publicMyObserver(Handler handler) {
            super(handler);
        }
        @Override
        publicvoid onChange(booleanselfChange) {
             
            //当短信的数据库发生了变化    我就去取出所有短信的内容
             
            Cursor cursor = getContentResolver().query(uri, new String[]{"address","body","date"},null,null,null);
            while(cursor.moveToNext()){
                 
                String address = cursor.getString(0);
                String body = cursor.getString(1);
                String date = cursor.getString(2);
                 
                System.out.println("address---"+address+"--body:"+body);
                 
            }
             
            super.onChange(selfChange);
        }
         
         
    }
     



/**
 * Created by sky on 2017/4/3.
 */

public class MyProvider extends ContentProvider {
    public static final int TABLE1_DIR = 0;
    public static final int TABLE1_TIEM = 1;
    public static final int TABLE2_DIR = 2;
    public static final int TABLE2_TIEM = 3;
    private static UriMatcher uriMatcher;

    static {
        /*
        * *:表示匹配任意长度的任意字符
        *
        * #:表示匹配任意长度的数字
        * 一个能匹配任意表内容URI格式写法:
        *      content://com.example.app.provider/*
        *
        *  一个能匹配任意table表中任意一行数据的内容URI格式写法:
        *      content://com.example.app.provider/table1#
        *
        * */
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        uriMatcher.addURI("com.example.app.provider", "table1", TABLE1_DIR);
        uriMatcher.addURI("com.example.app.provider", "table1/#", TABLE1_TIEM);
        uriMatcher.addURI("com.example.app.provider", "table2", TABLE1_DIR);
        uriMatcher.addURI("com.example.app.provider", "table2/#", TABLE1_TIEM);

    }

    @Override
    public boolean onCreate() {
        return false;
    }

    @Nullable
    @Override  //重写query()方法
    public Cursor query(@NonNull Uri uri, @Nullable String[] strings, @Nullable String s,
                        @Nullable String[] strings1, @Nullable String s1) {

        switch(uriMatcher.match(uri)){
            case TABLE1_DIR:
                // 查询table 表中的所有数据
                break;
            case TABLE1_TIEM:
                //查询table表中单条数据
            case TABLE2_DIR:
                //查询table表中的所有数据
                break;
            case TABLE2_TIEM:
                //查询table表中的单条数据
                break;

        }
        return null;
    }
    /*
    *
    * MIME类型写法:
    *   1.必须以vnd开头
    *   2.如内容URI以路径结尾,则后接android.cursor.dir/,如内容URI以id结尾,则后接 android.cursor.item/。
    *   3.最后街上vnd.<authority>.<path>
    *
    *   vnd.android.cursor.dir/vnd.com.example.app.provider.table1
    *
    *   eg:
    *    content:// com.example.app.provider/table1/1
    *
    *    vnd.android.cursor.item/vnd.example.app.provider.table
    * */

    @Nullable// 用于获取uri所对应的MIME类型
    public String getType(@NonNull Uri uri) {

        switch(uriMatcher.match(uri)){
            case TABLE1_DIR:
                return     "vnd.android.cursor.dir/vnd.com.example.app.provider.table1";
            case TABLE1_TIEM:
                return "vnd.android.cursor.item/vnd.com.example.app.provider.table1";
            case TABLE2_DIR:
                return "vnd.android.cursor.dir/vnd.com.example.app.provider.table2";
            case TABLE2_TIEM:
                return "vnd.android.cursor.item/vnd.com.example.app.provider.table2";
            default:
                break;

        }
        return null;
    }

    @Nullable
    @Override
    public Uri insert(@NonNull Uri uri, @Nullable ContentValues contentValues) {
        return null;
    }

    @Override
    public int delete(@NonNull Uri uri, @Nullable String s, @Nullable String[] strings) {
        return 0;
    }

    @Override
    public int update(@NonNull Uri uri, @Nullable ContentValues contentValues, @Nullable String s, @Nullable String[] strings) {
        return 0;
    }
}
原创粉丝点击