posts - 1, comments - 0, trackbacks - 0, articles - 0

创建Content Providers

Posted on 2009-07-20 14:38 dgshine 阅读(464) 评论(0)  编辑  收藏 所属分类: Android

创建Content Providers

2009-07-03 IMTI Haerbin dg

目标:

       创建Content Providers ,让自己的程序所收集的数据能够被其他应用所访问

应用案例:

       Service Http形式抓取网络地震信息,存入本地SQLite3,供本地应用查询,统计,同时以Content Providers形式对外提供数据,让另一个基于google地图的程序能够根据经纬度在地图上显示地震区域,并且可以向Content Providers发起查询得到经纬度

问题:

1, 怎么创建Content Providers

2, 我们的程序怎么经由Content Providers访问数据

别人的程序怎么经由Content Providers查询我们的数据

关键角色:

1, Content URI

2, SQLiteOpenHelper

3, ContentResolver

4, SQLiteQueryBuilder

5, Content Providers工作原理

介绍 

       Content Providers 是一种让我们能够在不同应用间共享数据 的唯一的 通用化接口机制,通过对底层的数据源进行抽象,Content Providers 解除了应用程序层和数据层的耦合,这样应用程序可以轻便的在不同数据源之上切换(和DAO的理想相当一致)

       Content Providers 使用 权限控制,通过URI模式访问,读写双向,由此,任何具有对应permissions(许可、权限)的应用程序都可以增删查改 由另一个程序创建的数据---包括一些本地化Android数据库(也就是说你的程序可以Happy的访问通讯录,浏览器历史等

       同样,你可以把你自己的数据源(你开发的饭馆评价系统的数据)发布成Content Providers ,这样其他开发者就可以和你所开发的应用中的数据进行交互,甚至扩展(别人可以在你的数据基础上挖掘开发出菜品评价系统)

倒叙进行:如何调用Content Providers

       我们可以使用ContentResoler访问Content Providers,每一个应用上下文android.content.Context(Activity是他的子类)都持有一个ContentResolver引用,于是

      

ContentResolver cr = getContentResolver();就很贴心的出现了

 

ContentResolver我们拿到手后,可以使用query(),insert(),update()等方法,但是还有一个URI

       备注:content URI             


A.       标准的前缀,不可以修改

B.       标识部分,对于第三方应用(用户自己开发的应用),此处应该使用完整的包名类名来保证唯一性,其实是对应在manifest.xml<provider>节点的authorities属性值<provider class="TransportationProvider" authorities="com.example.transportationprovider" />

C.       content providers用来确定是何种数据请求的,这个可以没有,也可以有多个,如果content provider仅提供一种类型的数据(只有trains,例如咱们这个例子),那么此段可以省略。如果可以提供几种类型的数据,那么就可能形如: "land/bus, land/train, sea/ship, and sea/submarine"

D.       被指定的记录,一般是被请求记录的id值,如果被申请使用指定类型的所有数据,那么形如content://com.example.transportationprovider/trains

需要关心,作为ContentResolver,需要使用URI来告诉Android 想要和哪一个ContentProvider交互(调用)


1 //返回所有的地震信息
2 
3     Cursor c = cr.query(EarthquakeProvider.CONTENT_URI, PROJECTION, null,         null, EarthquakeProvider.DEFAULT_SORT_ORDER);

其中


1 public staticfinal Uri CONTENT_URI = Uri
2 
3            .parse("content://com.paad.provider.Earthquake/earthquakes");
4 
5 Content Provider 的URI 是在AndroidManifest.xml 中声明的,如下:
6 
7 <!-- 注册ContentProvider -->
8 
9        <provider android:name=".earthquake.EarthquakeProvider" android:authorities="com.paad.provider.Earthquake" />

可见,authorities是一个标识,是我们自定义的,大多Content Providers都定义一个CONTENT_URI属性值存储对应xml中声明的authorities ,这样方便我们随时取用

 

通常 Content Providers 展现两种形式的URI入口,一个对应查询所有的请求,另一个对应查询单条记录

查询所有记录的URI:

    content://com.paad.provider.Earthquake/earthquakes

查询单条记录的URI:

    content://com.paad.provider.Earthquake/earthquakes/#

创建Content Providers 步骤

继承ContentProvider

    重写onCreateupdatequeryinsertdeletegetType回调方法,当应用程序用ContentResolver.insert()等操作时,此处的函数被调用

定义public static final Uri  CONTENT_URI属性,此变量代表你的ContentProvider能够处理的 URI ,必须是唯一的,(实际是引用AndroidManifest.xml中的定义),

   

1 public staticfinal Uri CONTENT_URI = Uri
2 
3        .parse("content://com.paad.provider.Earthquake/earthquakes");

构建数据存储系统,我们可以使用文件存储或是SQLite数据库,或其他

    针对SQLite3,我们的步骤如下:

l         定义内部类earthquakeDatabaseHelper继承SQLiteOpenHelper,并重写onCreate(SQLiteDatabase db)     onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion)方法   earthquakeDatabaseHelper的作用是封装了创建数据库、更新数据库版本的操作

l         对于query(),我们在其内部依赖Cursor SQLiteQueryBuilder.query()发送查询,对于其他insert,update,delete我们直接借助SQLiteDatabase.insert等完成

l         Content ProvideronCreate()中,我们做如下初始化

       

1 Context context = getContext();
2 
3        earthquakeDatabaseHelper dbHelper;
4 
5        dbHelper = new earthquakeDatabaseHelper(context, DATABASE_NAME,        null,DATABASE_VERSION);
6 
7        earthquakeDB = dbHelper.getWritableDatabase();
8 
9        return (earthquakeDB == null? false : true;

定义我们的查询时所会用到的列名,一般我们会把数据库中表的所有列名都定义成常量,方便查询时Cursor提取值

   

// Column Names 表中列名
 
     
public static final String KEY_ID = "_id";
 
     
public static final String KEY_DATE = "date";
 
     
public static final String KEY_DETAILS = "details";
 
     
public static final String KEY_LOCATION_LAT = "latitude";//……

URI 数据请求来了,作为Content Provider的开发者你需要告诉Conent Provider 怎么判断URI想要哪种数据,这里需借助UriMatcher

   

private static final UriMatcher uriMatcher;

    
// Allocate the UriMatcher object, where a URI ending in ‘earthquakes’

    
// will correspond to a request for all earthquakes, and ‘earthquakes’

    
// with a trailing ‘/[rowID]’ will represent a single earthquake row.

    
static {

       uriMatcher 
= new UriMatcher(UriMatcher.NO_MATCH);

       
// 匹配查询所有com.paad.provider.Earthquake

       uriMatcher.addURI(
"com.paad.provider.Earthquake""earthquakes", QUAKES);

       
// 匹配查询单个

       uriMatcher.addURI(
"com.paad.provider.Earthquake""earthquakes/#",QUAKE_ID);

    }

这个变量Content Provider getType()中会使用进行URI匹配


只有注册用户登录后才能发表评论。


网站导航: