`
zhuxinzx
  • 浏览: 293669 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

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";
   }
  
  }

分享到:
评论

相关推荐

    android之ContentResolver与ContentProvider介绍

    在Android开发中,ContentResolver和ContentProvider是两个至关重要的组件,它们允许不同应用之间安全地共享数据。ContentResolver作为一个接口,提供了统一的方式来访问和操作数据,而ContentProvider则是实现数据...

    ContentProvider实现数据共享

    在Android系统中,ContentProvider是四大组件之一,它扮演着数据共享的重要角色。ContentProvider使得应用程序之间能够安全、有序地访问彼此的数据,无论是保存在SQLite数据库中的数据,还是存储在文件系统或者其他...

    Android 之 自定义ContentProvider的使用

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

    andoid中ContentProvider完整实例.

    本实例将详细介绍如何创建并使用ContentProvider实现数据的增删改查(CRUD)操作。 首先,我们需要定义一个ContentProvider类,继承自Android的`ContentProvider`基类。这个类需要重写几个关键方法,包括`onCreate...

    ContentProvider案例

    在`http://blog.csdn.net/dmk877/article/details/50387741`这篇博客中,作者详细介绍了如何创建和使用ContentProvider。首先,你需要创建一个继承自`android.content.ContentProvider`的类,并实现其关键方法,包括...

    Android ContentProvider简单实现

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

    调用 ContentProvider

    以下步骤介绍了如何使用ContentResolver: 1. **获取ContentResolver**:在需要访问数据的类或方法中,通过调用`getApplicationContext().getContentResolver()`获取ContentResolver实例。 2. **定义URI**:每个...

    ContentProvider实现IPC的简单Demo

    本教程将通过一个简单的Demo来介绍如何使用ContentProvider进行数据交换。 首先,我们需要理解ContentProvider的基本结构。一个ContentProvider由以下几个关键部分组成: 1. **AndroidManifest.xml配置**:在应用...

    跨应用数据源ContentProvider

    最后,`ch11_permission_invoke_content_provider`可能介绍了如何在权限控制下正确地调用ContentProvider,确保数据访问的安全性。 总的来说,学习和掌握跨应用数据源ContentProvider,开发者可以实现应用间的数据...

    ContentProvider短信的获取备份

    博客中可能会介绍如何构建一个ContentQuery类,用于封装查询条件和参数,例如按日期、收件人等筛选短信。ContentQuery将与ContentResolver的query方法一起使用,以获取满足特定条件的短信数据。 接下来,我们需要...

    ContentProvider数据共享

    下面将详细介绍ContentProvider数据共享的基本使用方法。 1. 创建ContentProvider 要创建一个ContentProvider,你需要继承`android.content.ContentProvider`类,并重写其中的关键方法,如`onCreate()`, `query()`,...

    联系人操作 ContentProvider ContentResolver使用

    本篇将详细介绍如何在Android中利用ContentProvider和ContentResolver来操作联系人。 一、ContentProvider基础 1. **ContentProvider的作用**:ContentProvider为应用程序提供了一种标准化的方式,使得应用的数据...

    第8章 跨程序共享数据,探究ContentProvider.pptx

    本文将详细介绍 ContentProvider 的主要功能、运行时权限的简介、机制设计和代码示例。 ContentProvider 的主要功能 ------------------------- ContentProvider 是 Android 中的一种机制,用于在不同的应用程序...

    ContentProvider工具类

    本篇将详细介绍ContentProvider及其工具类的工作原理、使用方法以及如何在实际项目中应用。 一、ContentProvider基础 ContentProvider是Android系统提供的一个接口,用于暴露应用程序的数据,让其他应用能够通过...

    Google.Android开发入门与实战

    8.5 我的数据你来用——ContentProvider介绍 8.5.1 初识ContentProvider 8.5.2 使用ContentProvider读取系统数据 8.5.3 使用ContentProvider操作数据日记本实例 8.6 再学一招——网络存储 8.7 本章小结 第9章 我来...

    Google Android开发入门与实战的代码

    8.5 我的数据你来用——ContentProvider介绍 155 8.5.1 初识ContentProvider 155 8.5.2 使用ContentProvider读取系统数据 156 8.5.3 使用ContentProvider操作数据日记本实例 159 8.6 再学一招——网络...

    Android开发应用实战详解源代码

    5.8.2 contentprovider介绍 5.8.3 具体实现 5.9 文件管理 5.10 还原手机桌面 5.11 置换背景图 5.12 修改和删除文件 5.12.1 实现原理 5.12.2 java i/o基本类库介绍 5.12.3 具体实现 5.13 获取file和cache的路径 5.14...

    contentprovider

    2 相关概念介绍 1)ContentProvider简介 当应用继承ContentProvider类 并重写该类用于提供数据和存储数据的方法 就可以向其他应用共享其数据 虽然使用其他方法也可以对外共享数据 但数据访问方式会因数据存储的...

    自定义ContentProvider

    下面将详细介绍自定义ContentProvider及其相关的知识点。 一、ContentProvider概述 ContentProvider是Android四大组件之一(Activity、Service、BroadcastReceiver、ContentProvider),它的主要任务是管理和提供...

Global site tag (gtag.js) - Google Analytics