1. Download our Official Android App: Forums for Android!

Apps Android Store and call next_page_token

Discussion in 'Android Development' started by Ad621, Apr 7, 2016.

  1. Ad621

    Ad621 Newbie
    Thread Starter
    Rank:
    None
    Points:
    15
    Posts:
    14
    Joined:
    Apr 7, 2016

    Apr 7, 2016
    14
    0
    15
    Male
    Hi Guys! new here and im kinda stuck on a small issue. im working with google places on a small application m making and i'm currently able to show 20 markers on the map. I have a floating action button on my map screen and I was just wondering if theres a way to store and call the next_page_token so that when the user clicks on the floating button then it would display the 20 markers from the next page. I have the following code: (Lines 40 to 74)

    Code (Text):
    1.  public class MapsActivity extends FragmentActivity implements LocationListener {
    2.  
    3.     GoogleMap mMap;
    4.     double mLatitude = 0;
    5.     double mLongitude = 0;
    6.     HashMap<String, String> mMarkerPlaceLink = new HashMap<String, String>();
    7.  
    8.     @Override
    9.     protected void onCreate(Bundle savedInstanceState) {
    10.         super.onCreate(savedInstanceState);
    11.         setContentView(R.layout.activity_maps);
    12.         // Obtain the SupportMapFragment and get notified when the map is ready to be used.
    13.         SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
    14.                 .findFragmentById(R.id.map);
    15.         mMap = mapFragment.getMap();
    16.         // Enabling MyLocation in Google Map
    17.         mMap.setMyLocationEnabled(true);
    18.         mMap.getUiSettings().setCompassEnabled(true);
    19.         mMap.getUiSettings().setZoomControlsEnabled(true);
    20.  
    21.         // Getting LocationManager object from System Service
    22.         // LOCATION_SERVICE
    23.         LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
    24.  
    25.         // Creating a criteria object to retrieve provider
    26.         Criteria criteria = new Criteria();
    27.  
    28.         // Getting the name of the best provider
    29.         String provider = locationManager.getBestProvider(criteria, true);
    30.  
    31.         // Getting Current Location From GPS
    32.         Location location = locationManager.getLastKnownLocation(provider);
    33.  
    34.         // onLocationChanged(location);
    35.         if (location != null) {
    36.             onLocationChanged(location);
    37.         }
    38.  
    39.  
    40.  
    41.         StringBuilder sb = new StringBuilder(
    42.                 "https://maps.googleapis.com/maps/api/place/nearbysearch/json?");
    43.         sb.append("location=" + mLatitude + "," + mLongitude);
    44.         sb.append("&radius=1000");
    45.         sb.append("&key=PLACES_KEY");
    46.         // Creating a new non-ui thread task to download Google place json
    47.         // data
    48.         PlacesTask placesTask = new PlacesTask();
    49.  
    50.         // Invokes the "doInBackground()" method of the class PlaceTask
    51.         placesTask.execute(sb.toString());
    52.  
    53.         // Will display 20 more places returned form the next_page_token
    54.         FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab_more);
    55.         fab.setOnClickListener(new View.OnClickListener() {
    56.             @Override
    57.             public void onClick(View view) {
    58.                 Snackbar.make(view, "Finding you some more places!", Snackbar.LENGTH_LONG)
    59.                         .setAction("Action", null).show();
    60.  
    61.                 StringBuilder sb = new StringBuilder(
    62.                         "https://maps.googleapis.com/maps/api/place/nearbysearch/json?");
    63.                 sb.append("pagetoken=" );
    64.                 sb.append("&key=PLACES_KEY");
    65.                 // Creating a new non-ui thread task to download Google place json
    66.                 // data
    67.                 PlacesTask placesTask = new PlacesTask();
    68.  
    69.                 // Invokes the "doInBackground()" method of the class PlaceTask
    70.                 placesTask.execute(sb.toString());
    71.  
    72.             }
    73.         });
    74.  
    75.     }
    76.  
    77.  
    78.     /**
    79.      * A method to download json data from url
    80.      */
    81.     private String downloadUrl(String strUrl) throws IOException {
    82.         String data = "";
    83.         InputStream iStream = null;
    84.         HttpURLConnection urlConnection = null;
    85.         try {
    86.             URL url = new URL(strUrl);
    87.  
    88.             // Creating an http connection to communicate with url
    89.             urlConnection = (HttpURLConnection) url.openConnection();
    90.  
    91.             // Connecting to url
    92.             urlConnection.connect();
    93.  
    94.             // Reading data from url
    95.             iStream = urlConnection.getInputStream();
    96.  
    97.             BufferedReader br = new BufferedReader(new InputStreamReader(
    98.                     iStream));
    99.  
    100.             StringBuffer sb = new StringBuffer();
    101.  
    102.             String line = "";
    103.             while ((line = br.readLine()) != null) {
    104.                 sb.append(line);
    105.             }
    106.  
    107.             data = sb.toString();
    108.             Log.d("data", "json response: " + data);
    109.             br.close();
    110.  
    111.         } catch (Exception e) {
    112.             Log.d("Exception while downloading url", e.toString());
    113.         } finally {
    114.             iStream.close();
    115.             urlConnection.disconnect();
    116.         }
    117.  
    118.         return data;
    119.     }
    120.  
    121.  
    122.     /**
    123.      * A class, to download Google Places
    124.      */
    125.     private class PlacesTask extends AsyncTask<String, Integer, String> {
    126.  
    127.         String data = null;
    128.  
    129.         // Invoked by execute() method of this object
    130.         @Override
    131.         protected String doInBackground(String... url) {
    132.             try {
    133.                 data = downloadUrl(url[0]);
    134.             } catch (Exception e) {
    135.                 Log.d("Background Task", e.toString());
    136.             }
    137.             return data;
    138.         }
    139.  
    140.         // Executed after the complete execution of doInBackground() method
    141.         @Override
    142.         protected void onPostExecute(String result) {
    143.             ParserTask parserTask = new ParserTask();
    144.  
    145.             // Start parsing the Google places in JSON format
    146.             // Invokes the "doInBackground()" method of the class ParseTask
    147.             parserTask.execute(result);
    148.         }
    149.  
    150.     }
    151.  
    152.     /**
    153.      * A class to parse the Google Places in JSON format
    154.      */
    155.     private class ParserTask extends
    156.             AsyncTask<String, Integer, List<HashMap<String, String>>> {
    157.  
    158.         JSONObject jObject;
    159.  
    160.         // Invoked by execute() method of this object
    161.         @Override
    162.         protected List<HashMap<String, String>> doInBackground(
    163.                 String... jsonData) {
    164.  
    165.             List<HashMap<String, String>> places = null;
    166.             PlaceJSONParser placeJsonParser = new PlaceJSONParser();
    167.  
    168.             try {
    169.                 jObject = new JSONObject(jsonData[0]);
    170.  
    171.                 /** Getting the parsed data as a List construct */
    172.                 places = placeJsonParser.parse(jObject);
    173.  
    174.             } catch (Exception e) {
    175.                 Log.d("Exception", e.toString());
    176.             }
    177.             return places;
    178.         }
    179.  
    180.         // Executed after the complete execution of doInBackground() method
    181.         @Override
    182.         protected void onPostExecute(List<HashMap<String, String>> list) {
    183.  
    184.             // Clears all the existing markers
    185.             mMap.clear();
    186.             for (int i = 0; i < list.size(); i++) {
    187.  
    188.                 // Creating a marker
    189.                 MarkerOptions markerOptions = new MarkerOptions();
    190.  
    191.                 // Getting a place from the places list
    192.                 HashMap<String, String> hmPlace = list.get(i);
    193.  
    194.                 // Getting latitude of the place
    195.                 double lat = Double.parseDouble(hmPlace.get("lat"));
    196.  
    197.                 // Getting longitude of the place
    198.                 double lng = Double.parseDouble(hmPlace.get("lng"));
    199.  
    200.                 // Getting name
    201.                 String name = hmPlace.get("place_name");
    202.  
    203.                 String vicinity = hmPlace.get("vicinity");
    204.  
    205.                 LatLng latLng = new LatLng(lat, lng);
    206.  
    207.                 // Setting the position for the marker
    208.                 markerOptions.position(latLng);
    209.  
    210.                 markerOptions.title(name);
    211.  
    212.                 markerOptions.snippet(vicinity);
    213.  
    214.                 // Placing a marker on the touched position
    215.                 Marker m = mMap.addMarker(markerOptions);
    216.  
    217.                 // Linking Marker id and place reference
    218.  
    219.                 mMarkerPlaceLink.put(m.getId(), hmPlace.get("reference"));
    220.  
    221.             }
    222.  
    223.         }
    224.     }
    225.  
    226.     @Override
    227.     public void onLocationChanged(Location location) {
    228.         mLatitude = location.getLatitude();
    229.         mLongitude = location.getLongitude();
    230.         LatLng latLng = new LatLng(mLatitude, mLongitude);
    231.         mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
    232.         mMap.animateCamera(CameraUpdateFactory.zoomTo(15));
    233.  
    234.     }
    235.  
    236.     @Override
    237.     public void onStatusChanged(String provider, int status, Bundle extras) {
    238.  
    239.     }
    240.  
    241.     @Override
    242.     public void onProviderEnabled(String provider) {
    243.  
    244.     }
    245.  
    246.     @Override
    247.     public void onProviderDisabled(String provider) {
    248.  
    249.     }
    250. }
    251.  
    My JSONParser class:

    Code (Text):
    1.  
    2. public class PlaceJSONParser {
    3.  
    4.  
    5.  
    6.     /** Receives a JSONObject and returns a list */
    7.     public List<HashMap<String,String>> parse(JSONObject jObject){
    8.  
    9.         JSONArray jPlaces = null;
    10.         try {
    11.             /** Retrieves all the elements in the 'places' array */
    12.             jPlaces = jObject.getJSONArray("results");
    13.         } catch (JSONException e) {
    14.             e.printStackTrace();
    15.         }
    16.         /** Invoking getPlaces with the array of json object
    17.          * where each json object represent a place
    18.          */
    19.         return getPlaces(jPlaces);
    20.     }
    21.  
    22.  
    23.     private List<HashMap<String, String>> getPlaces(JSONArray jPlaces){
    24.         int placesCount = jPlaces.length();
    25.         List<HashMap<String, String>> placesList = new ArrayList<HashMap<String,String>>();
    26.         HashMap<String, String> place = null;
    27.  
    28.         /** Taking each place, parses and adds to list object */
    29.         for(int i=0; i<placesCount;i++){
    30.             try {
    31.                 /** Call getPlace with place JSON object to parse the place */
    32.                 place = getPlace((JSONObject)jPlaces.get(i));
    33.                 placesList.add(place);
    34.  
    35.             } catch (JSONException e) {
    36.                 e.printStackTrace();
    37.             }
    38.         }
    39.  
    40.         return placesList;
    41.     }
    42.  
    43.     /** Parsing the Place JSON object */
    44.     private HashMap<String, String> getPlace(JSONObject jPlace){
    45.  
    46.         HashMap<String, String> place = new HashMap<String, String>();
    47.         String placeName = "-NA-";
    48.         String vicinity = "-NA-";
    49.         String latitude="";
    50.         String longitude="";
    51.         String reference="";
    52.  
    53.  
    54.         try {
    55.             // Extracting Place name, if available
    56.             if(!jPlace.isNull("name")){
    57.                 placeName = jPlace.getString("name");
    58.             }
    59.  
    60.             // Extracting Place Vicinity, if available
    61.             if(!jPlace.isNull("vicinity")){
    62.                 vicinity = jPlace.getString("vicinity");
    63.             }
    64.  
    65.             latitude = jPlace.getJSONObject("geometry").getJSONObject("location").getString("lat");
    66.             longitude = jPlace.getJSONObject("geometry").getJSONObject("location").getString("lng");
    67.             reference = jPlace.getString("reference");
    68.  
    69.  
    70.             place.put("place_name", placeName);
    71.             place.put("vicinity", vicinity);
    72.             place.put("lat", latitude);
    73.             place.put("lng", longitude);
    74.             place.put("reference", reference);
    75.  
    76.  
    77.         } catch (JSONException e) {
    78.             e.printStackTrace();
    79.         }
    80.         return place;
    81.     }
    82. }
    83.  
    84.  
    Currently ive hardcoded the next_page_token into my code and it seems to work, but it only works once, any ideas on how i could call and retrieve it automatically using a variable?

    Any info will be appreciated!
    Thanks!

     

    Advertisement

    #1 Ad621, Apr 7, 2016
    Last edited: Apr 7, 2016
  2. LV426

    LV426 I say we take off and nuke this place from orbit
    Moderator
    Rank:
     #11
    Points:
    1,988
    Posts:
    7,678
    Joined:
    Oct 16, 2015

    Oct 16, 2015
    7,678
    11,111
    1,988
    Male
    Software developer
    South West of England
    What's the "next_page_token"? Is it something returned by the google maps web service?
     
  3. Ad621

    Ad621 Newbie
    Thread Starter
    Rank:
    None
    Points:
    15
    Posts:
    14
    Joined:
    Apr 7, 2016

    Apr 7, 2016
    14
    0
    15
    Male
    Yeh, when you run google maps/places in Android Studio, my terminal prints out 20 places that are close to me. These 20 places are on "one page" the next_page_token holds the other 20 places along with all their information such as location, name, address etc etc.
     
  4. LV426

    LV426 I say we take off and nuke this place from orbit
    Moderator
    Rank:
     #11
    Points:
    1,988
    Posts:
    7,678
    Joined:
    Oct 16, 2015

    Oct 16, 2015
    7,678
    11,111
    1,988
    Male
    Software developer
    South West of England
    So it sounds like you need a piece of code in your ParserTask, which extracts the next page token from the returned Json data.
     
  5. Ad621

    Ad621 Newbie
    Thread Starter
    Rank:
    None
    Points:
    15
    Posts:
    14
    Joined:
    Apr 7, 2016

    Apr 7, 2016
    14
    0
    15
    Male
    Yeh i was thinking about that but not 100% sure to go about coding that and then calling that on the floating button click
     
  6. LV426

    LV426 I say we take off and nuke this place from orbit
    Moderator
    Rank:
     #11
    Points:
    1,988
    Posts:
    7,678
    Joined:
    Oct 16, 2015

    Oct 16, 2015
    7,678
    11,111
    1,988
    Male
    Software developer
    South West of England
    Well it depends on the structure of your Json data, which isn't shown. It would be something similar to what PlaceJSONParser.parse() is doing, although that code is not shown either.

    Once you have extracted the next page token from the returned data, assign it to a class variable, and use it in place of the constant value PLACES_KEY
     
  7. Ad621

    Ad621 Newbie
    Thread Starter
    Rank:
    None
    Points:
    15
    Posts:
    14
    Joined:
    Apr 7, 2016

    Apr 7, 2016
    14
    0
    15
    Male
    Ive edited my original post to include the JSONparser class.
    So in my JSONParser class would i basically assign the next_page_token to a variable similar to how ive done with the Name and Vicinity?
     
  8. LV426

    LV426 I say we take off and nuke this place from orbit
    Moderator
    Rank:
     #11
    Points:
    1,988
    Posts:
    7,678
    Joined:
    Oct 16, 2015

    Oct 16, 2015
    7,678
    11,111
    1,988
    Male
    Software developer
    South West of England
    Well I'd create a new method on the JSONParser class to do it. You can create a class variable in JSONParser class called nextPageToken. Then define a method called getNextPageToken() which will extract the token from the Json.
    Of course you need to know what the next page token element is called within the Json data structure. Do you know that? If not then you will need to examine jObject to see what it looks like.
     
  9. Ad621

    Ad621 Newbie
    Thread Starter
    Rank:
    None
    Points:
    15
    Posts:
    14
    Joined:
    Apr 7, 2016

    Apr 7, 2016
    14
    0
    15
    Male
    Not really sure how to do that :/
    Yes im able to see the next_page_token in my terminal although i believe its different for each page..
     
  10. LV426

    LV426 I say we take off and nuke this place from orbit
    Moderator
    Rank:
     #11
    Points:
    1,988
    Posts:
    7,678
    Joined:
    Oct 16, 2015

    Oct 16, 2015
    7,678
    11,111
    1,988
    Male
    Software developer
    South West of England
    Ok this would be an ideal point to learn how to set breakpoints in your code, and run your app in debug mode. If you set a breakpoint at the start of your parse() method, you can look at the jObject parameter and see what's in it.

    But doesn't the google maps API documentation tell you what data is returned?
     
  11. Ad621

    Ad621 Newbie
    Thread Starter
    Rank:
    None
    Points:
    15
    Posts:
    14
    Joined:
    Apr 7, 2016

    Apr 7, 2016
    14
    0
    15
    Male
    My terminal prints out the JSON data which is exactly the same as whats displayed on the google api website, similar to whats shown here: https://developers.google.com/places/web-service/search#PlaceSearchResponses
     
  12. LV426

    LV426 I say we take off and nuke this place from orbit
    Moderator
    Rank:
     #11
    Points:
    1,988
    Posts:
    7,678
    Joined:
    Oct 16, 2015

    Oct 16, 2015
    7,678
    11,111
    1,988
    Male
    Software developer
    South West of England
    Ok I see it's literally called "next_page_token". So you would call

    Code (Text):
    1.  
    2. nextPageToken = jObject.getString("next_page_token");
    3.  
     
  13. Ad621

    Ad621 Newbie
    Thread Starter
    Rank:
    None
    Points:
    15
    Posts:
    14
    Joined:
    Apr 7, 2016

    Apr 7, 2016
    14
    0
    15
    Male
    So id call that in my JSONParser class?
     
  14. LV426

    LV426 I say we take off and nuke this place from orbit
    Moderator
    Rank:
     #11
    Points:
    1,988
    Posts:
    7,678
    Joined:
    Oct 16, 2015

    Oct 16, 2015
    7,678
    11,111
    1,988
    Male
    Software developer
    South West of England
    Yes you could put it in the parse() method. Like I said, create a class variable called nextPageToken, and a method getNextPageToken() to access it.
     
  15. Ad621

    Ad621 Newbie
    Thread Starter
    Rank:
    None
    Points:
    15
    Posts:
    14
    Joined:
    Apr 7, 2016

    Apr 7, 2016
    14
    0
    15
    Male
    So would this work?
    Code (Text):
    1.  
    2. String next_page_token;
    3.  
    4. public String getNext_Page_token(){
    5.     return next_page_token;
    6. }
    7.  
    and then
    Code (Text):
    1.  next_page_token = jObject.getString("next_page_token");
    would go in my parse method?
     
  16. LV426

    LV426 I say we take off and nuke this place from orbit
    Moderator
    Rank:
     #11
    Points:
    1,988
    Posts:
    7,678
    Joined:
    Oct 16, 2015

    Oct 16, 2015
    7,678
    11,111
    1,988
    Male
    Software developer
    South West of England
    there's only one way to find out.. :)
     
  17. Ad621

    Ad621 Newbie
    Thread Starter
    Rank:
    None
    Points:
    15
    Posts:
    14
    Joined:
    Apr 7, 2016

    Apr 7, 2016
    14
    0
    15
    Male
    Does this look correct? i dont have any errors

    Code (Text):
    1.  
    2.     String next_page_token;
    3.  
    4. /** Receives a JSONObject and returns a list */
    5. public List<HashMap<String,String>> parse(JSONObject jObject){
    6.  
    7.     JSONArray jPlaces = null;
    8.     try {
    9.  
    10.         jPlaces = jObject.getJSONArray("results");
    11.         next_page_token = jObject.getString("next_page_token");
    12.  
    13.     } catch (JSONException e) {
    14.         e.printStackTrace();
    15.     }
    16.  
    17.     return getPlaces(jPlaces);
    18. }
    19.  
    20. public String getNext_Page_token(){
    21.     return next_page_token;
    22. }
    23.  
     
  18. LV426

    LV426 I say we take off and nuke this place from orbit
    Moderator
    Rank:
     #11
    Points:
    1,988
    Posts:
    7,678
    Joined:
    Oct 16, 2015

    Oct 16, 2015
    7,678
    11,111
    1,988
    Male
    Software developer
    South West of England
    looks allright to me
     
  19. Ad621

    Ad621 Newbie
    Thread Starter
    Rank:
    None
    Points:
    15
    Posts:
    14
    Joined:
    Apr 7, 2016

    Apr 7, 2016
    14
    0
    15
    Male
    Okay so i created an object
    Code (Text):
    1.  
    2. private PlaceJSONParser getToken;
    i then did

    Code (Text):
    1.  
    2. sb.append("pagetoken=" + getToken.getNext_Page_token());
    3.  
    and i keep getting an error
    Code (Text):
    1.  
    2.  Attempt to invoke virtual method 'java.lang.String com.example.test.outandabout.PlaceJSONParser.getNext_Page_token()' on a null object reference
     
  20. LV426

    LV426 I say we take off and nuke this place from orbit
    Moderator
    Rank:
     #11
    Points:
    1,988
    Posts:
    7,678
    Joined:
    Oct 16, 2015

    Oct 16, 2015
    7,678
    11,111
    1,988
    Male
    Software developer
    South West of England
    getToken is null

    You already created an instance of the parser

    Code (Text):
    1.  
    2. PlaceJSONParser placeJsonParser = new PlaceJSONParser();
    3.  
    Use that to invoke getNext_Page_Token()
     
  21. Ad621

    Ad621 Newbie
    Thread Starter
    Rank:
    None
    Points:
    15
    Posts:
    14
    Joined:
    Apr 7, 2016

    Apr 7, 2016
    14
    0
    15
    Male
    Ah yeah that worked! i just moved placeJsonParser to the top of the class and called it there!
    Thank you so much!!
     
  22. LV426

    LV426 I say we take off and nuke this place from orbit
    Moderator
    Rank:
     #11
    Points:
    1,988
    Posts:
    7,678
    Joined:
    Oct 16, 2015

    Oct 16, 2015
    7,678
    11,111
    1,988
    Male
    Software developer
    South West of England
    One other thing to be aware of is that the next_page_token is not always present in the returned data. It could be null, so you should put some defensive null-checking code in there, just to be on the safe side.
     
  23. Ad621

    Ad621 Newbie
    Thread Starter
    Rank:
    None
    Points:
    15
    Posts:
    14
    Joined:
    Apr 7, 2016

    Apr 7, 2016
    14
    0
    15
    Male
    Yeah i just realised that it refreshes the map twice but then it says that there is no "next_page_token" soo would a simple if statement be enough to check if nextpagetoken is null and if so then to tell the user that theyve reached the end of the list?
     
  24. LV426

    LV426 I say we take off and nuke this place from orbit
    Moderator
    Rank:
     #11
    Points:
    1,988
    Posts:
    7,678
    Joined:
    Oct 16, 2015

    Oct 16, 2015
    7,678
    11,111
    1,988
    Male
    Software developer
    South West of England
    I would actually disable the button if there is no more data.
     
  25. Ad621

    Ad621 Newbie
    Thread Starter
    Rank:
    None
    Points:
    15
    Posts:
    14
    Joined:
    Apr 7, 2016

    Apr 7, 2016
    14
    0
    15
    Male
    Ah thats a good idea! Thanks!
     

Share This Page

Loading...