android Content provider 组件

转载 2012年03月30日 00:02:02

http://www.cnblogs.com/linzheng/archive/2011/01/22/1942101.html


Content Provider 属于Android应用程序的组件之一,作为应用程序之间唯一的共享数据的途径,Content Provider 主要的功能就是存储并检索数据以及向其他应用程序提供访问数据的借口。


    Android 系统为一些常见的数据类型(如音乐、视频、图像、手机通信录联系人信息等)内置了一系列的 Content Provider, 这些都位于android.provider包下。持有特定的许可,可以在自己开发的应用程序中访问这些Content Provider。

   让自己的数据和其他应用程序共享有两种方式:创建自己的Content Provier(即继承自ContentProvider的子类)  或者是将自己的数据添加到已有的Content Provider中去,后者需要保证现有的Content Provider和自己的数据类型相同且具有该 Content Provider的写入权限。对于Content Provider,最重要的就是数据模型(data model) 和 URI。
  
   1.数据模型
    Content Provider 将其存储的数据以数据表的形式提供给访问者,在数据表中每一行为一条记录,每一列为具有特定类型和意义的数据。每一条数据记录都包括一个 "_ID" 数值字段,改字段唯一标识一条数据。

   2.URI
    URI,每一个Content Provider 都对外提供一个能够唯一标识自己数据集(data set)的公开URI, 如果一个Content Provider管理多个数据集,其将会为每个数据集分配一个独立的URI。所有的Content Provider 的URI 都以"content://" 开头,其中"content:"是用来标识数据是由Content Provider管理的 schema。

      在几乎所有的Content Provider 的操作中都会用到URI,因此一般来讲,如果是自己开发的Content Provider,最好将URI定义为常量,这样在简化开发的同时也提高了代码的可维护性。

      首先来介绍如何访问Content Provider中的数据,访问 Content Provider中的数据主要通过ContentResolver对象,ContentResolver类提供了成员方法可以用来对Content Provider 中的数据进行查询、插入、修改和删除等操作。 以查询为例,查询一个 Content Provider 需要掌握如下的信息。

      唯一标识Content Provider 的URI
      需要访问的数据字段名称。
      该数据字段的数据类型

  提示: 如果需要访问特定的某条数据记录,只需该记录的ID 即可。

    查询Content Provider的方法有两个:ContentResolver的query() 和 Activity 对象的 managedQuery(),二者接收的参数均相同,返回的都是Cursor 对象,唯一不同的是 使用managedQuery 方法可以让Activity 来管理 Cursor 的生命周期。

    被管理的Cursor 会在 Activity进入暂停状态的时候调用自己的 deactivate 方法自行卸载,而在Activity回到运行状态时会调用自己的requery 方法重新查询生成的Cursor对象。如果一个未被管理的Cursor对象想被Activity管理,可以调用Activity的 startManagingCursor方法来实现。

 

Android应用程序可以使用文件或SqlLite数据库来存储数据。Content Provider提供了一种多应用间数据共享的方式,比如:联系人信息可以被多个应用程序访问。Content Provider是个实现了一组用于提供其他应用程序存取数据的标准方法的类。

应用程序可以在Content Provider中执行如下操作:
查询数据

修改数据

添加数据

删除数据

 

/Chapter10_ContentProvider_01_Test02/src/com/amaker/ch10/app/MainActivity.java

代码
package com.amaker.ch10.app; import android.app.Activity; import android.content.ContentUris; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.util.Log; import com.amaker.ch10.app.Employees.Employee; public class MainActivity extends Activity { @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 添加 insert(); // 查询 query(); // 更新 update(); // 查询 query(); // 删除 del(); // 查询 query(); } // 删除方法 private void del(){ // 删除ID为1的记录 Uri uri = ContentUris.withAppendedId(Employee.CONTENT_URI, 1); // 获得ContentResolver,并删除 getContentResolver().delete(uri, null, null); } // 更新 private void update(){ // 更新ID为1的记录 Uri uri = ContentUris.withAppendedId(Employee.CONTENT_URI, 1); ContentValues values = new ContentValues(); // 添加员工信息 values.put(Employee.NAME, "hz.guo"); values.put(Employee.GENDER, "male"); values.put(Employee.AGE,31); // 获得ContentResolver,并更新 getContentResolver().update(uri, values, null, null); } // 查询 private void query(){ // 查询列数组 String[] PROJECTION = new String[] { Employee._ID, // 0 Employee.NAME, // 1 Employee.GENDER, // 2 Employee.AGE // 3 }; // 查询所有备忘录信息 Cursor c = managedQuery(Employee.CONTENT_URI, PROJECTION, null, null, Employee.DEFAULT_SORT_ORDER); // 判断游标是否为空 if (c.moveToFirst()) { // 遍历游标 for (int i = 0; i < c.getCount(); i++) { c.moveToPosition(i); // 获得姓名 String name = c.getString(1); String gender = c.getString(2); int age = c.getInt(3); // 输出日志 Log.i("emp", name+":"+gender+":"+age); } } } // 插入 private void insert(){ // 声明Uri Uri uri = Employee.CONTENT_URI; // 实例化ContentValues ContentValues values = new ContentValues(); // 添加员工信息 values.put(Employee.NAME, "amaker"); values.put(Employee.GENDER, "male"); values.put(Employee.AGE,30); // 获得ContentResolver,并插入 getContentResolver().insert(uri, values); } }

 

/Chapter10_ContentProvider_01_Test02/src/com/amaker/ch10/app/Employees.java

代码
package com.amaker.ch10.app; import android.net.Uri; import android.provider.BaseColumns; /** * 通讯录常量类 */ public final class Employees { // 授权常量 public static final String AUTHORITY = "com.amaker.provider.Employees"; private Employees() {} // 内部类 public static final class Employee implements BaseColumns { // 构造方法 private Employee() {} // 访问Uri public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/employee"); // 内容类型 public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.amaker.employees"; public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.amaker.employees"; // 默认排序常量 public static final String DEFAULT_SORT_ORDER = "name DESC";// 按姓名排序 // 表字段常量 public static final String NAME = "name"; // 姓名 public static final String GENDER= "gender"; // 性别 public static final String AGE = "age"; // 年龄 } }

/Chapter10_ContentProvider_01_Test02/src/com/amaker/ch10/app/EmployeeProvider.java

 

代码
package com.amaker.ch10.app; import java.util.HashMap; 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.database.sqlite.SQLiteQueryBuilder; import android.net.Uri; import android.text.TextUtils; import com.amaker.ch10.app.Employees.Employee; public class EmployeeProvider extends ContentProvider{ // 数据库帮助类 private DBHelper dbHelper; // Uri工具类 private static final UriMatcher sUriMatcher; // 查询、更新条件 private static final int EMPLOYEE = 1; private static final int EMPLOYEE_ID = 2; // 查询列集合 private static HashMap<String, String> empProjectionMap; static { // Uri匹配工具类 sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); sUriMatcher.addURI(Employees.AUTHORITY, "employee", EMPLOYEE); sUriMatcher.addURI(Employees.AUTHORITY, "employee/#", EMPLOYEE_ID); // 实例化查询列集合 empProjectionMap = new HashMap<String, String>(); // 添加查询列 empProjectionMap.put(Employee._ID, Employee._ID); empProjectionMap.put(Employee.NAME, Employee.NAME); empProjectionMap.put(Employee.GENDER, Employee.GENDER); empProjectionMap.put(Employee.AGE, Employee.AGE); } // 创建是调用 public boolean onCreate() { // 实例化数据库帮助类 dbHelper = new DBHelper(getContext()); return true; } // 添加方法 public Uri insert(Uri uri, ContentValues values) { // 获得数据库实例 SQLiteDatabase db = dbHelper.getWritableDatabase(); // 插入数据,返回行ID long rowId = db.insert(DBHelper.EMPLOYEES_TABLE_NAME, Employee.NAME, values); // 如果插入成功返回uri if (rowId > 0) { Uri empUri = ContentUris.withAppendedId(Employee.CONTENT_URI, rowId); getContext().getContentResolver().notifyChange(empUri, null); return empUri; } return null; } // 删除方法 public int delete(Uri uri, String selection, String[] selectionArgs) { // 获得数据库实例 SQLiteDatabase db = dbHelper.getWritableDatabase(); // 获得数据库实例 int count; switch (sUriMatcher.match(uri)) { // 根据指定条件删除 case EMPLOYEE: count = db.delete(DBHelper.EMPLOYEES_TABLE_NAME, selection, selectionArgs); break; // 根据指定条件和ID删除 case EMPLOYEE_ID: String noteId = uri.getPathSegments().get(1); count = db.delete(DBHelper.EMPLOYEES_TABLE_NAME, Employee._ID + "=" + noteId + (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""), selectionArgs); break; default: throw new IllegalArgumentException("错误的 URI " + uri); } getContext().getContentResolver().notifyChange(uri, null); return count; } // 获得类型 public String getType(Uri uri) { return null; } // 查询方法 public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); switch (sUriMatcher.match(uri)) { // 查询所有 case EMPLOYEE: qb.setTables(DBHelper.EMPLOYEES_TABLE_NAME); qb.setProjectionMap(empProjectionMap); break; // 根据ID查询 case EMPLOYEE_ID: qb.setTables(DBHelper.EMPLOYEES_TABLE_NAME); qb.setProjectionMap(empProjectionMap); qb.appendWhere(Employee._ID + "=" + uri.getPathSegments().get(1)); break; default: throw new IllegalArgumentException("Uri错误! " + uri); } // 使用默认排序 String orderBy; if (TextUtils.isEmpty(sortOrder)) { orderBy = Employee.DEFAULT_SORT_ORDER; } else { orderBy = sortOrder; } // 获得数据库实例 SQLiteDatabase db = dbHelper.getReadableDatabase(); // 返回游标集合 Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy); c.setNotificationUri(getContext().getContentResolver(), uri); return c; } // 更新方法 public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { // 获得数据库实例 SQLiteDatabase db = dbHelper.getWritableDatabase(); int count; switch (sUriMatcher.match(uri)) { // 根据指定条件更新 case EMPLOYEE: count = db.update(DBHelper.EMPLOYEES_TABLE_NAME, values, selection, selectionArgs); break; // 根据指定条件和ID更新 case EMPLOYEE_ID: String noteId = uri.getPathSegments().get(1); count = db.update(DBHelper.EMPLOYEES_TABLE_NAME, values, Employee._ID + "=" + noteId + (!TextUtils.isEmpty(selection) ? " AND (" + selection + ')' : ""), selectionArgs); break; default: throw new IllegalArgumentException("错误的 URI " + uri); } getContext().getContentResolver().notifyChange(uri, null); return count; } }

 

 

 

/Chapter10_ContentProvider_01_Test02/src/com/amaker/ch10/app/DBHelper.java

代码
package com.amaker.ch10.app; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; import com.amaker.ch10.app.Employees.Employee; /** * * 数据库工具类 */ public class DBHelper extends SQLiteOpenHelper{ // 数据库名称常量 private static final String DATABASE_NAME = "Employees.db"; // 数据库版本常量 private static final int DATABASE_VERSION = 1; // 表名称常量 public static final String EMPLOYEES_TABLE_NAME = "employee"; // 构造方法 public DBHelper(Context context) { // 创建数据库 super(context, DATABASE_NAME,null, DATABASE_VERSION); } // 创建时调用 public void onCreate(SQLiteDatabase db) { db.execSQL("CREATE TABLE " + EMPLOYEES_TABLE_NAME + " (" + Employee._ID + " INTEGER PRIMARY KEY," + Employee.NAME + " TEXT," + Employee.GENDER + " TEXT," + Employee.AGE + " INTEGER" + ");"); } // 版本更新时调用 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // 删除表 db.execSQL("DROP TABLE IF EXISTS employee"); onCreate(db); } }

 

/Chapter10_ContentProvider_01_Test02/AndroidManifest.xml

代码
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.amaker.ch10.app" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon" android:label="@string/app_name"> <provider android:name="EmployeeProvider" android:authorities="com.amaker.provider.Employees"/> <activity android:name=".MainActivity" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-sdk android:minSdkVersion="3" /> </manifest>

相关文章推荐

android四大组件(总结)activity、service、content provider、broadcast receiver

Android四大组件分别为activity、service、content provider、broadcast receiver。 一、android四大组件详解 1、activi...

[Android知识体系]之四大组件:Content Provider应用实例

转载,原文:http://blog.csdn.net/luoshengyang/article/details/6950440上文简要介绍了Android应用程序组件Content Provider在...

15_Android四大组件:Activity 、Service、Broadcast receiver 、Content provider

Android四大组件:Activity、Service、Broadcast receiver、Content provider   在Android中,一个应用程序可以使用其它应用程序的组...

Android四大基本组件——Content Provider

ContentProvider:使一个应用程序的指定数据集提供给其他应用程序使用。这些数据可以存储在文件系统中、在一个SQLite数据库、或以任何其他合理的方式。 其他应用可以通过ContentRes...

Android 四大组件之Content Provider

ContentProvider的定义 为存储和获取数据提供统一的接口。可以在不同的应用程序之间共享数据。 ContentProvider提供的方法 query:查询 insert:插入 upd...
  • ashank
  • ashank
  • 2015年08月05日 20:44
  • 252

Android的四大组件:Activity、Service、Content Provider、Broadcast Receiver

组件是一个Android程序至关重要的构建模块。每一个组件都是系统进入你的应用的不同途径。但并不是所有的组件都是用户进入程序的真实入口,其中一些要依赖于其它组件,但是每一个组件都以自己独有的形式存在,...

01 Android应用的构成 四大组件 Activity, Intent Receiver , Service , Content Provider

对于一个Android应用程序来说,是由四种构造块组织而成的,这四种构造块如下: 但是,并不是每一个Android应用程序都需要这四种构造块,这不是必须的,某些时候,我们只需要这四种...

Android静态安全检测 -> Content Provider组件本地SQL注入漏洞

Content Provider组件本地SQL注入漏洞 - ContentProvider.query方法 一、API 1. 继承关系 【1】java.lang.Object 【2】and...

Android应用程序组件Content Provider的启动过程源代码分析

通过前面的学习,我们知道在Android系统中,Content Provider可以为不同的应用程序访问相同的数据提供统一的入口。Content Provider一般是运行在独立的进程中的,每一个Co...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:android Content provider 组件
举报原因:
原因补充:

(最多只允许输入30个字)