Android之ContentProvider(数据共享)

Android应用四大组件之一

为了在应用程序之间交换数据,Android提供了ContentProvider,它是不同应用程序之间进行数据交换的标准API,ContentProvider以某种Uri的形式对外提供数据,让其他应用程序使用ContentResolver根据Uri去访问操作数据

那么如何完整开发一个ContentProvider呢?

  • 首先定义自己的ContentProvider类,该类继承Android的ContentProvider基类
  • 然后在项目的AndroidMainfest.xml中注册ContentProvider,同时还需为他绑定一个Uri

  "false"  
  android:authorities="com.provider.Simple"  
  android:name="SimpleProvider">
  ".*"/>
  

   注册了SimpleProvider之后,就要知道SimpleProvider如何暴露它的数据。我们知道数据的操作无非就是增删改查等几个操作,因此SimpleProvider除了继承之外,还应该提供以下的的方法

  • public boolean onCreate() :在创建ContentProvider时调用
    ,当其他程序第一次调用时就会被创建出来
  • public Cursor query(Uri, String[], String, String[], String) 用于查询指定Uri的ContentProvider,返回一个Cursor
  • public Uri insert(Uri, ContentValues) 用于添加数据到指定Uri的ContentProvider中
  • public int update(Uri, ContentValues, String, String[]) 用于更新指定Uri的ContentProvider中的数据
  • public int delete(Uri, String, String[]) 用于从指定Uri的ContentProvider中删除数据
  • public String getType(Uri) 用于返回指定的Uri中的数据E类型

    •  MIME类型字符串以vnd.android.cursor.dir/开头时该Uri的数据可能包含多条
    • 以vnd.android.cursor.item/开头时,处理的数据为一条
    • vnd.< name >.< type >中的name具有表中唯一性

    这些操作与数据库的操作基本上完全一样,在此不详细说,需要特殊说明的地方是URI:
        在URI的D部分可能包含一个_ID ,这个应该出现在SQL语句中的,可以以种特殊的方式出现,这就要求我们在提供数据的时候,需要来额外关注这个特殊的信息。Android SDK推荐的方法是:在提供数据表字段中包含一个ID,在创建表时INTEGER PRIMARY KEY AUTOINCREMENID字段

ContentProvider 是如何组织数据的?

       组织数据主要包括:存储数据,读取数据,以数据库的方式暴露数据。数据的存储需要根据设计的需求,选择合适的存储结构,首选数据库,当然也可以选择本地其他文件,甚至可以是网络上的数据。数据的读取,以数据库的方式暴露数据这就要求,无论数据是如何存储的,数据最后必须以数据的方式访问。
       Android是如何实现应用程序之间数据共享的?我们以前谈到外界的程序可以通过ContentResolver接口访问ContentProvider提供的数据,今天我们来谈下如何创建自己的ContentProvider来实现应用程序之间的数据共享
       Android中的电话本等数据就是通过ContentProvider实现数据共享的,系统中有很多已经存在的共享Uri。我们可以使用ContentResolver通过Uri来操作不同表的数据;如Contacts.People.CONTENT_URI。
       查询Content Provider的方法有两个:ContentResolver的query() 和 Activity 对象的 managedQuery(),二者接收的参数均相同,返回的都是Cursor 对象,唯一不同的是 使用managedQuery 方法可以让Activity 来管理 Cursor 的生命周期。
        被管理的Cursor 会在 Activity进入暂停状态的时候调用自己的 deactivate 方法自行卸载,而在Activity回到运行状态时会调用自己的requery 方法重新查询生成的Cursor对象。如果一个未被管理的Cursor对象想被Activity管理,可以调用Activity的 startManagingCursor方法来实现。

ContentProvider 什么是URI?

    content ://com.android.provider/student

将其分为3个部分:

  • “conte://”:标准前缀,用来说明一个Content Provider控制这些数据,无的
  • com.android.provider:URI的标识,它定义了是哪个Content Provid提供这些数 据。对于第三方应用程序,为了保证URI标识的唯一性,它必须是一个完整的、小写的类名。是contentProvider的authorities,系统根据该部分找到操作哪个contentProvider称 ;”content://com.android.calendar” (系统日历的URI)
  • student:路径,URI下的某一个Item,就像网站一样,主网页下包含很多小网页。这里通俗的讲就是你要操作的数据库中表的名字,或者你也可以自己定义,记得在使用的时候保致就ok了
    •  “content://com.android.provider/student/#”  
        -  #表示数任意数字的数字字符组成
    • “content://com.android.provider/*”
        - *来匹配任意文本

UriMatcher:用于匹配Uri,它的用法如下:

  • 首先把你需要匹配Uri路径全部给注册上。
  • 常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码(-1)。

UriMautcher   riMatcher = new UriMatcher(UriMatcher.NO_MATCH);
  • 如果match()方法匹content://com.android.calendar/calendars路径,返回匹配O_MATCH);

  uriMatcher.addURI(“content://com.android.calendar”, “calendars”, 1);
  • 添加需要匹配uri,如果匹配就会返回匹配码,如果match()方法匹配 content://com.android.calendar/calendars/23路径,返回匹配码为2 uriMatcher.addURIiMatcher.addURI
  • 注册完需要匹配的Uri后,就可以使用uriMatcher.match(uri)方法对输入的Uri进行匹配,如果匹 配就返回匹配码,匹配码是调用 addURI()方法传入的第三个参数,假设匹配content://com. android.calendar/calendars路径,返回的匹配码为1。

      ContentUris:用于获取Uri路径后面的ID部分,它有两个比较实用的方法:
      withAppendedId(uri, id)用于为路径加上ID部分
      parseId(uri)方法用于从路径中获取ID部分
    以下是一个例子的简单说明:


 private static final String URI_AUTHORITY = "com.calendarwidget.provider";  
    public static final String URI_PATH2 = "RecordSet/#";//只是填充,没有作用  
    public static final Uri CONTENT_URI = Uri.parse("content://"  
    private static final UriMatcher sMatcher;  
    public static final int ALL_EVENT_RECORDS = 0;  
        sMatcher = new UriMatcher(UriMatcher.NO_MATCH);  
        sMatcher.addURI(URI_AUTHORITY, URI_PATH, ALL_EVENT_RECORDS);  
        sMatcher.addURI(URI_AUTHORITY, URI_PATH2, ALL_EVENT_RECORDS);  
    public boolean onCreate()  
        if (mContext == null)  
            mContext = getContext();  
    }  
    @Override  
    public Cursor query(Uri uri, String[] projection, String selection,  
        //匹配码  
                int match = sMatcher.match(uri);  
        switch (match)  
            case ALL_EVENT_RECORDS:  
                cur = loadAllCalendarEvent(this);  
            default:  
break;  
return cur;  
private MatrixCursor loadAllCalendarEvent(CalendarProvider calendarProvider)  
MatrixCursor mc = new MatrixCursor(CalendarConstants.PROJECTION);  
calendarCursor = calendarProvider  
.getContentResolver().query("content://com.android.calendar/calendars",  
while (calendarCursor.moveToNext())  
//TODO  
.....  
 
mc.addRow(rowObject);  
} finally  
calendarCursor.close();  
@Override  
public String getType(Uri uri)  
 
}  
 
@Override  
 
public Uri insert(Uri uri, ContentValues values)  
 
@Override  
 
public int delete(Uri uri, String selection, String[] selectionArgs)  
 
public int update(Uri uri, ContentValues values, String selection,  
 
} 
 
} 
public class CalendarProvider extends ContentProvider
public static final String URI_PATH = "RecordSet"; //只是填充,没有作用  

{  
}  
private Context mContext;  
{  
}  
String[] selectionArgs, String sortOrder)  
break;  
}  
{  
Cursor calendarCursor = null;  
 .getContext()  
 null, null,   
null, null); /  
}  
return mc;  
}  
{  
return null;  
return null;  
{  
}  
@Override  
String[] selectionArgs)  
return 0;  

你可能感兴趣的:(Android之ContentProvider(数据共享))