ContentProvider主要用於在不一樣應用程序之間實現數據共享功能。容許一個程序訪問另外一個程序,並保證被訪數據的安全性。java
Android系統自帶的電話簿、短信、媒體庫等提供了相似的接口。還能夠經過新建一個類繼承ContentProvider自定義本身的內容提供器。node
Google Doc對ContentProvider的部分描述:android
內容提供者繼承自ContentProvider基類,爲其餘應用程序取用和存儲管理數據實現了一套標準方案,但應用程序並不直接調用這些方法,而是使用ContentResolver對象,調用它的方法做爲代替。sql
example數據庫
讀取系統聯繫人安全
package sunny.example.contactstest; import java.util.ArrayList; import android.support.v7.app.ActionBarActivity; import android.database.Cursor; import android.os.Bundle; import android.provider.ContactsContract; import android.widget.ArrayAdapter; import android.widget.ListView; import java.util.List; public class MainActivity extends ActionBarActivity { ListView contactsView; ArrayAdapter<String> adapter; List<String> contactsList = new ArrayList<String>(); @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); contactsView = (ListView)findViewById(R.id.contacts_view); /*android.widget.ArrayAdapter.ArrayAdapter<String>(Context context, int textViewResourceId, List<String> objects) *Parameters: context The current context. textViewResourceId The resource ID for a layout file containing a TextView to use when instantiating views. objects The objects to represent in the ListView.*/ adapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1,contactsList); //void android.widget.ListView.setAdapter(ListAdapter adapter) contactsView.setAdapter(adapter); readContacts(); } private void readContacts(){ /*android.database.Cursor This interface provides random read-write access to the result set returned by a database query. */ Cursor cursor = null; try{ /* * ContentResolver android.content.ContextWrapper.getContentResolver() * Return a ContentResolver instance for your application's package. */ /*要訪問ContentProvider中共享的數據就要藉助getContentResolver類,經過getContentResolver()方法 * 獲取該類的實例,利用其中提供的方法對數據進行CRUD操做(Create/Retrieve/Delete)*/ cursor = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null); while(cursor.moveToNext()){ String displayName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)); String number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)); contactsList.add(displayName+"\n"+number); } }catch(Exception e){ e.printStackTrace(); }finally{ if(cursor!=null){ cursor.close(); } } } }
建立本身的內容提供器app
//DatabaseProvider.java建立數據庫 package sunny.example.databasetest; import android.content.ContentProvider; import android.content.ContentValues; import android.content.UriMatcher; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.net.Uri; public class DatabaseProvider extends ContentProvider{ public static final int BOOK_DIR = 0; public static final int BOOK_ITEM = 1; public static final int CATEGORY_DIR = 2; public static final int CATEGORY_ITEM = 3; public static final String AUTHORITY = "sunny.example.databasetest.provider"; private MyDatabaseHelper dbHelper; private static UriMatcher uriMatcher; /*void android.content.UriMatcher.addURI(String authority, String path, int code) Add a URI to match, and the code to return when this URI is matched. URI nodes may be exact match string, the token "*" that matches any text, or the token "#" that matches only numbers. Parameters: authority the authority to match path the path to match. * may be used as a wild card for any text, and # may be used as a wild card for numbers. code the code that is returned when a URI is matched against the given components. Must be positive.*/ static{ /*android.content.UriMatcher.UriMatcher(int code) Creates the root node of the URI tree. */ uriMatcher = new UriMatcher(UriMatcher.NO_MATCH); uriMatcher.addURI(AUTHORITY, "book", BOOK_DIR); uriMatcher.addURI(AUTHORITY, "book/#", BOOK_ITEM); uriMatcher.addURI(AUTHORITY, "category", CATEGORY_DIR); uriMatcher.addURI(AUTHORITY, "category/#", CATEGORY_ITEM); } @Override public boolean onCreate() { // TODO Auto-generated method stub dbHelper = new MyDatabaseHelper(getContext(),"BookStore.db",null,2); return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { // TODO Auto-generated method stub SQLiteDatabase db = dbHelper.getReadableDatabase(); Cursor cursor = null; switch(uriMatcher.match(uri)){ case BOOK_DIR: cursor = db.query("book",projection,selection,selectionArgs,null,null,sortOrder); break; case BOOK_ITEM: String bookId = uri.getPathSegments().get(1); cursor = db.query("book", projection, "id = ?", new String[]{bookId}, null,null, sortOrder); break; case CATEGORY_DIR: cursor = db.query("category", projection, selection, selectionArgs,null, null, sortOrder); break; case CATEGORY_ITEM: String categoryId = uri.getPathSegments().get(1); cursor = db.query("category", projection, "id = ?",new String[]{categoryId},null, null, sortOrder); break; default: break; } return null; } @Override public String getType(Uri uri) { // TODO Auto-generated method stub switch(uriMatcher.match(uri)){ case BOOK_DIR: return "vnd.android.cursor.dir/vnd.com.example.app.provider.table1"; case BOOK_ITEM: return "vnd.android.cursor.item/vnd.com.example.app.provider.table1"; case CATEGORY_DIR: return "vnd.android.cursor.dir/vnd.com.example.app.provider.table2"; case CATEGORY_ITEM: return "vnd.android.cursor.item/vnd.com.example.app.provider.table2"; default: break; } return null; } @Override public Uri insert(Uri uri, ContentValues values) { // TODO Auto-generated method stub SQLiteDatabase db = dbHelper.getWritableDatabase(); Uri uriReturn = null; switch(uriMatcher.match(uri)){ case BOOK_DIR: case BOOK_ITEM: long newBookId = db.insert("Book", null, values); uriReturn = uri.parse("content://"+AUTHORITY+"/book/"+newBookId); break; case CATEGORY_DIR: case CATEGORY_ITEM: long newCategoryId = db.insert("Category", null, values); uriReturn = uri.parse("content://"+AUTHORITY+"/category"+newCategoryId); break; default: break; } return uriReturn; } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { // TODO Auto-generated method stub SQLiteDatabase db = dbHelper.getWritableDatabase(); int deleteRows = 0; switch(uriMatcher.match(uri)){ case BOOK_DIR: deleteRows = db.delete("Book", selection, selectionArgs); break; case BOOK_ITEM: String bookId = uri.getPathSegments().get(1); deleteRows = db.delete("Book", "id = ?", new String[]{bookId}); break; case CATEGORY_DIR: deleteRows = db.delete("Category", selection, selectionArgs); break; case CATEGORY_ITEM: String categoryId = uri.getPathSegments().get(1); deleteRows = db.delete("Category", "id = ?", new String[]{categoryId}); default: break; } return deleteRows ; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { // TODO Auto-generated method stub SQLiteDatabase db = dbHelper.getWritableDatabase(); int updateRows = 0; switch(uriMatcher.match(uri)){ case BOOK_DIR: updateRows = db.update("Book", values, selection, selectionArgs); break; case BOOK_ITEM: String bookId = uri.getPathSegments().get(1); updateRows = db.update("Book", values, "id = ?", new String[]{bookId}); break; case CATEGORY_DIR: updateRows = db.update("Category", values, selection, selectionArgs); break; case CATEGORY_ITEM: String categoryId = uri.getPathSegments().get(1); updateRows = db.update("Category", values, "id = ?", new String[]{categoryId}); default: break; } return updateRows ; } }
//MyDatabaseHelper.java package sunny.example.databasetest; import android.content.Context; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteDatabase.CursorFactory; import android.database.sqlite.SQLiteOpenHelper; import android.widget.Toast; public class MyDatabaseHelper extends SQLiteOpenHelper{ //將建表語句定義成一個字符常量 public static final String CREATE_BOOK = "create table Book("+ "id integer primary key autoincrement,"+"author text,"+"price real,"+"pages integer,"+"name text)"; public static final String CREATE_CATEGORY="create table Category("+"id integer primary key autoincrement,"+"category_name text,"+"categpry_code integer)"; private Context mContext; public MyDatabaseHelper(Context context, String name, CursorFactory factory, int version) { //第二個參數:數據庫名。第三個參數:容許在查詢數據的時候返回一個自定義的Cursor.第四個參數:當前數據庫版本號 super(context, name, factory, version); // TODO Auto-generated constructor stub mContext = context; } @Override public void onCreate(SQLiteDatabase db) { // TODO Auto-generated method stub db.execSQL(CREATE_BOOK);//執行建表語句 db.execSQL(CREATE_CATEGORY); Toast.makeText(mContext, "Create Succeeded", Toast.LENGTH_SHORT).show(); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // TODO Auto-generated method stub db.execSQL("drop table if exists Book"); db.execSQL("drop table if exists Category"); onCreate(db); } }
//MainActivity.java package sunny.example.databasetest; import android.support.v7.app.ActionBarActivity; import android.content.ContentValues; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.os.Bundle; import android.util.Log; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView; public class MainActivity extends ActionBarActivity { //構建MyDatabaseHelper對象 private MyDatabaseHelper dbHelper; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); dbHelper = new MyDatabaseHelper(this,"BookStore.db",null,2); //將數據庫名指定爲BookStore.db,版本號指定爲1 dbHelper = new MyDatabaseHelper(this,"BookStore.db",null,1); Button createDatabase = (Button)findViewById(R.id.create_database); createDatabase.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { // TODO Auto-generated method stub //建立數據庫 dbHelper.getWritableDatabase(); } }); Button addData = (Button)findViewById(R.id.add_data); addData.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { // TODO Auto-generated method stub SQLiteDatabase db = dbHelper.getWritableDatabase(); ContentValues values = new ContentValues(); values.put("name", "A"); values.put("author", "Dan"); values.put("pages", 12); values.put("price",0.7); db.insert("Book",null,values); } }); Button updateData = (Button)findViewById(R.id.update_data); updateData.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { // TODO Auto-generated method stub SQLiteDatabase db = dbHelper.getWritableDatabase(); ContentValues values = new ContentValues(); values.put("price", 0.2); //將name等於A的price改爲0.2 db.update("Book", values, "name = ?", new String[]{"A"}); } }); Button deleteData = (Button)findViewById(R.id.delete_data); deleteData.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { // TODO Auto-generated method stub SQLiteDatabase db = dbHelper.getWritableDatabase(); //刪去頁數超過500頁的書 db.delete("Book", "pages > ?", new String[]{"500"}); } }); Button queryData = (Button)findViewById(R.id.query_data); queryData.setOnClickListener(new OnClickListener(){ @Override public void onClick(View v) { // TODO Auto-generated method stub SQLiteDatabase db = dbHelper.getWritableDatabase(); Cursor cursor = db.query("Book", null, null, null, null, null, null); /*Move the cursor to the first row. This method will return false if the cursor is empty. Returns: whether the move succeeded.*/ if(cursor.moveToFirst()){ do{ String name = cursor.getString(cursor.getColumnIndex("name")); String author = cursor.getString(cursor.getColumnIndex("author")); int pages = cursor.getInt(cursor.getColumnIndex("pages")); double price = cursor.getDouble(cursor.getColumnIndex("price")); Log.d("MainActivity","book name is" + name); TextView textView = (TextView)findViewById(R.id.textView); String nameT = "book name is" + name; textView.setText(nameT); }while(cursor.moveToNext()); } cursor.close(); } }); } }
<provider android:name="sunny.example.databasetest.DatabaseProvider" android:authorities="sunny.example.databasetest.provider" android:exported="true"></provider>