内容提供者是 Android 应用程序的主要构建块之一,为应用程序提供内容。ContentResolver
它们封装数据并通过单一接口将其提供给应用程序 。仅当您需要在多个应用程序之间共享数据时才需要内容提供程序。例如,联系人数据由多个应用程序使用,并且必须存储在内容提供程序中。如果您不需要在多个应用程序之间共享数据,您可以直接通过SQLiteDatabase
.
当通过 a 发出请求时ContentResolver
,系统会检查给定 URI 的权限,并将请求传递给向该权限注册的内容提供者。内容提供者可以随心所欲地解释 URI 的其余部分。该类UriMatcher
有助于解析 URI。
需要实现的主要方法是:
onCreate()
调用它来初始化提供程序query(Uri, String[], Bundle, CancellationSignal)
它将数据返回给调用者insert(Uri, ContentValues)
它将新数据插入内容提供程序update(Uri, ContentValues, Bundle)
更新内容提供者中的现有数据delete(Uri, Bundle)
从内容提供者中删除数据getType(Uri)
它返回内容提供程序中的 MIME 类型的数据
query 查询
四个参数:
public Cursor query (Uri uri,
String[] projection,
Bundle queryArgs,
CancellationSignal cancellationSignal)
参数 | |
---|---|
uri | Uri : 要查询的 URI。这将是客户端发送的完整 URI。该值不能为null 。 |
projection | String :要放入光标的列列表。如果null 提供一组默认列。 |
queryArgs | Bundle :包含操作所需的附加信息的 Bundle。参数可能包括 SQL 样式参数,例如,但请注意,每个单独提供程序的文档将指示它们支持哪些参数。这个值可能是。ContentResolver#QUERY_ARG_SQL_LIMIT null |
cancellationSignal | CancellationSignal : 取消正在进行的操作的信号,或null . |
六个参数:
public Cursor query (Uri uri,
String[] projection,
String selection,
String[] selectionArgs,
String sortOrder,
CancellationSignal cancellationSignal)
参数 | |
---|---|
uri | Uri : 要查询的 URI。这将是客户端发送的完整 URI;如果客户端请求特定记录,URI 将以记录号结尾,实现应该解析并添加到 WHERE 或 HAVING 子句,指定 _id 值。该值不能为null 。 |
projection | String :要放入光标的列列表。如果 null 包含所有列。 |
selection | String :过滤行时应用的选择标准。如果null 然后包括所有行。 |
selectionArgs | String :您可以在选择中包含 ?s,它将被 selectionArgs 中的值替换,以便它们出现在选择中。这些值将绑定为字符串。这个值可能是null 。 |
sortOrder | String : 游标中的行应该如何排序。如果null 那么提供者可以自由定义排序顺序。 |
cancellationSignal | CancellationSignal :取消正在进行的操作的信号,或者null 如果没有。如果操作被取消,那么OperationCanceledException 将在执行查询时抛出。 |
public abstract Cursor query (Uri uri,
String[] projection,
String selection,
String[] selectionArgs,
String sortOrder)
参数 | |
---|---|
uri | Uri : 要查询的 URI。这将是客户端发送的完整 URI;如果客户端请求特定记录,URI 将以记录号结尾,实现应该解析并添加到 WHERE 或 HAVING 子句,指定 _id 值。该值不能为null 。 |
projection | String :要放入光标的列列表。如果 null 包含所有列。 |
selection | String :过滤行时应用的选择标准。如果null 然后包括所有行。 |
selectionArgs | String :您可以在选择中包含 ?s,它将被 selectionArgs 中的值替换,以便它们出现在选择中。这些值将绑定为字符串。这个值可能是null 。 |
sortOrder | String : 游标中的行应该如何排序。如果null 那么提供者可以自由定义排序顺序。 |
insert 插入
两个参数:
public abstract Uri insert (Uri uri,
ContentValues values)
参数 | |
---|---|
uri | Uri : 插入请求的 content:// URI。该值不能为null 。 |
values | ContentValues :要添加到数据库的一组列名/值对。这个值可能是null 。 |
三个参数:
public Uri insert (Uri uri,
ContentValues values,
Bundle extras)
参数 | |
---|---|
uri | Uri : 插入请求的 content:// URI。该值不能为null 。 |
values | ContentValues :要添加到数据库的一组列名/值对。这个值可能是null 。 |
extras | Bundle :包含操作所需的附加信息的 Bundle。参数可能包括 SQL 样式参数,例如,但请注意,每个单独提供程序的文档将指示它们支持哪些参数。这个值可能是。ContentResolver#QUERY_ARG_SQL_LIMIT null |
update 更新
三个参数:
public int update (Uri uri,
ContentValues values,
Bundle extras)
参数 | |
---|---|
uri | Uri : 要查询的 URI。如果这是对特定记录的更新请求,则它可能具有记录 ID。该值不能为null 。 |
values | ContentValues :要在数据库中更新的一组列名/值对。这个值可能是null 。 |
extras | Bundle :包含操作所需的附加信息的 Bundle。参数可能包括 SQL 样式参数,例如,但请注意,每个单独提供程序的文档将指示它们支持哪些参数。这个值可能是。ContentResolver#QUERY_ARG_SQL_LIMIT null |
四个参数:
public abstract int update (Uri uri,
ContentValues values,
String selection,
String[] selectionArgs)
参数 | |
---|---|
uri | Uri : 要查询的 URI。如果这是对特定记录的更新请求,则它可能具有记录 ID。该值不能为null 。 |
values | ContentValues :要在数据库中更新的一组列名/值对。这个值可能是null 。 |
selection | String :一个可选的过滤器来匹配要更新的行。这个值可能是null 。 |
selectionArgs | String : 这个值可能是null 。 |
delete 删除
public int delete (Uri uri,
Bundle extras)
参数 | |
---|---|
uri | Uri :要查询的完整 URI,包括行 ID(如果请求特定记录)。该值不能为null 。 |
extras | Bundle :包含操作所需的附加信息的 Bundle。参数可能包括 SQL 样式参数,例如,但请注意,每个单独提供程序的文档将指示它们支持哪些参数。这个值可能是。ContentResolver#QUERY_ARG_SQL_LIMIT null |
getType 获取类型
public abstract String getType (Uri uri)
参数 | |
---|---|
uri | Uri : 要查询的 URI。该值不能为null 。 |
清单列表:
android:enabled="true" //启用外部访问开关
android:exported="true" //允许外部进行访问
<provider
android:name=".DatabaseProvider"
android:authorities="com.example.databasetest.provider"
android:enabled="true"
android:exported="true"></provider>
示例代码
(一)、内容提供者部分
类:DatabaseProvider
public class DatabaseProvider extends ContentProvider {
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, "student", 0);
//查询单行
uriMatcher.addURI(AUTHORITY, "student/#", 1);
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// Implement this to handle requests to delete one or more rows.
SQLiteDatabase db = dbHelper.getWritableDatabase();
int deleteRows = 0;
switch (uriMatcher.match(uri)) {
case 0:
deleteRows = db.delete("Student", selection, selectionArgs);
break;
case 1:
String studentId = uri.getPathSegments().get(1);
deleteRows = db.delete("Student", "id=?", new String[]{studentId});
break;
default:
break;
}
return deleteRows;
//throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public String getType(Uri uri) {
//content://com.example.app.provider/table/#
//该方法用于获取Uri对象所对应的MIME类型
// TODO: Implement this to handle requests for the MIME type of the data
// at the given URI.
switch (uriMatcher.match(uri)) {
case 0:
return "vnd.android.cursor.dir/vnd.com.example.databasetest.provider.student";
case 1:
return "vnd.android.cursor.item/vnd.com.example.databasetest.provider.student";
}
//throw new UnsupportedOperationException("Not yet implemented");
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
// TODO: Implement this to handle requests to insert a new row.
SQLiteDatabase db = dbHelper.getWritableDatabase();
Uri uriReturn = null;
switch (uriMatcher.match(uri)) {
case 0:
case 1:
long newStudentId = db.insert("Student", null, values);
uriReturn = Uri.parse("content://" + AUTHORITY + "/student/" + newStudentId);
break;
default:
break;
}
//throw new UnsupportedOperationException("Not yet implemented");
return uriReturn;
}
@Override
public boolean onCreate() {
// TODO: Implement this to initialize your content provider on startup.
dbHelper = new MyDatabaseHelper(getContext(), "StudentStore.db", null, 1);
return true;
}
@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 = dbHelper.getReadableDatabase();
Cursor cursor = null;
switch (uriMatcher.match(uri)) {
case 0:
cursor = db.query("Student", projection, selection, selectionArgs, null, null, sortOrder);
break;
case 1:
String studentId = uri.getPathSegments().get(1);
cursor = db.query("Student", projection, "id=?", new String[]{studentId}, null, null, sortOrder);
break;
default:
break;
}
//throw new UnsupportedOperationException("Not yet implemented");
return cursor;
}
@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 = dbHelper.getWritableDatabase();
int updateRows = 0;
switch (uriMatcher.match(uri)) {
case 0:
updateRows = db.update("Student", values, selection, selectionArgs);
break;
case 1:
String studentId = uri.getPathSegments().get(1);
updateRows = db.update("Student", values, "id=?", new String[]{studentId});
break;
default:
break;
}
return updateRows;
//throw new UnsupportedOperationException("Not yet implemented");
}
}
类:MyDatabaseHelper
public class MyDatabaseHelper extends SQLiteOpenHelper {
public static final String CREAT_Student="create table Student ("
+"id integer primary key autoincrement,"
+"name text,"
+"number text)";
private Context mContext;
public MyDatabaseHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
super(context, name, factory, version);
mContext=context;
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREAT_Student);
//Toast.makeText(mContext,"Creat succeeded",Toast.LENGTH_SHORT);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
类:MainActivity
public class MainActivity extends AppCompatActivity {
private MyDatabaseHelper dbHelper;
//private MyDatabaseHelper dbHelper1;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SQLiteStudioService.instance().start(this);
dbHelper = new MyDatabaseHelper(this, "StudentStore.db", null, 1);
//dbHelper1=new MyDatabaseHelper(this,"Book.db",null,1);
Button creatDatabase = (Button) findViewById(R.id.creat_database);
creatDatabase.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
dbHelper.getWritableDatabase();
//dbHelper1.getWritableDatabase();
}
});
Button addData = (Button) findViewById(R.id.add_data);
addData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("name", "Zhangsan");
values.put("number", "20200513");
db.insert("Student", null, values);
values.clear();
values.put("name", "Lisi");
values.put("number", "20200514");
db.insert("Student", null, values);
}
});
Button queryButton = (Button) findViewById(R.id.query_data);
queryButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SQLiteDatabase db = dbHelper.getWritableDatabase();
Cursor cursor = db.query("Student", null, null, null, null, null, null);
if (cursor.moveToFirst()) {
do {
String name = cursor.getString(cursor.getColumnIndex("name"));
String number = cursor.getString(cursor.getColumnIndex("number"));
Log.d("MainAvtivity", "name: " + name + ",number:" + number);
} while (cursor.moveToNext());
}
cursor.close();
}
});
}
}
布局文件:activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<Button
android:id="@+id/creat_database"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Creat database"/>
<Button
android:id="@+id/add_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Add data"/>
<Button
android:id="@+id/query_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Query data"/>
</LinearLayout>
(二)、外部访问内容提供者部分:
类:MainActivity
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
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 View.OnClickListener() {
@Override
public void onClick(View v) {
//com.example.databasetest.provider
Uri uri = Uri.parse("content://com.example.databasetest.provider/student");
ContentValues values = new ContentValues();
values.put("name", "新增名字1");
values.put("number", "20200515");
Uri newUri = getContentResolver().insert(uri, values);
newId = newUri.getPathSegments().get(1);
}
});
Button queryButton = (Button) findViewById(R.id.query_data);
queryButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Uri uri = Uri.parse("content://com.example.databasetest.provider/student");
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
if (cursor != null) {
while (cursor.moveToNext()) {
String name = cursor.getString(cursor.getColumnIndex("name"));
String number = cursor.getString(cursor.getColumnIndex("number"));
Log.d("MainAvtivity", "name: " + name + ", number: " + number);
}
}
cursor.close();
}
});
Button updateData = (Button) findViewById(R.id.updata_data);
updateData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Uri uri = Uri.parse("content://com.example.databasetest.provider/student/" + newId);
ContentValues values = new ContentValues();
values.put("name", "替换掉新增数据");
getContentResolver().update(uri, values, null, null);
}
});
Button deleteData = (Button) findViewById(R.id.delete_data);
deleteData.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Uri uri = Uri.parse("content://com.example.databasetest.provider/student/" + newId);
getContentResolver().delete(uri, null, null);
}
});
}
}
布局:activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<Button
android:id="@+id/add_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Add to Student"/>
<Button
android:id="@+id/query_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Query from Student"/>
<Button
android:id="@+id/updata_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Updata Student"/>
<Button
android:id="@+id/delete_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Delete from Student"/>
</LinearLayout>
内容提供者源码码云地址https://gitee.com/baipenggui/database-test
内容提供者,被外部访问的源码码云地址https://gitee.com/baipenggui/provider-test.git
百度云网盘,提取码:ndbzhttps://pan.baidu.com/s/1IyUcylOkriyRaQZmLtzVTg