http://blog.blundell-apps.com/sending-a-tweet/
... I set up Twitter user authentication as in the tutorial above such that the
Activity
doing the Twitter authentication has its content view changed to a WebView
, the Activity
is declared in the manifest file containing an intent-filter
to catch the Twitter callback and, on callback, the response is processed and the Activity
's content view is changed back to whatever it was.I got it working but in doing so I found (what I think is) an easier way and such that the
WebView
doesn't ever kick off the phone's web browser app (thereby leaving your app, which you don't really want), as follows:(1) Remove the
Activity
singleInstance
and intent-filter
declarations you added to the manifest file (in following the tutorial above). Don't need that anymore!(2) Add a
WebView
to your Activity
layout file and set its initial visibility to "gone"
and its position, height, width etc however you want it. I set its properties so that it covers the whole screen when visible, as follows:
<WebView
android:id="@+id/myWebView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:visibility="gone" />
(3) Get a handle to your WebView
in your Activity
and set its WebViewClient
to pick up the Twitter callback (and not to kick off the web browser app at any time), as follows...
myWebView = (WebView)findViewById(R.id.myWebView);
myWebView.setWebViewClient(new WebViewClient()
{
@Override
public boolean shouldOverrideUrlLoading(WebView webView, String url)
{
if (url != null
&& url.startsWith("myapptwittercallback:///myapp"))
handleTwitterCallback(url);
else
webView.loadUrl(url);
return true;
}
});
... Here you might also want to enable other settings of your WebView
like saving form data and javascript execution (e.g. myWebView.getSettings().setJavaScriptEnabled(true);
)(4) Make your
WebView
visible and focused at the point you need to do Twitter authentication, as follows:
try
{
twitter = new TwitterFactory().getInstance();
twitter.setOAuthConsumer(
myTwitterConsumerKey,
myTwitterConsumerSecret);
twitterRequestToken = twitter.getOAuthRequestToken(
"myapptwittercallback:///myapp");
myWebView.loadUrl(
twitterRequestToken.getAuthenticationURL());
myWebView.setVisibility(View.VISIBLE);
myWebView.requestFocus(View.FOCUS_DOWN);
}
catch (TwitterException ex)
{
Toast.makeText(
this,
"Login failed. Please try again.",
Toast.LENGTH_SHORT).show();
}
... Remember to clear your WebView
's history (i.e. myWebView.clearHistory()
and set its visibility to "gone"
in your handleTwitterCallback(String)
method.(5) Lastly, override your
Activity
's onBackPressed()
method so that your WebView
handles presses of the back
button if its visible, as follows...
@Override
public void onBackPressed()
{
if (myWebView.getVisibility() == View.VISIBLE)
{
if (myWebView.canGoBack())
{
myWebView.goBack();
return;
}
else
{
myWebView.setVisibility(View.GONE);
return;
}
}
super.onBackPressed();
}
That's it! You should now have Twitter integration in your app and the user should never leave your app in doing Twitter authentication.
15 comments:
Hi.
Thanks man for such a good article. Had been banging my head around ACTION_VIEW and new views for 2 weeks without any luck.
The results were simply not stable enough.
Hey thank you for your codes. I'm stuck at handleTwitterCallback(url). Can you show me an example of what should be in it? Thanks
@honeyhong, here's some things I do in my handleTwitterCallback(String url) method...
(1)
webView.clearHistory();
(2)
Uri uri = Uri.parse(url);
(3)
String oauthVerifier = uri.getQueryParameter("oauth_verifier");
(4)
AccessToken accessToken = twitter.getOAuthAccessToken(myTwitterRequestToken, oauthVerifier);
(5)
twitter.setOAuthAccessToken(accessToken);
That's it at its most basic. Be sure to add null- and exception- handling. And calls (4) and (5) will need to be in an AsyncTask (i.e. not called from the main ui thread). Hope that helps!
Hi,
my app crashes @ this line
request = twitter.getOAuthRequestToken(
"myapptwittercallback:///myapp" );
I don't understand what I have to write instead of "myapptwittercallback:///myapp");
what doe's this line mean?
THX
Hi Anonymous,
Most likely your app is crashing because you're calling the 'Twitter.getOAuthRequestToken(...)' method in the main ui thread of your activity and not in a background/async task. Call it instead in an 'AsyncTask.doInBackground(...)' method and it should work fine.
And your callback url can be anything really as long as it's the same in all places within your app.
Hi,
sorry for my bad english.
Thank you for the fast answer. I am trying to run twitter since 3 weeks for my application and nothing works.
Is it possible to explain this more detail?
Do I have to implement a new Class which extends from AsyncTask<> and write the doInBackgroundMethod() like this:
protected RequestToken doInBackground(Twitter...params)
{
return
twitter.getOAuthRequestToken( "myapptwittercallback:///myapp" );
}
and then instead of the call I do:
request = AsyncClass.doInBackground()?
THX
hi again,
so it's done!
I thank you so much man now it work's. That's all a little bit complicated ^^ but it works.
THANK YOU SO MUCH
Greetings from Germany.
Adil..this is the best tutorial ever! I found out the reason why twitter4j was not working was cos getOauthAccessToken was running from main thread.
Besides using a webview is better for UX flow... thanks its work for my app and I'll let you know when the app is done!
Thanks for this article! Almost got stuck with the popup browser! :)
Hi.. I got stuck with that handleTwitterCallback (url)..
Sorry coz i'm still new to progamming..
Can u explain that part further?
private void handleTwitterCallBack(String url){
myWebView.clearHistory();
Uri uri = Uri.parse(url);
final String veri = uri.getQueryParameter(URL_TWITTER_OAUTH_VERIFIER);
new AsyncTask(){
@Override
protected String doInBackground(String... arg0) {
// TODO Auto-generated method stub
try{
AccessToken at = twitter.getOAuthAccessToken(requestToken,veri);
twitter.setOAuthAccessToken(at);
}catch(TwitterException e){
System.out.println("EEEE :"+e.getErrorMessage());
}
return null;
}
}.execute(url);
myWebView.setVisibility(View.GONE);
}
This is my method..
Is it wrong? Can u help me to fix it if it's wrong?
Big thanks from me..
Brilliant, man!
Concise and well explained.
Thank you very, very much.
Alvin Varghese :
Please take look at this question.
http://stackoverflow.com/questions/21108320/android-app-not-signing-in-to-twitter
Alvin, I've left an answer for you on Stack Overflow.
A truly useful post - many thanks!
In response to some other questions, here is what I did:
private void handleTwitterCallback (String url) {
myWebView.clearHistory();
myWebView.setVisibility(View.GONE);
Uri uri = Uri.parse(url);
String oauthVerifier = uri.getQueryParameter("oauth_verifier");
new HandleTwitterCallback_AsyncCommand(oauthVerifier).execute();
}
public class HandleTwitterCallback_AsyncCommand extends AsyncTask {
private String mOauthVerifier = "";
public HandleTwitterCallback_AsyncCommand(String oauthVerifier) {
super();
mOauthVerifier = oauthVerifier;
}
@Override
protected Void doInBackground(Void... params) {
try {
// This must not run on the main UI thread...
AccessToken accessToken = mTwitter.getOAuthAccessToken(mReqToken, mOauthVerifier);
mTwitter.setOAuthAccessToken(accessToken);
saveAccessToken(accessToken);
mHandler.post(new Runnable(){
@Override
public void run() {
// We're authenticated - we can now tweet!
// This must run on the main UI thread... e.g. you can now post, if you want!
userLoggedIn();
}
});
} catch (TwitterException e) {
mHandler.post(new Runnable(){
@Override
public void run() {
String message = getString(R.string.socialmedia_twitter_login_error); // Twitter Login error, please try again later
Toast.makeText(MyActivity.this, message, Toast.LENGTH_SHORT).show();
}});
} catch (Exception e) {
}
return null;
}
}
Would you like give me a complete code how to implement a webview load in a dialog ?
Post a Comment