I am looking for a way how to make a POST (login) https request in android. How to make sure that the code don't trust self-signed/invalid certs. The input to the request needs to be in the following format:
{
"udid": DEVICE_ID
"email": "email#email.com",
"password": "password"
}
I need to make the auth call to this address format:
https://api.ADDRESS.com/v1/auth
Please note that I want to use HTTPs request and not HTTP.
You can use volley/retrofit library for parsing json.
example #
http://www.androidhive.info/2014/05/android-working-with-volley-library-1/
I ended up using OkHTTP after researching if it is secure to use in my case:
public class MainActivity extends AppCompatActivity {
public static final MediaType JSON
= MediaType.parse("application/json; charset=utf-8");
private static final String TAG = MainActivity.class.getSimpleName();
private JSONObject responseJson;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
final JSONObject myJson = new JSONObject();
try {
myJson.put("udid","c376e418-da42-39fb-0000-d821f1fd2804");
myJson.put("email","email
myJson.put("password","password");
} catch (JSONException e) {
e.printStackTrace();
}
Thread thread = new Thread(new Runnable(){
#Override
public void run() {
try {
//Your code goes here
String response = post("https://ADDRESS/v1/auth", myJson.toString());
responseJson = new JSONObject(response);
String message = responseJson.getString("message");
String token = responseJson.getString("token");
Log.d(TAG,"Response message: " + message);
Log.d(TAG,"Response token: " + token);
Log.d("MainActivity",response);
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.start();
}
String post(String url, String json) throws IOException {
OkHttpClient client = new OkHttpClient();
RequestBody body = RequestBody.create(JSON, json);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
Response response = client.newCall(request).execute();
return response.body().string();
}
}
Related
I use OkHttp for requests to my raspberry. I am thinking about putting the requests in a separate class.
Currently I have one method to send requests. The code is as follows:
private void sendRequest(String url, JSONObject json) {
Log.d(TAG, "sendRequest: Das Json: " + json);
// Authentication for the request to raspberry
OkHttpClient.Builder client = new OkHttpClient.Builder();
client.authenticator(new Authenticator() {
#Override
public Request authenticate(Route route, Response response) throws IOException {
String credential = Credentials.basic("username", "password");
return response.request().newBuilder()
.header("Authorization", credential)
.build();
}
});
// Sending out the request to the raspberry
OkHttpClient okHttpClient = client.build();
RequestBody body = RequestBody.create(null, new byte[]{});
if( json != null) {
body = RequestBody.create(MediaType.parse(
"application/json"),
json.toString()
);
}
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
okHttpClient.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
Log.d(LOG, "Big Fail");
e.printStackTrace();
}
#Override
public void onResponse(Call call, Response response) throws IOException {
try {
ResponseBody responseBody = response.body();
if( !response.isSuccessful() ) {
Log.d(TAG, "onResponse: We are in !response.successful()");
throw new IOException("Response not successful: " + response );
}
Log.d(LOG, "onResponse: Response is: " + responseBody.string());
} catch (Exception e) {
e.printStackTrace();
Log.d(LOG, "onResponse: failed!" + e);
}
}
});
}
Here is an example how the sendRequest() function is called:
private void makePremixCall(Premix premix) {
JSONArray jsonArray = new JSONArray();
ArrayList<Premixable> usedPremixables = premix.getUsedPremixables();
for(Premixable usedPremixable: usedPremixables) {
try {
JSONObject jsonObject = new JSONObject();
jsonObject.put("Silo", usedPremixable.getmSilo());
jsonObject.put("Gramm", usedPremixable.getmKgPerCow() * mFeeding.getmNumberOfCows());
jsonArray.put(jsonObject);
} catch (JSONException e) {
e.printStackTrace();
}
}
try {
JSONObject jsonObject = new JSONObject();
jsonObject.put("Components", jsonArray);
sendRequest("http://192.168.178.49:5000/evaluatePost", jsonObject);
} catch (JSONException e) {
e.printStackTrace();
Log.d(TAG, "makePremixCall: " + e);
}
}
My problem with this: I would like to have a separate class, which offers the function makePremix(Premix premix) and other functions that I need.
The only solution that comes to my mind is implementing the requests synchronously in the separate class and call that separate class in an AsyncTask in the class I am working in.
Do I oversee something? Is there a way to create a separate class and still use the OkHttp enqueue method?
You could extract makePremix(Premix premix) in a separate class and make sendRequest() public (or maybe package-private depending on your use case).
public void sendRequest(String url, JSONObject json)
However since sendRequest is generic and can be used by any other makeAnotherCall() in some other class you would need to get back result of every requests. Hence you can extract the Callback out of sendRequest()
public void sendRequest(String url, JSONObject json, Callback callback)
Now your sendRequest will look like
private void sendRequest(String url, JSONObject json) {
Log.d(TAG, "sendRequest: Das Json: " + json);
// Authentication for the request to raspberry
OkHttpClient.Builder client = new OkHttpClient.Builder();
client.authenticator(new Authenticator() {
#Override
public Request authenticate(Route route, Response response) throws IOException {
String credential = Credentials.basic("username", "password");
return response.request().newBuilder()
.header("Authorization", credential)
.build();
}
});
// Sending out the request to the raspberry
OkHttpClient okHttpClient = client.build();
RequestBody body = RequestBody.create(null, new byte[]{});
if( json != null) {
body = RequestBody.create(MediaType.parse(
"application/json"),
json.toString()
);
}
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
okHttpClient.newCall(request).enqueue(callback);
}
Hope it makes sense!
Also as a side note, see that you are creating a new OkHttp Client every time you call sendRequest. You could probably optimise memory here by caching the client and reusing it.
all I need to send the notifications for an app which contains 2 firebase database. from one firebase database I am sending notifications to an app. But app is not receiving the notifications
i have the same problem but resolve using this code
implement this library
implementation 'com.squareup.okhttp3:okhttp:3.4.1'
static OkHttpClient mClient;
static JSONArray jsonArray;
static Context context;
static String messageStr = "";
public static void sendNotification(Context mContext,String mMessage,final JSONArray jsonArray1) {
mClient = new OkHttpClient();
context = mContext;
messageStr = mMessage;
jsonArray = jsonArray1;
new MyTask().execute();
}
static class MyTask extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... params) {
try {
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject root = new JSONObject();
JSONObject notification = new JSONObject();
notification.put("text", messageStr);
notification.put("title", "Cell Command");
notification.put("line1", R.mipmap.ic_launcher);
notification.put("line2", "high");
root.put("to", jsonArray.get(i));
root.put("data", notification);
String result = postToFCM(root.toString());
Log.d("Main Activity", "Result: " + result);
return result;
}
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(String result) {
if (result != null) {
try {
JSONObject resultJson = new JSONObject(result);
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(context, "" + e.toString(), Toast.LENGTH_SHORT).show();
}
}
}
}
static String postToFCM(String bodyString) throws IOException {
final String FCM_MESSAGE_URL = "https://fcm.googleapis.com/fcm/send";
final MediaType JSON
= MediaType.parse("application/json");
RequestBody body = RequestBody.create(JSON, bodyString);
Request request = new Request.Builder()
.url(FCM_MESSAGE_URL)
.post(body)
.addHeader("Authorization", "key=" + "put your firebase legacy key")
.build();
Response response = mClient.newCall(request).execute();
return response.body().string();
}
inside jsonarray put your device token
hope this will help you.
I am using okhttp library for Json parsing.
I have created my AsyncTask as below for my Login Webservice :
class LoginAsyncTask extends AsyncTask<Void, Void, Void> {
private ProgressDialog dialog;
private String mstrLoginResponse="";
#Override
protected void onPreExecute() {
super.onPreExecute();
try {
dialog = new ProgressDialog(SignInActivity.this);
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(android.graphics.Color.TRANSPARENT));
dialog.setCancelable(false);
if (!dialog.isShowing()) {
dialog.show();
}
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
protected Void doInBackground(Void... params) {
try {
RequestBody formBody = new FormEncodingBuilder()
.add("mobile_number", strPhone)
.add("password", strPassword)
.build();
mstrLoginResponse = HttpUtils.postRun("login", formBody);
Constant.displayLogE(">>>TT : ",""+mstrLoginResponse);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
if (dialog.isShowing()) {
dialog.dismiss();
}
if (mstrLoginResponse != null) {
try {
JSONObject jsonRegister = new JSONObject(mstrLoginResponse);
int strLoginStatus = jsonRegister.getInt("status");
String strMessage = jsonRegister.getString("message");
if (strLoginStatus == 1) {
JSONObject jsonUserId = jsonRegister.getJSONObject("data");
String strUserId = jsonUserId.getString("user_id");
AppSettings.setPref(SignInActivity.this, USER_ID, String.valueOf(strUserId));
startActivity(new Intent(SignInActivity.this, MainActivity.class));
finish();
Constant.displayToast(SignInActivity.this, "" + strMessage);
} else {
ApiUtils.showAlertDialogue(SignInActivity.this, "" + strMessage);
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
But, Unfortunetly getting below response :
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>404 Page Not Found</title>
<style type="text/css">
::selection { background-color: #E13300; color: white; }
::-moz-selection { background-color: #E13300; color: white; }
and Exeption : org.json.JSONException: Value <!DOCTYPE of type java.lang.String cannot be converted to JSONObject
06-24 00:41:03.314 349-349/com.roadysmart W/System.err: at org.json.JSON.typeMismatch(JSON.java:111)
I am getting proper response in Postman.
My HttpUtils class is as below : `
public class HttpUtils {
/*public static final MediaType JSON
= MediaType.parse("application/json; charset=utf-8");*/
public static String BASE_URL = "http://temp.in/projects/temp/";
public static OkHttpClient client = new OkHttpClient();
public static String getRun(String url) throws IOException {
Log.d("URL===>", url);
Request request = new Request.Builder()
.url(url)
.build();
Response response = client.newCall(request).execute();
return response.body().string();
}
public static String postRun(String type, RequestBody formBody) throws IOException {
String str = "";
Request request = new Request.Builder()
.url(BASE_URL)
.post(formBody)
.build();
Response response = client.newCall(request).execute();
return response.body().string();
}
}
What might be the mistake ? Please, Help .
===>>EDIT :
Getting Proper response in postman as below :
{
"status": 1,
"message": "Login successful",
"data": {
"name": "subhu",
"mobile_number": "7777777777",
"email": "bhargavmodi777#gmail.com",
"user_id": "20"
}
}
Your response - <title>404 Page Not Found</title> tells me that your endpoint doesn't exist because you entered it incorrectly or the server is simply not running.
That exception you posted relates to the same issue, it can't parse the JSON because what the web call received was not application/json and instead just raw HTML.
Exeption : org.json.JSONException: Value <!DOCTYPE of type java.lang.String cannot
With that said, public static String BASE_URL = "http://temp.in/projects/temp/"; looks like a bad URL. Here is what I recommend:
First manually load that URL in your browser, you will notice the same HTML your client call received, will be presented to you.
Make sure you are running your server/service or whatever it is that responds to your request. You say Postman works, what parameters did you use? What are you communicating with?
If PostMan works, and postman runs from your computer, your computer is connected to your local network I presume. Is your Android device on the local network as well? Or are you on cell service (3G/LTE). If you are then your endpoint can't be reached unless you are connected to a VPN or something.
I am building an android app that needs to log the user to our server and the connection needs to be secure (HTTPs). My question is, should I use OKHTTP library for this purpose?
I use the library to log a user as follows:
public class MainActivity extends AppCompatActivity {
public static final MediaType JSON
= MediaType.parse("application/json; charset=utf-8");
private static final String TAG = MainActivity.class.getSimpleName();
private JSONObject responseJson;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
final JSONObject myJson = new JSONObject();
try {
myJson.put("udid","c376e418-da42-39fb-0000-d821f1fd2804");
myJson.put("email","email
myJson.put("password","password");
} catch (JSONException e) {
e.printStackTrace();
}
Thread thread = new Thread(new Runnable(){
#Override
public void run() {
try {
//Your code goes here
String response = post("https://ADDRESS/v1/auth", myJson.toString());
responseJson = new JSONObject(response);
String message = responseJson.getString("message");
String token = responseJson.getString("token");
Log.d(TAG,"Response message: " + message);
Log.d(TAG,"Response token: " + token);
Log.d("MainActivity",response);
} catch (Exception e) {
e.printStackTrace();
}
}
});
thread.start();
}
String post(String url, String json) throws IOException {
OkHttpClient client = new OkHttpClient();
RequestBody body = RequestBody.create(JSON, json);
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
Response response = client.newCall(request).execute();
return response.body().string();
}
}
should I use OKHTTP library for this purpose?
OkHttp supports https URLs, as do most HTTP client libraries for Android.
I'm pulling my hair out trying to get this to work. I'm using OkHTTP to make a POST request to my server. However, every method I've tried of making a successful POST request with parameters, causes the server to go down, giving me a response of '503 service unavailable'. I use exterior clients to test the server, like the Advanced Rest Client extension, and it works perfectly fine.
The URL for the API is in the format of "https://mystuff-herokuapp.com/postuser" and my body parameters are "user_id", "userName", "email". I've tried adding headers to the request, changing from FormBodyEncoding() to MultiPartBuilder(), etc etc.
onCreate
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dashboard);
//set toolbar as the acting action bar
Toolbar actionToolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(actionToolbar);
getSupportActionBar().setDisplayShowTitleEnabled(false);
Intent intent = getIntent();
String photoUrl = intent.getStringExtra("photo");
String userTwitterID = intent.getStringExtra("userID");
String userName = intent.getStringExtra("name");
String userEmail = intent.getStringExtra("email");
JSONObject jObject = new JSONObject();
try {
jObject.put("user_id", userTwitterID);
jObject.put("userName", userName);
jObject.put("userEmail", userEmail);
} catch (JSONException e) {
e.printStackTrace();
}
new UserApiProcess().execute(jObject);
}
Async Task
private class UserApiProcess extends AsyncTask<Object, Void, Void>{
#Override
protected Void doInBackground(Object... strings) {
OkHttpClient client = new OkHttpClient();
RequestBody formBody = new MultipartBuilder()
.addFormDataPart("user_id", "800")
.addFormDataPart("userName", "Nick")
.addFormDataPart("email", "something#something.com")
.build();
Request request = new Request.Builder()
.url("https://mystuff.herokuapp.com/postuser")
.addHeader("Content-Type", "x-www-form-urlencoded")
.post(formBody)
.build();
Response response = null;
try {
response = client.newCall(request).execute();
if(!response.isSuccessful()) throw new IOException("Unexpected code " + response);
System.out.println(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
Successful Response from Advanced Rest Client
My Server Error through Android
Try this. It should work.
private class UserApiProcess extends AsyncTask<Object, Void, Void>{
#Override
protected Void doInBackground(Object... strings) {
OkHttpClient client = new OkHttpClient();
RequestBody formBody = new FormEncodinBuilder()
.add("user_id", "800")
.add("userName", "Nick")
.add("email", "something#something.com")
.build();
Request request = new Request.Builder()
.url("https://mystuff.herokuapp.com/postuser")
.addHeader("Content-Type", "x-www-form-urlencoded")
.post(formBody)
.build();
Response response = null;
try {
response = client.newCall(request).execute();
if(!response.isSuccessful()) throw new IOException("Unexpected code " + response);
System.out.println(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}