O ActivityResultRegistry é a abordagem recomendada
ComponentActivity
agora oferece uma ActivityResultRegistry
que lhe permite lidar com o startActivityForResult()
+ onActivityResult()
, bem como requestPermissions()
+ onRequestPermissionsResult()
flui sem substituir métodos em sua Activity
ou Fragment
, traz maior segurança Tipo de viaActivityResultContract
, e fornece ganchos para testar esses fluxos.
É altamente recomendável usar as APIs de resultado da atividade introduzidas na atividade AndroidX 1.2.0-alpha02 e no fragmento 1.3.0-alpha02.
Adicione isto ao seu 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"
Como usar o contrato pré-construído?
Essa nova API possui as seguintes funcionalidades pré-criadas
- TakeVideo
- PickContact
- Obter conteudo
- GetContents
- OpenDocument
- OpenDocuments
- OpenDocumentTree
- CreateDocument
- Discar
- Tire uma foto
- RequestPermission
- RequestPermissions
Um exemplo que usa o contrato 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() }
}
Então, o que está acontecendo aqui? Vamos dividir um pouco. takePicture
é apenas um retorno de chamada que retorna um bitmap anulável - se é nulo ou não, depende se o onActivityResult
processo foi ou não bem-sucedido. prepareCall
depois registra essa chamada em um novo recurso ComponentActivity
chamado ActivityResultRegistry
- voltaremos a isso mais tarde. ActivityResultContracts.TakePicture()
é um dos ajudantes internos que o Google criou para nós e, finalmente, a chamada takePicture
realmente aciona a intenção da mesma maneira que você faria anteriormente Activity.startActivityForResult(intent, REQUEST_CODE)
.
Como escrever um contrato personalizado?
Contrato simples que pega um Int como uma Entrada e retorna uma String que solicitou a Atividade retorna no resultado 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)
}
}
}
Verifique esta documentação oficial para mais informações.