package com.commonusage.locationpicker;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.util.ArrayList;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Point;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Handler;
import android.os.ResultReceiver;
import android.os.StrictMode;
import android.provider.Settings;
import android.support.v7.app.ActionBarActivity;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.inputmethod.InputMethodManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.Toolbar;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnMapClickListener;
import com.google.android.gms.maps.GoogleMap.OnMapLongClickListener;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.VisibleRegion;
/**
*
* @author livin
*
*/
public class LocationPickerActivity extends ActionBarActivity implements
OnMapClickListener, OnMapLongClickListener {
Toolbar toolbar;
GoogleMap mMap;
GPSTracker gps;
LatLng userSelectedLatLng;
private AddressResultReceiver mResultReceiver;
ProgressDialog progress_dialogue;
public static boolean mMapIsTouched = false;
ImageView iv_clear,iv_marker;
TextView tv_label;
AutoCompleteTextView autoCompView;
public String userLocation = "";
ArrayAdapter<String> adapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_location_picker);
init();
getData();
}
// Receives the lat and lon points to in the map
public void getData() {
double lat = getIntent().getDoubleExtra("lat", 0);
double lon = getIntent().getDoubleExtra("lon", 0);
if (lat == 0 && lon == 0) {
showCurrentLocation();
} else {
showPreviouslySelectedLocation(lat, lon);
}
}
// Initializes the fields
public void init() {
progress_dialogue = new ProgressDialog(this);
mMap = ((SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.mapCommon)).getMap();
mMap.setOnMapClickListener(this);
mMap.setOnMapLongClickListener(this);
mMap.getUiSettings().setZoomControlsEnabled(true);
mMap.setMyLocationEnabled(true);
gps = new GPSTracker(this);
iv_clear = (ImageView) findViewById(R.id.iv_clear);
iv_marker = (ImageView) findViewById(R.id.iv_marker);
tv_label = (TextView) findViewById(R.id.tv_label);
autoCompView = (AutoCompleteTextView) findViewById(R.id.autocomplete);
adapter = new ArrayAdapter<String>(LocationPickerActivity.this,
android.R.layout.simple_list_item_1);
adapter.setNotifyOnChange(true);
autoCompView.setAdapter(adapter);
autoCompView.addTextChangedListener(new TextWatcher() {
public void onTextChanged(CharSequence s, int start, int before,
int count) {
if (count % 3 == 1) {
GetPlaces task = new GetPlaces();
// now pass the argument in the textview to the task
task.execute(autoCompView.getText().toString());
}
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
// TODO Auto-generated method stub
}
public void afterTextChanged(Editable s) {
}
});
autoCompView.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
// TODO Auto-generated method stub
try {
InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(autoCompView.getWindowToken(),
0);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder()
.permitAll().build();
StrictMode.setThreadPolicy(policy);
JSONObject locationJson = GetLocationFromAddress
.getLocationInfo(adapter.getItem(position));
double lng = ((JSONArray) locationJson.get("results"))
.getJSONObject(0).getJSONObject("geometry")
.getJSONObject("location").getDouble("lng");
double lat = ((JSONArray) locationJson.get("results"))
.getJSONObject(0).getJSONObject("geometry")
.getJSONObject("location").getDouble("lat");
LatLng latLng = new LatLng(lat, lng);
userSelectedLatLng = latLng;
// mMap.addMarker(new MarkerOptions().position(latLng));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng,
17));
userLocation = adapter.getItem(position);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
});
iv_clear.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
autoCompView.setText("");
}
});
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
gps = new GPSTracker(this);
}
/**
* Method to handle layout clicks
* @param view
*/
public void onClick(View view) {
switch (view.getId()) {
case R.id.bt_hybrid:
// Sets the map type to be "hybrid"
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
break;
case R.id.bt_normal:
// Sets the map type to be "normal"
mMap.setMapType(GoogleMap.MAP_TYPE_NORMAL);
break;
case R.id.bt_satelite:
// Sets the map type to be "normal"
mMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
break;
case R.id.iv_marker:
// Taped on the custom marker
tv_label.setText(userLocation);
if (tv_label.isShown()) {
tv_label.setVisibility(View.GONE);
}else{
tv_label.setVisibility(View.VISIBLE);
}
break;
default:
break;
}
}
/**
* Map points the current user location
*/
public void showCurrentLocation() {
if (gps.canGetLocation()) {
LatLng latLng = new LatLng(gps.getLatitude(), gps.getLongitude());
userSelectedLatLng = latLng;
// mMap.addMarker(new MarkerOptions().position(latLng));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 17));
new GetLocationTask().execute(0);
} else {
showSettingsAlert();
}
}
/**
* Moves the map to the given lat lon points, usefull if you wanted to point
* any particular place
*
* @param lat
* @param lon
*/
public void showPreviouslySelectedLocation(double lat, double lon) {
LatLng latLng = new LatLng(lat, lon);
userSelectedLatLng = latLng;
// mMap.addMarker(new MarkerOptions().position(latLng));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 17));
new GetLocationTask().execute(0);
}
/**
* GPS Settings alert
*/
public void showSettingsAlert() {
AlertDialog.Builder alertDialog = new AlertDialog.Builder(
LocationPickerActivity.this);
alertDialog.setTitle("Location Settings");
alertDialog
.setMessage("Enable Location Provider! Go to settings menu?");
alertDialog.setPositiveButton("Settings",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(
Settings.ACTION_LOCATION_SOURCE_SETTINGS);
LocationPickerActivity.this.startActivity(intent);
}
});
alertDialog.setNegativeButton("Cancel",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.cancel();
}
});
alertDialog.show();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.get_selected_location, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
Intent resultIntent = new Intent();
if (item.getItemId() == android.R.id.home) {
resultIntent.putExtra(AppConfig.USER_LAT,
userSelectedLatLng.latitude);
resultIntent.putExtra(AppConfig.USER_LNG,
userSelectedLatLng.longitude);
resultIntent.putExtra(AppConfig.USER_LOCATION, userLocation);
setResult(Activity.RESULT_OK, resultIntent);
finish();
return true;
} else if (item.getItemId() == R.id.action_done) {
// Gets the centre point of the map displayed
VisibleRegion visibleRegion = mMap.getProjection()
.getVisibleRegion();
Point x = mMap.getProjection().toScreenLocation(
visibleRegion.farRight);
Point y = mMap.getProjection().toScreenLocation(
visibleRegion.nearLeft);
Point centerPoint = new Point(x.x / 2, y.y / 2);
LatLng centerFromPoint = mMap.getProjection().fromScreenLocation(
centerPoint);
userSelectedLatLng = centerFromPoint;
new GetLocationTask().execute(1);
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* Statrs intnet service to get address from geocoder
*/
protected void startIntentService() {
// Get address from geocoder
mResultReceiver = new AddressResultReceiver(new Handler());
Location targetLocation = new Location("");// provider name is
// unecessary
targetLocation.setLatitude(userSelectedLatLng.latitude);// your coords
// of course
targetLocation.setLongitude(userSelectedLatLng.longitude);
Intent intent = new Intent(this, FetchAddressIntentService.class);
intent.putExtra(AppConfig.RECEIVER, mResultReceiver);
intent.putExtra(AppConfig.LOCATION_DATA_EXTRA, targetLocation);
startService(intent);
}
class AddressResultReceiver extends ResultReceiver {
public AddressResultReceiver(Handler handler) {
super(handler);
}
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
// Display the address string
// or an error message sent from the intent service.
// mAddressOutput = resultData.getString(AppConfig.RESULT_DATA_KEY);
// displayAddressOutput();
// Show a toast message if an address was found.
if (resultCode == AppConfig.SUCCESS_RESULT) {
if (progress_dialogue.isShowing()) {
progress_dialogue.dismiss();
}
userLocation = resultData.getString(AppConfig.RESULT_DATA_KEY);
autoCompView.setText(userLocation);
// finish();
// appConfig.showToast(resultData.toString());
} else {
// Get location from google api if geocoder is not responding
new GetLocationTask().execute(0);
}
}
}
@Override
public void onMapLongClick(LatLng arg0) {
// TODO Auto-generated method stub
}
@Override
public void onMapClick(LatLng latLng) {
// TODO Auto-generated method stub
userSelectedLatLng = latLng;
mMap.clear();
// mMap.addMarker(new MarkerOptions().position(latLng).draggable(true));
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, 17));
new GetLocationTask().execute(0);
}
/**
* Process the Put Message REQUEST TO THE SERVER
*/
public class GetLocationTask extends
AsyncTask<Integer, JSONObject, JSONObject> {
int whichTask = 0;
@Override
protected JSONObject doInBackground(Integer... params) {
// TODO Auto-generated method stub
whichTask = params[0];
return ServerConnector
.getJSONObjectfromURL("http://maps.googleapis.com/maps/api/geocode/json?latlng="
+ userSelectedLatLng.latitude
+ ","
+ userSelectedLatLng.longitude + "&sensor=false");
}
@Override
protected void onPostExecute(JSONObject jsonObj) {
// TODO Auto-generated method stub
super.onPostExecute(jsonObj);
if (progress_dialogue.isShowing()) {
progress_dialogue.dismiss();
}
if (jsonObj != null && !jsonObj.equals("")) {
try {
String Status = jsonObj.getString("status");
if (Status.equalsIgnoreCase("OK")) {
JSONArray Results = jsonObj.getJSONArray("results");
JSONObject zero = Results.getJSONObject(0);
Intent resultIntent = new Intent();
resultIntent.putExtra(AppConfig.USER_LAT,
userSelectedLatLng.latitude);
resultIntent.putExtra(AppConfig.USER_LNG,
userSelectedLatLng.longitude);
userLocation = convertFromUTF8(zero.getString("formatted_address"));
resultIntent.putExtra(AppConfig.USER_LOCATION,
userLocation);
setResult(Activity.RESULT_OK, resultIntent);
autoCompView.setText(userLocation);
// finish();
if (whichTask == 1) {
resultIntent.putExtra(AppConfig.USER_LAT,
userSelectedLatLng.latitude);
resultIntent.putExtra(AppConfig.USER_LNG,
userSelectedLatLng.longitude);
resultIntent.putExtra(AppConfig.USER_LOCATION,
userLocation);
setResult(Activity.RESULT_OK, resultIntent);
finish();
}
}
} catch (Exception e) {
// TODO: handle exception
}
} else {
Toast.makeText(
LocationPickerActivity.this,
"Some error occured. Make sure that you are connected to internet.",
Toast.LENGTH_SHORT).show();
return;
}
}
}
/**
* Method to convert string UTF* format
* used @Rainer-Lang
* @param s
* @return
*/
public static String convertFromUTF8(String s) {
String out = null;
try {
out = new String(s.getBytes("ISO-8859-1"), "UTF-8");
return out;
} catch (UnsupportedEncodingException var3) {
return null;
}
}
/**
* Getting google place suggestions
*
* @author livin
*
*/
class GetPlaces extends AsyncTask<String, Void, ArrayList<String>> {
@Override
// three dots is java for an array of strings
protected ArrayList<String> doInBackground(String... args) {
ArrayList<String> predictionsArr = new ArrayList<String>();
try {
URL googlePlaces = new URL(
// URLEncoder.encode(url,"UTF-8");
"https://maps.googleapis.com/maps/api/place/autocomplete/json?input="
+ URLEncoder.encode(args[0].toString(), "UTF-8")
+ "&types=geocode&language=en&sensor=true&key=AIzaSyAUG-M-cu2bxWEVGoUZXvU5WO6WMeP3vns");
URLConnection tc = googlePlaces.openConnection();
BufferedReader in = new BufferedReader(new InputStreamReader(
tc.getInputStream()));
String line;
StringBuffer sb = new StringBuffer();
// take Google's legible JSON and turn it into one big string.
while ((line = in.readLine()) != null) {
sb.append(line);
}
// turn that string into a JSON object
JSONObject predictions = new JSONObject(sb.toString());
// now get the JSON array that's inside that object
JSONArray ja = new JSONArray(
predictions.getString("predictions"));
for (int i = 0; i < ja.length(); i++) {
JSONObject jo = (JSONObject) ja.get(i);
// add each entry to our array
predictionsArr.add(jo.getString("description"));
}
} catch (IOException e) {
Log.e("YourApp", "GetPlaces : doInBackground", e);
} catch (JSONException e) {
Log.e("YourApp", "GetPlaces : doInBackground", e);
}
return predictionsArr;
}
// then our post
@Override
protected void onPostExecute(ArrayList<String> result) {
// Log.e("RESULT LOCATIONS", ""+result);
// update the adapter
adapter = new ArrayAdapter<String>(LocationPickerActivity.this,
android.R.layout.simple_list_item_1);
adapter.setNotifyOnChange(true);
// attach the adapter to textview
autoCompView.setAdapter(adapter);
adapter.clear();
for (String string : result) {
adapter.add(string);
adapter.notifyDataSetChanged();
}
}
}
}