Reputation: 385
I'm trying to get a user timeline from twitter with oauth2 (for application-only authentication) but the result is always null. I don't have experience with OAUTH , and I have looked to a couple tutorials and examples, but with no luck so far. I need to retreive a specific users timeline(in this example Twitter) without the user needing to login.
I had an application that used twitter API 1 and I tried to adapt my existing code to the new API 1.1 with oauth2 for application-only auth. So the code should work except it does'nt get anything back from Twitter. If I do get a result back then it should work again.
the connection with Twitter is made in the function twitterconnect underneath the asyncop.
here is my code:
public class TwitterActivity extends Activity {
private ConfigurationBuilder builder;
// twitter consumer key and secret
static String TWITTER_CONSUMER_KEY = "**************";
static String TWITTER_CONSUMER_SECRET = "*************";
// twitter acces token and accestokensecret
static String TWITTER_ACCES_TOKEN = "************";
static String TWITTER_ACCES_TOKEN_SECRET = "************";
ArrayList<Tweet> tweets = new ArrayList<Tweet>();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.twitter);
new AsyncOp().execute("test");
}
//Async class...
public class AsyncOp extends AsyncTask<String, Void,List<twitter4j.Status>> {
protected List<twitter4j.Status> doInBackground(String... urls) {
//auth with twitter
List<twitter4j.Status> statuses = null;
try {
Twitter twitter=twitterConnect();
statuses = twitter.getUserTimeline("Twitter");
return statuses;
} catch (Exception ex) {
Log.d("Main.displayTimeline", "" + ex.getMessage());
}
return statuses;
}
protected void onPostExecute(List<twitter4j.Status> statuses) {
try {
String TWITTER="EEE MMM dd HH:mm:ss ZZZZZ yyyy"; SimpleDateFormat sf=new
SimpleDateFormat(TWITTER, Locale.ENGLISH); sf.setLenient(true);
for(int i=0;i<statuses.size();i++){
twitter4j.Status stat = statuses.get(i);
User user=stat.getUser();
Date datePosted=stat.getCreatedAt();
String text=stat.getText();
String name=user.getName();
String profile_image_url=user.getProfileImageURL();
Tweet t =new Tweet(datePosted,text,name,profile_image_url,twitterHumanFriendlyDate(datePosted));
tweets.add(t);
// logcat info
Log.i("date",datePosted.toString());
Log.i("text",text);
Log.i("user",name);
Log.i("userprofilepic",profile_image_url);
Log.i("timeofpost",twitterHumanFriendlyDate(datePosted));
}
ListView listView = (ListView) findViewById(R.id.ListViewId);
listView.setAdapter(new UserItemAdapter(TwitterActivity.this,
R.layout.listitem, tweets));
ProgressBar bar=(ProgressBar) findViewById(R.id.progressBar1);
bar.setVisibility(View.GONE);
} catch
(Exception e) { e.printStackTrace(); } }
}
public class UserItemAdapter extends ArrayAdapter<Tweet> {
private ArrayList<Tweet> tweets;
public UserItemAdapter(Context context, int textViewResourceId,
ArrayList<Tweet> tweets) {
super(context, textViewResourceId, tweets);
this.tweets = tweets;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = convertView;
if (v == null) {
LayoutInflater vi = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
v = vi.inflate(R.layout.listitem, null);
}
Tweet tweet = tweets.get(position);
if (tweet != null) {
TextView username = (TextView) v.findViewById(R.id.username);
TextView message = (TextView) v.findViewById(R.id.message);
ImageView image = (ImageView) v.findViewById(R.id.avatar);
TextView date = (TextView) v.findViewById(R.id.date);
if (username != null) {
username.setText(tweet.username);
}
if (message != null) {
message.setText(tweet.message);
}
if (image != null) {
image.setImageBitmap(getBitmap(tweet.image_url));
}
if (date != null) {
date.setText(tweet.hfdate);
}
}
return v;
}
}
public Bitmap getBitmap(String bitmapUrl) {
try {
URL url = new URL(bitmapUrl);
return BitmapFactory.decodeStream(url.openConnection()
.getInputStream());
} catch (Exception ex) {
return null;
}
}
// build twitter
public Twitter twitterConnect() throws Exception
{
// setup
builder.setOAuthConsumerKey(TWITTER_CONSUMER_KEY).setOAuthConsumerSecret(TWITTER_CONSUMER_SECRET);
OAuth2Token token = new TwitterFactory(builder.build()).getInstance().getOAuth2Token();
// exercise & verify
ConfigurationBuilder cb = new ConfigurationBuilder();
cb.setUseSSL(true);
cb.setApplicationOnlyAuthEnabled(true);
Twitter twitter = new TwitterFactory(cb.build()).getInstance();
twitter.setOAuthConsumer(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET);
twitter.setOAuth2Token(token);
return twitter;
}
public String twitterHumanFriendlyDate(Date dateCreated) {
// parse Twitter date
SimpleDateFormat dateFormat = new SimpleDateFormat(
"EEE MMM dd HH:mm:ss ZZZZZ yyyy", Locale.ENGLISH);
dateFormat.setLenient(false);
Date created = dateCreated;
// today
Date today = new Date();
// how much time since (ms)
Long duration = today.getTime() - created.getTime();
long second = 1000;
long minute = second * 60;
long hour = minute * 60;
long day = hour * 24;
if (duration < second * 7) {
return "right now";
}
if (duration < minute) {
int n = (int) Math.floor(duration / second);
return n + " seconds ago";
}
if (duration < minute * 2) {
return "about 1 minute ago";
}
if (duration < hour) {
int n = (int) Math.floor(duration / minute);
return n + " minutes ago";
}
if (duration < hour * 2) {
return "about 1 hour ago";
}
if (duration < day) {
int n = (int) Math.floor(duration / hour);
return n + " hours ago";
}
if (duration > day && duration < day * 2) {
return "yesterday";
}
if (duration < day * 365) {
int n = (int) Math.floor(duration / day);
return n + " days ago";
} else {
return "over a year ago";
}
}
}
Is my problem wit the oauth method? or maybe wit the getusertimeline? If anyone has some example code or tutorial for oauth2 with twitter4j , It would be appreciated
Upvotes: 10
Views: 6565
Reputation: 14438
I had a lot of problems with this so thought I'd elaborate as people are requesting in the comments above.
There are several methods in which to load the appropriate settings for Twitter4j
to run as application only. As per documentation here (http://twitter4j.org/en/configuration.html) I went with a property file.
Here are the steps:
1) create a property file in your project root with file name of exactly twitter4j.properties
. If it were me, I'd put this inside a /resources
director but whatever.
2) inside the twitter4j.properties
file put something like this:
debug=true
enableApplicationOnlyAuth=true
http.useSSL=true
oauth.consumerKey=[consumer key here]
oauth.consumerSecret=[consumer secret here]
Note: SSL and enableApplicationOnlyAuth
are very important! If you haven't gotten consumer key / secret yet then you can follow a guide elsewhere but you get via registering your app here (https://apps.twitter.com/)
3) Download the twitter4j and include the jar in your project - http://twitter4j.org/en/index.html#howToUse
4) Here is a complete solution - Note this will need a search param passed in such as #Toyota
. or your could hardcode - Query query = new Query("#Toyota");
package twittertest;
import java.io.IOException;
import java.util.List;
import twitter4j.Query;
import twitter4j.QueryResult;
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.auth.OAuth2Token;
/**
*
* @author That Guy
*/
public class TwitterTest {
/**
* @param args the command line arguments
*/
public static void main(String[] args) throws IOException, TwitterException {
if (args.length < 1) {
System.out.println("java twitter4j.examples.search.SearchTweets [query]");
System.exit(-1);
}
Twitter twitter = new TwitterFactory().getInstance();
twitter.getOAuth2Token();
try {
Query query = new Query(args[0]);
QueryResult result;
do {
result = twitter.search(query);
List<Status> tweets = result.getTweets();
for (Status tweet : tweets) {
System.out.println("@" + tweet.getUser().getScreenName() + " - " + tweet.getText());
}
} while ((query = result.nextQuery()) != null);
System.exit(0);
} catch (TwitterException te) {
te.printStackTrace();
System.out.println("Failed to search tweets: " + te.getMessage());
System.exit(-1);
}
}
}
After you build it, you will see all the tweets outputting in batches to your console. I hope that can help someone out and provide a concise solution to work from
Upvotes: 3
Reputation: 49
Maybe this one will help you. Check here : http://www.socialseer.com/twitter-programming-in-java-with-twitter4j/authentication-with-twitter/application-authentication-example/
Upvotes: 0
Reputation: 385
after a long day of searching for the problem, I have found a Solution. I'm still not sure that this will work for multiple users at the same time. but when I test it I get the the last tweets from the user i specify.
I deleted the connecttwitter function, and declared the Twitter object in DoInBackground of my asynctask. To get an Oauth2 authentication you need to get a bearer token. this is made from your consumer key and secret (so this HAS to be set on your twitter object) here is the changed code (code from my connecttwitter to doinbackground of async task) with a few modifications
ConfigurationBuilder builder=new ConfigurationBuilder();
builder.setUseSSL(true);
builder.setApplicationOnlyAuthEnabled(true);
// setup
Twitter twitter = new TwitterFactory(builder.build()).getInstance();
// exercise & verify
twitter.setOAuthConsumer(TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET);
// OAuth2Token token = twitter.getOAuth2Token();
twitter.getOAuth2Token();
statuses = twitter.getUserTimeline("Twitter");
Upvotes: 12