在我的活动中,我通过startActivityForResult从主活动中调用第二个活动。在我的第二个活动中,有一些方法完成这个活动(可能没有结果),但是,只有其中一个返回结果。

例如,从主活动中调用第二个活动。在这个活动中,我正在检查手机的一些功能,比如它是否有摄像头。如果没有,我就关闭这个活动。此外,在MediaRecorder或MediaPlayer的准备过程中,如果发生问题,我将关闭此活动。

如果它的设备有摄像头,并且录制完成,那么在录制视频后,如果用户单击done按钮,那么我将把结果(录制视频的地址)发送回主活动。

如何检查主活动的结果?


当前回答

你需要重写Activity.onActivityResult():

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (resultCode == RESULT_CODE_ONE) {

       String a = data.getStringExtra("RESULT_CODE_ONE");

    }
    else if(resultCode == RESULT_CODE_TWO){

       // b was clicked
    }
    else{

    }
}

其他回答

这在Android上是一个非常常见的问题

它可以被分解成三个部分

开始活动B(发生在活动A中) 设置请求的数据(发生在活动B中) 接收请求的数据(发生在活动A中)

startActivity B

Intent i = new Intent(A.this, B.class);
startActivity(i);

设置请求数据

在这一部分中,您将决定在发生特定事件时是否要发回数据。

例如:在活动B中有一个EditText和两个按钮b1, b2。 单击按钮b1将数据发送回活动A。 单击按钮b2不会发送任何数据。

发送数据

b1......clickListener
{
    Intent resultIntent = new Intent();
    resultIntent.putExtra("Your_key", "Your_value");
    setResult(RES_CODE_A, resultIntent);
    finish();
}

不发送数据

b2......clickListener
{
   setResult(RES_CODE_B, new Intent());
   finish();
}

用户单击后退按钮

默认情况下,结果设置为Activity。RESULT_CANCEL响应代码

检索结果

重写onActivityResult方法

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);

    if (resultCode == RES_CODE_A) {

       // b1 was clicked
       String x = data.getStringExtra("RES_CODE_A");

    }
    else if(resultCode == RES_CODE_B){

       // b2 was clicked
    }
    else{
       // The back button was clicked
    }
}

startActivityForResult:在Android X中已弃用

对于新方法,我们有registerForActivityResult。

在爪哇:

 // You need to create a launcher variable inside onAttach or onCreate or global, i.e, before the activity is displayed
 ActivityResultLauncher<Intent> launchSomeActivity = registerForActivityResult(
     new ActivityResultContracts.StartActivityForResult(),
     new ActivityResultCallback<ActivityResult>() {
              @Override
              public void onActivityResult(ActivityResult result) {
                   if (result.getResultCode() == Activity.RESULT_OK) {
                         Intent data = result.getData();
                         // your operation....
                    }
               }
      });

      public void openYourActivity() {
            Intent intent = new Intent(this, SomeActivity.class);
            launchSomeActivity.launch(intent);
      }

在Kotlin:

var resultLauncher = registerForActivityResult(StartActivityForResult()) { result ->
    if (result.resultCode == Activity.RESULT_OK) {
        val data: Intent? = result.data
        // your operation...
    }
}

fun openYourActivity() {
    val intent = Intent(this, SomeActivity::class.java)
    resultLauncher.launch(intent)
}

优势:

新的方法是降低我们从一个片段或另一个活动调用活动时所面临的复杂性 很容易要求任何许可和得到回调

我将在简短的回答中发布Android X的新“方式”(因为在某些情况下,你不需要自定义注册表或合同)。如需详细信息,请参见:从活动获取结果

重要提示:Android X的向后兼容性存在bug,所以你必须在Gradle文件中添加fragment_version。否则你会得到一个异常“新结果API错误:只能使用低16位的requestCode”。

dependencies {

    def activity_version = "1.2.0-beta01"
    // Java language implementation
    implementation "androidx.activity:activity:$activity_version"
    // Kotlin
    implementation "androidx.activity:activity-ktx:$activity_version"

    def fragment_version = "1.3.0-beta02"
    // Java language implementation
    implementation "androidx.fragment:fragment:$fragment_version"
    // Kotlin
    implementation "androidx.fragment:fragment-ktx:$fragment_version"
    // Testing Fragments in Isolation
    debugImplementation "androidx.fragment:fragment-testing:$fragment_version"
}

现在你只需要添加活动的成员变量。这使用预定义的注册表和通用契约。

public class MyActivity extends AppCompatActivity{

   ...

    /**
     * Activity callback API.
     */
    // https://developer.android.com/training/basics/intents/result
    private ActivityResultLauncher<Intent> mStartForResult = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(),

            new ActivityResultCallback<ActivityResult>() {

                @Override
                public void onActivityResult(ActivityResult result) {
                    switch (result.getResultCode()) {
                        case Activity.RESULT_OK:
                            Intent intent = result.getData();
                            // Handle the Intent
                            Toast.makeText(MyActivity.this, "Activity returned ok", Toast.LENGTH_SHORT).show();
                            break;
                        case Activity.RESULT_CANCELED:
                            Toast.makeText(MyActivity.this, "Activity canceled", Toast.LENGTH_SHORT).show();
                            break;
                    }
                }
            });

在新API之前,你有:

btn.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                Intent intent = new Intent(MyActivity .this, EditActivity.class);
                startActivityForResult(intent, Constants.INTENT_EDIT_REQUEST_CODE);
            }
        });

您可能注意到请求代码现在由谷歌框架生成(并保持)。 你的代码变成:

 btn.setOnClickListener(new View.OnClickListener() {

                @Override
                public void onClick(View v) {
                    Intent intent = new Intent(MyActivity .this, EditActivity.class);
                    mStartForResult.launch(intent);
                }
            });

例子

为了在上下文中了解整个过程,这里有一个补充的答案。更多的解释请看我的完整回答。

MainActivity.java

public class MainActivity extends AppCompatActivity {

    // Add a different request code for every activity you are starting from here
    private static final int SECOND_ACTIVITY_REQUEST_CODE = 0;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    // "Go to Second Activity" button click
    public void onButtonClick(View view) {

        // Start the SecondActivity
        Intent intent = new Intent(this, SecondActivity.class);
        startActivityForResult(intent, SECOND_ACTIVITY_REQUEST_CODE);
    }

    // This method is called when the second activity finishes
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        // check that it is the SecondActivity with an OK result
        if (requestCode == SECOND_ACTIVITY_REQUEST_CODE) {
            if (resultCode == RESULT_OK) { // Activity.RESULT_OK

                // get String data from Intent
                String returnString = data.getStringExtra("keyName");

                // set text view with string
                TextView textView = (TextView) findViewById(R.id.textView);
                textView.setText(returnString);
            }
        }
    }
}

SecondActivity.java

public class SecondActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_second);
    }

    // "Send text back" button click
    public void onButtonClick(View view) {

        // get the text from the EditText
        EditText editText = (EditText) findViewById(R.id.editText);
        String stringToPassBack = editText.getText().toString();

        // put the String to pass back into an Intent and close this activity
        Intent intent = new Intent();
        intent.putExtra("keyName", stringToPassBack);
        setResult(RESULT_OK, intent);
        finish();
    }
}

如何检查主要活动的结果?

你需要重写Activity.onActivityResult(),然后检查它的参数:

requestCode标识哪个应用程序返回了这些结果。这是在调用startActivityForResult()时由您定义的。 resultCode告诉你这个应用程序是成功了、失败了还是其他什么 data保存此应用程序返回的任何信息。这可能是空的。