当Android中的应用需要访问其他应用的数据时,用ContentProvider可以很好的解决这个问题。今天介绍一下ContentProvider的用法。

首先开发ContentProvider有两个步骤:

1、开发一个ContentProvider的子类,该子类需要实现增、删、改、查等方法。

2、在AndroidManifest.xml文件中注册该ContentProvider。

下面通过一个实例来介绍一下ContentProvider到底怎么实现的。首先,我们也像系统一样把ContentProvider的Uri、数据列等信息以常量的形式公开出来、方便访问。为此,定义一个工具类,该类中只是包含一个public static的常量,该工具类的代码如下:

 public final class Words
{
// 定义该ContentProvider的Authority
public static final String AUTHORITY
= "org.crazyit.providers.dictprovider";
//定义一个静态内部类
public static final class Word implements BaseColumns
{
// 定义Content所允许操作的3个数据列
public final static String _ID = "_id";
public final static String WORD = "word";
public final static String DETAIL = "detail";
// 定义该Content提供服务的两个Uri
public final static Uri DICT_CONTENT_URI =
Uri.parse("content://" + AUTHORITY + "/words");
public final static Uri WORD_CONTENT_URI =
Uri.parse("content://" + AUTHORITY + "/word");
}
}

上面的工具类只是定义了一些简单的常量的工具类,这个工具类的作用就是告诉其他应用访问该ContentProvider的一些常用的入口。
  接下来开发一个ContentProvider的子类,并重写其中的增、删、改、查等方法,代码如下:

 public class DictProvider extends ContentProvider
{
private static UriMatcher matcher
= new UriMatcher(UriMatcher.NO_MATCH);
private static final int WORDS = 1;
private static final int WORD = 2;
private MyDatabaseHelper dbOpenHelper;
static
{
// 为UriMatcher注册两个Uri
matcher.addURI(Words.AUTHORITY, "words", WORDS);
matcher.addURI(Words.AUTHORITY, "word/#", WORD);
}
// 第一次调用该DictProvider时,系统先创建DictProvider对象,并回调该方法
@Override
public boolean onCreate()
{
dbOpenHelper = new MyDatabaseHelper(this.getContext(), "myDict.db3", 1);
return true;
}
// 插入数据方法
@Override
public Uri insert(Uri uri, ContentValues values)
{
// 获得数据库实例
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
// 插入数据,返回行ID
long rowId = db.insert("dict", Words.Word._ID, values);
// 如果插入成功返回uri
if (rowId > 0)
{
// 在已有的 Uri的后面追加ID数据
Uri wordUri = ContentUris.withAppendedId(uri, rowId);
// 通知数据已经改变
getContext().getContentResolver().notifyChange(wordUri, null);
return wordUri;
}
return null;
}
// 删除数据的方法
@Override
public int delete(Uri uri, String selection, String[] selectionArgs)
{
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
// 记录所删除的记录数
int num = 0;
// 对于uri进行匹配。
switch (matcher.match(uri))
{
case WORDS:
num = db.delete("dict", selection, selectionArgs);
break;
case WORD:
// 解析出所需要删除的记录ID
long id = ContentUris.parseId(uri);
String where = Words.Word._ID + "=" + id;
// 如果原来的where子句存在,拼接where子句
if (selection != null && !selection.equals(""))
{
where = where + " and " + selection;
}
num = db.delete("dict", where, selectionArgs);
break;
default:
throw new IllegalArgumentException("未知Uri:" + uri);
}
// 通知数据已经改变
getContext().getContentResolver().notifyChange(uri, null);
return num;
}
// 修改数据的方法
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs)
{
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
// 记录所修改的记录数
int num = 0;
switch (matcher.match(uri))
{
case WORDS:
num = db.update("dict", values, selection, selectionArgs);
break;
case WORD:
// 解析出想修改的记录ID
long id = ContentUris.parseId(uri);
String where = Words.Word._ID + "=" + id;
// 如果原来的where子句存在,拼接where子句
if (selection != null && !selection.equals(""))
{
where = where + " and " + selection;
}
num = db.update("dict", values, where, selectionArgs);
break;
default:
throw new IllegalArgumentException("未知Uri:" + uri);
}
// 通知数据已经改变
getContext().getContentResolver().notifyChange(uri, null);
return num;
}
// 查询数据的方法
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder)
{
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
switch (matcher.match(uri))
{
case WORDS:
// 执行查询
return db.query("dict", projection, selection, selectionArgs,
null, null, sortOrder);
case WORD:
// 解析出想查询的记录ID
long id = ContentUris.parseId(uri);
String where = Words.Word._ID + "=" + id;
// 如果原来的where子句存在,拼接where子句
if (selection != null && !"".equals(selection))
{
where = where + " and " + selection;
}
return db.query("dict", projection, where, selectionArgs, null,
null, sortOrder);
default:
throw new IllegalArgumentException("未知Uri:" + uri);
}
}
// 返回指定uri参数对应的数据的MIME类型
@Override
public String getType(Uri uri)
{
switch (matcher.match(uri))
{
// 如果操作的数据是多项记录
case WORDS:
return "vnd.android.cursor.dir/org.crazyit.dict";
// 如果操作的数据是单项记录
case WORD:
return "vnd.android.cursor.item/org.crazyit.dict";
default:
throw new IllegalArgumentException("未知Uri:" + uri);
}
}
}

上面的DictProvider类继承了ContentProvider,并实现了操作数据的增、删、改、查等方法。接下来需要在AndroidManitest.xml文件中注册该ContentProvider,代码:

 <!-- 注册一个ContentProvider -->
<provider android:name=".DictProvider"
android:authorities="org.crazyit.providers.dictprovider"/>

至此,整个ContentProvider开发完成,为了测试它,我们需要新建一个工程。
  在新的工程里,我们需要把上面创建的工具类拷贝到新工程里,下面的是使用ContentProvider的代码:

 public class DictResolver extends Activity
{
ContentResolver contentResolver;
Button insert = null;
Button search = null;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// 获取系统的ContentResolver对象
contentResolver = getContentResolver();
insert = (Button)findViewById(R.id.insert);
search = (Button)findViewById(R.id.search);
// 为insert按钮的单击事件绑定事件监听器
insert.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View source)
{
//获取用户输入
String word = ((EditText)findViewById(R.id.word))
.getText().toString();
String detail = ((EditText)findViewById(R.id.detail))
.getText().toString();
//插入生词记录
ContentValues values = new ContentValues();
values.put(Words.Word.WORD , word);
values.put(Words.Word.DETAIL , detail);
contentResolver.insert(Words.Word.DICT_CONTENT_URI , values);
//显示提示信息
Toast.makeText(DictResolver.this, "添加生词成功!" , 8000)
.show();
}
});
// 为search按钮的单击事件绑定事件监听器
search.setOnClickListener(new OnClickListener()
{
@Override
public void onClick(View source)
{
// 获取用户输入
String key = ((EditText) findViewById(R.id.key)).getText()
.toString();
// 执行查询
Cursor cursor = contentResolver.query(
47 Words.Word.DICT_CONTENT_URI, null
48 , "word like ? or detail like ?"
49 , new String[]{"%" + key + "%" , "%" + key + "%"}
50 , null);
//创建一个Bundle对象
Bundle data = new Bundle();
data.putSerializable("data", converCursorToList(cursor));
//创建一个Intent
Intent intent = new Intent(DictResolver.this
, ResultActivity.class);
intent.putExtras(data);
//启动Activity
startActivity(intent);
}
});
} private ArrayList<Map<String, String>> converCursorToList(
Cursor cursor)
{
ArrayList<Map<String, String>> result
= new ArrayList<Map<String, String>>();
// 遍历Cursor结果集
while (cursor.moveToNext())
{
// 将结果集中的数据存入ArrayList中
Map<String, String> map = new HashMap<String, String>();
// 取出查询记录中第2列、第3列的值
map.put(Words.Word.WORD, cursor.getString(1));
map.put(Words.Word.DETAIL, cursor.getString(2));
result.add(map);
}
return result;
}
}

至此,测试ContentProvider的关键代码已经给出了,希望能够帮助大家,在此也希望大家多多关注本人。

Android ContentProvider的实现的更多相关文章

  1. Android基础 : Android ContentProvider

    Android 应用程序通过ContentProvider实现方式统一的数据共享功能. 外界的程序通过ContentResolver接口可以访问ContentProvider提供的数据,在Activi ...

  2. Android ContentProvider完整案例

    ContentData类,提供数据常量: /** * 提供ContentProvider对外的各种常量,当外部数据需要访问的时候,就可以参考这些常量操作数据. * @author HB * */ pu ...

  3. Android ContentProvider基本用法

    转自:https://www.jianshu.com/p/601086916c8f 一.基本概念 ContentProvider是Android系统中提供的专门用户不同应用间进行数据共享的组件,提供了 ...

  4. Android ContentProvider 启动分析

    对于 ContentProvider 还不是很熟悉的同学,可以阅读上一篇 Android ContentProvider 基本原理和使用详解.本文主要是对 contentProvider 的源码进行分 ...

  5. Android ContentProvider介绍

    在Android中数据的存储一共有五种形式,分别是:Shared Preferences.网络存储.文件存储,外储存储.SQLite.但是我们知道一般这些存储都只是在单独的一个应用程序之中达到一个数据 ...

  6. Android ContentProvider 简单学习

    当应用继承ContentProvider类,并重写该类用于提供数据和存储数据的方法,就可以向其他应用共享其数据.以前我们学习过文件的操作模式,通过指定文件的操作模式为Context.MODE_WORL ...

  7. Android ContentProvider和Uri详解 (绝对全面)

        ContentProvider的基本概念 : 1.ContentProvider为存储和读取数据提供了统一的接口 2.使用ContentProvider,应用程序可以实现数据共享 3.andr ...

  8. Android ContentProvider和getContentResolver

    安卓系统中的数据库SqlLite操作和java中mysql的数据库操作很不一样,造成这样的原因是因为在安卓中数据库是属于进程的不存在数据库客户端,也不存在数据库服务器. 关于SqlLite数据库的文章 ...

  9. android ContentProvider学习

    1.ContentProvider提供位存储或获取数据提供了统一的接口. 2.使用ContentProvider可以在不同的应用程序之间共享数据. 3.Android为常见的一些数据提供了Conten ...

随机推荐

  1. 实体类实现Parcelable(包含boolean类型)

    实体类实现Parcelable接口需要实现方法: public ExtSignClockEntity(Parcel in) { timeMess = in.readString(); repeatMe ...

  2. springside3.1.8打包

    地址寻找 https://sourceforge.net/ https://sourceforge.net/projects/springside/files/SpringSide%203.0/3.3 ...

  3. solr5.2.1环境搭建教程

    环境:w8.1 + solr5.2.1 + apache7.0+jdk1.7 解压:solr5.2.1 复制E:\solr-5.2.1\server\webapps 下的solr.war包到D:\ap ...

  4. 在centos6.5中安装jdk

    一.下载jdk 下载地址 www.oracle.com,我这次安装的jdk是1.6版本的,以.bin结尾的,名称为 jdk-6u45-linux-i586.bin 二.安装步骤 1.在 /usr目录下 ...

  5. 关于Android代码混淆知识点

    现在有反编译技术,容易得到源码,所以要混淆代码,加大反编译难度. 只需要在 build.grade 的配置文件中配置就可以了. proguardFiles getDefaultProguardFile ...

  6. js中的apply和call API

    借用网上的一个例子: fun.call(this,arg1,arg2,arg3) fun.apply(this,arguments) this.fun(arg1,arg2,arg3) 三种方法等效. ...

  7. BOM组件物料重复检查

    好吧,今天同事让做个BOM组件物料重复检查 网上有很多例子都是在保存的时候检查的,用的是BADI :BOM_UPDATE 自己也试了一下,麻烦....很麻烦...尤其是在重复检查的时候: METHOD ...

  8. WordPress怎么在页面上添加目录

    要实现的如下功能,在页面上添加一个文章目录: 步骤:   1)在wordpress中,在Posts----Categories中建立目录, 2) 3)add new post,指定post所属的cat ...

  9. JavaScript之模块化编程

    前言 模块是任何大型应用程序架构中不可缺少的一部分,模块可以使我们清晰地分离和组织项目中的代码单元.在项目开发中,通过移除依赖,松耦合可以使应用程序的可维护性更强.与其他传统编程语言不同,在当前Jav ...

  10. mongodb的安装及注意事项

    环境:win8 32bit 1:安装 去mongodb的官网http://www.mongodb.org/downloads下载32bit的包 解压后会出现以下文件 在安装的盘C:下建立mongodb ...