Die ActivityResultRegistry ist der empfohlene Ansatz
ComponentActivitybietet jetzt eine Funktion ActivityResultRegistry, mit der Sie sowohl die startActivityForResult()+ onActivityResult()als auch die requestPermissions()+ onRequestPermissionsResult()Flows verarbeiten können, ohne die Methoden in Ihrem Activityoder zu überschreiben Fragment, erhöht die Typensicherheit über ActivityResultContractund bietet Hooks zum Testen dieser Flows.
Es wird dringend empfohlen, die in AndroidX Activity 1.2.0-alpha02 und Fragment 1.3.0-alpha02 eingeführten APIs für Aktivitätsergebnisse zu verwenden.
Fügen Sie dies Ihrem hinzu 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"
Wie verwende ich den vorgefertigten Vertrag?
Diese neue API verfügt über die folgenden vorgefertigten Funktionen
- Video aufnehmen
- PickContact
- GetContent
- GetContents
- OpenDocument
- OpenDocuments
- OpenDocumentTree
- CreateDocument
- Wählen
- Ein Bild machen
- Um Erlaubnis bitten
- RequestPermissions
Ein Beispiel, das den takePicture-Vertrag verwendet:
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() }
}
Also, was ist hier los? Lassen Sie es uns etwas aufschlüsseln. takePictureist nur ein Rückruf, der eine nullfähige Bitmap zurückgibt - ob sie null ist oder nicht, hängt davon ab, ob der onActivityResultProzess erfolgreich war oder nicht . prepareCallregistriert dann diesen Anruf in einer neuen Funktion ComponentActivitynamens the ActivityResultRegistry- wir werden später darauf zurückkommen. ActivityResultContracts.TakePicture()ist einer der integrierten Helfer, die Google für uns erstellt hat, und das endgültige Aufrufen takePicturelöst die Absicht auf dieselbe Weise aus, wie Sie es zuvor getan haben Activity.startActivityForResult(intent, REQUEST_CODE).
Wie schreibe ich einen benutzerdefinierten Vertrag?
Einfacher Vertrag, der ein Int als Eingabe verwendet und einen String zurückgibt, der die angeforderte Aktivität im Ergebnis Intent zurückgibt.
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)
}
}
}
Weitere Informationen finden Sie in dieser offiziellen Dokumentation.