zoukankan      html  css  js  c++  java
  • ContentProvider的使用

      为了在应用程序之间交换数据,Android提供了ContentProvider,ContentProvider是不同应用程序之间进行数据交换的标准API,当一个应用程序需要把自己的数据暴露给其他应用程序时,该应用程序就可通过提供Contentprovider来实现;其他应用程序就可通过ContentResolver来操作ContentProvider暴露的数据。

      ContentProvider是以某种Uri的形式对外提供数据,允许其他应用访问或修改数据;其他应用程序使用ContentResolver根据Uri去访问操作指定数据。使用ContentProvider的步骤如下(假设B应用程序要使用A应用程序中的数据):

    1、在A应用程序中的AndroidManifest.xml文件里的application节点里添加以下代码:

    1 <provider
    2             android:name="com.gnnuit.provider.PersonProvider"
    3             android:authorities="com.gnnuit.provider.PersonProvider" >
    4 </provider>

      其中,android:name是自己编写的provider类的全名;android:authorities是外界访问的名字,就相当于为该ContentProvider指定域名。

    2、在A应用程序里新建一个PersonProvider类使其继承ContentProvider基类。

      为了确定ContentProvider实际能处理的Uri,以及确定每个方法中Uri参数所操作的数据,Android系统提供了UriMatcher工具类。UriMatcher工具类主要提供了以下两个方法:

    (1)void arrURI(String authority,String path,int code):该方法用于向UriMatcher对象注册Uri。其中authority和path组合成一个Uri,而code则代表Uri对应的标识码。

    (2)int match(Uri uri):根据前面注册的Uri来判断指定Uri对应的标识码。如果找不到匹配的标识码,该方法将会返回-1。源码如下:

      1 package com.gnnuit.provider;
      2 
      3 import com.gnnuit.dao.PersonDao;
      4 import com.gnnuit.db.MyDbHelper;
      5 
      6 import android.content.ContentProvider;
      7 import android.content.ContentValues;
      8 import android.content.UriMatcher;
      9 import android.database.Cursor;
     10 import android.database.sqlite.SQLiteDatabase;
     11 import android.net.Uri;
     12 import android.util.Log;
     13 
     14 public class PersonProvider extends ContentProvider {
     15     private static final int ALL_PERSONS = 1;
     16     private static final int PERSON = 2;
     17     private static final int HAHA = 3;
     18     private static final int INSERT = 4;
     19     private static final int DELETE = 5;
     20     private static final int UPDATE = 6;
     21     private static final String TAG = "PersonProvider";
     22     private MyDbHelper dbHelper;
     23     // 创建了一个路径的识别器 uriMatcher 默认的返回值,如果没有找到匹配的类型 返回 -1;
     24     private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
     25     static {
     26         // 指定一个路径的匹配规则
     27         // 如果路径 满足 content://com.gnnuit.provider.PersonProvider/persons 返回值就是(
     28         // ALL_PERSONS) 1
     29         matcher.addURI("com.gnnuit.provider.PersonProvider", "persons",
     30                 ALL_PERSONS);
     31         // 如果路径 满足 content://com.gnnuit.provider.PersonProvider/person/10 返回值就是(
     32         // PERSON) 2
     33         matcher.addURI("com.gnnuit.provider.PersonProvider", "person/#", PERSON);
     34         matcher.addURI("com.gnnuit.provider.PersonProvider", "haha", HAHA);
     35         matcher.addURI("com.gnnuit.provider.PersonProvider", "insert", INSERT);
     36         matcher.addURI("com.gnnuit.provider.PersonProvider", "delete", DELETE);
     37         matcher.addURI("com.gnnuit.provider.PersonProvider", "update", UPDATE);
     38     }
     39 
     40     /**
     41      * PeronProvder 内容提供者第一次被创建的时候 调用的方法
     42      */
     43     @Override
     44     public boolean onCreate() {
     45         dbHelper = new MyDbHelper(getContext());
     46         return false;
     47     }
     48 
     49     @Override
     50     public Cursor query(Uri uri, String[] projection, String selection,
     51             String[] selectionArgs, String sortOrder) {
     52         int result = matcher.match(uri);
     53         switch (result) {
     54         case ALL_PERSONS:
     55             PersonDao dao = new PersonDao(getContext());
     56             return dao.getAllByCursor();
     57         case PERSON:
     58             SQLiteDatabase db = dbHelper.getReadableDatabase();
     59             if (db.isOpen()) {
     60                 Cursor cursor = db.query("person", projection, selection,
     61                         selectionArgs, null, null, null);
     62                 return cursor;
     63             }
     64         case HAHA:
     65             Log.i(TAG, "我是哈哈");
     66             return null;
     67         default:
     68             throw new IllegalArgumentException("URI不合法");
     69         }
     70     }
     71 
     72     /**
     73      * 有的时候 我们需要知道内容提供者返回的数据类型 知道返回的数据 是一个集合呀 还是一个单独的条目
     74      * 
     75      * 有的时候 告诉调用者 返回的数据是什么样的类型 MIME的数据类型
     76      */
     77     @Override
     78     public String getType(Uri uri) {
     79         int result = matcher.match(uri);
     80         switch (result) {
     81         // 符合 content://com.gnnuit.provider.PersonProvider/persons 代表的返回所有的数据
     82         case ALL_PERSONS:
     83             return "vnd.android.cursor.dir/people";
     84             // content://com.gnnuit.provider.PersonProvider/person/10
     85         case PERSON:
     86             return "vnd.android.cursor.item/people";
     87         default:
     88             return null;
     89         }
     90     }
     91 
     92     @Override
     93     public Uri insert(Uri uri, ContentValues values) {
     94         int result = matcher.match(uri);
     95         if (result == INSERT) {
     96             SQLiteDatabase db = dbHelper.getWritableDatabase();
     97             db.insert("person", null, values);
     98             // 当数据发生改变的时候
     99             getContext().getContentResolver().notifyChange(uri, null);
    100             return uri;
    101         } else {
    102             throw new IllegalArgumentException("URI不能被识别");
    103         }
    104     }
    105 
    106     @Override
    107     public int delete(Uri uri, String selection, String[] selectionArgs) {
    108         int result = matcher.match(uri);
    109         if (result == DELETE) {
    110             SQLiteDatabase db = dbHelper.getWritableDatabase();
    111             // 当数据发生改变的时候
    112             getContext().getContentResolver().notifyChange(uri, null);
    113             return db.delete("person", selection, selectionArgs);
    114         } else {
    115             throw new IllegalArgumentException("URI不能被识别");
    116         }
    117     }
    118 
    119     @Override
    120     public int update(Uri uri, ContentValues values, String selection,
    121             String[] selectionArgs) {
    122         int result = matcher.match(uri);
    123         if (result == UPDATE) {
    124             SQLiteDatabase db = dbHelper.getWritableDatabase();
    125             // 当数据发生改变的时候
    126             getContext().getContentResolver().notifyChange(uri, null);
    127             return db.update("person", values, selection, selectionArgs);
    128         } else {
    129             throw new IllegalArgumentException("URI不能被识别");
    130         }
    131     }
    132 
    133 }

      public String getType(Uri uri):该方法用于返回当前Uri所代表的MIME类型。如果该Uri对应数据可能包括多条记录,那么MIME类型字符串应该以vnd.android.cursor.dir/开头;如果该Uri对应的数据只包含一条记录,那么返回MIME类型字符串应该以vnd.android.cursor.item/开头。

    3、在B应用程序中使用,首先我们要得到一个ContentResolver对象,Context提供了getContentResolver()方法来获取ContentResolver对象。源码如下:

     1 package com.gnnuit.other;
     2 
     3 import android.net.Uri;
     4 import android.os.Bundle;
     5 import android.app.Activity;
     6 import android.content.ContentResolver;
     7 import android.database.Cursor;
     8 import android.view.Menu;
     9 
    10 public class MainActivity extends Activity {
    11 
    12     @Override
    13     protected void onCreate(Bundle savedInstanceState) {
    14         super.onCreate(savedInstanceState);
    15         setContentView(R.layout.activity_main);
    16         ContentResolver resolver = getContentResolver();
    17         Uri uri = Uri.parse("content://com.gnnuit.provider.PersonProvider/persons");
    18         Cursor cursor = resolver.query(uri, null, null, null, null);
    19         if (cursor != null) {
    20             while (cursor.moveToNext()) {
    21                 String name = cursor.getString(cursor.getColumnIndex("name"));
    22                 String age = cursor.getString(cursor.getColumnIndex("age"));
    23                 System.out.println("姓名:" + name + "年命:" + age);
    24             }
    25         } else {
    26             System.out.println("cursor为空");
    27         }
    28     }
    29 
    30     @Override
    31     public boolean onCreateOptionsMenu(Menu menu) {
    32         // Inflate the menu; this adds items to the action bar if it is present.
    33         getMenuInflater().inflate(R.menu.main, menu);
    34         return true;
    35     }
    36 
    37 }

     4、ContentProvider的Uri简介

      ContentProvider的Uri类似于HTTP的Uri,例如以下的Uri:

    content://com.gnnuit.provider.personprovider/persons

      它可以分为以下三个部分:

    (1)content://:这个部分是Android的ContentProvider规定的,就像http://一样。暴露ContentProvider、访问ContentProvider的协议默认是content://。

    (2)com.gnnuit.provider.personprovider:这个部分是ContentProvider的authority。系统就是由这个部分来找到操作哪个ContentProvider。只要访问指定的ContentProvider,这个部分总是固定的。

    (3)persons:资源部分,当访问者需要访问不同资源时,这个部分是动态改变的。

    5、几种典型的Uri含义:

    (1)content://com.gnnuit.provider.personprovider/persons

      此时它要访问的资源为persons,这意味着访问perosn数据中的所有记录。

    (2)content://com.gnnuit.provider.personprovider/person/2

      此时它要访问的资源为person/2,这意味着访问person数据中ID为2的记录。

    (3)content://com.gnnuit.provider.personprovider/person/2/name

      此时它要访问的资源为person/2/name,这意味着访问perosn数据中ID为2的记录的name字段。

    (4)大部分ContentProvider所操作的数据都来自于数据库,但有时这些数据也可来自于文件、XML或网络等其他存储方式,此时的Uri可改为如下形式:

    content://com.gnnuit.provider.personprovider/person/name/

      上面的Uri表示操作person节点下的name节点。

    6、将一个字符串转化成Uri的方法:

      Uri uri=Uri.parse("content://com.gnnuit.provider.personprovider/persons");

  • 相关阅读:
    hdu find the most comfortable road(贪心+并查集)
    hdu 迷瘴(贪心)
    Excel中指定的sheet名称或索引读取数据到DataTable
    SQLServer 批量插入数据的两种方法
    javascript基础教程3
    Enterprise Library 4.1学习笔记 配置应用程序块(c/s和b/s均适用)
    关于同一用户不能同时在两台电脑上登录问题的解决方案
    获取当天为一年中的第几周
    javascript基础教程4
    Excel导出方法选择(转自gwf25sz)
  • 原文地址:https://www.cnblogs.com/FlySheep/p/3452740.html
Copyright © 2011-2022 走看看