com.seamusdawkins.autocomplete.MainActivity.java Source code

Java tutorial

Introduction

Here is the source code for com.seamusdawkins.autocomplete.MainActivity.java

Source

/*
*    The MIT License (MIT)
*
*   Copyright (c) 2016 Cleidimar Viana
*
*   Permission is hereby granted, free of charge, to any person obtaining a copy
*   of this software and associated documentation files (the "Software"), to deal
*   in the Software without restriction, including without limitation the rights
*   to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
*   copies of the Software, and to permit persons to whom the Software is
*   furnished to do so, subject to the following conditions:
*   The above copyright notice and this permission notice shall be included in all
*   copies or substantial portions of the Software.
*   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
*   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
*   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
*   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
*   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
*   OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
*   SOFTWARE.
*/
package com.seamusdawkins.autocomplete;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.Toast;

import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;

import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;

public class MainActivity extends AppCompatActivity implements OnMapReadyCallback, AdapterView.OnItemClickListener {

    public static final int REQUEST_PERMISSION = 221;

    private static String TAG = MainActivity.class.getSimpleName();

    /* These variables are meant to floatint action button */
    private FloatingActionButton floatButton;

    /* These variables are meant to autocomplete */
    private static final String LOG_TAG = "Google Places Autocomplete";
    private static final String PLACES_API_BASE = "https://maps.googleapis.com/maps/api/place";
    private static final String TYPE_AUTOCOMPLETE = "/autocomplete";
    private static final String OUT_JSON = "/json";

    public static ArrayList resultListReference;

    private Activity activity;
    private GoogleMap map;

    private boolean error;
    private String urlPost;
    private Double latitude, longitude;
    private String description;

    private AutoCompleteTextView autoCompView;

    private SupportMapFragment mapFragment;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        activity = this;

        initUI();
        initListener();

    }

    /**
     * This method maping xml interface with java.
     */
    public void initUI() {
        mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);

        autoCompView = (AutoCompleteTextView) findViewById(R.id.autoCompleteTextView);
        floatButton = (FloatingActionButton) findViewById(R.id.float_button);
    }

    /**
     * This method implementing a listener
     */
    public void initListener() {

        mapFragment.getMapAsync(this);
        autoCompView.setAdapter(new GooglePlacesAutocompleteAdapter(this, R.layout.list_item_autocomplete));
        autoCompView.setOnItemClickListener(this);

        floatButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String url = "https://github.com/cleidimarviana/places-autocomplete-and-gps-coordinates";
                Intent intent = new Intent(Intent.ACTION_VIEW);
                intent.setData(Uri.parse(url));
                startActivity(intent);
            }
        });

    }

    @Override
    public void onMapReady(GoogleMap map) {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            if (checkSelfPermission(
                    android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                    && checkSelfPermission(
                            android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                // TODO: Consider calling
                //    public void requestPermissions(@NonNull String[] permissions, int requestCode)
                // here to request the missing permissions, and then overriding
                //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                //                                          int[] grantResults)
                // to handle the case where the user grants the permission. See the documentation
                // for Activity#requestPermissions for more details.

                ActivityCompat.requestPermissions(this,
                        new String[] { android.Manifest.permission.ACCESS_FINE_LOCATION }, REQUEST_PERMISSION);
                return;
            }
        } else {
            //Do Your Stuff
        }
        map.setMyLocationEnabled(true);

        this.map = map;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        switch (requestCode) {
        case REQUEST_PERMISSION: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Add your function here which open camera
            } else {

            }
            return;
        }
        }
    }

    /**
     * This method will results show the autocomplete addresses
     *
     * @param input
     * @return list
     */
    public ArrayList autocomplete(String input) {
        ArrayList resultList = null;
        resultListReference = null;

        HttpURLConnection conn = null;
        StringBuilder jsonResults = new StringBuilder();
        try {
            StringBuilder sb = new StringBuilder(PLACES_API_BASE + TYPE_AUTOCOMPLETE + OUT_JSON);
            sb.append("?key=" + activity.getString(R.string.google_server_key));
            //sb.append("&components=country:br");
            sb.append("&input=" + URLEncoder.encode(input, "utf8"));

            URL url = new URL(sb.toString());
            conn = (HttpURLConnection) url.openConnection();
            InputStreamReader in = new InputStreamReader(conn.getInputStream());

            // Load the results into a StringBuilder
            int read;
            char[] buff = new char[1024];
            while ((read = in.read(buff)) != -1) {
                jsonResults.append(buff, 0, read);
            }
        } catch (MalformedURLException e) {
            Log.wtf(LOG_TAG, "Error processing Places API URL: " + e);
            return resultList;
        } catch (IOException e) {
            Log.wtf(LOG_TAG, "Error connecting to Places API: " + e);
            return resultList;
        } finally {
            if (conn != null) {
                conn.disconnect();
            }
        }

        try {
            // Create a JSON object hierarchy from the results
            JSONObject jsonObj = new JSONObject(jsonResults.toString());
            JSONArray predsJsonArray = jsonObj.getJSONArray("predictions");

            // Extract the Place descriptions from the results
            resultList = new ArrayList(predsJsonArray.length());
            resultListReference = new ArrayList();
            for (int i = 0; i < predsJsonArray.length(); i++) {
                System.out.println(predsJsonArray.getJSONObject(i).getString("description"));
                System.out.println(predsJsonArray.getJSONObject(i).getString("reference"));
                System.out.println("--------------------------------------------------------");
                resultList.add(predsJsonArray.getJSONObject(i).getString("description"));
                resultListReference.add(predsJsonArray.getJSONObject(i).getString("reference"));
            }
        } catch (JSONException e) {
            Log.wtf(LOG_TAG, "Cannot process JSON results: " + e);
        }

        return resultList;
    }

    public void onItemClick(AdapterView adapterView, View view, int position, long id) {
        hideKeyboard();

        description = (String) adapterView.getItemAtPosition(position);
        Toast.makeText(this, description, Toast.LENGTH_SHORT).show();

        String reference = (String) resultListReference.get(position);
        String urlLocate = "https://maps.googleapis.com/maps/api/place/details/json?key="
                + getString(R.string.google_server_key) + "&reference=" + reference;
        AsyncTaskNewsParseJson myTask = new AsyncTaskNewsParseJson();
        myTask.execute(urlLocate);

        autoCompView.setText("");

    }

    class GooglePlacesAutocompleteAdapter extends ArrayAdapter implements Filterable {
        private ArrayList resultList;

        public GooglePlacesAutocompleteAdapter(Context context, int textViewResourceId) {
            super(context, textViewResourceId);
        }

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

        @Override
        public Object getItem(int index) {
            return resultList.get(index);
        }

        @Override
        public Filter getFilter() {
            Filter filter = new Filter() {
                @Override
                protected FilterResults performFiltering(CharSequence constraint) {
                    FilterResults filterResults = new FilterResults();
                    if (constraint != null) {
                        // Retrieve the autocomplete results.
                        resultList = autocomplete(constraint.toString());

                        // Assign the data to the FilterResults
                        filterResults.values = resultList;
                        filterResults.count = resultList.size();
                    }
                    return filterResults;
                }

                @Override
                protected void publishResults(CharSequence constraint, FilterResults results) {
                    if (results != null && results.count > 0) {
                        notifyDataSetChanged();
                    } else {
                        notifyDataSetInvalidated();
                    }
                }
            };
            return filter;
        }
    }

    public class AsyncTaskNewsParseJson extends AsyncTask<String, String, String> {
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
        }

        @Override
        protected String doInBackground(String... url) {

            urlPost = url[0];
            try {

                JSONObject jsonObjPoints = doGet(activity, urlPost, "UTF-8");

                if (jsonObjPoints.length() != 0) {

                    JSONObject jsonObjectResult = jsonObjPoints.getJSONObject("result");
                    JSONObject jsonObjectGeometry = jsonObjectResult.getJSONObject("geometry");
                    JSONObject jsonObjLocation = jsonObjectGeometry.getJSONObject("location");
                    Log.wtf(TAG,
                            "lat:" + jsonObjLocation.getString("lat") + " lng:" + jsonObjLocation.getString("lng"));

                    latitude = jsonObjLocation.getDouble("lat");
                    longitude = jsonObjLocation.getDouble("lng");

                }
            } catch (JSONException e) {
                e.printStackTrace();
                error = true;
            } catch (Exception e) {
                e.printStackTrace();
                error = true;
            }
            return null;
        }

        @Override
        protected void onPostExecute(String result) {

            if (error) {
                error = false;
            }

            CameraUpdate zoom = CameraUpdateFactory.zoomTo(12);

            LatLng sydney = new LatLng(latitude, longitude);
            map.addMarker(new MarkerOptions().title(description).snippet("" + latitude + "," + longitude)
                    .position(sydney));

            CameraUpdate center = CameraUpdateFactory.newLatLng(sydney);

            map.moveCamera(center);
            map.animateCamera(CameraUpdateFactory.zoomIn());
            map.animateCamera(zoom, 3000, null);

        }
    }

    public static JSONObject doGet(Activity act, String url, String charset) {

        HttpGet conn = new HttpGet(url);
        conn.addHeader("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");

        JSONObject o = null;
        HttpResponse resp;
        int status = 0;
        resp = null;
        try {
            HttpClient httpClient = new DefaultHttpClient();
            resp = httpClient.execute(conn);

        } catch (ClientProtocolException e) {
        } catch (IOException e) {
        }
        try {
            if (resp != null) {

                status = resp.getStatusLine().getStatusCode();
            }
            if (status == 200) {

                InputStream content = resp.getEntity().getContent();
                BufferedReader buffer = new BufferedReader(new InputStreamReader(content));

                String text;
                StringBuilder sb = new StringBuilder();

                while ((text = buffer.readLine()) != null) {
                    sb.append(text);
                }

                return new JSONObject(sb.toString());
            } else {
                JSONObject obj = new JSONObject();
                obj.put("status", String.valueOf(status));
                return obj;
            }

        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

    /**
     * This method will hide the keyboard.
     */
    private void hideKeyboard() {
        View view = getCurrentFocus();
        if (view != null) {
            ((InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE))
                    .hideSoftInputFromWindow(view.getWindowToken(), InputMethodManager.HIDE_NOT_ALWAYS);
        }
    }
}