Twitter4j实现Java Android的Twitter应用程序仅身份验证

10
我正在尝试使用oauth2(用于应用程序认证)从Twitter获取用户时间轴,但结果始终为null。我没有OAuth方面的经验,并且已经查看了几个教程和示例,但到目前为止还没有成功。我需要检索特定用户(在此示例中为Twitter)的时间轴,而无需用户登录。 我有一个应用程序使用了Twitter API 1,我试图将现有代码调整为新的API 1.1,使用oauth2进行应用程序认证。所以该代码应该能够正常工作,除非它没有从Twitter那里得到任何反馈。如果我确实收到了结果,那么它应该可以再次工作。
与Twitter的连接在asyncop下的twitterconnect函数中进行。
以下是我的代码:
    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";
    }
}

我的问题是关于oauth方法吗?还是关于getusertimeline方法? 如果有人有使用twitter4j进行oauth2的示例代码或教程,将不胜感激。

3个回答

12

在经过漫长的问题搜索后,我找到了一个解决方案。但我仍不确定这是否适用于多个用户同时使用。但是当我测试时,我可以获取指定用户的最新推文。

我删除了connecttwitter函数,并在我的asynctask的DoInBackground中声明了Twitter对象。要获得Oauth2认证,您需要获取一个bearer token。这是由您的consumer key和secret生成的(因此必须在您的Twitter对象上进行设置),以下是修改后的代码(从connecttwitter到async task的doinbackground),有一些修改。

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");

你好,能否给我你所写的“获取Twitter动态消息”的完整可运行代码?我遇到了问题。 - Kaidul
The method setApplicationOnlyAuthEnabled(boolean) is undefined for the type ConfigurationBuilder - jul
1
@jul 从这里下载并添加最新的Twitter4J库快照[http://twitter4j.org/en/index.html#snapshot]。 - Thamilan S
1
您可以使用ConfigurationBuilder方法设置消费者密钥和密钥,而不是使用Twitter.setOAuthConsumer,但从文档中并不完全清楚,在获取Twitter实例之后并在执行任何其他操作之前,您需要调用getOAuth2Token()方法。 - Jules

3
我遇到了许多问题,所以想详细说明一下,因为在上面的评论中有人要求。有几种方法可以加载适当的设置,使Twitter4j以应用程序方式运行。根据这里的文档(http://twitter4j.org/en/configuration.html),我选择了属性文件。
以下是步骤: 1) 在项目根目录下创建一个名为twitter4j.properties的属性文件。如果是我,我会把它放在/resources目录下,但无论如何都可以。 2)twitter4j.properties文件中放置类似于以下内容:
debug=true
enableApplicationOnlyAuth=true
http.useSSL=true
oauth.consumerKey=[consumer key here]
oauth.consumerSecret=[consumer secret here]

注意:SSL和enableApplicationOnlyAuth非常重要!如果您还没有获得消费者密钥/密钥,则可以在其他地方遵循指南,但您可以通过在此处注册应用程序来获取(https://apps.twitter.com/)。
3)下载twitter4j并将jar包包含在您的项目中- http://twitter4j.org/en/index.html#howToUse 4)这是一个完整的解决方案-请注意,这将需要传递搜索参数,例如#Toyota,或者您可以硬编码- 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);
        }
    }

}

构建完成后,您将看到所有推文分批输出到控制台。我希望这能帮助某些人,并提供一个简洁的解决方案。

0

请详细阐述一下。我们不鼓励“仅链接”答案,因为它们可能会消失并且随时无法访问。您可以从文章中引用相关内容开始。 - Andrew T.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接