當在系統中部署一個又一個Android應用以後,系統裏將會包含多個Android應用,有時候就須要在小同的應用之問芡亭數據,好比如今有一個短信接收應用,用戶想把接收到的陌生短信的發信人添加到聯繫人管理應用中,就須要在小同應用之問共寧數據。對於這種須要在小同應用之問共亨數據的需求,固然可讓一個應用程序直接去操做另個應用程序所記錄的數據,好比操做它所記錄的SharedPreferences、文件或數據庫等,這種方式顯得太雜亂了:不一樣的應用程序記錄數據的方式差異很大,這種力式不利於應用程序之問進行數據交換。
爲了在應用程序之問交換數據,Android提供了ContentProvider,ContentProvider是不一樣應用程序之間進行數據交換的標準API,當一個應用程序須要把本身的數據暴露給其餘程序使用時,該應用科序就能夠經過提供ContentProvider來實現;其餘應用程序就可經過ContentResolver來操做ContentProvider暴露的數據。
ContentProvider也是Android應刖的四大組件之一,與Activity、Service、BroadcastReceiver類似,它們都須要存AndroidManifest.xml文件中進行配置。
一旦某個應用程序經過ContentProvider暴露了本身的數據操做接口,那麼無論該應用程序是否啓動,其餘應用程序均可經過該接口來操做該應用程序的內部數據,包括增長數據、刪除數據、修改數據、查詢數據等。
java
MyUser.javaandroid
package com.supermario.mycontentprovider; import android.net.Uri; import android.provider.BaseColumns; public class MyUser { public static final String AUTHORITY = "com.supermario.MyContentProvider"; // BaseColumn類中已經包含了_id字段 public static final class User implements BaseColumns { // 定義Uri public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY); // 定義數據表列 public static final String USER_NAME = "USER_NAME"; } }
MyContentProvider.javasql
package com.supermario.mycontentprovider; 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; /** * MyContentProvider繼承ContentProvider類,實現其insert,update,delete,getType, * onCreate等方法 */ public class MyContentProvider extends ContentProvider { // 定義一個SQLiteDatabase變量 private SQLiteDatabase sqlDB; // 定義一個DatabaseHelper變量 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類,重寫其方法 */ public static class DatabaseHelper extends SQLiteOpenHelper { // 構造方法 public DatabaseHelper(Context context) { // 父類構造方法 super(context, DATABASE_NAME, null, DATABASE_VERSION); } // 當第一次建立數據庫的時候調用該方法,能夠爲數據庫增長一些表,和初始化一些數據 @Override public void onCreate(SQLiteDatabase db) { // 在數據庫裏生成一張表 db.execSQL("Create table " + TABLE_NAME + "( _id INTEGER PRIMARY KEY AUTOINCREMENT, USER_NAME TEXT);"); } // 當更新數據庫版本的時候,調用該方法。能夠刪除,修改表的一些信息 @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME); onCreate(db); } } // 這是一個回調函數,當生成所在類的對象時,這個方法被調用,建立一個數據庫 @Override public boolean onCreate() { dbHelper = new DatabaseHelper(getContext()); return (dbHelper == null) ? false : true; } // 查詢 @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { SQLiteQueryBuilder qb = new SQLiteQueryBuilder(); SQLiteDatabase db = dbHelper.getReadableDatabase(); qb.setTables(TABLE_NAME); Cursor c = qb.query(db, projection, selection, null, null, null,sortOrder); c.setNotificationUri(getContext().getContentResolver(), uri); return c; } // 取得類型 @Override public String getType(Uri uri) { return null; } // 插入數據 @Override public Uri insert(Uri uri, ContentValues contentvalues) { sqlDB = dbHelper.getWritableDatabase(); long rowId = sqlDB.insert(TABLE_NAME, "", contentvalues); if (rowId > 0) { Uri rowUri = ContentUris.appendId(MyUser.User.CONTENT_URI.buildUpon(), rowId).build(); getContext().getContentResolver().notifyChange(rowUri, null); return rowUri; } throw new SQLException("Failed to insert row into" + uri); } // 刪除數據 @Override public int delete(Uri uri, String selection, String[] selectionArgs) { return 0; } // 更新數據 @Override public int update(Uri uri, ContentValues values, String selection,String[] selectionArgs) { return 0; } }
MyContentActivity.java數據庫
package com.supermario.mycontentprovider; import android.app.Activity; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.widget.Toast; public class MyContentActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 插入兩條記錄 insertRecord("Test"); insertRecord("Guo"); // 顯示記錄 displayRecords(); } // 插入記錄 private void insertRecord(String userName) { ContentValues values = new ContentValues(); values.put(MyUser.User.USER_NAME, userName); getContentResolver().insert(MyUser.User.CONTENT_URI, values); } private void displayRecords() { // 構建一個字符串數組用於存放用戶的記錄 String columns[] = new String[] { MyUser.User._ID,MyUser.User.USER_NAME }; // 設定ContentProvider的Uri Uri myUri = MyUser.User.CONTENT_URI; Cursor cur = managedQuery(myUri, columns, null, null, null); if (cur.moveToFirst()) { String id = null; String userName = null; do { id = cur.getString(cur.getColumnIndex(MyUser.User._ID)); userName = cur.getString(cur.getColumnIndex(MyUser.User.USER_NAME)); // 顯示數據表中的數據 Toast.makeText(this, id + " " + userName, Toast.LENGTH_LONG).show(); } while (cur.moveToNext()); } } }
AndroidManifest.xml數組
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.supermario.mycontentprovider" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="10" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <!-- 聲明ContentProvider --> <provider android:name="MyContentProvider" android:authorities="com.supermario.MyContentProvider"></provider> <activity android:name=".MyContentActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
界面:app
MyConrentClientActivity.javaide
package com.supermario.mycontentclient; import android.app.Activity; import android.content.ContentResolver; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.view.View; import android.widget.Button; import android.widget.EditText; import android.widget.TextView; public class MyContentClientActivity extends Activity { public static final String AUTHORITY = "com.supermario.MyContentProvider"; private Button insertButton = null; // 訪問ContentProvider的Uri Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); TextView show=(TextView)findViewById(R.id.show); StringBuffer sb=new StringBuffer(""); // 獲得ContentProvider對於表的全部數據,以遊標格式保存 Cursor c = managedQuery(CONTENT_URI, new String[] { "_id", "USER_NAME" }, null, null, null); // 循環打印ContentProvider的數據 if (c.moveToFirst()) { String _id = null; String user_name = null; do { // 獲得_id列,USER_NAME列 _id = c.getString(c.getColumnIndex("_id")); user_name = c.getString(c.getColumnIndex("USER_NAME")); sb.append("_id = " + _id + ", user_name = " + user_name+"\n"); } while (c.moveToNext()); } show.setText(sb); // 根據Id獲得控件對象 insertButton = (Button) findViewById(R.id.insert); // 給按鈕綁定事件監聽器 insertButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 獲得EditText輸入的數據 String username = ((EditText) findViewById(R.id.userName)) .getText().toString(); // 生成一個ContentResolver對象 ContentResolver cr = getContentResolver(); // 生成一個ContentValues對象 ContentValues values = new ContentValues(); // 將EditText輸入的值,保存到ContentValues對象中 values.put("USER_NAME", username); // 插入數據 cr.insert(CONTENT_URI, values); } }); } }
main.xml函數
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <!-- 用於顯示數據庫信息 --> <TextView android:id="@+id/show" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <!-- 文本編輯框 ,用於輸入信息--> <EditText android:id="@+id/userName" android:layout_width="fill_parent" android:layout_height="wrap_content" /> <!-- 輸入按鈕 --> <Button android:id="@+id/insert" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Button" /> </LinearLayout>
AndroidManifest.xmlui
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.supermario.mycontentclient" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="10" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <activity android:name=".MyContentClientActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
界面:this