【发布时间】:2016-03-05 00:43:18
【问题描述】:
我尝试使用 twitter 在 android 中创建一个基于 oAuth 的应用程序。但是我在注销时遇到问题,因为应用程序不会通过要求凭据登录并通过单击登录直接传递到另一个布局来要求用户重新授权它。我清除了所有共享首选项详细信息以注销但仍然无法正常工作。 这些是我的课程:
MainActivity.java
public class MainActivity extends Activity {
static String TWITTER_CONSUMER_KEY = "key";
static String TWITTER_CONSUMER_SECRET = "sec";
// Preference Constants
static 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";
private static final String PREF_USER_NAME = "twitter_user_name";
private static final String PREF_PROFILE_IMAGE = "twitter_profile_url";
static final String TWITTER_CALLBACK_URL = "oauth://t4jsample";
// Twitter oauth urls
static final String URL_TWITTER_OAUTH_VERIFIER = "oauth_verifier";
// Progress dialog
ProgressDialog pDialog;
// Twitter
private static Twitter mTwitter;
private static RequestToken requestToken;
/* Any number for uniquely distinguish your request */
public static final int WEBVIEW_REQUEST_CODE = 100;
// Shared Preferences
private static SharedPreferences mSharedPreferences;
private RelativeLayout profileLayout, loginLayout;
private TextView mProfileName;
private ImageView mProfileImage;
private EditText mTweetText;
private Bitmap mProfileBitmap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Shared Preferences
mSharedPreferences = getApplicationContext().getSharedPreferences(
"PREFERENCE_NAME", MODE_PRIVATE);
loginLayout = (RelativeLayout) findViewById(R.id.login_layout);
profileLayout = (RelativeLayout) findViewById(R.id.profile_layout);
mProfileName = (TextView) findViewById(R.id.user_name);
mProfileImage = (ImageView) findViewById(R.id.user_profilePicture);
mTweetText = (EditText) findViewById(R.id.tweet_text);
updateUI();
}
/**
* Check to see if user currently logged in or not and updates the UI
*/
private void updateUI() {
if (isUserLoggedIn()) {
loginLayout.setVisibility(View.GONE);
profileLayout.setVisibility(View.VISIBLE);
String username = mSharedPreferences.getString(PREF_USER_NAME, "");
String profilePictureURL = mSharedPreferences.getString(PREF_PROFILE_IMAGE, "");
new LoadProfilePicture().execute(profilePictureURL);
// Displaying in xml ui
mProfileName.setText(Html.fromHtml("<b>Welcome " + username + "</b>"));
} else {
loginLayout.setVisibility(View.VISIBLE);
profileLayout.setVisibility(View.GONE);
}
}
/**
* Calls when user click tweet button
* @param view
*/
public void postTweet(View view) {
// Call update status function
// Get the status from EditText
String status = mTweetText.getText().toString();
if (TextUtils.isEmpty(status)) {
// EditText is empty
Toast.makeText(getApplicationContext(),
"Please enter status message", Toast.LENGTH_SHORT)
.show();
return;
}
// update status
new PostTweetOnTwitter().execute(status);
mTweetText.setText("");
}
/**
* Calls when user click login button
* @param view
*/
public void loginUser(View view) {
new LoginUserOnTwitter().execute();
}
/**
* Calls when user click logout button
* @param view
*/
public void logoutUser(View view) {
// Clear the shared preferences
getSharedPreferences("PREFERENCE_NAME", MODE_PRIVATE).edit().clear().commit();
SharedPreferences.Editor editor = mSharedPreferences.edit();
editor.remove(PREF_KEY_OAUTH_TOKEN).clear().commit();
editor.remove(PREF_KEY_OAUTH_SECRET).clear().commit();
editor.remove(PREF_KEY_TWITTER_LOGIN).clear().commit();
editor.remove(PREF_USER_NAME).clear().commit();
editor.remove(PREF_PROFILE_IMAGE).clear().commit();
editor.apply();
editor.commit();
updateUI();
}
/**
* Check user already logged in your application using twitter Login flag is
* fetched from Shared Preferences
*/
private boolean isUserLoggedIn() {
// return twitter login status from Shared Preferences
return mSharedPreferences.getBoolean(PREF_KEY_TWITTER_LOGIN, false);
}
/**
* Function to login user
*/
class LoginUserOnTwitter extends AsyncTask<Void, Void, String> {
@Override
protected String doInBackground(Void... params) {
ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
configurationBuilder.setOAuthConsumerKey(TWITTER_CONSUMER_KEY);
configurationBuilder.setOAuthConsumerSecret(TWITTER_CONSUMER_SECRET);
Configuration configuration = configurationBuilder.build();
mTwitter = new TwitterFactory(configuration).getInstance();
try {
requestToken = mTwitter.getOAuthRequestToken(TWITTER_CALLBACK_URL);
/**
* Loading twitter login page on webview for authorization
* Once authorized, results are received at onActivityResult
* */
final Intent intent = new Intent(MainActivity.this, WebViewActivity.class);
intent.putExtra(WebViewActivity.EXTRA_URL, requestToken.getAuthenticationURL());
startActivityForResult(intent, WEBVIEW_REQUEST_CODE);
} catch (TwitterException e) {
e.printStackTrace();
}
return null;
}
}
/**
* Saving user information, after user is authenticated for the first time.
* You don't need to show user to login, until user has a valid access token
*/
private void saveTwitterInfo(AccessToken accessToken) {
long userID = accessToken.getUserId();
User user;
try {
user = mTwitter.showUser(userID);
String username = user.getName();
String profilePicture = user.getOriginalProfileImageURL();
/* Storing oAuth tokens to shared preferences */
SharedPreferences.Editor editor = mSharedPreferences.edit();
editor.putString(PREF_KEY_OAUTH_TOKEN, accessToken.getToken());
editor.putString(PREF_KEY_OAUTH_SECRET, accessToken.getTokenSecret());
editor.putBoolean(PREF_KEY_TWITTER_LOGIN, true);
editor.putString(PREF_USER_NAME, username);
editor.putString(PREF_PROFILE_IMAGE, profilePicture);
editor.apply();
} catch (TwitterException e1) {
e1.printStackTrace();
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == Activity.RESULT_OK) {
if (requestCode == WEBVIEW_REQUEST_CODE && data != null) {
final Uri uri = Uri.parse(data.getStringExtra("KEY_URI"));
new Thread(new Runnable() {
@Override
public void run() {
String verifier = uri.getQueryParameter(MainActivity.URL_TWITTER_OAUTH_VERIFIER);
try {
AccessToken accessToken = mTwitter.getOAuthAccessToken(requestToken, verifier);
saveTwitterInfo(accessToken);
MainActivity.this.runOnUiThread(new Runnable() {
@Override
public void run() {
updateUI();
}
});
} catch (Exception e) {
e.printStackTrace();
if (e.getMessage() != null) {
Log.e("Twitter-->", e.getMessage());
} else {
Log.e("Twitter-->", "ERROR: Twitter callback failed");
}
}
}
}).start();
}
super.onActivityResult(requestCode, resultCode, data);
}
}
/**
* Function to update status
*/
class PostTweetOnTwitter extends AsyncTask<String, Void, String> {
/**
* Before starting background thread Show Progress Dialog
*/
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Updating to twitter...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
/**
* getting Places JSON
*/
protected String doInBackground(String... args) {
Log.d("Tweet Text", "> " + args[0]);
String status = args[0];
try {
ConfigurationBuilder builder = new ConfigurationBuilder();
builder.setOAuthConsumerKey(TWITTER_CONSUMER_KEY);
builder.setOAuthConsumerSecret(TWITTER_CONSUMER_SECRET);
// Access Token
String access_token = mSharedPreferences.getString(PREF_KEY_OAUTH_TOKEN, "");
// Access Token Secret
String access_token_secret = mSharedPreferences.getString(PREF_KEY_OAUTH_SECRET, "");
AccessToken accessToken = new AccessToken(access_token, access_token_secret);
Twitter twitter = new TwitterFactory(builder.build()).getInstance(accessToken);
// Update status
twitter4j.Status response = twitter.updateStatus(status);
Log.d("Status", "> " + response.getText());
} catch (TwitterException e) {
// Error in updating status
Log.d("Twitter Update Error", e.getMessage());
}
return null;
}
/**
* After completing background task Dismiss the progress dialog
**/
protected void onPostExecute(String file_url) {
// dismiss the dialog after getting all products
pDialog.dismiss();
}
}
/**
* Function to load profile picture
*/
private class LoadProfilePicture extends AsyncTask<String, Void, Bitmap> {
@Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Loading profile ...");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
/**
* Download image from the url
**/
protected Bitmap doInBackground(String... args) {
try {
mProfileBitmap = BitmapFactory.decodeStream((InputStream) new URL(args[0]).getContent());
} catch (Exception e) {
e.printStackTrace();
}
return mProfileBitmap;
}
/**
* After completing background task Dismiss the progress dialog and set bitmap to imageview
**/
protected void onPostExecute(Bitmap image) {
Bitmap image_circle = Bitmap.createBitmap(image.getWidth(), image.getHeight(), Bitmap.Config.ARGB_8888);
BitmapShader shader = new BitmapShader(image, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP);
Paint paint = new Paint();
paint.setShader(shader);
Canvas c = new Canvas(image_circle);
c.drawCircle(image.getWidth() / 2, image.getHeight() / 2, image.getWidth() / 2, paint);
mProfileImage.setImageBitmap(image_circle);
pDialog.hide();
}
}
}
我正在使用 web 视图调用 twitter oAuth。
WebViewActivity.java
public class WebViewActivity extends Activity{
WebView webView;
public static String EXTRA_URL = "extra_url";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.auth_dialog);
setTitle("Login");
final String url = this.getIntent().getStringExtra(EXTRA_URL);
if (null == url) {
Log.e("Twitter", "URL cannot be null");
finish();
}
webView = (WebView) findViewById(R.id.webView);
webView.setWebViewClient(new WebViewClient(){
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url){
if( url.contains(MainActivity.TWITTER_CALLBACK_URL)){
Uri uri = Uri.parse(url);
Intent resultIntent = new Intent();
resultIntent.putExtra("KEY_URI", uri.toString());
setResult(RESULT_OK, resultIntent);
/* closing webview */
finish();
return true;
}
return false;
}
});
webView.loadUrl(url);
}
}
我附上了我的应用程序的屏幕截图,并想展示它应该如何工作:
我需要的是当我发推文并单击注销并被重定向到登录屏幕时,我希望应用程序再次询问我的授权详细信息。目前,我的应用在登录后第二次使用时直接切换,无需询问我的任何详细信息以发送推文。
感谢任何形式的帮助。
【问题讨论】:
标签: java android eclipse twitter oauth