ContentProvider 的使用(1)
1)新建Android 项目,成功后,先编写我自己的Employee 类:
/*
* Copyright (C) Mesada Technologies Co., Ltd. 2005-2011.
* All rights reserved.
*
* This software is the confidential and proprietary information
* of Mesada Technologies Co., Ltd. ("Confidential Information").
* You shall not disclose such Confidential Information and shall
* use it only in accordance with the terms of the license agreement
* you entered into with Mesada.
*/
package com.mesada.demo;
import android.net.Uri;
/**
* 实体类,封装了相关的一些常量信息.
*
* @author Xiaolong Long
* @date 2011-3-10
* @version 1.0
*/
public class Employee {
public static final String MIME_DIR_PREFIX = "vnd.android.cursor.dir";
public static final String MIME_ITEM_PREFIX = "vnd.android.cursor.item";
public static final String MIME_ITEM = "vnd.mesada.employee";
//MIME:表示单一数据
public static final String MIME_TYPE_SINGLE = MIME_ITEM_PREFIX + "/"
+ MIME_ITEM;
//MIME:表示多条数据
public static final String MIME_TYPE_MULTIPLE = MIME_DIR_PREFIX + "/"
+ MIME_ITEM;
public static final String AUTHORITY = "com.mesada.demo.provider.employeeprovider";
public static final String PATH_SINGLE = "employee/#";
public static final String PATH_MULTIPLE = "employee";
public static final String STR = "content://" + AUTHORITY + "/"
+ PATH_MULTIPLE;
public static final Uri CONTENT_URI = Uri.parse(STR);
public static final String ID = "_id";
public static final String NAME = "name";
public static final String AGE = "age";
}
2)新建类,继承自ContentProvider,并重写其接口函数,代码如下:
/*
* Copyright (C) Mesada Technologies Co., Ltd. 2005-2011.
* All rights reserved.
*
* This software is the confidential and proprietary information
* of Mesada Technologies Co., Ltd. ("Confidential Information").
* You shall not disclose such Confidential Information and shall
* use it only in accordance with the terms of the license agreement
* you entered into with Mesada.
*/
package com.mesada.demo.provider;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteDatabase.CursorFactory;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import com.mesada.demo.Employee;
/**
* A Content Provider about Employee,Content providers are one of the primary
* building blocks of Android applications, providing content to applications.
* They encapsulate data and provide it to applications through the single
* ContentResolver interface. A content provider is only required if you need to
* share data between multiple applications. For example, the contacts data is
* used by multiple applications and must be stored in a content provider. If
* you don't need to share data amongst multiple applications you can use a
* database directly via SQLiteDatabase.
*
*
* When a request is made via a ContentResolver the system inspects the
* authority of the given URI and passes the request to the content provider
* registered with the authority. The content provider can interpret the rest of
* the URI however it wants. The UriMatcher class is helpful for parsing URIs.
*
*
* @author Xiaolong Long
* @date 2011-3-14
* @version 1.0
*/
public class EmployeeProvider extends ContentProvider {
private static final String DB_NAME = "mesada.db";
private static final String DB_TABLE = "employee";
private static final int DB_VERSION = 1;
private Context mContext;
private SQLiteDatabase mDb;
private DBOpenHelper mDBOpenHelper;
private static final int MULTIPLE_EMPLOYEE = 1;
private static final int SINGLE_EMPLOYEE = 2;
private static final UriMatcher mUriMatcher;
static {
mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
mUriMatcher.addURI(Employee.AUTHORITY, Employee.PATH_MULTIPLE,
MULTIPLE_EMPLOYEE);
mUriMatcher.addURI(Employee.AUTHORITY, Employee.PATH_SINGLE,
SINGLE_EMPLOYEE);
}
@Override
public String getType(Uri uri) {
// 根据给定的URI,返回相应的 MIME 类型
int code = mUriMatcher.match(uri);
switch (code) {
// 返回表示多个选项的MIME类型
case MULTIPLE_EMPLOYEE:
return Employee.MIME_TYPE_MULTIPLE;
// 返回表示单条记录的MIME类型
case SINGLE_EMPLOYEE:
return Employee.MIME_TYPE_SINGLE;
default:
throw new IllegalArgumentException("Unknown Uri:" + uri);
}
}
@Override
public boolean onCreate() {
mContext = getContext();
mDBOpenHelper = new DBOpenHelper(mContext, DB_NAME, null, DB_VERSION);
try {
mDb = mDBOpenHelper.getWritableDatabase();
} catch (Exception e) {
mDb = mDBOpenHelper.getReadableDatabase();
}
if (mDb != null) {
return true; // 数据提供者被成功载入
} else {
return false; // 数据提供者载入失败
}
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int count = 0;
int code = mUriMatcher.match(uri);
switch (code) {
case MULTIPLE_EMPLOYEE:
count = mDb.delete(DB_TABLE, selection, selectionArgs);
break;
case SINGLE_EMPLOYEE:
String str = uri.getPathSegments().get(1);
count = mDb
.delete(DB_TABLE, Employee.ID + "=" + str, selectionArgs);
break;
default:
throw new IllegalArgumentException("Unknown Uri:" + uri);
}
// 执行相应操作后,需要通知observer(观察者),databases产生变化
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
long id = mDb.insert(DB_TABLE, null, values);
if (id > 0) {
Uri newUri = ContentUris.withAppendedId(Employee.CONTENT_URI, id);
// 执行相应操作后,需要通知observer(观察者),databases产生变化
getContext().getContentResolver().notifyChange(newUri, null);
return newUri;
}
throw new SQLException("Failed to insert row into " + uri);
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables(DB_TABLE);
int code = mUriMatcher.match(uri);
switch (code) {
case SINGLE_EMPLOYEE:
qb.appendWhere(Employee.ID + "=" + uri.getPathSegments().get(1));
break;
default:
break;
}
Cursor cursor = qb.query(mDb, projection, selection, selectionArgs,
null, null, sortOrder);
cursor.setNotificationUri(getContext().getContentResolver(), uri);
return cursor;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
int count;
int code = mUriMatcher.match(uri);
switch (code) {
case MULTIPLE_EMPLOYEE:
count = mDb.update(DB_TABLE, values, selection, selectionArgs);
break;
case SINGLE_EMPLOYEE:
String segment = uri.getPathSegments().get(1);
count = mDb.update(DB_TABLE, values, Employee.ID + "=" + segment,
selectionArgs);
break;
default:
throw new IllegalArgumentException("Unknow URI:" + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
public class DBOpenHelper extends SQLiteOpenHelper {
private static final String DB_CREATE = "CREATE TABLE " + DB_TABLE
+ " (" + Employee.ID + " INTEGER PRIMARY KEY AUTOINCREMENT, "
+ Employee.NAME + " TEXT NOT NULL, " + Employee.AGE
+ " INTEGER);";
public DBOpenHelper(Context context, String name,
CursorFactory factory, int version) {
super(context, name, factory, version);
}
@Override
public void onCreate(SQLiteDatabase db) {
try {
db.execSQL(DB_CREATE);
System.err
.println("Verify that the table was created successfully.");
} catch (SQLiteException e) {
e.printStackTrace();
System.err.println("Failed to create table.");
}
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
/*
* 当你的应用要更新升级的时候,同时新版本中数据库表结构或内容有变化,这时upgrade方法会根据你的数据库版本号来判断数据库是否升级,
* 你可以在upgrade方法中执行数据库的变化。
*/
db.execSQL("DROP TABLE IF EXISTS " + DB_TABLE);
onCreate(db);
}
}
}
注:有人问onUpgrade(,,)函数会在什么时候调用,这取决于你的版本号是否已经改变,如 public DBOpenHelper(Context context, String name,
CursorFactory factory, int version) {
super(context, name, factory, version);
}中,如果version 改变了,就会执行该函数。
3) AndroidMainfest.xml 文件中加上provider 标签:
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mesada.demo.provider"
android:versionCode="1"
android:versionName="1.0">
<application
android:icon="@drawable/icon"
android:label="@string/app_name">
<provider
android:name=".EmployeeProvider"
android:authorities="com.mesada.demo.provider.employeeprovider" />
</application>
<uses-sdk
android:minSdkVersion="8" />
</manifest>
4)运行该项目后,即可。这样,ContentProvider 的开发工作已经完成,但它只是封闭了对数据操作的功能,如增删改查等。该项目没有相应的界面显示数据,在下一篇文章《ContentProvider 的使用(2)》说明如何调用ContentProvider,并对其进行增删改查的操作。
分享到:
相关推荐
本教程将深入讲解ContentProvider的使用方法,包括基础操作、多ContentProvider管理和多表操作。 首先,基础的ContentProvider用法涉及以下几个步骤: 1. **定义Uri匹配规则**:ContentProvider通过Uri(统一资源...
1. **了解系统Provider**:Android系统内置了一些ContentProvider,如联系人、日历等,了解它们的URI和MIME类型,这对于使用它们至关重要。 2. **获取ContentResolver**:在任何Activity、Service或者...
1. **ContentProvider基本概念** ContentProvider是Android系统提供的一种数据存储和访问机制,它允许应用程序之间进行数据交换,而无需暴露底层数据库或文件系统。通过ContentProvider,应用的数据可以被其他应用...
下面我们将深入探讨ContentProvider的使用,并结合"ContentProviderApp1"和"ContentProviderApp2"这两个示例项目来阐述其核心概念。 1. **ContentProvider的基本结构** - `ContentProvider`是一个抽象类,你需要...
为了方便其他应用使用ContentProvider,还需提供一个公开的类,实现`CursorLoader`的子类,如`MyCursorLoader`,重写`loadInBackground()`方法,以便于使用Loader框架加载数据。 在其他应用中,可以通过`...
1. ContentProvider的实现:继承自`ContentProvider`,实现基本的CRUD操作。 2. AndroidManifest.xml中的声明:暴露Provider并指定数据类型。 3. ContentResolver的使用:作为访问ContentProvider的客户端接口。 4. ...
1. **理解ContentProvider** ContentProvider是Android提供的一种标准接口,使得不同应用之间的数据共享成为可能。它封装了对SQLite数据库、文件系统等数据存储方式的访问,使得其他应用可以通过统一的URI(Uniform...
1. **定义Uri(统一资源标识符)**:每个ContentProvider都与一个或多个Uri关联,这些Uri用来唯一标识ContentProvider中的数据。例如,`content://com.example.provider/users` 就是一个典型的Uri,用于访问名为...
其他应用可以通过ContentResolver访问这些数据,使用标准的URI和ContentProvider操作。 综上所述,Android Room简化了SQLite数据库的管理,提供了更友好的编程接口,而ContentProvider则为数据共享提供了统一的入口...
本教程将通过一个具体的示例,即查询通讯录联系人信息,深入解析ContentProvider的使用方法。我们将使用Eclipse作为集成开发环境进行演示。 首先,理解ContentProvider的基本概念。ContentProvider是Android系统...
1. **SQLite数据库**:通常,ContentProvider会与SQLite数据库配合使用,通过`SQLiteOpenHelper`类来创建和升级数据库。在ContentProvider中,可以创建`SQLiteOpenHelper`的实例,使用其提供的方法来操作数据库。 2....
本文将深入探讨如何自定义ContentProvider和如何有效地使用ContentResolver进行数据操作。 首先,ContentProvider是Android系统中的一种特殊组件,它允许应用程序公开自己的数据,使得其他应用可以通过标准接口进行...
(1) 使用自定义SQLiteOpenHelper来管理数据库; (2) 提交作业应列出操作数据的Uri及数据表的字段名称; (3) 提交作业应给出自定义的CP文件的核心代码。 资源中包含自定义ContentProvider的相关实现的代码(Homework...
本教程将深入解析ContentProvider的使用及其源码,结合SQLite数据库和ContentResolver,帮助开发者更好地理解和运用这一核心功能。 一、ContentProvider基础 ContentProvider是一个抽象类,它是Android四大组件之...
1. ContentProvider概述:ContentProvider是Android四大组件之一,它的主要职责是管理应用内的数据并提供对外接口,让其他应用能够通过URI(统一资源标识符)来访问这些数据。这对于文件操作来说尤其有用,因为这样...
该文件中有两个应用,db应用通过ContentProvider对外提供数据共享,other应用提供测试代码对数据进行增删改查。 参考博客:http://blog.csdn.net/tan313/article/details/44338425
这篇内容将深入解析ContentProvider的工作原理以及如何创建和使用它。 首先,ContentProvider通过定义一个标准的接口,让数据访问变得规范。它提供了一套标准的CRUD(Create、Read、Update、Delete)操作,使得应用...
1. **ContentProvider的作用**:ContentProvider为应用程序提供了一种标准化的方式,使得应用的数据可以被其他应用访问,同时也保护了数据的安全性。每个ContentProvider都有一个唯一的URI(统一资源标识符),用于...