Android : Around me Tutorial

android-256This android tutorial deals about creating an “Around me” screen for your application. “Around me” shows near places around you using your current location. There are different possibilities to retrieve the near points.

The first one is to use Google Places API. You can use it for common places but it may not fit your needs :

The conclusion may be for you : DIY (do it yourself) and this is precisely the goal of this tutorial. I will show you two possible solutions :

Look at the video below to see the result of the tutorial :

Test before
If you wish to test before, you can install the application with the following link. The whole source code of the project is also available on github.

Your app idea

Let’s start coding !

Place bean

The first thing to do is to create the Place class. The distance attribute contains the distance between the place and the user location.

public class Place {

    private long id;
    private String name;
    private String country;
    private String image;
    private Location location;
    private float distance;

    public long getId() {
        return id;

    public void setId(long id) { = id;

    public String getName() {
        return name;

    public void setName(String name) { = name;

    public Location getLocation() {
        return location;

    public void setLocation(Location location) {
        this.location = location;

    public float getDistance() {
        return distance;

    public void setDistance(float distance) {
        this.distance = distance;

    public String getCountry() {
        return country;

    public void setCountry(String country) { = country;

    public String getImage() {
        return image;

    public void setImage(String image) {
        this.image = image;


Then, we need a service to retrieve the near places. This is the role of the interface PlaceProvider. You will see later about the two implementations : PlaceLocalProvider and PlaceRemoteProvider. The interface has a method onLocationChanged that must called when the user location changes. The method onPlaceLoadFinished of the callback must be invoked by the PlaceProvider implementation when the places are loaded.

public interface PlaceProvider {

    public void onLocationChanged(Location location);

    public void onDestroy();

    public interface PlaceLoaderCallback {
        public void onPlaceLoadFinished( List<Place> places );


You will need two layouts : one for the list, and one for the list item. In the first layout, we will display information about the user location : city and country and below, the list of the near places. In the layout of the list item, we will display the name of the place, the country, a image, and the distance from the user location.


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android=""





<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout xmlns:android=""
   android:orientation="vertical" android:layout_width="match_parent"







As we have a ListView, we need the adapter for it. There is nothing special except one thing to notice : i have used the excellent library Android-Universal-Image-Loader to load the images over the network. So, you have to download it and configure it into your project.

public class PlaceListAdapter extends ArrayAdapter<Place> {

    private List<Place> mPlaces;

    public PlaceListAdapter(Context context, int textViewResourceId, List<Place> objects) {
        super(context, textViewResourceId, objects);
        mPlaces = objects;

    public View getView(int position, View view, ViewGroup viewGroup) {

        View updateView;
        ViewHolder viewHolder;
        if (view == null) {
            LayoutInflater inflater = LayoutInflater.from(getContext());
            updateView = inflater.inflate(R.layout.aroundme_listitem, null);

            viewHolder = new ViewHolder();

            viewHolder.placeNameView = (TextView) updateView
            viewHolder.placeDistanceView = (TextView) updateView

            viewHolder.placeCountryView = (TextView) updateView

            viewHolder.placeImageView = (ImageView) updateView

        } else {
            updateView = view;
            viewHolder = (ViewHolder) updateView.getTag();

        Place place = getItem(position);
        viewHolder.placeDistanceView.setText(this.getContext().getString(R.string.aroundme_placedistance, (int) (place.getDistance() / 1000)));
        ImageLoader.getInstance().displayImage(place.getImage(), viewHolder.placeImageView);

        return updateView;

    private static class ViewHolder {
        public TextView placeNameView;
        public TextView placeDistanceView;
        public TextView placeCountryView;
        public ImageView placeImageView;


At least but not the less, here’s the code of the fragment that you will have to include into your project.
There are severals things to notice :

The sequency is the following :

  1. Google Play Services invokes the method onLocationChanged of the fragment when user location has changed.
  2. From the new location, the real address is updated using the Geocoder class.
  3. From the new location, the onLocationChanged of the PlaceProvider is invoked to get the new near places.
  4. The fragment is passed as the callback of the PlaceProvider (implements PlaceLocalProvider.PlaceLoaderCallback). The method onPlaceLoadFinished is invoked when new near places are available, so, in this method, we set up the new data in the list adapter, and notify it that its data has changed.
  5. /ol>

    public class AroundMeFragment extends Fragment implements GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener, LocationListener, PlaceLocalProvider.PlaceLoaderCallback {

        private LocationClient mLocationClient;

        private LocationRequest mRequest;

        private Geocoder mGeocoder;

        private PlaceListAdapter mPlaceListAdapter;

        private String mCityName;

        private PlaceProvider mPlaceProvider ;

        public void onCreate(Bundle savedInstanceState) {
            ((YourApplication) getActivity().getApplication()).inject(this);

            mLocationClient = new LocationClient(this.getActivity().getApplicationContext(), this, this);
            mRequest = LocationRequest.create()

            mGeocoder = new Geocoder(this.getActivity(), Locale.getDefault());

            mPlaceListAdapter = new PlaceListAdapter(getActivity(),, new ArrayList<Place>());
            if (savedInstanceState != null) {
                this.mCityName = savedInstanceState.getString("cityName");

            mPlaceProvider = new PlaceLocalProvider(this, this);

        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            View view = inflater.inflate(R.layout.aroundme_fragment, container, false);

            ListView listView = (ListView) view.findViewById(;
            listView.setOnScrollListener(new PauseOnScrollListener(ImageLoader.getInstance(), false, true));

            if (mCityName != null) {
                TextView textView = (TextView) view.findViewById(;

            return view ;

        public void onResume() {

            int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity());
            if (resultCode == ConnectionResult.SUCCESS){
                if (!mLocationClient.isConnected()) {
            } else{
                GooglePlayServicesUtil.getErrorDialog(resultCode, this.getActivity(), 1 ).show();

        public void onPause() {
            if ( mLocationClient.isConnected()) {

        public void onSaveInstanceState(Bundle outState) {
            outState.putString("cityName", this.mCityName);

        public void onConnected(Bundle bundle) {
            mLocationClient.requestLocationUpdates(mRequest, this);

        public void onDisconnected() {

        public void onLocationChanged(Location location) {
            if (BuildConfig.DEBUG) {
                Log.d(YourApplication.LOG_TAG, "AroundmeFragment.onLocationChanged() - new loc: " + location);

            try {
                List<Address> addresses = mGeocoder.getFromLocation(location.getLatitude(), location.getLongitude(), 1);

                if(addresses != null && !addresses.isEmpty()) {
                    Address address = addresses.get(0);
                    this.mCityName = address.getLocality() + " (" + address.getCountryName() + ")";
                    TextView textView = (TextView) getView().findViewById(;

                this.mPlaceProvider.onLocationChanged( location );
            } catch( Exception e ) {
                Log.e(YourApplication.LOG_TAG, "AroundmeFragment.onLocationChanged()", e );

        public void onConnectionFailed(ConnectionResult connectionResult) {
            Log.e(YourApplication.LOG_TAG, "AroundmeFragment.onConnectionFailed()", e );

        public void onPlaceLoadFinished(List<Place> places) {
            for( Place place : places ) {

        public void onDestroy() {

    The first step is almost done. Include the fragment into your project and use the FragmentManager to display it. I will not explain about that as it is not the purpose of the tutorial. You can find a complete example in the github of the Your App Idea project.

    You can continue with the following tutorials :

    Share Button


    5 Responses to “Android : Around me Tutorial”

    1. Android : Around Me (local provider) | on December 21st, 2013 4:40 pm

      […] the “Around me” tutorial. If you have not read the first part, you must read it first : Around Me tutorial. The LocalPlaceProvider consists in loading the near points in the database. Sqlite has no geo […]

    2. Android : Around me (remote provider) | on December 23rd, 2013 9:54 pm

      […] the “Around me” tutorial. If you have not read the first part, you must read it first : Around Me tutorial. The RemotePlaceProvider consists in loading the near points from a remote webservice. The first […]

    3. Lupajz on March 15th, 2014 10:11 am

      This example is somehow acting weird. Everytime I resume this fragment even without moving phone by an centimeter I still get called onLocationChange. Logging the lat and lng from location in remote provider i get Result :
      03-15 10:00:33.267: D/Lokacia :(27817): lat: 49.0655095 lng :20.3001365
      03-15 10:00:36.230: D/Lokacia :(27817): lat: 49.0655095 lng :20.3001365

      completly same.

    4. Michenux on March 19th, 2014 1:36 pm

      I think this is because we disconnect on onPause() and reconnect on onResume().

    5. Alex on April 1st, 2014 11:57 am

      seems very nice ! I will try this tutorial right now !

    Leave a Reply