JsonObjectRequest keeps throwing null pointer exception when it's not null - java

I'm currently trying to implement JsonObjectRequest. I'm looking for a location and trying to get the place's information. However, there is a problem with jsObjRequest (of type JsonObjectRequest)--it throws a null pointer exception even though it's not null when I check on the watchlist. I'm confused as to why. Here's the code:
private static final HttpTransport HTTP_TRANSPORT = new NetHttpTransport();
private static final String API_KEY = "AIzaSyBlOhVQWuyQGwlAGZnDo81Aeg50UJbFrfw";
private static final String PLACES_SEARCH_URL =
"https://maps.googleapis.com/maps/api/place/search/json?";
private static final String PLACES_TEXT_SEARCH_URL =
"https://maps.googleapis.com/maps/api/place/search/json?";
private static final String PLACES_DETAILS_URL =
"https://maps.googleapis.com/maps/api/place/details/json?";
private double _latitude;
private double _longitude;
private double _radius;
/**
* Searching places
* #param latitude - latitude of place
* #params longitude - longitude of place
* #param radius - radius of searchable area
* //#param types - type of place to search
* #return list of places
* */
public PlacesList search(double latitude, double longitude, double radius/*, String types*/)
throws Exception {
String url = PLACES_SEARCH_URL + "key=" + API_KEY + "&location=" + latitude + "," + longitude + "&radius=" + radius;
System.out.println(url);
JsonObjectRequest jsObjRequest = new JsonObjectRequest
(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
Log.d("SEARCH", "Part 1");
VolleyLog.v("Response:%n %s", response.toString(4));
} catch (JSONException e) {
Log.d("SEARCH", "Part 2 - Exception called");
e.printStackTrace();
}
catch (Exception e)
{
System.out.println("Exception caught in JsonObjectRequest");
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("SEARCH", "Part 3");
VolleyLog.e("Error: ", error.getMessage());
}
});
ApplicationController.getInstance().addToRequestQueue(jsObjRequest);
return new PlacesList();
}
It throws on the line that contains: ApplicationController.getInstance().addToRequestQueue(jsObjRequest);
The following block of code is where we catch the exception:
// Define a listener that responds to location updates
LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
// Called when a new location is found by the network location provider.
Double lat = location.getLatitude();
Double lon = location.getLongitude();
PlacesList myPlaces = new PlacesList();
try {
myPlaces = finder.search(lat, lon, 10);
} catch (Exception e) {
System.out.println("Could not find place. Exception in search.");
}
if (myPlaces.getMostLikelyPlace() != null) {
if (myPlaces.getMostLikelyPlace().getId() != null) {
Log.d("PLACEID", myPlaces.getMostLikelyPlace().getId());
System.out.println(myPlaces.getMostLikelyPlace().getId());
}
}
}
The error that we catch looks like this:
I/System.out: https://maps.googleapis.com/maps/api/place/search/json?key=AIzaSyBlOhVQWuyQGwlAGZnDo81Aeg50UJbFrfw&location=43.816,-111.78199833333335&radius=10.0
I/System.out: Could not find place. Exception in search.
Here is what the documentation says about JsonObjectRequest: https://developer.android.com/training/volley/request.html#request-json
I feel like I'm following the instructions on the documentation exactly. Is there any reason as to why it's throwing on that line of code?

try this setup for volley..
http://www.androidhive.info/2014/05/android-working-with-volley-library-1/
maybe something went wrong with the volley setup for the project .. happens with me all the time..

Related

How can I pass a variable as a value in an API.. Im using Geocoding API. But i can't get the location

double lat = 13.630754;
double longi = 123.18484;
JsonObjectRequest myRequest = new JsonObjectRequest(
Request.Method.POST,
// Here is where i used the variables for latitude and longitude
String.format(" https://maps.googleapis.com/maps/api/geocode/json?latlng=",lat,",",longi,"&key=my key"),
new JSONObject(jsonParams),
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Toast.makeText(getApplicationContext(),response.toString(),Toast.LENGTH_SHORT).show();
// t.setText(response.toString());
String address = null;
try {
address = response.getJSONArray("results").getJSONObject(0).getString("formatted_address");
} catch (JSONException e) {
e.printStackTrace();
}
t.setText(address);
}
},
String.format(" https://maps.googleapis.com/maps/api/geocode/json?latlng=",lat,",",longi,"&key=my key")
does not make any sense.
Either use string concatenation
"https://maps.googleapis.com/maps/api/geocode/json?latlng=" + lat + "," + longi + "&key=my key"
or a proper format string
String.format("https://maps.googleapis.com/maps/api/geocode/json?latlng=%1$s,%2$s&key=my key", lat, longi )
See the documentation: https://docs.oracle.com/javase/7/docs/api/java/util/Formatter.html

Why result size of getFromLocation() is 0 ? How to get address from geopoint ? - Android

I want to return a string array from Async class back to the activity that is calling this asynchronous class that is job is to do the reverse geocoding.
So, from my activity I call the constructor of the class like this:
Double[] lat_long = new Double[] { Double.parseDouble(map_lat), Double.parseDouble(map_long) };
ReverseGeocodingTask reverseGeocoding = new ReverseGeocodingTask(getActivity().getApplicationContext());
reverseGeocoding.execute(lat_long);
And this is the code of the class:
class ReverseGeocodingTask extends AsyncTask<Double, Void, List<String>> {
public static List<String> LIST = new ArrayList<String>();
Context mContext;
public ReverseGeocodingTask(Context context) {
super();
mContext = context;
}
#Override
protected List<String> doInBackground(Double... params) {
Geocoder gc= new Geocoder(mContext, Locale.getDefault());
List<Address> addrList = null;
double latitude = params[0].doubleValue();
double longitude = params[1].doubleValue();
Log.d("LATLONG", latitude + ":" + longitude);
try {
addrList = gc.getFromLocation(latitude, longitude, 1);
if (addrList.size() > 0) {
//format location info
Address address = addrList.get(0);
LIST.add(address.getLocality());
LIST.add(address.getSubAdminArea());
LIST.add(address.getCountryName());
Log.d("LIST", LIST.get(0));
}
else{
Log.d("addrList SIZE", "=0");
return null;
}
} catch (IOException e) {
e.printStackTrace();
return null;
}
return LIST;
}
#Override
protected void onPostExecute(List<String> result) {
if (result != null) {
Log.d("ON POST", result.get(0));
}
}
}
This is the logcat:
02-28 19:20:04.323 12275-14109/guide_me_for_all.guide_me_for_all D/LATLONG﹕ 34.681377999999995:33.039339
02-28 19:20:05.434 12275-14109/guide_me_for_all.guide_me_for_all D/addrList SIZE﹕ =0
I get correctly the latitude and longitude point as you can see from the Log.d(), BUT getFromLocation.size() is always 0.
This may be a problem with your GeoCoder service. If you're backend service for the device is not present or has other problems, you will get this response.
use isPresent to check if an implementation is present.
Also, see this post here:
Geocoder.getFromLocation throws IOException on Android emulator
And the docs mention that you need a backend service:
http://developer.android.com/reference/android/location/Geocoder.html

Google Places API: How to get photos and place id from latitude and longitude?

I want to get photos and place_id required by Google Place Details API of my current location.
Search nearby does not return places in my exact location. (current lat/lng returned by android location service).
Radar search requires a keyword. Please suggest.
Per the Google Place Search documentation the three things you need to provide are the KEY, LOCATION and RADIUS. I cut out a bunch of unnecessary code, but here's how I did something similar.
1) Get your current location
private void initializeMapLocation() {
LocationManager locationManager = (LocationManager) this
.getSystemService(Context.LOCATION_SERVICE);
Location lastLocation = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (lastLocation != null) {
setUserLocation(lastLocation);
}
}
private void setUserLocation(Location location) {
LatLng currentLatLng = new LatLng(location.getLatitude(), location.getLongitude());
mMap.animateCamera(CameraUpdateFactory.newLatLng(currentLatLng));
}
2) Build your search URL. You can add extra parameters like a keyword if you want by appending them on, but it doesn't sound like you want that in this particular case.
private void buildAndInitiateSearchTask(String searchType) {
Projection mProjection = mMap.getProjection();
LatLng mProjectionCenter = mProjection.getVisibleRegion().latLngBounds
.getCenter();
searchURL.append("https://maps.googleapis.com/maps/api/place/nearbysearch/");
searchURL.append("json?");
searchURL.append("location=" + mProjectionCenter.latitude + "," + mProjectionCenter.longitude);
searchURL.append("&radius=" + calculateProjectionRadiusInMeters(mProjection));
searchURL.append("&key=YOUR_KEY_HERE");
new PlaceSearchAPITask().execute(searchURL.toString());
}
private double calculateProjectionRadiusInMeters(Projection projection) {
LatLng farLeft = projection.getVisibleRegion().farLeft;
LatLng nearRight = projection.getVisibleRegion().nearRight;
Location farLeftLocation = new Location("Point A");
farLeftLocation.setLatitude(farLeft.latitude);
farLeftLocation.setLongitude(farLeft.longitude);
Location nearRightLocation = new Location("Point B");
nearRightLocation.setLatitude(nearRight.latitude);
nearRightLocation.setLongitude(nearRight.longitude);
return farLeftLocation.distanceTo(nearRightLocation) / 2 ;
}
3) Send your request and display your results as an AsyncTask
private class PlaceSearchAPITask extends AsyncTask<String, Void, String> {
#Override
protected String doInBackground(String... placesURL) {
StringBuilder placesBuilder = new StringBuilder();
for (String placeSearchURL : placesURL) {
HttpClient placesClient = createHttpClient();
try {
HttpGet placesGet = new HttpGet(placeSearchURL);
HttpResponse placesResponse = placesClient
.execute(placesGet);
StatusLine placeSearchStatus = placesResponse
.getStatusLine();
if (placeSearchStatus.getStatusCode() == 200) {
HttpEntity placesEntity = placesResponse
.getEntity();
InputStream placesContent = placesEntity
.getContent();
InputStreamReader placesInput = new InputStreamReader(
placesContent);
BufferedReader placesReader = new BufferedReader(
placesInput);
String lineIn;
while ((lineIn = placesReader.readLine()) != null) {
placesBuilder.append(lineIn);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
return placesBuilder.toString();
}
#Override
protected void onPostExecute(String result) {
try {
JSONObject resultObject = new JSONObject(result);
// This is my custom object to hold the pieces of the JSONResult that I want. You would need something else for your particular problem.
mapData = new MapDataSource(resultObject.optJSONArray("results"));
} catch (JSONException e) {
e.printStackTrace();
}
if (mapData != null) {
// TODO - This is where you would add your markers and whatnot.
}
}
}

Constructing the most reliable user country mechanism

In an application that I'm currently working on there is a huge need to determine user country as fast as possible and as reliable as possible. I have decided to rely on three ways for finding user country; each one has its advantages and disadvantages:
Android inner methods to get the SIM country.
GeoCoding.
IP to Location API.
Here are the three pieces of code:
1. Android inner methods to get the SIM country:
public static String getUserCountry(Context context) {
try {
final TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
final String simCountry = tm.getSimCountryIso();
if (simCountry != null && simCountry.length() == 2) { // SIM country code is available
CupsLog.d(TAG, "getUserCountry, simCountry: " + simCountry.toLowerCase(Locale.US));
return simCountry.toLowerCase(Locale.US);
}
else if (tm.getPhoneType() != TelephonyManager.PHONE_TYPE_CDMA) { // device is not 3G (would be unreliable)
String networkCountry = tm.getNetworkCountryIso();
if (networkCountry != null && networkCountry.length() == 2) { // network country code is available
CupsLog.d(TAG, "getUserCountry, networkCountry: " + networkCountry.toLowerCase(Locale.US));
return networkCountry.toLowerCase(Locale.US);
}
}
}
catch (Exception e) { }
return null;
}
2. GeoCoding:
public static void getCountryCode(final Location location, final Context context) {
CupsLog.d(TAG, "getCountryCode");
AsyncTask<Void, Void, String> countryCodeTask = new AsyncTask<Void, Void, String>() {
final float latitude = (float) location.getLatitude();
final float longitude = (float) location.getLongitude();
List<Address> addresses = null;
Geocoder gcd = new Geocoder(context);
String code = null;
#Override
protected String doInBackground(Void... params) {
CupsLog.d(TAG, "doInBackground");
try {
addresses = gcd.getFromLocation(latitude, longitude, 10);
for (int i=0; i < addresses.size(); i++)
{
if (addresses.get(i) != null && addresses.get(i).getCountryCode() != null)
{
code = addresses.get(i).getCountryCode();
}
}
} catch (IOException e) {
CupsLog.d(TAG, "IOException" + e);
}
return code;
}
#Override
protected void onPostExecute(String code)
{
if (code != null)
{
CupsLog.d(TAG, "getCountryCode :" + code.toLowerCase());
UserLocation.instance.setCountryCode(code.toLowerCase());
CookieUtil.formatLangueageAndLocationCookie();
CookieUtil.instance.instantateCookieUtil(context);
}
}
};
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.GINGERBREAD_MR1) {
CupsLog.d(TAG, "countryCodeTask.execute();");
countryCodeTask.execute();
} else {
CupsLog.d(TAG, "countryCodeTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);");
countryCodeTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
}
}
3. IP to Location API:
private void getUserCountryByIp() {
AsyncHttpClient client = new AsyncHttpClient();
client.setCookieStore(CookieUtil.instance.getPersistentCookieStore());
String userCountryApi = "http://ip-api.com/json";
CupsLog.i(TAG, "country uri: " + userCountryApi);
client.get(userCountryApi, new JsonHttpResponseHandler() {
#Override
public void onSuccess(JSONObject orderResponseJSON) {
CupsLog.i(TAG, "onSuccess(JSONObject res)");
try
{
CupsLog.i(TAG, "JsonResponse: "+ orderResponseJSON.toString(3));
String tempString = orderResponseJSON.getString("countryCode");
if (tempString != null)
{
//countryCodeFromIpApi = tempString.toLowerCase();
UserLocation.instance.setCountryCode(tempString.toLowerCase());
CookieUtil.formatLangueageAndLocationCookie();
CookieUtil.instance.instantateCookieUtil(LoginActivity.this);
isGotCountryFromIp = true;
}
} catch (JSONException e) {
CupsLog.i(TAG, "JSONException: " + e);
}
}
#Override
public void onFailure(Throwable arg0, JSONObject orderResponseJSON) {
CupsLog.i(TAG, "onFailure");
try {
CupsLog.i(TAG, "JsonResponse: "+ orderResponseJSON.toString(3));
} catch (JSONException e) {
CupsLog.i(TAG, "JSONException: " + e);
}
}
#Override
public void onFinish() {
CupsLog.i(TAG, "onFinish");
super.onFinish();
}
});
}
Now I have those 3 methods that are working great, my problem is more of a Java problem. The first method give me the result right away, while the two others (2,3) are potentiality long running tasks. what more is that the first option is the most not reliable one, as users can travel to different countries with the SIM card. The second is more reliable but still sometimes does not returns an country (depending on the location of the user). The third one is the one that I found to be the most reliable one, but the most long as well.
The question: knowing this information, how would I construct a method that uses those 3 methods in the right order for reliability stand point and considering the long running tasks factor?
Unfortunately there is no really reliable way to determine the physical location of a user (e.g. his/her cellphone) because:
SIM card might be bought and/or manufactured in other country;
Geocoding (which is AFAIU based on GPS/GLONASS coordinates) might give wrong (~10m) results or no results at all if user disabled it or no satellites are visible (underground, for example);
Resolving country by IP might also give you wrong results, for example because of using VPN;
So my advice would be to ask user, which country he is currently in and willing to "tell" you so.

How to Parse JSONObject and JSONArray at one time

i'm working on an app that uses JSON Responses which has both JSONObject and JSONArray. Both the information are required to place markers on map. But i'm facing problem in parsing both.
This is my Response when I called my URl
{
-source: {
LS: " ABCDEF",
name: "XYXA",
point: "77.583859,12.928751"
},
-stores: [
-{
ph: null,
distance: "0.3",
LS: " abcd",
id: 1209,
name: "xyz",
point: "77.583835,12.926359"
},
-{
ph: null,
distance: "0.3",
LS: " abcd",
id: 1209,
name: "xyz",
point: "77.583835,12.926359"
}
]
}
This is how I tried to handle JSON response
public class JSONResponseHandler implements ResponseHandler<List<LatlongRec>> {
#Override
public List<LatlongRec> handleResponse(HttpResponse response)
throws ClientProtocolException, IOException {
List<LatlongRec> result = new ArrayList<LatlongRec>();
String JSONResponse = new BasicResponseHandler()
.handleResponse(response);
try {
JSONObject object = (JSONObject)new JSONTokener(JSONResponse)
.nextValue();
JSONArray stores = object.getJSONArray("stores");
for (int i = 0; i < stores.length(); i++) {
JSONObject tmp = (JSONObject) stores.get(i);
result.add(new LatlongRec(tmp.getString("point"), tmp
.getString("name"), tmp.getString("LS"), tmp
.getString("ph")));
Log.v("points", "" + tmp.getString("point"));
}
} catch (JSONException e) {
e.printStackTrace();
}
return result;
}
}
In this LatlongRec is a class where I have created constructor and getters.
This is my Main Activity
public class SecondActivity extends Activity {
private static final double CAMERA_LNG = 77.583859;
private static final double CAMERA_LAT = 12.928751;
// The Map Object
private GoogleMap mMap;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
String city = getIntent().getStringExtra("city");
String area1 = getIntent().getStringExtra("area");
String area = area1.trim();
String URL = "http://xyzxyz.search.json?query="
+ area + "&city=" + city + "&app_id=test";
new HttpGetTask().execute(URL);
}
private class HttpGetTask extends AsyncTask<String, Void, List<LatlongRec>> {
AndroidHttpClient mClient = AndroidHttpClient.newInstance("");
#Override
protected List<LatlongRec> doInBackground(String... params) {
HttpGet request = new HttpGet(params[0]);
JSONResponseHandler responseHandler = new JSONResponseHandler();
try {
return mClient.execute(request, responseHandler);
} catch (ClientProtocolException e) {
} catch (IOException e) {
}
return null;
}
#SuppressLint("NewApi")
protected void onPostExecute(List<LatlongRec> result) {
// Get Map Object
mMap = ((MapFragment) getFragmentManager().findFragmentById(
R.id.map)).getMap();
if (null != mMap) {
// Add a marker for every earthquake
for (final LatlongRec rec : result) {
Log.v("pointM", "" + rec.getPoint());
Log.v("NAMES", "" + rec.getName());
String point = rec.getPoint();
String[] latlng = point.split(",");
String lat = latlng[0];
String lng = latlng[1];
Double lat1 = Double.parseDouble(lat);
Double lng1 = Double.parseDouble(lng);
Log.v("LATLNGM", "lat" + lng + "& lng " + lat);
// Add a new marker for each point
mMap.addMarker(new MarkerOptions()
.position(new LatLng(lng1, lat1))
.title(rec.getName())
.snippet(rec.getLS() + rec.getPh())
.icon(BitmapDescriptorFactory
.fromResource(R.drawable.main_marker)));
// Setting a custom info window adapter for the google map
CameraPosition cp = new CameraPosition(new LatLng(CAMERA_LAT,
CAMERA_LNG), 15, 40, 90);
mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cp));
}
if (null != mClient)
mClient.close();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.second, menu);
return true;
}
}
How to get points in source object to my main activity so that i can set CAMERA_LAT and CAMERA_LNG to Lat and Lng from that point.?
I'm new to JSON please help me to solve this.
Thanking you
String point[] = jsonObject.getJSONObject("source").getString("point").split(",");
double lat = Double.parseDouble(point[0]);
double lon = Double.parseDouble(point[1]);
Should get you on your way to getting the points out.
If you are looking on getting them to another activity, you should put them into a Bundle and pass them to the next activity. Here is a post explaining how to pass a bundle.
Try out a deserializer. I used the google GSON library to solve a similar problem I had. Take a peek at how I parsed the heroes array in the json object.
public class GameDeserializer implements JsonDeserializer<Game> {
public Game deserialize(JsonElement json, Type typeOfT,
JsonDeserializationContext context) throws JsonParseException {
JsonObject obj = json.getAsJsonObject().get("game").getAsJsonObject();
String id = obj.get("id").getAsString();
Integer turn = obj.get("turn").getAsInt();
Integer maxTurns = obj.get("maxTurns").getAsInt();
Hero[] heroes = new Hero[4];
for (int i = 0; i < 4; i++) {
heroes[i] = context.deserialize(obj.get("heroes").getAsJsonArray().get(i), Hero.class);
}
Board board = context.deserialize(obj.get("board"), Board.class);
Hero player = context.deserialize(json.getAsJsonObject().get("hero"), Hero.class);
String token = json.getAsJsonObject().get("token").getAsString();
String viewUrl = json.getAsJsonObject().get("viewUrl").getAsString();
String playUrl = json.getAsJsonObject().get("playUrl").getAsString();
boolean finished = obj.get("finished").getAsBoolean();
return new Game(id, turn, maxTurns, heroes, board, player, token, viewUrl, playUrl, finished);
}
}
}
I wouldn't have answered, but your question is very ambiguous and I'm not exactly sure if you need help with json, or with a String. In the latter case, disregard my answer.

Categories

Resources