ActivityResultRegistry jest zalecanym podejściem
ComponentActivity
teraz zapewnia opcję, ActivityResultRegistry
która pozwala obsługiwać zarówno przepływy startActivityForResult()
+, onActivityResult()
jak i requestPermissions()
+ onRequestPermissionsResult()
bez nadpisywania metod w twoim Activity
lub Fragment
, zapewnia zwiększone bezpieczeństwo typu poprzez ActivityResultContract
, i zapewnia zaczepy do testowania tych przepływów.
Zdecydowanie zaleca się stosowanie interfejsów API wyników wyników wprowadzonych w AndroidX Activity 1.2.0-alpha02 i Fragment 1.3.0-alpha02.
Dodaj to do swojego 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"
Jak korzystać z gotowej umowy?
Ten nowy interfejs API ma następujące wstępnie zbudowane funkcje
- Weź film
- PickContact
- Pobierz zawartość
- GetContents
- OpenDocument
- OpenDocuments
- OpenDocumentTree
- CreateDocument
- Wybierz
- Zrób zdjęcie
- Prośba o pozwolenie
- RequestPermissions
Przykład wykorzystujący umowę 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() }
}
Co się tu dzieje? Rozbijmy to lekko. takePicture
jest tylko wywołaniem zwrotnym, które zwraca zerowalną bitmapę - to, czy jest ona pusta, zależy od tego, czy onActivityResult
proces się powiódł, czy nie . prepareCall
następnie rejestruje to wywołanie w nowej funkcji o ComponentActivity
nazwie ActivityResultRegistry
- wrócimy do tego później. ActivityResultContracts.TakePicture()
jest jednym z wbudowanych pomocników, które Google dla nas stworzyło, a wreszcie wywołanie takePicture
faktycznie wyzwala zamiar w taki sam sposób, jak wcześniej Activity.startActivityForResult(intent, REQUEST_CODE)
.
Jak napisać niestandardową umowę?
Prosty kontrakt, który przyjmuje Int jako dane wejściowe i zwraca ciąg znaków, który zażądał działania, zwraca wynik 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)
}
}
}
Sprawdź tę oficjalną dokumentację, aby uzyskać więcej informacji.