ActivityResultRegistry est l'approche recommandée
ComponentActivity
fournit maintenant un ActivityResultRegistry
qui vous permet de gérer le startActivityForResult()
+ onActivityResult()
ainsi que requestPermissions()
+ onRequestPermissionsResult()
flux sans écraser les méthodes dans votre Activity
ou 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. takePicture
est juste un rappel qui retourne un bitmap nullable - que ce soit nul ou non dépend de la onActivityResult
réussite ou non du processus. prepareCall
puis enregistre cet appel dans une nouvelle fonctionnalité ComponentActivity
appelé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 takePicture
dé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.