Tuesday, 19 April 2016

Auto Complete for Location Search

Hi!


Today we are going to learn about the Auto-complete location searching feature in Android, In IOS it is very simple. But in android we have to take some effort to do that.

Type and search the location in android very common and mandatory feature for some application. With the help of Google we can achieve this.

Array Adopter to collect data form Google


package XXXX.raj.tot.xxxxxxxxxx.Common;

import android.content.Context;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.Toast;

import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.places.AutocompleteFilter;
import com.google.android.gms.location.places.AutocompletePrediction;
import com.google.android.gms.location.places.AutocompletePredictionBuffer;
import com.google.android.gms.location.places.Places;
import com.google.android.gms.maps.model.LatLngBounds;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.concurrent.TimeUnit;

public class Place_A extends ArrayAdapter<Place_A.PlaceAutocomplete> implements Filterable {
    private static final String TAG = "PlaceArrayAdapter";
    private GoogleApiClient mGoogleApiClient;
    private AutocompleteFilter mPlaceFilter;
    private LatLngBounds mBounds;
    private ArrayList<PlaceAutocomplete> mResultList;

    /**     * Constructor     *     * @param context  Context     * @param resource Layout resource     * @param bounds   Used to specify the search bounds     * @param filter   Used to specify place types     */    public Place_A(Context context, int resource, LatLngBounds bounds,
                   AutocompleteFilter filter) {
        super(context, resource);
        mBounds = bounds;
        mPlaceFilter = filter;
    }

    public void setGoogleApiClient(GoogleApiClient googleApiClient) {
        if (googleApiClient == null || !googleApiClient.isConnected()) {
            mGoogleApiClient = null;
        } else {
            mGoogleApiClient = googleApiClient;
        }
    }

    @Override    public int getCount() {
        return mResultList.size();
    }

    @Override    public PlaceAutocomplete getItem(int position) {
        return mResultList.get(position);
    }

    private ArrayList<PlaceAutocomplete> getPredictions(CharSequence constraint) {
        if (mGoogleApiClient != null) {
            Log.i(TAG, "Executing autocomplete query for: " + constraint);
            PendingResult<AutocompletePredictionBuffer> results =
                    Places.GeoDataApi                            .getAutocompletePredictions(mGoogleApiClient, constraint.toString(),
                                    mBounds, mPlaceFilter);
            // Wait for predictions, set the timeout.            AutocompletePredictionBuffer autocompletePredictions = results
                    .await(60, TimeUnit.SECONDS);
            final Status status = autocompletePredictions.getStatus();
            if (!status.isSuccess()) {
                Toast.makeText(getContext(), "Error: " + status.toString(),
                        Toast.LENGTH_SHORT).show();
                Log.e(TAG, "Error getting place predictions: " + status
                        .toString());
                autocompletePredictions.release();
                return null;
            }

            Log.i(TAG, "Query completed. Received " + autocompletePredictions.getCount()
                    + " predictions.");
            Iterator<AutocompletePrediction> iterator = autocompletePredictions.iterator();
            ArrayList resultList = new ArrayList<>(autocompletePredictions.getCount());
            while (iterator.hasNext()) {
                AutocompletePrediction prediction = iterator.next();
                resultList.add(new PlaceAutocomplete(prediction.getPlaceId(),
                        prediction.getDescription()));
            }
            // Buffer release            autocompletePredictions.release();
            return resultList;
        }
        Log.e(TAG, "Google API client is not connected.");
        return null;
    }

    @Override    public Filter getFilter() {
        Filter filter = new Filter() {
            @Override            protected FilterResults performFiltering(CharSequence constraint) {
                FilterResults results = new FilterResults();
                if (constraint != null) {
                    // Query the autocomplete API for the entered constraint                    mResultList = getPredictions(constraint);
                    if (mResultList != null) {
                        // Results                        results.values = mResultList;
                        results.count = mResultList.size();
                    }
                }
                return results;
            }

            @Override            protected void publishResults(CharSequence constraint, FilterResults results) {
                if (results != null && results.count > 0) {
                    // The API returned at least one result, update the data.                    notifyDataSetChanged();
                } else {
                    // The API did not return any results, invalidate the data set.                    notifyDataSetInvalidated();
                }
            }
        };
        return filter;
    }

    class PlaceAutocomplete {

        public CharSequence placeId;
        public CharSequence description;

        PlaceAutocomplete(CharSequence placeId, CharSequence description) {
            this.placeId = placeId;
            this.description = description;
        }

        @Override        public String toString() {
            return description.toString();
        }
    }
}



Main Class for Search Location



package XXXX.raj.tot.xxxxxxxxxx.Common;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.text.Html;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.location.places.Place;
import com.google.android.gms.location.places.PlaceBuffer;
import com.google.android.gms.location.places.Places;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;

import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.List;

import XXXX.raj.cp.helper.JSONParser;
import XXXX.raj.tot.xxxxxxxxxx.Others.URL_Loader;import XXXX.raj.tot.xxxxxxxxxx.R;import XXXX.raj.tot.xxxxxxxxxx.tracking_b.Vehicle_B;

public class PlaceSearch extends AppCompatActivity implements GoogleApiClient.OnConnectionFailedListener, GoogleApiClient.ConnectionCallbacks {

    // Google Info    private static final String LOG_TAG = "MainActivity";
    private static final int GOOGLE_API_CLIENT_ID = 0;
    private GoogleApiClient mGoogleApiClient;
    private static final LatLngBounds BOUNDS_MOUNTAIN_VIEW = new LatLngBounds(new LatLng(37.398160, -122.180831), new LatLng(37.430610, -121.972090));

    // Adoptr abjt    private Place_A from_adptr_loc;

    // Local var    private AutoCompleteTextView aet_from_location, aet_to_location;
    EditText et_trking_id;
    Spinner spn_trk_num;
    CheckBox chbk_is_fav;
    Button btn_get_direct;
    String F_name, F_address, F_place_ID, F_Lat_Long, T_name, T_address, T_place_ID, T_Lat_Long, Trking_id, Slt_vcl_id, Slt_vcl_nm, Slt_vcl_num;
    boolean is_Slted;
    ArrayList<Vehicle_B> array_vcl;
    ArrayList<String> array_vcl_name;
    String rout_for;

@Overrideprotected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_place_search);
    rout_for = getIntent().getStringExtra("rout_for");

    mGoogleApiClient = new GoogleApiClient.Builder(PlaceSearch.this)
            .addApi(Places.GEO_DATA_API)
            .enableAutoManage(this, GOOGLE_API_CLIENT_ID, this)
            .addConnectionCallbacks(this)
            .build();

    aet_from_location = (AutoCompleteTextView) findViewById(R.id
            .aet_from_location);
    aet_from_location.setThreshold(3);
    aet_to_location = (AutoCompleteTextView) findViewById(R.id
            .aet_to_location);
    aet_to_location.setThreshold(3);
    btn_get_direct = (Button) findViewById(R.id.btn_get_direct);
    et_trking_id = (EditText) findViewById(R.id.et_trking_id);
    spn_trk_num = (Spinner) findViewById(R.id.spn_trk_num);
    chbk_is_fav = (CheckBox) findViewById(R.id.chbk_is_fav);

    aet_from_location.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            final Place_A.PlaceAutocomplete item = from_adptr_loc.getItem(position);
            final String placeId = String.valueOf(item.placeId);
            Log.i(LOG_TAG, "Selected: " + item.description);
            PendingResult<PlaceBuffer> placeResult = Places.GeoDataApi                    .getPlaceById(mGoogleApiClient, placeId);
            placeResult.setResultCallback(from_Loc_mUpdatePlaceDetailsCallback);
            Log.i(LOG_TAG, "Fetching details for ID: " + item.placeId);
        }
    });

    from_adptr_loc = new Place_A(this, android.R.layout.simple_list_item_1,
            BOUNDS_MOUNTAIN_VIEW, null);
    aet_from_location.setAdapter(from_adptr_loc);
    aet_to_location.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            final Place_A.PlaceAutocomplete item = from_adptr_loc.getItem(position);
            final String placeId = String.valueOf(item.placeId);
            Log.i(LOG_TAG, "Selected: " + item.description);
            PendingResult<PlaceBuffer> placeResult = Places.GeoDataApi                    .getPlaceById(mGoogleApiClient, placeId);
            placeResult.setResultCallback(to_Loc_mUpdatePlaceDetailsCallback);
            Log.i(LOG_TAG, "Fetching details for ID: " + item.placeId);
        }
    });
    aet_to_location.setAdapter(from_adptr_loc);
}
private ResultCallback<PlaceBuffer> to_Loc_mUpdatePlaceDetailsCallback        = new ResultCallback<PlaceBuffer>() {
    @Override    public void onResult(PlaceBuffer places) {
        if (!places.getStatus().isSuccess()) {
            Log.e(LOG_TAG, "Place query did not complete. Error: " +
                    places.getStatus().toString());
            return;
        }
        // Selecting the first object buffer.        final Place place = places.get(0);

        CharSequence attributions = places.getAttributions();
        T_name = String.valueOf(Html.fromHtml(place.getName() + ""));
        T_address = String.valueOf(Html.fromHtml(place.getAddress() + ""));
        T_place_ID = String.valueOf(Html.fromHtml(place.getId() + ""));
        T_Lat_Long = String.valueOf(Html.fromHtml(place.getLatLng() + ""));

       /* mNameTextView.setText(Html.fromHtml(place.getName() + ""));        mAddressTextView.setText(Html.fromHtml(place.getAddress() + ""));        mIdTextView.setText(Html.fromHtml(place.getId() + ""));        mPhoneTextView.setText(Html.fromHtml(place.getPhoneNumber() + ""));        mWebTextView.setText(place.getWebsiteUri() + "");        if (attributions != null) {            mAttTextView.setText(Html.fromHtml(attributions.toString()));        }*/    }
};

private ResultCallback<PlaceBuffer> from_Loc_mUpdatePlaceDetailsCallback        = new ResultCallback<PlaceBuffer>() {
    @Override    public void onResult(PlaceBuffer places) {
        if (!places.getStatus().isSuccess()) {
            Log.e(LOG_TAG, "Place query did not complete. Error: " +
                    places.getStatus().toString());
            return;
        }
        // Selecting the first object buffer.        final Place place = places.get(0);
        CharSequence attributions = places.getAttributions();
        F_name = String.valueOf(Html.fromHtml(place.getName() + ""));
        F_address = String.valueOf(Html.fromHtml(place.getAddress() + ""));
        F_place_ID = String.valueOf(Html.fromHtml(place.getId() + ""));
        F_Lat_Long = String.valueOf(Html.fromHtml(place.getLatLng() + ""));

       /* mNameTextView.setText(Html.fromHtml(place.getName() + ""));        mAddressTextView.setText(Html.fromHtml(place.getAddress() + ""));        mIdTextView.setText(Html.fromHtml(place.getId() + ""));        mPhoneTextView.setText(Html.fromHtml(place.getPhoneNumber() + ""));        mWebTextView.setText(place.getWebsiteUri() + "");        if (attributions != null) {            mAttTextView.setText(Html.fromHtml(attributions.toString()));        }*/    }
};


@Overridepublic void onConnected(Bundle bundle) {
    from_adptr_loc.setGoogleApiClient(mGoogleApiClient);
    Log.i(LOG_TAG, "Google Places API connected.");

}

@Overridepublic void onConnectionFailed(ConnectionResult connectionResult) {
    Log.e(LOG_TAG, "Google Places API connection failed with error code: "            + connectionResult.getErrorCode());

    Toast.makeText(this,
            "Google Places API connection failed with error code:" +
                    connectionResult.getErrorCode(),
            Toast.LENGTH_LONG).show();
}

@Overridepublic void onConnectionSuspended(int i) {
    from_adptr_loc.setGoogleApiClient(null);
    Log.e(LOG_TAG, "Google Places API connection suspended.");
}

private class GeocoderHandler extends Handler {
    @Override    public void handleMessage(Message message) {
        String locationAddress;
        switch (message.what) {
            case 1:
                Bundle bundle = message.getData();
                locationAddress = bundle.getString("address");
                break;
            default:
                locationAddress = null;
        }
        Toast.makeText(getApplicationContext(), locationAddress, Toast.LENGTH_LONG).show();
    }
}

}


View for the above Activity


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="horizontal">

    <LinearLayout        android:layout_width="fill_parent"        android:layout_height="fill_parent"        android:layout_margin="5dp"        android:background="@color/wt"        android:gravity="center"        android:orientation="vertical"        android:weightSum="85">

        <LinearLayout            android:layout_width="fill_parent"            android:layout_height="0dp"            android:layout_weight="20"            android:orientation="horizontal">

            <LinearLayout                android:layout_width="fill_parent"                android:layout_height="fill_parent"                android:orientation="horizontal">

                <AutoCompleteTextView                    android:id="@+id/aet_from_location"                    android:layout_width="fill_parent"                    android:layout_height="fill_parent"                    android:layout_centerHorizontal="true"                    android:hint="From Location" />
            </LinearLayout>

        </LinearLayout>

        <LinearLayout            android:layout_width="fill_parent"            android:layout_height="0dp"            android:layout_weight="20"            android:orientation="horizontal">

            <AutoCompleteTextView                android:id="@+id/aet_to_location"                android:layout_width="fill_parent"                android:layout_height="fill_parent"                android:layout_centerHorizontal="true"                android:hint="To Location" />
        </LinearLayout>

        <LinearLayout            android:layout_width="fill_parent"            android:layout_height="0dp"            android:layout_weight="15"            android:orientation="horizontal">

            <EditText                android:id="@+id/et_trking_id"                android:layout_width="fill_parent"                android:layout_height="fill_parent"                android:hint="TRUCKING ID" />
        </LinearLayout>

        <LinearLayout            android:layout_width="fill_parent"            android:layout_height="0dp"            android:layout_weight="15"            android:orientation="horizontal"            android:weightSum="100">

            <LinearLayout                android:layout_width="0dp"                android:layout_height="fill_parent"                android:layout_weight="60"                android:gravity="center"                android:orientation="horizontal"                android:padding="2dp">

                <Spinner                    android:id="@+id/spn_trk_num"                    android:layout_width="fill_parent"                    android:layout_height="fill_parent" />
            </LinearLayout>

            <LinearLayout                android:layout_width="0dp"                android:layout_height="fill_parent"                android:layout_weight="40"                android:gravity="center"                android:orientation="horizontal"                android:padding="2dp">

                <CheckBox                    android:id="@+id/chbk_is_fav"                    android:layout_width="fill_parent"                    android:layout_height="fill_parent"                    android:checked="false"                    android:text="Add To Favorite" />
            </LinearLayout>
        </LinearLayout>

        <LinearLayout            android:layout_width="fill_parent"            android:layout_height="0dp"            android:layout_weight="15"            android:orientation="horizontal">

            <Button                android:id="@+id/btn_get_direct"                android:layout_width="fill_parent"                android:layout_height="fill_parent"                android:layout_margin="3dp"                android:background="@color/orng"                android:text="Get Direction"                android:textColor="@color/wt" />
        </LinearLayout>

    </LinearLayout>

</LinearLayout>


Add Permission to your Manifest file


   <uses-permission android:name="android.permission.INTERNET" />
   <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
   <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
   <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
   <!--The ACCESS_COARSE/FINE_LOCATION permissions are not required to use        Google Maps Android API v2, but are recommended.   -->   <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
   <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

<meta-data    android:name="com.google.android.gms.version"    android:value="@integer/google_play_services_version" />
<meta-data    android:name="com.google.android.geo.API_KEY"    android:value="@string/google_maps_key" />





Thats All..,

Please Leave Your Comment..,


Have A Great Day..,





No comments:

Post a Comment