📌  相关文章
📜  Android中的内容提供者(带有示例)

📅  最后修改于: 2021-05-09 17:38:36             🧑  作者: Mango

在Android中,内容提供者是一个非常重要的组件,可用于关系数据库存储应用程序数据的目的。内容提供者在android系统中的作用就像一个中央存储库,用于存储应用程序的数据,它可以方便其他应用程序根据用户要求安全地访问和修改该数据。 Android系统允许内容提供商以几种方式存储应用程序数据。用户可以通过将应用程序数据存储在SQLite数据库,文件或什至网络中来存储图像,音频,视频和个人联系信息等应用程序数据。为了共享数据,内容提供者具有某些权限,这些权限用于向其他应用程序授予或限制权限以干扰数据。

内容提供商

内容URI

内容URI(统一资源标识符)是内容提供者的关键概念。要从内容提供者访问数据,URI用作查询字符串。

内容URI不同部分的详细信息:

  • content:// – URI的必需部分,因为它表示给定的URI是内容URI。
  • 权限–表示内容提供者的名称,例如联系人,浏览器等。这部分对于每个内容提供者都必须是唯一的。
  • optionalPath –指定内容提供者提供的数据类型。这是必不可少的,因为这部分帮助内容提供者支持彼此不相关的不同类型的数据,例如音频和视频文件。
  • optionalID –是一个数字值,在需要访问特定记录时使用。

如果在URI中提到ID,则它是基于ID的URI,否则为基于目录的URI。

内容提供者中的操作

Content Provider中可能有四个基本操作,即CreateReadUpdateDelete 。这些操作通常称为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.

例子

内容提供者的主要目的是充当数据的中央存储库,用户可以在其中存储和获取数据。该存储库的访问权也以安全的方式提供给其他应用程序,以便满足用户的不同需求。以下是实现内容提供程序所涉及的步骤。在该内容提供者中,用户可以存储人员的姓名并可以获取存储的数据。此外,另一个应用程序还可以访问存储的数据并可以显示数据。

创建内容提供者:

步骤1:创建一个新项目

  1. 单击文件,然后单击新建=>新建项目。
  2. 选择语言作为Java/ Kotlin。
  3. 选择空的活动作为模板
  4. 根据需要选择最小的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类

  1. 单击文件,然后单击新建=>其他=> ContentProvider。
  2. 命名ContentProvider
  3. 定义权限(可以是任何东西,例如“ com.demo.user.provider” )
  4. 选择导出启用选项
  5. 选择语言为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布局

一个TextviewEditText字段,两个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:创建一个新项目

  1. 单击文件,然后单击新建=>新建项目。
  2. 选择语言作为Java/ Kotlin。
  3. 选择空的活动作为模板
  4. 根据需要选择最小的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"
        }
    }
}

输出:在模拟器上运行

想要一个节奏更快,更具竞争性的环境来学习Android的基础知识吗?
单击此处,前往由我们的专家精心策划的指南,以使您立即做好行业准备!