En Android , los proveedores de contenido son un componente muy importante que cumple el propósito de una base de datos relacional para almacenar los datos de las aplicaciones. El papel del proveedor de contenido en el sistema Android es como un depósito central en el que se almacenan los datos de las aplicaciones, y facilita que otras aplicaciones accedan de forma segura y modifiquen esos datos según los requisitos del usuario. El sistema Android permite que el proveedor de contenido almacene los datos de la aplicación de varias maneras. Los usuarios pueden almacenar los datos de la aplicación, como imágenes, audio, videos e información de contacto personal, almacenándolos en la base de datos SQLite , en archivos o incluso en una red.. Para compartir los datos, los proveedores de contenido tienen ciertos permisos que se utilizan para otorgar o restringir los derechos a otras aplicaciones para interferir con los datos.
URI de contenido
El URI de contenido (Identificador uniforme de recursos) es el concepto clave de los proveedores de contenido. Para acceder a los datos de un proveedor de contenido, se utiliza URI como string de consulta.
Estructura de un URI de contenido: contenido://autoridad/rutaopcional/IDopcional
Detalles de las diferentes partes del URI de contenido:
- content://: parte obligatoria del URI, ya que representa que el URI proporcionado es un URI de contenido.
- autoridad: significa el nombre del proveedor de contenido, como contactos, navegador, etc. Esta parte debe ser única para cada proveedor de contenido.
- OptionalPath: especifica el tipo de datos proporcionados por el proveedor de contenido. Es esencial ya que esta parte ayuda a los proveedores de contenido a admitir diferentes tipos de datos que no están relacionados entre sí, como archivos de audio y video.
- ID opcional: es un valor numérico que se utiliza cuando existe la necesidad de acceder a un registro en particular.
Si se menciona un ID en un URI, entonces es un URI basado en ID; de lo contrario, es un URI basado en directorio.
Operaciones en el proveedor de contenido
Cuatro operaciones fundamentales son posibles en el Proveedor de contenido: Crear , Leer , Actualizar y Eliminar . Estas operaciones a menudo se denominan operaciones CRUD .
- Crear: Operación para crear datos en un proveedor de contenido.
- Lectura: se utiliza para obtener datos de un proveedor de contenido.
- Actualizar: Para modificar datos existentes.
- Eliminar: para eliminar los datos existentes del almacenamiento.
Funcionamiento del proveedor de contenido
Los componentes de la interfaz de usuario de las aplicaciones de Android, como Actividad y Fragmentos , usan un objeto CursorLoader para enviar requests de consulta a ContentResolver. El objeto ContentResolver envía requests (como crear, leer, actualizar y eliminar) al ContentProvider como cliente. Después de recibir una solicitud, ContentProvider la procesa y devuelve el resultado deseado. A continuación se muestra un diagrama para representar estos procesos en forma pictórica.
Creación de un proveedor de contenido
Los siguientes son los pasos que es esencial seguir para crear un proveedor de contenido:
- Cree una clase en el mismo directorio donde reside el archivo MainActivity y esta clase debe extender la clase base ContentProvider.
- Para acceder al contenido, defina una dirección URI del proveedor de contenido.
- Cree una base de datos para almacenar los datos de la aplicación.
- Implemente los seis métodos abstractos de la clase ContentProvider.
- Registre el proveedor de contenido en el archivo AndroidManifest.xml usando la etiqueta <provider> .
Los siguientes son los seis métodos abstractos y su descripción que son esenciales para anular como parte de la clase ContenProvider:
Método abstracto |
Descripción |
---|---|
consulta() |
Un método que acepta argumentos y obtiene los datos del mesa deseada. Los datos se retiran como un objeto de cursor. |
insertar() |
Para insertar una nueva fila en la base de datos del proveedor de contenido. Devuelve el URI de contenido de la fila insertada. |
actualizar() |
Este método se utiliza para actualizar los campos de una fila existente. Devuelve el número de filas actualizadas. |
Eliminar() |
Este método se utiliza para eliminar las filas existentes. Devuelve el número de filas eliminadas. |
obtenerTipo() |
Este método devuelve la extensión de correo de Internet multipropósito (MIME) tipo de datos al URI de contenido dado. |
enCrear() |
A medida que se crea el proveedor de contenido, el sistema Android llama este método inmediatamente para inicializar el proveedor. |
Ejemplo
El propósito principal de un proveedor de contenido es servir como depósito central de datos donde los usuarios pueden almacenar y obtener los datos. El acceso a este repositorio se da también a otras aplicaciones pero de manera segura para atender los diferentes requerimientos del usuario. Los siguientes son los pasos involucrados en la implementación de un proveedor de contenido. En este proveedor de contenido, el usuario puede almacenar el nombre de las personas y puede obtener los datos almacenados. Además, otra aplicación también puede acceder a los datos almacenados y mostrar los datos.
Nota: Los siguientes pasos se realizan en Android Studio versión 4.0
Creación de un proveedor de contenido:
Paso 1: Crear un nuevo proyecto
- Haga clic en Archivo, luego en Nuevo => Nuevo proyecto.
- Seleccione el idioma como Java/Kotlin.
- Elija una actividad vacía como plantilla
- Seleccione el SDK mínimo según su necesidad.
Paso 2: Modifique el archivo strings.xml
Todas las strings utilizadas en la actividad se almacenan aquí.
XML
<resources> <string name="app_name">Content_Provider_In_Android</string> <string name="hintText">Enter User Name</string> <string name="heading">Content Provider In Android</string> <string name="insertButtontext">Insert Data</string> <string name="loadButtonText">Load Data</string> </resources>
Paso 3: crear la clase de proveedor de contenido
- Haga clic en Archivo, luego en Nuevo => Otro => Proveedor de contenido.
- Asigne un nombre al proveedor de contenido
- Defina autoridad (puede ser cualquier cosa, por ejemplo , «com.demo.user.provider» )
- Seleccione la opción Exportado y Habilitado
- Elija el idioma como Java/Kotlin
Esta clase amplía la clase base ContentProvider y anula los seis métodos abstractos. A continuación se muestra el código completo para definir un proveedor de contenido.
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<String, String> 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<String, String>? = 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<String>?, selection: String?, selectionArgs: Array<String>?, 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<String>? ): 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<String>? ): 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) } } }
Paso 4: Diseñe el diseño activity_main.xml
Se agregará una vista de texto, un campo de texto de edición, dos botones y una vista de texto para mostrar los datos almacenados en la actividad usando el siguiente código.
XML
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout 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:background="#168BC34A" tools:context=".MainActivity"> <LinearLayout android:id="@+id/linearLayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:orientation="vertical" app:layout_constraintBottom_toTopOf="@+id/imageView" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.13" tools:ignore="MissingConstraints"> <TextView android:id="@+id/textView1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="40dp" android:layout_marginBottom="70dp" android:fontFamily="@font/roboto" android:text="@string/heading" android:textAlignment="center" android:textAppearance="@style/TextAppearance.AppCompat.Large" android:textColor="@android:color/holo_green_dark" android:textSize="36sp" android:textStyle="bold" /> <EditText android:id="@+id/textName" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="20dp" android:layout_marginEnd="20dp" android:layout_marginBottom="40dp" android:fontFamily="@font/roboto" android:hint="@string/hintText" /> <Button android:id="@+id/insertButton" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginStart="20dp" android:layout_marginTop="10dp" android:layout_marginEnd="20dp" android:layout_marginBottom="20dp" android:background="#4CAF50" android:fontFamily="@font/roboto" android:onClick="onClickAddDetails" android:text="@string/insertButtontext" android:textAlignment="center" android:textAppearance="@style/TextAppearance.AppCompat.Display1" android:textColor="#FFFFFF" android:textStyle="bold" /> <Button android:id="@+id/loadButton" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginStart="20dp" android:layout_marginTop="10dp" android:layout_marginEnd="20dp" android:layout_marginBottom="20dp" android:background="#4CAF50" android:fontFamily="@font/roboto" android:onClick="onClickShowDetails" android:text="@string/loadButtonText" android:textAlignment="center" android:textAppearance="@style/TextAppearance.AppCompat.Display1" android:textColor="#FFFFFF" android:textStyle="bold" /> <TextView android:id="@+id/res" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="20dp" android:layout_marginEnd="20dp" android:clickable="false" android:ems="10" android:fontFamily="@font/roboto" android:textColor="@android:color/holo_green_dark" android:textSize="18sp" android:textStyle="bold" /> </LinearLayout> <ImageView android:id="@+id/imageView" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:srcCompat="@drawable/banner" /> </androidx.constraintlayout.widget.ConstraintLayout>
Paso 5: Modificar el archivo MainActivity
Las funcionalidades de los botones se definirán en este archivo. Además, aquí se menciona la consulta que se realizará al insertar y obtener los datos. A continuación se muestra el código completo.
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<View>(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<View>(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" } } }
Paso 6: Modifique el archivo AndroidManifest
El archivo AndroidManifest debe contener el nombre del proveedor de contenido, las autoridades y los permisos que permiten que otras aplicaciones accedan al proveedor de contenido.
XML
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.content_provider_in_android"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <provider android:name="com.example.contentprovidersinandroid.MyContentProvider" android:authorities="com.demo.user.provider" android:enabled="true" android:exported="true"></provider> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <meta-data android:name="preloaded_fonts" android:resource="@array/preloaded_fonts" /> </application> </manifest>
Crear otra aplicación para acceder al Proveedor de contenido:
Paso 1: Crear un nuevo Proyecto
- Haga clic en Archivo, luego en Nuevo => Nuevo proyecto.
- Seleccione el idioma como Java/Kotlin.
- Elija una actividad vacía como plantilla
- Seleccione el SDK mínimo según su necesidad.
Paso 2: Modificar el archivo strings.xml
Todas las strings utilizadas en la actividad se almacenan en este archivo.
XML
<resources> <string name="app_name">Accessing_Content_Provider</string> <string name="heading">Accessing data of Content Provider</string> <string name="loadButtonText">Load Data</string> </resources>
Paso 3: Diseño del diseño ctivity_main.xml
Se agregan dos TextView en la actividad, uno para el encabezado y otro para mostrar los datos almacenados en un proveedor de contenido. También se agrega un botón para recibir el comando para mostrar datos. A continuación se muestra el código para implementar este diseño.
XML
<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout 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:background="#168BC34A" tools:context=".MainActivity"> <LinearLayout android:id="@+id/linearLayout" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_centerVertical="true" android:orientation="vertical" app:layout_constraintBottom_toTopOf="@+id/imageView" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintVertical_bias="0.13" tools:ignore="MissingConstraints"> <TextView android:id="@+id/textView1" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="40dp" android:layout_marginBottom="70dp" android:fontFamily="@font/roboto" android:text="@string/heading" android:textAlignment="center" android:textAppearance="@style/TextAppearance.AppCompat.Large" android:textColor="@android:color/holo_green_dark" android:textSize="36sp" android:textStyle="bold" /> <Button android:id="@+id/loadButton" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_marginStart="20dp" android:layout_marginTop="10dp" android:layout_marginEnd="20dp" android:layout_marginBottom="20dp" android:background="#4CAF50" android:fontFamily="@font/roboto" android:onClick="onClickShowDetails" android:text="@string/loadButtonText" android:textAlignment="center" android:textAppearance="@style/TextAppearance.AppCompat.Display1" android:textColor="#FFFFFF" android:textStyle="bold" /> <TextView android:id="@+id/res" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="20dp" android:layout_marginEnd="20dp" android:clickable="false" android:ems="10" android:fontFamily="@font/roboto" android:textColor="@android:color/holo_green_dark" android:textSize="18sp" android:textStyle="bold" /> </LinearLayout> <ImageView android:id="@+id/imageView" android:layout_width="wrap_content" android:layout_height="wrap_content" app:layout_constraintBottom_toBottomOf="parent" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:srcCompat="@drawable/banner" /> </androidx.constraintlayout.widget.ConstraintLayout>
Paso 4: Modificar el archivo MainActivity
El ContentURI de la aplicación anterior se menciona aquí y las mismas funciones que se usaron en la aplicación anterior para mostrar los registros también se usarán aquí. A continuación se muestra el código completo:
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<View>(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" } } }
Salida: ejecutar en el emulador
Publicación traducida automáticamente
Artículo escrito por RISHU_MISHRA y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA