Android四大組件之Content Provider

來源:互聯網
上載者:User

標籤:sql   uri   android   content provider   getcontentresolver   

ContentProvider:內容提供者

1、為儲存和讀取資料提供了統一的介面

 2、使用ContentProvider,應用程式可以實現資料共用

 3、android內建的許多資料都是使用ContentProvider形式,供開發人員調用的(如視頻,音頻,圖片,通訊錄等)

 4、當應用繼承ContentProvider類,並重寫該類用於提供資料和儲存資料的方法,就可以向其他應用共用其資料。


先來瞭解一下Uri:

Uri,即通用資源標識符

1、Uri代表要操作的資料,Android上可用的每種資源 - 映像、視頻片段等都可以用Uri來表示

2、Uri一般由三部分組成:訪問資源的命名機制;存放資源的主機名稱; 資源自身的名稱,由路徑表示。

      Android的Uri由以下三部分組成: "content://"+資料的路徑+標示ID(可選)、

    如:所有連絡人的Uri: content://contacts/people

    某個連絡人的Uri: content://contacts/people/5    //連絡人中id為5的連絡人

3、如果要把一個字串轉換成Uri,可以使用Uri類中的parse()方法,如下:

Uri uri = Uri.parse("content://com.archer.ContentProvider")


ContentResolver:

在android中,每個應用程式是可以實現資料共用的,對於每一個應用程式程式都擁有一個ContentProvider執行個體進行儲存,

而ContentResolver則是用於管理所有程式的ContentProvider執行個體,通過ContentRescolver可以對資料進行添加、刪除、修改和查詢操作

通過getContentRescolver()擷取執行個體


下面通過建立一個Content Provider,並使用 SQLLite資料庫實現資料共用


首先,定義ContentProvider的CONTENT_URI,並且是public static final的Uri類型的類變數

必須為其制定一個唯一的字串值,一般用類的全名稱命名

package com.ContentProviderDemo.Archer;import android.net.Uri;import android.provider.BaseColumns;public class MyUsers {public static final String AUTHORITY = "com.archer.ContentProvider";//BaseColumn類中已經包含了 _id 欄位public static final class User implements BaseColumns{public static final Uri CONTENT_URI =Uri.parse("content://com.archer.ContentProvider");//表資料列public static final String USER_NAME = "USER_NAME";}}


之後建立一個類繼承ContentProvider

package com.ContentProviderDemo.Archer;import android.content.ContentProvider;import android.content.ContentUris;import android.content.ContentValues;import android.content.Context;import android.database.Cursor;import android.database.SQLException;import android.database.sqlite.SQLiteDatabase;import android.database.sqlite.SQLiteOpenHelper;import android.database.sqlite.SQLiteQueryBuilder;import android.net.Uri;public class MyContentProvider extends ContentProvider{/** * 定義一個SQLiteDatabase變數 * Android提供了一個名為SQLiteDatabase的類,它封裝了一些操作資料庫的API。 * 使用它能實現基本的CRUD(插入、查詢、更新、刪除)操作,通過getWritableDatabase()和getReadableDatabase()可以擷取資料庫執行個體 */private SQLiteDatabase sqlDB;private DatabaseHelper dbHelper;private static final String DATABASE_NAME = "Users.db"; //資料庫名private static final int DATABASE_VERSION = 1; //資料庫版本//表名private static final String TABLE_NAME = "User";//表名/** * 首先需要建立資料庫(定義一個內部類,繼承SQLiteOpenHelper類,重寫其方法) * SQliteOpenHelper是一個抽象類別,來管理資料庫的建立和版本的管理。 * 要使用它必須實現它的onCreate(SQLiteDatabase),onUpgrade(SQLiteDatabase, int, int)方法          * onCreate:當資料庫第一次被建立的時候被執行,例如建立表,初始化資料等。       * onUpgrade:當資料庫需要被更新的時候執行,例如刪除舊錶,建立新表。 * @author Administrator */private static class DatabaseHelper extends SQLiteOpenHelper{/*** 建立資料庫的構造方法* name 資料庫的名字* factory 查詢資料庫的遊標工廠一般情況下用sdk預設的* version 資料庫的版本一般大於0*/public DatabaseHelper(Context context){super(context,DATABASE_NAME,null,DATABASE_VERSION);}@Overridepublic void onCreate(SQLiteDatabase db) {String sq1 = "Create table " + TABLE_NAME + "( _id INTEGER PRIMARY KEY AUTOINCREMENT, USER_NAME TEXT);"; //建立表的sql語句db.execSQL(sq1); //建立表}/*** 更新資料的時候調用的方法,如新增表、修改資料*/@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {//增加一列db.execSQL("DROP TABLE IF EXISTS" + TABLE_NAME);onCreate(db);}}@Overridepublic int delete(Uri uri, String s, String[] arg2) {return 0;}@Overridepublic String getType(Uri arg0) {return null;}/** * 插入資料 * ContentValues類負責儲存一些名值對,的名是一個String類型,而值都是基本類型。 */@Overridepublic Uri insert(Uri uri, ContentValues contentValues) {//以讀寫方式開啟資料庫,一旦資料庫的磁碟空間滿了,資料庫就只能讀而不能寫,就會開啟失敗sqlDB = dbHelper.getWritableDatabase(); //插入一條新的紀錄,如果插入成功則會返回這條記錄的id,如果插入失敗會返回-1long rowId = sqlDB.insert(TABLE_NAME, "", contentValues);if(rowId > 0){ // ContentUris 類用於擷取Uri路徑後面的ID部分 //appendId:為該Uri加上IDUri rowUri = ContentUris.appendId(MyUsers.User.CONTENT_URI.buildUpon(), rowId).build(); // getContextResolver().notifyChange():獲得一個ContextResolver對象並且更新裡面的內容。getContext().getContentResolver().notifyChange(rowUri, null);return rowUri;}throw new SQLException("Fail to insert row into"+uri);}/** * 這是一個回呼函數,當產生所在類的對象時,這個方法被調用,建立一個資料庫 */@Overridepublic boolean onCreate() {dbHelper = new DatabaseHelper(getContext());return (dbHelper == null) ? false:true;}/** * 查詢 */@Overridepublic Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,String sortOrder) {//SQLiteQueryBuilder 是一個構造SQL查詢語句的輔助類。SQLiteQueryBuilder qb = new SQLiteQueryBuilder();//getReadableDatabase():先以讀寫方式開啟資料庫,如果資料庫的磁碟空間滿了,就會開啟失敗,當開啟失敗後會繼續嘗試以唯讀方式開啟資料庫SQLiteDatabase db = dbHelper.getReadableDatabase();qb.setTables(TABLE_NAME);/** * Cursor 是每行的集合 * 在Android中 查詢資料是通過Cursor 類來實現的。當我們使用 SQLiteDatabase.query()方法時,就會得到Cursor對象, *  Cursor所指向的就是每一條資料 */Cursor c = qb.query(db, projection, selection, null, null, null, sortOrder);c.setNotificationUri(getContext().getContentResolver(), uri);return c;}@Overridepublic int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) {return 0;}}


在AndroidManifest.xml中進行註冊:

<application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity            android:name=".MainActivity"            android:label="@string/app_name" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>        <provider             android:name=".MyContentProvider"            android:authorities="com.archer.ContentProvider">            </provider>        <!-- android:authorities屬性配置的就是該ContentProvider的名字,是它在Android系統中的名字,我們是通過這個名字去找對應的ContentProvider對象的-->    </application>


最後,建立一個新的工程(測試用)

package com.ContentProviderDemo.Archer;import android.app.Activity;import android.content.ContentValues;import android.database.Cursor;import android.net.Uri;import android.os.Bundle;import android.util.Log;/** * 在另一個工程中訪問建立的資料庫,不用再註冊provider,否則會儲存 * @author Administrator *  */public class MainActivity extends Activity {public static final String AUTHORITY = "com.archer.ContentProvider";private Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY);@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);insertRecord("record1");displayRecords(); }//插入資料private void insertRecord(String userName) {ContentValues values = new ContentValues();values.put("USER_NAME", userName);getContentResolver().insert(CONTENT_URI, values);}//查詢資料private void displayRecords() {// 該數組中包含了所有要返回的欄位String columns[] = new String[] { "_id", "USER_NAME" };Uri myUri = CONTENT_URI;Cursor cur = getContentResolver().query(myUri, columns, null, null,null);if (cur.moveToFirst()) {String id = null;String userName = null;do {id = cur.getString(cur.getColumnIndex("_id"));userName = cur.getString(cur.getColumnIndex("USER_NAME"));Log.e("TAG", "id:" + id + ";" + "userName:" + userName);} while (cur.moveToNext());}cur.close(); // 關閉Cursor對象}}

這樣,就是先不同應用程式間的資料共用了

Android四大組件之Content Provider

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.