《第一行代码--Android》读书笔记之内容提供器

原创 2015年11月21日 10:19:01

内容提供器(Content Provider)主要用于在不同的应用程序之间实现数据的共享功能,是android的四大组件之一。内容提供器的用法一般有两种,一种是使用向右的内容提供器来读取和操作相应程序中的数据;另一种是创建自己的内容提供其给自己程序要共享出去的数据提供外部访问接口。

  • 访问其他应用程序中的数据
    • 通过Context中的getContentResolver()方法得到ContentResolver对象。Resolver意思是分解器,溶剂,把内容提供器提供的一块数据分析溶解,呵呵,我的理解。ContentResolver提供了一系列对数据进行CRUD操作。
    • URI给内容提供器中的数据建立了唯一的标识符,需要作为传入CRUD的操作方法里。URI由两部分组成,”content://权限+路径”。权限是”包名.provide”。如果有子表,在provider后面加上”/table”。
      Public static final Uri CONTENT_URI = Uri.parse(“content://com.WangWeiDa.MyContentProvider/users”);
    • 调用具体的CRUD操作方法就可以了。
Cursor cursor=null;
        try {
            cursor=getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,null,null,null,null);
            while(cursor.moveToNext()){
                String name=cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
                String number=cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
                contactList.add(name+"\n"+number);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(cursor!=null)
                cursor.close();
        }
  • 创建自己的内容提供器
    • 自定义一个provider类继承自ContentProvider。重写实现ContentProvider的所有方法(query、insert、update、delete、getType、onCreate);
    • URI格式主要有两种,以路径结尾就表示期望访问该表的中的所有数据;以id结尾就表示期望访问该表中拥有相应id的数据。我们可以利用UriMatcher对象的addURI()和match()来匹配URI。
    • 在getType()方法中返回Uri对象对应的MIME类型。MIME格式
      1、以vnd开头
      2、如果uri以路径结尾,则后接android.cursor.dir/;如果以id结尾,则后接android.cursor.item/。
      3、最后接上vnd.< authority>.< path>。
      “vnd.android.cursor.dir/vnd.com.example.databasetest.provider.book”;
    • android中四大组件都是要在AndroidManifest中注册,ContentProvider也不例外。需要在android:name属性中制定该自定义Provider类的全名,在android:authroities属性中指定该内容提供器权限。另外,我实践过这样写还是不能让外部程序访问到我们的ContentProvider,还需要添加android:exported=”true”才行,书上并没有加这一属性,不知为何、、、
<provider
            android:authorities="com.example.tlh.databasetest.provider"
            android:name="com.example.tlh.databasetest.MyProvider"
            android:exported = "true">
        </provider>
public class MyProvider extends ContentProvider {
    private MyDatabaseHelper dbHelper;
    public static final int TABLE1_DIR=0;
    public static final int TABLE1_ITEM=1;
    public static final int TABLE2_DIR=2;
    public static final int TABLE2_ITEM=3;
    public static final String AUTHORITY="com.example.tlh.databasetest.provider";
    private static UriMatcher uriMatcher;
    static {
        uriMatcher=new UriMatcher(UriMatcher.NO_MATCH);
        uriMatcher.addURI(AUTHORITY,"book",TABLE1_DIR);
        uriMatcher.addURI(AUTHORITY,"book/#",TABLE1_ITEM);
        uriMatcher.addURI(AUTHORITY,"category",TABLE2_DIR);
        uriMatcher.addURI(AUTHORITY,"category/#",TABLE2_ITEM);
        //当后面调用uriMatcher.match()时返回相应自定义常量。
    }
    @Override
    public boolean onCreate() {//当且仅当有外部程序的ContentResolver尝试访问我们的程序数据时,初始化内容提供器,会调用此方法,若成功则return true.
    //得到数据库帮助类实例便于以后调用数据库的CURD操作方法。
        dbHelper=new MyDatabaseHelper(getContext(),"BookStore.db");
        return true;
    }

    @Nullable
    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        SQLiteDatabase db=dbHelper.getWritableDatabase();
        Cursor cursor=null;
        switch (uriMatcher.match(uri)){
            case TABLE1_DIR:
                cursor=db.query("Book",projection,null,null,null,null,sortOrder);
                break;
            case TABLE1_ITEM:
                String bookID=uri.getPathSegments().get(1);
                cursor=db.query("Book",projection,"id=?",new String[]{"bookID"},null,null,sortOrder);
                break;
            case TABLE2_DIR:
                cursor=db.query("Category",projection,null,null,null,null,sortOrder);
                break;
            case TABLE2_ITEM:
                String categoryID=uri.getPathSegments().get(1);
                cursor=db.query("Category",projection,"id=?",new String[]{"categoryID"},null,null,sortOrder);
                break;
        }
        return cursor;
    }

    @Nullable
    @Override
    public String getType(Uri uri) {//调用ContentResolver的CURD方法传递过来的URI参数
        switch (uriMatcher.match(uri)){
            case TABLE1_DIR:
                return "vnd.android.cursor.dir/vnd.com.example.databasetest.provider.book";
            case TABLE1_ITEM:
                return "vnd.android.cursor.item/vnd.com.example.databasetest.provider.book";
            case TABLE2_DIR:
                return "vnd.android.cursor.dir/vnd.com.example.databasetest.provider.category";
            case TABLE2_ITEM:
                return "vnd.android.cursor.item/vnd.com.example.databasetest.provider.category";
        }
        return null;
    }

    @Nullable
    @Override
    public Uri insert(Uri uri, ContentValues values) {
        SQLiteDatabase db=dbHelper.getWritableDatabase();
        Uri uriReturn=null;
        switch(uriMatcher.match(uri)){
            case TABLE1_DIR:
            case TABLE1_ITEM:
                Long bookID=db.insert("Book",null,values);
                uriReturn=Uri.parse("content://"+AUTHORITY+"/Book/"+bookID);
                break;
            case TABLE2_DIR:
            case TABLE2_ITEM:
                Long categoryID=db.insert("Category",null,values);
                uriReturn=Uri.parse("content://"+AUTHORITY+"/Category/"+categoryID);
                break;
        }
        return uriReturn;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        SQLiteDatabase db=dbHelper.getWritableDatabase();
        int deleteLine=0;
        switch (uriMatcher.match(uri)){
            case TABLE1_DIR:
                deleteLine=db.delete("Book",selection,selectionArgs);
                break;
            case TABLE1_ITEM:
                String bookID=uri.getPathSegments().get(1);
                deleteLine=db.delete("Book","id=?",new String[]{bookID});
                break;
            case TABLE2_DIR:
                deleteLine=db.delete("Category",selection,selectionArgs);
                break;
            case TABLE2_ITEM:
                String categoryID=uri.getPathSegments().get(1);
                deleteLine=db.delete("Category","id=?",new String[]{categoryID});
                break;
        }
        return deleteLine;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        SQLiteDatabase db=dbHelper.getWritableDatabase();
        int updateLine=0;
        switch (uriMatcher.match(uri)){
            case TABLE1_DIR:
                updateLine=db.update("Book",values,selection,selectionArgs);
                break;
            case TABLE1_ITEM:
                String bookID=uri.getPathSegments().get(1);
                updateLine=db.delete("Book","id=?",new String[]{bookID});
                break;
            case TABLE2_DIR:
                updateLine=db.delete("Category",selection,selectionArgs);
                break;
            case TABLE2_ITEM:
                String categoryID=uri.getPathSegments().get(1);
                updateLine=db.delete("Category","id=?",new String[]{categoryID});
                break;
        }
        return updateLine;
    }
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

第一行代码-7.3 创建自己的内容提供器

之前我们为了实现SQLite的功能,需要创建自己的DatabaseHelper类,现在我们也可以定义自己的ContentProvider来实现跨应用访问数据。但是六个方法都要重写。   由于整个My...

内容提供器(ContentResolver)---《第一行代码Android》笔记

作用 基本用法 内容URI CRUD操作 创建自己的内容提供器 作用1,使用现有的内容提供器读取或操作相应程序中的数据,比如电话薄、相册等 2,为我们的程序数据提供外部访问接口基本用法Content...
  • zlxtk
  • zlxtk
  • 2017年07月07日 18:24
  • 67

阅读郭林《第一行代码》的笔记——第7章 跨程序共享数据,探究内容提供器

内容提供器简介内容提供器(Content Provider)主要用于在不同的应用程序之间实现数据共享的功能,它提供了一套完整的机制,允许一个程序访问另一个程序中的数据,同时还能保证被访数据的安全性。目...

第一行代码 第7章 内容提供器 -- 运行时权限

Android运行时权限: 由android 6.0系统上引入了这个功能 , 允许用户在安装软件时不需要一次性授权所有的申请权限,而是可以在运行时对某一项权限申请进行授权。Android将权限分为两...

《第一行代码--Android》读书笔记之网络编程

浅用WebView 简单配置布局 具体代码 public class MainActivity
  • TellH
  • TellH
  • 2015年11月23日 09:52
  • 790

第一行代码Android第二章读书笔记

第一行代码Android第二章读书笔记 Activity 1.1 手动创建活动 1.2 Toast和Menu/销毁活动 Intent 2.1 显示/隐式 2.2 传递/返回数据 活动的生命周期...

《第一行代码--Android》读书笔记之碎片

碎片的基本用法: 碎片(fragment)是能嵌在活动中的UI片段,相当于mini型的Activity,有完整的布局,和生命周期。一个简单的碎片的创建过程: 新建一个碎片布局,比如,fragme...
  • TellH
  • TellH
  • 2015年11月19日 13:12
  • 892

《第一行代码Android》读书笔记

startActivityForResult()对应onActivityResult() back键会销毁Activity,相当于调用了finish()方法,可以重写onBackPressed()...
  • chinben
  • chinben
  • 2014年10月31日 15:23
  • 891

《第一行代码--Android》读书笔记之广播机制

广播的类型 标准广播(Normal Broadcasts)是完全异步执行的广播,在广播发出后,几乎所有的广播接受器都同一时间接收到这条广播消息,放射性传播的消息。 有序广播(Ordered Broad...
  • TellH
  • TellH
  • 2015年11月19日 17:35
  • 622

《第一行代码--Android》读书笔记之UI篇

比较难掌握的UI控件ProgressBar XML属性: android:progressBarStyle:默认进度条样式 android:progressBarStyleHorizontal:水...
  • TellH
  • TellH
  • 2015年11月18日 15:06
  • 475
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:《第一行代码--Android》读书笔记之内容提供器
举报原因:
原因补充:

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