ContentProvider主要用于在不同应用程序之间实现数据共享功能。允许一个程序访问另一个程序,并保证被访数据的安全性。
Android系统自带的电话簿、短信、媒体库等提供了类似的接口。还可以通过新建一个类继承ContentProvider自定义自己的内容提供器。
Google Doc对ContentProvider的部分描述:
内容提供者继承自ContentProvider基类,为其他应用程序取用和存储管理数据实现了一套标准方案,但应用程序并不直接调用这些方法,而是使用ContentResolver对象,调用它的方法作为代替。
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(); } } } }
创建自己的内容提供器
//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>