First off, I've looked at every question on the topic in this site at least twice, and I haven't been able to find anything.
I've used some tutorials to create a simple Twitter client with Twitter4J that only provides OAuth login. The code takes the user to the browser, where the accept the OAuth, and then the browser returns me to my app.
However, I'm unable to get the OAuth Access token using the method getOAuthAccessToken()
, in the method onNewIntent(Intent intent)
and the log shows that the error is simply Twitter Login Error > null
.
I've tried changing the location of the getOAuthAccessToken()
to with an onResume, an onNewIntent, I've made the Activity a singleInstance and a singleTask, and I've set the date and time correctly. If anyone could help me get the access token from Twitter upon returning from the browser, that would be great, thanks! Here's my code:
public class mAppActivity extends Activity {
// constants
static final String TWITTER_CONSUMER_KEY = "";
static final String TWITTER_CONSUMER_SECRET =
"";
// preference constants
static final String PREFERENCE_NAME = "twitter_oauth";
static final String PREF_KEY_OAUTH_TOKEN = "oauth_token";
static final String PREF_KEY_OAUTH_SECRET = "oauth_token_secret";
static final String PREF_KEY_TWITTER_LOGIN = "isTwitterLoggedIn";
static final String TWITTER_CALLBACK_URL = "callback://x-oauthflow-twitter";
// Twitter OAuth URLS
static final String URL_TWITTER_AUTH = "auth_url";
static final String URL_TWITTER_OAUTH_VERIFIER = "oauth_verifier";
static final String URL_TWITTER_OAUTH_TOKEN = "oauth_token";
// Buttons
Button btnLoginTwitter;
Button btnUpdateStatus;
Button btnLogoutTwitter;
// EditText for update
EditText txtUpdate;
// lbl update
TextView lblUpdate;
TextView lblUserName;
// ProgressDialog
ProgressDialog pdialog;
// Twitter
private static Twitter twitter;
private static RequestToken requestToken;
private AccessToken accessToken;
// SharedPreferences
private static SharedPreferences mSharedPreferences;
// Internet ConnectionDetector
private ConnectionDetector cd;
// AlertDialogManager
AlertDialogManager alert = new AlertDialogManager();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_app_m);
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
cd = new ConnectionDetector(getApplicationContext());
// check if connected to Internet
if (!cd.isConnectingToInternet()) {
// show error message
alert.showAlertDialog(mAppActivity.this,
"Internet Connection Error",
"Please connect to working Internet connection",
false);
// stop code by returning
return;
}
// check if Twitter keys are set
if (TWITTER_CONSUMER_KEY.trim().length() == 0 ||
TWITTER_CONSUMER_SECRET.trim().length() == 0) {
// show error message
alert.showAlertDialog(mAppActivity.this,
"Twitter OAuth Tokens Error",
"Please set your Twitter OAuth tokens first!",
false);
// stop code by returning
return;
}
// All UI elements
btnLoginTwitter = (Button) findViewById(R.id.btnLoginTwitter);
btnUpdateStatus = (Button) findViewById(R.id.btnUpdateStatus);
btnLogoutTwitter = (Button) findViewById(R.id.btnLogoutTwitter);
txtUpdate = (EditText) findViewById(R.id.txtUpdateStatus);
lblUpdate = (TextView) findViewById(R.id.lblUpdate);
lblUserName = (TextView) findViewById(R.id.lblUserName);
// SharedPreferences
mSharedPreferences = getApplicationContext()
.getSharedPreferences("MyPrefs", 0);
/**
* Twitter login button click event
* will call loginToTwitter() function
*/
btnLoginTwitter.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// Call Twitter login function
loginToTwitter();
}
});
/**
* Twitter logout button click
*/
btnLogoutTwitter.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// call Twitter logout function
logoutFromTwitter();
}
});
}
/**
* Function to log in to Twitter
*/
private void loginToTwitter() {
// Check if already logged in
if (!isTwitterLoggedInAlready()) {
ConfigurationBuilder builder = new ConfigurationBuilder();
builder.setUseSSL(true);
builder.setOAuthConsumerKey(TWITTER_CONSUMER_KEY);
builder.setOAuthConsumerSecret(TWITTER_CONSUMER_SECRET);
Configuration configuration = builder.build();
TwitterFactory factory = new TwitterFactory(configuration);
twitter = factory.getInstance();
Thread thread = new Thread(new Runnable(){
@Override
public void run() {
try {
requestToken = twitter
.getOAuthRequestToken(TWITTER_CALLBACK_URL);
mAppActivity.this.startActivity(new Intent(Intent.ACTION_VIEW, Uri
.parse(requestToken.getAuthenticationURL())));
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.start();
} else {
// user is already logged in into Twitter
Toast.makeText(getApplicationContext(),
"Already Logged into Twitter", Toast.LENGTH_LONG).show();
}
}
/**
* Checks if user is already logged in using Twitter login
* fetched from Shared Preferences
*/
private boolean isTwitterLoggedInAlready() {
// return Twitter login status from SharedPreferences
return mSharedPreferences.getBoolean(PREF_KEY_TWITTER_LOGIN, false);
}
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
/**
* This if condition is tested user is
* redirected from Twitter page. Parse the URI to OAuth Verifier
*/
Uri uri = intent.getData();
Toast.makeText(getApplicationContext(),
uri.toString(), Toast.LENGTH_LONG).show();
if (uri != null && uri.toString().startsWith(TWITTER_CALLBACK_URL)) {
// OAuth verifier
final String verifier = uri
.getQueryParameter(URL_TWITTER_OAUTH_VERIFIER);
try {
// get the access token
mAppActivity.this.accessToken =
twitter.getOAuthAccessToken(
requestToken);
// SharedPreferences
Editor e = mSharedPreferences.edit();
// after getting access token, access token secret
// store them in application preferences
e.putString(PREF_KEY_OAUTH_TOKEN, accessToken.getToken());
e.putString(PREF_KEY_OAUTH_SECRET,
accessToken.getTokenSecret());
// store login status - true
e.putBoolean(PREF_KEY_TWITTER_LOGIN, true);
e.commit(); // save changes
Log.e("Twitter OAuth Token", "> " + accessToken.getToken());
// hide login button
btnLoginTwitter.setVisibility(View.GONE);
// show update Twitter
lblUpdate.setVisibility(View.VISIBLE);
txtUpdate.setVisibility(View.VISIBLE);
btnUpdateStatus.setVisibility(View.VISIBLE);
btnLogoutTwitter.setVisibility(View.VISIBLE);
// get user details from Twitter
// for now only username is being gotten
long userID = accessToken.getUserId();
User user = twitter.showUser(userID);
String username = user.getName();
// display in xml ui
lblUserName.setText(Html.fromHtml("<b>Welcome " + username + "</b>"));
} catch (Exception e) {
// catch log for login errors
Log.e("Twitter Login Error", "> " + e.getMessage());
}
}
}
}
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.messagingapplication"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<!-- Permission - Internet Connect -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- Network State Permissions -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.messagingapplication.mAppActivity"
android:label="@string/app_name"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="x-oauthflow-twitter"
android:scheme="callback" />
</intent-filter>
</activity>
<activity
android:name="com.example.messagingapplication.MAppMainActivity"
android:label="@string/title_activity_mapp_main" >
</activity>
<activity
android:name="com.example.messagingapplication.Teest"
android:label="@string/title_activity_teest" >
</activity>
</application>
</manifest>