Android应用开发学习笔记之ContentProvider

时间:2021-07-24 08:23:24

作者:刘昊昱

博客:http://blog.csdn.net/liuhaoyutz

ContentProvider用于为其它应用程序提供共享数据,它为不同应用程序间共享数据提供了统一的操作接口。

一、ContentProvider的Uri

每个ContentProvider都有对应的Uri,例如,一个自定义的ContentProvider Uri格式如下:

content://authority/path/id

例如:

content://com.liuhaoyu.myprovider/table1/10

1、  content://是“scheme”,Android规定ContentProvider的scheme固定为content://

2、  com.liuhaoyu.myprovider是“authority”,authority用于唯一标识这个ContentProvider,authority一般使用完整的类名来表示,以保证其唯一性。

另外,对于自定义的ContentProvider,还需要在AndroidManifest.xml中指定authority对ContentProvider进行唯一标识。例如:

<manifest.... >

<applicationandroid:icon="@drawable/icon"android:label="@string/app_name">

<provider android:name=".MyContentProvider"

android:authorities="com.liuhaoyu.myprovider"/>

</application>

</manifest>

3、  authority之后的部分,表示我们要操作的数据,包括“path”和“id”,具体包括几个字段,应该根据需要而定。例如:

要操作table2表中的所有记录,则路径为table2

要操作table2表中的ID为2的记录,则路径为table2/2

要操作table2表中的ID为2的记录的name字段,则路径为table2/2/name

如果要把字符串转换为Uri,可以使用Uri.parse()函数,例如:

Uri uri = Uri.parse(“content://com.liuhaoyu.myprovider/table1/10/name”);

二、Uri的辅助类

因为Uri会经常用到,所以Android提供了两个Uri辅助类UriMatcher和ContentUris。UriMatcher用于对Uri进行匹配,ContentUris用于对Uri的ID部分进行操作。

先来通过一个例子看UriMatcher的用法:

UriMatcher sMatcher = new UriMatcher(UriMatcher.NO_MATCH);

sMatcher.addURI("com.liuhaoyu.myprovider","person", 1);

sMatcher.addURI("com.liuhaoyu.myprovider","person/#", 2);//#号为通配符

switch (sMatcher.match(Uri.parse("content://com.liuhaoyu.myprovider/person/10"))){

case 1

break;

case 2

break;

default:

break;

}

首先通过UriMatcher.addURI()对URI进行注册。以后就可以使用UriMatcher.match()对要处理的Uri进行匹配,如果匹配成功,返回注册的返回码。

ContentUris类有两个比较实用的方法:

ContentUris.withAppendedId()函数用于将ID添加到路径后面。

Uri uri = Uri.parse("content://com.liuhaoyu.myprovider/table1")

Uri resultUri = ContentUris.withAppendedId(uri,1);

生成的resultUri为:content://com.liuhaoyu.myprovider/1

ContentUris.parseId()函数用于从Uri中分析出ID。

Uri uri =Uri.parse("content://com.ljq.provider.personprovider/person/10")

long personid = ContentUris.parseId(uri);//获取的结果为:10

三、预定义ContentProvider

Android提供了一些预定义的ContentProvider,包括声音、图片、视频、联系人等等,它们大多数位于android.provider包中,下面列出一些常用的预定义ContentProvider:

Borwser:书签、浏览历史、搜索历史

CallLog:通话历史

Contacts:联系人

MediaStore:声音、视频、图片

四、自定义ContentProvider

若要定义自己的ContentProvider,需要完成以下操作:

(1)、建立数据存储系统。大多数ContentProvider使用Android文件存储方式或者SQlite数据库保存数据,但是开发者可以使用任何方式存储数据。Android提供了SQLiteOpenHelper类帮助创建数据库,SQLiteDatabase类帮助管理数据库。

(2)、继承ContentProvider类来提供数据访问接口。一般需要实现ContentProvider类的如下成员函数:

public class PersonContentProvider extendsContentProvider{

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)

}

(3)、在应用程序的AndroidManifest.xml文件中声明ContentProvider。例如:

<manifest.... >

<applicationandroid:icon="@drawable/icon"android:label="@string/app_name">

<provider android:name=".MyContentProvider"

android:authorities="com.liuhaoyu.myprovider"/>

</application>

</manifest>

五、使用ContentResolver

ContentProvider内部如何保存数据由其设计者决定,但是所有的ContentProvider都实现了一组通用的方法,用来对数据进行增、删、改、查。其它应用程序对ContentProvider进行操作时,并不会直接调用ContentProvider实现的方法,而是通过ContentResolver类实现对ContentProvider的操作。

可以通过Activity.getContentResolver()函数获取ContentResolver对象。

ContentResolver类提供了对ContentProvider进行增、删、改、查的相应函数,具体可参考官方文档。

六、监听ContentProvider的变化

若访问者要监听ContentProvider的变化,可以使用ContentResolver.registerContentObserver()注册一个ContentObserver对象对指定ContentProvider进行监听,如果ContentProvider的数据发生了变化,则ContentObserver.onChange()方法会被调用,可以在该函数中进行相应处理。

而在ContentProvider这边,当其中的数据发生变化时,需要调用ContentResolver.notifyChange()函数通知注册的ContentObserver。

七、应用举例

下面来看一个使用预定义的ContentProvider的例子,该程序运行效果如下:

Android应用开发学习笔记之ContentProvider

先来看主布局文件,其内容如下:

<?xml version="1.0"encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" > <TextView
android:id="@+id/result"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@android:color/white"
android:textSize="25dp" /> </LinearLayout>

下面看主Activity文件,其内容如下:

package com.liuhaoyu;

import android.app.Activity;
import android.content.ContentResolver;
import android.database.Cursor;
import android.os.Bundle;
importandroid.provider.ContactsContract.Contacts;
importandroid.provider.ContactsContract.CommonDataKinds.Phone;
import android.widget.TextView; public class MainActivity extends Activity{
private String[] columns = { Contacts._ID,
Contacts.DISPLAY_NAME,
Phone.NUMBER,
Phone.CONTACT_ID, }; public void onCreate(BundlesavedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TextView tv = (TextView)findViewById(R.id.result);
tv.setText(getQueryData());
} private String getQueryData() { StringBuilder sb = new StringBuilder();
ContentResolver resolver =getContentResolver();
Cursor cursor =resolver.query(Contacts.CONTENT_URI, null, null, null, null);
while (cursor.moveToNext()) {
int idIndex =cursor.getColumnIndex(columns[0]);
int displayNameIndex =cursor.getColumnIndex(columns[1]);
int id = cursor.getInt(idIndex);
String displayName = cursor.getString(displayNameIndex);
Cursor phone =resolver.query(Phone.CONTENT_URI, null, columns[3] + "=" + id, null,null);
while (phone.moveToNext()) {
int phoneNumberIndex =phone.getColumnIndex(columns[2]);
String phoneNumber =phone.getString(phoneNumberIndex);
sb.append(displayName + ":" + "\n" + phoneNumber + "\n");
}
}
cursor.close();
return sb.toString();
}
}

Android应用开发学习笔记之ContentProvider的更多相关文章

  1. Android应用开发学习笔记之播放音频

    作者:刘昊昱 博客:http://blog.csdn.net/liuhaoyutz Android支持常用音视频格式文件的播放,本文我们来学习怎样开发Android应用程序对音视频进行操作. Andr ...

  2. android移动开发学习笔记(二)神奇的Web API

    本次分两个大方向去讲解Web Api,1.如何实现Web Api?2.如何Android端如何调用Web Api?对于Web Api是什么?有什么优缺点?为什么用WebApi而不用Webservice ...

  3. Android应用开发学习笔记之事件处理

    作者:刘昊昱 博客:http://blog.csdn.net/liuhaoyutz Android提供的事件处理机制分为两类:一是基于监听的事件处理:二是基于回调的事件处理.对于基于监听的事件处理,主 ...

  4. Android应用开发学习笔记之Intent

    作者:刘昊昱 博客:http://blog.csdn.net/liuhaoyutz Intent是什么呢?来看Android官网上的定义: An intent is an abstractdescri ...

  5. Android应用开发学习笔记之AsyncTask

    作者:刘昊昱 博客:http://blog.csdn.net/liuhaoyutz 在上一篇文章中我们学习了多线程和Handler消息处理机制,如果有计算量比较大的任务,可以创建一个新线程执行计算工作 ...

  6. [Android游戏开发学习笔记]View和SurfaceView

    本文为阅读http://blog.csdn.net/xiaominghimi/article/details/6089594的笔记. 在Android游戏中充当主要角色的,除了控制类就是显示类.而在A ...

  7. Android应用开发学习笔记之Fragment

    作者:刘昊昱 博客:http://blog.csdn.net/liuhaoyutz Fragment翻译成中文就是“碎片”.“片断”的意思,Fragment通常用来作为一个Activity用户界面的一 ...

  8. Android应用开发学习笔记之菜单

    作者:刘昊昱 博客:http://blog.csdn.net/liuhaoyutz Android中的菜单分为选项菜单(OptionMenu)和上下文菜单(Context Menu).通常使用菜单资源 ...

  9. Android应用开发学习笔记之多线程与Handler消息处理机制

    作者:刘昊昱 博客:http://blog.csdn.net/liuhaoyutz 和JAVA一样,Android下我们可以通过创建一个Thread对象实现多线程.Thread类有多个构造函数,一般通 ...

随机推荐

  1. 【Java EE 学习 75 上】【数据采集系统第七天】【二进制运算实现权限管理】【权限分析和设计】

    一.权限计算相关分析 1.如何存储权限 首先说一下权限保存的问题,一个系统中最多有多少权限呢?一个大的系统中可能有成百上千个权限需要管理.怎么保存这么多的权限?首先,我们使用一个数字中的一位保存一种权 ...

  2. Dev Winform 简洁界面模板制作

    今天看到Dev的安装程序,发现界面很漂亮如下图: 于是想到做个类似的简洁明了的界面出来,平常开发小程序什么的都方便很多. 1.首先是自己添加了一个XtraForm,我们发现它有点丑(我为了性能,习惯把 ...

  3. 常用IDEA快捷键

    [转]常用IDEA快捷键 阿烈的博客 2013-06-29 72 阅读   最近已经从eclipse转到IntelliJ IDEA,IDEA用起来太顺手了,许多功能正合我意. 看到时光印记写的一篇&l ...

  4. Beyond Compare 3 设置自动换行

    设置自动换行方法: 在菜单栏里点击“工具”,然后在弹出列表里选择“文件格式”,在弹出框的左下角编辑文件格式默认值中,选择“文本格式”,对右侧的 ‘每行字符限制’进行修改保存即可,一般可设置80或90. ...

  5. AOP PostSharp

    using System; using System.Collections.Generic; using System.Linq; using System.Text; using PostShar ...

  6. jQuery EasyUI Combobox无法检索中文输入的问题

    在项目里使用了EasyUI的Combobox,当ComboBox的item是英文时,都能正常检索出对应项,但是如果使用中文输入法输入几个字母然后通过按shift键输入时,奇怪的事情发生了,combob ...

  7. js原生代码编写一个鼠标在页面移动坐标的检测功能,兼容各大浏览器

    function mousePosition(e) {     //IE9以上的浏览器获取     if (e.pageX || e.pageY) {         return {         ...

  8. 第六篇:python高级之网络编程

    python高级之网络编程   python高级之网络编程 本节内容 网络通信概念 socket编程 socket模块一些方法 聊天socket实现 远程执行命令及上传文件 socketserver及 ...

  9. UVALive 2522&Tab;Chocolate(概率DP)

    思路:定义DP方程dp[i][j]标记选到第i个巧克力的时候,桌面上还剩下j个巧克力,状态转移有两个方向,dp[i-1][j-1],dp[i-1]lj+1],分别表示桌面上多了一个和消了一个,乘上需要 ...

  10. InnoSetup 脚本打包及管理员权限设置

    InnoSetup使用教程:InnoSetup打包安装 脚本详细 1. 定义变量 #define MyAppName "TranslationTool" #define MyApp ...