Android笔记---四大组件之Content Provider内容提供者详解
来源:互联网 发布:如何评价李中莹 知乎 编辑:程序博客网 时间:2024/04/30 08:48
ContentProvider(内容提供者)是android中的四大组件之一,主要用于在不同的应用程序之间实现数据共享的功能,很多系统自带应用,比如联系人信息,图片库,音频库等应用,为了对其他应用暴露数据,就使用了ContentProvider机制,所以在遇到获取联系人信息,图片库,音频库等需求的时候,我们也需要用到ContentProvider,另外,如果我们想让其他的应用使用我们自己程序内的数据,可以使用ContentProvider定义一个对外开放的接口,从而使得其他的应用可以使用咱们应用的文件、数据库内存储的信息。
我们先看下ContentProvider中需要掌握的知识点:
1.URI字符串
2.ContentResolve类
3.UriMatcher类
4.ContentUris类
ContentProvider是以类似数据库中表的方式将数据暴露,也就是说ContentProvider就像一个“数据库”,外界获取其提供的数据,也就应该与从数据库中获取数据的操作基本一样有增删改查的方式,不过在方法参数上稍微有一些区别,所以我们首先需要找到我们的“数据表”,而这是通过一个URI字符串来确定的。
URI字符串由以下三部分组成:
1.scheme: 规定为content://
2.主机名(Authority): 用于唯一标识这个ContentProvider,外部调用可以根据这个标识来找到它,一般为了避免冲突, 都会采用程序包名的方式来进行命名
3.路径(path): 用于对同一应用程序中不同的表做区分的, 添加在权限的后面,eg:
要操作person表中id为10的记录,可以构建这样的路径:/person/10
要操作person表中id为10的记录的name字段, person/10/name
要操作person表中的所有记录,可以构建这样的路径:/person
当然要操作的数据不一定来自数据库,也可以是文件等他存储方式,如下:
要操作xml文件中person节点下的name节点,可以构建这样的路径:/person/name
在得到了内容URI字符串之后, 我们还需要将它解析成 Uri 对象才可以作为参数传入,只需要调用 Uri.parse()方法, 就可以将内容URI字符串解析成 Uri 对象了,加入我们需要对程序中为person的表进行操作,就可以先得到以下这样一个uri对象: Uri uri = Uri.parse("content://com.example.app.provider/person")
对到了uri对象之后我们就需要调用相应的方法对其进行操作,这样就需要借助于 ContentResolve 类, 可以通过 Context 中的 getContentResolver()方法获取到该类的实例,然后对数据进行增删改查。
以下通过两种情况进行分析:
1.获取系统应用程序的数据(以获取联系人电话方式为例)
2.本程序创建ContentProvider定义一个对外开放的接口将数据提供给其他应用程序调用。
1.获取系统应用程序的数据(以获取联系人电话方式为例)
获取系统的内容提供者的程序比较简单:
首先添加两条联系人已经电话记录:
在布局文件中增加一个ListView控件来展示获取的联系人,当然也有别的方式来显示联系人的信息,直接用TextView也可以。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" > <ListView android:id="@+id/contacts_view" android:layout_width="match_parent" android:layout_height="match_parent" > </ListView></RelativeLayout>
接下来给出Activity中的代码:
package com.example.androidstudycontentprovider;import java.util.ArrayList;import java.util.List;import android.app.Activity;import android.database.Cursor;import android.os.Bundle;import android.provider.ContactsContract;import android.widget.ArrayAdapter;import android.widget.ListView;import android.widget.TextView;public class MainActivity extends Activity { private ListView contactsView; //定义一个适配器 ArrayAdapter<String> adapter; //定义一个ArrayList数组容器来存放得到的联系人数据 List<String> contactsList = new ArrayList<String>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); contactsView = (ListView) findViewById(R.id.contacts_view); //为适配器添加布局R.layout.simple_list_item_1(android自带的布局)以及联系人信息contactsList adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, contactsList); //给ListView设置适配器 contactsView.setAdapter(adapter); //调用readContacts()方法 readContacts(); } private void readContacts() { Cursor cursor = null; try { //查询联系人数据,ContactsContract.CommonDataKinds.Phone类已经帮我们做好了封装 //提供了一个 CONTENT_URI 常量,而这个常量就是使用 Uri.parse()方法解析出来的结果,所以可以直接就用 cursor = getContentResolver().query( ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null); while (cursor.moveToNext()) { // 获取联系人姓名 String displayName = cursor .getString(cursor .getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)); // 获取联系人手机号 String number = cursor .getString(cursor .getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); //在contactsList容器添加需要显示的数据 contactsList.add(displayName + " " + number); } } catch (Exception e) { e.printStackTrace(); } finally { if (cursor != null) { //关闭cursor cursor.close(); } } }}
最后在AndroidManifest.xml文件中声明可以读取联系人权限就可以了:
<uses-permission android:name="android.permission.READ_CONTACTS" />
程序运行的结果如下:
2.本程序创建ContentProvider定义一个对外开放的接口将数据提供给其他应用程序调用。
对于这种情况,我们需要先掌握以下内容:
Android系统提供了两个用于操作Uri的工具类,分别为UriMatcher 和ContentUris ,所以我们需要先掌握下这两个类:
1.UriMatcher
UriMatcher 类主要用于匹配Uri,UriMatcher中提供了一个 addURI()方法,这个方法接收三个参数,可以分别把权限、路径和一个自定义代码传进去。这样, 当调用 UriMatcher 的 match()方法时,就可以将一个 Uri 对象传入, 返回值是某个能够匹配这个 Uri 对象所对应的自定义代码, 利用这个代码, 我们就可以判断出调用方期望访问的是哪张表中的数据了。
使用方法如下。
首先第一步,初始化:
//常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
第二步注册需要的Uri, 传入三个参数:
//*:表示匹配任意长度的任意字符//#:表示匹配任意长度的数字//所以,一个能够匹配任意表的内容 URI 格式就可以写成: content://com.dxy.provider/*//而一个能够匹配 table1 表中任意一行数据的内容 URI格式就可以写成: content://com.dxy.provider/table1/#//如果match()方法匹配content://com.dxy.provider/person路径,返回匹配码为PEOPLEmatcher.addURI("com.dxy.provider", "people", PEOPLE); matcher.addURI("com.dxy.provider", "person/#", PEOPLE_ID);
第三步,与已经注册的Uri进行匹配:
Uri uri = Uri.parse("content://" + "com.dxy.provider" + "/people"); int match = matcher.match(uri); switch (match) { case PEOPLE: //返回值是某个能够匹配这个 Uri 对象所对应的自定义代码 return "com.dxy.provider/people"; case PEOPLE_ID: return "com.dxy.provider/people"; default: return null; }
2.ContentUris
ContentUris 类用于获取Uri路径后面的ID部分, 它有两个比较实用的方法:
1.withAppendedId(uri, id)用于为路径加上ID部分:
Uri uri = Uri.parse("content://com.dxy.provider");//通过withAppendedId方法,为该Uri加上ID//最后resultUri为: content://com.dxy.provider/people/10Uri resultUri = ContentUris.withAppendedId(uri, 10);
2.parseId(uri)方法用于从路径中获取ID部分:
Uri uri = Uri.parse("content://com.dxy.provider/people/10") //可以从路径中或者id,最后personid 为 :10long personid = ContentUris.parseId(uri);
接下来我们看下ContentResolver类提供的四个方法对uri对象进行增删改查的操作:
1. public Uri insert(Uri uri, ContentValues values)
该方法用于往ContentProvider添加数据,用法如下:
ContentResolver resolver = getContentResolver();Uri uri = Uri.parse("content://com.example.app.provider/person");//实例化一个ContentValues类并且插入数据,ContentValues类也是负责存储一些键值对ContentValues values = new ContentValues();values.put("name", "itcast");values.put("age", 25);resolver.insert(uri, values);
2. public int delete(Uri uri, String selection, String[] selectionArgs)
该方法用于从ContentProvider删除数据,用法如下:
ContentResolver resolver = getContentResolver();Uri uri = Uri.parse("content://com.dxy.provider/person");//通过withAppendedId方法,为该Uri加上ID//最后deleteIdUri为: content://com.dxy.provider/people/10Uri deleteIdUri = ContentUris.withAppendedId(uri, 2);resolver.delete(deleteIdUri, null, null);
3. public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
该方法用于更新ContentProvider中的数据,用法如下:
ContentResolver resolver = getContentResolver();Uri uri = Uri.parse("content://com.dxy.provider/person");//把id为1的记录的name字段值更改新为limingContentValues updateValues = new ContentValues();updateValues.put("name", "liming");//通过withAppendedId方法,为该Uri加上ID//最后updateIdUri为: content://com.dxy.provider/people/1Uri updateIdUri = ContentUris.withAppendedId(uri, 1);resolver.update(updateIdUri, updateValues, null, null);
4. public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
该方法用于从ContentProvider中获取数据.
第一个参数为Uri,代表指定查询某个应用程序下的某一张表,第二个参数指定查询的列名,第三个参数指定 where 的约束条件,第四个参数为where中的占位符提供具体的值,第五个参数指定查询结果的排序方式。
ContentResolver resolver = getContentResolver();Uri uri = Uri.parse("content://com.dxy.provider/person");//获取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));}
具体实例代码这里不给出,可以参考android之内容提供者解析
- Android笔记---四大组件之Content Provider内容提供者详解
- 四大组件之内容提供者Content provider
- Android四大组件之Content Provider(内容提供者)
- Android四大组件之内容提供者Content Provider总结
- Android 的四大组件Content Provider内容提供者
- 【android学习】四大组件-Content Provider(内容提供者)
- Android四大基本组件(2)之Service 服务与Content Provider内容提供者
- Android之四大组件之一-Content Provider内容提供者的介绍(一)
- android-----(Content Provider 内容提供者组件)
- Android四大组件之一,内容提供器Content Provider详解
- 【Android 开发】:Content Provider (内容提供者) 详解
- 【Android 开发】:Content Provider (内容提供者) 详解
- Android四大组件之 内容提供器Content Provider
- Android之内容提供者(Content Provider)
- 黑马程序员-Android基础四大组建内容提供者Content Provider
- Android内容提供者(Content provider)
- Android Content Provider(内容提供者)
- Android四大组件之Content Provider
- 复杂链表的复制
- 数据流分析(二)
- 请求网络之HttpUrlConnection
- iOS 单例
- Android中View事件分发机制
- Android笔记---四大组件之Content Provider内容提供者详解
- python-pickle泡菜学习笔记
- AOJ--0558 Cheese
- ps切图(5)——图层原理及其操作
- 九度题目1186
- Android之external部分目录功能说明整理
- 机房收费系统之可行性研究报告
- EJB-EJB的基本分类
- 自定义ListView,禁止上下滑动