ActivityResultRegistry - рекомендуемый подход
ComponentActivityтеперь предоставляет, ActivityResultRegistryкоторый позволяет вам обрабатывать потоки startActivityForResult()+, onActivityResult()а также requestPermissions()+ onRequestPermissionsResult()без переопределения методов в вашем Activityили Fragment, обеспечивает повышенную безопасность типов через ActivityResultContractи предоставляет ловушки для тестирования этих потоков.
Настоятельно рекомендуется использовать API Result Activity, представленные в AndroidX Activity 1.2.0-alpha02 и Fragment 1.3.0-alpha02.
Добавьте это к вашему 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"
Как использовать готовый договор?
Этот новый API имеет следующие встроенные функции
- TakeVideo
- PickContact
- GetContent
- GetContents
- OpenDocument
- OpenDocuments
- OpenDocumentTree
- CreateDocument
- Набирать номер
- Сделать фотографию
- Просить разрешения
- RequestPermissions
Пример, использующий контракт 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() }
}
Так что здесь происходит? Давайте разберемся с этим немного. takePictureэто просто обратный вызов, который возвращает обнуляемое растровое изображение - независимо от того, является ли оно пустым, зависит от того, был ли onActivityResultпроцесс успешным. prepareCallзатем регистрирует этот вызов в новой функции ComponentActivityпод названием ActivityResultRegistry- мы вернемся к этому позже. ActivityResultContracts.TakePicture()является одним из встроенных помощников, которые Google создал для нас, и, наконец, вызов на takePictureсамом деле запускает Намерение так же, как ранееActivity.startActivityForResult(intent, REQUEST_CODE) .
Как написать заказной договор?
Простой контракт, который принимает Int в качестве входных данных и возвращает строку, запрошенную Activity, возвращается в результате 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)
}
}
}
Проверьте эту официальную документацию для получения дополнительной информации.