How to access WhatsApp statuses folder in Android 11 or above.
In this tutorial we will learn how to access WhatsApp statuses folder in android 11 and above programmatically. Accessing whatsapp statuses folder in android 11 is different from the other lower android versions. This difference is due to storage enhancements in Android 11.
Scoped Storage in Android 11
The Android 11 becomes with major changes in storage. These changes leads to the division of whole storage into blocks. This division is called scoped storage. Scoped storage has Media and Download collections. The media folder contains Images, Audios and Video files, while document collection stores the non media files.
Access WhatsApp Statuses Folder
We can access WhatsApp Status folder using the DocumentTreeIntent . This intent will allow access permission of whatsapp status folder.
Let’s start the process of accessing the whatsapp status folder.
Create a new android project
After creatiing new project add view binding feature in build.gradle file and sync the project.
buildFeatures {
viewBinding true
}
ACTION_OPEN_DOCUMENT_TREE Intent
To access the whatsapp statuses we first need to take permission of that folder. Without this permission we cannot access the statuses. To take permission we will use ACTION_OPEN_DOCUMENT_TREE Intent. This will open an UI with a button to take permission of this folder. To launch this intent we will create a launcher object for activity result.
val launcher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
// There are no request codes
val data: Intent? = result.data
if (data != null) {
getWAStatuses(data.data!!)
}
}
}
Take WhatsApp Status Folder Access Permission
This launcher will help us to launch that ACTION_OPEN_DOCUMENT_TREE Intent, and we can get back the result. Result contains the URI of whatsapp statuses folder. Let’s launch the intent using this method.
fun askMediaFolderAccessPermission() { val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE) intent.putExtra( DocumentsContract.EXTRA_INITIAL_URI, DocumentFile.fromTreeUri( this, Uri.parse("content://com.android.externalstorage.documents/tree/primary%3AAndroid%2Fmedia%2Fcom.whatsapp%2FWhatsApp%2FMedia%2F.Statuses"))!!.uri ) launcher.launch(intent) }
Here we use the intent to access folder permission. The initial uri parameter is used to open the whatsapp folder. When we will launch this intent, it will open an UI in which WhatsApp statuses folder will be opened and one button will appear to access permission of this folder. By pressing that button we can access files of that folder and will get the uri of that folder in result. Now we can get all statuses of that folder .
Fetch List of Whatsapp Statuses
Here is the method to get all WhatsApp statuses.
fun getWAStatuses(uri: Uri) {
val docFile = DocumentFile.fromTreeUri(this, uri)
val files = docFile!!.listFiles()
}
In this method we just fetch the list of files from that folder using the document file.
Now we can show these statuses in recyclerview.
Here is the full code.
MainActivity.kt
package com.example.statusdemo
import android.app.Activity
import android.content.Intent
import android.net.Uri
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.provider.DocumentsContract
import android.widget.Toast
import androidx.activity.result.contract.ActivityResultContracts
import androidx.documentfile.provider.DocumentFile
import androidx.recyclerview.widget.GridLayoutManager
import com.example.statusdemo.databinding.ActivityMainBinding
class MainActivity : AppCompatActivity() {
private lateinit var binding: ActivityMainBinding
val launcher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
// There are no request codes
val data: Intent? = result.data
if (data != null) {
getWAStatuses(data.data!!)
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding=ActivityMainBinding.inflate(layoutInflater)
setContentView(binding.root)
initRecyclerView()
askMediaFolderAccessPermission()
}
fun getWAStatuses(uri: Uri) {
val docFile = DocumentFile.fromTreeUri(this, uri)
val files = docFile!!.listFiles()
setRecyclerViewAdapter(files.toList())
}
fun initRecyclerView() {
val layoutManager = GridLayoutManager(this, 2)
binding.recyclerView.layoutManager = layoutManager
}
fun setRecyclerViewAdapter(files: List<DocumentFile>) {
val adapter = StatusListAdapter(this, files)
binding.recyclerView.adapter = adapter
}
fun askMediaFolderAccessPermission() {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE)
intent.putExtra(
DocumentsContract.EXTRA_INITIAL_URI,
DocumentFile.fromTreeUri(
this,
Uri.parse("content://com.android.externalstorage.documents/tree/primary%3AAndroid%2Fmedia%2Fcom.whatsapp%2FWhatsApp%2FMedia%2F.Statuses")
)!!
.uri
)
launcher.launch(intent)
}
}
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"
tools:context=".MainActivity">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
Layout_single_status.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_margin="6dp"
android:layout_height="150dp">
<ImageView
android:id="@+id/image_view"
android:scaleType="centerCrop"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
StatusListAdapter.kt
package com.example.statusdemo
import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.documentfile.provider.DocumentFile
import androidx.recyclerview.widget.RecyclerView
import com.example.statusdemo.databinding.LayoutSingleStatusBinding
class StatusListAdapter(val context : Context ,val list : List<DocumentFile>) : RecyclerView.Adapter<StatusListAdapter.StatusListHolder>() {
class StatusListHolder( val binding : LayoutSingleStatusBinding): RecyclerView.ViewHolder(binding.root){
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): StatusListHolder {
val binding =LayoutSingleStatusBinding.inflate(LayoutInflater.from(context),parent,false)
return StatusListHolder(binding)
}
override fun onBindViewHolder(holder: StatusListHolder, position: Int) {
holder.binding.imageView.setImageURI(list.get(position).uri)
}
override fun getItemCount(): Int {
return list.size
}
}
Conclusion
In this tutorial we have learned that how to access WhatsApp statuses folder in Android 11 and above with scoped store. We take permission of statuses folder using ACTION_OPEN_DOCUMENT_TREE Intent, and get list of all statues. Hope this will help you to understand the scoped storage and accessing files from this storage.