我有一个主要活动,可以根据情况作为调用不同活动的切入点。除其他外,我使用Firebase Auth来管理用户登录:
startActivityForResult(
AuthUI.getInstance().createSignInIntentBuilder()
.setAvailableProviders(providers)
.build(),
RC_SIGN_IN)
我覆盖onActivityResult()
来区分返回的意图/数据,例如:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
when (requestCode) {
REQUEST_CODE_1 -> {
// update UI and stuff
}
RC_SIGN_IN -> {
// check Firebase log in
}
// ...
}
}
使用documentation强烈推荐的Activity Result API,我认为我应该在prepareCall()
之前制作ActivityResultLauncher
,并确保启动时活动处于创建状态,但我仍然不明白如何像onActivityResult()
中那样(至少在一处)优雅地处理多个活动结果。
看着this article,似乎我需要实现ActivityResultContract
类型的多个子内部类(因此有多个prepareCall()
?),因为它们假设是不同的合同,对吗?有人可以给我看看一些反映上述onActivityResult()
逻辑的基本例子吗?
答案 0 :(得分:4)
您可以根据需要调用任意多个Activity以获取结果,并为每个回调分别设置回调:
val startForResult = registerForActivityResult(ActivityResultContracts.StartActivityForResult())
{ result: ActivityResult ->
if (result.resultCode == Activity.RESULT_OK) {
// you will get result here in result.data
}
}
}
startForResult(Intent(activity, CameraCaptureActivity::class.java))
您只需要指定Activity类-CameraCaptureActivity::class.java
更新:
The prepareCall() method has been renamed to registerForActivityResult() in Activity 1.2.0-alpha04 and Fragment 1.3.0-alpha04. And it should be startForResult.launch(...) in the last line
感谢拉斐尔·塔瓦雷斯进行更新
答案 1 :(得分:3)
在这种情况下,AuthUI返回的内容已经是一个Intent,因此,我们可以像下面的示例一样使用它。
private val startForResult =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
when(result.resultCode){
RESULT_OK -> {
val intent = result.data
// Handle the Intent...
mUser = FirebaseAuth.getInstance().currentUser
}
RESULT_CANCELED -> {
} else -> {
} }
}
使用以下任何一种方法从任何地方(例如单击按钮)开始活动:
AuthUI.getInstance().createSignInIntentBuilder().setAvailableProviders(providers)
.build().apply {
startForResult.launch(this)
}
答案 2 :(得分:3)
首先,不要忘记将此添加到您的 Gradle 依赖项
implementation 'androidx.activity:activity-ktx:1.2.0-alpha05'
implementation 'androidx.fragment:fragment-ktx:1.3.0-alpha05'
其次,通过扩展一个名为 ActivityResultContract<I, O>
的抽象类来创建结果契约。我的意思是输入的类型,O 的意思是输出的类型。然后你只需要覆盖2个方法
class PostActivityContract : ActivityResultContract<Int, String?>() {
override fun createIntent(context: Context, input: Int): Intent {
return Intent(context, PostActivity::class.java).apply {
putExtra(PostActivity.ID, postId)
}
}
override fun parseResult(resultCode: Int, intent: Intent?): String? {
val data = intent?.getStringExtra(PostActivity.TITLE)
return if (resultCode == Activity.RESULT_OK && data != null) data
else null
}
}
最后一步是将合约注册到 Activity
。您需要将自定义合同和回调传递给 registerForActivityResult
。
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
start_activity_contract.setOnClickListener {
openPostActivityCustom.launch(1)
}
}
// Custom activity result contract
private val openPostActivityCustom =
registerForActivityResult(PostActivityContract()) { result ->
// parseResult will return this as string?
if (result != null) toast("Result : $result")
else toast("No Result")
}
}
欲了解更多信息,请查看此FileInputFormat
答案 3 :(得分:1)
从现在开始,startActivityForResult()
已过时,请改用新方法。
示例
public void openActivityForResult() {
//Instead of startActivityForResult use this one
Intent intent = new Intent(this,OtherActivity.class);
someActivityResultLauncher.launch(intent);
}
//Instead of onActivityResult() method use this one
ActivityResultLauncher<Intent> someActivityResultLauncher = registerForActivityResult(
new ActivityResultContracts.StartActivityForResult(),
new ActivityResultCallback<ActivityResult>() {
@Override
public void onActivityResult(ActivityResult result) {
if (result.getResultCode() == Activity.RESULT_OK) {
// Here, no request code
Intent data = result.getData();
doSomeOperations();
}
}
});
答案 4 :(得分:1)
将此用于 Firebase AuthUI;
final ActivityResultLauncher<Intent> launcher = registerForActivityResult(
new FirebaseAuthUIActivityResultContract(), this::onSignInResult);
binding.loginSignup.setOnClickListener(view -> {
List<AuthUI.IdpConfig> provider = Arrays.asList(new AuthUI.IdpConfig.EmailBuilder().build(),
new AuthUI.IdpConfig.GoogleBuilder().build(),
new AuthUI.IdpConfig.PhoneBuilder().build());
Intent intent = AuthUI.getInstance()
.createSignInIntentBuilder()
.setIsSmartLockEnabled(false)
.setAlwaysShowSignInMethodScreen(true)
.setAvailableProviders(provider)
.build();
launcher.launch(intent);
});
private void onSignInResult(FirebaseAuthUIAuthenticationResult result) {
if (result.getResultCode() == RESULT_OK) {
FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
if (user != null) {
if (user.getMetadata() != null) {
if (user.getMetadata().getCreationTimestamp() != user.getMetadata().getLastSignInTimestamp()) {
Toast.makeText(this, "Welcome Back", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Welcome", Toast.LENGTH_SHORT).show();
}
startMainActivity();
}
}
} else {
IdpResponse response = result.getIdpResponse();
if (response == null)
Toast.makeText(this, "Canceled By You", Toast.LENGTH_SHORT).show();
else Log.d(TAG, "onCreate: ActivityResult" + response.getError());
}
}
private void startMainActivity() {
Intent intent = new Intent(LoginActivity.this, MainActivity.class);
startActivity(intent);
finish();
}
像这样。
答案 5 :(得分:0)
如果您从片段开始活动并将结果返回到片段,请执行此操作。
在片段中:
private lateinit var activityResult: ActivityResultLauncher<Intent>
activityResult = registerForActivityResult(
ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == RESULT_OK) {
val data = result.data
doSomeOperations(data)
}
}
SomeActivity.showScreen(activityResult, requireContext())
活动中:
// activity?.setResult(Activity.RESULT_OK) doesn't change.
companion object {
fun showScreen(activityResult: ActivityResultLauncher<Intent>, context: Context) {
val intent = Intent(context, SomeActivity::class.java)
activityResult.launch(intent)
}
}
答案 6 :(得分:0)
List<AuthUI.IdpConfig> providers = Arrays.asList(
new AuthUI.IdpConfig.EmailBuilder().build(),
new AuthUI.IdpConfig.GoogleBuilder().build());
ActivityResultLauncher<Intent> launcher = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), result -> {
if (result.getResultCode() == Activity.RESULT_OK) {
Log.v("LOGIN OK", "OK Result for Login");
}
});
launcher.launch(AuthUI.getInstance()
.createSignInIntentBuilder()
.setIsSmartLockEnabled(false)
.setAvailableProviders(providers)
.build());