My app I'm developing launches the official twitter app new post screen so the user can post a tweet with some extra text added in the intent. I have got this working nicely however things get a little confused if the user is not logged in with the twitter app. The app launches but the user has to sign in, once they've done that the normal twitter screen appears, if they use the back button to get back to my app the new post screen actually appears after hitting back on the twitter feed screen.
Is there any way I can check that a user is actually signed into the twitter app before trying to run the intent?
I think it's a Twitter app internal issue and you can't test for it.
On the other hand you could provide a Dialog warning the user for this matter with a "Do not show this dialog anymore" checkbox so he gets advised and can dimiss forever the Dialog. You could even provide instructions to authenticate insside the Twitter app in this Dialog.
I am using twitter4j lib.
Here I check for the username. If the username is null then there is no user signed in , else I get the username. This user name is available in the access token which I store in shared preference.
username= mySession.getUsername();
username = (username.equals("")) ? "Not logged in" : username;
code for mySession :-
public class MySession {
private SharedPreferences sharedPref;
private Editor editor;
private static final String TWEET_AUTH_KEY = "auth_key";
private static final String TWEET_AUTH_SECRET_KEY = "auth_secret_key";
private static final String TWEET_USER_NAME = "user_name";
private static final String SHARED = "Twitter_Preferences";
public TwitterSession(Context context) {
sharedPref = context.getSharedPreferences(SHARED, Context.MODE_PRIVATE);
editor = sharedPref.edit();
}
public void storeAccessToken(AccessToken accessToken, String username) {
editor.putString(TWEET_AUTH_KEY, accessToken.getToken());
editor.putString(TWEET_AUTH_SECRET_KEY, accessToken.getTokenSecret());
editor.putString(TWEET_USER_NAME, username);
editor.commit();
}
public void resetAccessToken() {
editor.putString(TWEET_AUTH_KEY, null);
editor.putString(TWEET_AUTH_SECRET_KEY, null);
editor.putString(TWEET_USER_NAME, null);
editor.commit();
}
public String getUsername() {
return sharedPref.getString(TWEET_USER_NAME, "");
}
public AccessToken getAccessToken() {
String token = sharedPref.getString(TWEET_AUTH_KEY, null);
String tokenSecret = sharedPref.getString(TWEET_AUTH_SECRET_KEY, null);
if (token != null && tokenSecret != null)
return new AccessToken(token, tokenSecret);
else
return null;
}
}
Hope this will help you.
Try this function which will in turn returns you true or false.
True : Logged in
False : Not logged in
twitter.getAuthorization() function will throw you an error if it is not logged in by handling this you can find whether user is previously logged in or not.
public static boolean isAuthenticated(SharedPreferences prefs) {
String token = prefs.getString(OAuth.OAUTH_TOKEN, "");
String secret = prefs.getString(OAuth.OAUTH_TOKEN_SECRET, "");
AccessToken a = new AccessToken(token,secret);
Twitter twitter = new TwitterFactory().getInstance();
twitter.setOAuthConsumer(Constants.CONSUMER_KEY, Constants.CONSUMER_SECRET);
try {
twitter.getAuthorization();
return true;
} catch (Exception e) {
return false;
}
}
just add these lines in the oncreate() in ur activity
final Session activeSession = Twitter.getInstance().core.getSessionManager().getActiveSession();
if (activeSession != null){
//do someting
}
Related
i dont know how to use my saved authentication token after restart of my application, so i don´t need to authenticate again.
/*DROPBOX ==========================*/
private String APP_KEY= "key";
private String APP_SECRET= "secret";
AppKeyPair appKeys;
AndroidAuthSession session;
DropboxAPI<AndroidAuthSession> dpAPI;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.readings_main);
//get dropbox keys
SharedPreferences sharedPref = getSharedPreferences(getString(R.string.dp_key_token), Context.MODE_PRIVATE);
// if i use these 2 lines i get exception that my key isn´t set in manifest, and thats true because in manifest i have the first key, not hte generated after auth.
// APP_KEY= sharedPref.getString("key", "key");
// APP_SECRET= sharedPref.getString("secret", "secret");
appKeys = new AppKeyPair(APP_KEY, APP_SECRET);
// setup dropbox session
session = new AndroidAuthSession(appKeys, AccessType.DROPBOX);
dpAPI= new DropboxAPI<AndroidAuthSession>(session);
}
protected void onResume() {
super.onResume();
if (dpAPI.getSession().authenticationSuccessful()) {
try {
// Required to complete auth, sets the access token on the session
dpAPI.getSession().finishAuthentication();
AccessTokenPair tokens = dpAPI.getSession().getAccessTokenPair();
//store keys in sharedpreferences ;
storeKeys(tokens.key, tokens.secret);
} catch (IllegalStateException e) {
Log.i("DbAuthLog", "Error authenticating", e);
}
}
}
public boolean storeKeys(String key, String secret) {
SharedPreferences sharedPref = getSharedPreferences(getString(R.string.dp_key_token), Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putString("key", key);
editor.putString("secret", secret);
return editor.commit();
}
Later i use...
dpAPI.getSession().startAuthentication(ADLAppActivity.this);
and then i upload a file, so everything works fine for me. But, after restart App i don´t want to authenticate again. How should i use the saved Token in SharedPref???
Please check this answer.
Instead of calling dpAPI.getSession().startAuthentication(ADLAppActivity.this); you should call session.setOAuth2AccessToken(RESTORED_TOKEN); with your token restored from preferences.
So I'm trying to get a list of status objects from a public Twitter timeline ( not my own Twitter timeline or anything that I have admin access to, just a public one from a local organization ) using the Twitter4J library in Android Studio, but I'm getting a little confused by the documentation. I'm running into this error: "Invalid access token format."
I did create a developers account with Twitter and got a consumer key and token, as well as an access token and secret numbers. Those values are saved in a set of private static strings for now. TWITTER_ZOO_ID is a private long with the Twitter ID number for the feed that I want to display. Here's the applicable code that I currently have:
Twitter twitter;
List<Status> statuses = null;
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setDebugEnabled(true)
.setOAuthConsumerKey( TWITTER_CONSUMER_KEY )
.setOAuthConsumerSecret( TWITTER_CONSUMER_SECRET )
.setOAuthAccessToken( TWITTER_AUTH_TOKEN )
.setOAuthAccessTokenSecret( TWITTER_AUTH_TOKEN_SECRET );
try {
TwitterFactory tf = new TwitterFactory(cb.build());
twitter = tf.getInstance();
twitter.setOAuthConsumer( TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET );
statuses = twitter.getUserTimeline( TWITTER_ZOO_ID );
}
catch( TwitterException e ) {
Log.e( "TwitterListFragment", "Twitter Exception" );
return;
}
for( Status status : statuses )
mAdapter.add( status );
If anyone has a link to a good example for Twitter 1.1 using Twitter4J, or can provide an example of how to get those statuses, I'd really appreciate it. I'm currently using Android Studio and including Twitter4J in Gradle from MavenCentral.
Thank you!
EDIT:
Upon further reading, I've added this additional code without success:
twitter.setOAuthConsumer( TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET );
AccessToken token = new AccessToken( TWITTER_AUTH_TOKEN, TWITTER_AUTH_TOKEN_SECRET );
twitter.setOAuthAccessToken( token );
If you want to get info from a public Twitter timeline, you can use Application-only Authentication, because the user doesn´t need to login, I think it fits you because you don´t use admin rights.
The application-only auth flow follows these steps:
An application encodes its consumer key and secret into a specially
encoded set of credentials.
An application makes a request to the POST
oauth2/token endpoint to exchange these credentials for a bearer token.
When accessing the REST API, the application uses the bearer token to authenticate.
Because twitter4j has added this feature recently, you should use the last snapshot library.
An example using it:
private ConfigurationBuilder builder;
private Twitter twitter;
private TwitterFactory factory;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.init_act_layout);
// setup
builder = new ConfigurationBuilder();
builder.setUseSSL(true);
builder.setApplicationOnlyAuthEnabled(true);
builder.setOAuthConsumerKey(Constants.CONSUMER_KEY);
builder.setOAuthConsumerSecret(Constants.CONSUMER_SECRET);
Configuration configuration = builder.build();
factory = new TwitterFactory(configuration);
((MyApp) (MyApp.getApp())).setTFactory(factory);
if (isNeededTwitterAuth()) {
twitter = factory.getInstance();
//Get the token async and save it
}
//Search tweets
}
/*
* Checks if twitter access token is already saved in preferences
*
* #return true if auth needed
*/
private boolean isNeededTwitterAuth() {
SharedPreferences settings = getSharedPreferences(Constants.TWITTER_PREFERENCES, Context.MODE_PRIVATE);
String twitterAccesToken = settings.getString("bearerAccessToken", "");
String twitterTokenType = settings.getString("bearerTokenType", "");
return ((twitterAccesToken.length() == 0) && (twitterTokenType.length() == 0));
}
}
To get the bearer token, do it out of Main UI thread to avoid Network exception, f.i. using AsyncTask:
#Override
protected OAuth2Token doInBackground(Void... params) {
OAuth2Token bearerToken = null;
try {
bearerToken = twitter.getOAuth2Token();
} catch (TwitterException e) {
e.printStackTrace();
}
return bearerToken;
}
When you obtain the bearer token, save it:
SharedPreferences appSettings = getSharedPreferences(Constants.TWITTER_PREFERENCES, MODE_PRIVATE);
SharedPreferences.Editor prefEditor = appSettings.edit();
prefEditor.putString("bearerAccessToken", result.getAccessToken());
prefEditor.putString("bearerTokenType", result.getTokenType());
prefEditor.commit();
And to use the bearer token:
OAuth2Token bearerToken = new OAuth2Token(bearerTokenType, bearerAccesstoken);
twitter.setOAuth2Token(bearerToken);
And search tweets (always out of Main thread):
#Override
protected QueryResult doInBackground(Void... params) {
twitter.setOAuth2Token(bearerToken);
Query query = new Query();
[...]
result = twitter.search(query);
A complete explanation in the blog (in Spanish...)
And a complete example in the twitter4j github
Hope it helps!
I would recommend using the recently updated Twitter SDK (Fabric).
https://docs.fabric.io/android/twitter/twitter.html
I want to log out Twitter. I tried to clear reference and request with a new request URI but my account still login. I read this question but it doesn't describe how to login in detail. How to logout Twitter and login with different account? Could you give me some code for logout or relogin?
The function get requet URI
public static String getRequestURI() {
try {
final Twitter twitter = new TwitterFactory().getInstance();
twitter.setOAuthConsumer(Constant.CONSUMER_KEY, Constant.CONSUMER_SECRET);
requestToken = twitter.getOAuthRequestToken(Constant.CALLBACK_URI);
return requestToken.getAuthenticationURL();
} catch (final TwitterException e) {
e.printStackTrace();
}
return "";
}
The function clear reference
public static boolean logout(final Context context) {
getPrefs(context);
CustomSharedPreferences.setPreferences(Constant.ACCESS_TOKEN, "");
CustomSharedPreferences.setPreferences(Constant.ACCESS_TOKEN_SECRET, "");
return true;
}
mTwitter.setOAuthAccessToken(null);
mTwitter.shutdown();
That works, source http://wenchaokong.blogspot.in/2013/03/android-twitter-integration-twitter4j.html
I'm trying to create on android a facebook application and I'm using android facebook-sdk .
The example that I'm trying to understand is this one:
https://github.com/facebook/facebook-android-sdk/tree/master/examples/stream
There is something that I don't understand in here if u could help me out a little bit it would be great.
At some point in the main Activity is doing something like:
Dispatcher dispatcher = new Dispatcher(this);
dispatcher.addHandler("login", LoginHandler.class);
dispatcher.addHandler("stream", StreamHandler.class);
dispatcher.addHandler("logout", LogoutHandler.class);
Session session = Session.restore(this);
if (session != null) {
dispatcher.runHandler("stream");
} else {
dispatcher.runHandler("login");
}
}
What I don't understand is the way this Session.restore(this) works.
The restore method looks like this:
public static Session restore(Context context) {
if (singleton != null) {
if (singleton.getFb().isSessionValid()) {
return singleton;
} else {
return null;
}
}
SharedPreferences prefs =
context.getSharedPreferences(KEY, Context.MODE_PRIVATE);
String appId = prefs.getString(APP_ID, null);
if (appId == null) {
return null;
}
Facebook fb = new Facebook(appId);
fb.setAccessToken(prefs.getString(TOKEN, null));
fb.setAccessExpires(prefs.getLong(EXPIRES, 0));
String uid = prefs.getString(UID, null);
String name = prefs.getString(NAME, null);
if (!fb.isSessionValid() || uid == null || name == null) {
return null;
}
Session session = new Session(fb, uid, name);
singleton = session;
return session;
}
If someone could explain me what is the whole purpose of SharedPreferences, what is stored there and why are these 2 lines needed :
fb.setAccessToken(prefs.getString(TOKEN, null));
fb.setAccessExpires(prefs.getLong(EXPIRES, 0));
When you access any facebook user information or any other action which requires permission to be accessed as shown below. . If the user press Allow button then A Token is inserted in their Database with the user Id , your App Id and the validation time (which may be unlimited) as well as the Actions you may perform (e.g Access Info, Send Email, Access Posts, Post to Wall etc.), that specific Token is returned to you and you save that Token to access the info and other action which are permitted against that token.
Whenever you make a request for any action they match that token, check validation and then see if that action is allowed by the user, if allowed you are granted to complete the action.
Here is my code, i keep getting an exception "Authorization failed (server replied with a 401). This can happen if the consumer key was not correct or the signatures did not match." on this line 'provider.retrieveAccessToken(consumer, verifier);'. I have triple checked my consumer key and secret and my twitter application is set as a Browser and tried setting provider.setOAuth10a(true), i have been struggling on this for 2 days!! I am using signpost 1.2.1.1 (core & commonshttp4), If anyone can help! Please im desperate
private static final String CONSUMER_KEY = "MY_CONSUMER_KEY";
private static final String CONSUMER_SECRET = "MY_CONSUMER_SECRET";
private static final String CALLBACK_URL = "tweet-mapper://mainactivity";
private static final String REQUEST_URL = "https://api.twitter.com/oauth/request_token";
private static final String ACCESS_TOKEN_URL = "https://api.twitter.com/oauth/access_token";
private static final String AUTH_URL = "https://api.twitter.com/oauth/authorize";
private static final String PREFERENCE_FILE = "twitter_oauth.prefs";
private static CommonsHttpOAuthConsumer consumer;
private static CommonsHttpOAuthProvider provider;
private static String ACCESS_KEY;
private static String ACCESS_SECRET;
private Twitter twitter;
/**
* Called when the activity is first created.
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
loginViaOAuth();
}
private void loginViaOAuth() {
try {
consumer = new CommonsHttpOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
provider.setOAuth10a(true);
provider = new CommonsHttpOAuthProvider(REQUEST_URL, ACCESS_TOKEN_URL, AUTH_URL);
String authURL = provider.retrieveRequestToken(consumer, CALLBACK_URL);
this.startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(authURL)));
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
}
}
#Override
protected void onResume() {
super.onResume();
Uri uri = this.getIntent().getData();
if (uri != null && uri.toString().startsWith(CALLBACK_URL)) {
String verifier = uri.getQueryParameter(OAuth.OAUTH_VERIFIER);
Log.d("verifier:", verifier);
try {
provider.setOAuth10a(true);
provider.retrieveAccessToken(consumer, verifier);
ACCESS_KEY = consumer.getToken();
ACCESS_SECRET = consumer.getTokenSecret();
AccessToken a = new AccessToken(ACCESS_KEY, ACCESS_SECRET);
// initialize Twitter4J
twitter = new Twitter();
twitter.setOAuthConsumer(CONSUMER_KEY, CONSUMER_SECRET);
twitter.setOAuthAccessToken(a);
String tweet = "#OAuth working via android app!";
twitter.updateStatus(tweet);
Toast.makeText(this, tweet, Toast.LENGTH_LONG).show();
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
}
}
Just found out a possible solution: You need to set a Callback URL on your twitter application account.
I had exactly the same problem on my Android application. It was even more frustrating that my twitter login was perfectly working and starting to fail on the signature for some random reasons.
I ran a lot of tests and I found that the problem came from the Android browser which is used in the OAuth process:
if you are logging in using the stored login/password, or if you have a cookie with your Twitter session and just have to click on "Accept", it fill fail with the 401 error
if you manually delete and re-enter your password, then it works!
I still can't understand how this affects the API call, but I guess there is some mix up in the browser when you submit the "accept" form with pre-entered information.
I'd be very curious to see if my workaround solves also your problem. I understand this is not a proper solution, but this is a beginning.
EDIT: use http:// instead of https:// for the Twitter OAuth URLs and it solves the problem. I still don't unsertand what is happening...
Check your api request it must be .json or .xml, something like
https://api.jabbakam.com/network/get_list.json or
http://api.twitter.com/1/account/verify_credentials.xml
I advise you to use Scribe library there is a built in class for using Twitter API.
https://github.com/fernandezpablo85/scribe-java/blob/master/src/test/java/org/scribe/examples/TwitterExample.java
When you create your twitter keys did you make Access level: Read and write?