org.json.JSONException: Expected literal value at character 0 - java

When i register it stores the data but doenot show any messages.
Here is my register.java
private void registerUser(final String name, final String email,
final String password,final String phoneNumber,final String UserType) {
// Tag used to cancel the request
String tag_string_req = "req_register";
pDialog.setMessage("Registering ...");
showDialog();
Log.d(TAG, "it is done!");
// (It says error on this line:)
StringRequest strReq = new StringRequest(Method.POST, AppConfig.URL_REGISTER, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d(TAG, "Register Response: " + response.toString());
hideDialog();
Log.d(TAG, "user added");
try {
JSONObject jObj = new JSONObject(response.substring(14));
boolean error = jObj.getBoolean("error");
Log.d(TAG, "Register Response-error: " + error);
Please help me

This error occurs as a result of response.substring(14) code part providing an invalid json.
I would use this code to converst String to Standard Json.
public String convertToStandardJSONString(String data_json) {
data_json = data_json.replaceAll("\\\\r\\\\n", "");
data_json = data_json.replace("\"{", "{");
data_json = data_json.replace("}\",", "},");
data_json = data_json.replace("}\"", "}");
return data_json;
}
Try to pass response.substring(14) to above function, and use the returned value.
JSONObject jObj = newJSONObject(convertStandardJSONString(response.substring(14)));

Related

Send Parameters in Volley Using GSON

What I Know
I am able to make a request with the help of JsonObjectRequest using Volley without GSON. Nowadays I am learning of GSON so I can make a request without parameter.
Sample Code
HashMap<String, String> params = new HashMap<String, String>();
params.put("user",userId);
Log.d(TAG + "pp", String.valueOf(params));
String Url = Constants.Base_URL + "getcoupons/";
JsonObjectRequest request = new JsonObjectRequest(Url, new JSONObject(params),
response -> {
Log.d(TAG, "respCoupan" + String.valueOf(response));
try {
String statusResponseObject = response.getString("status");
String msgObject = response.getString("msg");
if (statusResponseObject.equals("200")){
JSONArray jsonArray = response.getJSONArray("response");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject pendingFragResponse = jsonArray.getJSONObject(i);
String codeObject = pendingFragResponse.getString("code");
String typeObject = pendingFragResponse.getString("type");
String amountObject = pendingFragResponse.getString("amount");
String descriptionObject = pendingFragResponse.getString("description");
String leagueObject = pendingFragResponse.getString("league");
String expireObject = pendingFragResponse.getString("expire");
//
couponArrayList.add(new Coupon(codeObject, typeObject, amountObject,
descriptionObject, leagueObject, expireObject));
couponAdapter = new CouponAdapter( couponArrayList, CoupanActivity.this);
recyclerView.setAdapter(couponAdapter);
wp10ProgressBar.hideProgressBar();
wp10ProgressBar.setVisibility(View.GONE);
}
couponAdapter.notifyDataSetChanged();
// wp10ProgressBar.hideProgressBar();
}else {
wp10ProgressBar.hideProgressBar();
wp10ProgressBar.setVisibility(View.GONE);
Toast.makeText(CoupanActivity.this, msgObject, Toast.LENGTH_SHORT).show();
}
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(this, "Server didn't response, Try after some time", Toast.LENGTH_LONG).show();
}
}, error -> {
error.printStackTrace();
Log.d(TAG + "error", String.valueOf(error.getMessage()));
Toast.makeText(this, "Server didn't response, Try after some time", Toast.LENGTH_LONG).show();
});
MySingleton.getInstance(CoupanActivity.this).addToRequestQueue(request);
JSON
{
"status": "200",
"msg": "Successfully",
"response": [
{
"code": "YUDH20",
"type": "Flat",
"amount": "2",
"description": "Flat 20% credit Discount",
"league": "0",
"league_name": "",
"expire": "2019-08-22"
}
]
}
What I want
I want a clear example to make a request with GSON and Parameter (means send Hashmap values in request with GSON).
Can I use GSON for parameters of a java class?
How can I use GSON for Headers?
you must create data Class "ModelClass" and ResponseClass gson convert your data in "ModelClass" and you can using this class simply:
public class ModelClass {
private String status;
private String msg;
private JSONArray response;
...
}
and create a ResponseClass.class
public class ResponseClass {
private String code;
private String type;
private int amount;
private String description;
private String league;
private String league_name;
private String expire;
...
}
and change your code to:
HashMap<String, String> params = new HashMap<String, String>();
params.put("user", userId);
Log.d(TAG + "pp", String.valueOf(params));
String Url = SyncStateContract.Constants.Base_URL + "getcoupons/";
JsonObjectRequest request = new JsonObjectRequest(Url, new JSONObject(params),
response -> {
Log.d(TAG, "respCoupan" + String.valueOf(response));
try {
Gson gson = new GsonBuilder()
.serializeNulls()
.create();
Type type = new TypeToken<ModelClass>() {
}.getType();
ModelClass result = gson.fromJson(response.toString(), type);
if (result.getMsg().equals("200")) {
for (int i = 0; i < result.getResponse().size(); i++) {
result.getResponse().get(i).getAmount()
result.getResponse().get(i).getCode()
result.getResponse().get(i).getExpire()
...
}}
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(this, "Server didn't response, Try after some time", Toast.LENGTH_LONG).show();
}
}, error -> {
error.printStackTrace();
Log.d(TAG + "error", String.valueOf(error.getMessage()));
Toast.makeText(this, "Server didn't response, Try after some time", Toast.LENGTH_LONG).show();
});
MySingleton.getInstance(CoupanActivity.this).addToRequestQueue(request);

Change local variable inside method, when the method is executed the variable is not changed

I'm working on an android app. I have this form, when the button is clicked it execute a method called insertData(). Inside this function I change a local variable called "address" with another function getAddress().
Inside the function getAddress the local variable "address" is changed successfully. But when we enter the function insertData(), the variable "address" still contains the old data in this case "Location Unknown".
What am I not seeing here?
insertData()
public String address = "Location unknown";
public boolean insertData(String title, String description, String image, Double longitude, Double latitude, String date) {
String location = Double.toString(longitude) + "," + Double.toString(latitude);
getAddress(location);
Log.d("TAG2", address); // Still "Location unknown"
SQLiteDatabase db = this.getWritableDatabase();
ContentValues contentValues = new ContentValues();
contentValues.put(COL_2, title);
contentValues.put(COL_3, description);
contentValues.put(COL_4, image);
contentValues.put(COL_5, longitude);
contentValues.put(COL_6, latitude);
contentValues.put(COL_7, date);
contentValues.put(COL_8, address);
long result = db.insert(TABLE_NAME, null, contentValues);
if (result == -1)
return false;
else
return true;
}
getAddress()
public void getAddress(String coordination) {
String token = "{removed for a reason haha}";
String url = "https://api.mapbox.com/geocoding/v5/mapbox.places/" + coordination + ".json?access_token=" + token;
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(url).build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
#Override
public void onResponse(Call call, Response response) throws IOException {
if(response.isSuccessful()) {
String data = response.body().string();
JsonParser parser = new JsonParser();
try {
JsonObject obj = (JsonObject) parser.parse(data);
JsonArray arr = obj.getAsJsonArray("features");
JsonObject objj = arr.get(2).getAsJsonObject();
String place = objj.get("place_name").getAsString();
address = place;
Log.d("TAG", address); // Gives an address
}
catch (Exception e) {
e.printStackTrace();
}
}
}
});
}
Logcat Debugger
2019-06-15 20:12:58.968 31465-31465/com.example.triptracker D/TAG2: Location unkown
2019-06-15 20:12:59.269 31465-31569/com.example.triptracker D/TAG: Mountain View, California, United States
I cannot change the onResponse() method to return String. I don't know why, but it is a read only method.
getAddress {changed}
public void getAddress(String coordination) {
String token = "{empty}";
String url = "https://api.mapbox.com/geocoding/v5/mapbox.places/" + coordination + ".json?access_token=" + token;
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(url).build();
try (Response response = client.newCall(request).execute()) {
String data = response.body().string();
JsonParser parser = new JsonParser();
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
JsonObject obj = (JsonObject) parser.parse(data);
JsonArray arr = obj.getAsJsonArray("features");
JsonObject objj = arr.get(2).getAsJsonObject();
String place = objj.get("place_name").getAsString();
address = place;
Log.d("TAG", address);
}
catch (Exception e) {
e.printStackTrace();
}
}
getAddress() does its work asynchronously. By the time getAddress() returns, your HTTP request will not be complete, and so address will not have changed yet.
Since insertData() is doing disk I/O, you should be calling insertData() on its own background thread, so you do not freeze the UI while the disk I/O is going on. If that is the case, then you can use OkHttp synchronously, using execute() instead of enqueue(). That will allow you to have getAddress() return the address, so you can insert it into your database.

Sending string data to server script using volley in android fragment

Am trying to send data received from my android app to a server side php script. Am using the Volley. However, when I declare the the RequestQueue I get an error
"newRequestQueue (android.content.Context, com.android.volley.toolbox.HttpStack) cannot be applied to ()"
I tried using::
Blockquote
RequestQueue queue = Volley.newRequestQueue(this);
Blockquote
RequestQueue queue = Volley.newRequestQueue(getActivity().getApplicationContext());
Blockquote
Error is still the same on both cases. Please what am doing wrong?
PS- volley is in PostDataToEmail method of a fragment.
Here is the code below:
public void PostDataToEmail(){
final String service = service_type.toString();
final String error_message = incident.getText().toString();
final String requester = user_name.getText().toString();
final String number = mobile_no.getText().toString();
final String site = location.getText().toString();
final String support_time = timeDate.getText().toString();
final String support_date = date_field.getText().toString();
final String mode_of_contact = contact_mode.toString();
RequestQueue queue = Volley.newRequestQueue();
String url = "http://mywebsite/fromApp.php";
StringRequest postRequest = new StringRequest (Request.Method.POST, url,
new Response.Listener<String>(){
#Override
public void onResponse(String response) {
Log.d("Response", response);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse (VolleyError error) {
Log.d("ERROR", "error => " +error.toString());
}
}
) {
#Override
protected Map<String, String> getParams(){
Map<String, String> params = new HashMap<String, String>();
params.put("grant_type", "password");
params.put(" ", "{{%escape/");
params.put("Service: ", service);
params.put("Error Message: ", error_message);
params.put("Requester: ", requester);
params.put("Mobile No: ", number);
params.put("Location: ", site);
params.put("Time: ", support_time);
params.put("Date: ", support_date);
params.put("Contact mode: ", mode_of_contact);
return params;
}
};
queue.add(postRequest);
}
You need to add this in your declaration. RequestQueue some=newRequestQueue(this)

GCM Notification Receiver/Token Registration

EDIT: Figured it out -- see answer below
I'm attempting to generate registration tokens, store them in a server, and then use the tokens to send push notifications. At this point, I've successfully sent and stored registration tokens and am sending notifications from a web API, but they aren't arriving to my device. I was wondering if/what I should replace R.string.gcm_defaultSenderId with (i.e. the sender key from GCM?) I'm including my code for token registration as well as my notification listener below.
public class GCMRegistrationIntentService extends IntentService {
//Constants for success and errors
public static final String REGISTRATION_SUCCESS = "RegistrationSuccess";
public static final String REGISTRATION_ERROR = "RegistrationError";
private Context context;
private String sessionGUID = "";
private String userGUID = "";
//Class constructor
public GCMRegistrationIntentService() {
super("");
}
#Override
protected void onHandleIntent(Intent intent) {
context = getApplicationContext();
sessionGUID = RequestQueueSingleton.getInstance(context).getSessionGUID();
userGUID = RequestQueueSingleton.getInstance(context).getUserGUID();
//Registering gcm to the device
registerGCM();
}
//Registers the device to Google Cloud messaging and calls makeAPICall to send the registration
//token to the server
private void registerGCM() {
//Registration complete intent initially null
Intent registrationComplete;
//declare a token, try to find it with a successful registration
String token;
try {
//Creating an instanceid
InstanceID instanceID = InstanceID.getInstance(this);
//Getting the token from the instance id
token = instanceID.getToken(getString(R.string.gcm_defaultSenderId),
GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
//Display the token, need to send to server
Log.w("GCMRegIntentService", "token:" + token);
String android_id = Settings.Secure.getString(context.getContentResolver(),
Settings.Secure.ANDROID_ID);
int osTypeCode = Constants.OST_ANDROID;
JSONObject parms = new JSONObject();
try {
parms.put("deviceID", android_id);
parms.put("OSTypeCode", osTypeCode);
parms.put("token", token);
} catch (JSONException e) {
e.printStackTrace();
}
Transporter oTransporter = new Transporter(Constants.TransporterSubjectUSER,
Constants.REGISTER_NOTIFICATION_TOKEN, "", parms, userGUID, sessionGUID);
oTransporter.makeAPICall(getApplicationContext(), "");
//on registration complete. creating intent with success
registrationComplete = new Intent(REGISTRATION_SUCCESS);
//Putting the token to the intent
registrationComplete.putExtra("token", token);
} catch (Exception e) {
//If any error occurred
Log.w("GCMRegIntentService", "Registration error");
registrationComplete = new Intent(REGISTRATION_ERROR);
}
//Sending the broadcast that registration is completed
LocalBroadcastManager.getInstance(this).sendBroadcast(registrationComplete);
}
}
And the listener service:
public class GCMPushReceiverService extends GcmListenerService {
private static final String TAG = "GCMPushReceiverService";
//with every new message
#Override
public void onMessageReceived(String from, Bundle data){
System.out.println("WE'VE RECIEVED A MESSAGE");
String message = data.getString("message");
Log.d(TAG, "From: " + from);
Log.d(TAG, "Message: " + message);
sendNotification(message);
}
private void sendNotification(String message) {
Intent intent = new Intent(this, LogInPage.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
int requestCode = 0;
PendingIntent pendingIntent =
PendingIntent.getActivity(this, requestCode, intent, PendingIntent.FLAG_ONE_SHOT);
Uri sound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder noBuilder = new NotificationCompat.Builder(this);
noBuilder.setContentTitle("title");
noBuilder.setContentText(message);
noBuilder.setContentIntent(pendingIntent);
noBuilder.setSound(sound);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, noBuilder.build()); //0 = ID of notification
}
}
Lastly, as it may be of some assistance, the information transporter/networking class:
public class Transporter {
private String subject;
private String request;
private String key;
private Date lastUpdateDate;
private boolean forceLoad = false;
private Date requestDate;
private Date responseDate;
private int status;
private String statusMsg = "";
private String tempKey = "";
private JSONObject additionalInfo = null;
private JSONObject parameters;
public static String sessionGUID = "";
public static String userGUID = "";
public static String SERVER = Constants.qa_api;
//transporter object to interact with the server, containing information about the request
//made by the user
public Transporter(String pSubject, String pRequest, String pKey,
JSONObject parms, String userGUID, String sessionGUID)
{
subject = pSubject;
request = pRequest;
key = pKey;
parameters = parms;
setUserGUID(userGUID);
setSessionGUID(sessionGUID);
}
//implements an API call for a given transporter, takes 2 arguments:
//the application context (call getApplicationContext() whenever it's called)
//and a String that represents the field that we are trying to update (if there is one)
//i.e. if we are calling getUserFromSession(), we want the user guid so jsonID = "userGUID"
public void makeAPICall(final Context context, final String jsonID) {
RequestQueue mRequestQueue =
RequestQueueSingleton.getInstance(context).getRequestQueue();
String targetURL = getServerURL() + "/Transporter.aspx";
StringRequest postRequest = new StringRequest(Request.Method.POST, targetURL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
String parseXML= parseXML(response);
System.out.println("response: " + parseXML);
JSONObject lastResponseContent = null;
try {
lastResponseContent = new JSONObject(parseXML);
} catch (JSONException e) {
e.printStackTrace();
}
try {
if (lastResponseContent != null && !jsonID.equals("")) {
String info = lastResponseContent.getString(jsonID);
if (jsonID.equals("userGUID")) {
userGUID = info;
RequestQueueSingleton.getInstance(context).setUserGUID(userGUID);
}
}
//put other things in here to pull whatever info
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
}) {
#Override
public byte[] getBody() throws AuthFailureError {
String body = getXML(subject,
request, "",
sessionGUID, userGUID, null, parameters);
return body.getBytes();
}
};
postRequest.setTag("POST");
mRequestQueue.add(postRequest);
}
you need to send a post to the url "https://android.googleapis.com/gcm/send":
private void sendGCM() {
StringRequest strReq = new StringRequest(Request.Method.POST,
"https://android.googleapis.com/gcm/send", new Response.Listener<String>() {
#Override
public void onResponse(String response) {
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
NetworkResponse networkResponse = error.networkResponse;
Log.e(TAG, "Volley error: " + error.getMessage() + ", code: " + networkResponse);
Toast.makeText(getApplicationContext(), "Volley error: " + error.getMessage(), Toast.LENGTH_SHORT).show();
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
params.put("data", "message that you send");
params.put("to", "token gcm");
Log.e(TAG, "params: " + params.toString());
return params;
}
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
Map<String,String> headers = new HashMap<String, String>();
headers.put("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
headers.put("Authorization", "key="google key");
return headers;
}
};
}
So the Volley calls are non-sequential so the first call (to get a userGUID) didn't return before the second call (to register for notifications), so while the token registration was "successful," there was no corresponding user information so it didn't know how/where to send the push notification. To resolve, I made a special case in the makeAPICall class which created another StringRequest which first basically did the normal getUserFromSession but then recursively called MakeAPICall with the new userGUID information. To avoid an infinite loop, I used an if else statement: (if userGUID == null || userGUID.equals("")) then I did the recursive call, so when the first call returned that conditional was always false and it would only make one recursive call. This answer may be a rambling a bit, but the key take away is using onResponse to make another Volley call for sequential requests. See: Volley - serial requests instead of parallel? and Does Volley library handles all the request sequentially

Volley String cannot be converted to JSONObject

I'm always getting the following error as long as i put a array into Params. Even after converting to String it still gives that error. The code works fine without the contactlist array inside it. Any idea?
Error
com.android.volley.ParseError: org.json.JSONException: Value Created
of type java.lang.String cannot be converted to JSONObject
Sample response:
{
"username": "test2",
"lists": [
"contact_0",
"contact_1",
"contact_2",
"contact_3",
"contact_4",
"contact_5",
"contact_6",
"contact_7",
"contact_8",
"contact_9"
]
}
ArrayList<String> contactList = new ArrayList<String>();
public String joinInfo;
Cursor phones = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null,null,null, null);
while (phones.moveToNext())
{
String name=phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
String phoneNumber = phones.getString(phones.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
System.out.println("name : " + name + ", ID : " + phoneNumber);
joinInfo = name;
contactList.add(joinInfo);
}
phones.close();
RequestQueue rq = Volley.newRequestQueue(this);
JSONObject params = new JSONObject();
try {
params.put("username", "test2");
params.put("lists", contactList.toString()); // When i change this to simply "test" a string, it works fine.
Log.d("PANDA", contactList.toString());
} catch (JSONException e) {
e.printStackTrace();
}
JsonObjectRequest jsonObjReq = new JsonObjectRequest(Request.Method.POST,
"http://postcatcher.in/catchers/55521f03f708be0300001d28", params, //Not null.
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.d("PANDA", response.toString());
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.d("PANDA", "Error: " + error.getMessage());
Log.d("PANDA", error.toString());
}
});
// Adding request to request queue
rq.add(jsonObjReq);
PostCatcher although allowing us to post requests, its response is basically a plain string "Created" and not in Json format. As such our client code is not able to ascertain it and throws error. One thing is even without ArrayList object that is with plain (String, String) K,V pair also it would fail.
You can verify it if you try sending request through Advanced Rest Client (see attached)

Categories

Resources