package com.mobmonkey.mobmonkeyandroid; import org.json.JSONException; import org.json.JSONObject; import twitter4j.Twitter; import twitter4j.TwitterException; import twitter4j.TwitterFactory; import twitter4j.auth.AccessToken; import twitter4j.auth.RequestToken; import twitter4j.conf.Configuration; import twitter4j.conf.ConfigurationBuilder; import com.mobmonkey.mobmonkeyandroid.R; import com.mobmonkey.mobmonkeyandroid.utils.MMConstants; import com.mobmonkey.mobmonkeysdk.adapters.MMUserAdapter; import com.mobmonkey.mobmonkeysdk.utils.MMSDKConstants; import com.mobmonkey.mobmonkeysdk.utils.MMCallback; import com.mobmonkey.mobmonkeysdk.utils.MMProgressDialog; import android.annotation.SuppressLint; import android.app.Activity; import android.content.Intent; import android.content.SharedPreferences; import android.net.Uri; import android.os.Bundle; import android.util.Log; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.Toast; /** * @author Dezapp, LLC * */ public class TwitterAuthScreen extends Activity { private static final String TAG = "TwitterAuthScreen: "; private SharedPreferences userPrefs; private SharedPreferences.Editor userPrefsEditor; private WebView wvTwitterAuth; private Twitter twitter; private RequestToken requestToken; private AccessToken twitterAccessToken; /* (non-Javadoc) * @see android.app.Activity#onCreate(android.os.Bundle) */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); overridePendingTransition(R.anim.slide_right_in, R.anim.slide_hold); setContentView(R.layout.twitter_auth_screen); init(); startTwitterAuth(); } /* (non-Javadoc) * @see android.app.Activity#onBackPressed() */ @Override public void onBackPressed() { super.onBackPressed(); overridePendingTransition(R.anim.slide_hold, R.anim.slide_right_out); } /** * Initialize all the variables to be used in {@link TwitterAuthScreen} */ private void init() { userPrefs = getSharedPreferences(MMSDKConstants.USER_PREFS, MODE_PRIVATE); userPrefsEditor = userPrefs.edit(); wvTwitterAuth = (WebView) findViewById(R.id.wvtwitterauth); } /** * Function creates the {@link Twitter} object with the Twitter consumer key and consumer secret. It creates {@link RequestToken} to obtain the url for authentication and load the url in a {@link WebView}. * NOTE: Not launching a browser with the authentication url due to the fact the current {@link Activity} need to have launchMode=singleTask in the manifest to handle callback url from Twitter. The * {@link WebViewClient} will handle the callback url for Twitter authentication. */ @SuppressLint("SetJavaScriptEnabled") private void startTwitterAuth() { ConfigurationBuilder builder = new ConfigurationBuilder(); builder.setOAuthConsumerKey(MMConstants.TWITTER_CONSUMER_KEY); builder.setOAuthConsumerSecret(MMConstants.TWITTER_CONSUMER_SECRET); builder.setOAuthAccessToken(null); builder.setOAuthAccessTokenSecret(null); Configuration configuration = builder.build(); TwitterFactory factory = new TwitterFactory(configuration); twitter = factory.getInstance(); try { requestToken = twitter.getOAuthRequestToken(MMSDKConstants.TWITTER_CALLBACK_URL); wvTwitterAuth.getSettings().setJavaScriptEnabled(true); wvTwitterAuth.setWebViewClient(new MobMonkeyWebViewClient()); wvTwitterAuth.loadUrl(requestToken.getAuthenticationURL()); MMProgressDialog.dismissDialog(); } catch (TwitterException e) { e.printStackTrace(); } } /** * Function that parse Uri converted Twitter authentication callback url. It will obtain the {@link AccessToken} for {@link Twitter} from the OAuth_verifier it will receive after authentication. * @param uri */ private void parseUri(Uri uri) { try { if(uri.getQueryParameter(MMSDKConstants.TWITTER_OAUTH_VERIFIER) != null) { twitterAccessToken = twitter.getOAuthAccessToken(requestToken, uri.getQueryParameter(MMSDKConstants.TWITTER_OAUTH_VERIFIER)); Log.d(TAG, TAG + "provider name: " + twitterAccessToken.getScreenName()); Log.d(TAG, TAG + "provider access token: " + twitterAccessToken.getToken()); MMUserAdapter.signInUserTwitter(new TwitterAuthCallback(), MMConstants.PARTNER_ID, twitterAccessToken.getScreenName(), twitterAccessToken.getToken()); int requestCode = getIntent().getIntExtra(MMSDKConstants.REQUEST_CODE, MMSDKConstants.DEFAULT_INT); // Depend on which Activity it was called from, it will display the appropriate signin/signup message if(requestCode == MMSDKConstants.REQUEST_CODE_SIGN_IN_TWITTER_AUTH) { MMProgressDialog.displayDialog(TwitterAuthScreen.this, MMSDKConstants.DEFAULT_STRING_EMPTY, getString(R.string.pd_signing_in_twitter)); } else if(requestCode == MMSDKConstants.REQUEST_CODE_SIGN_UP_TWITTER_AUTH) { MMProgressDialog.displayDialog(TwitterAuthScreen.this, MMSDKConstants.DEFAULT_STRING_EMPTY, getString(R.string.pd_signing_up_twitter)); } } else { finish(); } } catch (TwitterException e) { e.printStackTrace(); } } /** * Custom {@link WebViewClient} specifically to handle the callback url of Twitter * @author Dezapp, LLC * */ private class MobMonkeyWebViewClient extends WebViewClient { /* (non-Javadoc) * @see android.webkit.WebViewClient#shouldOverrideUrlLoading(android.webkit.WebView, java.lang.String) */ @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { if(url.contains(MMSDKConstants.TWITTER_CALLBACK_URL)) { parseUri(Uri.parse(url)); return true; } return false; } } /** * Custom {@link MMCallback} specifically for {@link TwitterAuthScreen} to be processed after receiving response from MobMonkey server. * @author Dezapp, LLC * */ private class TwitterAuthCallback implements MMCallback { public void processCallback(Object obj) { MMProgressDialog.dismissDialog(); if(((String) obj).equals(MMSDKConstants.CONNECTION_TIMED_OUT)) { Toast.makeText(TwitterAuthScreen.this, getString(R.string.toast_connection_timed_out), Toast.LENGTH_SHORT).show(); } else { try { JSONObject response = new JSONObject((String) obj); if(response.getString(MMSDKConstants.JSON_KEY_ID).equals(MMSDKConstants.RESPONSE_ID_SUCCESS)) { setResult(MMSDKConstants.RESULT_CODE_SUCCESS); userPrefsEditor.putString(MMSDKConstants.KEY_USER, twitterAccessToken.getScreenName()); userPrefsEditor.putString(MMSDKConstants.KEY_AUTH, twitterAccessToken.getToken()); userPrefsEditor.putBoolean(MMSDKConstants.KEY_USE_OAUTH, false); userPrefsEditor.putString(MMSDKConstants.KEY_USER, twitterAccessToken.getScreenName()); userPrefsEditor.putString(MMSDKConstants.KEY_AUTH, twitterAccessToken.getToken()); // TODO: set useOAuth to true once figure out how to get the email address from Twitter user // Twitter API does not allow email to be return to app // userPrefsEditor.putBoolean(MMSDKConstants.KEY_USE_OAUTH, true); // userPrefsEditor.putString(MMSDKConstants.KEY_OAUTH_PROVIDER, MMSDKConstants.OAUTH_PROVIDER_TWITTER); // userPrefsEditor.putString(MMSDKConstants.KEY_OAUTH_PROVIDER_USER_NAME, twitterAccessToken.getScreenName()); userPrefsEditor.commit(); } else if(response.getString(MMSDKConstants.JSON_KEY_ID).equals(MMSDKConstants.RESPONSE_ID_NOT_FOUND)) { Intent resultIntent = new Intent(); resultIntent.putExtra(MMSDKConstants.KEY_OAUTH_PROVIDER_USER_NAME, twitterAccessToken.getScreenName()); resultIntent.putExtra(MMSDKConstants.KEY_OAUTH_TOKEN, twitterAccessToken.getToken()); setResult(MMSDKConstants.RESULT_CODE_NOT_FOUND, resultIntent); } else { Toast.makeText(TwitterAuthScreen.this, response.getString(MMSDKConstants.JSON_KEY_DESCRIPTION), Toast.LENGTH_LONG).show(); } finish(); overridePendingTransition(R.anim.slide_hold, R.anim.slide_right_out); } catch (JSONException e) { e.printStackTrace(); } } Log.d(TAG, TAG + "response: " + (String) obj); } } }