在Android中从Twitter提取图像

问题描述

我写了TwitteraPI来访问Twitter的api。

public class TwitteraPI {

    private String twitterapiKey;
    private String twitteraPISecret;
    final static String TWITTER_TOKEN_URL = "https://api.twitter.com/oauth2/token";
    final static String TWITTER_STREAM_URL = "https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=";

    public TwitteraPI(String twitteraPIKey,String twitterapiSecret) {
        this.twitterapiKey = twitteraPIKey;
        this.twitteraPISecret = twitterapiSecret;
    }

    public ArrayList<TwitterTweet> getTwitterTweets(String screenName) {
        ArrayList<TwitterTweet> twitterTweetArrayList = null;
        try {
            String twitterUrlApiKey = URLEncoder.encode(twitterapiKey,"UTF-8");
            String twitterUrlApiSecret = URLEncoder.encode(twitteraPISecret,"UTF-8");
            String twitterKeySecret = twitterUrlApiKey + ":" + twitterUrlApiSecret;
            String twitterKeyBase64 = Base64.encodetoString(twitterKeySecret.getBytes(),Base64.NO_WRAP);
            TwitterauthToken twitterauthToken = getTwitterauthToken(twitterKeyBase64);
            twitterTweetArrayList = getTwitterTweets(screenName,twitterauthToken);
        } catch (UnsupportedEncodingException | IllegalStateException ex) {
            ex.printstacktrace();
        }
        return twitterTweetArrayList;
    }

    public ArrayList<TwitterTweet> getTwitterTweets(String screenName,TwitterauthToken twitterauthToken) {
        ArrayList<TwitterTweet> twitterTweetArrayList = null;
        if (twitterauthToken != null && twitterauthToken.token_type.equals("bearer")) {
            HttpGet httpGet = new HttpGet(TWITTER_STREAM_URL + screenName);
            httpGet.setHeader("Authorization","Bearer "
                    +twitterauthToken.access_token);
            httpGet.setHeader("Content-Type","application/json");
            HttpUtil httpUtil = new HttpUtil();
            String twitterTweets = httpUtil.getHttpResponse(httpGet);
            twitterTweetArrayList = convertJsonToTwitterTweet(twitterTweets);
        }
        return twitterTweetArrayList;
    }

    public TwitterauthToken getTwitterauthToken(String twitterKeyBase64)
            throws UnsupportedEncodingException {
        HttpPost httpPost = new HttpPost(TWITTER_TOKEN_URL);
        httpPost.setHeader("Authorization","Basic " + twitterKeyBase64);
        httpPost.setHeader("Content-Type","application/x-www-form-urlencoded;charset=UTF-8");
        httpPost.setEntity(new StringEntity("grant_type=client_credentials"));
        HttpUtil httpUtil = new HttpUtil();
        String twitterjsonResponse = httpUtil.getHttpResponse(httpPost);
        return convertJsonToTwitterauthToken(twitterjsonResponse);
    }

    private TwitterauthToken convertJsonToTwitterauthToken(String jsonAuth) {
        TwitterauthToken twitterauthToken = null;
        if (jsonAuth != null && jsonAuth.length() > 0) {
            try {
                Gson gson = new Gson();
                twitterauthToken = gson.fromJson(jsonAuth,TwitterauthToken.class);
            } catch (IllegalStateException ex) {
                ex.printstacktrace();
            }
        }
        return twitterauthToken;
    }

    private ArrayList<TwitterTweet> convertJsonToTwitterTweet(String twitterTweets) {
        ArrayList<TwitterTweet> twitterTweetArrayList = null;
        if (twitterTweets != null && twitterTweets.length() > 0) {
            try {
                Gson gson = new Gson();
                twitterTweetArrayList = gson.fromJson(twitterTweets,new Typetoken<ArrayList<TwitterTweet>>() {
                }.getType());
            } catch (IllegalStateException e) {
                e.printstacktrace();
            }
        }
        return twitterTweetArrayList;
    }

    private static class TwitterauthToken {
        String token_type;
        String access_token;
    }

}  

然后我在async中按如下方式使用

public class TwitterasyncTask extends AsyncTask<Object,Void,ArrayList<TwitterTweet>> {

    ListActivity callerActivity;

    @Override
    protected ArrayList<TwitterTweet> doInBackground(Object... params) {
        ArrayList<TwitterTweet> twitterTweets = null;
        callerActivity = (ListActivity) params[1];
        if (params.length > 0) {
            TwitteraPI twitteraPI = new TwitteraPI(TWITTER_API_KEY,TWITTER_API_SECRET);
            twitterTweets = twitteraPI.getTwitterTweets(params[0].toString());
        }
        return twitterTweets;
    }

    @Override
    protected void onPreExecute() {
    }

    @Override
    protected void onPostExecute(ArrayList<TwitterTweet> twitterTweets) {
        ArrayAdapter<TwitterTweet> adapter = new ArrayAdapter<>(callerActivity,R.layout.activity_twitter_view,R.id.listTextView,twitterTweets);
        callerActivity.setlistadapter(adapter);
        ListView lv = callerActivity.getListView();
        lv.setDividerHeight(0);
        //lv.setDivider(this.getResources().getDrawable(android.R.color.transparent));
        lv.setBackgroundColor(callerActivity.getResources().getColor(R.color.color_white));
    }
}  

这将拉出数据,如图所示

twitter


但这不会拉出与被拉的推文相关的图像。如何修改Twitter API以获取图像?

解决方法

您可以向statuses user timeline API service添加参数,以免截断推文。这将检索完整的推文,不仅是文本,还包括图像。

参数为tweet_mode=extended

因此,我建议您将TWITTER_STREAM_URL常量修改为以下内容:

final static String TWITTER_STREAM_URL = "https://api.twitter.com/1.1/statuses/user_timeline.json?tweet_mode=extended&screen_name=";

现在,您将看到响应中将包含一系列推文。对于每条推文,您都会找到一个entities字段,其中包含一个media字段。这包含一系列媒体项目。每个媒体项目都有一个type,如果它的值为photo,则可以使用以下两个字段之一获取图像:media_urlmedia_url_https。>

举个例子,通过对my user timeline执行GET请求(您需要使用Bearer令牌),您将找到以下推文:

{
    "id": 1264252718828437505,"id_str": "1264252718828437505","full_text": "Just noticed that AS won't warn about the specific hardcoded string \"Hello World!\" in activity_main.xml (or any other xml).\nI guess they had to hardcode an if statement to not warn about it. ? ","truncated": false,"entities": {
        "media": [
            {
                "id": 1264251325023498240,"id_str": "1264251325023498240","media_url": "http://pbs.twimg.com/media/EYuF4b7XsAAOGGi.jpg","media_url_https": "https://pbs.twimg.com/media/EYuF4b7XsAAOGGi.jpg","type": "photo",...

您没有发布TwitterTweet类,但您还需要对其进行修改以包含这些字段,如下所示:

public class TwitterTweet {
    ...
    Entities entities;
}

public class Entities {
    List<Media> media;
}

public class Media {
    String mediaUrl;
    String type;
}

您可以在Tweet,实体和媒体对象here中找到更多信息。