I have created an android app for the Portuguese (Brasil). This is one of my client's app. The client is getting feedback from the app users that they are not able to use the app properly or it goes back to start screen when they click on the button to import a contact from the Phonebook.
i.e. In the app, there are various places where I start the activity to get the result.
startActivityForResult(intent, requestCode);
Generally, I'm doing this from Fragments. And to pass the result from Activity to its Fragment, I'm doing like following:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (getSupportFragmentManager() != null) {
Fragment fragment = getFragment();
if (fragment != null)
fragment.onActivityResult(requestCode, resultCode, data);
}
}
So to check this problem We asked some of the users to check if they have Developer options enabled on their device. And Yes, they have it enabled on their devices. So we asked them to disable this and try the app and believe me it works.
I also have this option enabled on my device to test the app (Debugging) and I haven't faced any problem like this while using the app.
I don't understand this issue and I need to find the appropriate solution.
So I need your help to solve this problem.
Looking for the positive responses.
Thanks.
Try fragment context instead of getActivity() as you are starting activity from the fragment and result should be returnned to fragment.
Intent intent=new Intent(fragment.getContext(), Activity.class)
fragment.startActivityForResult(intent,REQUEST_CODE);
Finally, after a very long time, the issue is resolved.
When we have Don't keep Activities option enabled on the device and as soon as you leave the activity, it gets destroyed.
And in the onCreate, I was adding the initial fragment again.
But now I have added a check of
if(savedInstanceState == null)
// initial fragment here
else
// nothing to do
This check resolved the issue in my app. Hope it helps the others too.
Related
In my App, Activity1 launches Activity2 with "startActivityForResult()".
When Activity2 is done, the following code is called:
Activity2.java
private void finishActivity(final boolean accepted)
{
Intent returnIntent = new Intent();
setResult(accepted ? RESULT_OK : RESULT_CANCELED, returnIntent);
finish();
}
Activity1 receives this callback, and if the result is not RESULT_OK, it also finishes.
Activity1.java
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == Globals.REQUEST_CODE_TOS)
{
if (resultCode != RESULT_OK)
finish();
}
}
After Activity1 finishes the app closes, as expected.
THE PROBLEM --
However, after my app closes, instead of going to the home screen, a previous application on the stack briefly launches forward, then closes also! Then I get to the home screen.
In the Android bug tracker, I see a similar bug listed for the case when the back button is pressed, which I believe is the same as calling finish():
https://code.google.com/p/android/issues/detail?id=71067
I'm seeing this on a Nexus 5, running 4.4.4.
Is this just a bug? Or are there any workarounds for the behavior?
EDIT --
To clarify the behavior I desire:
In Google Maps, if you decline the TOS popup, the app closes and you go directly to the home screen. There is no awkward flash to some previously opened app.
This is decidedly the same issue as the one you linked in your question (I've been following it for months, as I own a Nexus 5 myself). It was actually fixed in the AOSP, but that particular fix doesn't seem to have found its way into the N5 yet. I've got my fingers crossed for a fix in Lollipop, but we'll see when that rolls out.
As for a workaround, I don't think any exists at the moment, although if I'm wrong on that I would love to know - I work on an app myself which does something similar (manually calls finish() the bottom-most activity in the stack when closed via the back button).
Might be the empty Intent you return via setResult(). Have you tried null here, instead?
There are a lot of questions out there on similar topics, but after searching around I haven't found one that matches my issue.
I know about starting intents for result, and overriding onActivityResult() to handle these intents, but for some reason, I'm having issues when I'm coming back from activity b to activity a. So, for example, in the last of 3 activities (AddDirections class) I start in my project, I call this method to return back to the previous activity:
public void finish(View v){
Intent intent = new Intent(getApplicationContext(), AddIngredients.class);
intent.putExtra(Home.RECIPE_INTENT, (Parcelable)recipe);
intent.putExtra(Home.RECIPE_ID_INTENT, recipe.getId());
setResult(RESULT_OK, intent);
finish();
}
In the AddIngredients class, I have this method:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == RESULT_OK && requestCode == DIRECTIONS_REQUEST){
Intent intent = new Intent(getApplicationContext(), NameRecipe.class);
Recipe recipe = data.getParcelableExtra(Home.RECIPE_INTENT);
intent.putExtra(Home.RECIPE_INTENT, (Parcelable)recipe);
setResult(RESULT_OK, intent);
finish();
}
}
This should accept the returned result from the AddDirections class, and pass it off to NameRecipe, where I have the exact same method (Except for in the new Intent method it says Home.class). In the Home class, I have basically the same method again to receive the intent as it backs all the way out of the app.
Now, I will say that this works if I go straight through the steps from beginning to end. But if I use the up navigation to go the current activity's parent activity, then it messes everything up. Then when I click finish in the final step it messes up the resultCodes that I set for each intent. I make sure to explicitly set the correct result to RESULT_OK (which equals 1) but then for some reason, sometimes it changes what I've set to be the resultCode to be 0 instead.
Here's what I do in an activity if the user clicks the up navigation:
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
Intent intent = NavUtils.getParentActivityIntent(this);
intent.putExtra(Home.RECIPE_INTENT, (Parcelable)recipe);
setResult(RESULT_OK, intent);
NavUtils.navigateUpTo(this, intent);
finish(); //Have tried with and without this
return true;
}
return super.onOptionsItemSelected(item);
}
Like I said, I've searched for a lot of reasons why the resultCode gets overwritten after using the up navigation, but I haven't found a single reason why.
Any help would be greatly appreciated.
It looks like the underlying question is really how do I navigate between multiple activities through the stack using the up navigation that is built in. I am wondering if the project is setup correctly for this type of navigation. From the android developer resources, up navigation from google, you have to setup the navigation buttons with a parent activity. Then the application can traverse between the different activities. From what it looks like this should allow A->B B->C c->D and back to A if needed. I would also add in a button that would allow a direct path back to A if the user so chooses.
If you have more information on what you are trying to accomplish between activities whether it is data passed back and forth or just returning to the previous activity that would be helpful. Hopefully the link will help your issue with this.
your problem seems to be the NavUp, this util class tends to clear everything to navigate to the parent including your resultCode and the instance of the activity, resulting in a Canceled result (if started for result) to a new instance of the parent activity, in order to fix that a quick fix would be to declare android:launchMode="singleTop" in your manifest, but I wouldn't recommend to use that unless you are 100% that you want that, instead I would go into my navigator class, or my method for navigate and overwrite that specific navigation to something like:
Intent parentActivityIntent = NavUtils.getParentActivityIntent(this);
parentActivityIntent.setFlags(
Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP
);
NavUtils.navigateUpTo(this, parentActivityIntent);
Hope this helps!!
Sorry for the late answer :p
if by 'up navigation' you mean back key pressed then you need to override a function
#Override
public void onBackPressed() {
// TODO Auto-generated method stub
super.onBackPressed();
}
if from what it seems to be you are trying to get back when clicking an item from the Options Menu to your parent activity directly then i think you will need to go back step by step as at this moment there is already an activity running and waiting for a result so when you go directly to home activity its already waiting an answer from activity B and not activity C i hope i explained it right :)
I am trying to design a one time login system.
On the loginActivity the user enters a phone number to which I send a secret code thru SMS
On the confirmationActivity the user enters the secret code.
If the secret code is successful, I want to finish both confirmationActivity and loginActivity. To do that from loginActivity I do
Intent intent = new Intent(this, ConfirmationActivity.class);
startActivityForResult(intent, EXIT_CODE);
Then again in loginActivity I call
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == EXIT_CODE) {
finish();
}
}
}
To test whether my system works, after registration, I click on the back button:
Expected behavior: Not being able to go back or close the app
Actual behavior: go back to the loginActivity (notice that it skips the confirmationActivity)
My hope is that once a user successfully registers they should never again get access to either the confirmationActivity or the loginActivity. And that when they close my app and restart it, it skips those two pages and take the user directly to the home page.
Note: It looks like the onActivityResult method is never called. I place a few println calls in there and they are never printed on LogCat.
DISCLAIMER: Last time I asked a question and showed a code snippet, one respondent got distracted and started talking about the snippet instead of addressing the question. The snippet here is just to show what I have tried. Obviously it has not solved the problem. Thank you.
One possible solution could be:
Instead of opening the app with LoginActivity you create a new one called FirstActivity.
In this activity you check if you have set a flag in sharedPreferences.
If this check is true then continue to your logged-in Activity.
If this check returns false start LoginActivity. After a User has succesfully entered the "secret", you should set a flag in the sharedPreferences. Next time the user opens the app the flag in sharedPreferences will be set a you will know that the user is already registered.
Any questions? comment below
I'm actually following SessionLoginFragment.java example from facebook sdk samples.
What I really don't understand is this:
when I make
session.openForRead(new Session.OpenRequest(fragment).setCallback(statusCallback));
to log my user to facebook and ask basic read permission (just to test the integration) it simply does not work.
I digged a bit with the debugger and I followed the path. If you don't put a requestCode to the OpenRequest of the session it will give it a random one (and this is ok).
openForRead (my actual session is in CREATED status) will create the permission dialog. When you hit the "Ok" button it will perform a
request.getStartActivityDelegate().startActivityForResult(intent, request.getRequestCode());
You can see the code from the fb sdk source code. Well the requestCode is the same of the session (and here's ok).
When fb log you into the system it will finish his facebook.LoginActivity and call me back my onActivityResult in my activity. The problem is that here the requestCode is different from the request's one. And I don't know why and where it comes from!
If I go into my fb account my application is there, so it means that I've done the correct auth flow that finish well. But I wont get correctly authenticated from my app because of this problem.
Do you know why and how can I solve it?
Thanks.
UPDATE WITH FLOW DETAIL:
This is the actual flow (from fragment):
session.openForRead(new Session.OpenRequest(fragment).setCallback(statusCallback));
After creating it, the request code is (always) 64206
Now openForRead flow will call (final part)
request.getStartActivityDelegate().startActivityForResult(intent, request.getRequestCode());
That call the LoginActivity from facebook SDK and do the client/server validation/oauth
Now on my activity is called onActivityResult (not on the fragment but on the activity part)
and here I call
Session.getActiveSession().onActivityResult(activity, requestCode, resultCode, data);
And here the requestCode is requestCode 129742
How is it possible? As I already said, the problem in all this flow is that requestCode returned to onActivityResult is different from my pendingRequest requestCode and this break (getActiveSession().onActivityResult return without executing code) the login client part.
I ran into the same problem, except that in my case the offending requestCode was 326350 (0x4face). And I was indeed calling super.onActivityResult, so the workaround proposed by Eric Savage was already in place but not effective. Weirdest thing of all, this stuff did work just a couple of weeks ago, and the offending behaviour appeared without myself upgrading anything (Facebook SDK version, Android version, support library version, even the phone on which I'm developing/testing, are all the same as when I had it working).
However, Eric's answer contains other interesting hints, which I exploited to make my code work again. Basically, instead of passing the whole requestCode to Session.onActivityResult, I cut the lowest 16 bits and pass those only.
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Session session = Session.getActiveSession();
int sanitizedRequestCode = requestCode % 0x10000;
session.onActivityResult(this, sanitizedRequestCode, resultCode, data);
}
I do believe this is a bug that should be fixed in the Facebook SDK, and would insist to have it patched for the next release.
Just ran into this same issue. The difference between 64206 (0xface) and 129742 (0x1face) is because FragmentActivity has tacked on an extra 0x10000 to determine which fragment it came from. This was resolved by making sure the super activity was called during onActivityResult
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
// ...
}
}
You "Can only use lower 16 bits for requestCode", as stated in FragmentActivity.startActivityFromFragment
I'm invoking android native calculator from my app, how do i get result data from it.. means i started native calender like this, after finishing calculation i press back onActivityResult is executed and data returned is null, how to get calculated data.. Help me
Intent i = new Intent();
i.setClassName("com.android.calculator2",
"com.android.calculator2.Calculator");
startActivityForResult(i, 1);
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == 1){
Log.i("CALCULATOR", "Result Data is"+ data);
}
}
After some testing, I'm starting to think that you can't really get something back from the calculator. Calling something with startActivityForResult doesn't mean it's going to return something other than null and since there's no way of getting out of the calculator other than pressing the back key, I think this is one of those cases.
The native calculator doesn't seem to be calling setResult(RESULT_SUCESS,intent_with_data) which is the step needed to be able to retrieve this result. Easiest thing I can think of, since you're wanting to do some calculation is to implement your own calculator class and call that one instead of the native one.
Calculators are easy to make and you have a zillion examples on the net. Just make sure you have an OK button that calls setResult(RESULT_SUCESS, intent_with_data) after you put extras to the intent with the result.
Warning
Be aware that you're hardcoding a class name instead of calling an intent by specifying an action and URI. This may call the original calculator on the emulator and standard versions of Android, but manufacturers change those kinds of things and since no one is supposed to be calling them like you intend to with your intent, you may end up crashing the app.