Android - Post status update with media Twitter & Tumblr - android

I am trying to allow Android users to post images to Twitter/Tumblr using my app. I am able to authenticate and retrieve user and account info, but I am having trouble with the actual image upload. (Basically I'm ok with all of the HTTP GET api calls, but not the HTTP POST).
I am receiving the following errors (Twitter/Tumblr respectively):
"response":{"errors":[{"message":"Error creating status","code":189}]}
"response":{"errors":["Error uploading photo."]},"meta":{"msg":"Bad Request","status":400}
Does anyone know what this means? I don't believe it's an authentication error, because I am able to get user info, etc... It looks to me like the problem is with the parameters, presumably media.
I have tried a number of options, including using the image file/data/url, using HttpParams/MultipartEntity, and using "media"/"media[]" but haven't had much success. Below is the current code that I am using. Is there something wrong with my format? Is there something else Twitter/Tumblr is looking for? If anyone has any ideas, suggestions, or improvements, they would be much appreciated. Thanks!
private class TwitterShareTask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
String result = "";
HttpClient httpclient = GlobalValues.getHttpClient();
HttpPost request = new HttpPost("https://api.twitter.com/1.1/statuses/update_with_media.json");
try {
MultipartEntity entity = new MultipartEntity();
entity.addPart("status", new StringBody(ETdescription.getText().toString()));
entity.addPart("media[]", new FileBody(new File(GlobalValues.getRealPathFromURI(
Camera_ShareActivity.this, imageUri))));
request.setEntity(entity);
TwitterUtils.getTwitterConsumer().sign(request);
HttpResponse response = httpclient.execute(request, GlobalValues.getLocalContext());
HttpEntity httpentity = response.getEntity();
InputStream instream = httpentity.getContent();
result = GlobalValues.convertStreamToString(instream);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (OAuthMessageSignerException e) {
e.printStackTrace();
} catch (OAuthExpectationFailedException e) {
e.printStackTrace();
} catch (OAuthCommunicationException e) {
e.printStackTrace();
}
return result;
}
public void onPostExecute(String result) {
try {
JSONObject jObject = new JSONObject(result.trim());
System.out.println(jObject);
} catch (JSONException e) {
e.printStackTrace();
}
}
}
~~~ Edit: As requested by YuDroid ~~~
private static class TwitterUploadTask extends AsyncTask<String, Void, String> {
private File image;
private String message;
private OAuthConsumer twitterConsumer;
public TwitterUploadTask(OAuthConsumer consumer, File file, String string) {
this.image = file;
this.message = string;
this.twitterConsumer = consumer;
}
#Override
protected String doInBackground(String... params) {
String result = "";
HttpClient httpclient = GlobalValues.getHttpClient();
HttpPost request = new HttpPost("https://api.twitter.com/1.1/statuses/update_with_media.json");
ByteArrayInputStream bais = null;
try {
FileInputStream fis = new FileInputStream(image);
BufferedInputStream bis = new BufferedInputStream(fis, 8192);
Bitmap bm = BitmapFactory.decodeStream(bis);
bis.close();
fis.close();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.PNG, 100, baos);
byte[] myTwitterByteArray = baos.toByteArray();
bais = new ByteArrayInputStream(myTwitterByteArray);
} catch (IOException e) {
e.printStackTrace();
}
try {
MultipartEntity entity = new MultipartEntity();
entity.addPart("status", new StringBody(message));
entity.addPart("media[]", new InputStreamBody(bais, image.getName()));
request.setEntity(entity);
twitterConsumer.sign(request);
HttpResponse response = httpclient.execute(request, GlobalValues.getLocalContext());
HttpEntity httpentity = response.getEntity();
InputStream instream = httpentity.getContent();
result = GlobalValues.convertStreamToString(instream);
Log.i("statuses/update_with_media", result);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (OAuthMessageSignerException e) {
e.printStackTrace();
} catch (OAuthExpectationFailedException e) {
e.printStackTrace();
} catch (OAuthCommunicationException e) {
e.printStackTrace();
}
return result;
}
public void onPostExecute(String result) {
try {
JSONObject jObject = new JSONObject(result.trim());
System.out.println(jObject);
} catch (JSONException e) {
e.printStackTrace();
}
}
}

Related

Sending Variables to a REST api to be saved on server

I am really struggling with this for some time now and I am really lost in terms of how this works.
I have written a REST service in netbeans and I have passed through Json data and tested that it works using Postman and it is successfully saving to the database.
Now, I want the variables in my mobile application to be sent to that REST api so that they can then be saved to the database.
I have looked at many answers on this but can get none which fully explain to me how to do this.. Ideally I am trying to POST or PUT data from my mobile app into my database.
Here is what I have tried so far:
submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
details = editTextDetails.getText().toString();
getCurrentDateandTime();
String url = "http://localhost:8080/engAppApi/webservices/engineerTable/";
HttpClient client = new DefaultHttpClient();
HttpPost request = new HttpPost(url);
JSONObject params = new JSONObject();
try {
params.put("machinetype", machineType);
} catch (JSONException e) {
e.printStackTrace();
}
try {
params.put("workordernumber", workOrderNumber);
} catch (JSONException e) {
e.printStackTrace();
}
try {
params.put("employeename", employee);
} catch (JSONException e) {
e.printStackTrace();
}
try {
params.put("activity", activity);
} catch (JSONException e) {
e.printStackTrace();
}
try {
params.put("durationhours", durationHours);
} catch (JSONException e) {
e.printStackTrace();
}
try {
params.put("durationmins", durationMins);
} catch (JSONException e) {
e.printStackTrace();
}
try {
params.put("downtimehours", downTimeHours);
} catch (JSONException e) {
e.printStackTrace();
}
try {
params.put("downtimemins", downTimeMins);
} catch (JSONException e) {
e.printStackTrace();
}
try {
params.put("details", details);
} catch (JSONException e) {
e.printStackTrace();
}
try {
params.put("currentdateandtime", currentDateandTime);
} catch (JSONException e) {
e.printStackTrace();
}
StringEntity jsonEntity = null;
try {
jsonEntity = new StringEntity(params.toString());
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
request = new HttpPost(url);
request.addHeader("Content-Type", "application/json");
request.setEntity(jsonEntity);
try {
HttpResponse response = client.execute(request);
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
can someone please point me in the right direction
Thanks in advance!
just use retrofit 2 for connect to server.
see this link
You have an idea in how to do the post petition, but you have a couple of problems. The first and more important problem is that if you want to retrieve information from a server, you must put your code in an async task. You can't do it in UI Thread. So, i'm gonna share with you a class that implements all the logic you need and you just have to use it. First you need to use gson, look how to use it here
https://github.com/google/gson
and the code is here. It have two methods, one for GET and other for POST.
import android.os.AsyncTask;
import android.util.Log;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
/**
* Created by Administrador on 4/27/2017.
*/
public class JsonReaderFromUrl {
public static final int SUCCESS = 0;
public static final int FAILED = 1;
public static final int PROGRESS = 2;
public interface OnJesonInterface{
void OnJsonReceive(int status, JSONObject jsonObject, int key);
}
public JsonReaderFromUrl() {
}
public void getJsonFromUrlPost(final String url, final OnJesonInterface onJesonInterface, final String body, final int key){
new AsyncTask<Void, String, String>() {
#Override
protected void onPreExecute() {
super.onPreExecute();
onJesonInterface.OnJsonReceive(PROGRESS,null,0);
}
#Override
protected String doInBackground(Void... params) {
if(android.os.Debug.isDebuggerConnected())
android.os.Debug.waitForDebugger();
try {
URL urlJson = new URL(url);
HttpURLConnection connection = (HttpURLConnection) urlJson.openConnection();
connection.setDoInput(true);
connection.setRequestProperty("Content-Type","application/json");
connection.setRequestMethod("POST");
OutputStream outputStream = connection.getOutputStream();
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
writer.write(body);
writer.flush();
writer.close();
outputStream.close();
connection.connect();
StringBuilder stringBuilder = new StringBuilder();
int httpStatus = connection.getResponseCode();
if (httpStatus == HttpURLConnection.HTTP_CREATED){
BufferedReader br = new BufferedReader(
new InputStreamReader(connection.getInputStream(),"utf-8")
);
String line = "";
while ((line = br.readLine()) != null){
stringBuilder.append(line + "\n");
}
br.close();
return stringBuilder.toString();
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if (s != null){
try {
JSONObject jsonObject = new JSONObject(s);
onJesonInterface.OnJsonReceive(SUCCESS,jsonObject,key);
} catch (JSONException e) {
e.printStackTrace();
}
}
else {
onJesonInterface.OnJsonReceive(FAILED,null,0);
}
}
}.execute();
}
public void getJsonFromUrl(final String url, final OnJesonInterface onJesonInterface){
AsyncTask<Void,String,String> asyncTask = new AsyncTask<Void, String, String>() {
#Override
protected void onPreExecute() {
super.onPreExecute();
onJesonInterface.OnJsonReceive(PROGRESS,null,0);
}
#Override
protected String doInBackground(Void... params) {
try {
URL urlJson = new URL(url);
HttpURLConnection connection = (HttpURLConnection) urlJson.openConnection();
connection.connect();
InputStream stream = connection.getInputStream();
BufferedReader reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer stringBuffer = new StringBuffer();
String line = "";
while ((line = reader.readLine()) != null){
stringBuffer.append(line + "\n");
Log.d("RESPONDE JSON: ",">" + line);
}
return stringBuffer.toString();
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if (s != null){
try {
JSONObject jsonObject = new JSONObject(s);
onJesonInterface.OnJsonReceive(SUCCESS,jsonObject,0);
} catch (JSONException e) {
e.printStackTrace();
}
}
else {
onJesonInterface.OnJsonReceive(FAILED,null,0);
}
}
}.execute();
}
}
import this class where you need and use it PD: The key value is an int that can be used to retrieve what response correspond to each petition, this in case you use this class with a lot of petitions.

failed to connect to http Android

when the connection is so low i get an exception " failed to connect to : http ......", this is my code, can any one please helps me to avoid the exception.
when the connection is so low i get an exception " failed to connect to : http ......", this is my code, can any one please helps me to avoid the exception
private void parseM3uUrlAndPrepare_new(final String url) {
AsyncTask<String, Integer, String> asyn = new AsyncTask<String, Integer, String>(){
URL the_url;
HttpURLConnection conn;
String filePath = "";
InputStream inputStream;
HttpGet getRequest;
#Override
protected void onPreExecute() {
super.onPreExecute();
try {
the_url = new URL(url);
conn = (HttpURLConnection) the_url.openConnection(Proxy.NO_PROXY);
getRequest = new HttpGet(url);
}
catch (MalformedURLException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
#Override
protected String doInBackground(String... params) {
if(conn != null) {
try {
inputStream = new BufferedInputStream(conn.getInputStream());
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = bufferedReader.readLine()) != null) {
if (line.startsWith("#")) {
}
else if (line.length() > 0) {
filePath = "";
if (line.startsWith("http://")) { // Assume it's a full URL
filePath = line;
}
else { // Assume it's relative
try{
filePath = getRequest.getURI().resolve(line).toString();
}
catch(IllegalArgumentException e){
e.printStackTrace();
}
catch(Exception e){
e.printStackTrace();
}
}
}
}
}
catch (Exception e) {
e.printStackTrace();
}
try {
inputStream.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
return filePath;
}
#Override
protected void onPostExecute(String filePath) {
try {
mediaPlayer.setDataSource(filePath);
DATA_SET = true;
mediaPlayer.prepareAsync(); //this will prepare file a.k.a buffering
}
catch (IllegalArgumentException e) {
e.printStackTrace();
}
catch (IllegalStateException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
};
asyn.execute("");
}
Maybe the problem is the BufferedInputStream. I wrote this code (a long time ago) if you want to try it.
Give an input stream to the fonction and let it work.
import java.io.InputStream;
import java.util.Scanner;
/**
* Created by badetitou.
*/
public class ReadIt {
public static String ReadIt(InputStream is){
return new Scanner(is,"UTF-8").useDelimiter("").next();
}
}

unable to save data to txt in loop asynctask

I am trying to save every output data in asynctask for each http call.But I am unable to see any data in a file.I really appreciate any help.Thanks in Advance.
final String[] ar={"1","2","3",.............,"25"}
filename="test_file";
myFile = new File("/sdcard/"+filename);
try {
myFile.createNewFile();
fOut = new FileOutputStream(myFile);
} catch (FileNotFoundException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
myOutWriter = new OutputStreamWriter(fOut);
for ( j = 0; j < ar.length; j++) {
u="http://www.example.com/"+ar[j];
JSONParser jParser=new JSONParser();
new MyAsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,u);
}
try {
myOutWriter.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
class MyAsyncTask extends AsyncTask<String, String, Void> {
private ProgressDialog progressDialog = new ProgressDialog(MainActivity.this);
InputStream inputStream = null;
String result = "";
protected void onPreExecute() {
progressDialog.setMessage("Downloading your data...");
progressDialog.show();
progressDialog.setOnCancelListener(new OnCancelListener() {
public void onCancel(DialogInterface arg0) {
MyAsyncTask.this.cancel(true);
}
});
}
#Override
protected Void doInBackground(String... params) {
String url_select = params[0];
try {
HttpClient httpclient = new DefaultHttpClient();
HttpResponse httpResponse = httpclient.execute(new HttpGet(url_select));
// receive response as inputStream
inputStream = httpResponse.getEntity().getContent();
//
// // Read content & Log
// inputStream = httpEntity.getContent();
} catch (UnsupportedEncodingException e1) {
Log.e("UnsupportedEncodingException", e1.toString());
e1.printStackTrace();
} catch (ClientProtocolException e2) {
Log.e("ClientProtocolException", e2.toString());
e2.printStackTrace();
} catch (IllegalStateException e3) {
Log.e("IllegalStateException", e3.toString());
e3.printStackTrace();
} catch (IOException e4) {
Log.e("IOException", e4.toString());
e4.printStackTrace();
}
// Convert response to string using String Builder
try {
BufferedReader bReader = new BufferedReader(new InputStreamReader(inputStream, "iso-8859-1"), 8);
StringBuilder sBuilder = new StringBuilder();
String line = null;
while ((line = bReader.readLine()) != null) {
sBuilder.append(line + "\n");
}
inputStream.close();
result = sBuilder.toString();
} catch (Exception e) {
Log.e("StringBuilding & BufferedReader", "Error converting result " + e.toString());
}
return null;
} // protected Void doInBackground(String... params)
protected void onPostExecute(Void v) {
//parse JSON data
try{
JSONObject jArray = new JSONObject(result);
String name = jArray.getString("name");
if (name!=null) {
Log.w("idname", name);
//
myOutWriter.append(name).append("\r\n");
//
Toast.makeText(getBaseContext(), name, 5).show();
}
// End Loop
this.progressDialog.dismiss();
} catch (JSONException e) {
Log.e("JSONException", "Error: " + e.toString());
} // catch (JSONException e)
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
} // protected void onPostExecute(Void v)
} //class MyAsyncTask extends AsyncTask<String, String, Void>
for ( j = 0; j < ar.length; j++) {
u="http://www.example.com/"+ar[j];
JSONParser jParser=new JSONParser();
new MyAsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR,u);
}
try {
myOutWriter.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
You close the myOutWriter after start MyAsyncTask. So when MyAsyncTask try to write data to file, it throw OutputStreamWriter is closed exception.
You need remove the code of close myOutWriter from here. Add add close code at the end of onPostExecute like below:
void onPostExecute(Void v) {
.....
} catch (JSONException e) {
Log.e("JSONException", "Error: " + e.toString());
} // catch (JSONException e)
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
int count = taskCount.decrementAndGet()
if(count == 0 ) {
try {
myOutWriter.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} // protected void onPostExecute(Void v)
the definition of taskCount is like this:
AtomicInteger taskCount = new AtomicInteger(ar.length - 1);
At last, I think Thread and CountDownLatch is better option
check if entity not null then write to db
HttpEntity entity = response.getEntity();
if(entity!=null ){
inputStream = entity.getContent();
}

Extracting data from server takes too much time- android

I have a android application, where i extract data from the multiple urls and save then as arraylist of string. It works fine, but for fetching data from 13 urls, it takes close to 15-20 sec. Where as fetching the data from same set of urls take 3-4 sec in same app built using phonegap. Here is the code below.
#Override
protected String doInBackground(String... params) {
client = new DefaultHttpClient();
for(int i=0;i<url.size();i++)
{
get = new HttpGet(url.get(i));
try {
response = client.execute(get);
} catch (ClientProtocolException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
entity = response.getEntity();
InputStream is = null;
try {
is = entity.getContent();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
BufferedReader reader = new BufferedReader(
new InputStreamReader(is));
StringBuffer buffer = new StringBuffer();
String line = null;
do {
try {
line = reader.readLine();
} catch (IOException e) {
e.printStackTrace();
}
buffer.append(line);
} while (line != null);
String str = buffer.toString();
param.add(str);
}
return null;
}
Could anyone please suggest how i can speed this execution and reduce the extraction time.
You could try starting a separate thread for each iteration from the for loop.
Smth like this :
for(int i = 0; i < url.size(); i++){
//start thread that gets data from url and adds it to the list
}

Http delete gets bad request in Android

I am working with Android http stuff to register/unregister to the server. I have a DELETE request to use HttpDelete. I am getting Http401 'Bad request' error when I try to call it. I cannot why it is happening. Please help me.
Here is my code:
HttpUtils.java
private BasicHttpParams mParams;
private UsernamePasswordCredentials mCredentials = null;
private ResponseHandler mResponseHandler = null;
public void setUserCredentials(String userName, String password) {
this.mCredentials = new UsernamePasswordCredentials(userName, password);
}
public void setResponseHandler(ResponseHandler responseHandler){
this.mResponseHandler = responseHandler;
}
public Result<String> delete(String url){
Result<String> result = new Result<T>();
result.setStatus(Result.FAIL);
try {
DefaultHttpClient httpClient = new DefaultHttpClient(mParams);
httpClient.setParams(mParams);
httpClient.getCredentialsProvider().setCredentials(new AuthScope(null, -1), mCredentials);
HttpResponse response = httpClient.execute(new HttpDelete(url));
result.setResult(mResponseHandler.handleResponse(response));
result.setStatus(Result.SUCCESS);
} catch (IllegalArgumentException e) {
e.printStackTrace();
result.setMessage(e.getMessage());
} catch (ClientProtocolException e) {
e.printStackTrace();
result.setMessage(e.getMessage());
} catch (ConnectTimeoutException e) {
result.setMessage("Connection timed out.");
} catch (IOException e) {
e.printStackTrace();
result.setMessage(e.getMessage());
}
return result;
}
UnregisterTask.java
#Override
protected Void doInBackground(String... urls) {
if (urls==null || urls.length!=1)
return null;
String url = urls[0];
HttpUtils httpUtils = new HttpUtils();
httpUtils.setUserCredentials("userid", "password");
httpUtils.setResponseHandler(new UnrgisterHandler());
httpUtils.delete(url);
Result<String> result = aClient.delete(url);
if (result!=null || result.result != null){
//Do Something
}
}
//UnrgisterActivity.java
public void onUnregisterButtonClick(View view){
UnregisterTask task = new UnregisterTask(this);
task.execute(ServerConfig.getIdmServer() + ServerConfig.DELETE_DEVICE + "myid");
}
Error recevied:
Apache Tomcat/7.0.26 - Error report HTTP Status 400 - type Status reportmessage description The request sent by the client was syntactically incorrect ().Apache Tomcat/7.0.26
Thanks in Advance.
I fixed it by myself but I do not understand clearly why the error happened. I changed my code after searching how to set basic authentication.
public Result<T> delete(String url)
Result<T> result = new Result<T>();
result.setStatus(Status.FAIL);
try {
DefaultHttpClient http = new DefaultHttpClient();
if (this.mCredentials!=null){
CredentialsProvider credProvider = new BasicCredentialsProvider();
credProvider.setCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT), this.mCredentials);
http.setCredentialsProvider(credProvider);
}
HttpDelete delete = new HttpDelete(url);
//delete.setEntity(new StringEntity(data, "UTF8"));
delete.addHeader("Content-type", JSON_TYPE);
HttpResponse response = http.execute(delete);
result.setResult(mResponseHandler.handleResponse(response));
result.setStatus(Result.Status.SUCCESS);
} catch (IllegalArgumentException e) {
e.printStackTrace();
result.setMessage(e.getMessage());
} catch (ClientProtocolException e) {
e.printStackTrace();
result.setMessage(e.getMessage());
} catch (ConnectTimeoutException e) {
result.setMessage("Connection timed out.");
} catch (IOException e) {
e.printStackTrace();
result.setMessage(e.getMessage());
}
return result;
}
A bit still confusing. Anyway, now it works charm.

Categories

Resources