在 android 中从 Twitter 中提取图像

Posted

技术标签:

【中文标题】在 android 中从 Twitter 中提取图像【英文标题】:Pulling image from twitter in android 【发布时间】:2020-12-21 05:33:38 【问题描述】:

我写了一个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 API 来获取图片?

【问题讨论】:

【参考方案1】:

您可以向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=";

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

举个例子,通过对my user timeline 执行GET 请求(您需要使用您的Bearer Token),您会发现以下推文:


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


您可以找到有关推文、实体和媒体对象的更多信息,here。

【讨论】:

以上是关于在 android 中从 Twitter 中提取图像的主要内容,如果未能解决你的问题,请参考以下文章

如何在android中为jsoup设置用户代理和连接超时

twitter4s:如何在播放框架中从 Action.async 返回未来

在 iOS 中从 Twitter 获取用户个人资料详细信息(尤其是电子邮件地址)

我想在目标 c 中从 Twitter 注销 [重复]

在 Android 中从内存中加载声音

如何在 C# Rest 服务中从 Android 应用程序读取 JSON 数据