7

I am trying to start file chooser on a button click (composable function). Unable to use startActivityForResult().

@Composable
fun SelectScreen() {

    Button(onClick = {
        val intent = Intent(Intent.ACTION_GET_CONTENT)
        startActivity(intent)
    }
    ) {
        Text("BUTTON")
    }
}
hippietrail
  • 15,848
  • 18
  • 99
  • 158
Hitesh Patel
  • 183
  • 2
  • 12

5 Answers5

18

Here is my suggestion:

val pickPictureLauncher = rememberLauncherForActivityResult(
    ActivityResultContracts.GetContent()
) { imageUri ->
    if (imageUri != null) {
        // Update the state with the Uri
    }
}

// In your button's click
pickPictureLauncher.launch("image/*")

and in your composable which display the image, you can do the following

val image = remember {
   // Make sure to resize and compress
   // the image to avoid display a big bitmap
   ImageUtils.imageFromUri(imageUi)
}
Image(
   image,
   contentDescription = null
)
nglauber
  • 18,674
  • 6
  • 70
  • 75
7

You can use rememberLauncherForActivityResult() to register a request to Activity#startActivityForResult, designated by the given ActivityResultContract.

This creates a record in the ActivityResultRegistry associated with this caller, managing request code, as well as conversions to/from Intent under the hood.

Something like:

val result = remember { mutableStateOf<Uri?>(null) }
val launcher = rememberLauncherForActivityResult(ActivityResultContracts.OpenDocument()) {
    result.value = it
}

Button(onClick = { launcher.launch(arrayOf("image/*")) }) {
    Text(text = "Open Document")
}

result.value?.let {
   //...
}
Gabriele Mariotti
  • 320,139
  • 94
  • 887
  • 841
2

to use "startActivityForResult()" in compose I found this solution and it worked for me

@Composable
fun SelectScreen() {
val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.type = "*/*";
intent.addCategory(Intent.CATEGORY_OPENABLE);
val launcher = rememberLauncherForActivityResult(ActivityResultContracts.StartActivityForResult()) {}

Button(onClick = {
    launcher.launch(intent)
}) {
    Text(text = "Take a picture")
}

}

Hitesh Patel
  • 183
  • 2
  • 12
0

This is not an answer but startActivity only available under Activity's context not in compose u need to parse the context somewhere to use it context.startActivity.

for onActivityResult there is a new way to do, check out this: OnActivityResult method is deprecated, what is the alternative?

adwardwo1f
  • 817
  • 6
  • 18
0

You will have to start an activity from a valid context, that could be either your application context or activity. If you don't need results back from an activity, meaning that you are not starting the activity for the result then you can start from the application context as well.

companion object{

   var mContext : Context? = null

   /*
   * should set your mContext variable value to this in your activity onCreate,    onStart
   * and set to null in your onStop to avoid leaks
   */
   fun getActivityContext() : Context{
       return mContext;
   }


   fun getApplicationContext() : Context{
       return ApplicationClass.getInstance()
   }
}


@Composable
fun SelectScreen() {
    Button(onClick = {
        val intent = Intent(Intent.ACTION_GET_CONTENT)
        getActivityContext().startActivity(intent)
    }
    ) {
        Text("BUTTON")
    }
}
Wajid
  • 2,235
  • 1
  • 19
  • 29