package com.samknows.ska.activity; import java.io.ByteArrayInputStream; import android.app.Activity; import android.content.Intent; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.os.Handler; import android.util.Log; import android.view.View; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.Toast; import twitter4j.StatusUpdate; import twitter4j.Twitter; import twitter4j.TwitterException; import twitter4j.TwitterFactory; import twitter4j.auth.AccessToken; import twitter4j.auth.RequestToken; import com.samknows.libcore.R; import com.samknows.libcore.SKPorting; import com.samknows.measurement.SKApplication; // http://blog.blundell-apps.com/sending-a-tweet/ public class SKAPostToTwitterActivity extends Activity { private static final String TAG = "PostToTwitter"; /** Name to store the users access token */ private static final String PREF_ACCESS_TOKEN = "accessToken"; /** Name to store the users access token secret */ private static final String PREF_ACCESS_TOKEN_SECRET = "accessTokenSecret"; /** Consumer Key generated when you registered your app at https://dev.twitter.com/apps/ */ private static final String CONSUMER_KEY = "x23Mr06aRgLJtq2nE2wJA"; /** Consumer Secret generated when you registered your app at https://dev.twitter.com/apps/ */ private static final String CONSUMER_SECRET = "oZAKYoX1i4zhYJQktOLlXEw5POMild8qlYDNUi8CEI"; // XXX Encode in your app /** The url that Twitter will redirect to after a user log's in - this will be picked up by your app manifest and redirected into this activity */ private static final String CALLBACK_URL = "libcore-twitter-android:///"; /** Preferences to store a logged in users credentials */ private SharedPreferences mPrefs; /** Twitter4j object */ private Twitter mTwitter; /** The request token signifies the unique ID of the request you are sending to twitter */ private RequestToken mReqToken; private String mMessageToPost = ""; private byte[] mImageToPost = null; private WebView myWebView; /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); Log.i(TAG, "Loading TweetToTwitterActivity"); setContentView(R.layout.ska_post_to_twitter_activity); // http://adilatwork.blogspot.co.uk/2011/12/android-twitter-login-using-twitter4j.html myWebView = (WebView)findViewById(R.id.myWebView); myWebView.getSettings().setJavaScriptEnabled(true); 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; } }); setTitle(getString(R.string.socialmedia_post_to_twitter_title)); Intent intent = getIntent(); mMessageToPost = intent.getStringExtra("messageToPost"); mImageToPost = intent.getByteArrayExtra("imageToPost"); // Should only be an image, if that is appropriate to the application configuration. // If not null, it contains the byte data of a png file to post. SKPorting.sAssert(getClass(), (mImageToPost != null) == SKApplication.getAppInstance().isSocialMediaImageExportSupported()); // Create a new shared preference object to remember if the user has // already given us permission mPrefs = getSharedPreferences("twitterPrefs", MODE_PRIVATE); Log.i(TAG, "Got Preferences"); // if (com.samknows.measurement.util.OtherUtils.isDebuggable(this)) { // // In debug builds, for now - clear the login details in the shared preferences, // // to force a fresh login each time! // clearLoginDetails(); // } // Load the twitter4j helper mTwitter = new TwitterFactory().getInstance(); Log.i(TAG, "Got Twitter4j"); // Tell twitter4j that we want to use it with our app mTwitter.setOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET); Log.i(TAG, "Inflated Twitter4j"); // Start by trying to login! doLoginToTwitter(); } private void doLoginToTwitter() { Log.i(TAG, "doLoginToTwitter"); if (mPrefs.contains(PREF_ACCESS_TOKEN)) { Log.i(TAG, "Repeat User"); loginAuthorisedUser(); } else { Log.i(TAG, "New User"); new LoginNewUser_AsyncCommand().execute(); } } 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(); } @Override public void onBackPressed() { if (myWebView.getVisibility() == View.VISIBLE) { if (myWebView.canGoBack()) { myWebView.goBack(); return; } else { myWebView.setVisibility(View.GONE); return; } } super.onBackPressed(); } /** * The user had previously given our app permission to use Twitter</br> * Therefore we retrieve these credentials and fill out the Twitter4j helper */ private void loginAuthorisedUser() { String token = mPrefs.getString(PREF_ACCESS_TOKEN, null); String secret = mPrefs.getString(PREF_ACCESS_TOKEN_SECRET, null); // Create the twitter access token from the credentials we got previously AccessToken at = new AccessToken(token, secret); mTwitter.setOAuthAccessToken(at); //Toast.makeText(this, "Welcome back", Toast.LENGTH_SHORT).show(); userLoggedIn(); } @Override protected void onResume() { super.onResume(); Log.i(TAG, "Arrived at onResume"); } /** * Allow the user to Tweet */ private void userLoggedIn() { Log.i(TAG, "User logged in - allowing to tweet"); // When this happens, we can now post the tweet automatically! new PostTweet_AsyncCommand().execute(); } private void saveAccessToken(AccessToken at) { String token = at.getToken(); String secret = at.getTokenSecret(); Editor editor = mPrefs.edit(); editor.putString(PREF_ACCESS_TOKEN, token); editor.putString(PREF_ACCESS_TOKEN_SECRET, secret); editor.commit(); } final Handler mHandler = new Handler(); private void clearLoginDetails() { // If (say) the user has blocked the app on the Twitter site, we should clear-out cache login // details, to enable the user to resolve this the next time they enter the screen. Editor editor = mPrefs.edit(); editor.remove(PREF_ACCESS_TOKEN); editor.remove(PREF_ACCESS_TOKEN_SECRET); editor.commit(); } /** * Send a tweet on your timeline, with a Toast msg for success or failure */ // Params, Progress, Result public class PostTweet_AsyncCommand extends AsyncTask<Void, String, Void> { WebView twitterSite = new WebView(SKAPostToTwitterActivity.this); @Override protected Void doInBackground(Void... params) { try { // Post a simple text message. // This must not run on the main UI thread... if (mImageToPost == null) { // No image to post... mTwitter.updateStatus(mMessageToPost); } else { // We have an image to post, as a png file in a byte array! StatusUpdate status = new StatusUpdate(mMessageToPost); status.setMedia("Results", new ByteArrayInputStream(mImageToPost)); mTwitter.updateStatus(mMessageToPost); } mHandler.post(new Runnable(){ @Override public void run() { // This must run on the main UI thread... String message = getString(R.string.socialmedia_twitter_tweet_successful); // Tweet Successful! Toast.makeText(SKAPostToTwitterActivity.this, message, Toast.LENGTH_SHORT).show(); // Set the content view back after we changed to a webview setContentView(R.layout.ska_post_to_twitter_activity); SKAPostToTwitterActivity.this.finish(); }}); } catch (TwitterException e) { int errorCode = e.getErrorCode(); if (errorCode == 187) { // Status is a duplicate! mHandler.post(new Runnable(){ @Override public void run() { String message = getString(R.string.socialmedia_twitter_tweet_duplicate_detected); // Twitter won't let you post duplicate messages! Toast.makeText(SKAPostToTwitterActivity.this, message, Toast.LENGTH_SHORT).show(); // Set the content view back after we changed to a webview setContentView(R.layout.ska_post_to_twitter_activity); SKAPostToTwitterActivity.this.finish(); }}); } else { mHandler.post(new Runnable(){ @Override public void run() { String message = getString(R.string.socialmedia_twitter_tweet_error); // Tweet error, please try again later Toast.makeText(SKAPostToTwitterActivity.this, message, Toast.LENGTH_SHORT).show(); // Set the content view back after we changed to a webview setContentView(R.layout.ska_post_to_twitter_activity); clearLoginDetails(); SKAPostToTwitterActivity.this.finish(); }}); } } catch (Exception e) { SKPorting.sAssert(getClass(), false); } return null; } } /** * Create a request that is sent to Twitter asking 'can our app have permission to use Twitter for this user'</br> * We are given back the {@link mReqToken} * that is a unique indetifier to this request</br> * The browser then pops up on the twitter website and the user logins in ( we never see this informaton * )</br> Twitter then redirects us to {@link CALLBACK_URL} if the login was a success</br> * */ // Params, Progress, Result public class LoginNewUser_AsyncCommand extends AsyncTask<Void, String, Void> { // WebView twitterSite = new WebView(SKAPostToTwitterActivity.this); @Override protected void onPreExecute() { // TODO Auto-generated method stub super.onPreExecute(); } @Override protected Void doInBackground(Void... params) { try { // This must not run on the main UI thread... mReqToken = mTwitter.getOAuthRequestToken("myapptwittercallback:///myapp"); mHandler.post(new Runnable(){ @Override public void run() { // This must run on the main UI thread... myWebView.setVisibility(View.VISIBLE); myWebView.requestFocus(View.FOCUS_DOWN); myWebView.loadUrl(mReqToken.getAuthenticationURL()); } }); } 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(SKAPostToTwitterActivity.this, message, Toast.LENGTH_SHORT).show(); }}); } catch (Exception e) { SKPorting.sAssert(getClass(), false); } return null; } } public class HandleTwitterCallback_AsyncCommand extends AsyncTask<Void, String, Void> { private String mOauthVerifier = ""; public HandleTwitterCallback_AsyncCommand(String oauthVerifier) { super(); mOauthVerifier = oauthVerifier; } // WebView twitterSite = new WebView(SKAPostToTwitterActivity.this); @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... 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(SKAPostToTwitterActivity.this, message, Toast.LENGTH_SHORT).show(); }}); } catch (Exception e) { SKPorting.sAssert(getClass(), false); } return null; } } }