在Android中,内容提供者是一个非常重要的组件,可用于关系数据库存储应用程序数据的目的。内容提供者在android系统中的作用就像一个中央存储库,用于存储应用程序的数据,它可以方便其他应用程序根据用户要求安全地访问和修改该数据。 Android系统允许内容提供商以几种方式存储应用程序数据。用户可以通过将应用程序数据存储在SQLite数据库,文件或什至网络中来存储图像,音频,视频和个人联系信息等应用程序数据。为了共享数据,内容提供者具有某些权限,这些权限用于向其他应用程序授予或限制权限以干扰数据。
内容URI
内容URI(统一资源标识符)是内容提供者的关键概念。要从内容提供者访问数据,URI用作查询字符串。
Structure of a Content URI: content://authority/optionalPath/optionalID
内容URI不同部分的详细信息:
- content:// – URI的必需部分,因为它表示给定的URI是内容URI。
- 权限–表示内容提供者的名称,例如联系人,浏览器等。这部分对于每个内容提供者都必须是唯一的。
- optionalPath –指定内容提供者提供的数据类型。这是必不可少的,因为这部分帮助内容提供者支持彼此不相关的不同类型的数据,例如音频和视频文件。
- optionalID –是一个数字值,在需要访问特定记录时使用。
如果在URI中提到ID,则它是基于ID的URI,否则为基于目录的URI。
内容提供者中的操作
Content Provider中可能有四个基本操作,即Create , Read , Update和Delete 。这些操作通常称为CRUD操作。
- 创建:在内容提供者中创建数据的操作。
- 读取:用于从内容提供商获取数据。
- 更新:修改现有数据。
- 删除:从存储中删除现有数据。
内容提供商的工作
诸如“活动”和“片段”之类的android应用程序的UI组件使用对象CursorLoader将查询请求发送到ContentResolver。 ContentResolver对象将请求(例如创建,读取,更新和删除)作为客户端发送到ContentProvider 。收到请求后,ContentProvider对其进行处理并返回所需的结果。下图以图形形式表示了这些过程。
创建内容提供者
以下是创建内容提供者必须遵循的步骤:
- 在MainActivity文件所在的同一目录中创建一个类,并且该类必须扩展ContentProvider基类。
- 要访问内容,请定义内容提供者URI地址。
- 创建一个数据库来存储应用程序数据。
- 实现ContentProvider类的六个抽象方法。
- 使用
标签 在AndroidManifest.xml文件中注册内容提供者。
以下是六个抽象方法及其描述,它们是作为ContenProvider类的一部分重写的必不可少的:
Abstract Method |
Description |
---|---|
query() |
A method that accepts arguments and fetches the data from the desired table. Data is retired as a cursor object. |
insert() |
To insert a new row in the database of the content provider. It returns the content URI of the inserted row. |
update() |
This method is used to update the fields of an existing row. It returns the number of rows updated. |
delete() |
This method is used to delete the existing rows. It returns the number of rows deleted. |
getType() |
This method returns the Multipurpose Internet Mail Extension(MIME) type of data to the given Content URI. |
onCreate() |
As the content provider is created, the android system calls this method immediately to initialise the provider. |
例子
内容提供者的主要目的是充当数据的中央存储库,用户可以在其中存储和获取数据。该存储库的访问权也以安全的方式提供给其他应用程序,以便满足用户的不同需求。以下是实现内容提供程序所涉及的步骤。在该内容提供者中,用户可以存储人员的姓名并可以获取存储的数据。此外,另一个应用程序还可以访问存储的数据并可以显示数据。
Note: Following steps are performed on Android Studio version 4.0
创建内容提供者:
步骤1:创建一个新项目
- 单击文件,然后单击新建=>新建项目。
- 选择语言作为Java/ Kotlin。
- 选择空的活动作为模板
- 根据需要选择最小的SDK。
步骤2:修改字符串.xml文件
活动中使用的所有字符串都存储在这里。
XML
Content_Provider_In_Android
Enter User Name
Content Provider In Android
Insert Data
Load Data
Java
package com.example.contentprovidersinandroid;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import java.util.HashMap;
public class MyContentProvider extends ContentProvider {
public MyContentProvider() {
}
// defining authority so that other application can access it
static final String PROVIDER_NAME = "com.demo.user.provider";
// defining content URI
static final String URL = "content://" + PROVIDER_NAME + "/users";
// parsing the content URI
static final Uri CONTENT_URI = Uri.parse(URL);
static final String id = "id";
static final String name = "name";
static final int uriCode = 1;
static final UriMatcher uriMatcher;
private static HashMap values;
static {
// to match the content URI
// every time user access table under content provider
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
// to access whole table
uriMatcher.addURI(PROVIDER_NAME, "users", uriCode);
// to access a particular row
// of the table
uriMatcher.addURI(PROVIDER_NAME, "users/*", uriCode);
}
@Override
public String getType(Uri uri) {
switch (uriMatcher.match(uri)) {
case uriCode:
return "vnd.android.cursor.dir/users";
default:
throw new IllegalArgumentException("Unsupported URI: " + uri);
}
}
// creating the database
@Override
public boolean onCreate() {
Context context = getContext();
DatabaseHelper dbHelper = new DatabaseHelper(context);
db = dbHelper.getWritableDatabase();
if (db != null) {
return true;
}
return false;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables(TABLE_NAME);
switch (uriMatcher.match(uri)) {
case uriCode:
qb.setProjectionMap(values);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
if (sortOrder == null || sortOrder == "") {
sortOrder = id;
}
Cursor c = qb.query(db, projection, selection, selectionArgs, null,
null, sortOrder);
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}
// adding data to the database
@Override
public Uri insert(Uri uri, ContentValues values) {
long rowID = db.insert(TABLE_NAME, "", values);
if (rowID > 0) {
Uri _uri = ContentUris.withAppendedId(CONTENT_URI, rowID);
getContext().getContentResolver().notifyChange(_uri, null);
return _uri;
}
throw new SQLiteException("Failed to add a record into " + uri);
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
int count = 0;
switch (uriMatcher.match(uri)) {
case uriCode:
count = db.update(TABLE_NAME, values, selection, selectionArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int count = 0;
switch (uriMatcher.match(uri)) {
case uriCode:
count = db.delete(TABLE_NAME, selection, selectionArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
// creating object of database
// to perform query
private SQLiteDatabase db;
// declaring name of the database
static final String DATABASE_NAME = "UserDB";
// declaring table name of the database
static final String TABLE_NAME = "Users";
// declaring version of the database
static final int DATABASE_VERSION = 1;
// sql query to create the table
static final String CREATE_DB_TABLE = " CREATE TABLE " + TABLE_NAME
+ " (id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ " name TEXT NOT NULL);";
// creating a database
private static class DatabaseHelper extends SQLiteOpenHelper {
// defining a constructor
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
// creating a table in the database
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_DB_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// sql query to drop a table
// having similar name
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
}
}
Kotlin
package com.example.contentprovidersinandroid
import android.content.*
import android.database.Cursor
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteException
import android.database.sqlite.SQLiteOpenHelper
import android.database.sqlite.SQLiteQueryBuilder
import android.net.Uri
class MyContentProvider : ContentProvider() {
companion object {
// defining authority so that other application can access it
const val PROVIDER_NAME = "com.demo.user.provider"
// defining content URI
const val URL = "content://$PROVIDER_NAME/users"
// parsing the content URI
val CONTENT_URI = Uri.parse(URL)
const val id = "id"
const val name = "name"
const val uriCode = 1
var uriMatcher: UriMatcher? = null
private val values: HashMap? = null
// declaring name of the database
const val DATABASE_NAME = "UserDB"
// declaring table name of the database
const val TABLE_NAME = "Users"
// declaring version of the database
const val DATABASE_VERSION = 1
// sql query to create the table
const val CREATE_DB_TABLE =
(" CREATE TABLE " + TABLE_NAME
+ " (id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ " name TEXT NOT NULL);")
init {
// to match the content URI
// every time user access table under content provider
uriMatcher = UriMatcher(UriMatcher.NO_MATCH)
// to access whole table
uriMatcher!!.addURI(
PROVIDER_NAME,
"users",
uriCode
)
// to access a particular row
// of the table
uriMatcher!!.addURI(
PROVIDER_NAME,
"users/*",
uriCode
)
}
}
override fun getType(uri: Uri): String? {
return when (uriMatcher!!.match(uri)) {
uriCode -> "vnd.android.cursor.dir/users"
else -> throw IllegalArgumentException("Unsupported URI: $uri")
}
}
// creating the database
override fun onCreate(): Boolean {
val context = context
val dbHelper =
DatabaseHelper(context)
db = dbHelper.writableDatabase
return if (db != null) {
true
} else false
}
override fun query(
uri: Uri, projection: Array?, selection: String?,
selectionArgs: Array?, sortOrder: String?
): Cursor? {
var sortOrder = sortOrder
val qb = SQLiteQueryBuilder()
qb.tables = TABLE_NAME
when (uriMatcher!!.match(uri)) {
uriCode -> qb.projectionMap = values
else -> throw IllegalArgumentException("Unknown URI $uri")
}
if (sortOrder == null || sortOrder === "") {
sortOrder = id
}
val c = qb.query(
db, projection, selection, selectionArgs, null,
null, sortOrder
)
c.setNotificationUri(context!!.contentResolver, uri)
return c
}
// adding data to the database
override fun insert(uri: Uri, values: ContentValues?): Uri? {
val rowID = db!!.insert(TABLE_NAME, "", values)
if (rowID > 0) {
val _uri =
ContentUris.withAppendedId(CONTENT_URI, rowID)
context!!.contentResolver.notifyChange(_uri, null)
return _uri
}
throw SQLiteException("Failed to add a record into $uri")
}
override fun update(
uri: Uri, values: ContentValues?, selection: String?,
selectionArgs: Array?
): Int {
var count = 0
count = when (uriMatcher!!.match(uri)) {
uriCode -> db!!.update(TABLE_NAME, values, selection, selectionArgs)
else -> throw IllegalArgumentException("Unknown URI $uri")
}
context!!.contentResolver.notifyChange(uri, null)
return count
}
override fun delete(
uri: Uri,
selection: String?,
selectionArgs: Array?
): Int {
var count = 0
count = when (uriMatcher!!.match(uri)) {
uriCode -> db!!.delete(TABLE_NAME, selection, selectionArgs)
else -> throw IllegalArgumentException("Unknown URI $uri")
}
context!!.contentResolver.notifyChange(uri, null)
return count
}
// creating object of database
// to perform query
private var db: SQLiteDatabase? = null
// creating a database
private class DatabaseHelper // defining a constructor
internal constructor(context: Context?) : SQLiteOpenHelper(
context,
DATABASE_NAME,
null,
DATABASE_VERSION
) {
// creating a table in the database
override fun onCreate(db: SQLiteDatabase) {
db.execSQL(CREATE_DB_TABLE)
}
override fun onUpgrade(
db: SQLiteDatabase,
oldVersion: Int,
newVersion: Int
) {
// sql query to drop a table
// having similar name
db.execSQL("DROP TABLE IF EXISTS $TABLE_NAME")
onCreate(db)
}
}
}
XML
Java
package com.example.contentprovidersinandroid;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
return true;
}
public void onClickAddDetails(View view) {
// class to add values in the database
ContentValues values = new ContentValues();
// fetching text from user
values.put(MyContentProvider.name, ((EditText) findViewById(R.id.textName)).getText().toString());
// inserting into database through content URI
getContentResolver().insert(MyContentProvider.CONTENT_URI, values);
// displaying a toast message
Toast.makeText(getBaseContext(), "New Record Inserted", Toast.LENGTH_LONG).show();
}
public void onClickShowDetails(View view) {
// inserting complete table details in this text field
TextView resultView= (TextView) findViewById(R.id.res);
// creating a cursor object of the
// content URI
Cursor cursor = getContentResolver().query(Uri.parse("content://com.demo.user.provider/users"), null, null, null, null);
// iteration of the cursor
// to print whole table
if(cursor.moveToFirst()) {
StringBuilder strBuild=new StringBuilder();
while (!cursor.isAfterLast()) {
strBuild.append("\n"+cursor.getString(cursor.getColumnIndex("id"))+ "-"+ cursor.getString(cursor.getColumnIndex("name")));
cursor.moveToNext();
}
resultView.setText(strBuild);
}
else {
resultView.setText("No Records Found");
}
}
}
Kotlin
package com.example.content_provider_in_android
import android.content.ContentValues
import android.content.Context
import android.net.Uri
import android.os.Bundle
import android.view.MotionEvent
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.example.contentprovidersinandroid.MyContentProvider
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
override fun onTouchEvent(event: MotionEvent?): Boolean {
val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(currentFocus!!.windowToken, 0)
return true
}
fun onClickAddDetails(view: View?) {
// class to add values in the database
val values = ContentValues()
// fetching text from user
values.put(MyContentProvider.name, (findViewById(R.id.textName) as EditText).text.toString())
// inserting into database through content URI
contentResolver.insert(MyContentProvider.CONTENT_URI, values)
// displaying a toast message
Toast.makeText(baseContext, "New Record Inserted", Toast.LENGTH_LONG).show()
}
fun onClickShowDetails(view: View?) {
// inserting complete table details in this text field
val resultView = findViewById(R.id.res) as TextView
// creating a cursor object of the
// content URI
val cursor = contentResolver.query(Uri.parse("content://com.demo.user.provider/users"), null, null, null, null)
// iteration of the cursor
// to print whole table
if (cursor!!.moveToFirst()) {
val strBuild = StringBuilder()
while (!cursor.isAfterLast) {
strBuild.append("""
${cursor.getString(cursor.getColumnIndex("id"))}-${cursor.getString(cursor.getColumnIndex("name"))}
""".trimIndent())
cursor.moveToNext()
}
resultView.text = strBuild
} else {
resultView.text = "No Records Found"
}
}
}
XML
XML
Accessing_Content_Provider
Accessing data of Content Provider
Load Data
XML
Java
package com.example.accessingcontentprovider;
import androidx.appcompat.app.AppCompatActivity;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
Uri CONTENT_URI = Uri.parse("content://com.demo.user.provider/users");
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void onClickShowDetails(View view) {
// inserting complete table details in this text field
TextView resultView= (TextView) findViewById(R.id.res);
// creating a cursor object of the
// content URI
Cursor cursor = getContentResolver().query(Uri.parse("content://com.demo.user.provider/users"), null, null, null, null);
// iteration of the cursor
// to print whole table
if(cursor.moveToFirst()) {
StringBuilder strBuild=new StringBuilder();
while (!cursor.isAfterLast()) {
strBuild.append("\n"+cursor.getString(cursor.getColumnIndex("id"))+ "-"+ cursor.getString(cursor.getColumnIndex("name")));
cursor.moveToNext();
}
resultView.setText(strBuild);
}
else {
resultView.setText("No Records Found");
}
}
}
Kotlin
package com.example.accessing_content_provider
import android.net.Uri
import android.os.Bundle
import android.view.View
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
var CONTENT_URI = Uri.parse("content://com.demo.user.provider/users")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
fun onClickShowDetails(view: View?) {
// inserting complete table details in this text field
val resultView = findViewById(R.id.res) as TextView
// creating a cursor object of the
// content URI
val cursor = contentResolver.query(Uri.parse("content://com.demo.user.provider/users"), null, null, null, null)
// iteration of the cursor
// to print whole table
if (cursor!!.moveToFirst()) {
val strBuild = StringBuilder()
while (!cursor.isAfterLast) {
strBuild.append("""
${cursor.getString(cursor.getColumnIndex("id"))}-${cursor.getString(cursor.getColumnIndex("name"))}
""".trimIndent())
cursor.moveToNext()
}
resultView.text = strBuild
} else {
resultView.text = "No Records Found"
}
}
}
步骤3:创建Content Provider类
- 单击文件,然后单击新建=>其他=> ContentProvider。
- 命名ContentProvider
- 定义权限(可以是任何东西,例如“ com.demo.user.provider” )
- 选择导出并启用选项
- 选择语言为Java/ Kotlin
此类扩展了ContentProvider基类,并覆盖了六个抽象方法。以下是定义内容提供者的完整代码。
Java
package com.example.contentprovidersinandroid;
import android.content.ContentProvider;
import android.content.ContentUris;
import android.content.ContentValues;
import android.content.Context;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteException;
import android.database.sqlite.SQLiteOpenHelper;
import android.database.sqlite.SQLiteQueryBuilder;
import android.net.Uri;
import java.util.HashMap;
public class MyContentProvider extends ContentProvider {
public MyContentProvider() {
}
// defining authority so that other application can access it
static final String PROVIDER_NAME = "com.demo.user.provider";
// defining content URI
static final String URL = "content://" + PROVIDER_NAME + "/users";
// parsing the content URI
static final Uri CONTENT_URI = Uri.parse(URL);
static final String id = "id";
static final String name = "name";
static final int uriCode = 1;
static final UriMatcher uriMatcher;
private static HashMap values;
static {
// to match the content URI
// every time user access table under content provider
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
// to access whole table
uriMatcher.addURI(PROVIDER_NAME, "users", uriCode);
// to access a particular row
// of the table
uriMatcher.addURI(PROVIDER_NAME, "users/*", uriCode);
}
@Override
public String getType(Uri uri) {
switch (uriMatcher.match(uri)) {
case uriCode:
return "vnd.android.cursor.dir/users";
default:
throw new IllegalArgumentException("Unsupported URI: " + uri);
}
}
// creating the database
@Override
public boolean onCreate() {
Context context = getContext();
DatabaseHelper dbHelper = new DatabaseHelper(context);
db = dbHelper.getWritableDatabase();
if (db != null) {
return true;
}
return false;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
qb.setTables(TABLE_NAME);
switch (uriMatcher.match(uri)) {
case uriCode:
qb.setProjectionMap(values);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
if (sortOrder == null || sortOrder == "") {
sortOrder = id;
}
Cursor c = qb.query(db, projection, selection, selectionArgs, null,
null, sortOrder);
c.setNotificationUri(getContext().getContentResolver(), uri);
return c;
}
// adding data to the database
@Override
public Uri insert(Uri uri, ContentValues values) {
long rowID = db.insert(TABLE_NAME, "", values);
if (rowID > 0) {
Uri _uri = ContentUris.withAppendedId(CONTENT_URI, rowID);
getContext().getContentResolver().notifyChange(_uri, null);
return _uri;
}
throw new SQLiteException("Failed to add a record into " + uri);
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
int count = 0;
switch (uriMatcher.match(uri)) {
case uriCode:
count = db.update(TABLE_NAME, values, selection, selectionArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
int count = 0;
switch (uriMatcher.match(uri)) {
case uriCode:
count = db.delete(TABLE_NAME, selection, selectionArgs);
break;
default:
throw new IllegalArgumentException("Unknown URI " + uri);
}
getContext().getContentResolver().notifyChange(uri, null);
return count;
}
// creating object of database
// to perform query
private SQLiteDatabase db;
// declaring name of the database
static final String DATABASE_NAME = "UserDB";
// declaring table name of the database
static final String TABLE_NAME = "Users";
// declaring version of the database
static final int DATABASE_VERSION = 1;
// sql query to create the table
static final String CREATE_DB_TABLE = " CREATE TABLE " + TABLE_NAME
+ " (id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ " name TEXT NOT NULL);";
// creating a database
private static class DatabaseHelper extends SQLiteOpenHelper {
// defining a constructor
DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
// creating a table in the database
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_DB_TABLE);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
// sql query to drop a table
// having similar name
db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
onCreate(db);
}
}
}
科特林
package com.example.contentprovidersinandroid
import android.content.*
import android.database.Cursor
import android.database.sqlite.SQLiteDatabase
import android.database.sqlite.SQLiteException
import android.database.sqlite.SQLiteOpenHelper
import android.database.sqlite.SQLiteQueryBuilder
import android.net.Uri
class MyContentProvider : ContentProvider() {
companion object {
// defining authority so that other application can access it
const val PROVIDER_NAME = "com.demo.user.provider"
// defining content URI
const val URL = "content://$PROVIDER_NAME/users"
// parsing the content URI
val CONTENT_URI = Uri.parse(URL)
const val id = "id"
const val name = "name"
const val uriCode = 1
var uriMatcher: UriMatcher? = null
private val values: HashMap? = null
// declaring name of the database
const val DATABASE_NAME = "UserDB"
// declaring table name of the database
const val TABLE_NAME = "Users"
// declaring version of the database
const val DATABASE_VERSION = 1
// sql query to create the table
const val CREATE_DB_TABLE =
(" CREATE TABLE " + TABLE_NAME
+ " (id INTEGER PRIMARY KEY AUTOINCREMENT, "
+ " name TEXT NOT NULL);")
init {
// to match the content URI
// every time user access table under content provider
uriMatcher = UriMatcher(UriMatcher.NO_MATCH)
// to access whole table
uriMatcher!!.addURI(
PROVIDER_NAME,
"users",
uriCode
)
// to access a particular row
// of the table
uriMatcher!!.addURI(
PROVIDER_NAME,
"users/*",
uriCode
)
}
}
override fun getType(uri: Uri): String? {
return when (uriMatcher!!.match(uri)) {
uriCode -> "vnd.android.cursor.dir/users"
else -> throw IllegalArgumentException("Unsupported URI: $uri")
}
}
// creating the database
override fun onCreate(): Boolean {
val context = context
val dbHelper =
DatabaseHelper(context)
db = dbHelper.writableDatabase
return if (db != null) {
true
} else false
}
override fun query(
uri: Uri, projection: Array?, selection: String?,
selectionArgs: Array?, sortOrder: String?
): Cursor? {
var sortOrder = sortOrder
val qb = SQLiteQueryBuilder()
qb.tables = TABLE_NAME
when (uriMatcher!!.match(uri)) {
uriCode -> qb.projectionMap = values
else -> throw IllegalArgumentException("Unknown URI $uri")
}
if (sortOrder == null || sortOrder === "") {
sortOrder = id
}
val c = qb.query(
db, projection, selection, selectionArgs, null,
null, sortOrder
)
c.setNotificationUri(context!!.contentResolver, uri)
return c
}
// adding data to the database
override fun insert(uri: Uri, values: ContentValues?): Uri? {
val rowID = db!!.insert(TABLE_NAME, "", values)
if (rowID > 0) {
val _uri =
ContentUris.withAppendedId(CONTENT_URI, rowID)
context!!.contentResolver.notifyChange(_uri, null)
return _uri
}
throw SQLiteException("Failed to add a record into $uri")
}
override fun update(
uri: Uri, values: ContentValues?, selection: String?,
selectionArgs: Array?
): Int {
var count = 0
count = when (uriMatcher!!.match(uri)) {
uriCode -> db!!.update(TABLE_NAME, values, selection, selectionArgs)
else -> throw IllegalArgumentException("Unknown URI $uri")
}
context!!.contentResolver.notifyChange(uri, null)
return count
}
override fun delete(
uri: Uri,
selection: String?,
selectionArgs: Array?
): Int {
var count = 0
count = when (uriMatcher!!.match(uri)) {
uriCode -> db!!.delete(TABLE_NAME, selection, selectionArgs)
else -> throw IllegalArgumentException("Unknown URI $uri")
}
context!!.contentResolver.notifyChange(uri, null)
return count
}
// creating object of database
// to perform query
private var db: SQLiteDatabase? = null
// creating a database
private class DatabaseHelper // defining a constructor
internal constructor(context: Context?) : SQLiteOpenHelper(
context,
DATABASE_NAME,
null,
DATABASE_VERSION
) {
// creating a table in the database
override fun onCreate(db: SQLiteDatabase) {
db.execSQL(CREATE_DB_TABLE)
}
override fun onUpgrade(
db: SQLiteDatabase,
oldVersion: Int,
newVersion: Int
) {
// sql query to drop a table
// having similar name
db.execSQL("DROP TABLE IF EXISTS $TABLE_NAME")
onCreate(db)
}
}
}
步骤4:设计activity_main.xml布局
一个Textview , EditText字段,两个Button , 并使用以下代码在活动中添加一个用于显示所存储数据的Textview 。
XML格式
步骤5:修改MainActivity文件
按钮功能将在此文件中定义。此外,这里提到在插入和获取数据时要执行的查询。以下是完整的代码。
Java
package com.example.contentprovidersinandroid;
import androidx.appcompat.app.AppCompatActivity;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onTouchEvent(MotionEvent event) {
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
return true;
}
public void onClickAddDetails(View view) {
// class to add values in the database
ContentValues values = new ContentValues();
// fetching text from user
values.put(MyContentProvider.name, ((EditText) findViewById(R.id.textName)).getText().toString());
// inserting into database through content URI
getContentResolver().insert(MyContentProvider.CONTENT_URI, values);
// displaying a toast message
Toast.makeText(getBaseContext(), "New Record Inserted", Toast.LENGTH_LONG).show();
}
public void onClickShowDetails(View view) {
// inserting complete table details in this text field
TextView resultView= (TextView) findViewById(R.id.res);
// creating a cursor object of the
// content URI
Cursor cursor = getContentResolver().query(Uri.parse("content://com.demo.user.provider/users"), null, null, null, null);
// iteration of the cursor
// to print whole table
if(cursor.moveToFirst()) {
StringBuilder strBuild=new StringBuilder();
while (!cursor.isAfterLast()) {
strBuild.append("\n"+cursor.getString(cursor.getColumnIndex("id"))+ "-"+ cursor.getString(cursor.getColumnIndex("name")));
cursor.moveToNext();
}
resultView.setText(strBuild);
}
else {
resultView.setText("No Records Found");
}
}
}
科特林
package com.example.content_provider_in_android
import android.content.ContentValues
import android.content.Context
import android.net.Uri
import android.os.Bundle
import android.view.MotionEvent
import android.view.View
import android.view.inputmethod.InputMethodManager
import android.widget.EditText
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import com.example.contentprovidersinandroid.MyContentProvider
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
override fun onTouchEvent(event: MotionEvent?): Boolean {
val imm = getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
imm.hideSoftInputFromWindow(currentFocus!!.windowToken, 0)
return true
}
fun onClickAddDetails(view: View?) {
// class to add values in the database
val values = ContentValues()
// fetching text from user
values.put(MyContentProvider.name, (findViewById(R.id.textName) as EditText).text.toString())
// inserting into database through content URI
contentResolver.insert(MyContentProvider.CONTENT_URI, values)
// displaying a toast message
Toast.makeText(baseContext, "New Record Inserted", Toast.LENGTH_LONG).show()
}
fun onClickShowDetails(view: View?) {
// inserting complete table details in this text field
val resultView = findViewById(R.id.res) as TextView
// creating a cursor object of the
// content URI
val cursor = contentResolver.query(Uri.parse("content://com.demo.user.provider/users"), null, null, null, null)
// iteration of the cursor
// to print whole table
if (cursor!!.moveToFirst()) {
val strBuild = StringBuilder()
while (!cursor.isAfterLast) {
strBuild.append("""
${cursor.getString(cursor.getColumnIndex("id"))}-${cursor.getString(cursor.getColumnIndex("name"))}
""".trimIndent())
cursor.moveToNext()
}
resultView.text = strBuild
} else {
resultView.text = "No Records Found"
}
}
}
步骤6:修改AndroidManifest文件
AndroidManifest文件必须包含内容提供者名称,权限和权限,以便其他应用程序可以访问该内容提供者。
XML格式
创建另一个应用程序以访问内容提供者:
步骤1:创建一个新项目
- 单击文件,然后单击新建=>新建项目。
- 选择语言作为Java/ Kotlin。
- 选择空的活动作为模板
- 根据需要选择最小的SDK。
步骤2:修改字符串.xml文件
活动中使用的所有字符串都存储在此文件中。
XML格式
Accessing_Content_Provider
Accessing data of Content Provider
Load Data
步骤3:设计ctivity_main.xml布局
在活动中添加了两个TextView,一个用于标题,另一个用于在内容提供者中显示存储的数据。还添加了一个按钮,以接收显示数据的命令。下面是实现此设计的代码。
XML格式
步骤4:修改MainActivity文件
这里提到了先前应用程序的ContentURI,并且这里还将使用与先前应用程序中用于显示记录的功能相同的功能。以下是完整的代码:
Java
package com.example.accessingcontentprovider;
import androidx.appcompat.app.AppCompatActivity;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
Uri CONTENT_URI = Uri.parse("content://com.demo.user.provider/users");
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void onClickShowDetails(View view) {
// inserting complete table details in this text field
TextView resultView= (TextView) findViewById(R.id.res);
// creating a cursor object of the
// content URI
Cursor cursor = getContentResolver().query(Uri.parse("content://com.demo.user.provider/users"), null, null, null, null);
// iteration of the cursor
// to print whole table
if(cursor.moveToFirst()) {
StringBuilder strBuild=new StringBuilder();
while (!cursor.isAfterLast()) {
strBuild.append("\n"+cursor.getString(cursor.getColumnIndex("id"))+ "-"+ cursor.getString(cursor.getColumnIndex("name")));
cursor.moveToNext();
}
resultView.setText(strBuild);
}
else {
resultView.setText("No Records Found");
}
}
}
科特林
package com.example.accessing_content_provider
import android.net.Uri
import android.os.Bundle
import android.view.View
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
class MainActivity : AppCompatActivity() {
var CONTENT_URI = Uri.parse("content://com.demo.user.provider/users")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
}
fun onClickShowDetails(view: View?) {
// inserting complete table details in this text field
val resultView = findViewById(R.id.res) as TextView
// creating a cursor object of the
// content URI
val cursor = contentResolver.query(Uri.parse("content://com.demo.user.provider/users"), null, null, null, null)
// iteration of the cursor
// to print whole table
if (cursor!!.moveToFirst()) {
val strBuild = StringBuilder()
while (!cursor.isAfterLast) {
strBuild.append("""
${cursor.getString(cursor.getColumnIndex("id"))}-${cursor.getString(cursor.getColumnIndex("name"))}
""".trimIndent())
cursor.moveToNext()
}
resultView.text = strBuild
} else {
resultView.text = "No Records Found"
}
}
}