【问题标题】:How to post an image to Twitter using statuses/update_with_media in android如何在 android 中使用 statuses/update_with_media 将图像发布到 Twitter
【发布时间】:2015-06-12 03:32:38
【问题描述】:

我需要在 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());
        }

【问题讨论】:

  • 您是如何将 Twitter 集成到您的应用程序中的?你在使用任何 twitter 特定的库吗?最好的。
  • 是的,我已经在我的应用程序中集成了 Twitter。
  • 抱歉,如果我不清楚,如何您将 twitter 集成到您的应用程序中?无论如何,看起来你已经发布了更多,而且你正在使用 Twitter4j
  • 感谢分享此代码。因此,您正在使用已弃用的 apache http 客户端在 twitter 上发布此帖子,并且您的问题状态打印为 System.out.println("Response: " + s);。但我在这里看不到您如何为使用它的用户发送身份验证?为什么不能在 twitter4j 中执行此操作,因为它必须处理所有的 oauth?您可能必须先解决此问题,然后它才会起作用。
  • 这里有一个教程:sholtz9421.wordpress.com/2011/10/29/…。如果你不使用 twitter4j,实际上 twitter 的 api 非常直观,很容易编写自己的客户端并让 scribe 之类的东西来处理 oauth!最美好的祝愿!

标签: android twitter


【解决方案1】:

第一次尝试:

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

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

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

所以第一次尝试是不要求您升级到 twitter4j。有时升级很痛苦!相反,您可以使用 this blog 中详细说明的库来破解。但这并不容易,因为库不同。

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

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

等等。

第二次尝试:

但是让我们不要做这一切——结果你还是有最新版本的 twitter4j。对不起,我先走了 cul-de-sac - 我不应该假设,但我已将上述内容包含在内,以供其他需要帮助的人使用。

事实证明,最新版本已经实现了这个端点——文档here。除了它需要一个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,响应中的错误代码是什么?您通过身份验证了吗?

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

希望对你有帮助,

最好的,

汤姆。

【讨论】:

  • 显然你得到了一个 403- 如果你想链接的文件的名称加上你的状态超过了每条推文的字符数限制,也会发生这种情况:见 dev.twitter.com/docs/api/1.1/post/statuses/update_with_media跨度>
  • 我已经尝试了第二次。它作为一个小网址发布推文。我想这样发布图片,而不是 url。
  • 太棒了——点击推文时它不会出现吗?
  • 是的,看来,我不想那样。我想直接发布图片。
  • 你能在推特上给我一个例子来说明你的意思吗? AFAIK,您不能将图像嵌入推文中...您有一个链接,并且当您单击推文时“展开”。总是有 ASCII 艺术......无论哪种方式,你在做什么听起来很酷,我真的祝你好运!
【解决方案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 不区分大小写。

【讨论】:

  • 这是目前的方法。如果您是最新的,请执行此操作!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-02-28
  • 2013-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-10
  • 2012-06-28
相关资源
最近更新 更多