I have a Android Class where I am able to locate the GPS position.But I would like to know can this be implemented to locate many other devices on the map.How to implement this.
Here is my code
public class MapDemoActivity extends AppCompatActivity implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {
private SupportMapFragment mapFragment;
private GoogleMap map;
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
private long UPDATE_INTERVAL = 60000; /* 60 secs */
private long FASTEST_INTERVAL = 5000; /* 5 secs */
/*
* Define a request code to send to Google Play services This code is
* returned in Activity.onActivityResult
*/
private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.map_demo_activity);
mapFragment = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map));
if (mapFragment != null) {
mapFragment.getMapAsync(new OnMapReadyCallback() {
#Override
public void onMapReady(GoogleMap map) {
loadMap(map);
}
});
} else {
Toast.makeText(this, "Error - Map Fragment was null!!", Toast.LENGTH_SHORT).show();
}
}
protected void loadMap(GoogleMap googleMap) {
map = googleMap;
if (map != null) {
// Map is ready
Toast.makeText(this, "Map Fragment was loaded properly!", Toast.LENGTH_SHORT).show();
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED)
map.setMyLocationEnabled(true);
// Now that map has loaded, let's get our location!
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
connectClient();
} else {
Toast.makeText(this, "Error - Map was null!!", Toast.LENGTH_SHORT).show();
}
}
protected void connectClient() {
// Connect the client.
if (isGooglePlayServicesAvailable() && mGoogleApiClient != null) {
mGoogleApiClient.connect();
}
}
/*
* Called when the Activity becomes visible.
*/
#Override
protected void onStart() {
super.onStart();
connectClient();
}
/*
* Called when the Activity is no longer visible.
*/
#Override
protected void onStop() {
// Disconnecting the client invalidates it.
if (mGoogleApiClient != null) {
mGoogleApiClient.disconnect();
}
super.onStop();
}
/*
* Handle results returned to the FragmentActivity by Google Play services
*/
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// Decide what to do based on the original request code
switch (requestCode) {
case CONNECTION_FAILURE_RESOLUTION_REQUEST:
/*
* If the result code is Activity.RESULT_OK, try to connect again
*/
switch (resultCode) {
case Activity.RESULT_OK:
mGoogleApiClient.connect();
break;
}
}
}
private boolean isGooglePlayServicesAvailable() {
// Check that Google Play services is available
int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
// If Google Play services is available
if (ConnectionResult.SUCCESS == resultCode) {
// In debug mode, log the status
Log.d("Location Updates", "Google Play services is available.");
return true;
} else {
// Get the error dialog from Google Play services
Dialog errorDialog = GooglePlayServicesUtil.getErrorDialog(resultCode, this,
CONNECTION_FAILURE_RESOLUTION_REQUEST);
// If Google Play services can provide an error dialog
if (errorDialog != null) {
// Create a new DialogFragment for the error dialog
ErrorDialogFragment errorFragment = new ErrorDialogFragment();
errorFragment.setDialog(errorDialog);
errorFragment.show(getSupportFragmentManager(), "Location Updates");
}
return false;
}
}
/*
* Called by Location Services when the request to connect the client
* finishes successfully. At this point, you can request the current
* location or start periodic updates
*/
#Override
public void onConnected(Bundle dataBundle) {
// Display the connection status
Location location = null;
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED)
location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (location != null) {
Toast.makeText(this, "GPS location was found!", Toast.LENGTH_SHORT).show();
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, 17);
map.animateCamera(cameraUpdate);
startLocationUpdates();
} else {
Toast.makeText(this, "Current location was null, enable GPS on emulator!", Toast.LENGTH_SHORT).show();
}
}
protected void startLocationUpdates() {
mLocationRequest = new LocationRequest();
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
mLocationRequest.setInterval(UPDATE_INTERVAL);
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
|| ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED)
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,
mLocationRequest, this);
}
public void onLocationChanged(Location location) {
// Report to the UI that the location was updated
String msg = "Updated Location: " +
Double.toString(location.getLatitude()) + "," +
Double.toString(location.getLongitude());
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
}
/*
* Called by Location Services if the connection to the location client
* drops because of an error.
*/
#Override
public void onConnectionSuspended(int i) {
if (i == CAUSE_SERVICE_DISCONNECTED) {
Toast.makeText(this, "Disconnected. Please re-connect.", Toast.LENGTH_SHORT).show();
} else if (i == CAUSE_NETWORK_LOST) {
Toast.makeText(this, "Network lost. Please re-connect.", Toast.LENGTH_SHORT).show();
}
}
/*
* Called by Location Services if the attempt to Location Services fails.
*/
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
/*
* Google Play services can resolve some errors it detects. If the error
* has a resolution, try sending an Intent to start a Google Play
* services activity that can resolve error.
*/
if (connectionResult.hasResolution()) {
try {
// Start an Activity that tries to resolve the error
connectionResult.startResolutionForResult(this,
CONNECTION_FAILURE_RESOLUTION_REQUEST);
/*
* Thrown if Google Play services canceled the original
* PendingIntent
*/
} catch (IntentSender.SendIntentException e) {
// Log the error
e.printStackTrace();
}
} else {
Toast.makeText(getApplicationContext(),
"Sorry. Location services not available to you", Toast.LENGTH_LONG).show();
}
}
// Define a DialogFragment that displays the error dialog
public static class ErrorDialogFragment extends DialogFragment {
// Global field to contain the error dialog
private Dialog mDialog;
// Default constructor. Sets the dialog field to null
public ErrorDialogFragment() {
super();
mDialog = null;
}
// Set the dialog to display
public void setDialog(Dialog dialog) {
mDialog = dialog;
}
// Return a Dialog to the DialogFragment.
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
return mDialog;
}
}
}
I want to plot multiple mobile device location on the map.How can this be achieved.
If you want to have an app that shows multiple devices, like a flight radar type of thing, you'll probably need for those devices to upload/publish their location periodically to a server, and then have other devices fetch that information periodically from that server and display it in the client.
I hope that makes sense.
Related
I have defined a service (i.e. LocationService ) which gives me users's current latitude and longitude as an intent extras to my_activity. Now , I want to use them to show current location on map (using Google maps) . I passed these latlng in mMap.animateCamera and mMap.moveCamera methods but they are not showing any Marker or zoom in to the current location . Please tell me if I am doing anything wrong .
Code for the LocationService and my MainActivity is pasted below :
LocationServices.java
public class LocationServicesForLocationUpdates extends Service implements LocationListener,
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener{
private static final String TAG = LocationServicesForLocationUpdates.class.getSimpleName();
public static final String ACTION_LOCATION_BROADCAST
= LocationServicesForLocationUpdates.class.getName() + "LocationBroadcast";
public static final String EXTRA_LATITUDE = "extra_latitude";
public static final String EXTRA_LONGITUDE = "extra_longitude";
private GoogleApiClient mLocationClient;
private LocationRequest mLocationRequest = new LocationRequest();
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
mLocationClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(5000);
mLocationRequest.setFastestInterval(3000);
mLocationClient.connect();
// return super.onStartCommand(intent, flags, startId);
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
/*
* LOCATION CALLBACKS
*/
#Override
public void onConnected(Bundle dataBundle) {
if (ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// 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 ActivityCompat#requestPermissions for more details.
Log.d(TAG, "== Error On onConnected() Permission not granted");
//Permission not granted by user so cancel the further execution.
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(mLocationClient, mLocationRequest ,this);
Log.d(TAG, "Connected to Google API");
}
//to get the location change
#Override
public void onLocationChanged(Location location) {
Log.d(TAG, "Location changed");
if (location != null) {
Log.d(TAG, "== location != null");
//Send result to activities
sendMessageToUI(String.valueOf(location.getLatitude()), String.valueOf(location.getLongitude()));
}
}
private void sendMessageToUI(String lat, String lng) {
Log.d(TAG, "Sending info...");
Intent intent = new Intent(ACTION_LOCATION_BROADCAST);
intent.putExtra(EXTRA_LATITUDE, lat);
intent.putExtra(EXTRA_LONGITUDE, lng);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
}
New MainActivity.java
public class MainActivity extends AppCompatActivity implements OnMapReadyCallback{
private TextView mLatlngTxtVu , mAddressTxtVu;
private boolean mAlreadyStartedService;
private static final String TAG = ParentHomeActivity.class.getSimpleName();
private static final int REQUEST_PERMISSIONS_REQUEST_CODE = 34;
private GoogleMap mGoogleMap;
Double mlattitude , mlongitude;
Marker mCurrentMarker;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_parent_home);
Log.d(TAG, "onCreate: Called");
mLatlngTxtVu = (TextView) findViewById(R.id.latlng_txtview);
mAddressTxtVu = (TextView) findViewById(R.id.address_txtvu);
LocalBroadcastManager.getInstance(this).registerReceiver(
new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
mlattitude = Double.parseDouble(intent.getStringExtra(LocationServicesForLocationUpdates.EXTRA_LATITUDE));
mlongitude = Double.parseDouble(intent.getStringExtra(LocationServicesForLocationUpdates.EXTRA_LONGITUDE));
Log.d("latlng", "onReceive: " + mlongitude + mlattitude);
if (mlattitude != null && mlongitude != null) {
mLatlngTxtVu.setText("Latitude : " + mlattitude + "Longitude: " + mlongitude);
}
}
}, new IntentFilter(LocationServicesForLocationUpdates.ACTION_LOCATION_BROADCAST)
);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.main_map);
mapFragment.getMapAsync(MainActivity.this);
}
#Override
protected void onResume() {
super.onResume();
checkGooglePlayServices();
}
#Override
public void onMapReady(GoogleMap googleMap) {
mGoogleMap = googleMap ;
Log.d(TAG, "onMapReady: called");
Log.d("coord", mlattitude + " " + mlongitude);
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
// ActivityCompat#requestPermissions
// 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 ActivityCompat#requestPermissions for more details.
return;
}
mGoogleMap.setMyLocationEnabled(true);
mGoogleMap.getUiSettings().setMyLocationButtonEnabled(true);
mGoogleMap.getUiSettings().setMapToolbarEnabled(false);
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(new LatLng(mlattitude, mlongitude)) // Sets the center of the map to location user
.zoom(14) // Sets the zoom
.bearing(0) // Sets the orientation of the camera to east
.tilt(90) // Sets the tilt of the camera to 30 degrees
.build(); // Creates a CameraPosition from the builder
mGoogleMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
LatLng latLng = new LatLng(mlattitude , mlongitude);
mGoogleMap.addMarker(new MarkerOptions().position(latLng).title("YOU"));
// mGoogleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
/* CameraPosition cameraPosition = new CameraPosition.Builder()
.target(new LatLng(mlattitude, mlongitude)) // Sets the center of the map to location user
.zoom(17) // Sets the zoom
.bearing(90) // Sets the orientation of the camera to east
.tilt(40) // Sets the tilt of the camera to 30 degrees
.build(); // Creates a CameraPosition from the builder
mGoogleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));*/
}
private void checkGooglePlayServices() {
//Check whether this user has installed Google play service which is being used by Location updates.
if (isGooglePlayServicesAvailable()) {
//Passing null to indicate that it is executing for the first time.
checkAndPromptForInternetConnection(null);
} else {
Toast.makeText(getApplicationContext(), "Play services Not Available", Toast.LENGTH_LONG).show();
}
}
private boolean checkAndPromptForInternetConnection(DialogInterface dialog) {
ConnectivityManager connectivityManager
= (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
if (activeNetworkInfo == null || !activeNetworkInfo.isConnected()) {
promptInternetConnect();
return false;
}
if (dialog != null) {
dialog.dismiss();
}
//Yes there is active internet connection. Next check Location is granted by user or not.
if (checkPermissions()) { //Yes permissions are granted by the user. Go to the next step.
startedLocationServices();
} else { //No user has not granted the permissions yet. Request now.
requestPermissions();
}
return true;
}
/**
* Step 3: Start the Location Monitor Service
*/
private void startedLocationServices() {
//And it will be keep running until you close the entire application from task manager.
//This method will executed only once.
if (!mAlreadyStartedService && mLatlngTxtVu != null) {
mLatlngTxtVu.setText("Running ");
//Start location sharing service to app server.........
Intent intent = new Intent(this, LocationServicesForLocationUpdates.class);
startService(intent);
mAlreadyStartedService = true;
//Ends................................................
}
}
/**
* Show A Dialog with button to refresh the internet state.
*/
private void promptInternetConnect() {
AlertDialog.Builder builder = new AlertDialog.Builder(ParentHomeActivity.this);
builder.setTitle("No internet connection");
builder.setMessage("Please Check your internet connection");
String positiveText = "Refresh";
builder.setPositiveButton(positiveText,
new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//Block the Application Execution until user grants the permissions
if (checkAndPromptForInternetConnection(dialog)) {
//Now make sure about location permission.
if (checkPermissions()) {
//Step 2: Start the Location Monitor Service
//Everything is there to start the service.
startedLocationServices();
} else if (!checkPermissions()) {
requestPermissions();
}
}
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
/**
* Return the availability of GooglePlayServices
*/
public boolean isGooglePlayServicesAvailable() {
GoogleApiAvailability googleApiAvailability = GoogleApiAvailability.getInstance();
int status = googleApiAvailability.isGooglePlayServicesAvailable(this);
if (status != ConnectionResult.SUCCESS) {
if (googleApiAvailability.isUserResolvableError(status)) {
googleApiAvailability.getErrorDialog(this, status, 2404).show();
}
return false;
}
return true;
}
/**
* Return the current state of the permissions needed.
*/
private boolean checkPermissions() {
int permissionState1 = ActivityCompat.checkSelfPermission(this,
android.Manifest.permission.ACCESS_FINE_LOCATION);
int permissionState2 = ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION);
return permissionState1 == PackageManager.PERMISSION_GRANTED && permissionState2 == PackageManager.PERMISSION_GRANTED;
}
/**
* Start permissions requests.
*/
private void requestPermissions() {
boolean shouldProvideRationale =
ActivityCompat.shouldShowRequestPermissionRationale(this,
android.Manifest.permission.ACCESS_FINE_LOCATION);
boolean shouldProvideRationale2 =
ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.ACCESS_COARSE_LOCATION);
// Provide an additional rationale to the img_user. This would happen if the img_user denied the
// request previously, but didn't check the "Don't ask again" checkbox.
if (shouldProvideRationale || shouldProvideRationale2) {
Log.i(TAG, "Displaying permission rationale to provide additional context.");
showSnackbar(R.string.grantPermission,
android.R.string.ok, new View.OnClickListener() {
#Override
public void onClick(View view) {
// Request permission
ActivityCompat.requestPermissions(ParentHomeActivity.this,
new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION},
REQUEST_PERMISSIONS_REQUEST_CODE);
}
});
} else {
Log.i(TAG, "Requesting permission");
// Request permission. It's possible this can be auto answered if device policy
// sets the permission in a given state or the img_user denied the permission
// previously and checked "Never ask again".
ActivityCompat.requestPermissions(ParentHomeActivity.this,
new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION},
REQUEST_PERMISSIONS_REQUEST_CODE);
}
}
/**
* Shows a {#link Snackbar}.
*
* #param mainTextStringId The id for the string resource for the Snackbar text.
* #param actionStringId The text of the action item.
* #param listener The listener associated with the Snackbar action.
*/
private void showSnackbar(final int mainTextStringId, final int actionStringId,
View.OnClickListener listener) {
Snackbar.make(
findViewById(android.R.id.content),
getString(mainTextStringId),
Snackbar.LENGTH_INDEFINITE)
.setAction(getString(actionStringId), listener).show();
}
/**
* Callback received when a permissions request has been completed.
*/
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions,
#NonNull int[] grantResults) {
Log.i(TAG, "onRequestPermissionResult");
if (requestCode == REQUEST_PERMISSIONS_REQUEST_CODE) {
if (grantResults.length <= 0) {
// If img_user interaction was interrupted, the permission request is cancelled and you
// receive empty arrays.
Log.i(TAG, "User interaction was cancelled.");
} else if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Log.i(TAG, "Permission granted, updates requested, starting location updates");
startedLocationServices();
} else {
// Permission denied.
// Notify the img_user via a SnackBar that they have rejected a core permission for the
// app, which makes the Activity useless. In a real app, core permissions would
// typically be best requested during a welcome-screen flow.
// Additionally, it is important to remember that a permission might have been
// rejected without asking the img_user for permission (device policy or "Never ask
// again" prompts). Therefore, a img_user interface affordance is typically implemented
// when permissions are denied. Otherwise, your app could appear unresponsive to
// touches or interactions which have required permissions.
showSnackbar(R.string.permissionDenied,
R.string.settings, new View.OnClickListener() {
#Override
public void onClick(View view) {
// Build intent that displays the App settings screen.
Intent intent = new Intent();
intent.setAction(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package",
BuildConfig.APPLICATION_ID, null);
intent.setData(uri);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
});
}
}
}
#Override
public void onDestroy() {
//Stop location sharing service to app server.........
stopService(new Intent(this, LocationServicesForLocationUpdates.class));
mAlreadyStartedService = false;
//Ends................................................
super.onDestroy();
}
}
Feel free to ask any queries in case you don't understand my problem and tell me the correct approach to solve my problem . I am new to android app development.
in onMapReady() please create a new LatLng position and add it in as MarkerOption
#Override
public void onMapReady(GoogleMap googleMap) {
.......
.......
// make sure you are getting your latitude and longitude string value
mlattitude = Double.parseDouble(intent.getStringExtra(LocationServicesForLocationUpdates.EXTRA_LATITUDE));
mlongitude = Double.parseDouble(intent.getStringExtra(LocationServicesForLocationUpdates.EXTRA_LONGITUDE));
CameraPosition cameraPosition = new CameraPosition.Builder()
.target(new LatLng(mLattitude,mlongitude)) // My position
.zoom(14) // Zoom Level
.bearing(0) // camera position, (0 north , 180 south )
.tilt(90) // Inclinaison de la camera
.build();
googleMap.moveCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
LatLng position = new LatLng(mlattitude,mlongitude);
googleMap.addMarker(new MarkerOptions().position(position)
.title("my marker"));
}
edit
Do not forget to call getMapAsync in your onReceive() method
LocalBroadcastManager.getInstance(this).registerReceiver(
new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
mlattitude = Double.parseDouble(intent.getStringExtra(LocationServicesForLocationUpdates.EXTRA_LATITUDE));
mlongitude = Double.parseDouble(intent.getStringExtra(LocationServicesForLocationUpdates.EXTRA_LONGITUDE));
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.main_map);
mapFragment.getMapAsync(MainActivity.this);
Log.d("latlng", "onReceive: " + mlongitude + mlattitude);
if (mlattitude != null && mlongitude != null) {
mLatlngTxtVu.setText("Latitude : " + mlattitude + "Longitude: " + mlongitude);
}
}
}, new IntentFilter(LocationServicesForLocationUpdates.ACTION_LOCATION_BROADCAST)
);
);
You can do like that :
public class MapsMarkerActivity extends AppCompatActivity
implements OnMapReadyCallback {
// Include the OnCreate() method here too, as described above.
#Override
public void onMapReady(GoogleMap googleMap) {
// Add a marker in Sydney, Australia,
// and move the map's camera to the same location.
LatLng sydney = new LatLng(-33.852, 151.211);
googleMap.addMarker(new MarkerOptions().position(sydney)
.title("Marker in Sydney"));
googleMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
}
}
The code is from the Google documentation page
i want to display current location on map, my map is in fragment and i'm using fused location provider in non activity class, but i'm not getting current location when the map is loaded, it is giving me current location only if i press mylocation button, but i want that when map is loaded it should show my current location not the world map.
locationprovide.java
public class LocationProvider implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {
public interface LocationCallback {
public void handleNewLocation(Location location);
}
public static final String TAG = LocationProvider.class.getSimpleName();
/*
* Define a request code to send to Google Play services
* This code is returned in Activity.onActivityResult
*/
private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
private LocationCallback mLocationCallback;
private Context mContext;
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
public LocationProvider(Context context,LocationCallback locationCallback) {
mGoogleApiClient = new GoogleApiClient.Builder(context)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mContext = context;
mLocationCallback = locationCallback;
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(1000);
mLocationRequest.setFastestInterval(1000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
}
public void connect() {
mGoogleApiClient.connect();
}
public void disconnect() {
if (mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
mGoogleApiClient.disconnect();
}
}
#Override
public void onConnected(Bundle bundle) {
Log.i(TAG, "Location services connected.");
if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(mContext, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// 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 ActivityCompat#requestPermissions for more details.
return;
}
Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (location == null) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
else {
mLocationCallback.handleNewLocation(location);
}
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
/*
* Google Play services can resolve some errors it detects.
* If the error has a resolution, try sending an Intent to
* start a Google Play services activity that can resolve
* error.
*/
if (connectionResult.hasResolution() && mContext instanceof Activity) {
try {
Activity activity = (Activity)mContext;
// Start an Activity that tries to resolve the error
connectionResult.startResolutionForResult(activity, CONNECTION_FAILURE_RESOLUTION_REQUEST);
/*
* Thrown if Google Play services canceled the original
* PendingIntent
*/
} catch (IntentSender.SendIntentException e) {
// Log the error
e.printStackTrace();
}
} else {
/*
* If no resolution is available, display a dialog to the
* user with the error.
*/
Log.i(TAG, "Location services connection failed with code " + connectionResult.getErrorCode());
}
}
#Override
public void onLocationChanged(Location location) {
mLocationCallback.handleNewLocation(location);
}
}
fragment
public class ChildMapFragment extends Fragment implements OnMapReadyCallback,LocationProvider.LocationCallback {
private LocationProvider mLocationProvider;
private GoogleMap mMap;
Location mLastLocation;
Marker mCurrLocationMarker;
LocationRequest mLocationRequest;
Context mContext;
String sid,cid;
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view= inflater.inflate(R.layout.fragment_child_map, container, false);
SupportMapFragment mapFragment = (SupportMapFragment)this.getChildFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
checkLocationPermission();
}else{
mLocationProvider = new LocationProvider(mContext,this);
}
if (mLocationProvider!=null)
mLocationProvider.connect();
return view;
}
#Override
public void onViewCreated(View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
if (mLocationProvider!=null)
mLocationProvider.connect();
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
//Initialize Google Play Services
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(mContext,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
mLocationProvider = new LocationProvider(mContext,this);
mMap.setMyLocationEnabled(true);
}
}
else {
mLocationProvider = new LocationProvider(mContext,this);
mMap.setMyLocationEnabled(true);
}
}
#Override
public void handleNewLocation(Location location) {
mLastLocation = location;
if (mCurrLocationMarker != null) {
mCurrLocationMarker.remove();
}
//Place current location marker
LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latLng);
markerOptions.title("Current Position");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
mCurrLocationMarker = mMap.addMarker(markerOptions);
//move map camera
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.animateCamera(CameraUpdateFactory.zoomTo(11));
}
#Override
public void onDestroyView() {
super.onDestroyView();
mMap.clear();
}
#Override
public void onResume() {
super.onResume();
if (mLocationProvider!=null)
mLocationProvider.connect();
}
#Override
public void onPause() {
super.onPause();
if (mLocationProvider!=null)
mLocationProvider.disconnect();
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
mContext=context;
}
public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99;
public boolean checkLocationPermission(){
if (ContextCompat.checkSelfPermission(mContext,
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Asking user if explanation is needed
if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) mContext,
Manifest.permission.ACCESS_FINE_LOCATION)) {
// Show an explanation to the user *asynchronously* -- don't block
// this thread waiting for the user's response! After the user
// sees the explanation, try again to request the permission.
//Prompt the user once explanation has been shown
ActivityCompat.requestPermissions((Activity) mContext,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
} else {
// No explanation needed, we can request the permission.
ActivityCompat.requestPermissions((Activity) mContext,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_LOCATION);
}
return false;
} else {
return true;
}
}
#Override
public void onRequestPermissionsResult(int requestCode,
#NonNull String permissions[], #NonNull int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// permission was granted. Do the
// contacts-related task you need to do.
if (ContextCompat.checkSelfPermission(mContext,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
mLocationProvider = new LocationProvider(mContext,this);
mMap.setMyLocationEnabled(true);
}
} else {
// Permission denied, Disable the functionality that depends on this permission.
Toast.makeText(mContext, "permission denied", Toast.LENGTH_LONG).show();
}
return;
}
}
}
}
just put the code below
if (mLocationProvider!=null){
mLocationProvider.connect();
}
where you are using
mLocationProvider = new LocationProvider(mContext,this);
private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
private double currentLatitude;
private double currentLongitude;
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
Button btn_start;
TextView txt_refersh;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_demo);
btn_start = (Button) findViewById(R.id.btn_start);
txt_refersh = (TextView) findViewById(R.id.txt_refersh);
btn_start.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.e("currentLatitude", "" + currentLatitude);
Log.e("currentLongitude", "" + currentLongitude);
}
});
mGoogleApiClient = new GoogleApiClient.Builder(this)
// The next two lines tell the new client that “this” current class will handle connection stuff
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
//fourth line adds the LocationServices API endpoint from GooglePlayServices
.addApi(LocationServices.API)
.build();
// Create the LocationRequest object
mLocationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(10 * 1000) // 10 seconds, in milliseconds
.setFastestInterval(1 * 1000); // 1 second, in milliseconds
}
#Override
protected void onResume() {
System.runFinalization();
Runtime.getRuntime().gc();
System.gc();
Log.e("System GC", "Called");
super.onResume();
//Now lets connect to the API
mGoogleApiClient.connect();
}
#Override
protected void onStart() {
super.onStart();
}
#Override
protected void onPause() {
if (mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
mGoogleApiClient.disconnect();
}
super.onPause();
Log.v(this.getClass().getSimpleName(), "onPause()");
}
#Override
public void onConnected(Bundle bundle) {
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// 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 ActivityCompat#requestPermissions for more details.
return;
}
Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (location == null) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
} else {
//If everything went fine lets get latitude and longitude
currentLatitude = location.getLatitude();
currentLongitude = location.getLongitude();
LocationRequest locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
locationRequest.setInterval(60000);
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
// ActivityCompat#requestPermissions
// 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 ActivityCompat#requestPermissions for more details.
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
getLocationdetails(getApplicationContext());
Log.e("currentLatitude", "" + currentLatitude);
Log.e("currentLongitude", "" + currentLongitude);
}
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
/*
* Google Play services can resolve some errors it detects.
* If the error has a resolution, try sending an Intent to
* start a Google Play services activity that can resolve
* error.
*/
if (connectionResult.hasResolution()) {
try {
// Start an Activity that tries to resolve the error
connectionResult.startResolutionForResult(this, CONNECTION_FAILURE_RESOLUTION_REQUEST);
/*
* Thrown if Google Play services canceled the original
* PendingIntent
*/
} catch (IntentSender.SendIntentException e) {
// Log the error
e.printStackTrace();
}
} else {
/*
* If no resolution is available, display a dialog to the
* user with the error.
*/
Log.e("Error", "Location services connection failed with code " + connectionResult.getErrorCode());
}
}
/**
* If locationChanges change lat and long
*
* #param location
*/
#Override
public void onLocationChanged(Location location) {
currentLatitude = location.getLatitude();
currentLongitude = location.getLongitude();
}
private Location getLocationdetails(Context context) {
Location location = null;
if (mGoogleApiClient != null) {
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return null;
} else {
Log.e("currentLatitude", "" + currentLatitude);
Log.e("currentLongitude", "" + currentLongitude);
location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
}
}
return location;
}
I use locationRequest.setInterval (60000); for refreshing my location but it is still not refreshing. What should I do more to get the current Latitude and Longitude every after 10 mins. I just wanted to get the log of lat long every after 10 mins.
I'm developing an Android app, and I need to get latitude and longitude of the user.
I googled and found that Google API is the best for this, and I found a tutorial on this link: http://www.androidhive.info/2015/02/android-location-api-using-google-play-services/
How I don't need location updates (just click in a button, and get the location), I just copied this piece of code from tutorial:
public class MainActivity1 extends Activity implements ConnectionCallbacks,
OnConnectionFailedListener {
private Location mLastLocation;
// Google client to interact with Google API
private GoogleApiClient mGoogleApiClient;
// UI elements
private TextView lblLocation;
private Button btnShowLocation, btnStartLocationUpdates;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lblLocation = (TextView) findViewById(R.id.lblLocation);
btnShowLocation = (Button) findViewById(R.id.btnShowLocation);
btnStartLocationUpdates = (Button) findViewById(R.id.btnLocationUpdates);
// First we need to check availability of play services
if (checkPlayServices()) {
// Building the GoogleApi client
buildGoogleApiClient();
}
// Show location button click listener
btnShowLocation.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
displayLocation();
}
});
}
/**
* Method to display the location on UI
* */
private void displayLocation() {
mLastLocation = LocationServices.FusedLocationApi
.getLastLocation(mGoogleApiClient);
if (mLastLocation != null) {
double latitude = mLastLocation.getLatitude();
double longitude = mLastLocation.getLongitude();
lblLocation.setText(latitude + ", " + longitude);
} else {
lblLocation
.setText("(Couldn't get the location. Make sure location is enabled on the device)");
}
}
/**
* Creating google api client object
* */
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API).build();
}
/**
* Method to verify google play services on the device
* */
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 {
Toast.makeText(getApplicationContext(),
"This device is not supported.", Toast.LENGTH_LONG)
.show();
finish();
}
return false;
}
return true;
}
#Override
protected void onStart() {
super.onStart();
if (mGoogleApiClient != null) {
mGoogleApiClient.connect();
}
}
#Override
protected void onResume() {
super.onResume();
checkPlayServices();
}
/**
* Google api callback methods
*/
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = "
+ result.getErrorCode());
}
#Override
public void onConnected(Bundle arg0) {
// Once connected with google api, get the location
displayLocation();
}
#Override
public void onConnectionSuspended(int arg0) {
mGoogleApiClient.connect();
}
}
and it worked!!!
But I want to create a method (in another class) that get the current location and return it (instead of doing this inside activity).
So, I modified what I did above, and finished with the following:
public class UserLocation implements ConnectionCallbacks, OnConnectionFailedListener {
private Location mLastLocation;
// Google client to interact with Google API
private GoogleApiClient mGoogleApiClient;
public HashMap<String, Double> getUserLocation(Activity act) {
HashMap<String, Double> getLocation = new HashMap<>();
if (checkPlayServices(act)) {
buildGoogleApiClient(act);
}
mLastLocation = LocationServices.FusedLocationApi
.getLastLocation(mGoogleApiClient);
if (mLastLocation != null) {
double latitude = mLastLocation.getLatitude();
double longitude = mLastLocation.getLongitude();
getLocation.put("latitude", latitude);
getLocation.put("longitude", longitude);
return getLocation;
} else {
Log.i("FAIL: ", "(Couldn't get the location. Make sure location is enabled on the device)");
return null;
}
}
/**
* Creating google api client object
*/
protected synchronized void buildGoogleApiClient(Activity act) {
mGoogleApiClient = new GoogleApiClient.Builder(act)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API).build();
}
/**
* Method to verify google play services on the device
*/
private boolean checkPlayServices(Activity act) {
int resultCode = GooglePlayServicesUtil
.isGooglePlayServicesAvailable(act);
if (resultCode != ConnectionResult.SUCCESS) {
return false;
}
return true;
}
/**
* Google api callback methods
*/
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.i("Fail: ", "Connection failed: ConnectionResult.getErrorCode() = "
+ result.getErrorCode());
}
#Override
public void onConnected(Bundle arg0) {
}
#Override
public void onConnectionSuspended(int arg0) {
mGoogleApiClient.connect();
}
}
And I call it from the main Activity this way:
HashMap<String, Double> userLoc = ul.getUserLocation(this);
ul.getUserLocation(getActivity());
But with this new class, I don't get the location... I debuged, and saw that mLastLocation is always null...
Can somebody tell me what I'm doing wrong?
In the activity you get last location after Google API client connected and it is right. In UserLocation class you are trying to get location before connection established and it is wrong.
From the docs:
If not connected null will be returned.
You need to move getting location in onConnected() method and somehow notify the activity. You can create callback for it or simply let the activity implement ConnectionCallbacks instead of UserLocation.
I am creating an app in android -studio , and I have a problem .
The app contains the Google Maps which shows us our location , but what really would make was that the push of a button , our location was sent by sms to a number of mobile phone , it will be possible ?
I created a demo app and it can:
Show your current location on the map as a marker.
Have a button. When you click it, it will create a SMS massage that you can send
your location via SMS.
Sample code:
public class MapsActivity extends FragmentActivity implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener,
ResultCallback<LocationSettingsResult>,
View.OnClickListener {
public static final String TAG = MapsActivity.class.getSimpleName();
/*
* Define a request code to send to Google Play services
* This code is returned in Activity.onActivityResult
*/
private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
protected static final int REQUEST_CHECK_SETTINGS = 0x1;
private GoogleMap mMap; // Might be null if Google Play services APK is not available.
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
private LocationSettingsRequest mLocationSettingsRequest;
private Button btn_send_location;
private double mCurrentLatitude;
private double mCurrentLongitude;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
setUpMapIfNeeded();
btn_send_location = (Button) findViewById(R.id.send_my_location_btn);
btn_send_location.setOnClickListener(this);
long interval = 10 * 1000; // 10 seconds, in milliseconds
long fastestInterval = 1 * 1000; // 1 second, in milliseconds
float minDisplacement = 0;
// // Check if has GPS
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
buildAlertMessageNoGps();
}
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
// Create the LocationRequest object
// mLocationRequest = LocationRequest.create()
// .setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY)
// .setInterval(interval)
// .setFastestInterval(fastestInterval)
// .setSmallestDisplacement(minDisplacement);
// Check if has GPS by using Google play service
// buildLocationSettingsRequest();
// checkLocationSettings();
}
#Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
mGoogleApiClient.connect();
}
#Override
protected void onPause() {
super.onPause();
if (mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
mGoogleApiClient.disconnect();
}
}
/**
* Sets up the map if it is possible to do so (i.e., the Google Play services APK is correctly
* installed) and the map has not already been instantiated.. This will ensure that we only ever
* call {#link #setUpMap()} once when {#link #mMap} is not null.
* <p/>
* If it isn't installed {#link SupportMapFragment} (and
* {#link com.google.android.gms.maps.MapView MapView}) will show a prompt for the user to
* install/update the Google Play services APK on their device.
* <p/>
* A user can return to this FragmentActivity after following the prompt and correctly
* installing/updating/enabling the Google Play services. Since the FragmentActivity may not
* have been completely destroyed during this process (it is likely that it would only be
* stopped or paused), {#link #onCreate(Bundle)} may not be called again so we should call this
* method in {#link #onResume()} to guarantee that it will be called.
*/
private void setUpMapIfNeeded() {
// Do a null check to confirm that we have not already instantiated the map.
if (mMap == null) {
// Try to obtain the map from the SupportMapFragment.
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
}
}
private void handleNewLocation(Location location) {
Log.d(TAG, location.toString());
mCurrentLatitude = location.getLatitude();
mCurrentLongitude = location.getLongitude();
LatLng latLng = new LatLng(mCurrentLatitude, mCurrentLongitude);
//mMap.addMarker(new MarkerOptions().position(new LatLng(currentLatitude, currentLongitude)).title("Current Location"));
MarkerOptions options = new MarkerOptions()
.position(latLng)
.title("I am here!");
mMap.addMarker(options);
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(latLng, 15));
}
#Override
public void onConnected(Bundle bundle) {
Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (location == null) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
} else {
handleNewLocation(location);
}
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
/*
* Google Play services can resolve some errors it detects.
* If the error has a resolution, try sending an Intent to
* start a Google Play services activity that can resolve
* error.
*/
if (connectionResult.hasResolution()) {
try {
// Start an Activity that tries to resolve the error
connectionResult.startResolutionForResult(this, CONNECTION_FAILURE_RESOLUTION_REQUEST);
/*
* Thrown if Google Play services canceled the original
* PendingIntent
*/
} catch (IntentSender.SendIntentException e) {
// Log the error
e.printStackTrace();
}
} else {
/*
* If no resolution is available, display a dialog to the
* user with the error.
*/
Log.i(TAG, "Location services connection failed with code " + connectionResult.getErrorCode());
}
}
#Override
public void onLocationChanged(Location location) {
handleNewLocation(location);
}
private void buildAlertMessageNoGps() {
final AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setMessage("Your GPS seems to be disabled, do you want to enable it?")
.setCancelable(false)
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
public void onClick(#SuppressWarnings("unused") final DialogInterface dialog, #SuppressWarnings("unused") final int id) {
startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));
}
})
.setNegativeButton("No", new DialogInterface.OnClickListener() {
public void onClick(final DialogInterface dialog, #SuppressWarnings("unused") final int id) {
dialog.cancel();
}
});
final AlertDialog alert = builder.create();
alert.show();
}
/**
* Uses a {#link com.google.android.gms.location.LocationSettingsRequest.Builder} to build
* a {#link com.google.android.gms.location.LocationSettingsRequest} that is used for checking
* if a device has the needed location settings.
*/
protected void buildLocationSettingsRequest() {
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
builder.addLocationRequest(mLocationRequest);
mLocationSettingsRequest = builder.build();
}
protected void checkLocationSettings() {
PendingResult<LocationSettingsResult> result =
LocationServices.SettingsApi.checkLocationSettings(
mGoogleApiClient,
mLocationSettingsRequest
);
result.setResultCallback(this);
}
#Override
public void onResult(LocationSettingsResult locationSettingsResult) {
final Status status = locationSettingsResult.getStatus();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
// NO need to show the dialog;
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
// Location settings are not satisfied. Show the user a dialog
try {
// Show the dialog by calling startResolutionForResult(), and check the result
// in onActivityResult().
status.startResolutionForResult(this, REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException e) {
//unable to execute request
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
// Location settings are inadequate, and cannot be fixed here. Dialog not created
break;
}
}
#Override
public void onClick(View v) {
Intent sendIntent = new Intent(Intent.ACTION_VIEW);
sendIntent.setData(Uri.parse("sms:"));
sendIntent.putExtra("sms_body", "My location at \nLatitude: " + mCurrentLatitude + " \nLongitude: " + mCurrentLongitude);
startActivity(sendIntent);
}
}
And the xml file activity_maps.xml is:
<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="vertical">
<Button
android:id="#+id/send_my_location_btn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Send My location via SMS"/>
<fragment
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MapsActivity"/>
</LinearLayout>
If you want to get the whole project, please refer to here.