2

我需要在 Twitter 上发布一张图片。我已经在我的应用程序中集成了 Twitter。我需要将图像作为 URL 链接而不是推文。我不想使用 TwitPic。

我使用以下代码创建了多部分实体。它给出 404 错误。

Bitmap bm = null;
                String encodedImage = "";
                try {

                    URL aURL = new URL("http://50.57.227.117/blacksheep/uploaded/Detailed_images/961314275649aladdins.jpg");
                    URLConnection conn = aURL.openConnection();
                    conn.connect();
                    InputStream is = conn.getInputStream();
                    BufferedInputStream bis = new BufferedInputStream(is, 8192);
                    bm = BitmapFactory.decodeStream(bis);
                    bis.close();
                    is.close();
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
                     imageBytes = baos.toByteArray();
                     encodedImage = Base64.encodeToString(imageBytes, Base64.DEFAULT);
                     Log.v("encodedImage >>",encodedImage); 

                } catch (MalformedURLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

                HttpClient httpClient = new DefaultHttpClient();
                HttpPost postRequest = new HttpPost(
                        "https://api.twitter.com/1.1/statuses/update_with_media.json");
               ByteArrayBody bab = new ByteArrayBody(imageBytes, "forest.jpg");

                MultipartEntity reqEntity = new MultipartEntity(
                        HttpMultipartMode.BROWSER_COMPATIBLE);
              reqEntity.addPart("media", bab);
                reqEntity.addPart("status", new StringBody("test image"));
                postRequest.setEntity(reqEntity);
                HttpResponse response = httpClient.execute(postRequest);
                BufferedReader reader = new BufferedReader(new InputStreamReader(
                        response.getEntity().getContent(), "UTF-8"));
                String sResponse;
                StringBuilder s = new StringBuilder();

                while ((sResponse = reader.readLine()) != null) {
                    s = s.append(sResponse);
                }
                System.out.println("Response: " + s);
            // Update status
            //twitter4j.Status response = twitter.updateStatus(encodedImage);
        //  twitter4j.Status response1 = twitter.updateStatus(status);

            //Log.d("Status", "> " + response1.getText());
        } catch (TwitterException e) {
            // Error in updating status
            Log.d("Twitter Update Error", e.getMessage());
        }
4

2 回答 2

5

第一次尝试:

因此,您似乎在使用 Apache 的旧 http 客户端向您用来帮助与 twitter 集成的库 twitter4j 发出请求。我假设您使用的是 3.03 之前的最新版本,并且不希望您升级。你看,update_with_media 很新,所以我认为你的版本没有实现它。

您所做的问题是 twitter 使用oauth进行身份验证。因此,您需要使用您获得的访问令牌“签署”请求。Twitter4j,AFAIK,为你做这件事。在不破坏身份验证的情况下,您不能使用单独的客户端在不参考您的好帮助程序库的情况下进行一些调用

端点../update_with_media被定义为更新当前身份验证用户的状态。我怀疑,由于您的请求中没有访问令牌且没有用户,因此该端点甚至没有意义,因此 Twitter 将其解释为404(未找到)而不是401(未经授权)- 有趣。

所以第一次尝试是不要求你升级到 twitter4j。有时升级很痛苦!相反,您可以使用此博客中详细介绍的库来破解。但这并不容易,因为图书馆是不同的。

因此,如果您真的想向 twitter4j 发出单独的请求,我们可以尝试的其他方法是实际进行签名,也许使用scribe使其更容易......大致:

        final OAuthService myTwitterService = TwitterClient.getTwitterClient().getService();
        final OAuthRequest aNiceOAuthRequest = new org.scribe.model.OAuthRequest(
                YOURPOST, THATURL);

等等

第二次尝试:

但是让我们不要做所有这些 - 事实证明你有最新版本的 twitter4j 反正。很抱歉先走下死胡同——我不应该假设,但我已经将上述内容包括在内,以供其他任何人需要时提供帮助。

事实证明,最新版本已在此处实现了此端点文档。除了它需要一个StatusUpdate对象。所以你想做这样的事情:

final StatusUpdate statusUpdate = new StatusUpdate("Hallee hallo my status java.lang.String here...");
       // now do as you did until:
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
                bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
                 imageBytes = baos.toByteArray();
                 encodedImage = Base64.encodeToString(imageBytes, Base64.DEFAULT);
       // then flip the stream
       byte[] myTwitterUploadBytes = bos.toByteArray();
       ByteArrayInputStream bis = new ByteArrayInputStream(myTwitterUploadBytes);
       // doo and double check your encoding etc, similar to in your question..
       statusUpdate.setMedia("give me a java.lang.String name", bis);
       // then continue just using twitter for j- update status as you would
       //... get twitter etc...
       //
       twitter4j.Status response = twitter.updateStatus(statusUpdate);

目前还没有一个盒子在我身上进行测试-应该是正确的。如果它仍然给出 404s,响应中的错误代码是什么?你认证了吗?

如果这不起作用,我们也可以尝试上述一些作为备份。

希望这可以帮助,

最好的,

汤姆。

于 2013-05-24T14:56:48.493 回答
2

使用 4.0.3(可能更早),使用 twitter4j 在推文中嵌入图像非常简单:

Twitter                         twtobj;
StatusUpdate                    stsupd;
Status                          stsres;

twtobj=twitterFactory.getInstance();
twtobj.setOAuthConsumer(csmkey,csmsec);
twtobj.setOAuthAccessToken(new AccessToken(acstkn,acssec));

stsupd=new StatusUpdate(msgtxt);
if(medurls.length>0) {
    long[]                      medidns=new long[medurls.length];

    for(int xa=0; xa<medurls.length; xa++) {
        String                  medurl=Util.resolveRelativeUrl(medurls[xa]);
        InputStream             imgstm=null;

        try {
            imgstm=new URL(medurl).openConnection().getInputStream();
            medidns[xa]=twtobj.uploadMedia(medurl,imgstm).getMediaId();                     // this actually uploads the image to Twitter at this point
            }
        catch(MalformedURLException thr) { throw new ShfFail(Fail.IMAGE_URL ,"The media URL is not valid: " +medurl+" ("+thr.getMessage()+")"); }
        catch(IOException           thr) { throw new ShfFail(Fail.IMAGE_READ,"The media could not be read: "+medurl+" ("+thr.getMessage()+")"); }
        finally                          { GenUtil.close(imgstm); }
        }
    stsupd.setMediaIds(medidns);
    }
stsres=twtobj.updateStatus(stsupd);

请注意,截至 2015 年 6 月 10 日,最多允许 4 个图像、1 个动画 GIF 或 1 个视频。

另请注意,我正在捕获图像流以在外部块中显式关闭它们(未显示)。这可能是不必要的,但我找不到肯定的确认。

如果有人关心,resolveRelativeUrls允许将相对路径解析为当前文件夹中的文件 URL 是否方便:

static public String resolveRelativeUrl(String url) {
    if(!TextUtil.stringCT(url,"://")) {
        url=new File(url).getAbsoluteFile().toURI().toString();
        }
    return url;
    }

该实用程序方法stringCT不区分大小写。

于 2015-06-11T03:13:50.370 回答