如何在Android上管理startActivityForResult?

Hes*_*sam 935 android android-intent android-activity startactivityforresult

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

例如,从主要活动我称之为第二个.在这项活动中,我正在检查手机的某些功能,例如是否有相机.如果它没有,那么我将关闭此活动.此外,在准备期间MediaRecorderMediaPlayer如果出现问题,我将关闭此活动.

如果其设备有摄像头并完全录制,则在用户点击完成按钮后录制视频后,我会将结果(录制视频的地址)发送回主要活动.

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

Nis*_*ant 2379

从您的FirstActivity调用SecondActivity使用 startActivityForResult()方法

例如:

Intent i = new Intent(this, SecondActivity.class);
startActivityForResult(i, 1);
Run Code Online (Sandbox Code Playgroud)

在您的SecondActivity设置中,您要返回的数据FirstActivity.如果您不想返回,请不要设置任何.

例如:SecondActivity如果要发回数据,请执行以下操作:

Intent returnIntent = new Intent();
returnIntent.putExtra("result",result);
setResult(Activity.RESULT_OK,returnIntent);
finish();
Run Code Online (Sandbox Code Playgroud)

如果您不想返回数据:

Intent returnIntent = new Intent();
setResult(Activity.RESULT_CANCELED, returnIntent);
finish();
Run Code Online (Sandbox Code Playgroud)

现在在您的FirstActivity课程中编写以下代码的onActivityResult()方法.

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

    if (requestCode == 1) {
        if(resultCode == Activity.RESULT_OK){
            String result=data.getStringExtra("result");
        }
        if (resultCode == Activity.RESULT_CANCELED) {
            //Write your code if there's no result
        }
    }
}//onActivityResult
Run Code Online (Sandbox Code Playgroud)

  • 所以这取决于你,如果你不需要知道取消的原因,你可以只使用setResult(RESULT_CANCELED); 没有任何意图 (9认同)
  • 对我来说它不起作用 - 这就是我讨厌Android的东西 - 这个系统太不可靠了: - / (6认同)
  • @ismail假设在`SecondActivity`中发生了一些异常,在这种情况下你也需要将结果返回给`FirstActivity`,这样你就可以在catch块中将结果设置为``RESULT_CANCELLED'`并返回`FirstActivty`在"FirstActivity's"的onActivityResult()中你可以检查你是否获得了成功或失败的结果. (3认同)
  • 当 RESUT_CANCELLED 在 setResult(RESULT_CANCELED, returnIntent) 中时放置意图的目的是什么? (2认同)
  • @Lei Leyba调用startActivityForResult()后没有调用finish().First Actvity将进入暂停状态. (2认同)

Sam*_*Sam 49

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

您需要覆盖Activity.onActivityResult()然后检查其参数:

  • requestCode识别哪个应用返回了这些结果.这是你打电话时定义的startActivityForResult().
  • resultCode 通知您此应用程序是成功,失败还是其他不同
  • data保存此应用程序返回的任何信息.这可能是null.


Jul*_*rto 42

补充@ Nishant的答案,返回活动结果的最佳方法是:

Intent returnIntent = getIntent();
returnIntent.putExtra("result",result);
setResult(RESULT_OK,returnIntent);
finish();
Run Code Online (Sandbox Code Playgroud)

我有问题

new Intent();
Run Code Online (Sandbox Code Playgroud)

然后我发现正确的方法是使用

getIntent();
Run Code Online (Sandbox Code Playgroud)

获得当前的意图


Sur*_*gch 41

要在上下文中查看整个过程,这是一个补充答案.有关更多解释,请参阅我更全面的答案.

在此输入图像描述

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);
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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();
    }
}
Run Code Online (Sandbox Code Playgroud)


Dar*_*ish 13

ActivityResultRegistry 是推荐的方法

ComponentActivity现在提供了一个ActivityResultRegistry,让您无需覆盖or 中的方法即可处理startActivityForResult()+onActivityResult()requestPermissions()+onRequestPermissionsResult()流,通过 提高类型安全性,并提供用于测试这些流的钩子。ActivityFragmentActivityResultContract

强烈建议使用 Android 10 Activity 1.2.0-alpha02 和 Fragment 1.3.0-alpha02 中引入的 Activity Result API。

将此添加到您的 build.gradle

def activity_version = "1.2.0-beta01"

// Java language implementation
implementation "androidx.activity:activity:$activity_version"
// Kotlin
implementation "androidx.activity:activity-ktx:$activity_version"
Run Code Online (Sandbox Code Playgroud)

如何使用预建合约

这个新 API 具有以下预建功能

  1. 拍视频
  2. PickContact
  3. 获取内容
  4. 获取内容
  5. 开放文档
  6. 开放文档
  7. 打开文档树
  8. 创建文档
  9. 拨号
  10. 拍照片
  11. 请求权限
  12. 请求权限

使用 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() }
}
Run Code Online (Sandbox Code Playgroud)

那么这里发生了什么?让我们稍微分解一下。takePicture只是一个回调,它返回一个可为空的位图 - 它是否为空取决于该onActivityResult过程是否成功。prepareCall然后将此调用注册到ComponentActivity名为 the的新功能中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)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

查看此官方文档以获取更多信息。


Tom*_*zyk 11

对于那些在onActivityResult中遇到错误requestCode问题的人

如果您是startActivityForResult()从您的呼叫Fragment,则拥有片段的活动会更改requestCode.

如果您想在活动中获得正确的resultCode,请尝试以下操作:

更改:

startActivityForResult(intent, 1); 至:

getActivity().startActivityForResult(intent, 1);


Dav*_*viF 10

如果要使用活动结果更新用户界面,则无法使用" this.runOnUiThread(new Runnable() {} 执行此操作"UI不会刷新新值.相反,你可以这样做:

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

    if (resultCode == RESULT_CANCELED) {
        return;
    }

    global_lat = data.getDoubleExtra("LATITUDE", 0);
    global_lng = data.getDoubleExtra("LONGITUDE", 0);
    new_latlng = true;
}

@Override
protected void onResume() {
    super.onResume();

    if(new_latlng)
    {
        PhysicalTagProperties.this.setLocation(global_lat, global_lng);
        new_latlng=false;
    }
}
Run Code Online (Sandbox Code Playgroud)

这看起来很傻,但效果很好.


San*_*inh 9

startActivityForResult:已在 Android X 中弃用

对于我们拥有的方式registerForActivityResult

在 Java 中:

 // 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);
      }
Run Code Online (Sandbox Code Playgroud)

在科特林:

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)
}
Run Code Online (Sandbox Code Playgroud)

优势:

  1. 新方法是降低我们在从片段或另一个活动中调用活动时所面临的复杂性
  2. 轻松请求任何许可并获得回调


Eld*_*opj 8

科特林中

假设 A 和 B 是活动,导航是从 A -> B 我们需要从 A <- B 返回的结果

一个

    // calling the Activity B
    resultLauncher.launch(Intent(requireContext(), B::class.java))

    // we get data in here from B
    private var resultLauncher =
    registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
        when (result.resultCode) {
            Activity.RESULT_OK -> {
                result.data?.getStringExtra("VALUE")?.let {
                    // data received here
                }
            }
            Activity.RESULT_CANCELED -> {
                // cancel or failure
            }
        }
    }
Run Code Online (Sandbox Code Playgroud)

B

    // Sending result value back to A
    if (success) {
       setResult(RESULT_OK, Intent().putExtra("VALUE", value))
    } else {
       setResult(RESULT_CANCELED)
    }
Run Code Online (Sandbox Code Playgroud)


归档时间:

查看次数:

662723 次

最近记录:

6 年,6 月 前