Are you looking something like in the images below..
Here, if we drag marker on map it will automatically update the current lat, longs..
Here is the full complete solution with the code.
1.) Create a class AppUtils
public class AppUtils {
public class LocationConstants {
public static final int SUCCESS_RESULT = 0;
public static final int FAILURE_RESULT = 1;
public static final String PACKAGE_NAME = "your package name";
public static final String RECEIVER = PACKAGE_NAME + ".RECEIVER";
public static final String RESULT_DATA_KEY = PACKAGE_NAME + ".RESULT_DATA_KEY";
public static final String LOCATION_DATA_EXTRA = PACKAGE_NAME + ".LOCATION_DATA_EXTRA";
public static final String LOCATION_DATA_AREA = PACKAGE_NAME + ".LOCATION_DATA_AREA";
public static final String LOCATION_DATA_CITY = PACKAGE_NAME + ".LOCATION_DATA_CITY";
public static final String LOCATION_DATA_STREET = PACKAGE_NAME + ".LOCATION_DATA_STREET";
}
public static boolean hasLollipop() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP;
}
public static boolean isLocationEnabled(Context context) {
int locationMode = 0;
String locationProviders;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
try {
locationMode = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE);
} catch (Settings.SettingNotFoundException e) {
e.printStackTrace();
}
return locationMode != Settings.Secure.LOCATION_MODE_OFF;
} else {
locationProviders = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
return !TextUtils.isEmpty(locationProviders);
}
}
}
2.) create another class FetchAddressIntentService
This class will fetch the address and point to that particular location which user is going to type on Google AutocompleteTextView
..
public class FetchAddressIntentService extends IntentService {
private static final String TAG = "FetchAddressIS";
/**
* The receiver where results are forwarded from this service.
*/
protected ResultReceiver mReceiver;
/**
* This constructor is required, and calls the super IntentService(String)
* constructor with the name for a worker thread.
*/
public FetchAddressIntentService() {
// Use the TAG to name the worker thread.
super(TAG);
}
/**
* Tries to get the location address using a Geocoder. If successful, sends an address to a
* result receiver. If unsuccessful, sends an error message instead.
* Note: We define a {@link ResultReceiver} in * MainActivity to process content
* sent from this service.
* <p>
* This service calls this method from the default worker thread with the intent that started
* the service. When this method returns, the service automatically stops.
*/
@Override
protected void onHandleIntent(Intent intent) {
String errorMessage = "";
mReceiver = intent.getParcelableExtra(AppUtils.LocationConstants.RECEIVER);
// Check if receiver was properly registered.
if (mReceiver == null) {
Log.wtf(TAG, "No receiver received. There is nowhere to send the results.");
return;
}
// Get the location passed to this service through an extra.
Location location = intent.getParcelableExtra(AppUtils.LocationConstants.LOCATION_DATA_EXTRA);
// Make sure that the location data was really sent over through an extra. If it wasn't,
// send an error error message and return.
if (location == null) {
errorMessage = getString(R.string.no_location_data_provided);
Log.wtf(TAG, errorMessage);
deliverResultToReceiver(AppUtils.LocationConstants.FAILURE_RESULT, errorMessage, null);
return;
}
// Errors could still arise from using the Geocoder (for example, if there is no
// connectivity, or if the Geocoder is given illegal location data). Or, the Geocoder may
// simply not have an address for a location. In all these cases, we communicate with the
// receiver using a resultCode indicating failure. If an address is found, we use a
// resultCode indicating success.
// The Geocoder used in this sample. The Geocoder's responses are localized for the given
// Locale, which represents a specific geographical or linguistic region. Locales are used
// to alter the presentation of information such as numbers or dates to suit the conventions
// in the region they describe.
Geocoder geocoder = new Geocoder(this, Locale.getDefault());
// Address found using the Geocoder.
List<Address> addresses = null;
try {
// Using getFromLocation() returns an array of Addresses for the area immediately
// surrounding the given latitude and longitude. The results are a best guess and are
// not guaranteed to be accurate.
addresses = geocoder.getFromLocation(
location.getLatitude(),
location.getLongitude(),
// In this sample, we get just a single address.
1);
} catch (IOException ioException) {
// Catch network or other I/O problems.
errorMessage = getString(R.string.service_not_available);
Log.e(TAG, errorMessage, ioException);
} catch (IllegalArgumentException illegalArgumentException) {
// Catch invalid latitude or longitude values.
errorMessage = getString(R.string.invalid_lat_long_used);
Log.e(TAG, errorMessage + ". " +
"Latitude = " + location.getLatitude() +
", Longitude = " + location.getLongitude(), illegalArgumentException);
}
// Handle case where no address was found.
if (addresses == null || addresses.size() == 0) {
if (errorMessage.isEmpty()) {
errorMessage = getString(R.string.no_address_found);
Log.e(TAG, errorMessage);
}
deliverResultToReceiver(AppUtils.LocationConstants.FAILURE_RESULT, errorMessage, null);
} else {
Address address = addresses.get(0);
ArrayList<String> addressFragments = new ArrayList<String>();
for (int i = 0; i < address.getMaxAddressLineIndex(); i++) {
addressFragments.add(address.getAddressLine(i));
}
deliverResultToReceiver(AppUtils.LocationConstants.SUCCESS_RESULT,
TextUtils.join(System.getProperty("line.separator"), addressFragments), address);
//TextUtils.split(TextUtils.join(System.getProperty("line.separator"), addressFragments), System.getProperty("line.separator"));
}
}
/**
* Sends a resultCode and message to the receiver.
*/
private void deliverResultToReceiver(int resultCode, String message, Address address) {
try {
Bundle bundle = new Bundle();
bundle.putString(AppUtils.LocationConstants.RESULT_DATA_KEY, message);
bundle.putString(AppUtils.LocationConstants.LOCATION_DATA_AREA, address.getSubLocality());
bundle.putString(AppUtils.LocationConstants.LOCATION_DATA_CITY, address.getLocality());
bundle.putString(AppUtils.LocationConstants.LOCATION_DATA_STREET, address.getAddressLine(0));
mReceiver.send(resultCode, bundle);
} catch (Exception e) {
e.printStackTrace();
}
}
}
3.) Create your MapActivity
in this we are going to display our map
public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, com.google.android.gms.location.LocationListener {
private GoogleMap mMap;
private GoogleApiClient mGoogleApiClient;
private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
private static String TAG = "MAP LOCATION";
Context mContext;
TextView mLocationMarkerText;
public LatLng mCenterLatLong;
/**
* Receiver registered with this activity to get the response from FetchAddressIntentService.
*/
private AddressResultReceiver mResultReceiver;
/**
* The formatted location address.
*/
protected String mAddressOutput;
protected String mAreaOutput;
protected String mCityOutput;
protected String mStateOutput;
EditText mLocationAddress;
TextView mLocationText;
private static final int REQUEST_CODE_AUTOCOMPLETE = 1;
Toolbar mToolbar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
mContext = this;
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mLocationMarkerText = (TextView) findViewById(R.id.locationMarkertext);
mLocationAddress = (EditText) findViewById(R.id.Address); //sss
mLocationText = (TextView) findViewById(R.id.Locality); //sss
mToolbar = (Toolbar) findViewById(R.id.toolbar); //sss
setSupportActionBar(mToolbar);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setTitle(getResources().getString(R.string.app_name));
mLocationText.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
openAutocompleteActivity();
}
});
mapFragment.getMapAsync(this);
mResultReceiver = new AddressResultReceiver(new Handler());
if (checkPlayServices()) {
if (!AppUtils.isLocationEnabled(mContext)) {
// notify user
AlertDialog.Builder dialog = new AlertDialog.Builder(mContext);
dialog.setMessage("Location not enabled!");
dialog.setPositiveButton("Open location settings", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
Intent myIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(myIntent);
}
});
dialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
// TODO Auto-generated method stub
}
});
dialog.show();
}
buildGoogleApiClient();
} else {
Toast.makeText(mContext, "Location not supported in this device", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onMapReady(GoogleMap googleMap) {
Log.d(TAG, "OnMapReady");
mMap = googleMap;
mMap.setOnCameraChangeListener(new GoogleMap.OnCameraChangeListener() {
@Override
public void onCameraChange(CameraPosition cameraPosition) {
Log.d("Camera postion change" + "", cameraPosition + "");
mCenterLatLong = cameraPosition.target;
mMap.clear();
try {
Location mLocation = new Location("");
mLocation.setLatitude(mCenterLatLong.latitude);
mLocation.setLongitude(mCenterLatLong.longitude);
startIntentService(mLocation);
mLocationMarkerText.setText("Lat : " + mCenterLatLong.latitude + "," + "Long : " + mCenterLatLong.longitude);
} catch (Exception e) {
e.printStackTrace();
}
}
});
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
}
@Override
public void onConnected(Bundle bundle) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
if (mLastLocation != null) {
changeMap(mLastLocation);
Log.d(TAG, "ON connected");
} else
try {
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
} catch (Exception e) {
e.printStackTrace();
}
try {
LocationRequest mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(10000);
mLocationRequest.setFastestInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onConnectionSuspended(int i) {
Log.i(TAG, "Connection suspended");
mGoogleApiClient.connect();
}
@Override
public void onLocationChanged(Location location) {
try {
if (location != null)
changeMap(location);
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, this);
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
@Override
protected void onStart() {
super.onStart();
try {
mGoogleApiClient.connect();
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
protected void onStop() {
super.onStop();
try {
} catch (RuntimeException e) {
e.printStackTrace();
}
if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
private boolean checkPlayServices() {
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.SUCCESS) {
if (GooglePlayServicesUtil.isUserRecoverableError(resultCode)) {
GooglePlayServicesUtil.getErrorDialog(resultCode, this,
PLAY_SERVICES_RESOLUTION_REQUEST).show();
} else {
//finish();
}
return false;
}
return true;
}
private void changeMap(Location location) {
Log.d(TAG, "Reaching map" + mMap);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
// check if map is created successfully or not
if (mMap != null) {
mMap.getUiSettings().setZoomControlsEnabled(false);
LatLng latLong;
latLong = new LatLng(location.getLatitude(), location.getLongitude());
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(latLong).zoom(15).tilt(70).build();
mMap.setMyLocationEnabled(true);
mMap.getUiSettings().setMyLocationButtonEnabled(true);
mMap.animateCamera(CameraUpdateFactory
.newCameraPosition(cameraPosition));
mLocationMarkerText.setText("Lat : " + location.getLatitude() + "," + "Long : " + location.getLongitude());
startIntentService(location);
} else {
Toast.makeText(getApplicationContext(),
"Sorry! unable to create maps", Toast.LENGTH_SHORT)
.show();
}
}
/**
* Receiver for data sent from FetchAddressIntentService.
*/
class AddressResultReceiver extends ResultReceiver {
public AddressResultReceiver(Handler handler) {
super(handler);
}
/**
* Receives data sent from
* FetchAddressIntentService and updates the UI in MainActivity.
*/
@Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
// Display the address string or an error message sent from the intent service.
mAddressOutput = resultData.getString(AppUtils.LocationConstants.RESULT_DATA_KEY);
mAreaOutput = resultData.getString(AppUtils.LocationConstants.LOCATION_DATA_AREA);
mCityOutput = resultData.getString(AppUtils.LocationConstants.LOCATION_DATA_CITY);
mStateOutput = resultData.getString(AppUtils.LocationConstants.LOCATION_DATA_STREET);
displayAddressOutput();
// Show a toast message if an address was found.
if (resultCode == AppUtils.LocationConstants.SUCCESS_RESULT) {
// showToast(getString(R.string.address_found));
}
}
}
/**
* Updates the address in the UI.
*/
protected void displayAddressOutput() {
// mLocationAddressTextView.setText(mAddressOutput);
try {
if (mAreaOutput != null)
// mLocationText.setText(mAreaOutput+ "");
mLocationAddress.setText(mAddressOutput);
//mLocationText.setText(mAreaOutput);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Creates an intent, adds location data to it as an extra, and starts the intent service for
* fetching an address.
*/
protected void startIntentService(Location mLocation) {
// Create an intent for passing to the intent service responsible for fetching the address.
Intent intent = new Intent(this, FetchAddressIntentService.class);
// Pass the result receiver as an extra to the service.
intent.putExtra(AppUtils.LocationConstants.RECEIVER, mResultReceiver);
// Pass the location data as an extra to the service.
intent.putExtra(AppUtils.LocationConstants.LOCATION_DATA_EXTRA, mLocation);
// Start the service. If the service isn't already running, it is instantiated and started
// (creating a process for it if needed); if it is running then it remains running. The
// service kills itself automatically once all intents are processed.
startService(intent);
}
private void openAutocompleteActivity() {
try {
// The autocomplete activity requires Google Play Services to be available. The intent
// builder checks this and throws an exception if it is not the case.
Intent intent = new PlaceAutocomplete.IntentBuilder(PlaceAutocomplete.MODE_FULLSCREEN)
.build(this);
startActivityForResult(intent, REQUEST_CODE_AUTOCOMPLETE);
} catch (GooglePlayServicesRepairableException e) {
// Indicates that Google Play Services is either not installed or not up to date. Prompt
// the user to correct the issue.
GoogleApiAvailability.getInstance().getErrorDialog(this, e.getConnectionStatusCode(),
0 /* requestCode */).show();
} catch (GooglePlayServicesNotAvailableException e) {
// Indicates that Google Play Services is not available and the problem is not easily
// resolvable.
String message = "Google Play Services is not available: " +
GoogleApiAvailability.getInstance().getErrorString(e.errorCode);
Toast.makeText(mContext, message, Toast.LENGTH_SHORT).show();
}
}
/**
* Called after the autocomplete activity has finished to return its result.
*/
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Check that the result was from the autocomplete widget.
if (requestCode == REQUEST_CODE_AUTOCOMPLETE) {
if (resultCode == RESULT_OK) {
// Get the user's selected place from the Intent.
Place place = PlaceAutocomplete.getPlace(mContext, data);
// TODO call location based filter
LatLng latLong;
latLong = place.getLatLng();
//mLocationText.setText(place.getName() + "");
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(latLong).zoom(15).tilt(70).build();
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
return;
}
mMap.setMyLocationEnabled(true);
mMap.animateCamera(CameraUpdateFactory
.newCameraPosition(cameraPosition));
}
} else if (resultCode == PlaceAutocomplete.RESULT_ERROR) {
Status status = PlaceAutocomplete.getStatus(mContext, data);
} else if (resultCode == RESULT_CANCELED) {
// Indicates that the activity closed before a selection was made. For example if
// the user pressed the back button.
}
}
}
4.) Changes in Manifest
provide all the necessary internet permissions.
Don't forget to add these two things
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="Your google map api key" />
and,
<service
android:name=".FetchAddressIntentService"
android:exported="false" />
That's it, You're done with the code part!!
Just Run it..