5, ContentProvider related
ContentProvider: content provider is responsible for data access. It is often used for APP data sharing, cross process data access, etc... for example, reading photo albums and contacts are implemented by ContentProvider
- **1. * * we want to access other applications in our own applications, or some data exposed to us by the ContentProvider, such as mobile phone contacts, SMS, photo albums, etc! If we want to read or modify these data, we need to use the ContentProvider!
- **2. * * for our own applications, we can also use ContentProvider if we want to expose some of our data and read or operate it for other applications. In addition, we can choose the data to be exposed to avoid the disclosure of our private data!
1. Permission application
Starting from Android 6.0, all permissions involving user privacy (reading and writing SMS, reading and writing contacts, shooting, recording, etc.) need to be applied at runtime, and a pop-up window will remind the user whether to authorize. If the user is not authorized, the operation cannot continue
First, declare the permission to read the address book in AndroidManifest.xml
<uses-permission android:name="android.permission.READ_CONTACTS"/>
The runtime dynamically applies for permission and requests user authorization
class TestContentProviderActivity : AppCompatActivity(){ override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) //Determine the permission to read the address book if(ActivityCompat.checkSelfPermission(this , android.Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED){ //If not authorized ActivityCompat.requestPermissions( this , arrayOf(android.Manifest.permission.READ_CONTACTS) , 100) }else{ getContacts() //Read contacts } } //Read contacts private fun getContacts() { Toast.makeText(this, "getContacts", Toast.LENGTH_SHORT).show() } override fun onRequestPermissionsResult( requestCode: Int, permissions: Array<out String>, grantResults: IntArray ) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) if(requestCode==100 && permissions[0]==android.Manifest.permission.READ_CONTACTS){ if(grantResults[0] == PackageManager.PERMISSION_GRANTED){ //Indicates that permission is granted getContacts() }else{ Toast.makeText(this,"Permission to read the address book is denied. The program will not continue to work",Toast.LENGTH_LONG).show() } } } }
2. Read the contact list
Table name | explain |
---|---|
content://com.android.contacts/data/phones | Read the name of the contact's table |
field | explain |
---|---|
display_name | user name |
Data1 | cell-phone number |
//Read contacts @SuppressLint("Range") private fun getContacts() { //Query object val resolver = contentResolver //Format a uri val uri = Uri.parse("content://com.android.contacts/data/phones") //Get a cursor val cursor = resolver.query(uri, null, null, null, null)?:return while (cursor.moveToNext()) { //Get contact name and number val displayName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME)) val phoneNumber = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)) Log.e("ContentProvider", "full name:$displayName") Log.e("ContentProvider", "number:$phoneNumber") Log.e("ContentProvider", "======================") } cursor.close() //Cursor closed!! }
3. Insert contact in the address book
Table name | explain |
---|---|
content://com.android.contacts/data/data | Insert the name of the contact's table |
content://com.android.contacts/data/raw_contacts | Insert the name of the contact's original table |
//Insert contact private fun insertContact() { /* * First, send a message to RawContacts.CONTENT_URI performs a null value insertion in order to obtain the rawContactId returned by the system * At this time, insert the data in the data table later to make the inserted contact visible in the address book */ val resolver = contentResolver val values = ContentValues() val rawContactUri = contentResolver!!.insert(ContactsContract.RawContacts.CONTENT_URI, values)!! val rawContactId = ContentUris.parseId(rawContactUri) //Write name data into the data table values.clear() //Clear the possible data first values.put(ContactsContract.Data.RAW_CONTACT_ID , rawContactId) values.put(ContactsContract.Data.MIMETYPE , CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE) //Content type values.put(CommonDataKinds.StructuredName.GIVEN_NAME , "some_name") resolver.insert(ContactsContract.Data.CONTENT_URI , values) //Write phone data to the data table values.clear() //Clear the possible data first values.put(ContactsContract.Data.RAW_CONTACT_ID , rawContactId) values.put(ContactsContract.Data.MIMETYPE , CommonDataKinds.Phone.CONTENT_ITEM_TYPE) //Content type values.put(CommonDataKinds.Phone.NUMBER , "1231231234") values.put(CommonDataKinds.Phone.TYPE , CommonDataKinds.Phone.TYPE_MOBILE) //cell-phone number resolver.insert(ContactsContract.Data.CONTENT_URI , values) //Write Email data to the data table values.clear() //Clear the possible data first values.put(ContactsContract.Data.RAW_CONTACT_ID , rawContactId) values.put(ContactsContract.Data.MIMETYPE , CommonDataKinds.Email.CONTENT_ITEM_TYPE) //Content type values.put(CommonDataKinds.Email.DATA , "some_name@xx.com") values.put(CommonDataKinds.Email.TYPE , CommonDataKinds.Email.TYPE_HOME) //Home mailbox resolver.insert(ContactsContract.Data.CONTENT_URI , values) }
4. Update contact information
- Get the contact of the contact in the address book according to the mobile phone number_ id
@SuppressLint("Range") fun getContactIdByPhone(phone : Long) : String?{ val uri = Uri.parse("content://com.android.contacts/data/phones/filter/$phone") val resolver = contentResolver val cursor = resolver.query(uri, arrayOf(ContactsContract.Data.CONTACT_ID), null, null, null)?:return null if (cursor.moveToNext()){ val contractId = cursor.getString(cursor.getColumnIndex(ContactsContract.Data.CONTACT_ID)) return contractId } return null }
- Update contact's name
//Update contacts private fun updateContact() { val contractId = getContactIdByPhone(234524) if(contractId == null){ Toast.makeText(this , "The contact does not exist and cannot be updated" , Toast.LENGTH_LONG).show() return } val values = ContentValues() values.put(ContactsContract.Data.MIMETYPE , CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE) values.put(CommonDataKinds.StructuredName.GIVEN_NAME, "new_name") contentResolver.update( ContactsContract.Data.CONTENT_URI, values, "${ContactsContract.Data.CONTACT_ID}=?", arrayOf(contractId) ) }
5. Delete contact
- Delete contact by name
val ret = contentResolver.delete( ContactsContract.RawContacts.CONTENT_URI, CommonDataKinds.Phone.DISPLAY_NAME + "=?", arrayOf("some_name") ) if(ret>0){ Toast.makeText(this,"Delete succeeded", Toast.LENGTH_SHORT).show() }else{ Toast.makeText(this, "Deletion failed", Toast.LENGTH_SHORT).show() }
- Delete contact according to mobile phone number
val contact_id = getContactIdByPhone(1111) contentResolver.delete(RawContacts.CONTENT_URI,CommonDataKinds.Phone.CONTACT_ID+"=?", arrayOf(contact_id));
6. Read all messages in inbox
field | explain |
---|---|
address | Recipient address, i.e. mobile phone number, e.g. + 861381180000 |
person | character |
date | Date, long type, such as 1256539465022. You can set the date display format |
protocol | Protocol 0: SMS_RPOTO SMS, 1:MMS_PROTO MMS |
read | Read 0: unread, 1: read |
type | SMS type 1: received SMS, 2: sent SMS |
body | Specific content of SMS |
Dynamic access required
<uses-permission android:name="android.permission.READ_SMS"/>
private fun getMessage() { val uri = Uri.parse("content://sms/") val resolver = contentResolver //Query the sender address, date, type and content of SMS val cursor = resolver.query(uri, arrayOf("address", "address", "type", "body"), null, null, null)?:return while (cursor.moveToNext()){ val address = cursor.getString(0) val data = cursor.getString(1) val type = cursor.getString(2) val body = cursor.getString(3) Log.e("ContentProvider","addressee $address") Log.e("ContentProvider","Type time [$type]:$data") Log.e("ContentProvider","SMS content $body") Log.e("ContentProvider","-----------------------------") } cursor.close() //Close cursor!! }
Other operation URIs related to SMS
content://sms/ All SMS
content://sms/inbox Inbox
content://sms/sent has been sent
content://sms/draft draft
content://sms/outbox Outbox
content://sms/failed fail in send
content://sms/queued List to be sent