为什么要用contentcontent provider详解

android 自己开发应用中用不用contentprovider_百度知道
android 自己开发应用中用不用contentprovider
我有更好的答案
  用不用主要看实际应用的需求。
  众所周知,A应用要访问B应用中的数据,最好的方法就是B应用提供给B一些访问接口,然后A通过这个接口来进行对B中的数据进行增删改查
  为了统一接口,Android中申明了内容提供者(ContentProvider)这样一个组件,优点是统一了数据的访问方式与提供方式,下面以B应用提供访问接口(ContentProvider)给A应用为例来详细阐述
  首先B应用必须写一个类继承自ContentProvider,并重写里面的一些方法
  public class PersonContentProvider extends
ContentProvider{
  public boolean onCreate()
  public Uri insert(Uri uri, ContentValues
  public int delete(Uri uri, String
selection, String[] selectionArgs)
  publi...
其他类似问题
为您推荐:
android的相关知识
等待您来回答
下载知道APP
随时随地咨询
出门在外也不愁<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
您的访问请求被拒绝 403 Forbidden - ITeye技术社区
您的访问请求被拒绝
亲爱的会员,您的IP地址所在网段被ITeye拒绝服务,这可能是以下两种情况导致:
一、您所在的网段内有网络爬虫大量抓取ITeye网页,为保证其他人流畅的访问ITeye,该网段被ITeye拒绝
二、您通过某个代理服务器访问ITeye网站,该代理服务器被网络爬虫利用,大量抓取ITeye网页
请您点击按钮解除封锁&本节引言:
本节给大家带来的是Android四大组件中的最后一个——ContentProvider(内容提供者),可能部分读者
有疑问了,"Android不是有五大组件的吗?还有个Intent呢?"对的,Intent也是很重要的,但是他
只是维系这几个组件间的纽带!Intent我们下一章会讲解!说会这个ContentProvider,我们什么时候
会用到他呢?有下面这两种:
1.我们想在自己的应用中访问别的应用,或者说一些ContentProvider暴露给我们的一些数据,
比如手机联系人,短信等!我们想对这些数据进行读取或者修改,这就需要用到ContentProvider了!
2.我们自己的应用,想把自己的一些数据暴露出来,给其他的应用进行读取或操作,我们也可以用
到ContentProvider,另外我们可以选择要暴露的数据,就避免了我们隐私数据的的泄露!
好像好流弊的样子,其实用起来也很简单,下面我们来对ContentProvider进行学习~
官方文档:
本节我们来讲解下ContentProvder的概念,给大家写几个常用的使用系统ContentProvider的示例,
以及自定义ContentProvider!
1.ContentProvider概念讲解:
2.使用系统提供的ContentProvider
其实很多时候我们用到ContentProvider并不是自己暴露自己的数据,更多的时候通过
ContentResolver来读取其他应用的信息,最常用的莫过于读取系统APP,信息,联系人,
多媒体信息等!如果你想来调用这些ContentProvider就需要自行查阅相关的API资料了!
另外,不同的版本,可能对应着不同的URL!这里给出如何获取URL与对应的数据库表的字段,
这里以最常用的联系人为例,其他自行google~
①来到系统源码文件下:all-src.rar -> TeleponeProvider -> AndroidManifest.xml查找对应API
②打开模拟器的file exploer/data/data/com.android.providers.contacts/databases/contact2.db
导出后使用SQLite图形工具查看,三个核心的表:raw_contact表,data表,mimetypes表!
下面演示一些基本的操作示例:
1)简单的读取收件箱信息:
核心代码:
private void getMsgs(){
Uri uri = Uri.parse("content://sms/");
ContentResolver resolver = getContentResolver();
//获取的是哪些列的信息
Cursor cursor = resolver.query(uri, new String[]{"address","date","type","body"}, null, null, null);
while(cursor.moveToNext())
String address = cursor.getString(0);
String date = cursor.getString(1);
String type = cursor.getString(2);
String body = cursor.getString(3);
System.out.println("地址:" + address);
System.out.println("时间:" + date);
System.out.println("类型:" + type);
System.out.println("内容:" + body);
System.out.println("======================");
cursor.close();
别忘了,往AndroidManifest.xml加入读取收件箱的权限:
&uses-permission android:name="android.permission.READ_SMS"/&
运行结果:
部分运行结果如下:
2)简单的往收件箱里插入一条信息
核心代码:
private void insertMsg() {
ContentResolver resolver = getContentResolver();
Uri uri = Uri.parse("content://sms/");
ContentValues conValues = new ContentValues();
conValues.put("address", "");
conValues.put("type", 1);
conValues.put("date", System.currentTimeMillis());
conValues.put("body", "no zuo no die why you try!");
resolver.insert(uri, conValues);
Log.e("HeHe", "短信插入完毕~");
运行结果:
注意事项:
上述代码在4.4以下都可以实现写入短信的功能,而5.0上就无法写入,原因是:
从5.0开始,默认短信应用外的软件不能以写入短信数据库的形式发短信!
3)简单的读取手机联系人
核心代码:
private void getContacts(){
//①查询raw_contacts表获得联系人的id
ContentResolver resolver = getContentResolver();
Uri uri = monDataKinds.Phone.CONTENT_URI;
//查询联系人数据
cursor = resolver.query(uri, null, null, null, null);
while(cursor.moveToNext())
//获取联系人姓名,手机号码
String cName = cursor.getString(cursor.monDataKinds.Phone.DISPLAY_NAME));
String cNum = cursor.getString(cursor.monDataKinds.Phone.NUMBER));
System.out.println("姓名:" + cName);
System.out.println("号码:" + cNum);
System.out.println("======================");
cursor.close();
别忘了加读联系人的权限:
&uses-permission android:name="android.permission.READ_CONTACTS"/&
运行结果:
部分运行结果如下:
4)查询指定电话的联系人信息
核心代码:
private void queryContact(String number){
Uri uri = Uri.parse("content://com.android.contacts/data/phones/filter/" + number);
ContentResolver resolver = getContentResolver();
Cursor cursor = resolver.query(uri, new String[]{"display_name"}, null, null, null);
if (cursor.moveToFirst()) {
String name = cursor.getString(0);
System.out.println(number + "对应的联系人名称:" + name);
cursor.close();
运行结果:
5)添加一个新的联系人
核心代码:
private void AddContact() throws RemoteException, OperationApplicationException {
//使用事务添加联系人
Uri uri = Uri.parse("content://com.android.contacts/raw_contacts");
Uri dataUri =
Uri.parse("content://com.android.contacts/data");
ContentResolver resolver = getContentResolver();
ArrayList&ContentProviderOperation& operations = new ArrayList&ContentProviderOperation&();
ContentProviderOperation op1 = ContentProviderOperation.newInsert(uri)
.withValue("account_name", null)
operations.add(op1);
//依次是姓名,号码,邮编
ContentProviderOperation op2 = ContentProviderOperation.newInsert(dataUri)
.withValueBackReference("raw_contact_id", 0)
.withValue("mimetype", "vnd.android.cursor.item/name")
.withValue("data2", "Coder-pig")
operations.add(op2);
ContentProviderOperation op3 = ContentProviderOperation.newInsert(dataUri)
.withValueBackReference("raw_contact_id", 0)
.withValue("mimetype", "vnd.android.cursor.item/phone_v2")
.withValue("data1", "")
.withValue("data2", "2")
operations.add(op3);
ContentProviderOperation op4 = ContentProviderOperation.newInsert(dataUri)
.withValueBackReference("raw_contact_id", 0)
.withValue("mimetype", "vnd.android.cursor.item/email_v2")
.withValue("data1", "")
.withValue("data2", "2")
operations.add(op4);
//将上述内容添加到手机联系人中~
resolver.applyBatch("com.android.contacts", operations);
Toast.makeText(getApplicationContext(), "添加成功", Toast.LENGTH_SHORT).show();
别忘了权限:
&uses-permission android:name="android.permission.WRITE_CONTACTS"/&
&uses-permission android:name="android.permission.WRITE_PROFILE"/&
3.自定义ContentProvider
我们很少会自己来定义ContentProvider,因为我们很多时候都不希望自己应用的数据暴露给
其他应用,虽然这样,学习如何ContentProvider还是有必要的,多一种数据传输的方式,是吧~
这是之前画的一个流程图:
接下来我们就来一步步实现:
在开始之前我们先要创建一个数据库创建类(数据库内容后面会讲~):
DBOpenHelper.java
public class DBOpenHelper extends SQLiteOpenHelper {
final String CREATE_SQL = "CREATE TABLE test(_id INTEGER PRIMARY KEY AUTOINCREMENT,name)";
public DBOpenHelper(Context context, String name, CursorFactory factory,
int version) {
super(context, name, null, 1);
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_SQL);
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// TODO Auto-generated method stub
Step 1:自定义ContentProvider类,实现onCreate(),getType(),根据需求重写对应的增删改查方法:
NameContentProvider.java
public class NameContentProvider extends ContentProvider {
//初始化一些常量
private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
private DBOpenHelper dbOpenH
//为了方便直接使用UriMatcher,这里addURI,下面再调用Matcher进行匹配
matcher.addURI("com.jay.example.providers.myprovider", "test", 1);
public boolean onCreate() {
dbOpenHelper = new DBOpenHelper(this.getContext(), "test.db", null, 1);
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
public String getType(Uri uri) {
public Uri insert(Uri uri, ContentValues values) {
switch(matcher.match(uri))
//把数据库打开放到里面是想证明uri匹配完成
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
long rowId = db.insert("test", null, values);
if(rowId & 0)
//在前面已有的Uri后面追加ID
Uri nameUri = ContentUris.withAppendedId(uri, rowId);
//通知数据已经发生改变
getContext().getContentResolver().notifyChange(nameUri, null);
return nameU
public int delete(Uri uri, String selection, String[] selectionArgs) {
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
Step 2:AndroidManifest.xml中为ContentProvider进行注册:
&!--属性依次为:全限定类名,用于匹配的URI,是否共享数据 --&
&provider android:name="com.jay.example.bean.NameContentProvider"
android:authorities="com.jay.example.providers.myprovider"
android:exported="true" /&
好的,作为ContentProvider的部分就完成了!
接下来,创建一个新的项目,我们来实现ContentResolver的部分,我们直接通过按钮点击插入一条数据:
MainActivity.java
public class MainActivity extends Activity {
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btninsert = (Button) findViewById(R.id.btninsert);
//读取contentprovider 数据
final ContentResolver resolver = this.getContentResolver();
btninsert.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
ContentValues values = new ContentValues();
values.put("name", "测试");
Uri uri = Uri.parse("content://com.jay.example.providers.myprovider/test");
resolver.insert(uri, values);
Toast.makeText(getApplicationContext(), "数据插入成功", Toast.LENGTH_SHORT).show();
如何使用?
好吧,代码还是蛮简单的,先运行作为ContentProvider的项目,接着再运行ContentResolver的项目,
点击按钮插入一条数据,然后打开file exploer将ContentProvider的db数据库取出,用图形查看工具
查看即可发现插入数据,时间关系,就不演示结果了~
4.通过ContentObserver监听ContentProvider的数据变化
使用指南:
运行程序后,晾一边,收到短信后,可以在logcat上看到该条信息的内容,可以根据自己的需求
将Activtiy改做Service,而在后台做这种事情~
本节小结:
好的,关于ContentProvider的初探就到这里,本节我们学习了:
ContentProvider的概念以及流程,使用系统提供的一些ContentProvider,以及定制自己的ContentProvider,
最后还讲解了通过ContentObserver监听ContentProvider的数据变化,ContentProvider的内容就掌握得差不多
了,下一节我们来走走文档看下有什么不知道的~谢谢
4.4.1 ContentProvider初探&&&&&&&&&&&
  最近写了一个数据库,这个数据库的服务没包装在Provider中,导致在测试的时候老是出现Cursor没有关闭的问题,搞不定,所以决定把数据的增删查改都写在Provider中,刚开始的时候不知道怎么写,参考了下源码中的闹钟的Provider。
  下面是系统源码中的闹钟的Provider:
* Copyright (C) 2007 The Android Open Source Project
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software 11
* distributed under the License is distributed on an "AS IS" BASIS, 12
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13
* See the License for the specific language governing permissions and 14
* limitations under the License. 15
17 &package com.android. 18
19 &import android.content.ContentP 20 &import android.content.ContentU 21 &import android.content.ContentV 22 &import android.content.C 23 &import android.content.UriM 24 &import android.database.C 25 &import android.database.SQLE 26 &import android.database.sqlite.SQLiteD 27 &import android.database.sqlite.SQLiteOpenH 28 &import android.database.sqlite.SQLiteQueryB 29 &import android.net.U 30 &import android.text.TextU 31
32 &public class AlarmProvider extends ContentProvider { 33
private SQLiteOpenHelper mOpenH 34
private static final int ALARMS = 1; 36
private static final int ALARMS_ID = 2; 37
private static final UriMatcher sURLMatcher = new UriMatcher( 38
UriMatcher.NO_MATCH); 39
static { 41
sURLMatcher.addURI("com.android.alarmclock", "alarm", ALARMS); 42
sURLMatcher.addURI("com.android.alarmclock", "alarm/#", ALARMS_ID); 43
private static class DatabaseHelper extends SQLiteOpenHelper { 46
private static final String DATABASE_NAME = "alarms.db"; 47
private static final int DATABASE_VERSION = 5; 48
public DatabaseHelper(Context context) { 50
super(context, DATABASE_NAME, null, DATABASE_VERSION); 51
@Override 54
public void onCreate(SQLiteDatabase db) { 55
db.execSQL("CREATE TABLE alarms (" + 56
"_id INTEGER PRIMARY KEY," + 57
"hour INTEGER, " + 58
"minutes INTEGER, " + 59
"daysofweek INTEGER, " + 60
"alarmtime INTEGER, " + 61
"enabled INTEGER, " + 62
"vibrate INTEGER, " + 63
"message TEXT, " + 64
"alert TEXT);"); 65
// insert default alarms 67 &
String insertMe = "INSERT INTO alarms " + 68
"(hour, minutes, daysofweek, alarmtime, enabled, vibrate, message, alert) " + 69
"VALUES "; 70
db.execSQL(insertMe + "(7, 0, 127, 0, 0, 1, '', '');"); 71
db.execSQL(insertMe + "(8, 30, 31, 0, 0, 1, '', '');"); 72
db.execSQL(insertMe + "(9, 00, 0, 0, 0, 1, '', '');"); 73
@Override 76
public void onUpgrade(SQLiteDatabase db, int oldVersion, int currentVersion) { 77
if (Log.LOGV) Log.v( 78
"Upgrading alarms database from version " + 79
oldVersion + " to " + currentVersion + 80
", which will destroy all old data"); 81
db.execSQL("DROP TABLE IF EXISTS alarms"); 82
onCreate(db); 83
public AlarmProvider() { 87
@Override 90
public boolean onCreate() { 91
mOpenHelper = new DatabaseHelper(getContext()); 92
return true; 93
@Override 96
public Cursor query(Uri url, String[] projectionIn, String selection, 97
String[] selectionArgs, String sort) { 98
SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); 99 100
// Generate the body of the query101 &
int match = sURLMatcher.match(url);102
switch (match) {103
case ALARMS:104
qb.setTables("alarms");105
case ALARMS_ID:107
qb.setTables("alarms");108
qb.appendWhere("_id=");109
qb.appendWhere(url.getPathSegments().get(1));110
default:112
throw new IllegalArgumentException("Unknown URL " + url);113
SQLiteDatabase db = mOpenHelper.getReadableDatabase();116
Cursor ret = qb.query(db, projectionIn, selection, selectionArgs,117
null, null, sort);118 119
if (ret == null) {120
if (Log.LOGV) Log.v("Alarms.query: failed");121
} else {122
ret.setNotificationUri(getContext().getContentResolver(), url);123
@Override129
public String getType(Uri url) {130
int match = sURLMatcher.match(url);131
switch (match) {132
case ALARMS:133
return "vnd.android.cursor.dir/alarms";134
case ALARMS_ID:135
return "vnd.android.cursor.item/alarms";136
default:137
throw new IllegalArgumentException("Unknown URL");138
@Override142
public int update(Uri url, ContentValues values, String where, String[] whereArgs) {143
long rowId = 0;145
int match = sURLMatcher.match(url);146
SQLiteDatabase db = mOpenHelper.getWritableDatabase();147
switch (match) {148
case ALARMS_ID: {149
String segment = url.getPathSegments().get(1);150
rowId = Long.parseLong(segment);151
count = db.update("alarms", values, "_id=" + rowId, null);152
default: {155
throw new UnsupportedOperationException(156
"Cannot update URL: " + url);157
if (Log.LOGV) Log.v("*** notifyChange() rowId: " + rowId + " url " + url);160
getContext().getContentResolver().notifyChange(url, null);161
@Override165
public Uri insert(Uri url, ContentValues initialValues) {166
if (sURLMatcher.match(url) != ALARMS) {167
throw new IllegalArgumentException("Cannot insert into URL: " + url);168
ContentV171
if (initialValues != null)172
values = new ContentValues(initialValues);173
values = new ContentValues();175 176
if (!values.containsKey(Alarm.Columns.HOUR))177
values.put(Alarm.Columns.HOUR, 0);178 179
if (!values.containsKey(Alarm.Columns.MINUTES))180
values.put(Alarm.Columns.MINUTES, 0);181 182
if (!values.containsKey(Alarm.Columns.DAYS_OF_WEEK))183
values.put(Alarm.Columns.DAYS_OF_WEEK, 0);184 185
if (!values.containsKey(Alarm.Columns.ALARM_TIME))186
values.put(Alarm.Columns.ALARM_TIME, 0);187 188
if (!values.containsKey(Alarm.Columns.ENABLED))189
values.put(Alarm.Columns.ENABLED, 0);190 191
if (!values.containsKey(Alarm.Columns.VIBRATE))192
values.put(Alarm.Columns.VIBRATE, 1);193 194
if (!values.containsKey(Alarm.Columns.MESSAGE))195
values.put(Alarm.Columns.MESSAGE, "");196 197
if (!values.containsKey(Alarm.Columns.ALERT))198
values.put(Alarm.Columns.ALERT, "");199 200
SQLiteDatabase db = mOpenHelper.getWritableDatabase();201
long rowId = db.insert("alarms", Alarm.Columns.MESSAGE, values);202
if (rowId & 0) {203
throw new SQLException("Failed to insert row into " + url);204
if (Log.LOGV) Log.v("Added alarm rowId = " + rowId);206 207
Uri newUrl = ContentUris.withAppendedId(Alarm.Columns.CONTENT_URI, rowId);208
getContext().getContentResolver().notifyChange(newUrl, null);209
return newU210
public int delete(Uri url, String where, String[] whereArgs) {213
SQLiteDatabase db = mOpenHelper.getWritableDatabase();214
long rowId = 0;216
switch (sURLMatcher.match(url)) {217
case ALARMS:218
count = db.delete("alarms", where, whereArgs);219
case ALARMS_ID:221
String segment = url.getPathSegments().get(1);222
rowId = Long.parseLong(segment);223
if (TextUtils.isEmpty(where)) {224
where = "_id=" +225
} else {226
where = "_id=" + segment + " AND (" + where + ")";227
count = db.delete("alarms", where, whereArgs);229
default:231
throw new IllegalArgumentException("Cannot delete from URL: " + url);232
getContext().getContentResolver().notifyChange(url, null);235
  其实对于数据库的操作,无非是四种,增删查改;在这里我仿照系统的闹钟的Provider自己写了一个Provider。以供以后忘记了的时候好参考参考:
  首先我们邀创建一个数据库,并确定数据库是否生成。
1 package com.test.
3 &import android.content.ContentV
4 &import android.content.C
5 &import android.database.sqlite.SQLiteD
6 &import android.database.sqlite.SQLiteOpenH
7 &import android.net.U
8 &import android.provider.BaseC
10 &public class AppDataBase extends SQLiteOpenHelper { 11
//数据库的名字 13 &
private static final String DATABASE_NAME = "test.db"; 14
private static final int DATABASE_VERSION = 1; 15
//数据表的名字 16 &
private static final String TABLE_NAME = "test"; 17
//数据表中的字段 18 &
public static final String FIELD_ID = "field_id"; 19
public static final String FIELD_SHOW = "field_show"; 20
public static final String FIELD_LOCTION = "field_location"; 21
//用于表示该数据的一个Uri 23 &
public static final Uri CONTENT_URI = Uri.parse("content://com.fermax.monitor/apps"); 24
//创建数据库 26 &
public AppDataBase (Context context) { 27
super(context, DATABASE_NAME, null, DATABASE_VERSION); 28
//创建表 31
@Override 32
public void onCreate (SQLiteDatabase db) { 33
String sql = "Create table "+TABLE_NAME+"("+BaseColumns._ID + " integer primary key autoincrement," +
FIELD_ID + " integer not null, "
FIELD_LOCTION + " integer not null, " +
FIELD_SHOW + " integer not null );"; 37
db.execSQL(sql); 38
initDataBase(db); 40
//初始化表 43
private void initDataBase (SQLiteDatabase db) { 44
ContentValues cv = new ContentValues(); 45
cv.put(FIELD_ID, 1); 46
cv.put(FIELD_LOCTION, 1); 47
cv.put(FIELD_SHOW, 1); 48
db.insert(TABLE_NAME, null, cv); 49
cv.clear(); 51
cv.put(FIELD_ID, 2); 52
cv.put(FIELD_LOCTION, 2); 53
cv.put(FIELD_SHOW, 1); 54
db.insert(TABLE_NAME, null, cv); 55
cv.clear(); 57
cv.put(FIELD_ID, 3); 58
cv.put(FIELD_LOCTION, 3); 59
cv.put(FIELD_SHOW, 0); 60
db.insert(TABLE_NAME, null, cv); 61
cv.clear(); 63
cv.put(FIELD_ID, 4); 64
cv.put(FIELD_LOCTION, 4); 65
cv.put(FIELD_SHOW, 1); 66
db.insert(TABLE_NAME, null, cv); 67
cv.clear(); 69
cv.put(FIELD_ID, 5); 70
cv.put(FIELD_LOCTION, 5); 71
cv.put(FIELD_SHOW, 0); 72
db.insert(TABLE_NAME, null, cv); 73
cv.clear(); 75
cv.put(FIELD_ID, 6); 76
cv.put(FIELD_LOCTION, 6); 77
cv.put(FIELD_SHOW, 0); 78
db.insert(TABLE_NAME, null, cv); 79
cv.clear(); 81
cv.put(FIELD_ID, 7); 82
cv.put(FIELD_LOCTION, 7); 83
cv.put(FIELD_SHOW, 0); 84
db.insert(TABLE_NAME, null, cv); 85
cv.clear(); 87
cv.put(FIELD_ID, 8); 88
cv.put(FIELD_LOCTION, 8); 89
cv.put(FIELD_SHOW, 1); 90
db.insert(TABLE_NAME, null, cv); 91
cv.clear(); 93
cv.put(FIELD_ID, 9); 94
cv.put(FIELD_LOCTION, 9); 95
cv.put(FIELD_SHOW, 0); 96
db.insert(TABLE_NAME, null, cv); 97
cv.clear(); 99
cv.put(FIELD_ID, 10);100
cv.put(FIELD_LOCTION, 10);101
cv.put(FIELD_SHOW, 0);102
db.insert(TABLE_NAME, null, cv);103
cv.clear();105
cv.put(FIELD_ID, 11);106
cv.put(FIELD_LOCTION, 11);107
cv.put(FIELD_SHOW, 0);108
db.insert(TABLE_NAME, null, cv);109
cv.clear();111
cv.put(FIELD_ID, 12);112
cv.put(FIELD_LOCTION, 12);113
cv.put(FIELD_SHOW, 0);114
db.insert(TABLE_NAME, null, cv);115
cv.clear();117
cv.put(FIELD_ID, 13);118
cv.put(FIELD_LOCTION, 13);119
cv.put(FIELD_SHOW, 0);120
db.insert(TABLE_NAME, null, cv);121
cv.clear();123
cv.put(FIELD_ID, 14);124
cv.put(FIELD_LOCTION, 14);125
cv.put(FIELD_SHOW, 1);126
db.insert(TABLE_NAME, null, cv);127
cv.clear();129
cv.put(FIELD_ID, 15);130
cv.put(FIELD_LOCTION, 15);131
cv.put(FIELD_SHOW, 1);132
db.insert(TABLE_NAME, null, cv);133
cv.clear();135
cv.put(FIELD_ID, 16);136
cv.put(FIELD_LOCTION, 16);137
cv.put(FIELD_SHOW, 1);138
db.insert(TABLE_NAME, null, cv);139
cv.clear();141
cv.put(FIELD_ID, 17);142
cv.put(FIELD_LOCTION, 17);143
cv.put(FIELD_SHOW, 0);144
db.insert(TABLE_NAME, null, cv);145
cv.clear();147
cv.put(FIELD_ID, 18);148
cv.put(FIELD_LOCTION, 18);149
cv.put(FIELD_SHOW, 1);150
db.insert(TABLE_NAME, null, cv);151
cv.clear();153
cv.put(FIELD_ID, 19);154
cv.put(FIELD_LOCTION, 19);155
cv.put(FIELD_SHOW, 0);156
db.insert(TABLE_NAME, null, cv);157
cv.clear();159
cv.put(FIELD_ID, 20);160
cv.put(FIELD_LOCTION, 20);161
cv.put(FIELD_SHOW, 0);162
db.insert(TABLE_NAME, null, cv);163
cv.clear();165
cv.put(FIELD_ID, 21);166
cv.put(FIELD_LOCTION, 21);167
cv.put(FIELD_SHOW, 0);168
db.insert(TABLE_NAME, null, cv);169
cv.clear();171
cv.put(FIELD_ID, 22);172
cv.put(FIELD_LOCTION, 22);173
cv.put(FIELD_SHOW, 0);174
db.insert(TABLE_NAME, null, cv);175
cv.clear();177
cv.put(FIELD_ID, 23);178
cv.put(FIELD_LOCTION, 23);179
cv.put(FIELD_SHOW, 0);180
db.insert(TABLE_NAME, null, cv);181
cv.clear();183
cv.put(FIELD_ID, 24);184
cv.put(FIELD_LOCTION, 24);185
cv.put(FIELD_SHOW, 0);186
db.insert(TABLE_NAME, null, cv);187
//用于更新表190
@Override191
public void onUpgrade (SQLiteDatabase db, int oldVersion, int newVersion) {192
String sql=" DROP TABLE IF EXISTS "+TABLE_NAME;193
db.execSQL(sql);194
onCreate(db);195
上面是创建了一个数据库并初始化了很多值,但我们并不知道数据库是否生成了,我们可以写一个测试类,来测试一下数据库是否生成了。
package com.test.import android.test.AndroidTestC/** * test the database. * @author shang * */public class DBTest extends AndroidTestCase {
//用于测试数据库是否生成
public void TestHomeDB() throws Exception {
AppDataBase appDataBase = new AppDataBase(this.getContext());
appDataBase.getWritableDatabase();
  写完测试类后不要忘记在manifest.xml文件中加上包和instrumentation:
1 &!-- android:targetPackage 是用来存放生成的数据库的位置的,可以和manifest中的package相同 --&2
&instrumentation3
android:name="android.test.InstrumentationTestRunner"4
android:targetPackage="com.test.provider"5
android:label="test for my app"/&
  如下所示:
  还有测试包,这个放在application下面,上面一个放在manifest根目录下面:
&!-- 这个是用来说明android测试的包 --&2
&uses-library android:name="android.test.runner"/&
  然后运行测试包,看data中对应的目录下生成了数据库文件没有:
我们可以看到生成了数据库了,好了,既然生成了数据库,我们就要把数据库的增删查改包装在一个Provider中,这个Provider是要继承ContentProvider的:
1 package com.test.
3 import android.content.ContentP
4 import android.content.ContentU
5 import android.content.ContentV
6 import android.content.UriM
7 import android.database.C
8 import android.database.sqlite.SQLiteD
9 import android.database.sqlite.SQLiteOpenH 10 import android.database.sqlite.SQLiteQueryB 11 import android.net.U 12 import android.text.TextU 13 import android.util.L 14
15 public class AppProvider extends ContentProvider { 16
private SQLiteOpenHelper mOpenH 18
//用于做所有的操作 20
private static final int APPS = 1; 21
//用于做跟ID有关的操作 23
private static final int APPS_ID = 2; 24
//初始化UriMatcher 26
private static final UriMatcher mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); 27
//在UriMatcher中加入指定的Uri 29
mUriMatcher.addURI("com.fermax.monitor", "apps", APPS); 31
mUriMatcher.addURI("com.fermax.monitor", "apps/#", APPS_ID); 32
//拿到OpenHelper的对象 35
@Override 36
public boolean onCreate () { 37
mOpenHelper = new AppDataBase(getContext()); 38
return true; 39
//做查询操作 42
@Override 43
public Cursor query (Uri uri, String[] projection, String selection, 44
String[] selectionArgs, String sortOrder) { 45
SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); 46
int match = mUriMatcher.match(uri); 48
switch (match) { 49
//直接查询表中的所有的数据 50
case APPS: 51
qb.setTables("test"); 52
//根据Id查询 55
case APPS_ID: 56
qb.setTables("test"); 57
qb.appendWhere("_id ="); 58
//拿到Uri后面的第一个参数,并将它赋给数据库中的字段_id. 60
qb.appendWhere(uri.getPathSegments().get(1)); 61
default: 64
throw new IllegalArgumentException("Unknow Uri " + uri); 65
//根据指定的条件查询数据,并返回Cursor 68
SQLiteDatabase db = mOpenHelper.getReadableDatabase(); 69
Cursor ret = qb.query(db, projection, selection, selectionArgs, null, null, sortOrder); 70
if(ret == null) { 71
Log.v("ddd","apps: apps query failed"); 72
} else { 73
ret.setNotificationUri(getContext().getContentResolver(), uri); 74
//返回给定的Uri数据的MIME类型 79
@Override 80
public String getType (Uri uri) { 81
int match = mUriMatcher.match(uri); 82
switch (match) { 83
case APPS: 84
return "vnd.android.cursor.dir/apps"; 85
case APPS_ID: 87
return "vnd.android.cursor.item/apps"; 88
default: 90
throw new IllegalArgumentException("Unknow uri"); 91
//做插入操作 95
@Override 96
public Uri insert (Uri uri, ContentValues initialValues) { 97
//插入操作要对所有的字段插入,如果带有参数,则报异常 98
if(mUriMatcher.match(uri) != APPS) { 99
throw new IllegalArgumentException("Can not insert into uri " + uri);100
//将给定的值插入数据库,如果给的值为空,则设默认值0103
ContentV104
if(initialValues != null) {105
values = new ContentValues(initialValues);106
} else {107
values = new ContentValues();108
if(!values.containsKey(AppDataBase.FIELD_ID)) {111
values.put(AppDataBase.FIELD_ID, 0);112
if(!values.containsKey(AppDataBase.FIELD_LOCTION)) {115
values.put(AppDataBase.FIELD_LOCTION, 0);116
if(!values.containsKey(AppDataBase.FIELD_SHOW)) {119
values.put(AppDataBase.FIELD_SHOW, 0);120
//向表中插入数据。123
SQLiteDatabase db = mOpenHelper.getWritableDatabase();124
long rowId = db.insert("test", null, values);125
if(rowId & 0) {126
throw new IllegalArgumentException("Failed to insert to " + uri);127
Uri newUri = ContentUris.withAppendedId(AppDataBase.CONTENT_URI, rowId);130
getContext().getContentResolver().notifyChange(newUri, null);131
return newU132
//删除数据135
@Override136
public int delete (Uri uri, String selection, String[] selectionArgs) {137
SQLiteDatabase db = mOpenHelper.getWritableDatabase();138
int match = mUriMatcher.match(uri);140
switch (match) {141
//如果没有参数,则删除指定的参数的列143
case APPS:144
count = db.delete("test", selection, selectionArgs);145
//如果带有参数ID,则删除指定的参数和指定Id的列148
case APPS_ID:149
String segment = uri.getPathSegments().get(1);150
if(TextUtils.isEmpty(selection)) {151
selection = "_id=" +152
} else {153
selection = "_id=" + segment + "and (" +
selection + ")" ;154
//执行删除操作157
count = db.delete("test", selection, selectionArgs);158
default:161
throw new IllegalArgumentException("can not delete from uri " + uri);162
getContext().getContentResolver().notifyChange(uri, null);165
//执行更新操作169
@Override170
public int update (Uri uri, ContentValues values, String selection,171
String[] selectionArgs) {172
long rowId = 0;174
int match = mUriMatcher.match(uri);175
SQLiteDatabase db = mOpenHelper.getWritableDatabase();176
switch (match) {177
//对指定的id的列进行更新178
case APPS_ID:179
//拿到Uri参数中的id,并转化成long类型,然后根据指定的id更新181
String segment = uri.getPathSegments().get(1);182
rowId = Long.valueOf(segment);183
count = db.update("test", values, "_id = " + rowId, null);184
default:187
throw new IllegalArgumentException("can not update the uri " + uri);188
getContext().getContentResolver().notifyChange(uri, null);190
完了之后我们要在manifest里面注册这个Provider:
&!-- 注册数据库的Provider --&2
&provider3
android:name=".AppProvider"4
android:authorities="com.fermax.monitor"5
android:exported="true"/
完了之后就可以在测试类中测试了,用Provider做增删查改非常方便:
//用于测试插入一条数据到数据库 3
public void testInsert() throws Exception { 4
ContentValues cv = new ContentValues(); 5
cv.put(AppDataBase.FIELD_ID, 100); 6
cv.put(AppDataBase.FIELD_LOCTION, 100); 7
cv.put(AppDataBase.FIELD_SHOW, 100); 8
getContext().getContentResolver().insert(AppDataBase.CONTENT_URI, cv); 9
//用于测试从数据库中删除一条数据12
public void testDelete() throws Exception {13
int _id = 25;14
String uriStr = "content://com.fermax.monitor/apps/" + _15
Uri uri = Uri.parse(uriStr);16
getContext().getContentResolver().delete(uri, null, null);17
//用于测试从数据库中查询数据20
public void testQuery() throws Exception {21
Cursor c = getContext().getContentResolver().query(AppDataBase.CONTENT_URI, null, null, null, null);22
if(c != null && c.getCount() != 0) {23
while(c.moveToNext()) {24
int location = c.getInt(c.getColumnIndexOrThrow(AppDataBase.FIELD_LOCTION));25
System.out.println("location = " + location);26
c.close();29
//用于测试从数据库中更新一条数据32
public void testUpdate() throws Exception {33
int _id = 24;34
String uriString = "content://com.fermax.monitor/apps/" + _35
Uri uri = Uri.parse(uriString);36
ContentValues cv = new ContentValues();37
cv.put(AppDataBase.FIELD_LOCTION, 150);38
getContext().getContentResolver().update(uri, cv, null, null);39
运行完成之后可以去数据库中查看数据库中的数据是否发生了变化,这里我就不在赘述。
下面是这个工程的打包文件:
阅读(...) 评论()

我要回帖

更多关于 content provider 的文章

 

随机推荐