Android組件之自訂ContentProvider

來源:互聯網
上載者:User

標籤:android   style   blog   http   io   ar   os   使用   java   

Android的資料存放區有五種方式Shared Preferences、網路儲存、檔案儲存體、外儲儲存、SQLite,一般這些儲存都只是在單獨的一個應用程式之中達到一個資料的共用,有時候我們需要操作其他應用程式的一些資料,例如常見系統裡的通訊錄,簡訊,照片等等,所以雲端儲存,通訊錄,豔照門等等就孕育而生了。ContentProvider可以理解成內容提供者,也可以理解為一個介面,就是提供了一個供外部存取的介面,有的時候需要進行許可權控制。

ContentProvider簡介

ContentProvider向我們提供了我們在應用程式之前共用資料的一種機制,而我們知道每一個應用程式都是運行在不同的應用程式的,不同程式的之間資料共用是現實的需要,程式總不能使閉環的,Android中的ContentProvider外共用資料的好處是統一了資料的訪問方式。簡單總結說下:

  1. ContentProvider為儲存和擷取資料提供了統一的介面。ContentProvide對資料進行封裝,不用關心資料存放區的細節。使用表的形式來組織資料。
  2. 使用ContentProvider可以在不同的應用程式之間共用資料。 
  3. Android為常見的一些資料提供了預設的ContentProvider(包括音頻、視頻、圖片和通訊錄等)。 

說到了ContentProvider這麼多好處,不能不說下Uri(Universal Resource Identifier)注意不是URL,通用資源標識符,看個簡單的讀取連絡人的Uri,content://contacts/people,

  1. content://是首碼,固定的;
  2. contacts 主機名稱(或叫Authority)用於唯一標識這個ContentProvider,外部調用者可以根據這個標識來調用;
  3. people  路徑(path)表示我們要操作的資料,路徑的構建根據業務而定;
自訂ContentProvider

俗話說,欲善其事必先利其器,想要成為一個內容提供者,就先需要有資料,先建立一個SqlDbConncetion:

public class SqlDBConnection extends SQLiteOpenHelper {private static final String DbName ="Book.db";private static int version=1;public SqlDBConnection(Context context) {super(context, DbName, null, version);}@Overridepublic void onCreate(SQLiteDatabase db) {// TODO Auto-generated method stub String sqlString="create table Book (id integer primary key autoincrement,Name nvarchar(200),Title nvarchar(200))"; db.execSQL(sqlString);}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {// TODO Auto-generated method stub}}

  上篇文章講的junit測試這個時候可以拿過來使用一下初始化下資料:

public class BookCase extends AndroidTestCase {public void Intial() {SqlDBConnection dbConnection = new SqlDBConnection(getContext());SQLiteDatabase sqlDataBase = dbConnection.getWritableDatabase();long row = 0;for (int i = 0; i < 5; i++) {ContentValues values = new ContentValues();values.put("Name", "書籍"+i);values.put("Title", "標題" + i);row = sqlDataBase.insert("Book", null, values);Log.i("BookCase", "插入成功:" + row);}}}

 前面是基礎工作,這個時候就可以建立一個自己的ContentProvider:

public class MyContentProvider extends ContentProvider {private static final String AUTHORITY = "com.example.googlecontentprovider.MyContentProvider";private static final int CONTENT_INSERT = 0;private static final int CONTENT_QUERY = 1;private static final int CONTENT_DELETE = 2;private static final int CONTENT_UPDATE = 3;private static final int CONTENT_QUERY_SINGLE = 4;private static UriMatcher uriMatcher;private SqlDBConnection dbConnection = null;static {uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);uriMatcher.addURI(AUTHORITY, "book/insert", CONTENT_INSERT);uriMatcher.addURI(AUTHORITY, "book/query", CONTENT_QUERY);uriMatcher.addURI(AUTHORITY, "book/delete", CONTENT_DELETE);uriMatcher.addURI(AUTHORITY, "book/update", CONTENT_UPDATE);uriMatcher.addURI(AUTHORITY, "book/query/#", CONTENT_QUERY_SINGLE);}@Overridepublic boolean onCreate() {dbConnection = new SqlDBConnection(getContext());return true;}@Overridepublic Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder) {SQLiteDatabase dbDatabase = dbConnection.getWritableDatabase();switch (uriMatcher.match(uri)) {case CONTENT_QUERY:if (dbDatabase.isOpen()) {Cursor cursor=dbDatabase.query("Book", projection, selection, selectionArgs, null, null, null);return cursor;}break;case CONTENT_QUERY_SINGLE:if (dbDatabase.isOpen()) {long id=ContentUris.parseId(uri);Cursor cursor=dbDatabase.query("Book", projection, "id=?", new String[]{id+""}, null, null, null);return cursor;}break;default:break;}return null;}@Overridepublic String getType(Uri uri) {// TODO Auto-generated method stubreturn null;}@Overridepublic Uri insert(Uri uri, ContentValues values) {SQLiteDatabase dbDatabase = dbConnection.getWritableDatabase();switch (uriMatcher.match(uri)) {case CONTENT_INSERT:if (dbDatabase.isOpen()) {long id = dbDatabase.insert("Book", null, values);dbDatabase.close();return ContentUris.withAppendedId(uri, id);}break;default:break;}return null;}@Overridepublic int delete(Uri uri, String selection, String[] selectionArgs) {// TODO Auto-generated method stubSQLiteDatabase dbDatabase = dbConnection.getWritableDatabase();switch (uriMatcher.match(uri)) {case CONTENT_DELETE:if (dbDatabase.isOpen()) {int count= dbDatabase.delete("Book", selection, selectionArgs);dbDatabase.close();return count;}break;default:break;}return 0;}@Overridepublic int update(Uri uri, ContentValues values, String selection,String[] selectionArgs) {SQLiteDatabase dbDatabase = dbConnection.getWritableDatabase();switch (uriMatcher.match(uri)) {case CONTENT_UPDATE:if (dbDatabase.isOpen()) {int count= dbDatabase.update("Book", values, selection, selectionArgs);dbDatabase.close();return count;}break;default:break;}return 0;}}

 主機名稱是需要自己去AndroidManifest.xml檔案中自己配置的,要求是唯一的,最好是用包名就好:

   <provider android:name="com.example.googlecontentprovider.MyContentProvider"            android:authorities="com.example.googlecontentprovider.MyContentProvider"></provider>

  如果覺得上面的那一串代碼不是很好理解,下面調用的時候我會分別解釋。

ContentResolver的使用

方法寫在一個應用程式中調用屬於正常,在另外一個程式中調用該程式的方法就是類似於介面了,下面先看原來初始化的資料:

重新建立一個Android測試專案,定義為BookCase,首先插入資料,定義一個Uri,這裡面主機名稱就是上面定義的包名,book/insert與CONTENT_INSERT是對應的:

public void bookInsert() {Uri uri = Uri.parse("content://com.example.googlecontentprovider.MyContentProvider/book/insert");ContentResolver resolver = getContext().getContentResolver();ContentValues values = new ContentValues();values.put("Name", "書籍5");values.put("Title", "標題5");uri = resolver.insert(uri, values);Log.i("BookCase", "Uri" + uri);long id = ContentUris.parseId(uri);Log.i("BookCase", "測試成功" + id);}

  顯示結果如下:

然後更新剛才插入的資料,同樣的更具Code給Uri賦值,然後初始化一個ContentResolver,調用update方法:

public void bookUpdate() {Uri uri = Uri.parse("content://com.example.googlecontentprovider.MyContentProvider/book/update");ContentResolver resolver = getContext().getContentResolver();ContentValues values=new ContentValues();values.put("Name", "修改");int count = resolver.update(uri, values, " id=?",new String[]{"10"});Log.i("BookCase", "更新了" + count + "行");}

  結果如下:

刪除插入的資料:

public void bookDelete() {Uri uri = Uri.parse("content://com.example.googlecontentprovider.MyContentProvider/book/delete");ContentResolver resolver = getContext().getContentResolver();String where =" id=?";String[] argString = {"10"};int count = resolver.delete(uri, where, argString);Log.i("BookCase", "刪除了" + count + "行");}

結果如下:

查詢所有的資料:

public void bookQuery() {Uri uri = Uri.parse("content://com.example.googlecontentprovider.MyContentProvider/book/query");ContentResolver resolver = getContext().getContentResolver();Cursor  cursor=resolver.query(uri, new String[]{"id","Name","Title"}, null, null, null);if (cursor.getCount()>0) {while (cursor.moveToNext()) {int id=cursor.getInt(cursor.getColumnIndex("Id"));String nameString=cursor.getString(cursor.getColumnIndex("Name"));String titleString=cursor.getString(cursor.getColumnIndex("Title"));Log.i("BookCase", id+"---"+nameString+"---"+titleString);}}}

  Log下的記錄:

查詢單條記錄:

public void bookQuerySingle() {Uri uri = Uri.parse("content://com.example.googlecontentprovider.MyContentProvider/book/query");ContentResolver resolver = getContext().getContentResolver();uri=ContentUris.withAppendedId(uri,1);Cursor  cursor=resolver.query(uri, new String[]{"id","Name","Title"}, null, null, null);if (cursor.getCount()>0) {while (cursor.moveToNext()) {int id=cursor.getInt(cursor.getColumnIndex("Id"));String nameString=cursor.getString(cursor.getColumnIndex("Name"));String titleString=cursor.getString(cursor.getColumnIndex("Title"));Log.i("BookCase", id+"---"+nameString+"---"+titleString);}}}

 結果:

至此一個自訂ContentProvider全部搞定,如有不當,請各位多多指教~

Android組件之自訂ContentProvider

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.