How to pass and return Intent (Camera) - android

I need something little different than usual.
I have like 20 buttons that can take image. I use same handler. Depending on what button clicked - I just pass "ButtonIndex" inside intent to camera. I would like to get that value back in OnActivityResult so I know what to process.
Is that possible? I tried to read from returned intent but value get's lost.

Yep. You can use startActivityForResult (Intent intent, int requestCode)
The requestcode will be returned when the activity exits.

Related

Retrieving putExtra values from onActivityResult intent

I am trying to append certain data to an intent, before using StartActivityForResult on it.
When the intent returns in OnActivityForResult, I would like to access the data I appended in the intent. So I can correlate the data retrieved in the intent, with things like database entries, container ids, etc.
Unfortunately the intent that returns does not seem to be the same one I started. I tried comparing (==) the old and the new intent in a test case, and the result failed, and not surprisingly then the data I am trying append is not there. Is there any link back to the original intent?
Basic idea of what I've tried:
Code to StartActivityForResult in psuedo code:
Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
i.putExtra([-Key-], [int]);
i.putExtra([-Key-], [int]);
....
getParentFragment().startActivityForResult(i, requestCode);
Pseudo Code for OnActivityResult
#Override
public void onActivityResult(int requestCode, int resultCode, Intent intent) {
....
switch(requestcode){
case RESULT_LOAD_IMAGE :
//These always evaluate to default. The intent returns with the picture,
//and I process it fine (with default values), but any extra data i try to append
//to the intent is lost.
int rowId = intent.getIntExtra([-Key-], [-def_value-]);
....
....
break;
default:
throw new RuntimeException();
}
}
When you launch an Activity using implicit Intent resolution, which is what you are doing when you do this:
Intent i = new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI)
....
getParentFragment().startActivityForResult(i, requestCode);
you don't have any guarantees what Activity will actually be chosen to perform the action. Because of this, there isn't any "contract" between your Activity and the Activity that will be used to perform the desired action. This is, unfortunately, one of the disavantages of using implicit Intent resolution. Because there is no contract between the 2 Activities, you can't be sure what you are going to get in the result that is returned to you in onActivityResult().
If you look at the documentation for ACTION_PICK, it at least indicates what "should" happen (if the selected Activity actually behaves the way the documentation reads):
Input: getData() is URI containing a directory of data
(vnd.android.cursor.dir/*) from which to pick an item.
Output: The URI of the item that was picked.
This indicates that you should provide a URI that contains a directory of data and that you will be returned an Intent containing the URI of the item that was picked. That's it. That's all you can expect to get. You can put lots of other "extras" in the Intent that you pass to the Activity with ACTION_PICK, but that Activity doesn't care about those extras and will just ignore them. The Activity that performs the ACTION_PICK will create a new Intent containing the URI of the selected item and pass that back to you. It doesn't pass your original Intent back. The "input Intent" and the "output Intent" are completely different and don't have anything to do with each other.
To solve your problem, I'd suggest that you create a unique integer requestCode and save your "extras" in a table or map in your Activity associated with that requestCode. Then you can launch the ACTION_PICK activity using the requestCode. In onActivityResult() you can use the requestCode argument that comes back to find your "extras" that you saved and you'll be able to associate the returned URI with them.
NOTE: One more thing: When you call startActivityForResult() your Activity will be paused and the launched Activity will run. Your Activity won't be resumed until onActivityResult() is called. This means that you will only ever be able to have one ACTION_PICK pending at any given time. For this reason you may not need a way to associate a specific PICK action with any given data.

android launched activity exit callback function

I am launching the android setting activity, from an android service.
Intent LaunchIntent = getPackageManager().getLaunchIntentForPackage("com.android.settings");
startActivity(LaunchIntent);
I am searching, how I can detect if the setting activity is closed,As I need some callback method.
If there is a callback method to know the settings or any other app like browsers,if launched in this method to know if the launched activity is exit its own.
Since settings and browsers are general code we can't put broadcast code in these activities.
Use startActivityForResult to launch the settings activity like so:
Intent LaunchIntent =
getPackageManager().getLaunchIntentForPackage("com.android.settings");
startActivityForResult(LaunchIntent, 42);
Usually, you would use a specific request code as the second argument, but in this case, you have no control over what the settings Activity could return as a result, and you only want to know when it finishes, so you can essentially make up a request code. It must be greater than 0, however. The docs state this here:
requestCode If >= 0, this code will be returned in onActivityResult() when the activity exits.
Then, you can override the onActivityResult method to handle what happens when the settings activity closes:
#Override
protected void onActivityResult (int requestCode, int resultCode, Intent data){
// Do whatever you would like to do
}
If you had used a specific request code when you started the Activity, this is where you would check if the result code exists, but since we aren't expecting any real result, the result code will likely be equal to RESULT_CANCELLED, but that's okay since you at least know that the Activity was cancelled.

Android system stops application when launching Media Intent

I am launching a media intent to take a photo. After the user took a picture and gets back to the previous activity the whole application has restarted.
As this doesn't happen all the time, I think my application goes to the background and android kills it when the device has low memory.
Is there any way to keep my application from going to the background?
Thanks!
This is normal behavior in Android, all activities currently not visible on screen (after onStop) can be killed without notice (i.e. onDestory) if the system has low memory.
This usually happens to our app on one of our test devices which has memory issues regardless of our app.
You can usually recreate this behavior when you open the camera via the intent, and then rotate the device (portrait to landscape), this will also kill and re-create your app.
To solve this you need to extend onSaveInstanceState and use the savedInstanceState parameter in your onCreate to pass from your killed instance to your new instance some important information (like "we're in the middle of getting a pic from the camera").
I can think of two possibilities...
It's not killing the activity, but the intent launches a new activity. You can stop this by putting a tag in your manifest.xml as an attribute in the activity tag like this:
<activity
android:name=".nameOfActivity"
android:launchMode="singleTop" />
Make sure that the media intent is under the activity to handle the photo, and not a main/launcher activity.
IMO two options:
Implement onSaveInstanceState/onRestoreInstanceState
or
Make your activity a service.
I faced this issue and got a solution after R&D for it.
Set Target Android 4.0 and then add this line in AndroidManifest.xml of activity:
android:configChanges="screenLayout|uiMode|orientation|screenSize|smallestScreenSize"
It works for me.
When you start media intent use following method instead of startActivity(intent)
startActivityForResult(intent, REQUEST_CODE); //private int REQUEST_CODE = 232
When the started activity finishes, your calling activity will be started. You need to handle this using following function
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
//Perform your task
}
}
The activity started need to override follwoing method
#Override
public void onBackPressed() {
Intent intent = new Intent();
setResult(REQUEST_CODE, intent);
super.onBackPressed();
}
startActivityForResult() is an special way for starting activity for a specific task and get the desired result. The called activity will send the data back.
You can use the method putExtra() & getExtra in intent to send and receive data between two activity.
This will solve your problem hopefully.
If you have doubts comment. And if possible share your code so it can be more clear.

Android: Certain intent extras prevent activity finish

I have an activity which allows me to take an image with the camera, and I want to send this image to the parent activity as an Intent extra. However, if I actually try to add the image to the intent, all of a sudden the finish() call never seems to do anything and my activity never closes.
Here's some of my code:
public void onPictureTaken(byte[] imageData, Camera c)
{
if (imageData != null) {
// Send the result as a byte array
Intent intent = new Intent();
intent.putExtra("imagedata", imageData);
setResult(RESULT_OK, intent);
finish();
}
}
The odd thing is, if I comment out the putExtra() call then it all works properly (without the image, of course) and my activity closes and I hit the parent's onActivityResult() callback. But if I leave the line in, then the activity never closes and the callback never fires.
I've tried putting more trivial things in the extras, like strings, and it's all worked perfectly. putExtra() is allowed to take a byte array and I've even tried wrapping it up as a Bitmap and sending that, but it didn't work either. The only thing I can think of is that I'm just not supposed to pass something that big into an Intent, in which case I guess I'll just try writing it to a file instead. It's just that writing is to a file should be slower than just passing the byte array reference around, which is why I'm trying to do it this way.
Any ideas? Thanks in advance :)
Phone: Samsung Galaxy S
API level: 7
You shouldn't be including your image data within the Intent extras. See this thread for clarification. In a nutshell, keep your Intent extras as small as possible.
I would suggest storing your picture to the SD card, and passing the path to this file in your Intent.
try this code
public void quit() {
int pid = android.os.Process.myPid();
android.os.Process.killProcess(pid);
System.exit(0);
}
and call it using quit();

onActivityResult doesn't work?

I am facing with a problem related startActivityForResult()
To start SecondActivity from FirstActivity :
Intent intent = new Intent();
intent.setClass(FirstActivity.this, SecondActivity.class);
intent.putExtra("key1", "12345");
startActivityForResult(intent, 0);
And handles result :
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//TODO handle here.
}
To send the message to FirstActivity from SecondActivity :
in SecondActivity :
setResult(0);
I can't handle the result on onActivityResult in FirstActivity.
It never works for my application.
My OS is : 1.5
What is wrong here?
startActivityForResult is meant to be used for situations where you want to select a piece of data, or perform some sort of action that your Activity or application cannot do.
For example, you want to pick a contact, so you launch the contacts application, the user chooses the person they want, and you get sent the result. Or you want to take a photo, so you launch the camera application and ask it to send you the photo once it's done. This action is completely separate from your first activity that calls startActivityForResult.
The Activity you're launching will not send you the result until that Activity has completed, i.e. finish() has been called.
So in your case, you need to call this in SecondActivity:
setResult(...);
finish();
before FirstActivity will receive the result in its onActivityResult method. Of course, this means that SecondActivity is now gone and FirstActivity is top of the stack again.
It's not possible to send the result to FirstActivity then close it while keeping SecondActivity still active. In this case you should just handle whatever this 'result' is in SecondActivity, or send it off to a Service you define to do whatever processing it is you want.
I was stuck here for a while. Adding my problem here to make sure that you don't scratch your head as well.
The second parameter of this function has to be 0 or higher.
startActivityForResult(intent, 0); // <- this is OK
I was setting the second parameter to RESULT_OK, which is -1, and my onActivityResult callback was never getting called. So if you get stuck like me, you can also check if your second parameter is correct.
startActivityForResult(intent, RESULT_OK); // <- this is wrong
The above line will fail to call onActivityResult.
I was also stuck on the same problem - but due to a different reason as matangs. Apparently startActivityForResult only works if you have android:launchMode set to standard for main activity (in manifest). Hope it helps someone.
Your code seems ok, but do you stop your second activity ?
Try this in it :
setResult(0);
finish();
If you are doing actions on onPause (like unbinding a service) try to comment it and see if onActivityResult is called (I wasted few good hours on this..)
Thanks to #johndodo (that point to the manifiest) - I find my solution for the same problem.
removing android:noHistory=true at the manifiest" solved this problem for me.

Categories

Resources