標籤:
1ContentProvider相關知識
1.1在安卓應用中,通過檔案方式對外共用資料,需要進行檔案操作讀寫資料;採用sharedpreferences共用資料,需要使用sharedpreferences API讀寫資料。可以看出雖然它們 可以對外共用資料,但資料訪問方式會因資料存放區的方式而不同。
在安卓中使用ContentProvider共用資料在不同的應用程式之間共用資料,底層的操作是透明的,對外提供統一介面,並可以讓其它應用輕鬆訪問該資料。
1.2ContentProvider使用表的形式來組織資料,無論資料的來源是什麼,都會認為是一種表,然後把資料群組織成表格。並且提供了查詢(query)、插入(insert)、更新(update)、刪除(delete)、擷取資料類型(getType)以及建立資料時調用的回呼函數(onCreate)等操作。另外每個ContentProvider都有一個公用的URI,這個URI用於表示這個ContentProvider所提供的資料。Android所提供的ContentProvider都存放在android.provider包當中。
2代碼
2.1訪問系統中的連絡人
public class MainActivity extends Activity {private ListView listView = null;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);listView = (ListView) this.findViewById(R.id.listView);// 查詢系統中的所有連絡人Uri uri = Uri.parse("content://com.android.contacts/contacts");Cursor cursor = getContentResolver().query(uri, null, null, null, null);// 根據Cursor建立SimpleCursorAdapter對象SimpleCursorAdapter simpleCursorAdapter = new SimpleCursorAdapter(this,android.R.layout.simple_list_item_1, cursor,new String[] { ContactsContract.Contacts.DISPLAY_NAME },new int[] { android.R.id.text1 },CursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);// 在ListVIew中顯示連絡人清單listView.setAdapter(simpleCursorAdapter);}}
同時需要在資訊清單檔加入訪問通訊許可請求
<uses-permission android:name="android.permission.READ_CONTACTS" />
2.2程式的Content Provider
這個例子是對資料庫實現的操作,資料庫的操作是上一篇中的內容
資料庫操作類
public class DBOpenHelper extends SQLiteOpenHelper {public DBOpenHelper(Context context) {/** * postgrade.db 資料庫的名字 ;null 表示使用預設的遊標工廠 ;1 表示一開始的版本,建議設定為1 */super(context, "postgrade.db", null, 1);}@Overridepublic void onCreate(SQLiteDatabase db) {// 該方法在第一次建立資料庫的時候被調用// 因此可以在這個地方建立表之類的操作db.execSQL("CREATE TABLE student(id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR(20))");}@Overridepublic void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {// 修改資料庫的版本會觸發此函數// 在這裡可以添加新的表或者修改表的欄位}}
自訂的content provider
public class StuProvider extends ContentProvider {private DBOpenHelper dbOpenHelper = null;private static final UriMatcher MATCHER;private static final int STU = 0;// 匹配成功後的傳回值private static final String AUTHORITY;// 網域名稱[主機名稱]private static final String STUDENT;// 路徑名static {// 在不匹配的時候,返回-1,即UriMatcher.NO_MATCHMATCHER = new UriMatcher(UriMatcher.NO_MATCH);AUTHORITY = "org.tonny.providers.stuprovider";STUDENT = "student";MATCHER.addURI(AUTHORITY, STUDENT, STU);}@Overridepublic boolean onCreate() {// 在建立執行個體的時候調用,只會被調用一次;用作資料的初始化操作dbOpenHelper = new DBOpenHelper(getContext());return false;}@Overridepublic String getType(Uri uri) {// 返回當前要操作的資料的內容類型如txt-->plain/text html -->html/textreturn null;}@Overridepublic Uri insert(Uri uri, ContentValues values) {// 允許外部的應用向內容提供者插入資料SQLiteDatabase db = dbOpenHelper.getWritableDatabase();switch (MATCHER.match(uri)) {case STU:// 調用自身的方法,第二個參數爲插入空值時候的列名long rowId = db.insert("student", null, values);Uri insertUri = ContentUris.withAppendedId(uri, rowId);// 也可以使用這種方式// Uri insertUri =// Uri.parse("content://org.tonny.test.providers.stuprovider/student/"+// rowId);return insertUri;default:throw new IllegalArgumentException("This is an unknown Uri:" + uri);}}@Overridepublic int delete(Uri uri, String selection, String[] selectionArgs) {// TODO Auto-generated method stubreturn 0;}@Overridepublic int update(Uri uri, ContentValues values, String selection,String[] selectionArgs) {// TODO Auto-generated method stubreturn 0;}@Overridepublic Cursor query(Uri uri, String[] projection, String selection,String[] selectionArgs, String sortOrder) {// TODO Auto-generated method stubreturn null;}}
model層
package org.tonny.domain;public class Student {private int id;private String name;public Student() {}public Student(int id, String name) {this.id = id;this.name = name;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}}
表相關操作
public class StudentService {private DBOpenHelper dbHelper = null;public StudentService(Context context) {this.dbHelper = new DBOpenHelper(context);}public void insert(Student stu) {// 內部有緩存功能,使用的是同一個控制代碼,如果資料庫滿了,則返回一個唯讀控制代碼SQLiteDatabase db = dbHelper.getWritableDatabase();// 使用預留位置號‘?’,防止特殊字元db.execSQL("INSERT INTO student VALUES(?,?)",new Object[] { stu.getId(), stu.getName() });}public void delete(Integer id) {SQLiteDatabase db = dbHelper.getReadableDatabase();db.execSQL("DELETE FROM student WHERE id = ?",new String[] { String.valueOf(id) });}public void update(Student stu) {SQLiteDatabase db = dbHelper.getWritableDatabase();db.execSQL("UPDATE student SET name = ? WHERE id = ?", new String[] {stu.getName(), String.valueOf(stu.getId()) });}public Student query(Integer id) {SQLiteDatabase db = dbHelper.getReadableDatabase();String sql = "SELECT * FROM student WHERE id = ?";Cursor cursor = db.rawQuery(sql, new String[] { String.valueOf(id) });if (cursor.moveToFirst()) {int stuId = cursor.getInt(cursor.getColumnIndex("id"));String stuName = cursor.getString(cursor.getColumnIndex("name"));return new Student(stuId, stuName);}return null;}}
activity操作
public class MainActivity extends Activity {private EditText _txtId = null;private EditText _txtName = null;private StudentService _service = null;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);_txtId = (EditText) this.findViewById(R.id.txtId);_txtName = (EditText) this.findViewById(R.id.txtName);_service = new StudentService(getApplicationContext());}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {// Inflate the menu; this adds items to the action bar if it is present.getMenuInflater().inflate(R.menu.main, menu);return true;}public void onBtnOK(View v) {int id = Integer.valueOf(_txtId.getText().toString());String name = _txtName.getText().toString();Student stu = new Student(id, name);_service.insert(stu);}}
資訊清單檔中對uri的說明
<provider android:name="org.tonny.db.StuProvider" android:authorities="org.tonny.providers.stuprovider" android:exported="true" tools:ignore="ExportedContentProvider" />
3.總結
到今天,已經感覺是時候去找些業務研究研究了
Android學習五:Content Provider 使用