0

Sorry for the length, but I've been stuck on this for a while.

I'm trying to read Google Places API from an Android app, I've written similar code in Eclipse and it runs successfully, however when I changed it for Android it breaks:

public constructor(double lat, double lng, int maxPrice, double distance) throws Exception {
        responseBuilder = new StringBuilder();
        //Format the params
        query = String.format("type=%s&maxprice=%s&opennow=%s&key=%s&location=%s&radius=%s",
                URLEncoder.encode(type,charset),
                URLEncoder.encode(String.valueOf(maxPrice),charset),
                URLEncoder.encode(opennow,charset),
                URLEncoder.encode(apiKey,charset),
                URLEncoder.encode(lat + "," + lng,charset),
                URLEncoder.encode(String.valueOf(distance),charset));
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    //Create a connection with the website
                    HttpURLConnection connection = (HttpURLConnection) new URL(url + "?" + query).openConnection();
                    //Set the requrest property
                    connection.setRequestProperty("Accept-Charset", charset);
                    //Get the response
                    InputStream response = connection.getInputStream();
                    //Scan the response
                    Scanner responseScanner = new Scanner(response);
                    while(responseScanner.hasNextLine()) {
                        responseBuilder.append(responseScanner.nextLine());
                    }
                    responseScanner.close();
                    obj = new JSONObject(responseBuilder.toString());
                    //arr is a global variable
                    arr = obj.getJSONArray("results");
                    setRandNumber();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

When I try to access an element (even the first) in arr,

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int org.json.JSONArray.length()' on a null object reference
                      at com.example.turtl.project.picker.ispopulated(picker.java:72)
                      at com.example.turtl.project.MainActivity.getRestaurant(MainActivity.java:67)
                      at java.lang.reflect.Method.invoke(Native Method) 
                      at android.support.v7.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:288) 
                      at android.view.View.performClick(View.java:5610) 
                      at android.view.View$PerformClick.run(View.java:22260) 
                      at android.os.Handler.handleCallback(Handler.java:751) 
                      at android.os.Handler.dispatchMessage(Handler.java:95) 
                      at android.os.Looper.loop(Looper.java:154) 
                      at android.app.ActivityThread.main(ActivityThread.java:6077) 
                      at java.lang.reflect.Method.invoke(Native Method) 
                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865) 
                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755) 
Application terminated.

This is the offending function:

public void getResult(View view) throws Exception {
        EditText priceText = (EditText) findViewById(R.id.maxPrice);
        EditText mileText = (EditText) findViewById(R.id.searchSize);
        if (criteriaIsNull(priceText, mileText)) {
            showAlert("Invalid Fields", "Please set a max price and a distance to search");
        } else {
            miles = Integer.parseInt(mileText.getText().toString());
            double meters = milesToMeters(miles);
            maxPrice = Integer.parseInt(priceText.getText().toString());
            if ((miles != previousMiles || maxPrice != previousMaxPrice) && !criteriaIsNull(priceText, mileText)) {
                previousMaxPrice = maxPrice;
                previousMiles = miles;
                picker = new picker(loc.getLatitude(), loc.getLongitude(), maxPrice, meters);
                if (picker.ispopulated()){
                    //This line specifically
                    showAlert(picker.getResultName(), picker.getResultAddress());
                } else {
                    wait(1000);
                }
            } else {
                picker.getNewPlace();
                showAlert(picker.getResultName(), picker.getResultAddress());
            }
        }
    }

This is a function I wrote to check if the array was being populated, it also crashes since it calls a method of arr:

 public boolean ispopulated() {
        return (arr.length()>0);
    }

I checked if the call was coming too fast and the array wasn't given time to populate, but I had it wait 10 seconds, and 100 seconds and still the code crashed when it reached that line. I used URLConnection when I was originally writing the code, but changed to HTTPURLConnection when it didn't work and I read some other questions.

Is this a valid way to perform an API call for a JSON response in Android? Is there a better way I should be using? I'm new to Android development so I'm not familiar with its best practices. Any help is appreciated.

CS2016
  • 331
  • 1
  • 3
  • 15

1 Answers1

0

From your code, I assume you want to show places in your Android App satisfying a filter.

Google recommends to first use Google Places API for Android. If that doesn't fit your use case, and you need to use Google Places API for Web Service, please do so through a proxy server. The main benefit of using proxy server is securing your API key. Plus, you can prevent excessive data being pushed to your Android client.

If you are looking for best library for coding on server, use Client libraries for Google Maps Web Service.

And, since you are coding in Java, use Java client library for Google Maps API Web Services

BhalchandraSW
  • 714
  • 5
  • 13
  • Thank you, that's exactly what I was looking for, I don't know why I didn't find these resources before. – CS2016 Mar 26 '17 at 20:21