ActivityResultRegistry es el enfoque recomendado
ComponentActivity
Ahora proporciona una ActivityResultRegistry
que le permite manejar el startActivityForResult()
+ onActivityResult()
, así como requestPermissions()
+ onRequestPermissionsResult()
fluye sin anulando métodos en su Activity
o Fragment
, aporta una mayor seguridad a través de tipo ActivityResultContract
, y proporciona enlaces para probar estos flujos.
Se recomienda encarecidamente utilizar las API de resultados de actividad introducidas en AndroidX Activity 1.2.0-alpha02 y Fragment 1.3.0-alpha02.
Agregue esto a su 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"
¿Cómo usar el contrato preconstruido?
Esta nueva API tiene las siguientes funcionalidades preconstruidas
- Toma video
- PickContact
- Obtener el contenido
- GetContents
- OpenDocument
- OpenDocuments
- OpenDocumentTree
- CreateDocument
- Marcar
- Tomar la foto
- Solicitar permiso
- RequestPermissions
Un ejemplo que utiliza takePicture contract:
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() }
}
Entonces, ¿qué está pasando aquí? Vamos a desglosarlo un poco. takePicture
es solo una devolución de llamada que devuelve un mapa de bits anulable: si es nulo o no depende de si el onActivityResult
proceso fue exitoso o no . prepareCall
luego registra esta llamada en una nueva función ComponentActivity
llamada ActivityResultRegistry
- volveremos a esto más adelante. ActivityResultContracts.TakePicture()
es uno de los ayudantes integrados que Google ha creado para nosotros, y finalmente invocandotakePicture
realidad activa la intención de la misma manera que lo haría anteriormente Activity.startActivityForResult(intent, REQUEST_CODE)
.
¿Cómo escribir un contrato personalizado?
Contrato simple que toma un Int como Entrada y devuelve una Cadena que la Actividad solicitada devuelve en la Intención del resultado.
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)
}
}
}
Consulte esta documentación oficial para más información.