I am trying to upload media to twitter in android. I am using this Update with Media Api. I am using the following code
multiPartEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
try
{
multiPartEntity.addPart("status", new StringBody("Metallica rules man! |m|"));
multiPartEntity.addPart("media[]", new InputStreamBody(getResources().openRawResource(R.drawable.metallica), "metallica.jpg"));
post = new HttpPost("https://api.twitter.com/1.1/statuses/update_with_media.json");
post.setEntity(multiPartEntity);
post.addHeader("Content-Type", "multipart/form-data");
post.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, false);
consumer.sign(post);
response = client.execute(post);
entity = response.getEntity();
} catch (Exception e1)
{
e1.printStackTrace();
}
But I get the error code 131 - Internal error from Twitter. I also tried sending the image in the form of a byte array but in vain. I got the same error. Could anyone please help me in resolving this issue?
Related
I am developing an android app where user logs on to his/her account. After logging in I will receive XSRF token and Laravel Session Id to recognise the specific user. I have to send these tokens for every request I send to the API's to get the appropriate information. But when I am sending the required details as shown in the image, I am getting HTMl file as response instead of getting JSON Object. I was seriously stuck at this problem. Correct Solution may take forward the whole app.
class RegisterConnection extends AsyncTask<String,String,JSONObject> {
protected JSONObject doInBackground(String... arg0) {
JSONObject output = new JSONObject();
DefaultHttpClient client = new DefaultHttpClient();
HttpConnectionParams.setConnectionTimeout(client.getParams(), 5000); //Timeout Limit
HttpResponse response = null;
try {
HttpGet get = new HttpGet(statsURL);
get.setHeader("Accept", "application/json");
CookieStore store = new BasicCookieStore();
BasicClientCookie cookie1 = new BasicClientCookie("XSRF-TOKEN", XSRF);
BasicClientCookie cookie2 = new BasicClientCookie("laravel_session", laravel);
store.addCookie(cookie1);
store.addCookie(cookie2);
client.setCookieStore(store);
response = client.execute(get);
if(response!=null){
InputStream in = response.getEntity().getContent();
String resultstring = Utilities.convertStreamToString(in);
Log.i("Result1", resultstring);
output = new JSONObject(resultstring);
Log.i("Result2", output.toString());
}
} catch(Exception e) {
e.printStackTrace();
try {
output.put("sai","error");
Log.i("MainActivity", output.toString());
} catch (JSONException e1) {
e1.printStackTrace();
}
return output;
}
return output;
}
These are the server requirements
http://imgur.com/OY9Q673
This is the Output received
http://imgur.com/IB5AEcT
As far as I can tell, there is nothing wrong with your Android client code.
You are getting HTML from the server so the main reason could be that your Laravel server is rendering the views and sending you back html instead of JSON. Instead of rendering the views on the server, you should send JSON response on your Laravel server side.
Add Jsoup dependency in your gradle file
implementation 'org.jsoup:jsoup:1.11.2'
Document document = Jsoup.parse("http://imgur.com/IB5AEcT");
Elements el = doc.select("button");
Log.i("..........",""+el.attr("data-invite-details"));
Jsoup tutorial
http://jsoup.org/apidocs/org/jsoup/Jsoup.html
I have to work on an application where i need to send the class object as Parameter using Multipart Entity along with a file. I have checked that the Multipart addpart method doesn't accept an Object to post to Web Api.Below is the Code i have tried. Any Suggestions on how to pass the object would be great.
HttpPost post = BaseActivity.getHttpPost("MyURL");
MultipartEntity entity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE,"",Charset.defaultCharset());
try {
ServiceJobFileModel sjfm = new ServiceJobFileModel();
sjfm.setFileExtension(myfileextension);
sjfm.setCapturedDate(captdate);
sjfm.setFileName("/pathtofile/filename.extension");
File f = new File(sjmf.getFileName());
entity.addPart("file", new FileBody(f));
entity.addPart("serviceJobFileModel", sjfm); // Compiler Error
post.addHeader("Accept-Encoding", "gzip, deflate");
post.setEntity(entity);
} catch (UnsupportedEncodingException e) {
Log.v("encoding exception","E::: "+e);
e.printStackTrace();
}
The Web Api is developed in Dotnet which is why the windows mobile app has sent the parameters as
var parameters = new ServiceJobFileModel()
{
FileExtension = serviceJobFileModel.FileExtension,
CapturedDate = serviceJobFileModel.CapturedDate,
ServiceJobNumber = serviceJobFileModel.ServiceJobNumber
};
content.Add(new StreamContent(filestream), "file", Path.GetFileName(fileName));
content.Add(new ObjectContent<ServiceJobFileModel>(parameters, new JsonMediaTypeFormatter()), "serviceJobFileModel");
IMHO you should serialize your object in a text format like JSON or XML and then use a StringBody to send it.
I'm currently using Scribe to both authenticate and post non-media messages to Twitter successfully. This was very easy, my first test message posted with no issues. However, I can't seem to post photos at all. I have reviewed Twitter's instructions for posting with media, both here and here.
All of the Scribe/Twitter examples at Github are for non-media posts. It would be great if someone could provide a solid example of how to post photos to Twitter via Scribe!
I'm have two issues in particular:
1) My posts will not pass authorization. I've tried mimicking the examples I posted above, but nothing seems to work.
2) When converting the image from byte[] to a string, I only seem to get 4113 characters before it stops. From my understanding, this is well under the number of characters a String can hold.
Here is how I'm extracting the photo:
// GET PHOTO FILE AND FILE LENGTH
// INSTANTIATE UPLOAD VARIABLE WITH FILE LENGTH
File file = new File(photo); // ("photo" is a string path to the photo file)
int fileLength = (int) file.length();
uploadFile = new byte[fileLength];
// CREATE BUFFER INPUT STREAM OF FILE
BufferedInputStream inputStream;
try {inputStream = new BufferedInputStream(new FileInputStream(file));}
catch (FileNotFoundException e)
{
inputStream = null;
Toast.makeText(this.getApplicationContext(), "Buffer input stream error!", Toast.LENGTH_LONG).show();
}
// READ DATA FROM FILE INTO UPLOAD VARIABLE
// CLOSE INPUT STREAM
try {inputStream.read(uploadFile);}
catch (IOException e) {Toast.makeText(this.getApplicationContext(), "Read input stream to upload variable error!", Toast.LENGTH_LONG).show();}
try {inputStream.close();}
catch (IOException e) {Toast.makeText(this.getApplicationContext(), "Close input stream error!", Toast.LENGTH_LONG).show();}
After a LOT of research and piece milling code from various places I finally figured out what I was doing wrong. Here is an example of how to post photos to Twitter via Scribe OAuth:
NOTE: This assumes a few things...
1) You have already saved the photo and have the file path
2) You have already authenticated the user at some point and have a valid access Token
3) You MUST add apache-mime4j-0.6.jar & httpmime-4.0.1.jar to you libs folder and include them in your build path!!!
I really hope this helps someone! It's very easy to implement, but took a few days of troubleshooting to get it working correctly!
// BUILD OAUTH SERVICE
OAuthService oAuth = new ServiceBuilder()
.provider(TwitterApi.class)
.apiKey(YOUR_TWITTER_API_KEY) // REPLACE WITH YOUR OWN!!!
.apiSecret(YOUR_TWITTER_API_SECRET) // REPLACE WITH YOUR OWN!!!
.callback(YOUR_CALLBACK) // REPLACE WITH YOUR OWN!!!
.build();
// BUILD OAUTH REQUEST & SIGN IT RIGHT AWAY (OTHERWISE MULTIPART FORM MAY PREVENT SIGNING)
OAuthRequest request = new OAuthRequest(Verb.POST, "https://upload.twitter.com/1.1/statuses/update_with_media.json");
oAuth.signRequest(USER_ACCESS_TOKEN, request); // ENTER USER'S ACCESS TOKEN
// ADD MULTIPART FORM
try
{
MultipartEntity entity = new MultipartEntity();
entity.addPart("status", new StringBody(message)); // THIS IS THE TWITTER MESSAGE
entity.addPart("media", new FileBody(new File(photo))); // THIS IS THE PHOTO TO UPLOAD
ByteArrayOutputStream out = new ByteArrayOutputStream();
entity.writeTo(out);
request.addPayload(out.toByteArray());
request.addHeader(entity.getContentType().getName(), entity.getContentType().getValue());
}
catch (UnsupportedEncodingException e) {e.printStackTrace();}
catch (IOException e) {e.printStackTrace();}
// SEND REQUEST
try {response = new JSONObject (request.send().getBody());}
catch (JSONException e) {Log.e("YOUR_APP_TAG", "JSONException Thrown: " + e.getMessage());}
I'm trying to simulate a process like "cache validation" in my application.
I will download a new version of my webapplication on the device (android-based), but I only want to download a new version of the files, based in a etag comparision.
Does anyone a example of how use the Etag mechanism in Android?
You can access the ETag field from a HttpURLConnection object such as like this:
HttpURLConnection conn = (HttpURLConnection)new URL(url).openConnection();
String etag = conn.getHeaderField("ETag");
Of course, you will need to make sure that the server you are testing this against supports ETags.
Maybe class "HttpRequest" from this library (kevinsawicki) will help you.
For example:
File latest = new File("/data/cache.json");
HttpRequest request = HttpRequest.get("http://google.com");
//Copy response to file
request.body(latest);
//Store eTag of response
String eTag = request.eTag();
//Later you can check if changes exist
boolean unchanged = HttpRequest.get("http://google.com")
.ifNoneMatch(eTag)
.notModified();
HttpClient httpClient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(url);
try {
HttpResponse response = httpClient.execute(httpPost);
Log.d("Http Response:", response.getFirstHeader("etag").toString());
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
You can refer to the specific implement of ShallowEtagHeaderFilter performing etag generation and validation in Spring.
As part of my Android app, I'd like to upload bitmaps to be remotely stored. I have simple HTTP GET and POST communication working perfectly, but documentation on how to do a multipart POST seems to be as rare as unicorns.
Furthermore, I'd like to transmit the image directly from memory, instead of working with a file. In the example code below, I'm getting a byte array from a file to be used later on with HttpClient and MultipartEntity.
File input = new File("climb.jpg");
byte[] data = new byte[(int)input.length()];
FileInputStream fis = new FileInputStream(input);
fis.read(data);
ByteArrayPartSource baps = new ByteArrayPartSource(input.getName(), data);
This all seems fairly clear to me, except that I can't for the life of me find out where to get this ByteArrayPartSource. I have linked to the httpclient and httpmime JAR files, but no dice. I hear that the package structure changed drastically between HttpClient 3.x and 4.x.
Is anyone using this ByteArrayPartSource in Android, and how did they import it?
After digging around in the documentation and scouring the Internet, I came up with something that fit my needs. To make a multipart request such as a form POST, the following code did the trick for me:
File input = new File("climb.jpg");
DefaultHttpClient client = new DefaultHttpClient();
HttpPost post = new HttpPost("http://localhost:3000/routes");
MultipartEntity multi = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
String line;
multi.addPart("name", new StringBody("test"));
multi.addPart("grade", new StringBody("test"));
multi.addPart("quality", new StringBody("test"));
multi.addPart("latitude", new StringBody("40.74"));
multi.addPart("longitude", new StringBody("40.74"));
multi.addPart("photo", new FileBody(input));
post.setEntity(multi);
HttpResponse resp = client.execute(post);
The HTTPMultipartMode.BROWSER_COMPATIBLE bit is very important. Thanks to Radomir's blog on this one.
try this:
HttpClient httpClient = new DefaultHttpClient() ;
HttpPost httpPost = new HttpPost("http://example.com");
MultipartEntity entity = new MultipartEntity();
entity.addPart("file", new FileBody(file));
httpPost.setEntity(entity );
HttpResponse response = null;
try {
response = httpClient.execute(httpPost);
} catch (ClientProtocolException e) {
Log.e("ClientProtocolException : "+e, e.getMessage());
} catch (IOException e) {
Log.e("IOException : "+e, e.getMessage());
}
Perhaps you can do following step to import library into your Android.
requirement library
- apache-mime4j-0.6.jar
- httpmime-4.0.1.jar
Right click your project and click properties
select java build path
select tab called "Order and Export"
Apply it
Fully uninstall you apk file with the adb uninstall due to existing apk not cater for new library
install again your apk
run it
Thanks,
Jenz
I'm having the same problem. I'm trying to upload an image through MultiPart Entity and it seens that the several updates on HttpClient/MIME are cracking everything. I'm trying the following code, falling with an Error "NoClassDefFoundError":
public static void executeMultipartPost(File image, ArrayList<Cookie> cookies, String myUrlToPost) {
try {
// my post instance
HttpPost httppost = new HttpPost(myUrlToPost);
// setting cookies for the connection session
if (cookies != null && cookies.size() > 0) {
String cookieString = "";
for (int i=0; i<cookies.size(); ++i) {
cookieString += cookies.get(i).getName()+"="+cookies.get(i).getValue()+";";
}
cookieString += "domain=" + BaseUrl + "; " + "path=/";
httppost.addHeader("Cookie", cookieString);
}
// creating the http client
HttpClient httpclient = new DefaultHttpClient();
// creating the multientity part [ERROR OCCURS IN THIS BELLOW LINE]
MultipartEntity multipartEntity = new MultipartEntity();
multipartEntity.addPart("photoupload", new FileBody(image));
httppost.setEntity(multipartEntity);
HttpResponse response = httpclient.execute(httppost);
HttpEntity resEntity = response.getEntity();
} catch (Exception e) {}
}
This method is fully compilable and uses the httpclient-4.0.1.jar and httpmime-4.2.jar libs, but again, I remember that it crashs in the commented line for me.