Tag Archives: AutoPlaceComplete Fragment android

PlaceAutoCompleteFragment with custom UI

Hello Guys,

I have used PlaceAutocomplete the updated one (fragment), earlier it was a normal textview provided by android but now Android has changed it to fragment and we have to integrate fragment in our xml layout file.

For this we require few things :

1) Getting SHA-1 fingerprint of keystore.

2) Using Project name and SHA-1, Get an API key from Google Console and integrate in project.

3) Including latest google play services gradle (8.4.0)
1) Getting SHA-1 fingerprint of keystore (Android Debug Key):

i) Launch Android studio.
ii) Select project in “Project” mode.
iii) Select “Gradle” tab, at right hand side.
iv) Explore it -> Project Name -> Tasks -> android -> signingReport.
v) At console (run) you will get both MD5 and SHA1 .

2) Getting API Key from Google Console :

i)Go to the Google Developers Console.
ii)Select a project, or create a new one.
iii)Click Continue to enable the Google Places API for Android.
iv)On the Credentials page, create an Android key and set the API credentials.
Note: If you have an existing Android key, you may use that key.
V)In the create key dialog, restrict usage to your Android apps—enter your app’s SHA-1 fingerprint and package name.  (which we created above).
vi) Click Create , now you can find API key and we can use it by integrating in Android Manifest of our project.

<application>
  ...
  <meta-data
      android:name="com.google.android.geo.API_KEY"
      android:value="YOUR_API_KEY"/>
</application>

In Application tag in manifest.

3) Including latest google play services gradle (8.4.0): 

compile 'com.google.android.gms:play-services-location:8.4.0'

just add this in build.gradle of project.

 

Now create Activity and include this in its layout. Note that the name attribute is having path of our custom AutoPlaceComplete class.

<fragment
    android:id="@+id/autocomplete_fragment"
    android:name="com.example.CustomPlaceAutoCompleteFragment"
    android:layout_width="match_parent"
    android:layout_height="wrap_content" />

 

Over here we have made our own custom place auto-complete by extending the PlaceAutoCompleteFragment, so that we can provide our own UI for AutoComplete.
CustomPlaceAutoCompleteFragment :

 

import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;

import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import com.google.android.gms.common.GooglePlayServicesRepairableException;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.places.AutocompleteFilter;
import com.google.android.gms.location.places.Place;
import com.google.android.gms.location.places.ui.PlaceAutocomplete;
import com.google.android.gms.location.places.ui.PlaceAutocompleteFragment;
import com.google.android.gms.location.places.ui.PlaceSelectionListener;
import com.google.android.gms.maps.model.LatLngBounds;
import com.example.R;

/**
 * Created by sunny on 22/12/15.
 */
public class CustomPlaceAutoCompleteFragment extends PlaceAutocompleteFragment {

    private EditText editSearch;

    private View zzaRh;
    private View zzaRi;
    private EditText zzaRj;
    @Nullable
    private LatLngBounds zzaRk;
    @Nullable
    private AutocompleteFilter zzaRl;
    @Nullable
    private PlaceSelectionListener zzaRm;

    public CustomPlaceAutoCompleteFragment() {
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View var4 = inflater.inflate(R.layout.layout_place_autocomplete, container, false);

        editSearch = (EditText) var4.findViewById(R.id.editWorkLocation);
        editSearch.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                zzzG();
            }
        });

        return var4;
    }


    public void onDestroyView() {
        this.zzaRh = null;
        this.zzaRi = null;
        this.editSearch = null;
        super.onDestroyView();
    }

    public void setBoundsBias(@Nullable LatLngBounds bounds) {
        this.zzaRk = bounds;
    }

    public void setFilter(@Nullable AutocompleteFilter filter) {
        this.zzaRl = filter;
    }

    public void setText(CharSequence text) {
        this.editSearch.setText(text);
        //this.zzzF();
    }

    public void setHint(CharSequence hint) {
        this.editSearch.setHint(hint);
        this.zzaRh.setContentDescription(hint);
    }

    public void setOnPlaceSelectedListener(PlaceSelectionListener listener) {
        this.zzaRm = listener;
    }

    private void zzzF() {
        boolean var1 = !this.editSearch.getText().toString().isEmpty();
        //this.zzaRi.setVisibility(var1?0:8);
    }

    private void zzzG() {
        int var1 = -1;

        try {
            Intent var2 = (new PlaceAutocomplete.IntentBuilder(2)).setBoundsBias(this.zzaRk).setFilter(this.zzaRl).zzeq(this.editSearch.getText().toString()).zzig(1).build(this.getActivity());
            this.startActivityForResult(var2, 1);
        } catch (GooglePlayServicesRepairableException var3) {
            var1 = var3.getConnectionStatusCode();
            Log.e("Places", "Could not open autocomplete activity", var3);
        } catch (GooglePlayServicesNotAvailableException var4) {
            var1 = var4.errorCode;
            Log.e("Places", "Could not open autocomplete activity", var4);
        }

        if (var1 != -1) {
            GoogleApiAvailability var5 = GoogleApiAvailability.getInstance();
            var5.showErrorDialogFragment(this.getActivity(), var1, 2);
        }

    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == 1) {
            if (resultCode == -1) {
                Place var4 = PlaceAutocomplete.getPlace(this.getActivity(), data);
                if (this.zzaRm != null) {
                    this.zzaRm.onPlaceSelected(var4);
                }

                this.setText(var4.getName().toString());
            } else if (resultCode == 2) {
                Status var5 = PlaceAutocomplete.getStatus(this.getActivity(), data);
                if (this.zzaRm != null) {
                    this.zzaRm.onError(var5);
                }
            }
        }

        super.onActivityResult(requestCode, resultCode, data);
    }

}

 

 

As we have used custom view so we are require to provide our own layout.
In our layout I have taken EditText and one location pin image at its right side.

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical">


    <EditText
        android:id="@+id/editWorkLocation"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:drawableRight="@drawable/ic_pin_blue" //Pin image
        android:editable="false"
        android:hint="@string/work_business_location"
        android:singleLine="true"
        android:textColor="@color/black"
        android:textSize="@dimen/txt_14sp" />

</LinearLayout>

 

As its been included in xml (layout), now we can call it from code side.
Write the below code in onCreate or onCreateView (if fragment is used) :

 

// Retrieve the PlaceAutocompleteFragment.
PlaceAutocompleteFragment autocompleteFragment = (PlaceAutocompleteFragment)
        getActivity().getFragmentManager().findFragmentById(R.id.autocomplete_fragment);

// Register a listener to receive callbacks when a place has been selected or an error has
// occurred.
autocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
    @Override
    public void onPlaceSelected(Place place) {
        // TODO: Get info about the selected place.
        Log.i(TAG, "Place: " + place.getName());
Log.i(TAG, "Place Selected: " + place.getName() + "  " + place.getLatLng());

        double workLatitude = place.getLatLng().latitude;
        double workLongitude = place.getLatLng().longitude;

      //Over we can get the address, rating, price level,etc.

    }

    @Override
    public void onError(Status status) {
        // TODO: Handle the error.
        Log.i(TAG, "An error occurred: " + status);
    }
  });

 

Or implement PlaceSelectionListener in your Activity or fragment.

Now you can finally execute the project and on click of EditText, fragment will get open and you can get locations based on your typed string.
Also do not try to remove Google keyword from fragment (which gets open), as its been mandatory to show  “Powered by Google ” text in PlaceAutoComplete.

Check other blogs like Volley PART I, Image uploading and downloading using volley (in coming blog), etc.