Android - Fournisseur de contenu

1. Introduction

ContentProvider est principalement utilisé pour réaliser la fonction de partage de données entre différentes applications.Il fournit un ensemble complet de mécanismes qui permettent à un programme d'accéder aux données d'un autre programme, tout en assurant la sécurité des données accédées. Actuellement, l'utilisation de ContentProvider est le moyen standard pour Android de partager des données entre les programmes. ContentProvider peut choisir quelle partie des données partager uniquement, afin de s'assurer que les données privées de notre programme n'auront pas de risque de fuite.

1. Utilisation de base de ContentResolver

Pour chaque application, si vous souhaitez accéder aux données partagées dans le ContentProvider, vous devez utiliser la classe ContentResolver, et vous pouvez obtenir une instance de cette classe via la méthode getContentResolver() dans le Context . ContentResolver fournit une série de méthodes pour ajouter, supprimer, modifier et interroger des données. La méthode insert() est utilisée pour ajouter des données, la méthode update() est utilisée pour mettre à jour les données, la méthode delete() est utilisée pour supprimer des données, et la méthode query() Utilisée pour interroger les données. Y a-t-il une sensation de déjà-vu ? C'est vrai, ces méthodes sont également utilisées dans SQLiteDatabase pour effectuer des opérations d'ajout, de suppression, de modification et de requête, mais elles sont légèrement différentes dans les paramètres de méthode. Contrairement à SQLiteDatabase, les méthodes d'ajout, de suppression, de modification et de requête dans ContentResolver n'acceptent pas les paramètres de nom de table, mais utilisent à la place un paramètre Uri, appelé URI de contenu. L'URI de contenu établit un identifiant unique pour les données dans le ContentProvider, et il se compose principalement de deux parties : l'autorité et le chemin. L'autorité est utilisée pour distinguer différentes applications. Généralement, afin d'éviter les conflits, le nom du package d'application est utilisé pour la dénomination. Par exemple, si le nom de package d'une application est com.example.app, l'autorité correspondant à l'application peut être nommée com.example.app.provider. path est utilisé pour distinguer différentes tables dans la même application et est généralement ajouté après l'autorité. Par exemple, il existe deux tables table1 et table2 dans la base de données d'une application. À ce stade, vous pouvez nommer les chemins comme /table1 et /table2 respectivement, puis combiner l'autorité et le chemin, et l'URI de contenu devient com.example. app.provider/table1 et com.example.app.provider/table2. Cependant, il est encore difficile d'identifier ces deux chaînes comme deux URI de contenu.Nous devons également ajouter une déclaration de protocole à la tête de la chaîne. Par conséquent, le format le plus standard pour un URI de contenu est le suivant :

content://com.example.app.provider/table1 
content://com.example.app.provider/table2

Après avoir obtenu la chaîne URI de contenu, nous devons l'analyser dans un objet Uri avant de la transmettre en tant que paramètre. La méthode d'analyse est également assez simple, le code est le suivant :

val uri = Uri.parse("content://com.example.app.provider/table1")

2. utiliser

val cursor = contentResolver.query(
 uri,
 projection,
 selection,
 selectionArgs,
 sortOrder)

 Une fois la requête terminée, un objet Cursor est toujours renvoyé, puis nous pouvons lire les données de l'objet Cursor une par une. L'idée de lecture est toujours de parcourir toutes les lignes du curseur en déplaçant la position du curseur, puis d'aller chercher les données de la colonne correspondante dans chaque ligne, le code est le suivant :

 while (cursor.moveToNext()) { 
    val column1 = cursor.getString(cursor.getColumnIndex("column1")) 
    val column2 = cursor.getInt(cursor.getColumnIndex("column2")) 
} 
cursor.close()

Après avoir maîtrisé l'opération de requête la plus difficile, les opérations restantes d'ajout, de modification et de suppression sont encore plus faciles. Voyons d'abord comment ajouter une donnée à table1, le code est le suivant :

val values = contentValuesOf("column1" to "text", "column2" to 1) contentResolver.insert(uri, values)

On peut voir que les données à ajouter sont toujours assemblées dans ContentValues, puis la méthode insert() de ContentResolver est appelée, et les Uri et ContentValues ​​sont transmises en tant que paramètres.

Si nous voulons mettre à jour ces données nouvellement ajoutées et effacer la valeur de la colonne1, nous pouvons utiliser la méthode update() de ContentResolver. Le code est le suivant :

val values = contentValuesOf("column1" to "") 
contentResolver.update(uri, values, "column1 = ? and column2 = ?", arrayOf("text", "1")) 

Notez que le code ci-dessus utilise les paramètres selection et selectionArgs pour contraindre les données à être mises à jour afin d'empêcher que toutes les lignes ne soient affectées. Enfin, vous pouvez appeler la méthode delete() de ContentResolver pour supprimer cette donnée, le code est le suivant :

contentResolver.delete(uri, "column2 = ?", arrayOf("1"))

utiliser

//<uses-permission android:name="android.permission.READ_CONTACTS" />

class MainActivity : AppCompatActivity() {
 private val contactsList = ArrayList<String>()
 private lateinit var adapter: ArrayAdapter<String>
 override fun onCreate(savedInstanceState: Bundle?) {
 super.onCreate(savedInstanceState)
 setContentView(R.layout.activity_main)
     adapter = ArrayAdapter(this, android.R.layout.simple_list_item_1, contactsList)
     contactsView.adapter = adapter
     if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS)
     != PackageManager.PERMISSION_GRANTED) {
     ActivityCompat.requestPermissions(this,
     arrayOf(Manifest.permission.READ_CONTACTS), 1)
 } else {
     readContacts()
 }
 }
 override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>,
 grantResults: IntArray) {
 super.onRequestPermissionsResult(requestCode, permissions, grantResults)
     when (requestCode) {
     1 -> {
     if (grantResults.isNotEmpty()
     && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
     readContacts()
 } else {
     Toast.makeText(this, "You denied the permission",
     Toast.LENGTH_SHORT).show()
 }
 }
 }
 }
 private fun readContacts() {
 // 查询联系人数据
     contentResolver.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
     null, null, null, null)?.apply {
     while (moveToNext()) {
     // 获取联系人姓名
     val displayName = getString(getColumnIndex(
     ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME))
     // 获取联系人手机号
     val number = getString(getColumnIndex(
     ContactsContract.CommonDataKinds.Phone.NUMBER))
     contactsList.add("$displayName\n$number")
 }
 adapter.notifyDataSetChanged()
     close()
 }
 }
}

 Deuxièmement, l'utilisation de ContentProvider

class MyProvider : ContentProvider() {
 override fun onCreate(): Boolean {
 return false
 }
 override fun query(uri: Uri, projection: Array<String>?, selection: String?,
 selectionArgs: Array<String>?, sortOrder: String?): Cursor? {
 return null
 }
 override fun insert(uri: Uri, values: ContentValues?): Uri? {
 return null
 }
 override fun update(uri: Uri, values: ContentValues?, selection: String?,
 selectionArgs: Array<String>?): Int {
 return 0
 }
 override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int {
 return 0
 }
 override fun getType(uri: Uri): String? {
 return null
 }
}

(1) onCreate(). Appelé lorsque le ContentProvider est initialisé. En général, les opérations telles que la création et la mise à niveau de la base de données sont terminées ici. Le retour de true indique que l'initialisation de ContentProvider a réussi et le retour de false indique un échec.

(2) requête(). Interrogez les données de ContentProvider. Le paramètre uri est utilisé pour déterminer la table à interroger, le paramètre projection est utilisé pour déterminer les colonnes à interroger, les paramètres selection et selectionArgs sont utilisés pour restreindre les lignes à interroger, le paramètre sortOrder est utilisé pour trier les résultats et le les résultats de la requête sont stockés dans l'objet Cursor et renvoyés.

(3) insérer(). Ajoutez une donnée à ContentProvider. Le paramètre uri est utilisé pour déterminer la table à ajouter, et les données à ajouter sont stockées dans le paramètre values. Une fois l'ajout terminé, un URI représentant le nouvel enregistrement est renvoyé.

(4) mise à jour(). Mettez à jour les données existantes dans ContentProvider. Le paramètre uri est utilisé pour déterminer les données dans quelle table mettre à jour. Les nouvelles données sont stockées dans le paramètre values. Les paramètres selection et selectionArgs sont utilisés pour restreindre les lignes à mettre à jour, et le nombre de lignes affectées sera renvoyé comme valeur de retour.

(5) supprimer(). Supprimer les données de ContentProvider. Le paramètre uri est utilisé pour déterminer les données dans quelle table supprimer, les paramètres selection et selectionArgs sont utilisés pour restreindre les lignes à supprimer, et le nombre de lignes supprimées sera renvoyé comme valeur de retour.

(6) getType(). Renvoie le type MIME correspondant en fonction de l'URI du contenu entrant. On peut voir que de nombreuses méthodes ont le paramètre uri, qui est également passé lors de l'appel de la méthode d'ajout, de suppression, de modification et de requête du résolveur de contenu. Nous devons maintenant analyser le paramètre uri entrant et analyser la table et les données auxquelles l'appelant s'attend à accéder.

Je suppose que tu aimes

Origine blog.csdn.net/m0_59482482/article/details/129718728
conseillé
Classement