我需要将图片发布到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());
}
答案 0 :(得分:5)
首次尝试:
因此,您似乎正在使用Apache的旧http客户端在您用来帮助集成twitter,twitter4j的库外部发出请求。我假设您使用的是3.03之前的最新版本,并且不希望您升级。你看,update_with_media是新的,所以我认为你的版本没有实现它。
您正在做的问题是Twitter使用 oauth 进行身份验证。因此,您需要使用您获得的访问令牌“签署”请求。 Twitter4j,AFAIK,为您做到这一点。 在不破坏身份验证的情况下,您无法使用单独的客户端进行一些调用而无需引用您的好帮助程序库。
端点../update_with_media
定义为更新当前身份验证用户的状态。我怀疑,由于您的请求中没有访问令牌且没有用户,因此该端点甚至没有意义,因此Twitter将其解释为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);
目前还没有一个盒子让我测试 - 应该是正确的。如果仍然给出404,那么响应中的错误代码是什么?你认证了吗?
如果这不起作用,我们也可以尝试上面的一些作为备份。
希望这有帮助,
最好的,
汤姆。
答案 1 :(得分: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-06-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
不区分大小写。