在上一个DataBaseTest项目的基础上继续开发,copy一下,名字叫做ContentProvider
首先将MyDataBase中使用的Toast去掉,因为跨程序访问时我们不能直接使用Toast
然后创建一个内容提供器(右键--new--other--ContentProvider)
在类的一开始,定义了4个常量,分别用于表示访问Book表/Category表中的所有数据/单条数据
public class MyContentProvider 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 ACTHORITY = "com.example.contentprovider.provider";
private static UriMatcher sUriMatcher;
private MyDatabaseHelper mMyDatabaseHelper;
//对UriMatcher进行了初始化操作
static {
sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
sUriMatcher.addURI(ACTHORITY,"book",BOOK_DIR);
sUriMatcher.addURI(ACTHORITY,"book/#",BOOK_ITEM);
sUriMatcher.addURI(ACTHORITY,"category",CATEGORY_DIR);
sUriMatcher.addURI(ACTHORITY,"catetory/#",CATEGORY_ITEM);
}
public MyContentProvider() {
}
//创建了一个MyDatabaseHelper实例,返回true表示内容提供器初始化成功
@Override
public boolean onCreate() {
// TODO: Implement this to initialize your content provider on startup.
mMyDatabaseHelper = new MyDatabaseHelper(getContext(),"BookStore.db",null,2);
return true;
}
//通过获取SQLiteDatabase实例,根据uri参数判断用户想要访问哪张表,调用其query方法进行查询,并将cursor对象返回
//当访问单条数据时,调用了uri.getPathSegments()方法,它会将内容URI权限之后部分以/进行切割
//并把分割后的结果放入到一个字符串列表里,这个列表的第0个位置存放的是路径,第1个位置存放的是id
//得到id之后,再根据selection,selectionArgs进行约束,就实现了查找单条数据的功能
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
// TODO: Implement this to handle query requests from clients.
//查询数据
SQLiteDatabase db = mMyDatabaseHelper.getReadableDatabase();
Cursor cursor = null;
switch (sUriMatcher.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;
}
//同样先获得了SQLiteDatabase实例,然后根据传入的参数判断出用户想要往哪张表里添加数据,在调用insert()
//需要注意的是insert()要求返回一个uri,所以我们需要调用Uri.parse()方法来讲一个内容URI解析成Uri对象
@Override
public Uri insert(Uri uri, ContentValues values) {
// TODO: Implement this to handle requests to insert a new row.
//添加数据
SQLiteDatabase db = mMyDatabaseHelper.getWritableDatabase();
Uri uriReturn = null;
switch (sUriMatcher.match(uri)) {
case BOOK_DIR:
case BOOK_ITEM:
long newBookId = db.insert("Book",null,values);
uriReturn = Uri.parse("content://" + ACTHORITY + "/book/" + newBookId);
break;
case CATEGORY_DIR:
case CATEGORY_ITEM:
long newCategoryId = db.insert("Category",null,values);
uriReturn = Uri.parse("content://" + ACTHORITY + "/category/" + newCategoryId);
break;
default:
break;
}
return uriReturn;
}
//先获取实例,然后根据用户想要更新哪张表的数据,调用update方法进行更新
//受影响的行数将作为返回值返回
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// TODO: Implement this to handle requests to update one or more rows.
//更新数据
SQLiteDatabase db = mMyDatabaseHelper.getWritableDatabase();
int updatedRows = 0;
switch (sUriMatcher.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;
}
//首先获取到SQLiteDatabase实例,然后根据传入的uri参数判断出用户想要删除哪张表的数据
//被删除的行数将作为返回值返回
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// Implement this to handle requests to delete one or more rows.
SQLiteDatabase db = mMyDatabaseHelper.getWritableDatabase();
int deleteRows = 0;
switch (sUriMatcher.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});
break;
default:
break;
}
return deleteRows;
}
@Override
public String getType(Uri uri) {
// TODO: Implement this to handle requests for the MIME type of the data
// at the given URI.
switch (sUriMatcher.match(uri)) {
case BOOK_DIR:
return "vnd.android.cursor.dir/vnd.com.example.contentprovider.provider.book";
case BOOK_ITEM:
return "vnd.android.cursor.item/vnd.com.example.contentprovider.provider.book";
case CATEGORY_DIR:
return "vnd.android.cursor.dir/vnd.com.example.contentprovider.provider.category";
case CATEGORY_ITEM:
return "vnd.android.cursor.item/vnd.com.example.contentprovider.provider.category";
}
return null;
}
}
- 修改Manifest文件
由于我们是自动创建的,因此系统自动帮我们注册了provider
<provider
android:name=".MyContentProvider"
android:authorities="com.example.contentprovider.provider"
android:enabled="true"
android:exported="true"></provider>
创建一个providerTest项目去访问contentProvider中的数据
- 修改activity_main
<Button
android:id="@+id/add_button"
android:layout_width="252dp"
android:layout_height="54dp"
android:layout_marginTop="192dp"
android:text="@string/add_button"
android:onClick="addButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.496"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/query_button"
android:layout_width="252dp"
android:layout_height="54dp"
android:layout_marginTop="36dp"
android:text="@string/query_button"
android:onClick="queryButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.496"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/add_button" />
<Button
android:id="@+id/update_button"
android:layout_width="252dp"
android:layout_height="54dp"
android:layout_marginTop="36dp"
android:text="@string/update_button"
android:onClick="updateButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.496"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/query_button" />
<Button
android:id="@+id/delete_button"
android:layout_width="252dp"
android:layout_height="54dp"
android:layout_marginTop="36dp"
android:text="@string/delete_button"
android:onClick="deleteButton"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.496"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/update_button" />
- 修改MainActivity
public class MainActivity extends AppCompatActivity {
private String newId;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
//添加数据
//调用Uri.parse()方法将一个内容URI解析成Uri对象
//insert()方法会返回一个Uri对象,这个对象中包含了新增数据的id
public void addButton(View view) {
Uri uri = Uri.parse("content://com.example.contentprovider.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",22.85);
Uri newUri = getContentResolver().insert(uri,values);
newId = newUri.getPathSegments().get(1);
}
//查询数据
public void queryButton(View view) {
Uri uri = Uri.parse("content://com.example.contentprovider.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();
}
}
//更新数据
public void updateButton(View view) {
Uri uri = Uri.parse("content://com.example.contentprovider.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);
}
//删除数据
public void deleteButton(View view) {
Uri uri = Uri.parse("content://com.example.contentprovider.provider/book/" + newId);
getContentResolver().delete(uri,null,null);
}
}
- 下载地址
https://github.com/qricis/DoSomeAndroidTest/tree/main/ContentProvider
https://github.com/qricis/DoSomeAndroidTest/tree/main/ProviderTest