对《第一行代码-----android》的读书笔记
其主要应用于在不同的程序之间实现数据共享的功能,它提供了一套完整的机制,允许一个程序访问另一个程序的数据,同时还保证数据见的安全性。
内容提供器的用法一般有两种,一种是使用现有的内容提供器来读取和操作相应程序的数据,另一种是创建自己的内容提供器给我们的程序的数据提供外部访问接口。
一个内容提供器对其数据提供了外部的访问接口,任何其他应用程序就都可以对这部分程序进行访问。
android系统中自带的电话簿,短信,媒体库等程序都提供了类似的访问接口。
想要访问内容提供器中共享的数据,就一定借助ContentResolver类,可以通过Context中的getContentResolver()方法获取到该类的实例。
其中提供了一系列的方法用于对数据库进行CRUD操作。不同于SQLiteDatabase,ContentResoleer中的CRUD都是不接受表名参数的,而是使用Uri的参数来代替,这个参数被称为内容URI。
内容URI给内容提供器中的数据建立了唯一的标识符,他主要有两部分组成,权限和路径。权限一般使用报名组成路径一般由表明组成。
content://com.example.app.provider/table1
之后,我们就可以将它解析成URI对象才可以作为参数传入。
Uri uri=Uri.parse("content://com.example.app.provider/table1")
只需调用Uri.parse()方法,就可以内容URI字符串解析成Uri对象
使用这个uri对象来查询table1表中的数据
Cursor cursor=getContentResolver().query{ uri, projection, //制定查询的列明 selection, //指定where的约束条件名 selectionArgs,//为where中的占位符提供具体的值 orderBy,//指定查询结果的排序方式 );
查询完返回的还是Cursor对象
if(cursor!=null){ while(cursor.moveToNext(){ String colum1=cursor.getString(ccursor.getColumnIndex("column1")); int column2=cursor.getInt(cursor.getColumnIndex("column3")); } cursor.close(); }
ContentValues values=new ContentValues(); values.put("column1","text"); values.put("column2",1); getContentResolver().inset(uri.values);
仍然是将数据组装到ContentValues中,然后调用ContentResolver的insert()方法,将Uri和ContentValues作为参数传入即可
更新一条数据,把column1的值晴空,可以借助ContentResolver的updata()方法实现
ContentValues values=new ContentValues(); values.put("column1",""); getContentResolver().update(uri,values,"column1=?and colum2=?",new String[]{"text","1"});
注意:哟上代码使用了selection和selectionArgs参数来对想要更新的数据进行了约束
getContentResolver().delete(uri,:column3=?",new String[]{"1"});
public class MainActivity extends Activity { 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); adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, contactsList); contactsView.setAdapter(adapter); readContacts(); } private void readContacts() { Cursor cursor = null; try { //查询联系人数据 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(); } } } }
一个能够匹配任意表的内容URI格式就可以写成:content://com.example.app.provider/*
能够匹配table表中任意一行数据的内容URI格式就可以写成:content://com.example.app.provider/table1/#
getType()方法,它是所有内容提供器都必须提供的方法,用于获取Uri对象对应的MIME类型。一个内容URI多对应的MIME字符串主要有三部分组成:
1.必须以vnd组成
2.如果内容URI以路径结尾,则后接android.cursor.dir/,如果内容URI以id结尾,则后接android.cursor.item/.
3.最后接上vnd.<authority>.<path>
public String getType(Uri uri) { switch (uriMatcher.match(uri)) { case BOOK_DIR: return "vnd.android.cursor.dir/vnd.com.example.databasetest.provider.book"; case BOOK_ITEM: return "vnd.android.cursor.item/vnd.com.example.databasetest.provider.book"; case CATEGORY_DIR: return "vnd.android.cursor.dir/vnd.com.example.databasetest.provider.category"; case CATEGORY_ITEM: return "vnd.android.cursor.item/vnd.com.example.databasetest.provider.category"; } return null; }
对外实现接口:
package com.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 = "com.example.databasetest.provider"; private static UriMatcher uriMatcher; private MyDatabaseHelper dbHelper; static { 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() { dbHelper = new MyDatabaseHelper(getContext(), "BookStore.db", null, 2); return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { 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 cursor; } @Override public Uri insert(Uri uri, ContentValues values) { 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 update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { SQLiteDatabase db = dbHelper.getWritableDatabase(); int updatedRows = 0; switch (uriMatcher.match(uri)) { case BOOK_DIR: updatedRows = db.update("Book", values, selection, selectionArgs); break; case BOOK_ITEM: String bookId = uri.getPathSegments().get(1); updatedRows = db.update("Book", values, "id = ?", new String[] { bookId }); break; case CATEGORY_DIR: updatedRows = db.update("Category", values, selection, selectionArgs); break; case CATEGORY_ITEM: String categoryId = uri.getPathSegments().get(1); updatedRows = db.update("Category", values, "id = ?", new String[] { categoryId }); break; default: break; } return updatedRows; } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { SQLiteDatabase db = dbHelper.getWritableDatabase(); int deletedRows = 0; switch (uriMatcher.match(uri)) { case BOOK_DIR: deletedRows = db.delete("Book", selection, selectionArgs); break; case BOOK_ITEM: String bookId = uri.getPathSegments().get(1); deletedRows = db.delete("Book", "id = ?", new String[] { bookId }); break; case CATEGORY_DIR: deletedRows = db.delete("Category", selection, selectionArgs); break; case CATEGORY_ITEM: String categoryId = uri.getPathSegments().get(1); deletedRows = db.delete("Category", "id = ?", new String[] { categoryId }); break; default: break; } return deletedRows; } @Override public String getType(Uri uri) { switch (uriMatcher.match(uri)) { case BOOK_DIR: return "vnd.android.cursor.dir/vnd.com.example.databasetest.provider.book"; case BOOK_ITEM: return "vnd.android.cursor.item/vnd.com.example.databasetest.provider.book"; case CATEGORY_DIR: return "vnd.android.cursor.dir/vnd.com.example.databasetest.provider.category"; case CATEGORY_ITEM: return "vnd.android.cursor.item/vnd.com.example.databasetest.provider.category"; } return null; } }程序测试:
public class MainActivity extends Activity { private String newId; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button addData = (Button) findViewById(R.id.add_data); addData.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Uri uri = Uri .parse("content://com.example.databasetest.provider/book"); ContentValues values = new ContentValues(); values.put("name", "A Clash of Kings"); values.put("author", "George Martin"); values.put("pages", 1040); values.put("price", 55.55); Uri newUri = getContentResolver().insert(uri, values); newId = newUri.getPathSegments().get(1); } }); Button queryData = (Button) findViewById(R.id.query_data); queryData.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Uri uri = Uri .parse("content://com.example.databasetest.provider/book"); Cursor cursor = getContentResolver().query(uri, null, null, null, null); if (cursor != null) { while (cursor.moveToNext()) { 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); Log.d("MainActivity", "book author is " + author); Log.d("MainActivity", "book pages is " + pages); Log.d("MainActivity", "book price is " + price); } cursor.close(); } } }); Button updateData = (Button) findViewById(R.id.update_data); updateData.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Uri uri = Uri .parse("content://com.example.databasetest.provider/book/" + newId); ContentValues values = new ContentValues(); values.put("name", "A Storm of Swords"); values.put("pages", 1216); values.put("price", 24.05); getContentResolver().update(uri, values, null, null); } }); Button deleteData = (Button) findViewById(R.id.delete_data); deleteData.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Uri uri = Uri .parse("content://com.example.databasetest.provider/book/" + newId); getContentResolver().delete(uri, null, null); } }); } }