Returning to activity after Twitter OAuth finished - android

I have Twitter OAuth working in my application using an intent-filter in my manifest. How I have implemented it, once the user clicks a button to post via Twitter I start a new Activity (lets just called it TwitterLoginActivity), that new TwitterLoginActivity creates a new Intent with the authUrl like this:
Intent oauthIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(authUrl));
This opens a browser, I authorize my app, and it returns in the onResume() function of TwitterLoginActivity. At this point I post to twitter just fine and do a finish() on this activity.
All this works like a champ, but in calling this finish() it returns to the Twitter.com webpage I just authorized from. I'm not great at understanding how the activity stack works, but is there anyway to remove all of the WebViews of Twitter.com that I saw and on that finish() it just returns back to the original point in my application where the user had clicked the post button?

I don't know if you resolved your issue, but yesterday I had the same problem and I resolved it this way:
1) In the intent to lauch the WebBrowser to sign in on Twitter, add the next flags:
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(authUrl));
intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.addFlags(Intent.FLAG_FROM_BACKGROUND);
startActivity(intent);
2) In the Manifest, where you declare the TwitterLoginActivity that launches the intent, add the property:
android:launchMode="singleTask"
3) When the login with Twitter is completed, WebBrowser finishes and goes back to TwitterLoginActivity but onCreate isn't called because of singleTask launch mode, onNewIntent is called instead. To save the token and token secret, you have to move the code from onResume to OnNewIntent.
Now, if you press the back button or finish TwitterLoginActivity, it goes to the previous activity and the WebBrowser never shows up again.
I hope this helps!

This works for me: render the oauth web page in a WebView you control rather than launching out to the browser app.
The oauth web page, when it calls its callback, will actually be replacing itself in the webview, where your WebViewClient can catch that expected URL, process the results, and finish() the webview (removing it from the activity stack).
In other words, the WebView will be under your direct control, rather than being the browser.

This sounds like a perfect time to use Activity.startActivityForResult() instead of Activity.startActivity(). You're original activity just needs your TwitterLoginActivity to login the user, so once done, it should return back to your original activity.
Implement onActivityResult() to handle the response from TwitterLoginActivity.
Read about it here

Related

ANDROID: open an URL in external browser, while continuing the application

In the starting activity of my app I show a dialog to user and ask if he wants to see some contents in my website or not.
If he clicks No, the dialog disappears and I call continueActivity() to do some process and go from current activity to MainActivity.
If he click yes, I want to open the webpage in the external browser and again I call continueActivity() to do some process and go from current activity to MainActivity.
The problem is in positive state. This is my code in positive state:
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.aaa.ir"));
startActivity(browserIntent);
continueActivity();
Because of calling continueActivity(), the external browser can't open and if I don't call continueActivity(), the URL opens in the external browser and the app sticks in the current activity.
So how could I open the URL and at the same time, continue the process and go to other activities.
I usually use
startActivityForResult(browserIntent, BROWSER_REQUEST);
and override onActivityResult(int reqCode, int resultStat, Intent intent)
if(reqCode == BROWSER_REQUEST) {
continueActivity();
}
Once you call startActivity, your current Activity will follow through the exit of the Activity lifecycle. This is unavoidable.
If you have processing you want to continue in the meantime, you should consider a Service. If you want the App to return to its current state, you need to store relevant data and load your Activity to its previous state (or next intended state).
in both ways ContinueActivity is opening. i don't know you architecture. You could just add to intent some extra like
intent.putBoolean("openExternalLink", dialogResultHere);
Then in continueActivity you will got this intent like
getIntent().getBoolean("openExternalLink")
also dont forget to delete this option, otherwise you will open browser each time after Activity recreation (screen rotation, minimize, etc.)
getIntent().removeBoolean("openExternalLink");
P.S. signatures of methods could be littlebit different, but general idea is here

Custom Action Intent Opens my App in the same context as the app that I clicked From

I have searched a lot on this.
But, I have my code working to open my app using a custom intent URL. This URL is usually delivered via email.
When I click on the link, it opens my app fine and everything seems to be working; however, it opens in the context of the email application.
For example, if I click on the link from Gmail, when I open multitasking, I have to click on Gmail to return back to the app that just opened.
I would think it should open my app and I can continue using Gmail while my other app is running.
Any thoughts on this?
Make your URL look like this:
intent:#Intent;launchFlags=0x10000000;component=com.mycompany.myapp/com.mycompany.myapp.MyActivity;end
This URL contains the launchFlag for Intent.FLAG_ACTIVIY_NEW_TASK, so this will launch your app in a separate task (outside of the email client or browser or whatever).
EDIT: Add additional details based on OP's comment
You say that you are using a URL like this: http://com.my.app/5058749
In that case you must have used an Intent filter to get Android to open your app by specifying an <intent-filter> on a certain <activity> in your manifest. There are several things you can do to deal with the problem of the launched Activity ending up in the same task as the Activity that launched it:
1) If the Activity is always intended to be the root (starting, first) Activity of a task, you can put the following code in onCreate() after the call to super.onCreate():
if (!isTaskRoot()) {
// Activity was launched into another task. Restart it in its own task
Intent intent = new Intent(this, this.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
return;
}
2) You can set the launch mode of this Activity to singleTask in the manifest by adding
android:launchMode="singleTask"
to the <activity> definition. This will cause the Activity to be launched in its own task but this launch mode has other consequences that are more subtle and so you need to be careful about using it. In general I don't like to suggest this because it tends to create more problems than it solves.
3) You can determine if your app was launched from the browser or email client by examining the Intent used to start it in onCreate() (The Intent will have the data set to the URL when launched via the browser or email client). You can then decide if you want to restart it in its own task by using the code I've supplied in option 1 above.
Add Intent.FLAG_ACTIVITY_NEW_TASK and Intent.FLAG_ACTIVITY_CLEAR_TOP flags(intent.SetFlags() to your intent. Your actitivty will be opened in a new task and this activity will be the root of your new stack.
This is the default behavior with android, but to override it, you need to pass
Intent.FLAG_ACTIVITY_NEW_TASK
Intent.FLAG_ACTIVITY_CLEAR_TOP
with your intent.

Managing the back stack after oauth login on Android

I am implementing oauth login in Android, and I'm stuck on one point. I am required to redirect to the native browser to initiate the login (rather than use an embedded WebView of my own), but that is causing issues with the back stack. My goal is simple: return to my activity after the redirect with no trace of the native browser in the back stack. Here is the closest I've come so far:
To initiate the login from my activity I use:
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY
| Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
context.startActivity(intent);
I have a separate activity to receive the return redirect and handle the rest of the login process. I don't really care whether it's a separate activity or not, it is just my current solution. In its manifest I set android:noHistory="true". Once it finishes the login process, I attempt to return to the first activity using code like this:
Intent intent = new Intent(context, OrigActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
context.startActivity(intent);
However, this ends up creating a second copy of the original activity, and when I press back it returns me to the first copy. In other words, it does not seem to respect FLAG_ACTIVITY_CLEAR_TOP. Did I miss something simple to make it work, despite all my searching? Or is there some other way I should go about all of this?
Edit: It turns out the problem stems from the fact that the browser is launched in a separate task. From some Android documentation:
... if your application issues an intent to open the Android Browser, its activity is not placed in the same task as your application. Instead, either a new task starts for the Browser or, if the Browser already has a task running in the background, that task is brought forward to handle the new intent.
If I set my original activity's launch mode to singleTask it properly brings it to the foreground instead of creating a new copy, but a new problem occurs. The browser is now in the back stack behind all of my activities, so now it seems FLAG_ACTIVITY_NO_HISTORY is not being respected. I'm not sure if that brings me any closer to a proper solution ...
Edit 2: Correction: if the browser was not running before I launched it, everything works perfectly. However, if it WAS already running FLAG_ACTIVITY_NO_HISTORY seems to have no effect on it.
What you're seeing makes sense because calling the browser with the FLAG_ACTIVITY_NO_HISTORY wouldn't remove back stack from PRIOR to the start of your application.

Clear android activity stack starting a new activity

I have an application and every new created activity will start an async task to validate the user session. If the session is valid, the application flows continues. If not, the whole activity stack must be cleared and there should be only the login activity. This activity has a "no history" flag so it is never kept in the stack.
I've been trying some solutions provided here: Android: Clear Activity Stack but with no success.
This must works on the lowest android possible, being the least 2.2
Thanks!
I keep my login Activity on the stack. In the onResume() of the login Activity, I check to see if the user has login credentials and, if so, call startActivity for the next screen presented after login. The user does not see the login screen in this case.
When the user presses the logout button, I clear the user's credentials and then this clears the stack all the way back to the login screen:
Intent intentLaunchLogin = new Intent(this, ActivityLogin.class);
intentLaunchLogin.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intentLaunchLogin);
Also, if the user is on the screen presented after the login and they press the 'back' button, I don't want them to go to the login Activity. This code will send the user to the Home screen as would be expected:
moveTaskToBack(true);
Could you do something like is described here:
http://blog.janjonas.net/2010-12-20/android-development-restart-application-programmatically
basically you create an alarm that starts your intent, then you close your app completely.
This is what I always do and works perfectly.
I start the app with the main activity an check if the user is logged in, if he is not logged in launch the login activity like this
void launchLoginActivity(){
/* Move user to LoginActivity, and remove the backstack */
Intent intent = new Intent(getApplicationContext(), LoginActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
finish();
}
It will not allow u to go back

Opening browser activity, but prevent it from being in the activity history

I'm working on an app that launches the browser activity to perform a Twitter OAuth authorization. This process uses a callback url which will re-launch the activity that started the browser activity in the first place.
My problem is that the browser pages remain in the history stack and when the user then clicks back from the preferences activity that launched the browser in the first place, they don't go back to the app's main activity, but instead are brought back to the browser. I've tried adding flags to the launching intent to prevent history and reset on clear, but it doesn't seem to work when running on my phone, only on the emulators.
Here is the code I'm using to launch the browser activity:
Intent webIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(authUrl));
webIntent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
webIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
webIntent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
ctx.startActivity(webIntent);
Anyone have any idea what might be wrong?
Set the activity flag to Intent.FLAG_ACTIVITY_CLEAR_TOP after starting it. This way, the task will be deleted form the app stack so your main activity remains the top one on every new launch:
ctx.startActivity(webIntent);
browserIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
call
finish();
after
ctx.startActivity(webIntent);
Hi i have the same problem at the moment. I think the solution is to start the activity you want to return to with a special flag:
Intent intent = new Intent(this, acticityToReturnTo.getClass());
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity(intent);
The problem is that is does not work (on 1.6 at least).. But maybe someone finds a solution for this. I think FLAG_ACTIVITY_CLEAR_TOP is exactly what we.
I found that Intent.FLAG_ACTIVITY_NO_HISTORY works only if the browser was not running before. If I restart Android and run my app which call browser everything work well. But when I start browser before my app, browser will stay in history.
Here is related question also, but with no really working solution
How can I do that in Android. Activity -> WebBrowser -> Acrivity, but Press Back not see the WebBrowser

Categories

Resources