Try is working properly but catch is given error - android

Hey guys i am working in an app and i am verify my mobile number through OTP when i am send OTP to verify there is error mobile is verify but catch block is given error and Activity not going to next Acivity and not log is showing
private void verifyOtp(final String otp){
final StringRequest strReq = new StringRequest(Request.Method.POST,
config.Config.URL_VERIFY_OTP, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d(TAG, response.toString());
try {
JSONObject responseObj = new JSONObject(response);
// Parsing json object response
// response will be a json object
boolean status =responseObj.getBoolean("status");
if (status==true) {
// parsing the user profile information
JSONObject profileObj = responseObj.getJSONObject(response);
String mobile = profileObj.getString("mobile");
PrefManager pref = new PrefManager(getApplicationContext());
pref.createLogin(mobile);
Intent intent = new Intent(HttpService.this, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
Toast.makeText(getApplicationContext(), "HTTPIF"+status, Toast.LENGTH_LONG).show();
} else {
Toast.makeText(getApplicationContext(), "HTTPELSE"+status, Toast.LENGTH_LONG).show();
}
} catch (JSONException e) { //------this is working and give toast----//
System.out.print("jsonError :=>"+e);
Toast.makeText(getApplicationContext(),
"Error is WWW: " + e.getMessage(),
Toast.LENGTH_LONG).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "HTTPError: " + error.getMessage());
Toast.makeText(getApplicationContext(),
error.getMessage(), Toast.LENGTH_SHORT).show();
}
}) {
MyApplication userinfo = (MyApplication)getApplicationContext();
final String user = userinfo.getuser(); // Global Variable get Value uID
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("akey","xxxxxxxxxx");
params.put("mobileverify", otp);
params.put("uid",user);
Log.e(TAG, "Posting params: " + params.toString());
return params;
}
};
MyApplication.getInstance().addToRequestQueue(strReq);
}

String mobile = profileObj.getString("mobile");
You may get no String but a null.

You are getting a JSONException. This may be due to many reasons and you will find them here: http://developer.android.com/reference/org/json/JSONException.html
The reason for this is, you are using a StringRequest. That means, the response is a plain String and not a JSON response. Just print out the reponse and see for yourself that it's not a valid JSON. What you need to use instead is a JSONRequest, or handle the String reponse as it is, instead of json parsing.
UPDATE:
Your problem might be because of either of the two lines below, since both of them can throw JSONException: getJSONObject() , getString()
JSONObject profileObj = responseObj.getJSONObject(response);
String mobile = profileObj.getString("mobile");
You say your JSON response is {"msg":"verified","status":true}. Then how are you trying to fetch profileObj or the value for mobile ? If the value is not found for the key, it will throw JSONException. To avoid this, you need check if the value for the key exists. Use has(String key) to confirm a mapping for the key exists, before fetching it.

Related

Volley POST request not working on Android after updating PHP backend to Slim 4

I have a sign in script for our Android app. It uses Volley 1.1.1 and has worked fine for year but after switching our PHP backend from Slim 3 to Slim 4, it's no longer working.
public Map<String,String> loginUser(String uemail, String upassword, final AuthAsyncResponse callBack) {
String url = "https://myendpoint.com/auth/signin";
Map<String,String> userData = new HashMap<>();
final HashMap<String, String> postParams = new HashMap<String, String>();
Log.d(TAG, "login status uemail: " + uemail);
Log.d(TAG, "login status upassword: " + upassword);
postParams.put("email", uemail);
postParams.put("password", upassword);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(
Request.Method.POST,
url,
new JSONObject(postParams),
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
Log.d(TAG, "onResponse: response");
// ... sign in tasks
// ... build a user data object
} catch (JSONException e) {
e.printStackTrace();
Log.d(TAG, "login status: ", e);
}
Log.d(TAG, "failed ");
if (null != callBack) callBack.processFinished(userData);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("LOG", "login status onErrorResponse: " + error);
}
}
)
{
#Override
public String getBodyContentType() {
return "application/json; charset=utf-8";
}
};
AppController.getInstance().getRequestQueue().getCache().clear();
AppController.getInstance().addToRequestQueue(jsonObjectRequest);
return userData;
}
I am able to log the initial uemail and upassword variables, which tells me the function is running. However, once I call new JsonObjectRequest, nothing happens. I don't get any of the log messages I put in the try catch block or in the error listener. I also don't get any run time errors.
If I change the endpoint to a site running Slim 3, the script works, however with Slim 4 it doesn't.
I have tried the endpoint with Postman and I'm able to get a response with the necessary data back.
GET requests seem to be working fine.
What could have changed so that the script stopped working all of a sudden?
According to this page: https://akrabat.com/receiving-input-into-a-slim-4-application/
I needed to add this line
$app->addBodyParsingMiddleware();
to my Slim app.

Android does not Toast after successful POST

I am sending data from an android client to a grails backend. I want two things to happen when data is successfully posted:
A toast with some of the params I have posted(In this case I want
only name)
An intent to open another activity.
However with my code, the parameters are posted successfully to the db but the toast and the intent do not happen.
Here is my code:
*/
private void registerUser(final String chname, final String chdesc, final String patientID) {
// Tag used to cancel the request
String tag_string_req = "req_register";
pDialog.setMessage("Registering ...");
showDialog();
StringRequest strReq = new StringRequest(Method.POST,
Configs.URL_LOGIN, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d(TAG, "Register Response: " + response.toString());
hideDialog();
try {
JSONObject jObj = new JSONObject(response);
boolean error = jObj.getBoolean("error");
if (!error) {
// User successfully stored in MySQL
// Now store the user in sqlite
String uid = jObj.getString("uid");
JSONObject user = jObj.getJSONObject("user");
String chname = user.getString("name");
String chdesc = user.getString("description");
String patientID = user.getString("patient");
Toast.makeText(getApplicationContext(), "User successfully registered.", Toast.LENGTH_LONG).show();
// Launch login activity
Intent intent = new Intent(AddChronics.this,
ChronicsFragment.class);
startActivity(intent);
finish();
} else {
// Error occurred in registration. Get the error
// message
String errorMsg = jObj.getString("error_msg");
Toast.makeText(getApplicationContext(),
errorMsg, Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "Registration Error: " + error.getMessage());
Toast.makeText(getApplicationContext(),
error.getMessage(), Toast.LENGTH_LONG).show();
hideDialog();
}
}) {
#Override
protected Map<String, String> getParams() {
// Posting params to activity_register url
Map<String, String> params = new HashMap<String, String>();
params.put("name", chname);
params.put("description", chdesc);
params.put("patient", patientID);
params.put("action", "chronicAdd");
return params;
}
};
AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
}
Note: The API works just fine. I have checked and the params are successfully saved to the db.
Your code looks fine, the only thing that might prevent the intent and toast from happening is if your code gets cought by an excepetion here:
catch (JSONException e) {
e.printStackTrace();
}
Caused by one of these guys:
String uid = jObj.getString("uid");
JSONObject user = jObj.getJSONObject("user");
Did you check that?
Have you tried using activity context instead of applicationContext?

Using Volley Library in android in a structured pattern

I am using Volley to make network calls in my application... For many screens ...(say fragments) I am making various requests like LoginRequest, FetchUsers Request, FetchExams Request..... and handling response and errors in each fragments.
What is the best approach I can use like....
1. Subclass a request
2. Create an interface/callbacks
3. Get results/response or error response in my fragment...
This is how I am doing ....creating many such methods.....
private void syncAllUsers() {
progressDialog.setMessage("Loading Users...");
StringRequest jsonProductCategoryFetchRequest = new StringRequest(Request.Method.POST, Config.SELECT_USERS,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
if(Constants.DEBUG_MODE_ON)
Log.d(Constants.DEBUG_LOG, "RESPONSE for Teachers: "+response);
JSONObject result = new JSONObject(response);
boolean code = result.getBoolean("error");
if (!code) {
//Get the Users Json Array
JSONArray ja = result.getJSONArray("users");
if(ja != null) {
db.deleteAllUsers();
for (int i = 0; i < ja.length(); i++) {
JSONObject jobj = ja.getJSONObject(i);
User user = new User();
user.setId(jobj.getInt(User.KEY_ID));
user.setName(jobj.getString(User.KEY_NAME));
user.setEmail(jobj.getString(User.KEY_EMAIL));
user.setPhone(jobj.getString(User.KEY_PHONE));
user.setGender(jobj.getString(User.KEY_GENDER));
user.setUsername(jobj.getString(User.KEY_USERNAME));
user.setPassword(jobj.getString(User.KEY_PASSWORD));
user.setOrganization_id(jobj.getString(User.KEY_ORGANIZATION_ID));
user.setDob(jobj.getString(User.KEY_DOB));
user.setStatus(jobj.getString(User.KEY_STATUS));
user.setApi_key(jobj.getString(User.KEY_API_KEY));
user.setDate_created(jobj.getString(User.KEY_DATE_CREATED));
user.setRole_id(jobj.getInt(User.KEY_ROLE_ID));
//Delete local Teachers before updating
db.createUser(user);
} // for loop ends
}
}
//syncAllExams();
progressDialog.dismiss();
getActivity().finish();
startActivity(new Intent(getActivity(), MainActivity.class));
} catch (Exception e) {
Log.d(Constants.DEBUG_LOG, "Exception Syncing Users: " , e);
Toast.makeText(getActivity(),"Something went wrong while fetching users", Toast.LENGTH_SHORT).show();
progressDialog.dismiss();
getActivity().finish();
startActivity(new Intent(getActivity(), MainActivity.class));
}
}
} , new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
if(Constants.DEBUG_MODE_ON)
Log.d(Constants.DEBUG_LOG, "Error Response for Users : "+error.getCause()+""+error.toString());
Toast.makeText(getActivity(), getString(R.string.no_internet), Toast.LENGTH_SHORT).show();
progressDialog.dismiss();
getActivity().finish();
startActivity(new Intent(getActivity(), MainActivity.class));
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put(User.KEY_ORGANIZATION_ID, preferencesManager.getOrganizationID());
params.put(User.KEY_API_KEY, preferencesManager.getApiKey());
Log.d("Registration", "PARAMS : " + params.entrySet());
return params;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
HashMap<String, String> params = new HashMap<String, String>();
// params.put("Content-Type", "application/json; charset=utf-8");
params.put("Content-Type", "application/x-www-form-urlencoded");
String auth = preferencesManager.getApiKey();
params.put("Authorization", auth);
return params;
}
};
MyApplication.getInstance().addToReqQueue(jsonProductCategoryFetchRequest);
}
I think there would be a clean way to perform this. Any suggestions.
I have been using this class for creating requests, it transforms your json into your object automaticaly with gson. Find example here:
https://gist.github.com/ficusk/5474673
Create Request Manager.. Which is only dealing with Requesting your web services. That Manager should also handle any network error and other errors which are not application layer.
Use this request manager from your Model classes where your business logic is. Send Request Parameter as JSON.. Also you can send your different listeners from to Request Manager So that when web service response comes it directly comes to you Model class and you can parse JSON response according to your needs.
This way parsing logic stays with Model class and Requesting logic stays with Request manager.. So in future if you change web service address you need to check only one place.. And if you change request and response parameter for webservice you dont need to change request manager and only Model class...
There might be some other ways..
public final class RequestManager {
private static final String ROOT_HOST = //Your Webservice Host Root.
private RequestQueue queue;
public RequestManager(final Context context) {
queue = Volley.newRequestQueue(context);
}
//Internal Calling method .. Not exposed..
private void doRequest(final int method, final String url, final JSONObject jsonParam, final Response.Listener<JSONObject> listener,
final Response.ErrorListener errlsn) {
JSONObjectRequest jsonObjectRequest = new SONObjectRequest(method, url, jsonParam, listener, errlsn);
queue.add(jsonObjectRequest);
}
public void doLogin(final User user, final Response.Listener<JSONObject> listener, final Response.ErrorListener errlsn)
throws Exception {
// Make login request JSON here
if (user == null || listener == null || errlsn == null) {
//throw Exception
}
final JSONObject jsonObj = new JSONObject();
//Convert user object to JSON Object
doRequest(Request.Method.GET, LOGIN_URL, jsonObj, listener, errlsn);
}
}

Android: Posting a POST or JSON request to server without all the deprecated functions

I'm in the process of developing an Android app, which uses HTTP POST to send login data to a server. This all worked fine, until both the HTTPClient and the NameValuePair libraries were deprecated in recent updates.
I've Google'd a lot for new methods, and I know I should use Http(s)URLConnection for connecting to a server, but I can't get it to work properly and the Google Developers site doesn't provide an example either. I did use this piece of code but it won't work, throwing all sorts of syntax errors (missing ;'s and such).
Is there anyone who can provide an example of a working HTTP(s) request? Both POST and JSON are fine, as I can easily adjust the PHP code to receive JSON objects. Thanks in advance!
Use volley. Here is a scratch for you how to use it.
StringRequest strReq = new StringRequest(Request.Method.POST,
<url>, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d(TAG, response.toString());
try {
//whatever format from response,do here...for eg:
JSONObject responseObj = new JSONObject(response);
//do parsing here after posting and response..
}
} catch (JSONException e) {
Toast.makeText(getApplicationContext(),
"Error: " + e.getMessage(),
Toast.LENGTH_LONG).show();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "Error: " + error.getMessage());
Toast.makeText(getApplicationContext(),
error.getMessage(), Toast.LENGTH_SHORT).show();
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("name", editText.getText().toString());
Log.e(TAG, "Posting params: " + params.toString());
return params;
}
};

Android - Volley request parameters not included in request?

I have a JSONObjectRequest I'm trying to send to my Rails app via Volley. I'm hitting my Rails API, but am getting 401 responses. My API definitely works via curl, so I think I haven't formed my Volley request quite right.
public void login(View button) {
EditText userEmailField = (EditText) findViewById(R.id.userEmail);
mUserEmail = userEmailField.getText().toString();
EditText userPasswordField = (EditText) findViewById(R.id.userPassword);
mUserPassword = userPasswordField.getText().toString();
if (mUserEmail.length() == 0 || mUserPassword.length() == 0) {
// input fields are empty
Toast.makeText(this, "Please complete all the fields",
Toast.LENGTH_LONG).show();
return;
} else {
JsonObjectRequest loginRequest = new JsonObjectRequest(Request.Method.POST, url, null,
new Response.Listener<JSONObject>() {
#Override public void onResponse(JSONObject response) {
try {
//everything is good
if (response.getBoolean("success")) {
SharedPreferences.Editor editor = mPreferences.edit();
//Save auth_token into shared preferences
editor.putString("AuthToken", response.getJSONObject("data").getString("auth_token"));
editor.commit();
// launch the HomeActivity and close this one
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
startActivity(intent);
finish();
}
} catch (Exception e) {
// something went wrong: show Toast
//with the exception message
Toast.makeText(myActivity, e.getMessage(), Toast.LENGTH_LONG).show();
}
}
},
new Response.ErrorListener()
{
#Override public void onErrorResponse(VolleyError error) {
Log.d("Error.Response", error.toString());
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("email", mUserEmail);
params.put("password", mUserPassword);
return params;
}
};
VolleySingleton.getInstance(this).addToRequestQueue(loginRequest); //Call to get dashboard feed
}
};
EDIT
Rails log with 401: It appears that my params aren't being included with the request. What did I do wrong in the Volley request that it wouldn't be included?
Started POST "/api/v1/sessions" for 11.111.111.11 at ....
Processing by Api::V1::SessionsController#create as JSON
Parameters: {"session"=>{}}
Completed 401 Unauthorized in 2ms
Thanks to #jamesw for pointing me in the right direction here. For some reason, getParams is not being called in this POST Request. I'm not sure why, but apparently other people have had the same issue.
A workaround is to create a JSONObject and pass it into the JsonObjectRequest:
JSONObject parentData = new JSONObject();
JSONObject childData = new JSONObject();
try {
childData.put("email", mUserEmail);
childData.put("password", mUserPassword);
parentData.put("user", childData);
} catch (JSONException e) {
e.printStackTrace();
}
Pass it into the JOR constructor:
JsonObjectRequest loginRequest = new JsonObjectRequest(Request.Method.POST, url, parentData, Listener..., ErrorListener...
Works for me, but if someone can explain how to call getParams() or a cleaner solution, feel free to answer and I'll accept.

Categories

Resources