Trying to use this "Words API" in an android application which only seems to accept requests using Unirest.
Request example for the definition of "incredible" (specified by api):
HttpResponse<JsonNode> response = Unirest.get("https://wordsapiv1.p.mashape.com/words/incredible/definitions")
.header("X-Mashape-Key", "**********apikey************")
.header("Accept", "application/json")
.asJson();
The trouble is implementing the unirest request with doInBackground in AsyncTask.
protected void OnPreExecute(){
json_url = "https://wordsapiv1.p.mashape.com/words/incredible/definitions";
//where does api key go?
}
protected String doInBackground(Void... params) {
try {
// unirest goes here but how?
URL url = new URL(json_url);
HttpURLConnection httpURLConnection = (HttpURLConnection)url.openConnection();
InputStream inputStream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder stringBuilder = new StringBuilder();
while ((JSON_STRING = bufferedReader.readLine()) !=null)
stringBuilder.append(JSON_STRING+"\n");
bufferedReader.close();
inputStream.close();
httpURLConnection.disconnect();
return stringBuilder.toString().trim();
}catch (MalformedURLException e){
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
Not sure exactly how to structure the request within doInBackground.
Is it possible to do this?
This code is not tested but to give you an idea on how you might solve this problem.
private class TastingUniRestAsync extends AsyncTask<String, Void, String> {
protected String doInBackground(String... urls) {
String pathToFile = urls[0];
String responseResult = "";
HttpResponse<JsonNode> response = Unirest.get(pathToFile)
.header("X-Mashape-Key", "**********apikey************")
.header("Accept", "application/json")
.asJson();
if(null != response){
//convert your response to the data type you want. Here I am using string
responseResult = //assign the manipulated Json string;
}
return responseResult
}
protected void onPostExecute(String responseResult){
// You can assign it to TextView widget for example
mTextView.setText(responseResult);
}
}
I think the better solution would be to use the Volley library. Take a look at my solution, don't forget to add a dependency: compile 'com.android.volley:volley:1.0.0'. If you need more information.
RequestQueue requestQueue = Volley.newRequestQueue(this);
String uri = Uri.parse("https://wordsapiv1.p.mashape.com/words/incredible/definitions")
.buildUpon()
.build().toString();
StringRequest stringRequest = new StringRequest(
Request.Method.GET, uri, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d("VolleyResponse", "response: " + response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("VolleyError", error.toString());
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
params.put("X-Mashape-Key", "<API_KEY>");
params.put("Accept", "text/plain");
return params;
}
};
requestQueue.add(stringRequest);
Related
I am trying to create an app on android studio and im new to this IDE and language. I managed to implement the GET method for Imflip api, but im stuck on the POST method. I would like to return an Meme with a caption added by the user.
Im using Android Studio 3.4.1. I've tried the code attached. For testing purposes, i've hardcoded the username, password, and two captions. Also, when i call POST() I pass the id 61579 as a parameter. I've tried finding he value for the response but it says that its "200"...
What i need is a url for the created meme.
Hope anyone can help.
Thanks in Advance.
private void POST(String memeID) {
try {
RequestQueue requestQueue = Volley.newRequestQueue(this);
String URL = "https://api.imgflip.com/caption_image";
JSONObject jsonBody = new JSONObject();
jsonBody.put("template_id", memeID);
jsonBody.put("username", "Meme_Genie");
jsonBody.put("password", "Password");
jsonBody.put("text0", "Hello");
jsonBody.put("text1", "World");
final String requestBody = jsonBody.toString();
StringRequest stringRequest = new StringRequest(Request.Method.POST, URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.i("VOLLEY", response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("VOLLEY", error.toString());
}
}) {
#Override
public String getBodyContentType() {
return "application/json; charset=utf-8";
}
#Override
public byte[] getBody() throws AuthFailureError {
try {
return requestBody == null ? null : requestBody.getBytes("utf-8");
} catch (UnsupportedEncodingException uee) {
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", requestBody, "utf-8");
return null;
}
}
#Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
String responseString = "";
if (response != null) {
responseString = String.valueOf(response.statusCode);
// can get more details such as response.headers
}
return Response.success(responseString, HttpHeaderParser.parseCacheHeaders(response));
}
};
requestQueue.add(stringRequest);
} catch (JSONException e) {
e.printStackTrace();
}
}
Switching from encode = "json" to encode = "form"
Or switching your body to BodySerializationMethod.UrlEncoded will work
this code is ok for get data from server but if my API is POST Method how to pass params to server by POSt Request and fetch data. code is here, please let me know
public class GetTripTeportData extends AsyncTask<String, Integer,String> {
#Override
protected void onPreExecute() {...}
#Override
protected String doInBackground(String... params) {
String responseBodyText = null;
OkHttpClient client = new OkHttpClient();
try {
Request request = new Request.Builder().url(excelApi).build();
Response response = null;
response = client.newCall(request).execute();//.....
responseBodyText = response.body().string();
JSONObject resultData = new JSONObject(responseBodyText);
JSONArray itemArray = resultData.getJSONArray("data");
for (int i=0; i<itemArray.length();i++){
JSONObject jobject = itemArray.getJSONObject(i);
String iduser = jobject.getString("id");
String vehicleno = jobject.getString("vehicleno");
String startdate = jobject.getString("startdate");
allList.add(new ExcelReportAdminResponse(iduser,vehicleno,startdate));
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
runOnUiThread(new Runnable() {
#Override
public void run() {
}
});
return responseBodyText;
}
#Override
protected void onPostExecute(String s) {......}
}
To post data with default http client with async task you can do as below:
First create network utility class as below:
public class NetworkUtilities {
public static String postData(String Url, String message ){
try {
URL url = new URL(Url);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setReadTimeout(10000); /*milliseconds*/
conn.setConnectTimeout(15000); /* milliseconds */
conn.setRequestMethod("POST");
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setFixedLengthStreamingMode(message.getBytes().length);
conn.setRequestProperty("Content-Type", "application/json;charset=utf-8");
conn.setRequestProperty("X-Requested-With", "XMLHttpRequest");
conn.connect();
OutputStream os = new BufferedOutputStream(conn.getOutputStream());
os.write(message.getBytes());
os.flush();
InputStream is = conn.getInputStream();
java.util.Scanner s = new java.util.Scanner(is).useDelimiter("\\A");
return s.hasNext() ? s.next() : "";
}
catch (Exception e){
Log.e("Exception: " , e.toString());
}
finally {
// os.close();
//is.close();
//conn.disconnect();
}
return "";
}
}
Then write async task to call that postData() method from NetworkUtilities class as below:
private class PostDataAsync extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... params) {
return NetworkUtilities.postData(params[0], params[1]);
}
#Override
protected void onPostExecute(String result) {
Log.e("Data response: ", result);
}
#Override
protected void onPreExecute() {
// TODO: Loader and stuff to add later here.
}
#Override
protected void onProgressUpdate(Void... values) {
}
}
Then to call that async task means to call api do as below:
String message = "";
try {
JSONObject jsonBody = new JSONObject();
jsonBody.put("user_id", session.getSession());
message = jsonBody.toString();
} catch (Exception e) {
Log.e("JSON error: ", e.toString());
}
PostDataAsync postData = new PostDataAsync();
postData.execute("YOUR_POST_API_URL_HERE", message);
By using this way you can be able to post data with async task.
For POST call with JSON body
final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
RequestBody body = RequestBody.create(JSON, /*YOUR JSON REQUEST*/ jsonString);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
try {
Response response = client.newCall(request).execute();
} catch(IOException io){
// do something
}
I need to make an api request which.
Two headers :
Accept
Authorization
Five body params.
Number
Make
Model
Description
Plates
Through postman everything works great.
But when i try through android app i can't get through.
Note: Login through the same host works great so the setup its not the problem i think my main problem is in api call.
public void add(View view) {
RequestQueue queue = Volley.newRequestQueue(this);
String URL = "http://10.0.2.2:8000/api/trucks";
StringRequest request = new StringRequest(Request.Method.POST, URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonObj = new JSONObject(response);
// parse response
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
NetworkResponse response = error.networkResponse;
String errorMsg = "";
if (response != null && response.data != null) {
String errorString = new String(response.data);
}
}
}
) {
#Override
public Map<String, String> getHeaders() {
HashMap<String, String> headers = new HashMap<>();
headers.put("Accept", "application/json");
headers.put("Authorization", "Bearer " + myToken);
return headers;
}
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
TextInputEditText number = findViewById(R.id.textInputEditTextNumber);
TextInputEditText make = findViewById(R.id.textInputEditTextMake);
TextInputEditText model = findViewById(R.id.textInputEditTextModel);
TextInputEditText description = findViewById(R.id.textInputEditTextDescription);
TextInputEditText plates = findViewById(R.id.textInputEditTextPlates);
params.put("number", number.getText().toString());
params.put("make", make.getText().toString());
params.put("model", model.getText().toString());
params.put("description", description.getText().toString());
params.put("plates", plates.getText().toString());
return params;
}
};
queue.add(request);
}
Edit: by Solution #1.
public void add(View view) throws JSONException {
RequestQueue queue = Volley.newRequestQueue(this);
TextInputEditText number = findViewById(R.id.textInputEditTextNumber);
TextInputEditText make = findViewById(R.id.textInputEditTextMake);
TextInputEditText model = findViewById(R.id.textInputEditTextModel);
TextInputEditText description = findViewById(R.id.textInputEditTextDescription);
TextInputEditText plates = findViewById(R.id.textInputEditTextPlates);
JSONObject jsonObject = new JSONObject();
jsonObject.put("Number", number.getText().toString());
jsonObject.put("Make", make.getText().toString());
jsonObject.put("Model", model.getText().toString());
jsonObject.put("Description", description.getText().toString());
jsonObject.put("Plates", plates.getText().toString());
final String requestBody = jsonObject.toString();
JsonObjectRequest jsonRequest = new JsonObjectRequest(Request.Method.POST, "http://10.0.2.2:8000/api/trucks", jsonObject,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
//now handle the response
Toast.makeText(truck_add.this, response.toString(), Toast.LENGTH_SHORT).show();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
//handle the error
Toast.makeText(truck_add.this, "An error occurred", Toast.LENGTH_SHORT).show();
error.printStackTrace();
}
}) { //this is the part, that adds the header to the request
#Override
public Map<String, String> getHeaders() {
Map<String, String> params = new HashMap<String, String>();
params.put("Accept", "application/json");
params.put("Authorization", myToken);
return params;
}
};
queue.add(jsonRequest);
}
Postman :
When you want to pass the data through the body, you need to create a json object before string request.
try this way,
1. create a string url for request.
2. create json object for body data and pass data to it. Like,
JSONObject jsonObject= new JSONObject();
jsonObject.put("Number", address.getNumber());
jsonObject.put("Make", address.getMake());
jsonObject.put("Model", address.getModel());
jsonObject.put("Description", address.getDescription());
jsonObject.put("Plates", address.getPlates());
final String requestBody=jsonObject.toString();
3. After this, apply stringRequest.
4. Now, add below lines before header method and after error method.
#Override
public String getBodyContentType() {
return "application/json; charset=utf-8";
}
#Override
public byte[] getBody() throws AuthFailureError {
try {
return requestBody == null ? null : requestBody.getBytes("utf-8");
} catch (UnsupportedEncodingException uee) {
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", requestBody, "utf-8");
return null;
}
5. In your getHeaders() method, use Content-Type for "application/json" and for Authorization you must use only token without (Bearer).
Done.
public void add(View view) throws JSONException {
String URL = "http://10.0.2.2:8000/api/trucks";
//removed views initialization from here.
//you need to initialize views in oncreate() / oncreateView() method.
/*first create json object in here.
then set keys as per required body format with values
*/
JSONObject jsonObject = new JSONObject();
jsonObject.put("Number", number.getText().toString());
jsonObject.put("Make", make.getText().toString());
jsonObject.put("Model", model.getText().toString());
jsonObject.put("Description", description.getText().toString());
jsonObject.put("Plates", plates.getText().toString());
final String requestBody = jsonObject.toString();
RequestQueue queue = Volley.newRequestQueue(this);
StringRequest request = new StringRequest(Request.Method.POST, URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonObj = new JSONObject(response);
// parse response
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
NetworkResponse response = error.networkResponse;
String errorMsg = "";
if (response != null && response.data != null) {
String errorString = new String(response.data);
}
}
}
) { //this is the part, that adds the header to the request
//this is where you need to add the body related methods
#Override
public String getBodyContentType() {
return "application/json; charset=utf-8";
}
#Override
public byte[] getBody() throws AuthFailureError {
try {
return requestBody == null ? null : requestBody.getBytes("utf-8");
} catch (UnsupportedEncodingException uee) {
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s
using %s", requestBody, "utf-8");
return null;
}
#Override
public Map<String, String> getHeaders() {
Map<String, String> params = new HashMap<String, String>();
params.put("Content-Type", "application/json");
params.put("Authorization", myToken);
return params;
}
};
queue.add(jsonRequest);
}
Put Log in every method to check which method being executed and for possible error
If there is an error after this, then post error from logcat and we will solve it quickly.
I am trying to use geo location api to get lattitude and longitude of the location. So for this I created a project on developer console and created an api key. I used this api key with this api https://www.googleapis.com/geolocation/v1/geolocate?key=YOUR_API_KEY
So this when I executed the request in postman it works well.
But when I tried to execute same request in an app its giving response as response code 400.
Response code 400 as per developer guide
https://developers.google.com/maps/documentation/geolocation/intro#errors
shows it comes when the api key is wrong. But how the key works in postman and not in the app?
Here is the code for server request:
public JSONObject sendPostRequest1(String data) {
try {
URL url = new URL(api);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
// con.setRequestProperty("content-type", "application/x-www-form-urlencoded");
con.setDoOutput(true);
con.setDoInput(true);
OutputStreamWriter writer = new OutputStreamWriter(con.getOutputStream());
try {
writer.write(data);
} catch (Exception e) {
Log.e("Exception111", e.toString());
}
writer.close();
int responseCode = con.getResponseCode();
if (responseCode == HttpURLConnection.HTTP_OK || responseCode == HttpURLConnection.HTTP_CREATED) {
StringBuilder sb = new StringBuilder();
BufferedReader reader = new BufferedReader(new InputStreamReader(con.getInputStream()));
String line = "";
while ((line = reader.readLine()) != null) {
sb.append(line);
}
reader.close();
Log.d("ServerResponse", new String(sb));
String output = new String(sb);
return new JSONObject(output);
} else {
Log.e("Exception", "" + responseCode);
}
}
catch (JSONException je)
{
je.printStackTrace();
return Excpetion2JSON.getJSON(je);
}
catch(IOException e)
{
}
return null;
}
Async Task :
public class GetLocationAsyncTask extends AsyncTask<String, Void, JSONObject> {
String api;
JSONObject jsonParams;
Context mContext;
private ProgressDialog loadingDialog;
private String number,code;
public GetLocationsCallBack getLocationsCallBack;
public GetLocationAsyncTask(Context context,GetLocationsCallBack getLocationsCallBack) {
this.mContext = context;
this.getLocationsCallBack = getLocationsCallBack;
}
public interface GetLocationsCallBack {
void doPostExecute(ArrayList<Location> list);
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected JSONObject doInBackground(String... params) {
try {
api = "https://www.googleapis.com/geolocation/v1/geolocate?key=AIzaSyCArRAX4oHdfFWrTWhXrOVBQtbs";
jsonParams = new JSONObject();
jsonParams.put("cellId", params[0]);
jsonParams.put("locationAreaCode",params[1]);
ServerRequest request = new ServerRequest(api, jsonParams);
return request.sendPostRequest1(jsonParams.toString());
} catch (Exception ue) {
return Excpetion2JSON.getJSON(ue);
}
} //end of doInBackground
#Override
protected void onPostExecute(JSONObject response) {
super.onPostExecute(response);
if(response.has("location"))
{
try {
Location location = new Location();
location.setLattitude(response.getString("lat"));
location.setLongitude(response.getString("lng"));
ArrayList<Location> locations = location.getLocationArrayList();
locations.add(location);
}
catch (JSONException je)
{
Log.d("JsonException",je.toString());
}
}
if (loadingDialog.isShowing())
loadingDialog.dismiss();
}
}
Executing async task:
TelephonyManager telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
GsmCellLocation cellLocation = (GsmCellLocation)telephonyManager.getCellLocation();
int cellid= cellLocation.getCid();
int celllac = cellLocation.getLac();
Log.d("CellLocation", cellLocation.toString());
Log.d("GSM CELL ID", String.valueOf(cellid));
Log.d("GSM Location Code", String.valueOf(celllac));
GetLocationAsyncTask getLocationAsyncTask = new GetLocationAsyncTask(MainActivity.this,MainActivity.this);
getLocationAsyncTask.execute(String.valueOf(cellid),String.valueOf(celllac));
Whats going wrong with this? Please help. Thank you..
You have to tell the receiving side that it is json that you send
con.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
I'm attempting to do a PUT in x-www-form-urlencoded to a drupal table with Volley from my Android app. I'm try to send a 'type' and 'value', in the params and I get a 500 error. A basic StringRequest returns 404.
Here's my latest code. I've only found one or two entries that touch on the Volley Put. Any help would be appreciated. Have a great day.
private void postTestAnswerResult(String id, String answerResult) {
StringRequest req = null;
requestQueue = Volley.newRequestQueue(this);
final String baseURL = "http://blah.blah.com/api/answer/";
String URL = baseURL + id;
// Post params to be sent to the server
HashMap<String, String> params = new HashMap<String, String>();
params.put("Content-Type","application/x-www-form-urlencoded");
params.put("type", answerResult);
req = new StringRequest(Request.Method.PUT, URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
VolleyLog.v("Response:%n %s", response.toString());
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
try {
String responseBody = new String(
volleyError.networkResponse.data, "utf-8");
JSONObject jsonObject = new JSONObject(responseBody);
} catch (JSONException e) {
// Handle a malformed json response
} catch (UnsupportedEncodingException error) {
}
}
}
);
requestQueue.add(req);
}
In case you are still having problems with this, as #Meier points out in a comment above, you are not using the params variable, or rather you aren't using it correctly. The data doesn't get sent to the server, and the server is probably expecting the data resulting in the 500 error.
You need to override the getParams method of the StringRequest call in order to send the data. So, the following would be closer to getting the job done:
private void postTestAnswerResult(String id, String answerResult) {
StringRequest req = null;
requestQueue = Volley.newRequestQueue(this);
final String baseURL = "http://blah.blah.com/api/answer/";
String URL = baseURL + id;
req = new StringRequest(Request.Method.PUT, URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
VolleyLog.v("Response:%n %s", response.toString());
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError volleyError) {
try {
String responseBody = new String(
volleyError.networkResponse.data, "utf-8");
JSONObject jsonObject = new JSONObject(responseBody);
} catch (JSONException e) {
// Handle a malformed json response
} catch (UnsupportedEncodingException error) {
}
}
}
) {
#Override
protected Map<String, String> getParams()
{
HashMap<String, String> params = new HashMap<String, String>();
// params.put("Content-Type","application/x-www-form-urlencoded"); This shouldn't be here. This is a HTTP header. If you want to specify header you should also override getHeaders.
params.put("type", answerResult);
return params;
}
};
requestQueue.add(req);
Browser don't ignore 500 errors. They very often show up as ugly messages in the browser window.