I am using both an ImagePicker and a barcode reader in a single activity. The main problem is that both of these require onActivityResult() to display the result. As we know a single activity can only have a single onActivityResult() method in it. How can I display both of them?
I have tried using switch cases to assign multiple requestCodes in the onActivityResult() but can't seem to figure out the solution.
Here's the method I tried.
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;
}
}
}
The rest of the answers told to use startActivityForResult() but that method requires Intent to go from one activity to another but I don't want to do this.
In both cases, the libraries you're using provide a way to specify a request code so you can distinguish the results in onActivityResult
.
Your scanQR
object should set a request code, per the source code:
massetBarcode.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
scanQR.setRequestCode(123).initiateScan();
}
});
You getImage()
method should also specify a request code, again, 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
}
Now, you can handle each request code as needed:
@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;
}
}
Closing thought: I've never used either library. I found the solution by 1) assuming any library that provides an Activity you're supposed to invoke for a result would allow you to specify a request code for it and 2) looking through their documentation and source code for how to do that.
I'd encourage you to thoroughly study the documentation and source code for any open source library you intend to use since as soon as you do their code become your code and their bugs become your bugs, so you better know how to fix or workaround them.
Hope that helps!