I have a android app that uses the twilio sdk and is hosted by heroku server. I'm trying to push a button in my app to send a HTTP request to heroku to send a REST API request to Twilio to update my twiml URL. The current way i'm trying to send the the HTTP request is not working. I have looked through all of the examples that i could find and none of them show how to do this function. Does anybody know how to do this? Thanks in advance.
This is my code for trying to send the HTTP request to heroku
holdButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://yourappnamehere.herokuapp.com/hello");
try {
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
HttpEntity ht = response.getEntity();
BufferedHttpEntity buf = new BufferedHttpEntity(ht);
InputStream is = buf.getContent();
BufferedReader r = new BufferedReader(new InputStreamReader(is));
StringBuilder total = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
total.append(line);
}
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//setting a toast to see if this is being initiated
Toast.makeText(getBaseContext(), "why wont it work!", Toast.LENGTH_SHORT).show();
}
;
});
This is my updated code including the volley library
holdButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//setting up a request queue from Volley API
//RequestQueue mRequestQueue;
// Instantiate the cache
Cache cache = new DiskBasedCache(getCacheDir(), 1024 * 1024); // 1MB cap
// Set up the network to use HttpURLConnection as the HTTP client.
Network network = new BasicNetwork(new HurlStack());
// Instantiate the RequestQueue with the cache and network.
mRequestQueue = new RequestQueue(cache, network);
// Start the queue
mRequestQueue.start();
String url = "http://yourappnamehere.herokuapp.com/hello";
// Formulate the request and handle the response.
StringRequest stringRequest = new StringRequest(Request.Method.POST, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
// Do something with the response
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// Handle error
}
});
// Add the request to the RequestQueue.
mRequestQueue.add(stringRequest);
Toast.makeText(getBaseContext(), "why wont it work!", Toast.LENGTH_SHORT).show();
}
;
});
I would suggest using a library like Google Volley which is pretty slick
https://developer.android.com/training/volley/index.html
HttpRequest is deprecated from API level 22. It would be best practice to avoid using that. Use java.net.HttpUrlConnection instead.
However, if you still want to use it, the above code needs to be run on a thread other than the UI thread as mentioned in the comment above.
Related
I'm using the below code on my main activity to log the user into my app. The app's backend is Wordpress. The server returns a success message, and the user is authenticated, but as soon as I get to the next screen/activity, and attempt to have the user create a post to wordpress, the server returns the message
"Sorry, you are not allowed to create posts as this user."
Especially odd in this case because the user credentials I'm using to login are the admin user.
Any idea how I can fix this?
LoginActivity (my user logs in successfully):
private class UserNetwork extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... voids) {
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("username", "admin");
jsonObject.put("password", "123456");
} catch (JSONException e) {
e.printStackTrace();
}
OkHttpClient client = new OkHttpClient();
MediaType JSON = MediaType.parse("application/json; charset=utf-8");
RequestBody body = RequestBody.create(JSON, jsonObject.toString());
Request request = new Request.Builder()
.url("http://myurl.com/wp-json/wp/v2/custom-plugin/login")
.post(body)
.build();
Response response = null;
try {
response = client.newCall(request).execute();
String resStr = response.body().string();
Log.i("The response is", String.valueOf(response));
int responseCode = response.code();
Log.i("Check response code", String.valueOf(responseCode));
if (responseCode == 200) {
Log.i("We're logged in!", String.valueOf(responseCode));
Intent i = new Intent(LoginActivity.this, DashboardActivity.class);
startActivity(i);
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
DashboardActivity (user attempts to create post, and 'Unauthorized' messsage is returned):
private class UserPosts extends AsyncTask<Void, Void, Void> {
#Override
protected Void doInBackground(Void... voids) {
JSONObject jsonObject = new JSONObject();
try {
jsonObject.put("title", "Our first post");
jsonObject.put("content", "this is a test");
jsonObject.put("status", "publish");
} catch (JSONException e) {
e.printStackTrace();
}
OkHttpClient client = new OkHttpClient();
MediaType JSON = MediaType.parse("application/json; charset=utf-8");
// put your json here
RequestBody body = RequestBody.create(JSON, jsonObject.toString());
Request request = new Request.Builder()
.url("http://myurl.com/wp-json/wp/v2/posts")
.post(body)
.build();
Response response = null;
try {
response = client.newCall(request).execute();
String resStr = response.body().string();
Log.i("The response is", String.valueOf(response));
int responseCode = response.code();
Log.i("Check response code", String.valueOf(responseCode));
if (responseCode == 200) {
Log.i("Creating post!", String.valueOf(responseCode));
} else {
Log.i("Post not created.", String.valueOf(responseCode));
}
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
The problem you're having is caused by HTTP protocol being stateless.
That means whenever you perform request, server treats you as a new entity.
In case of most authenticated requests, the client is responsible for storing the tokens issued by the server during the login, and then passing them to following requests.
When you are using the browser it is the client and usually is being responsible for handling this state (it ma also be a JavaScript code running in the browser).
In your code that is your responsibility to store this state.
While you're using OkHttp, you could use CookieJar and it would probably work. However in the end using user credentials to authenticate application is not the best idea and using extension that would allow you to specify credentials for an application as #faozi suggested would probably be a better solution.
You need to install and activate the Application Passwords plugin and then follow the instructions given
here.
But you don’t need to actually set up any Application Passwords for your users.
you need to authenticate it first : here
you can add code in WordPress file to authenticate it
This question already has answers here:
How to add parameters to api (http post) using okhttp library in Android
(9 answers)
Closed 6 years ago.
Recently I want use a search interface.But I am confused by the request body.
According to reference,when you need to search in their site,you can do like this:
curl -d "keyword=android" http://gankio.herokuapp.com/search
So how to post a this request in java rather than curl?
I have tried useing okhttp.
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
OkHttpClient client = new OkHttpClient();
String json = "keyword=android";
RequestBody body = RequestBody.create(JSON,json);
Request request = new Request.Builder()
.url("http://gankio.herokuapp.com/search")
.post(body)
.build();
try {
Response response = client.newCall(request).execute();
Log.d("TAG",response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
});
thread.start();`
I have solved this question.
Thread thread = new Thread(new Runnable() {
#Override
public void run() {
OkHttpClient client = new OkHttpClient();
RequestBody requestBody = new FormBody.Builder().add("keyword", "android").build();
Request request = new Request.Builder()
.url("http://gankio.herokuapp.com/search")
.post(requestBody)
.build();
try {
Response response = client.newCall(request).execute();
Log.d("TAG", response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
});
thread.start();
You want to call the service using post request and form param, please use the below code:
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("http://gankio.herokuapp.com/search?keyword=android")
.post( RequestBody.create(MediaType.parse("application/json; charset=utf-8"), ""))
.build();
try {
Response response = client.newCall(request).execute();
System.out.println(response.toString());
System.out.println(response.body().string());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Response response = client.newCall(request).execute();
The service that you want to call does not need any body to pass, only it needs form parameter (keyword) with value (android), but you are trying to pass the parameter using the body, and this is your mistake
You can try using HttpUrlConnection from java.net
This link will explain HttpUrlConnection connection process.
I am using blobstore API to upload an image to my app. This works fine locally, which means image is successfully uploaded and callback works as well. But when I am sending the multipart request to the uploadurl returned by createUploadUrl from the server, it always gives me 404 not found error.
Is it possible that blobstore is not enabled for my app? Why can't I see my blobstore in the google cloud console? I have to go to here https://appengine.google.com/blobstore/ to see my blobs.
Code on the app side: doPost handles callback and doGet returns the uploadUrl (both within same servlet /_ah/admin/new_image). doPost(call back handler code) is never triggered and neither is image is uploaded.
#Override
public void doPost(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
Map<String, List<BlobKey>> blobs = blobstoreService.getUploads(req);
List<BlobKey> blobKeys = blobs.get("image");
ImagesService imagesService = ImagesServiceFactory.getImagesService();
String imageUrl = imagesService.getServingUrl(ServingUrlOptions.Builder.withBlobKey(blobKeys.get(0)));
Long businessId = Long.parseLong(req.getParameter("business_id"));
String linkUrl = req.getParameter("link_url");
Long id = Long.parseLong(req.getParameter("advertisement_id"));
AdvertisementManager.addNewAdvertisement(id, imageUrl, linkUrl, businessId);
}
#Override
public void doGet(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
PrintWriter out = resp.getWriter();
resp.setContentType( "text/html" );
String uploadUrl = blobstoreService.createUploadUrl("");
Logger.getLogger("").log(Level.WARNING,uploadUrl);
out.print(uploadUrl);
}
Code to upload an image: First send a get request to get the upload url, then sends the multipart request with the image File
public static void upload(Long id, File file, String linkUrl, Long businessId){
HttpClient httpclientget = HttpClientBuilder.create().build();
HttpGet httpget = new HttpGet("http://app-url/_ah/admin/new_image");
String uploadUrl = "";
try {
HttpResponse responseGet = httpclientget.execute(httpget);
uploadUrl = EntityUtils.toString(responseGet.getEntity());
Logger.getLogger("").log(Level.WARNING,uploadUrl);
} catch (Exception e) {
e.printStackTrace();
}
HttpClient httpclient = HttpClientBuilder.create().build();
HttpPost httpPost = null;
String uri=null;
try {
URIBuilder builder = new URIBuilder(uploadUrl);
builder.setParameter("advertisement_id", id.toString());
builder.setParameter("link_url", linkUrl);
builder.setParameter("business_id", businessId.toString());
uri=builder.build().toString();
} catch (URISyntaxException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
httpPost = new HttpPost(uri);
System.out.println(uri);
if (file!=null){
MultipartEntityBuilder reqEntity = MultipartEntityBuilder.create();
reqEntity.addBinaryBody("image", file, ContentType.create("image/jpeg"), "ad.jpg");
httpPost.setEntity(reqEntity.build());
}
try {
HttpResponse response = httpclient.execute(httpPost);
System.out.println(response);
} catch (Exception e){
System.out.println(e.getMessage());
e.printStackTrace();
}
}
AFAIK the /_ah/* space is reserved for internal GAE services and you shouldn't use it. The reason you are getting a 404 is probably Google preventing you from deploying that servlet, try changing the URL.
My requirement is to upload the images to server using a Multipart request. I was able to create a Multipart Http Request using the HttpClient, which is deprecated. Is it possible to achieve the same using HttpUrlConnection? If yes, how?
Update:
Current code
{
ProgressDialog progress_dialog;
#Override
protected void onPreExecute() {
// setting progress bar to zero
progress_dialog=new ProgressDialog(CreateAlbum.this);
progress_dialog.setTitle("Loading..");
progress_dialog.show();
super.onPreExecute();
}
#Override
protected String doInBackground(Void... params) {
return uploadFile();
}
#SuppressWarnings("deprecation")
private String uploadFile() {
String responseString = null;
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://192.168.1.42:8080/test/fileUpload.php");
try
{
MultipartEntityBuilder entity = MultipartEntityBuilder.create();
entity.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
File sourceFile = new File(fileUri);
// Adding file data to http body
entity.addPart("image", new FileBody(sourceFile));
// Extra parameters if you want to pass to server
entity.addPart("website",
new StringBody("www.androidhive.info"));
entity.addPart("email", new StringBody("abc#gmail.com"));
httppost.setEntity(entity);
// Making server call
HttpResponse response = httpclient.execute(httppost);
HttpEntity r_entity = response.getEntity();
int statusCode = response.getStatusLine().getStatusCode();
Log.i("RAE", "STATUS CODE IS"+statusCode);
if (statusCode == 200) {
// Server response
responseString = EntityUtils.toString(r_entity);
} else {
responseString = "Error occurred! Http Status Code: "
+ statusCode;
}
} catch (ClientProtocolException e) {
responseString = e.toString();
} catch (IOException e) {
responseString = e.toString();
}
return responseString;
}
#Override
protected void onPostExecute(String result) {
Log.e("RAE", "Response from server: " + result);
progress_dialog.dismiss();
// showing the server response in an alert dialog
Toast.makeText(getApplicationContext(), "File Uploaded", Toast.LENGTH_SHORT).show();
super.onPostExecute(result);
}
}
AndroidHttpClient has been depreciated and has no longer support from the developers. So one will have to use java's own HttpURLConnection under java.net package. Here is a demo android application which implements HttpURLConnection. Just use the following git commands and run the application in android studio
Clone the git project :-
git clone https://github.com/viper-pranish/android-tutorial.git
Download the right version of project where HttpURLConnection is implemented
git checkout 399e3d1f9624353e522faf350f38a12db635c09a
EDIT
After you understand from my code how to make a POST with HttpUrlConnection, you can edit it and integrate the following answers: Sending files using POST with HttpURLConnection
This is how I make a form-encoded POST:
// Connection
URL url = new URL("http://www.example.com");
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod("POST");
conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
conn.setDoOutput(true);
conn.setDoInput(true);
// Data to be sent
DataOutputStream out = new DataOutputStream(conn.getOutputStream());
out.writeBytes(printParams(params));
out.flush();
out.close();
// Print received response
BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()));
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println(inputLine);
}
in.close();
where printParams is a simple function to trasform a Map into a string like a=b&c=d:
public static String printParams(Map<String, String> params) {
StringBuffer sb = new StringBuffer();
for (Map.Entry<String, String> e: params.entrySet()) {
if (sb.length() > 0) {
sb.append("&");
}
sb.append(e.getKey()).append('=').append(e.getValue());
}
return sb.toString();
}
This link has everything you need to send a file to server using multipart. It has been updated to use the most recent http classes in android. I have tested it and use it myself today. Cheers!
http://www.androidhive.info/2014/12/android-uploading-camera-image-video-to-server-with-progress-bar/
For the nexts post show your code, the programmers need see that for give more great help, thanks. On the one hand I always use in my apps httpClient and it's the best way for me because you can configuration a specific client with handling cookies, authentication, connection management, and other features, it's simple if you have the code. If you want to see more info from this theme you can visit this links, in Class Overview part:
http://developer.android.com/reference/org/apache/http/client/HttpClient.html
http://developer.android.com/reference/java/net/HttpURLConnection.html
On the other hand, if you want to do a multiple connections with your server I recommend a parallel programming with httpClient with processes and threads can read more info here: http://developer.android.com/guide/components/processes-and-threads.html
// Last Update //
Sorry Rahul Batra I work with API 21... I noted this for next version of my app. But as the first Step I will try to use a backgroud tasks with httpURLConnection.
This post have a really great information:
http://android-developers.blogspot.com.es/2011/09/androids-http-clients.html
I hope it help you this answer!! If you need more information or anything let me know, good luck Rahul Batra.
My GCM app generate multiple registrations for same device. I have searched for this but coud'nt find any solution.
Here is my main activity::
public void onCreate(Bundle savedInstanceState) {
GCMRegistrar.checkDevice(this);
GCMRegistrar.checkManifest(this);
final String regId = GCMRegistrar.getRegistrationId(this);
if (regId.equals("")) {
GCMRegistrar.register(this, "952039800261");
} else {
Log.v(TAG, "Already registered");
}}
And this is my onRegistered() method::
protected void onRegistered(Context arg0, final String regId) {
Intent registrationIntent = new Intent("com.google.android.c2dm.intent.REGISTER");
// sets the app name in the intent
registrationIntent.putExtra("app", PendingIntent.getBroadcast(this, 0, new Intent(), 0));
registrationIntent.putExtra("sender", senderId);
startService(registrationIntent);
// Create a new HttpClient and Post Header
HttpClient httpclient = new DefaultHttpClient();
HttpPost httppost = new HttpPost("http://www.ludlowcastle.co.in/moksha/register.php");
try {
// Add your data
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("regId", regId));
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs));
// Execute HTTP Post Request
HttpResponse response = httpclient.execute(httppost);
} catch (ClientProtocolException e) {
// TODO Auto-generated catch block
} catch (IOException e) {
// TODO Auto-generated catch block
}
I have got around 5K registrations IDs for same device on my server..
You are registering in an infinite loop.
I don't use the GCMRegistrar class, but I'm quite sure that GCMRegistrar.register(this, "952039800261"); does the same as these lines :
Intent registrationIntent = new Intent("com.google.android.c2dm.intent.REGISTER");
// sets the app name in the intent
registrationIntent.putExtra("app", PendingIntent.getBroadcast(this, 0, new Intent(), 0));
registrationIntent.putExtra("sender", senderId);
startService(registrationIntent);
In my app, these 4 lines are in the onCreate method of my main activity instead of the GCMRegistrar call.
When onRegistered is called, this means the registration has been successful and you have a registration id. Since you are asking in this method to register again, a new registration request is sent to Google, and then this method is called again when the next registration succeeds. I'm not sure if you are getting different registration IDs on each call, or if you get the same one, but simply removing the mentioned 4 lines from onRegistered will solve your problem.