`

Android ContentProvider的介绍(很详细)

 
阅读更多

一、ContentProvider的概念
  ContentProvider:为存储和获取数据提供统一的接口。可以在不同的应用程序之间共享数据。Android已经为常见的一些数据提供了默认的ContentProvider
  1、ContentProvider使用表的形式来组织数据
   无论数据的来源是什么,ContentProvider都会认为是一种表,然后把数据组织成表格
  2、ContentProvider提供的方法
   query:查询
   insert:插入
   update:更新
   delete:删除
   getType:得到数据类型
   onCreate:创建数据时调用的回调函数
  3、每个ContentProvider都有一个公共的URI,这个URI用于表示这个ContentProvider所提供的数据。Android所提供的ContentProvider都存放在android.provider包当中
  二、ContentProvider的内部原理
  自定义一个ContentProvider,来实现内部原理
  步骤:
  1、定义一个CONTENT_URI常量(里面的字符串必须是唯一)
  Public static final Uri CONTENT_URI = Uri.parse("content://com.WangWeiDa.MyContentprovider");
  如果有子表,URI为:
  Public static final Uri CONTENT_URI = Uri.parse("content://com.WangWeiDa.MyContentProvider/users");
  2、定义一个类,继承ContentProvider
  Public class MyContentProvider extends ContentProvider
  3、实现ContentProvider的所有方法(query、insert、update、delete、getType、onCreate)
  package com.WangWeiDa.cp;
  
  import java.util.HashMap;
  
  import com.WangWeiDa.cp.MyContentProviderMetaData.UserTableMetaData;
  import com.WangWeiDa.data.DatabaseHelp;
  
  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;
  
  public class MyContentProvider extends ContentProvider {
   //访问表的所有列
   public static final int INCOMING_USER_COLLECTION = 1;
   //访问单独的列
   public static final int INCOMING_USER_SINGLE = 2;
   //操作URI的类
   public static final UriMatcher uriMatcher;
   //为UriMatcher添加自定义的URI
   static{
   uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
   uriMatcher.addURI(MyContentProviderMetaData.AUTHORITIES,"/user",
   INCOMING_USER_COLLECTION);
   uriMatcher.addURI(MyContentProviderMetaData.AUTHORITIES,"/user/#",
   INCOMING_USER_SINGLE);
  
   }
   private DatabaseHelp dh;
   //为数据库表字段起别名
   public static HashMap userProjectionMap;
   static
   {
   userProjectionMap = new HashMap();
   userProjectionMap.put(UserTableMetaData._ID,UserTableMetaData._ID);
   userProjectionMap.put(UserTableMetaData.USER_NAME, UserTableMetaData.USER_NAME);
   }
   /**
   * 删除表数据
   */
   @Override
   public int delete(Uri uri, String selection, String[] selectionArgs) {
   System.out.println("delete");
   //得到一个可写的数据库
   SQLiteDatabase db = dh.getWritableDatabase();
   //执行删除,得到删除的行数
   int count = db.delete(UserTableMetaData.TABLE_NAME, selection, selectionArgs);
   return count;
   }
   /**
   * 数据库访问类型
   */
   @Override
   public String getType(Uri uri) {
   System.out.println("getType");
   //根据用户请求,得到数据类型
   switch (uriMatcher.match(uri)) {
   case INCOMING_USER_COLLECTION:
   return MyContentProviderMetaData.UserTableMetaData.CONTENT_TYPE;
   case INCOMING_USER_SINGLE:
   return MyContentProviderMetaData.UserTableMetaData.CONTENT_TYPE_ITEM;
   default:
   throw new IllegalArgumentException("UnKnown URI"+uri);
   }
   }
   /**
   * 插入数据
   */
   @Override
   public Uri insert(Uri uri, ContentValues values) {
   //得到一个可写的数据库
   SQLiteDatabase db = dh.getWritableDatabase();
   //向指定的表插入数据,得到返回的Id
   long rowId = db.insert(UserTableMetaData.TABLE_NAME, null, values);
   if(rowId > 0){//判断插入是否执行成功
   //如果添加成功,利用新添加的Id和
   Uri insertedUserUri = ContentUris.withAppendedId(UserTableMetaData.CONTENT_URI, rowId);
   //通知监听器,数据已经改变
   getContext().getContentResolver().notifyChange(insertedUserUri, null);
   return insertedUserUri;
   }
   return uri;
   }
   /**
   * 创建ContentProvider时调用的回调函数
   */
   @Override
   public boolean onCreate() {
   System.out.println("onCreate");
   //得到数据库帮助类
   dh = new DatabaseHelp(getContext(),MyContentProviderMetaData.DATABASE_NAME);
   return false;
   }
   /**
   * 查询数据库
   */
   @Override
   public Cursor query(Uri uri, String[] projection, String selection,
   String[] selectionArgs, String sortOrder) {
   //创建一个执行查询的Sqlite
   SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
   //判断用户请求,查询所有还是单个
   switch(uriMatcher.match(uri)){
   case INCOMING_USER_COLLECTION:
   //设置要查询的表名
   qb.setTables(UserTableMetaData.TABLE_NAME);
   //设置表字段的别名
   qb.setProjectionMap(userProjectionMap);
   break;
   case INCOMING_USER_SINGLE:
   qb.setTables(UserTableMetaData.TABLE_NAME);
   qb.setProjectionMap(userProjectionMap);
   //追加条件,getPathSegments()得到用户请求的Uri地址截取的数组,get(1)得到去掉地址中/以后的第二个元素
   qb.appendWhere(UserTableMetaData._ID + "=" + uri.getPathSegments().get(1));
   break;
   }
   //设置排序
   String orderBy;
   if(TextUtils.isEmpty(sortOrder)){
   orderBy = UserTableMetaData.DEFAULT_SORT_ORDER;
   }
   else{
   orderBy = sortOrder;
   }
   //得到一个可读的数据库
   SQLiteDatabase db = dh.getReadableDatabase();
   //执行查询,把输入传入
   Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy);
   //设置监听
   c.setNotificationUri(getContext().getContentResolver(), uri);
   return c;
  
   }
   /**
   * 更新数据库
   */
   @Override
   public int update(Uri uri, ContentValues values, String selection,
   String[] selectionArgs) {
   System.out.println("update");
   //得到一个可写的数据库
   SQLiteDatabase db = dh.getWritableDatabase();
   //执行更新语句,得到更新的条数
   int count = db.update(UserTableMetaData.TABLE_NAME, values, selection, selectionArgs);
   return count;
   }
  
  }
  
  4、在AndroidMinifest.xml中进行声明
    

 

 

 

 

 

 


   android:name=".cp.MyContentProvider"
  

 

 

 

 

 

 


   android:authorities="com.WangWeiDa.cp.MyContentProvider"
   />
  **为ContentProvider提供一个常量类MyContentProviderMetaData.java
  package com.WangWeiDa.cp;
  
  import android.net.Uri;
  import android.provider.BaseColumns;
  
  public class MyContentProviderMetaData {
   //URI的指定,此处的字符串必须和声明的authorities一致
   public static final String AUTHORITIES = "com.wangweida.cp.MyContentProvider";
   //数据库名称
   public static final String DATABASE_NAME = "myContentProvider.db";
   //数据库的版本
   public static final int DATABASE_VERSION = 1;
   //表名 
   public static final String USERS_TABLE_NAME = "user";
   
   public static final class UserTableMetaData implements BaseColumns{
   //表名
   public static final String TABLE_NAME = "user";
   //访问该ContentProvider的URI
   public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITIES + "/user");
   //该ContentProvider所返回的数据类型的定义
   public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.myprovider.user";
   public static final String CONTENT_TYPE_ITEM = "vnd.android.cursor.item/vnd.myprovider.user";
   //列名
   public static final String USER_NAME = "name";
   //默认的排序方法
   public static final String DEFAULT_SORT_ORDER = "_id desc";
   }
  
  }

分享到:
评论
4 楼 蓝月儿 2013-01-29  
CONTENT_TYPE 字符串中指定的
CONTENT_TYPE = "vnd.android.cursor.dir/vnd.myprovider.user";
CONTENT_TYPE_ITEM = "vnd.android.cursor.item/vnd.myprovider.user";
"vnd.android.cursor.dir/vnd."和"vnd.android.cursor.item/vnd"是什么意思?
3 楼 hongyabing 2012-10-21  
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
   uriMatcher.addURI(MyContentProviderMetaData.AUTHORITIES,"/user",
   INCOMING_USER_COLLECTION);
   uriMatcher.addURI(MyContentProviderMetaData.AUTHORITIES,"/user/#",
   INCOMING_USER_SINGLE);
这里不能写成,/user,/user/#,必须写成user,user/#
2 楼 asheng0401 2012-06-15  
逻辑比较乱
1 楼 liu1084 2012-03-09  
详细个毛啊 格式都这么乱 连个注释都懒得写

相关推荐

    Android+Room+ContentProvider

    在Android应用开发中,数据持久化是一个至关重要的环节,而Android Room和ContentProvider是其中的两个关键组件。本文将深入探讨这两个技术,并结合实际案例,解释如何在Android应用中使用它们来管理和共享SQLite...

    Android ContentProvider全面解析

    在Android系统中,ContentProvider是四大组件之一,它扮演着数据共享和访问的重要角色。ContentProvider使得应用程序可以将自己的数据结构暴露给其他应用,同时也能够访问其他应用公开的数据。本篇文章将全面解析...

    android 用ContentProvider操作文件

    在Android系统中,ContentProvider是一种核心组件,它允许应用程序之间共享数据,而无需直接访问对方的内部存储。在本教程中,我们将深入探讨如何利用ContentProvider来操作文件,以及其在跨应用数据传输中的作用。 ...

    android ContentProvider Demo

    在"oldS1_ContentProvider"和"Test"这两个文件中,"oldS1_ContentProvider"很可能包含了ContentProvider的具体实现,包括URI匹配、数据操作和权限控制。而"Test"文件可能是用来测试ContentProvider功能的类,通过...

    Android ContentProvider简单实现

    本篇文章将详细介绍如何在Android中实现一个简单的ContentProvider。 首先,理解ContentProvider的基本概念。ContentProvider是Android系统提供的一种机制,用于封装和暴露数据。它基于URI(统一资源标识符)来操作...

    Android中ContentProvider的示例

    在Android系统中,ContentProvider是四大组件之一,它扮演着数据共享的角色,使得不同应用程序间可以安全地交换数据。本示例将深入讲解如何创建和使用ContentProvider。 首先,我们来理解ContentProvider的基本概念...

    android contentprovider使用示例

    本示例将详细解释如何在Android中使用ContentProvider。 1. **ContentProvider基本概念** ContentProvider是Android系统提供的一种数据存储和访问机制,它允许应用程序之间进行数据交换,而无需暴露底层数据库或...

    免费下载:android ContentProvider详细解析

    ### android ContentProvider 详解 #### 一、ContentProvider 概述 ContentProvider 是 Android 四大组件之一,它主要用于在不同的应用程序之间实现数据共享。在 Android 中,每个应用程序都有自己的私有存储空间...

    Android学习 ContentProvider数据更新与Observer模式.doc

    在Android开发中,ContentProvider和Observer模式是两个关键的概念,它们在数据管理和更新中起着重要作用。ContentProvider作为Android系统中数据共享的桥梁,允许不同的应用程序之间交换数据,而Observer模式则是一...

    Android应用开发使用ContentProvider以及SQLite实现对数据库的相关操作

    ContentProvider则是Android框架提供的一种机制,用于在应用程序之间共享数据,同时也可用于管理SQLite数据库。接下来,我们将深入探讨如何使用ContentProvider和SQLite在Android应用中执行数据库操作。 首先,...

    android-关于ContentProvider的使用例子

    在Android开发中,ContentProvider是四大组件之一,它扮演着数据共享的重要角色。ContentProvider使得应用程序之间能够安全、有序地访问彼此的数据,无论是系统内置的数据(如联系人、日历等)还是自定义的数据存储...

    Android 之 自定义ContentProvider的使用

    博文链接中提到的"sunzone.iteye.com/blog/1884167"可能详细介绍了如何根据上述步骤创建一个自定义的ContentProvider。通过阅读这个博客,你可以获取具体的代码示例和实现细节。 10. **最佳实践** - 数据访问应尽...

    Android 基于ContentProvider 的音乐播放器

    Android基于ContentProvider的音乐播放器,通过读取系统多媒体信息,得到储存在外部存储器上的所有音频文件内容,用listview显示歌曲名和歌手信息.并通过mediaPlayer进行播放.该版本只是完成了一个音乐播放器的最简单...

    ContentProvider的创建与访问 android

    在Android系统中,ContentProvider是四大组件之一,它充当了数据共享的桥梁,使得不同的应用程序之间可以安全地读写数据。本篇文章将深入探讨ContentProvider的创建与访问过程,帮助你更好地理解和应用这一核心功能...

    Android-Intent-数据存取-ContentProvider.doc

    "Android Intent 和 ContentProvider" Android Intent 是 Android 组件之间的信使,负责在 Android 三大核心组件(Activity、Service、Broadcast Receiver)之间传递信息。Intent 是一个将要执行的动作的抽象描述...

    android自定义contentprovider

    在Android开发中,ContentProvider是一种核心组件,它允许应用程序间共享数据。ContentProvider构建于Android的URI机制之上,为其他应用提供了结构化的数据访问接口。本篇将详细讲解如何自定义ContentProvider,以及...

    android contentprovider的例子

    在Android应用开发中,ContentProvider是一个至关重要的组件,它扮演着数据共享的角色,使得不同的应用程序之间可以安全地读写共享数据。"android contentprovider的例子"这个主题将带你深入理解ContentProvider的...

    ContentProvider多表创建

    在Android系统中,ContentProvider是实现数据共享和跨应用数据访问的重要组件。它遵循统一的URI(Uniform Resource Identifier)机制,使得不同的应用可以方便地读取和修改存储在ContentProvider中的数据。本教程将...

    Android ContentProvider 使用详解源码

    在Android系统中,ContentProvider是实现跨应用数据共享的关键组件,它允许应用程序暴露自己的数据集,使得其他应用可以通过标准的接口进行访问。本教程将深入解析ContentProvider的使用及其源码,结合SQLite数据库...

Global site tag (gtag.js) - Google Analytics