ActivityResultRegistry è l'approccio consigliato
ComponentActivity
fornisce ora una ActivityResultRegistry
che consente di gestire il startActivityForResult()
+ onActivityResult()
e requestPermissions()
+ onRequestPermissionsResult()
scorre senza sostituire i metodi nel vostro Activity
o Fragment
, porta maggiore sicurezza tipo via ActivityResultContract
e 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 onActivityResult
processo abbia avuto successo o meno . prepareCall
quindi registra questa chiamata in una nuova funzione ComponentActivity
chiamata ActivityResultRegistry
- torneremo su questo più tardi. ActivityResultContracts.TakePicture()
è uno degli helper integrati che Google ha creato per noi e infine invocare in takePicture
realtà 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.