Content Provider in Android
Hello friends hi. This post is regarding all about Content Provider in Android. Content Provider is also one of the most important topic of Android Application.
So let's get start....
Basically a Content Provider manages access to a structured set of data. It encapsulate the data and the mechanism for defining data security. It is used to share the data between different applications.
Content Providers support the four basic operations, normally called CRUD-operations.
What is Content URI (Universal Resource Identifier)?
Content URI is the key concept of content provider. To query a content provider, you can specify the query string in the form of URI.
URI: content://authority/data_type/id
- content:// → This is prefix of all the URI and it is mandatory part of URI.
- authority → This part should be always unique for every content provider, it specify the name of content provider. for example contacts, browser etc.
- data_type → This indicates the type of data provider by content provider.
- id → it is a numeric value that is used to access particular record.
**** Operations of Content Provider are CRUD
- CREATE : you can create a new data.
- READ : you can access the available data.
- UPDATE: you can modify the existing data.
- DELETE: you can delete the data permanently from device as well.
Implementation of Contnent Provider for fetching contact list:
Step 1: Add a contact data class to handle the fields cleanly.
data class Contact (val name: String, val number: String)
Step 2: Add adapter for the items of contacts list.
class ContactAdapter(private val contacts: List<Contact>) :
RecyclerView.Adapter<ContactAdapter.ContactViewHolder>() {
private lateinit var binding: ContactBinding
override fun getItemCount() = contacts.size
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ContactViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
binding = ContactBinding.inflate(layoutInflater, parent, false)
return ContactViewHolder(binding.root)
}
override fun onBindViewHolder(holder: ContactViewHolder, position: Int) {
holder.apply {
val contact = contacts[position]
bind(contact)
}
}
inner class ContactViewHolder(private val v: View) : RecyclerView.ViewHolder(v) {
fun bind(contact: Contact) {
val name = v.findViewById<TextView>(R.id.name)
val number = v.findViewById<TextView>(R.id.number)
name.text = contact.name
number.text = contact.number
}
}
}
RecyclerView.Adapter<ContactAdapter.ContactViewHolder>() {
private lateinit var binding: ContactBinding
override fun getItemCount() = contacts.size
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ContactViewHolder {
val layoutInflater = LayoutInflater.from(parent.context)
binding = ContactBinding.inflate(layoutInflater, parent, false)
return ContactViewHolder(binding.root)
}
override fun onBindViewHolder(holder: ContactViewHolder, position: Int) {
holder.apply {
val contact = contacts[position]
bind(contact)
}
}
inner class ContactViewHolder(private val v: View) : RecyclerView.ViewHolder(v) {
fun bind(contact: Contact) {
val name = v.findViewById<TextView>(R.id.name)
val number = v.findViewById<TextView>(R.id.number)
name.text = contact.name
number.text = contact.number
}
}
}
Step 3: Now implement the content provider.
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
private lateinit var contactAdapter: ContactAdapter
private var contacts = ArrayList<Contact>()
private var contactsStr = ArrayList<String>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.apply {
fab.setOnClickListener {
syncContacts()
}
}
}
private fun syncContacts() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& checkSelfPermission(Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED
) {
requestPermissions(
arrayOf(Manifest.permission.READ_CONTACTS),
PERMISSION_REQ_READ_CONTACTS
)
} else {
fetchContacts()
setAdapter()
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == PERMISSION_REQ_READ_CONTACTS) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
syncContacts()
} else {
Snackbar.make(
this,
binding.root,
"Permission Not Granted",
Snackbar.LENGTH_SHORT
)
.show()
}
}
}
private fun fetchContacts() {
val resolver: ContentResolver = contentResolver
val cursor = resolver.query(
ContactsContract.Contacts.CONTENT_URI,
null, null, null, null
)
if (cursor!!.count > 0) {
while (cursor.moveToNext()) {
val id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID))
val name =
cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME))
val phoneNum =
cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))
.toInt()
if (phoneNum > 0) {
val cursorPhone = contentResolver.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " =?",
arrayOf(id),
null
)
if (cursorPhone!!.count > 0) {
while (cursorPhone.moveToNext()) {
val phoneNumValue = cursorPhone.getString(
cursorPhone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)
)
contactsStr.add("$name|$phoneNumValue")
}
}
cursorPhone.close()
}
}
}
for (contact in contactsStr) {
val contactSplit = contact.split("|")
Log.i("TechAmit", contactSplit.toString())
contacts.add(Contact(contactSplit[0], contactSplit[1]))
}
}
private fun setAdapter() {
contactAdapter = ContactAdapter(contacts)
binding.apply {
contactRecyclerView.layoutManager = LinearLayoutManager(this@MainActivity)
contactRecyclerView.adapter = contactAdapter
ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) {
override fun onMove(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder
): Boolean {
return false
}
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
val pos = viewHolder.adapterPosition
contacts.removeAt(pos)
contactAdapter.notifyItemRemoved(pos)
Toast.makeText(this@MainActivity, "Contact Deleted", Toast.LENGTH_LONG)
.show()
}
}).attachToRecyclerView(contactRecyclerView)
ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT) {
override fun onMove(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder
): Boolean {
return false
}
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
val pos = viewHolder.adapterPosition
contacts.removeAt(pos)
contactAdapter.notifyItemRemoved(pos)
Toast.makeText(this@MainActivity, "Contact Archived", Toast.LENGTH_LONG)
.show()
}
}).attachToRecyclerView(contactRecyclerView)
}
}
companion object {
const val PERMISSION_REQ_READ_CONTACTS = 100
}
}
private lateinit var binding: ActivityMainBinding
private lateinit var contactAdapter: ContactAdapter
private var contacts = ArrayList<Contact>()
private var contactsStr = ArrayList<String>()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
binding.apply {
fab.setOnClickListener {
syncContacts()
}
}
}
private fun syncContacts() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M
&& checkSelfPermission(Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED
) {
requestPermissions(
arrayOf(Manifest.permission.READ_CONTACTS),
PERMISSION_REQ_READ_CONTACTS
)
} else {
fetchContacts()
setAdapter()
}
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == PERMISSION_REQ_READ_CONTACTS) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
syncContacts()
} else {
Snackbar.make(
this,
binding.root,
"Permission Not Granted",
Snackbar.LENGTH_SHORT
)
.show()
}
}
}
private fun fetchContacts() {
val resolver: ContentResolver = contentResolver
val cursor = resolver.query(
ContactsContract.Contacts.CONTENT_URI,
null, null, null, null
)
if (cursor!!.count > 0) {
while (cursor.moveToNext()) {
val id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID))
val name =
cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME))
val phoneNum =
cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.HAS_PHONE_NUMBER))
.toInt()
if (phoneNum > 0) {
val cursorPhone = contentResolver.query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI,
null,
ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " =?",
arrayOf(id),
null
)
if (cursorPhone!!.count > 0) {
while (cursorPhone.moveToNext()) {
val phoneNumValue = cursorPhone.getString(
cursorPhone.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER)
)
contactsStr.add("$name|$phoneNumValue")
}
}
cursorPhone.close()
}
}
}
for (contact in contactsStr) {
val contactSplit = contact.split("|")
Log.i("TechAmit", contactSplit.toString())
contacts.add(Contact(contactSplit[0], contactSplit[1]))
}
}
private fun setAdapter() {
contactAdapter = ContactAdapter(contacts)
binding.apply {
contactRecyclerView.layoutManager = LinearLayoutManager(this@MainActivity)
contactRecyclerView.adapter = contactAdapter
ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.LEFT) {
override fun onMove(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder
): Boolean {
return false
}
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
val pos = viewHolder.adapterPosition
contacts.removeAt(pos)
contactAdapter.notifyItemRemoved(pos)
Toast.makeText(this@MainActivity, "Contact Deleted", Toast.LENGTH_LONG)
.show()
}
}).attachToRecyclerView(contactRecyclerView)
ItemTouchHelper(object : ItemTouchHelper.SimpleCallback(0, ItemTouchHelper.RIGHT) {
override fun onMove(
recyclerView: RecyclerView,
viewHolder: RecyclerView.ViewHolder,
target: RecyclerView.ViewHolder
): Boolean {
return false
}
override fun onSwiped(viewHolder: RecyclerView.ViewHolder, direction: Int) {
val pos = viewHolder.adapterPosition
contacts.removeAt(pos)
contactAdapter.notifyItemRemoved(pos)
Toast.makeText(this@MainActivity, "Contact Archived", Toast.LENGTH_LONG)
.show()
}
}).attachToRecyclerView(contactRecyclerView)
}
}
companion object {
const val PERMISSION_REQ_READ_CONTACTS = 100
}
}

Comments
Post a Comment