內容目錄
相關知識
權限宣告與請求
CONTACTS 屬於危險權限,所以除了要在 AndroidManifest.xml 中宣告權限,還得在運行時請求權限許可。
ContentURI
存取 Contacts (聯絡人) 的 URI 為: ContactsContract.CommonDataKinds.Phone.*CONTENT_URI*
顯示名稱的欄位:ContactsContract.CommonDataKinds.Phone.*DISPLAY_NAME*
電話欄位:ContactsContract.CommonDataKinds.Phone.*NUMBER*
ContentResolver
這裏我們只會用到 ContentResolver 的 query() 功能,
val cursor = contentResolver.query( uri, // ContentURI projection, // 指定查詢的欄位名稱 selection, // 指定 WHERE 的條件 selectionArgs, // 為 WHERE 的佔位符號提供實際值 sortOrder) // 指定資料排序
使用範例
// 查詢 todos 資料表的所有資料,取得所有欄位 val cursor = contentResolver.query( Uri.parse("content://app.kirin.android.provider/todos"), null, null, null, null) while(cursor.moveToNext()) { val title = cursor.getString(cursor.getColumnIndex("title")) } cursor.close()
程式實作
建立含有一個 EmptyActivity 的專案: ContentResolver Lab
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="<http://schemas.android.com/apk/res/android>" package="app.kirin.android.contentresolverlab"> <uses-permission android:name="android.permission.READ_CONTACTS" /> <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/Theme.ContentResolverLab"> <activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="<http://schemas.android.com/apk/res/android>" xmlns:app="<http://schemas.android.com/apk/res-auto>" xmlns:tools="<http://schemas.android.com/tools>" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <ListView android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/lv_contacts" /> </LinearLayout>
MainActivity.kt
package app.kirin.android.contentresolverlab import android.Manifest import android.annotation.SuppressLint import android.content.pm.PackageManager import androidx.appcompat.app.AppCompatActivity import android.os.Bundle import android.provider.ContactsContract import android.widget.ArrayAdapter import android.widget.ListView import android.widget.Toast import androidx.activity.result.contract.ActivityResultContracts import androidx.core.content.ContextCompat 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) val lvContacts = findViewById<ListView>(R.id.lv_contacts) lvContacts.adapter = adapter val permissionLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission()) { result -> if (result) { showContacts() } else { Toast.makeText(this, "必須同意權限請求才能繼續使用", Toast.LENGTH_SHORT).show() } } if(ContextCompat.checkSelfPermission( this, Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED) { showContacts() } else { permissionLauncher.launch(Manifest.permission.READ_CONTACTS) } } private fun showContacts() { 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() } } }
Comments