如何在Android上管理startActivityForResult

如何在Android上管理startActivityForResult,android,android-intent,android-activity,startactivityforresult,Android,Android Intent,Android Activity,Startactivityforresult,在我的活动中,我通过startActivityForResult从主活动调用第二个活动。在我的第二个活动中,有一些方法完成了这个活动(可能没有结果),但是,其中只有一个方法返回结果 例如,在主活动中,我调用第二个活动。在本活动中,我将检查手机的一些功能,例如它是否有摄像头。如果没有,我将关闭此活动。另外,在准备MediaRecorder或MediaPlayer的过程中,如果出现问题,我将关闭此活动 如果它的设备有摄像头,并且录制完成,那么在录制视频后,如果用户单击“完成”按钮,我会将结果(录制视

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

例如,在主活动中,我调用第二个活动。在本活动中,我将检查手机的一些功能,例如它是否有摄像头。如果没有,我将关闭此活动。另外,在准备
MediaRecorder
MediaPlayer
的过程中,如果出现问题,我将关闭此活动

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

如何检查主要活动的结果

如何检查主要活动的结果

您需要覆盖并检查其参数:

  • requestCode
    识别哪个应用程序返回了这些结果。这是由您在调用
    startActivityForResult()
    时定义的
  • resultCode
    通知您此应用程序是否成功、失败或其他情况
  • 数据
    保存此应用程序返回的任何信息。这可能是
    null

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

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

    if (requestCode == LAUNCH_SECOND_ACTIVITY) {
        if(resultCode == Activity.RESULT_OK){
            String result=data.getStringExtra("result");
        }
        if (resultCode == Activity.RESULT_CANCELED) {
            // Write your code if there's no result
        }
    }
} //onActivityResult
例如:

int LAUNCH_SECOND_ACTIVITY = 1
Intent i = new Intent(this, SecondActivity.class);
startActivityForResult(i, LAUNCH_SECOND_ACTIVITY);
SecondActivity
中,设置要返回到
FirstActivity
的数据。如果您不想返回,请不要设置任何

例如:在
SecondActivity
中,如果要发回数据:

Intent returnIntent = new Intent();
returnIntent.putExtra("result",result);
setResult(Activity.RESULT_OK,returnIntent);
finish();
如果不想返回数据:

Intent returnIntent = new Intent();
setResult(Activity.RESULT_CANCELED, returnIntent);
finish();
现在,在您的
FirstActivity
类中,为
onActivityResult()
方法编写以下代码

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

    if (requestCode == LAUNCH_SECOND_ACTIVITY) {
        if(resultCode == Activity.RESULT_OK){
            String result=data.getStringExtra("result");
        }
        if (resultCode == Activity.RESULT_CANCELED) {
            // Write your code if there's no result
        }
    }
} //onActivityResult

要在Kotlin中以更好的方式实现两个活动之间的数据传递,请通过“”。

如果要使用活动结果更新用户界面,则不能使用
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;
    }
}

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

首先在第一个
活动
中使用带有参数的
startActivityForResult()
,如果要将数据从第二个
活动
发送到第一个
活动
中,则使用
Intent
setResult()传递值
方法,并在
onActivityResult()方法中获取该数据。在第一个
活动中,返回活动结果的最佳方法是:

Intent returnIntent = getIntent();
returnIntent.putExtra("result",result);
setResult(RESULT_OK,returnIntent);
finish();
我和你有问题

new Intent();
然后我发现正确的方法是使用

getIntent();

获取当前意图。

适用于那些对

如果您正在从
片段
调用
startActivityForResult()
,则拥有片段的活动将更改请求代码

如果要在活动中获得正确的结果代码,请尝试以下操作:

更改:

startActivityForResult(意图,1);
To:


getActivity().startActivityForResult(intent,1);
示例

要在上下文中查看整个过程,这里有一个补充答案。有关更多解释,请参阅

MainActivity.java

SecondActivity.java


这是Android上非常常见的问题

它可以分为三部分

  • 启动活动B(发生在活动A中)
  • 设置请求的数据(发生在活动B中)
  • 接收请求的数据(发生在活动A中)
  • 星触觉B
  • 设置请求的数据
  • 在本部分中,您将决定在特定事件发生时是否要发回数据

    例如:在活动B中有一个编辑文本和两个按钮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();
    }
    
    不发送数据

    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\u取消响应代码

  • 检索结果
  • 对于那个重写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
        }
    }
    

    您需要重写Activity.onActivityResult():

    建议使用ActivityResultRegistry
    ComponentActivity
    现在提供了一个
    ActivityResultRegistry
    ,允许您处理
    startActivityForResult()
    +
    onActivityResult()
    以及
    requestPermissions()
    +
    onRequestPermissionsResult()
    活动
    片段
    中不重写方法的流,通过
    活动ResultContract
    提高类型安全性,并提供用于测试这些流的挂钩

    强烈建议使用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"
    
    如何使用预制合同 此新API具有以下预构建功能

  • 录影带
  • 拾取触点
  • 获取内容
  • 获取内容
  • 开放文档
  • 开放文档
  • OpenDocumentTree
  • 创建文档
  • 拨盘
  • 拍照
  • 请求许可
  • 请求权限
  • 使用拍摄合同的示例:

    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() }
    }
    
    那么这里发生了什么?让我们稍微分解一下。
    takePicture
    只是一个返回可为空位图的回调-它是否为空取决于
    onActivityResult
    过程是否成功。
    prepareCall
    然后将此调用注册到上的一个新功能中
    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() }
    }
    
    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)
            }
        }
    }
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    
        findViewById(R.id.takeCam).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent=new Intent(getApplicationContext(),TakePhotoActivity.class);
                intent.putExtra("Mode","Take");
                startActivity(intent);
            }
        });
        findViewById(R.id.selectGal).setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Intent intent=new Intent(getApplicationContext(),TakePhotoActivity.class);
                intent.putExtra("Mode","Gallery");
                startActivity(intent);
            }
        });
    }
    
    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
    
    }
    
    private static final int CAMERA_REQUEST = 1888;
    private ImageView imageView;
    private static final int MY_CAMERA_PERMISSION_CODE = 100;
    private static final int PICK_PHOTO_FOR_AVATAR = 0;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_take_photo);
    
        imageView=findViewById(R.id.imageView);
    
        if(getIntent().getStringExtra("Mode").equals("Gallery"))
        {
            pickImage();
        }
        else {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (checkSelfPermission(Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
                    requestPermissions(new String[]{Manifest.permission.CAMERA}, MY_CAMERA_PERMISSION_CODE);
                } else {
                    Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                    startActivityForResult(cameraIntent, CAMERA_REQUEST);
                }
            }
        }
    }
    public void pickImage() {
        Intent intent = new Intent(Intent.ACTION_PICK);
        intent.setType("image/*");
        startActivityForResult(intent, PICK_PHOTO_FOR_AVATAR);
    }
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
    {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == MY_CAMERA_PERMISSION_CODE)
        {
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED)
            {
                Intent cameraIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
                startActivityForResult(cameraIntent, CAMERA_REQUEST);
            }
            else
            {
                Toast.makeText(this, "Camera Permission Denied..", Toast.LENGTH_LONG).show();
            }
        }
    }
    
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == CAMERA_REQUEST && resultCode == Activity.RESULT_OK) {
            Bitmap photo = (Bitmap) data.getExtras().get("data");
            imageView.setImageBitmap(photo);
        }
            if (requestCode == PICK_PHOTO_FOR_AVATAR && resultCode == Activity.RESULT_OK) {
                if (data == null) {
                    Log.d("ABC","No Such Image Selected");
                    return;
                }
                try {
                    Uri selectedData=data.getData();
                    Log.d("ABC","Image Pick-Up");
                    imageView.setImageURI(selectedData);
                    InputStream inputStream = getApplicationContext().getContentResolver().openInputStream(selectedData);
                    Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
                    Bitmap bmp=MediaStore.Images.Media.getBitmap(getContentResolver(),selectedData);
                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch(IOException e){
    
                }
        }
    }
    
    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;
                        }
                    }
                });
    
    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);
                    }
                });
    
     // 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);
          }
    
    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)
    }