ContentProvider的使用
这方面的资料应该网上已经很多了,我在这里只是做简单的总结就行了。
如题:ContentProvider是android的内容提供器,可以为应用程序提供各种的数据,例如数据表,txt文件,xml文件等等。应用程序可以利用SQLLiteDataBase这个类来操作数据表中的内容。
下面就简单的介绍下ContentProvider的具体使用。
ContentProvider使用可以分为两种情况:1.使用android系统提供的数据内容。2.使用android系统以外的应用程序提供的数据内容。
下面就分别介绍下这两种情况的使用过程。
1.使用android系统提供的数据内容
这里对android系统提供的通讯录进行操作
首先通过ContentResolver这个类来获得数据表的访问模型
ContentResolver resolver = getContentResolver();
有了这个类,再知道通讯录的uri,还有操作的参数就可以对通讯录操作了。
需要修改的内容(也就是sql中需要修改的部分)
ContentValues values = new ContentValues();
现在往通讯录中添加一条数据
首先需要获得一个通讯录的数据表中的id,之后为这个id添加相应的数据
// 向RawContacts.CONTENT_URI执行一个空值插入,
// 目的是获取系统返回的rawContactId
Uri uri = resolver.insert(RawContacts.CONTENT_URI, values);
// 获得新增空值的id
long id = ContentUris.parseId(uri);
向新增的id中添加联系人
values.put(Data.RAW_CONTACT_ID, id);
// 设置内容类性
values.put(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
// 设置联系人的名字
values.put(StructuredName.GIVEN_NAME, name.getText().toString());
// 向联系人URI添加联系人名字
resolver.insert(
ContactsContract.Data.CONTENT_URI,
values);
这样的话联系人的姓名就被添加到通讯录中了,如果还要添加电话号码,email等内容的话。同理如下处理:
values.clear();
values.put(Data.RAW_CONTACT_ID, id);
values.put(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
// 添加电话号码
values.put(Phone.NUMBER, phone.getText().toString());
values.put(Phone.TYPE, Phone.TYPE_MOBILE);
resolver.insert(
android.provider.ContactsContract.Data.CONTENT_URI,
values);
values.clear();
// 添加email
values.put(Data.RAW_CONTACT_ID, id);
values.put(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
values.put(Email.DATA, email.getText().toString());
values.put(Email.TYPE,Email.TYPE_WORK );
resolver.insert(
android.provider.ContactsContract.Data.CONTENT_URI,
values);
别忘记添加对通讯录的权限
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.WRITE_CONTACTS"/>
这样第一种情况就算完成了。注意添加不同的信息的时候ContentValues的put的内容的不同。
第二种情况,应用程序1访问应用程序2的数据内容,那么首先要将程序2的数据内容构造成一个ContentProvider,供程序1使用。
那么这里依旧将程序2中数据表的内容共享出来。
第一步:为程序2建造一个数据库,紧接生成数据表
public class MyDatabaseHelper extends SQLiteOpenHelper { /**
* 创建数据表
*/
final String CREATE_TABLE_SQL = "create table dict(_id integer primary key autoincrement , word , detail)"; /**
* @param context 上下午对象
* @param name 数据库名称
* @param version 版本号
*/
public MyDatabaseHelper(Context context, String name, int version) {
super(context, name, null, version);
} @Override
public void onCreate(SQLiteDatabase db) {
// 第一次使用数据库时自动建表
db.execSQL(CREATE_TABLE_SQL);
} /* (non-Javadoc)更新数据库
* @see android.database.sqlite.SQLiteOpenHelper#onUpgrade(android.database.sqlite.SQLiteDatabase, int, int)
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
System.out.println("--------onUpdate Called--------" + oldVersion
+ "--->" + newVersion);
}
}
这样实例化
MyDatabaseHelper dbHelper = new MyDatabaseHelper(this, "myDict.db3", 1);
就可以建立一个数据库并生成一个数据表
因为MyDatabaseHelper继承了SQLiteOpenHelper,所有就可以使用dbHelper来操作数据库和数据表了
新增一条记录word,detail是传入表中两个字段的内容
dbHelper.execSQL("insert into dict values(null , ? , ?)", new String[] {
word, detail });
这样的话就将数据库和表创建成功
下一步将表的内容构建成ContentProvider,供其他的程序使用
/**
*
*/
package org.crazyit.content; import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri; /**
* Description:将新建的数据库共享(注意必须要继承ContentProvider,需要在配置文件增加provider节点)
* <br/>网站: <a href="http://www.crazyit.org">疯狂Java联盟</a>
* <br/>Copyright (C), 2001-2012, Yeeku.H.Lee
* <br/>This program is protected by copyright laws.
* <br/>Program Name:
* <br/>Date:
* @author Yeeku.H.Lee kongyeeku@163.com
* @version 1.0
*/
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);
}
}
}
上面的类用到了一些静态的变量
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 -->
<provider android:name=".DictProvider"
android:authorities="org.crazyit.providers.dictprovider"/>
这样程序2就已经将数据表的内容提供了出来,我们在程序1只需要在按照第一种情况对数据表进行操作即可。
在程序1中如下操作
// 获取系统的ContentResolver对象
contentResolver = getContentResolver();
新增一条数据(Words类和程序2中的是同样的)
//插入生词记录
ContentValues values = new ContentValues();
values.put(Words.Word.WORD , word);
values.put(Words.Word.DETAIL , detail);
contentResolver.insert(Words.Word.DICT_CONTENT_URI , values);
增删改查只要按照上面的操作举一反三即可。(注意的是数据表的uri的构建)
好了大体就是这个样子了,如果还有疑问,请看传播智客的视频,绝大部分都参考其内容。
测试的过程中,如果程序2没有启动,那么程序1是没有办法去操作程序2提供的数据表内容的。
ContentProvider的使用的更多相关文章
- Android之ContentProvider数据存储
一.ContentProvider保存数据介绍 一个程序可以通过实现一个ContentProvider的抽象接口将自己的数据完全暴露出去,而且ContentProvider是以类似数据库中表的方式将数 ...
- Xamarin.Android之ContentProvider
一.前言 掌握了如何使用SQLiteOpenHelper之后,我们就可以进行下一步的学习.本章我们将会学习如何使用ContentProvider来将数据库方面的操作封装起来,同时它还可以供其他应用访问 ...
- ContentProvider域名替换小工具
开发项目域名想怎么换就怎么换,就是这么任性! 这是一个很有意思的小工具! 这是一个方便开发人员和测试人员的小工具!! 吐槽: 一直在做Android开发,一直总有一个问题存在:做自己公司的apk开发时 ...
- Android开发学习—— ContentProvider内容提供者
* 应用的数据库是不允许其他应用访问的* 内容提供者的作用就是让别的应用访问到你的数据库.把私有数据暴露给其他应用,通常,是把私有数据库的数据暴露给其他应用. Uri:包含一个具有一定格式的字符串的对 ...
- 简单的学习心得:网易云课堂Android开发第六章SQLite与ContentProvider
一.SQLite 1.基本操作: (1)创建数据库:在SQLiteOpenHelper的子类构造器中创建. (2)创建表:在SQLiteOpenHelper的子类onCreate方法中,调用execS ...
- ContentProvider中央档案馆,以及获取联系人电话的示例
Android官方文档介绍的数据存储方式共有五种,sqlite,SharedPreferences,网络存储,外储存储,文件存储,但是这些数据都无法进行共享,那么我们就引入了今天的主角:Content ...
- Android基础 : Android ContentProvider
Android 应用程序通过ContentProvider实现方式统一的数据共享功能. 外界的程序通过ContentResolver接口可以访问ContentProvider提供的数据,在Activi ...
- 安卓初級教程(3):ContentProvider的運用原理
package com.example.android.provider; import java.util.ArrayList; import java.util.HashMap; import j ...
- Android探索之ContentProvider熟悉而又陌生的组件
前言: 总结这篇文章之前我们先来回顾一下Android Sqlite数据库,参考文章:http://www.cnblogs.com/whoislcj/p/5506294.html,Android程序内 ...
- 四大组件之ContentProvider
前言 ContentProvider作为Android的四大组件之一,是属于需要掌握的基础知识,可能在我们的应用中,对于Activity和Service这两个组件用的很常见,了解的也很多,但是对Con ...
随机推荐
- ubuntu12.04安装搜狗输入法配置,安装packettracer字体设置,软件推荐
装上系统,后的各种配置,各种出错之后的解决. 一.安装搜狗输入法 如果系统以前安装了先卸载: sudo apt-get remove fcitx* #删除配置文件 sudo apt-get purge ...
- 一个好用的Dialog插件
网页中常常须要弹出dialog,尽管非常多JS开源框架都提供这个功能,可是效果都不是非常好,比方easy-UI.改动样式这些又不是我擅长的,身边又没有美工兄弟,苦逼啊! (Easy-UI的BasicD ...
- android中设置TextView/Button 走马灯效果
在Android的ApiDemo中,有Button的走马灯效果,但是换作是TextView,还是有一点差异. 定义走马灯(Marquee),主要在Project/res/layout/main.xml ...
- 1.VMwareTools安装
1 选中虚拟机.右击.然后点击:安装Vmware-tool(最好是有网络的情况下安装) 2 将Vmware-tool的安装文件复制到暂时文件夹下,截图例如以下: 3 解压VMwareTools- ...
- 探索Oracle之数据库升级七 11gR2 to 12c 升级完毕后插入PDB
探索Oracle之数据库升级七 11gR2 to 12c 升级完毕后插入PDB 前言: 从Oracle 12c開始,引入了容器数据库的概念,能够实现数据库插拔操作,例如以下图: 如今我们 ...
- poj3177(边双连通分量+缩点)
传送门:Redundant Paths 题意:有n个牧场,Bessie 要从一个牧场到另一个牧场,要求至少要有2条独立的路可以走.现已有m条路,求至少要新建多少条路,使得任何两个牧场之间至少有两条独立 ...
- ubuntu 经常使用软件及环境
安装完系统后,更新系统 sudo apt-get update # 更新源索引 sudo apt-get dist-upgrade # 更新系统 sudo apt-get autoremove 1安装 ...
- IBM之MQ使用指南
随着计算机网络和分布式应用的不断发展.远程消息传递越来越成为应用系统中必不可少的组成部分. 商业消息中间件的出现保证了消息传输的可靠性,高效率和安全性,同一时候也降低了系统的开发周期. 眼下应用最多的 ...
- 开源图计算框架GraphLab介绍
GraphLab介绍 GraphLab 是由CMU(卡内基梅隆大学)的Select 实验室在2010 年提出的一个基于图像处理模型的开源图计算框架.框架使用C++语言开发实现. 该框架是面向机器学习( ...
- Java 使用AES/CBC/PKCS7Padding 加解密字符串
介于java 不支持PKCS7Padding,只支持PKCS5Padding 但是PKCS7Padding 和 PKCS5Padding 没有什么区别要实现在java端用PKCS7Padding填充, ...