一、ContentProvider介绍
ContentProvider的底层是Binder,主要用于跨进程访问。
通过实现ContentProvider的query、update、insert、delete等方法即可。
二、ContentProvider创建
三、权限设置
创建时,需要在AndroidMainfest中声明权限 authorities为唯一标识。
<provider android:name=".MyContentProvider" android:authorities="com.example.fyq.broadtest" //这是唯一标识,一般写包名 android:permission="com.example.PROVIDER" //这是权限,需要有此权限才可以访问 android:process=":provider"//开启另一进程 android:enabled="true" android:exported="true"></provider>
四、实现应用访问
同一应用的其他进程或者另一应用来访问结果是一样的,实现如下:
public class ProviderActivity extends Activity { /** * 外部访问类,用于访问ContentProvider及数据库 * @param savedInstanceState */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_provider); Uri uri = Uri.parse("com.example.fyq.broadtest");//android:authorities属性的标识 getContentResolver().query(uri, null, null, null, null); getContentResolver().query(uri, null, null, null, null); getContentResolver().query(uri, null, null, null, null); //======================添加内容 /** * 访问book表 */ Uri bookUri = Uri.parse("content://com.example.fyq.broadtest/book"); ContentValues values = new ContentValues(); values.put("_id", 6); values.put("name", "书名"); getContentResolver().insert(bookUri, values);//插入一本书 //查询所有书 Cursor bookCursor = getContentResolver().query(bookUri, new String[]{"_id", "name"}, null, null, null); while (bookCursor.moveToNext()) { Book book = new Book(); book.bookId = bookCursor.getInt(0); book.bookName = bookCursor.getString(1); } bookCursor.close(); //======================添加内容 } }
五、创建数据库及表的类
/** * Created by fyq on 2018/5/17. * 这个类是创建数据库的类 */ public class DbOpenHelper extends SQLiteOpenHelper { private static final String DB_NAME = "book_provider.db";//数据库名 public static final String BOOK_TABLE_NAME = "book"; public static final String USER_TABLE_NAME = "user"; private static final int DB_VERSION = 1; //执行语句 ----PRIMARY主键 private String CREATE_BOOK_TABLE = "CREATE TABLE IF NOT EXISTS" + BOOK_TABLE_NAME + "(_id INTEGER PRIMARY KEY," + "name TEXT"; private String CREATE_USER_TABLE = "CREATE TABLE IF NOT EXISTS" + USER_TABLE_NAME + "(_id INTEGER PRIMARY KEY," + "name TEXT," + "sex INT)"; public DbOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) { super(context, name, factory, version); } public DbOpenHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version, DatabaseErrorHandler errorHandler) { super(context, name, factory, version, errorHandler); } public DbOpenHelper(Context mContext) { super(mContext, DB_NAME, null, DB_VERSION); } @Override public void onCreate(SQLiteDatabase db) { db.execSQL(CREATE_BOOK_TABLE); db.execSQL(CREATE_USER_TABLE); } @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { } }
六、数据库操作类
/** * 这个类是用于访问数据库,对数据库进行操作的 */ public class BookContentProvider extends ContentProvider { private static final String TAG = "BookContentProvider"; //==============二、添加内容==================== /** *用于对应Uri和Uri_Code */ public static final String AUTHORITY = "com.example.fyq.broadtest";//这个是根据AndroidMainfest中唯一标识来命名的 //对Book和User两个不同的对象定义URI的标识 public static final Uri BOOK_CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/book"); public static final Uri USER_CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/user"); public static final int BOOK_URI_CODE = 0; public static final int USER_URI_CODE = 1; private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); static { sUriMatcher.addURI(AUTHORITY, "book", BOOK_URI_CODE);//通过此方式关联Uri和Uri_Code sUriMatcher.addURI(AUTHORITY, "user", USER_URI_CODE); } private SQLiteDatabase mDb; private Context mContext; /** * 通过Uri获取Uri_Code,根据Uri_Code再得到表名 */ private String getTableName(Uri uri) { String tableName = null; switch (sUriMatcher.match(uri)) { case BOOK_URI_CODE://知道Code后获取表名 tableName = DbOpenHelper.BOOK_TABLE_NAME; break; case USER_URI_CODE: tableName = DbOpenHelper.USER_TABLE_NAME; break; default: break; } return tableName; } //===============二、添加内容================== public BookContentProvider() { } @Override public String getType(Uri uri) { return null; } @Override public boolean onCreate() { mContext = getContext(); initProviderData();//ContentProvider创建时初始化数据库。此过程不应在主线程中进行,因为耗时 return true; } private void initProviderData() { mDb = new DbOpenHelper(mContext).getWritableDatabase();//DBOpen是继承自SQLiteOpenHelper的 /** * 之后mDb.execSQL执行SQL语句 */ } /** * 除了query外,其他三个方法会引起数据源改变 * @param uri * @param projection * @param selection * @param selectionArgs * @param sortOrder * @return */ @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { Log.d(TAG, "query: current thread:" + Thread.currentThread().getName()); String table = getTableName(uri); if (table == null) { // TODO: Implement this to handle query requests from clients. throw new UnsupportedOperationException("Not yet implemented"); } return mDb.query(table, projection, selection, selectionArgs, null, null, sortOrder, null); } @Override public Uri insert(Uri uri, ContentValues values) { String table = getTableName(uri); if(table == null) { // TODO: Implement this to handle requests to insert a new row. throw new UnsupportedOperationException("Not yet implemented"); } mDb.insert(table, null, values); //可能通过ContentProvider的registerContentObserver来注册观察者;通过unre...来解绑 mContext.getContentResolver().notifyChange(uri,null);//通知外界数据有变化 return uri; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { /** * ignore未写 */ // TODO: Implement this to handle requests to update one or more rows. throw new UnsupportedOperationException("Not yet implemented"); } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { /** * ignore未写 */ // Implement this to handle requests to delete one or more rows. throw new UnsupportedOperationException("Not yet implemented"); } }