ActivityResultRegistry è l'approccio consigliato
ComponentActivityfornisce ora una ActivityResultRegistryche consente di gestire il startActivityForResult()+ onActivityResult()e requestPermissions()+ onRequestPermissionsResult()scorre senza sostituire i metodi nel vostro Activityo Fragment, porta maggiore sicurezza tipo via ActivityResultContracte fornisce ganci per testare questi flussi.
Si consiglia vivamente di utilizzare le API dei risultati delle attività introdotte in AndroidX Activity 1.2.0-alpha02 e Fragment 1.3.0-alpha02.
Aggiungi questo al tuo 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"
Come utilizzare il contratto pre-costruito?
Questa nuova API ha le seguenti funzionalità predefinite
- TakeVideo
- PickContact
- getContent
- getContents
- OpenDocument
- OpenDocuments
- OpenDocumentTree
- CreateDocument
- Comporre
- Fare una foto
- Richiesta di permesso
- RequestPermissions
Un esempio che utilizza il contratto 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() }
}
Quindi cosa sta succedendo qui? Analizziamolo leggermente. takePictureè solo un callback che restituisce un Bitmap nullable - che sia nullo dipende dal fatto che il onActivityResultprocesso abbia avuto successo o meno . prepareCallquindi registra questa chiamata in una nuova funzione ComponentActivitychiamata ActivityResultRegistry- torneremo su questo più tardi. ActivityResultContracts.TakePicture()è uno degli helper integrati che Google ha creato per noi e infine invocare in takePicturerealtà attiva l'intento nello stesso modo in cui lo faresti in precedenza Activity.startActivityForResult(intent, REQUEST_CODE).
Come scrivere un contratto personalizzato?
Il contratto semplice che accetta un Int come input e restituisce una stringa che ha richiesto l'attività restituisce il risultato Intento.
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)
}
}
}
Controlla questa documentazione ufficiale per maggiori informazioni.