如何在一个活动中添加多个 onActivityResult() 而不去其他活动? [复制]

Posted

技术标签:

【中文标题】如何在一个活动中添加多个 onActivityResult() 而不去其他活动? [复制]【英文标题】:How to add multiple onActivityResult() in a single activity without going to other activities? [duplicate] 【发布时间】:2020-05-05 17:42:29 【问题描述】:

我在一个活动中同时使用 ImagePicker 和条形码阅读器。主要问题是这两个都需要 onActivityResult() 来显示结果。正如我们所知,单个活动中只能有一个 onActivityResult() 方法。如何同时显示它们?

我曾尝试使用 switch case 在 onActivityResult() 中分配多个 requestCodes,但似乎无法找出解决方案。

这是我尝试过的方法。

public class MainActivity extends AppCompatActivity

private TextView mIdentificationNumber;
private IntentIntegrator scanQR;

//Authentication For Firebase.
private FirebaseAuth mAuth;

//Toolbar
private Toolbar mToolBar;

private DatabaseReference mUserRef;

private ImageView mAssetImg;
private EditText massetName, massetModel, massetBarcode, massetArea, massetDescription;

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

    //Getting the Present instance of the FireBase Authentication
    mAuth = FirebaseAuth.getInstance();

    //Finding The Toolbar with it's unique Id.
    mToolBar = (Toolbar) findViewById(R.id.main_page_toolbar);

    //Setting Up the ToolBar in The ActionBar.
    setSupportActionBar(mToolBar);

    if (mAuth.getCurrentUser() != null)

        mUserRef = FirebaseDatabase.getInstance().getReference().child("Users")
                .child(mAuth.getCurrentUser().getUid());
        mUserRef.keepSynced(true);

    

    massetBarcode = (EditText) findViewById(R.id.BarcodeAsset);
    scanQR = new IntentIntegrator(this);
    massetBarcode.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View v) 

            scanQR.initiateScan();

        
    );

    mAssetImg = (ImageView) findViewById(R.id.asset_img);
    mAssetImg.setOnClickListener(new View.OnClickListener() 
        @Override
        public void onClick(View v) 

            getImage();
        
    );



//OnStart Method is started when the Authentication Starts.
@Override
public void onStart() 
    super.onStart();
    // Check if user is signed in (non-null).
    FirebaseUser currentUser = mAuth.getCurrentUser();

    if (currentUser == null)

        startUser();

     else 

        mUserRef.child("online").setValue("true");
        Log.d("STARTING THE ACTIVITY" , "TRUE");

    


@Override
protected void onPause() 
    super.onPause();

    FirebaseUser currentUser = mAuth.getCurrentUser();

    if (currentUser != null)

        mUserRef.child("online").setValue(ServerValue.TIMESTAMP);
        Log.d("STOPPING THE ACTIVITY" , "TRUE");

    



private void startUser() 

    //Sending the user in the StartActivity If the User Is Not Logged In.
    Intent startIntent = new Intent(MainActivity.this , AuthenticationActivity.class);
    startActivity(startIntent);
    //Finishing Up The Intent So the User Can't Go Back To MainActivity Without LoggingIn.
    finish();



//Setting The Menu Options In The AppBarLayout.
@Override
public boolean onCreateOptionsMenu(Menu menu) 
    super.onCreateOptionsMenu(menu);
    //Inflating the Menu with the Unique R.menu.Id.
    getMenuInflater().inflate(R.menu.main_menu , menu);

    return true;


//Setting the Individual Item In The Menu.(Logout Button)
@Override
public boolean onOptionsItemSelected(MenuItem item) 
    super.onOptionsItemSelected(item);

    if (item.getItemId() == R.id.main_logout_btn)

        FirebaseAuth.getInstance().signOut();
        startUser();

    

    return true;


private void getImage() 

    ImagePicker.Companion.with(this)
            .crop()                 //Crop image(Optional), Check Customization for more option
            .compress(1024)         //Final image size will be less than 1 MB(Optional)
            .maxResultSize(1080, 1080)  //Final image resolution will be less than 1080 x 1080(Optional)
            .start();



@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) 
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) 
        case 0:
            IntentResult result = IntentIntegrator.parseActivityResult(requestCode, resultCode, data);
            if (result != null) 
                if (result.getContents() == null) 
                    Toast.makeText(this, "Cancelled", Toast.LENGTH_LONG).show();
                 else 

                    massetBarcode.setText(result.getContents());

                    Toast.makeText(this, "Scanned: " + result.getContents(), Toast.LENGTH_LONG).show();
                
            
            break;

        case 1:
            if (resultCode == Activity.RESULT_OK) 

                assert data != null;
                Uri imageURI = data.getData();
                mAssetImg.setImageURI(imageURI);

            
            break;
    


其余的答案告诉使用 startActivityForResult() 但该方法需要 Intent 从一个活动转到另一个,但我不想这样做。

【问题讨论】:

你能贴出你的片段代码吗? 如果您想在 2 个活动之间进行通信 startActivityForResult 将使用不同的请求代码解决您的问题。但是如果你想在片段和活动之间进行通信,你应该使用接口。见***.com/questions/14247954/… @mohnage7 嘿,我在这个问题上犯了一个错误,它不是一个片段,而是一个图像选择器,它直接进入画廊选择图像并在 onActivityResult() 方法中获取结果。 【参考方案1】:

在这两种情况下,您使用的库都提供了一种指定请求代码的方法,以便您可以区分 onActivityResult 中的结果。

您的scanQR 对象应设置请求代码per the source code:

massetBarcode.setOnClickListener(new View.OnClickListener() 
    @Override
    public void onClick(View v) 
        scanQR.setRequestCode(123).initiateScan();
    
);

getImage() 方法还应该指定一个请求代码,同样,per the library's source code。

private void getImage() 
    ImagePicker.Companion.with(this)
        .crop()                 //Crop image(Optional), Check Customization for more option
        .compress(1024)         //Final image size will be less than 1 MB(Optional)
        .maxResultSize(1080, 1080)  //Final image resolution will be less than 1080 x 1080(Optional)
        .start(456); // Start with request code

现在,您可以根据需要处理每个请求代码:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) 
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) 
        case 123:
            // HANDLE BARCODE
            break;

        case 456:
            // HANDLE IMAGE
            break;
    

结束思想:我从未使用过这两个库。我通过以下方式找到了解决方案:1)假设任何提供您应该为结果调用的 Activity 的库都允许您为其指定请求代码,以及 2)查看他们的文档和源代码以了解如何做到这一点。

我鼓励您彻底研究您打算使用的任何开源库的文档和源代码,因为一旦您使用它们的代码就会变成您的代码,它们的错误就会变成您的错误,因此您最好知道如何修复或解决方法。

希望有帮助!

【讨论】:

你好,我问错了,不是fragment,而是imagepicker,直接进入gallery挑选图片,在onActivityResult()方法中获取结果。条形码阅读器是第三方库。我更正了这个问题。 OK - 在这两种情况下,您都没有指定要在 onActivityResult 中使用的代码。显示扫描仪和图像选择器的代码,或指向您正在使用的第 3 方库。 ImagePicker - github.com/Dhaval2404/ImagePicker 条码扫描仪 - github.com/journeyapps/zxing-android-embedded【参考方案2】:

startActivityForResult 方法可以使用第二个参数,一个数字,以便您区分结果

startActivityForResul(intent, 8)

您不需要在其他活动中重新设置代码,这是在后台处理的。所以你可能想将数字添加为常量

private static final CAMERA_INTENT = 2

然后像这样使用它

startActivityForResul(intent, CAMERA_INTENT)

终于在onActivityResult实现了案例基础

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) 

if (CAMERA_INTENT == requestCode) 
    //DO PHOTO STUFF


你需要评估的参数是requestCode

【讨论】:

startActivityForResult() 需要intent 作为参数,实例化一个intent 需要两个activity。我不想从一项活动转到另一项活动。 同理,将显式意图改成隐式意图Intent intent = new Intent(Intent.CAMERA_ACTION); startActivityForResult(intent, 7); Intent.CAMERA_ACTION 显示错误 你不能指望 SO 为你完成所有工作 这里是常见意图的文档 developer.android.com/guide/components/intents-common 这里是显式和隐式意图 developer.android.com/guide/components/intents-filters 在这里你有所有的意图 developer.android.com/reference/android/content/Intent 你的问题是如何为 1 个活动的结果进行 2 个活动,这是解决方案,其他问题,其他帖子【参考方案3】:

为了从片段中获取结果到您的 Activity,您可以使用Interface 来启用它们之间的通信。

StartActivityForResult 用于启动活动并从中获取结果。

请阅读更多信息from here。

【讨论】:

以上是关于如何在一个活动中添加多个 onActivityResult() 而不去其他活动? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

向多个活动添加相同的上下文菜单

在 RecyclerView 项目上添加多个 onClickListener

如何在android中的操作栏上添加多个图标?

如何为多个活动注册制作网站? [关闭]

如何绘制 UML 活动图

将行添加到多个工作表时清除错误