Activity Result Contracts
ActivityResultContracts
is a class that we can use to do some standard and type-safe Activity operations, such as taking pictures or opening documents.
Taking Picture​
ActivityResultContracts.TakePicture
class allows you to take a picture and save it to the provided content URI. The callback will return true
if the picture is successfully saved.
First, register the launcher within Activity's onCreate
method:
package com.hanmajid.androidnotebook
import android.net.Uri
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
class MainActivity : ComponentActivity() {
private lateinit var launcher: ActivityResultLauncher<Uri>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
launcher = registerForActivityResult(ActivityResultContracts.TakePicture()) { isSuccess ->
// Log the result
Log.i("TAG", isSuccess.toString())
}
}
}
Next, we only need to call the launch()
method and provide the content URI of our picture file as the argument:
import androidx.core.content.FileProvider
import java.io.File
val file = File.createTempFile("temp", ".jpg")
uri = FileProvider.getUriForFile(
this@MainActivity,
"com.hanmajid.androidnotebook",
file,
)
launcher.launch(uri)
Taking Picture Preview​
ActivityResultContracts.TakePicturePreview
class allows you to take a picture and save it as a Bitmap. The callback will return the Bitmap of the taken picture. Otherwise, it will return null.
First, register the launcher within Activity's onCreate
method:
package com.hanmajid.androidnotebook
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
class MainActivity : ComponentActivity() {
private lateinit var launcher: ActivityResultLauncher<Void?>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
launcher = registerForActivityResult(ActivityResultContracts.TakePicturePreview()) { bitmap ->
// Log the result
Log.i("TAG", bitmap.toString())
}
}
}
Next, we only need to call the launch()
method:
launcher.launch(null)
Capturing Video​
ActivityResultContracts.CaptureVideo
class allows you to take a video and save it to the provided content URI. The callback will return true
if the video is successfully saved.
First, register the launcher within Activity's onCreate
method:
package com.hanmajid.androidnotebook
import android.net.Uri
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
class MainActivity : ComponentActivity() {
private lateinit var launcher: ActivityResultLauncher<Uri>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
launcher = registerForActivityResult(ActivityResultContracts.CaptureVideo()) { isSuccess ->
// Log the result
Log.i("TAG", isSuccess.toString())
}
}
}
Next, we only need to call the launch()
method and provide the content URI of our video file as the argument:
import androidx.core.content.FileProvider
import java.io.File
val file = File.createTempFile("temp", ".mp4")
uri = FileProvider.getUriForFile(
this@MainActivity,
"com.hanmajid.androidnotebook",
file,
)
launcher.launch(uri)
Creating Document​
ActivityResultContracts.CreateDocument
class allows you to select a path for creating a new file with the given mimeType
. The callback will return the content URI of the empty file that was created, or it will return null
if user cancels the prompt.
First, register the launcher within Activity's onCreate
method:
package com.hanmajid.androidnotebook
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
class MainActivity : ComponentActivity() {
private lateinit var launcher: ActivityResultLauncher<String>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
launcher = registerForActivityResult(ActivityResultContracts.CreateDocument("text/plain")) { contentUri ->
// Log the result
Log.i("TAG", contentUri.toString())
}
}
}
In the above example, we want to create a text file (text/plain
).
Next, we only need to call the launch()
method and provide the suggested name for the file as the argument:
launcher.launch("new_file.txt")
Getting Document​
ActivityResultContracts.GetContent
class allows you to display a prompt for user to select a file. The callback will return the content URI of the file, or it will return null
if user cancels the prompt.
First, register the launcher within Activity's onCreate
method:
package com.hanmajid.androidnotebook
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
class MainActivity : ComponentActivity() {
private lateinit var launcher: ActivityResultLauncher<String>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
launcher = registerForActivityResult(ActivityResultContracts.GetContent()) { contentUri ->
// Log the result
Log.i("TAG", contentUri.toString())
}
}
}
Next, we only need to call the launch()
method and provide the mime type filter as the argument:
launcher.launch("image/*")
Getting Multiple Documents​
ActivityResultContracts.GetMultipleContents
class allows you to display a prompt for user to select one or more files. The callback will return a list of the content URI of the files, or it will return an empty list if user cancels the prompt.
First, register the launcher within Activity's onCreate
method:
package com.hanmajid.androidnotebook
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
class MainActivity : ComponentActivity() {
private lateinit var launcher: ActivityResultLauncher<String>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
launcher = registerForActivityResult(ActivityResultContracts.GetMultipleContents()) { contentUris ->
// Log the result
Log.i("TAG", contentUris.toString())
}
}
}
Next, we only need to call the launch()
method and provide the mime type filter as the argument:
launcher.launch("image/*")
Opening Document​
ActivityResultContracts.OpenDocument
class allows you to display a prompt for user to select a file similar to ActivityResultContracts.GetContent
. The callback will return the content URI of the file, or it will return null
if user cancels the prompt.
First, register the launcher within Activity's onCreate
method:
package com.hanmajid.androidnotebook
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
class MainActivity : ComponentActivity() {
private lateinit var launcher: ActivityResultLauncher<Array<String>>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
launcher = registerForActivityResult(ActivityResultContracts.OpenDocument()) { contentUri ->
// Log the result
Log.i("TAG", contentUri.toString())
}
}
}
Next, we only need to call the launch()
method and provide the mime types filter as the argument:
launcher.launch(arrayOf("image/*", "video/*"))
Opening Document Tree​
ActivityResultContracts.OpenDocumentTree
class allows you to display a prompt for user to select a directory. The callback will return the content URI of the directory, or it will return null
if user cancels the prompt. Apps can fully manage documents within the returned directory.
First, register the launcher within Activity's onCreate
method:
package com.hanmajid.androidnotebook
import android.net.Uri
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
class MainActivity : ComponentActivity() {
private lateinit var launcher: ActivityResultLauncher<Uri?>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
launcher = registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) { contentUri ->
// Log the result
Log.i("TAG", contentUri.toString())
}
}
}
Next, we only need to call the launch()
method and provide optional Uri of the initial starting location as the argument:
launcher.launch(null)
Opening Multiple Documents​
ActivityResultContracts.OpenMultipleDocuments
class allows you to display a prompt for user to select multiple files similar to ActivityResultContracts.GetMultipleContents
. The callback will return list of the content URI of the files, or it will return empty list if user cancels the prompt.
First, register the launcher within Activity's onCreate
method:
package com.hanmajid.androidnotebook
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
class MainActivity : ComponentActivity() {
private lateinit var launcher: ActivityResultLauncher<Array<String>>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
launcher = registerForActivityResult(ActivityResultContracts.OpenMultipleDocuments()) { contentUris ->
// Log the result
Log.i("TAG", contentUris.toString())
}
}
}
Next, we only need to call the launch()
method and provide the mime types filter as the argument:
launcher.launch(arrayOf("image/*", "video/*"))
Picking Contact​
ActivityResultContracts.PickContact
class allows you to display a prompt for user to select a contact from their device. The callback will return the content URI of the contact, or it will return null if the user cancels the prompt.
First, register the launcher within Activity's onCreate
method:
package com.hanmajid.androidnotebook
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
class MainActivity : ComponentActivity() {
private lateinit var launcher: ActivityResultLauncher<Void?>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
launcher = registerForActivityResult(ActivityResultContracts.PickContact()) { uri ->
// Log the result
Log.i("TAG", uri.toString())
}
}
}
Next, we only need to call the launch()
method:
launcher.launch(null)
Picking Visual Media​
ActivityResultContracts.PickVisualMedia
class allows you to display a prompt for user to select a single image, video, or other type of visual media. The callback will return the content URI of the visual media, or it will return null if the user cancels the prompt.
First, register the launcher within Activity's onCreate
method:
package com.hanmajid.androidnotebook
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.PickVisualMediaRequest
import androidx.activity.result.contract.ActivityResultContracts
class MainActivity : ComponentActivity() {
private lateinit var launcher: ActivityResultLauncher<PickVisualMediaRequest>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
launcher = registerForActivityResult(ActivityResultContracts.PickVisualMedia()) { contentUri ->
// Log the result
Log.i("TAG", contentUri.toString())
}
}
}
Next, we only need to call the launch()
method and pass a PickVisualMediaRequest
instance:
// For picking an image
launcher.launch(
PickVisualMediaRequest.Builder()
.setMediaType(ActivityResultContracts.PickVisualMedia.ImageOnly)
.build()
)
// For picking a video
launcher.launch(
PickVisualMediaRequest.Builder()
.setMediaType(ActivityResultContracts.PickVisualMedia.VideoOnly)
.build()
)
// For picking an image or a video
launcher.launch(
PickVisualMediaRequest.Builder()
.setMediaType(ActivityResultContracts.PickVisualMedia.ImageAndVideo)
.build()
)
// For picking a visual media with mime type "image/png"
launcher.launch(
PickVisualMediaRequest.Builder()
.setMediaType(ActivityResultContracts.PickVisualMedia.SingleMimeType("image/png"))
.build()
)
Requesting Permission​
ActivityResultContracts.RequestPermission
class allows you to display a prompt for user to grant a certain permission for the app. The callback will return true if the permission is granted, or it will return false if the user denies or cancels it.
First, register the launcher within Activity's onCreate
method:
package com.hanmajid.androidnotebook
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
class MainActivity : ComponentActivity() {
private lateinit var launcher: ActivityResultLauncher<String>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
launcher = registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
// Log the result
Log.i("TAG", isGranted.toString())
}
}
}
Next, we only need to call the launch()
method and provide the permission that you want to grant:
launcher.launch(android.Manifest.permission.ACCESS_COARSE_LOCATION)
Requesting Multiple Permissions​
ActivityResultContracts.RequestMultiplePermissions
class allows you to display a prompt for user to grant multiple permissions for the app. The callback will return a Map<String, bool>
that contains the permission status for each requested permission.
First, register the launcher within Activity's onCreate
method:
package com.hanmajid.androidnotebook
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
class MainActivity : ComponentActivity() {
private lateinit var launcher: ActivityResultLauncher<Array<String>>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
launcher = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { mapIsGranted ->
// Log the result
Log.i("TAG", mapIsGranted.toString())
}
}
}
Next, we only need to call the launch()
method and provide the array of permissions that you want to grant:
launcher.launch(
arrayOf(
android.Manifest.permission.ACCESS_COARSE_LOCATION,
android.Manifest.permission.READ_CONTACTS,
)
)
Starting Intent (Activity For Result)​
ActivityResultContracts.StartActivityForResult
class allows you to start an Intent. The callback will return an ActivityResult
of the output. With this class, we don't have to manage request codes ourselves.
First, register the launcher within Activity's onCreate
method:
package com.hanmajid.androidnotebook
import android.content.Intent
import android.os.Bundle
import android.util.Log
import androidx.activity.ComponentActivity
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
class MainActivity : ComponentActivity() {
private lateinit var launcher: ActivityResultLauncher<Intent>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
launcher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { activityResult ->
// Log the result
Log.i("TAG", activityResult.toString())
}
}
}
Next, we only need to call the launch()
method and provide the Intent that we want to launch:
launcher.launch(
Intent(ACTION_REQUEST_PERMISSIONS).apply {
putExtra(
EXTRA_PERMISSIONS, arrayOf(
android.Manifest.permission.ACCESS_COARSE_LOCATION
)
)
}
)
References​
ActivityResultContracts
| Android DevelopersActivityResultContracts.CaptureVideo
| Android DevelopersActivityResultContracts.CreateDocument
| Android DevelopersActivityResultContracts.GetContent
| Android DevelopersActivityResultContracts.GetMultipleContents
| Android DevelopersActivityResultContracts.OpenDocument
| Android DevelopersActivityResultContracts.OpenDocumentTree
| Android DevelopersActivityResultContracts.OpenMultipleDocuments
| Android DevelopersActivityResultContracts.PickContact
| Android DevelopersActivityResultContracts.RequestPermission
| Android DevelopersActivityResultContracts.RequestMultiplePermissions
| Android DevelopersActivityResultContracts.TakePicture
| Android DevelopersActivityResultContracts.TakePicturePreview
| Android DevelopersActivityResultContracts.PickVisualMedia
| Android DevelopersActivityResultContracts.StartActivityForResult
| Android Developers