I have got a JSON response from an API that I have converted to a string and trying to compare it for true or false value,
On the log cat I can see the result:
{
"message": "success",
"status": "Auth_Successful",
"response": "Authentication successful"
}
I am trying fit it into an if statement like below
I have tried most of the comparison methods(==, .equals(), .compareTo()) but not getting any result
Can anyone let me know what is the correct way to approach it as I am still new to Java and Android. I have seen a lot of similar posts but unable to figure out.
Thank you very much for your time and assistance in this matter.
package com.example.shiben.fabapp;
public class MainActivity extends AppCompatActivity {
private Request request;
private static final String Tag = MainActivity.class.getName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button LoginButton = (Button) findViewById(R.id.loginButton);
EditText userName = (EditText) findViewById(R.id.userName);
EditText userPassword = (EditText) findViewById(R.id.userPassword);
final TextView displayTest = (TextView) findViewById(R.id.displayTest);
LoginButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
OkHttpClient client = new OkHttpClient();
MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
RequestBody body = RequestBody.create(mediaType, "username=xxxxxxxxx&password=xxxxxxxxx");
Request request = new Request.Builder()
.url("http://9.xxx.xxx.xxx/test/xxxxx_api.aspx")
.post(body)
.addHeader("cache-control", "no-cache")
.addHeader("content-type", "application/json")
.build();
//execute the request
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
Log.i(Tag, e.getMessage());
}
#Override
public void onResponse(Call call, Response response) throws IOException {
Log.i(Tag, response.body().string());
String result = response.body().toString();
//if (result==("{\"message\":\"success\",\"status\":\"Auth_Successful\",\"response\":\"Authentication successful\"}")){
if (result.compareTo("{\"message\":\"success\",\"status\":\"Auth_Successful\",\"response\":\"Authentication successful\"}")==0) {
//if (result.equals("{\"message\":\"success\",\"status\":\"Auth_Successful\",\"response\":\"Authentication successful\"}")) {
TastyToast.makeText(MainActivity.this, "String Comparison Success", TastyToast.LENGTH_LONG, TastyToast.SUCCESS);
}
}
});
}
});
}
}
You should parse the JSON string and compare the message.
if (message.equals("success"))
If you don't like to parse, you may try this one (Bad practice):
if(response.contains("success"))
String result = response.body().toString(); doesn't work. Please use string() method instead of toString()
#Override
public void onResponse(Response response) throws IOException {
if (response.isSuccessful()) {
doSomething(response.body().string());
}
}
private void doSomething(String response) {
}
Try this in your code .
String result = response.body().toString();
if(TextUtils.isEmpty(result)){
Toast.makeText(this, "result is null", Toast.LENGTH_SHORT).show();
return;
}
try {
JSONObject jsonObject = new JSONObject(result);
String message = jsonObject.optString("message");
String status = jsonObject.optString("status");
String response = jsonObject.optString("response");
if (TextUtils.equals("success", message)) {
TastyToast.makeText(MainActivity.this, "String Comparison Success", TastyToast.LENGTH_LONG, TastyToast.SUCCESS);
}
} catch (JSONException e) {
e.printStackTrace();
}
The problem is related with OkHttp
This is because when you called the following:
Log.i(Tag, response.body().string());
String result = response.body().toString();
String result will be empty because you've already called response.body() in Log. When you called it, it will be emptied.
So, you need to save it to the result before calling it from the log. Something like this:
String result = response.body().toString();
Log.i(Tag, result);
Here from the documentation:
The response body can be consumed only once.
This class may be used to stream very large responses. For example, it
is possible to use this class to read a response that is larger than
the entire memory allocated to the current process. It can even stream
a response larger than the total storage on the current device, which
is a common requirement for video streaming applications.
Because this class does not buffer the full response in memory, the
application may not re-read the bytes of the response. Use this one
shot to read the entire response into memory with bytes() or string().
Or stream the response with either source(), byteStream(), or
charStream().
I used volley instead of okhttp and got it sorted ,
Below is the code
public class MainActivity extends AppCompatActivity {
private static final String TAG = MainActivity.class.getName();
private Button btnSendRequest;
private RequestQueue mRequestQueue;
//creating a string request
private StringRequest stringRequest;
private String url = "http://9.xxx.xxx.xxx/test/xxxxxxx.aspx";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnSendRequest = (Button) findViewById(R.id.loginBtn);
btnSendRequest.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//on click of the button send request and print the response
//initializing request queue and string request in sendRequestAndPrintResponse
sendRequestAndPrintResponse();
}
});
}
private void sendRequestAndPrintResponse() {
mRequestQueue = Volley.newRequestQueue(this);
stringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.i(TAG, "Success" + response.toString());
String result = response.toString();
TextView displayText = (TextView) findViewById(R.id.displayText);
displayText.setText(result);
if (result.equalsIgnoreCase("{\"message\":\"success\",\"status\":\"Auth_Successful\",\"response\":\"Authentication successful\"}")){
Toast.makeText(getApplicationContext(), "comparison successful", Toast.LENGTH_LONG).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.i(TAG, error.toString());
}
}){
#Override
protected Map<String, String> getParams()
{
Map<String, String> params = new HashMap<String, String>();
params.put("username", "someone#example.com");
params.put("password", "myPassword");
return params;
}
};
mRequestQueue.add(stringRequest);
}
}
If anyone could let me know what went wrong with okhttp, it would be very helpful for future reference.
Related
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
RequestQueue requestQueue;
requestQueue = Volley.newRequestQueue(this);
List<news_Objects> newsList = new ArrayList<>();
//url for News API
String url="https://newsapi.org/v2/everything?q=apple&from=2021-08-31&to=2021-08-31&sortBy=popularity&apiKey=ca3d6c89eff24db2a8ef78868f0af555";
//making json object request
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jsonArr = response.getJSONArray("articles");
for (int i = 0; i < jsonArr.length(); i++) {
JSONObject newsDetail = jsonArr.getJSONObject(i);
//class name news_Objects created
news_Objects news = new news_Objects();
String imtUrl = newsDetail.getString("urlToImage");
String title = newsDetail.getString("title");
String detail = newsDetail.getString("description");
String newsUrl = newsDetail.getString("url");
String content = newsDetail.getString("content");
news.setNewsImageUrl(imtUrl);
news.setNewsTitle(title);
news.setNewsDetail(detail);
news.setNewsUrl(newsUrl);
news.setContent(content);
newsList.add(news);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("fine", "Something Wrong"+error);
Toast.makeText(MainActivity.this, "Something Wrong "+error, Toast.LENGTH_SHORT).show();
error.printStackTrace();
}
});
requestQueue.add(request);
}
}
Your API Key is Invalid please check your API key. Getting this response:
{"status":"error","code":"apiKeyInvalid","message":"Your API key is invalid or incorrect. Check your key, or go to https://newsapi.org to create a free API key."}
Maybe Your API key is not live, please check your API key status than again hit the api.
MainActivity:
RequestQueue requestQueue;
String url = "http://andriodtest.eb2a.com/show.php";
TextView textView;
ListView listView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) findViewById(R.id.TextView);
requestQueue = Volley.newRequestQueue(this);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Toast.makeText(MainActivity.this, response.toString(), Toast.LENGTH_LONG).show();
try {
JSONArray jsonArray = response.getJSONArray("users");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject respons = jsonArray.getJSONObject(i);
String id = respons.getString("id");
String info = respons.getString("name");
textView.append(id);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("VOLLEY", "ERROR");
}
}
);
requestQueue.add(jsonObjectRequest);
When run app no data called
And file config is work 100%.
example
And if set Textview= "text" not work.
I think the problem is public void onResponse.
Please help me important
Your code seems fine, however it looks like your server's response is not returning a json object but instead a javascript file for setting a cookie (you can try hitting your url with Postman to look at the javascript response I'm mentioning).
Volley expects to receive a json response and that may be the reason why your app is currently not working as expected.
I would probably try to change the way the server responds. The following link has some suggestions in order to solve that issue:
Why I can't retrieve data from my webserver as json but i can when i test it on localhost
I am trying to save my data to server. can any one help me?
when i am trying to save data through browser it is working fine but when i try it through this code doesn'n give any response??
public class Register extends AppCompatActivity implements View.OnClickListener {
private static final String TAG = "dRegister";
EditText etName, etEmail, etMobile, etPassword, /*etRePassword*/
etCity;
Button register;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
etName = (EditText) findViewById(R.id.name);
etEmail = (EditText) findViewById(R.id.email);
etMobile = (EditText) findViewById(R.id.mobile);
etCity = (EditText) findViewById(R.id.etCity);
etPassword = (EditText) findViewById(R.id.password);
//etRePassword = (EditText) findViewById(R.id.rePassword);
register = (Button) findViewById(R.id.bRegister);
register.setOnClickListener(this);
}
#Override
public void onClick(View v) {
final String name = etName.getText().toString();
final String email = etEmail.getText().toString();
final String password = etPassword.getText().toString();
final String city = etCity.getText().toString();
final String phoneno = etMobile.getText().toString();
StringRequest registerRequest = new StringRequest(Request.Method.POST,RegisterRequest.REGISTER_REQUEST_URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d(TAG, response + " Response");
if(response.equals("SUCCESS")){
startActivity(new Intent(Register.this,MainActivity.class));
}
else{
Toast.makeText(Register.this, "You have not Registered!", Toast.LENGTH_SHORT).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d(TAG, "Error " + error.toString());
if(error.networkResponse == null){
if(error.getClass().equals(TimeoutError.class));
Toast.makeText(Register.this, "oops Time out error!", Toast.LENGTH_SHORT).show();
}
}
}){
#Override
public Map<String, String> getHeaders()throws AuthFailureError{
Map<String, String> headers = new HashMap<>();
headers.put("name",name);
headers.put("email",email);
headers.put("password",password);
headers.put("city",city);
headers.put("phoneno",phoneno);
return headers;
}
};
registerRequest.setRetryPolicy(new DefaultRetryPolicy(1000 * 15,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
/*Response.Listener<String> responseListener = new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d(TAG, response + "");
try {
JSONObject jsonResponse = new JSONObject(response);
boolean success = jsonResponse.getBoolean("success");
if (success) {
Intent intent = new Intent(Register.this, MainActivity.class);
startActivity(intent);
} else {
AlertDialog.Builder builder = new AlertDialog.Builder(Register.this);
builder.setMessage("Registration failed").setNegativeButton("Retry", null)
.create().show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
};
RegisterRequest registerRequest = new RegisterRequest(name, email, city, phoneno, password, responseListener){
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
//super.getHeaders();
Map<String,String> headers = new HashMap<>();
String credential = "raju#gmail.com:123";
String auth = "Basic "+ Base64.encodeToString(credential.getBytes(),Base64.NO_WRAP);
//headers.put("Content-Type");
headers.put("Authorization",auth);
//
return headers;
}
};*/
RequestQueue queue = Volley.newRequestQueue(Register.this);
registerRequest.setShouldCache(false);
queue.add(registerRequest);
}
}
Here Is my server code....
#RequestMapping(value = "/savemobileUser", method = RequestMethod.POST)
public #ResponseBody String saveUser(#RequestBody MobileUserModel mobileUser) {
MobileUserModel user = new MobileUserModel();
user.setActivationKey(mobileUser.getActivationKey());
user.setCity(mobileUser.getCity());
user.setEmail(mobileUser.getEmail());
user.setImeino(mobileUser.getImeino());
user.setName(mobileUser.getName());
user.setPassword(mobileUser.getPassword());
user.setPhoneno(mobileUser.getPhoneno());
userrepository.save(user);
System.out.println("Saved");
// return "User has been saved Successfully";
return "SUCCESS";
}
Put following inside your onClick method:
switch (v.getId()) {
case R.id.bRegister:
// add your registration process code here
break;
}
Make Sure you have given Internet permissions in your manifest.
<uses-permission android:name="android.permission.INTERNET" />
Please provide your json response format and also the parameter type that you are sending. It may occur due to different reasons, for example, there is an json array in response and you are mapping it just in simple object or the attributes (variable) that you are mapping into it, names are not exactly similar to json response filed or there can be different multiple reasons.
I have an android activity that executes an Asynchronous Okhttp call, when the activity is loaded ( called from the onStart method as getActiveRequests()).
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
Button btLogout;
UserLocalStore userLocalStore;
String username;
String userEmail;
String recentAppName;
String recentRequestTime;
String isExpired;
TelephonyManager telephonyManager;
OkHttpClient client;
TextView tvRecentAppName, tvRecentRequestTime, tvIsExpired;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
userLocalStore = new UserLocalStore(this);
telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
TextView tvUserName = (TextView) findViewById(R.id.userName);
TextView tvUserEmail = (TextView) findViewById(R.id.userEmail);
tvRecentAppName = (TextView) findViewById(R.id.recentAppName);
tvRecentRequestTime = (TextView) findViewById(R.id.recentRequestTime);
tvIsExpired = (TextView) findViewById(R.id.isExpired);
client = new OkHttpClient();
username = userLocalStore.getLoggedInUser().name;
userEmail = userLocalStore.getLoggedInUser().email;
tvUserEmail.setText(userEmail);
tvUserName.setText(username);
btLogout = (Button) findViewById(R.id.btLogout);
btLogout.setOnClickListener(this);
}
#Override
protected void onStart() {
super.onStart();
if(authenticateUser() == true){
getActiveRequests();
}else{
startActivity(new Intent(this, LoginActivity.class));
}
}
What I want to do Is update the UI once the Http call has been made using the SetText methods. Here is my call, implemented in the GetActiveRequests() method.
client.newCall(request)
.enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
String hello = "failed call";
}
#Override
public void onResponse(Call call, Response response) throws IOException {
final String responseData = response.body().string();
if (responseData != null) {
Gson gson = new Gson();
JsonElement element = gson.fromJson(responseData, JsonElement.class);
JsonObject jsonObject = element.getAsJsonObject();
final AccessRequest request = gson.fromJson(jsonObject, AccessRequest.class);
recentAppName = request.AppName.toString();
recentRequestTime = request.RequestTime.toString();
if (request.IsExpired)
isExpired = "Has Expired";
else isExpired = "Active";
tvRecentAppName.setText(recentAppName);
tvRecentRequestTime.setText(recentRequestTime);
tvIsExpired.setText(isExpired);
}
}
});
The problem I am having is that when the debugger reaches the SetText lines of code, it is causing the app to crash and close. I am at a loss as to how I can solve this but I assume it has something to with the Okhttp Async call not being able to update the UI, as my setText methods are working fine in onCreate().
That's because views' updates can only be done on UI thread and OkHttp's onResponse runs on background thread. Try to run that on main thread like this:
#Override
public void onResponse(Call call, Response response) throws IOException {
final String responseData = response.body().string();
if (responseData != null) {
Gson gson = new Gson();
JsonElement element = gson.fromJson(responseData, JsonElement.class);
JsonObject jsonObject = element.getAsJsonObject();
final AccessRequest request = gson.fromJson(jsonObject, AccessRequest.class);
recentAppName = request.AppName.toString();
recentRequestTime = request.RequestTime.toString();
if (request.IsExpired)
isExpired = "Has Expired";
else isExpired = "Active";
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
//Handle UI here
tvRecentAppName.setText(recentAppName);
tvRecentRequestTime.setText(recentRequestTime);
tvIsExpired.setText(isExpired);
}
});
}
}
Similarly if you have update any views on onFailure, do it on UI thread.
I'm retrieving the content of a invalid web address with volley, i.e. http://www.gigd32fdsu.com:
This is my test code:
// Instantiate the RequestQueue.
RequestQueue queue = Volley.newRequestQueue(this);
final String url = "http://www.gigd32fdsu.com";
// Request a string response from the provided URL.
StringRequest stringRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener() {
#Override
public void onResponse(Object response) {
// Display the first 500 characters of the response string.
mTextView.setText("Response is: " + response.toString().substring(0, 500));
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
mTextView.setText("That didn't work! " + error.networkResponse.statusCode);
}
});
// Add the request to the RequestQueue.
queue.add(stringRequest);
When I run this code I receive the callback onResponse(String) with an error page from my ISP. How can I read the HTTP status code in order to detect that the web displaying is not correct?
Thanks
Simple solution is to override parseNetworkResponse in makeStringReq(), no need for another class:
private void makeStringReq() {
showProgressDialog();
StringRequest strReq = new StringRequest(Method.GET,
Const.URL_STRING_REQ,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d(TAG, response.toString());
msgResponse.setText(response.toString());
hideProgressDialog();
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d(TAG, "Error: " + error.getMessage());
hideProgressDialog();
}
}) {
#Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
int mStatusCode = response.statusCode;
return super.parseNetworkResponse(response);
}
};
// Adding request to request queue
AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
}
I will make the response from VinceStyling more complete. I'll tell you what I do.
Once you override this method, save the statusCode in your class.
#Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
statusCode=response.statusCode;
return super.parseNetworkResponse(response);
}
After that you should compare it with HttpURLConnection constants to act accordingly. For example:
int statusCode=webService.getStatusCode();
switch (statusCode){
case HttpURLConnection.HTTP_OK:
//do stuff
break;
case HttpURLConnection.HTTP_NOT_FOUND:
//do stuff
break;
case HttpURLConnection.HTTP_INTERNAL_ERROR:
//do stuff
break;
}
Just override the parseNetworkResponse method then take the statusCode value.
public class StrImplRequest extends StringRequest {
#Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
// take the statusCode here.
response.statusCode;
return super.parseNetworkResponse(response);
}
}
#VinceStyling 's answer is ok,
or you can extend Request class and do what you wanna do.
For example,
ServerStatusRequestObject extends Request {
private final Response.Listener mListener;
private String mBody = "";
private String mContentType;
public ServerStatusRequestObject(int method,
String url,
Response.Listener listener,
Response.ErrorListener errorListener) {
super(method, url, errorListener);
mListener = listener;
mContentType = "application/json";
if (method == Method.POST) {
RetryPolicy policy = new DefaultRetryPolicy(5000, 0, 5);
setRetryPolicy(policy);
}
}
#Override
protected Response parseNetworkResponse(NetworkResponse response) {
return Response.success(response.statusCode, HttpHeaderParser.parseCacheHeaders(response));
}
#Override
protected void deliverResponse(Object response) {
if (mListener != null) {
mListener.onResponse(response);
}
}
#Override
public byte[] getBody() throws AuthFailureError {
return mBody.getBytes();
}
#Override
public String getBodyContentType() {
return mContentType;
}
#Override
public int compareTo(Object another) {
return 0;
}
then in your response handler, you can still receive the whole messages from server.
Try it.