ActivityResultRegistry est l'approche recommandée
ComponentActivityfournit maintenant un ActivityResultRegistryqui vous permet de gérer le startActivityForResult()+ onActivityResult()ainsi que requestPermissions()+ onRequestPermissionsResult()flux sans écraser les méthodes dans votre Activityou Fragment, apporte la sécurité de type augmenté parActivityResultContract et fournit des crochets pour tester ces flux.
Il est fortement recommandé d'utiliser les API Activity Result introduites dans AndroidX Activity 1.2.0-alpha02 et Fragment 1.3.0-alpha02.
Ajoutez ceci à votre build.gradle
def activity_version = "1.2.0-alpha03"
// Java language implementation
implementation "androidx.activity:activity:$activity_version"
// Kotlin
implementation "androidx.activity:activity-ktx:$activity_version"
Comment utiliser le contrat pré-construit?
Cette nouvelle API possède les fonctionnalités pré-construites suivantes
- Prendre une vidéo
- PickContact
- Obtenir du contenu
- GetContents
- OpenDocument
- OpenDocuments
- OpenDocumentTree
- CreateDocument
- Cadran
- TakePicture
- Demander la permission
- RequestPermissions
Un exemple qui utilise le contrat takePicture:
private val takePicture = prepareCall(ActivityResultContracts.TakePicture())
{ bitmap: Bitmap? ->
// Do something with the Bitmap, if present
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
button.setOnClickListener { takePicture() }
}
Alors qu'est-ce qui se passe ici? Décomposons-le légèrement. takePictureest juste un rappel qui retourne un bitmap nullable - que ce soit nul ou non dépend de la onActivityResultréussite ou non du processus. prepareCallpuis enregistre cet appel dans une nouvelle fonctionnalité ComponentActivityappelée ActivityResultRegistry- nous y reviendrons plus tard. ActivityResultContracts.TakePicture()est l'un des assistants intégrés que Google a créés pour nous, et enfin, l'invocation takePicturedéclenche réellement l'intention de la même manière que vous le feriez précédemment avecActivity.startActivityForResult(intent, REQUEST_CODE) .
Comment rédiger un contrat personnalisé?
Contrat simple qui prend un Int comme entrée et renvoie une chaîne qui a demandé que l'activité retourne dans le résultat Intent.
class MyContract : ActivityResultContract<Int, String>() {
companion object {
const val ACTION = "com.myapp.action.MY_ACTION"
const val INPUT_INT = "input_int"
const val OUTPUT_STRING = "output_string"
}
override fun createIntent(input: Int): Intent {
return Intent(ACTION)
.apply { putExtra(INPUT_INT, input) }
}
override fun parseResult(resultCode: Int, intent: Intent?): String? {
return when (resultCode) {
Activity.RESULT_OK -> intent?.getStringExtra(OUTPUT_STRING)
else -> null
}
}
}
class MyActivity : AppCompatActivity() {
private val myActionCall = prepareCall(MyContract()) { result ->
Log.i("MyActivity", "Obtained result: $result")
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
...
button.setOnClickListener {
myActionCall(500)
}
}
}
Consultez cette documentation officielle pour plus d'informations.