Email address google maps app in a message to the mobile phone? - android

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.

Related

Can't get location googleApiClient

I am trying to get the user's location with the GoogleApiClient, it works fine if the GPS is enabled when the activity starts, however, if it is not enabled and i ask for the user to enable the GPS, i can't seem to get the location. I am trying to use a LocationListener, I have tried both the native and the GooglePlayServices listeners. Here is my code:
Check if GPS is enabled in onCreate:
//Ask the user to enable GPS if it is not.
mLocationRequestBalancedPowerAccuracy = new LocationRequest()
.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY)
.setInterval(3600000)
.setFastestInterval(300000);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(mLocationRequestBalancedPowerAccuracy);
PendingResult<LocationSettingsResult> result =
LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
#Override
public void onResult(#NonNull LocationSettingsResult result) {
final Status status = result.getStatus();
//final LocationSettingsStates states = result.getLocationSettingsStates();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
try {
status.startResolutionForResult(
MainActivity.this,
REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException e) {
Log.d("Location error", e.toString());
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
break;
}
}
});
If the result is RESOLUTION REQUIRED, I run the onResult method where I start listening for location if the user accepts to enable GPS:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//final LocationSettingsStates states = LocationSettingsStates.fromIntent(data);
switch (requestCode) {
case REQUEST_CHECK_SETTINGS:
switch (resultCode) {
case Activity.RESULT_OK:
// All required changes were successfully made
// User accepted to use GPS, start searching for location
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequestBalancedPowerAccuracy, this);
Log.d("locationmanager", "location result ok");
break;
case Activity.RESULT_CANCELED:
// The user was asked to change settings, but chose not to
this.finishAffinity();
break;
default:
break;
}
break;
}
}
The line Log.d("locationmanager", "location result ok"); is executed, but the above line does not seem to execute.
Finally here is my listener:
#Override
public void onLocationChanged(Location location) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
Log.d("changed location", String.valueOf(location.getLatitude()) + " " + String.valueOf(location.getLongitude()));
}
Try using this Location Listener class:
/**
* Getting Navigation Updates.
* <p>
* Demonstrates how to use the Fused Navigation Provider API to get updates about a device's
* location. The Fused Navigation Provider is part of the Google Play services location APIs.
* <p>
*
* Author Mayank
*/
public class GPSLocationListener implements ConnectionCallbacks, OnConnectionFailedListener, LocationListener {
protected static final String TAG = "location-updates-sample";
/**
* The desired interval for location updates. Inexact. Updates may be more or less frequent.
*/
public static final long UPDATE_INTERVAL_IN_MILLISECONDS = 10000;
/**
* The fastest rate for active location updates. Exact. Updates will never be more frequent
* than this value.
*/
public static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS =
UPDATE_INTERVAL_IN_MILLISECONDS / 2;
/**
* Provides the entry point to Google Play services.
*/
protected GoogleApiClient mGoogleApiClient;
/**
* Stores parameters for requests to the FusedLocationProviderApi.
*/
protected LocationRequest mLocationRequest;
/**
* Represents a geographical location.
*/
protected Location mCurrentLocation;
private Activity mActivity;
public GPSLocationListener(Activity activity) {
this.mActivity = activity;
// Kick off the process of building a GoogleApiClient and requesting the LocationServices API.
buildGoogleApiClient();
}
/**
* Builds a GoogleApiClient. Uses the {#code #addApi} method to request the
* LocationServices API.
*/
protected synchronized void buildGoogleApiClient() {
Log.i(TAG, "Building GoogleApiClient");
mGoogleApiClient = new GoogleApiClient.Builder(mActivity)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
createLocationRequest();
}
/**
* Sets up the location request. Android has two location request settings:
* {#code ACCESS_COARSE_LOCATION} and {#code ACCESS_FINE_LOCATION}. These settings control
* the accuracy of the current location. This sample uses ACCESS_FINE_LOCATION, as defined in
* the AndroidManifest.xml.
* <p/>
* When the ACCESS_FINE_LOCATION setting is specified, combined with a fast update
* interval (5 seconds), the Fused Navigation Provider API returns location updates that are
* accurate to within a few feet.
* <p/>
* These settings are appropriate for mapping applications that show real-time location
* updates.
*/
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
// Sets the desired interval for active location updates. This interval is
// inexact. You may not receive updates at all if no location sources are available, or
// you may receive them slower than requested. You may also receive updates faster than
// requested if other applications are requesting location at a faster interval.
mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
// Sets the fastest rate for active location updates. This interval is exact, and your
// application will never receive updates faster than this value.
mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
/**
* Requests location updates from the FusedLocationApi.
*/
protected void startLocationUpdates() {
// The final argument to {#code requestLocationUpdates()} is a LocationListener
// (http://developer.android.com/reference/com/google/android/gms/location/LocationListener.html).
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
/**
* Removes location updates from the FusedLocationApi.
*/
protected void stopLocationUpdates() {
// It is a good practice to remove location requests when the activity is in a paused or
// stopped state. Doing so helps battery performance and is especially
// recommended in applications that request frequent location updates.
// The final argument to {#code requestLocationUpdates()} is a LocationListener
// (http://developer.android.com/reference/com/google/android/gms/location/LocationListener.html).
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
public void onStart() {
mGoogleApiClient.connect();
// Within {#code onPause()}, we pause location updates, but leave the
// connection to GoogleApiClient intact. Here, we resume receiving
// location updates if the user has requested them.
}
public void onStop() {
// Stop location updates to save battery, but don't disconnect the GoogleApiClient object.
if (mGoogleApiClient.isConnected()) {
stopLocationUpdates();
mGoogleApiClient.disconnect();
}
}
/**
* Runs when a GoogleApiClient object successfully connects.
*/
#Override
public void onConnected(Bundle connectionHint) {
Log.i(TAG, "Connected to GoogleApiClient");
// If the initial location was never previously requested, we use
// FusedLocationApi.getLastLocation() to get it. If it was previously requested, we store
// its value in the Bundle and check for it in onCreate().
if (mCurrentLocation == null) {
mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
locationReceived();
}
// start location updates.
startLocationUpdates();
}
/**
* Callback that fires when the location changes.
*/
#Override
public void onLocationChanged(Location location) {
mCurrentLocation = location;
}
#Override
public void onConnectionSuspended(int cause) {
// The connection to Google Play services was lost for some reason. We call connect() to
// attempt to re-establish the connection.
Log.i(TAG, "Connection suspended");
mGoogleApiClient.connect();
}
#Override
public void onConnectionFailed(ConnectionResult result) {
// Refer to the javadoc for ConnectionResult to see what error codes might be returned in
// onConnectionFailed.
Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + result.getErrorCode());
}
public GoogleApiClient getGoogleApiClient(){
return mGoogleApiClient;
}
}
In your Activity:
//provides gps location updates
private GPSLocationListener gpsLocationListener;
#Override
public void onStart() {
super.onStart();
//call to location listener to start location updates when activity gets started
if (gpsLocationListener != null) {
gpsLocationListener.onStart();
}
}
#Override
public void onStop() {
super.onStop();
//call to stop location updates when activity gets stopped
if (gpsLocationListener != null) {
gpsLocationListener.onStop();
}
}
#Override
public void onCreate() {
super.onCreate();
//call to initialize gpsLocationLister instance
gpsLocationListener = new GPSLocationListener((MainActivity) mainView);
}
Hope this helps you.

How to solve geofence mock_location error?

so im running this sample app i got on github which deals with google maps and geo fences: https://github.com/androidfu/GeofenceExample
And when I run the code I get this error : Caused by: java.lang.SecurityException: com.androidfu.example.geofences from uid 10170 not allowed to perform MOCK_LOCATION
Here is the code for the class followed by the stack trace. Hope you guys can give me some insight. Also i have mock location in manifest. The error is coming from the onResume() method.
public class MapsActivity extends FragmentActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, View.OnClickListener, ResultCallback<Status> {
public static final String TAG = MapsActivity.class.getSimpleName();
private static final long LOCATION_ITERATION_PAUSE_TIME = 1000;
private static final int NUMBER_OF_LOCATION_ITERATIONS = 10;
private GoogleMap googleMap; // Might be null if Google Play services APK is not available.
private MyPlaces happyPlace;
private MyPlaces home;
private List<Geofence> myFences = new ArrayList<>();
private GoogleApiClient googleApiClient;
private PendingIntent geofencePendingIntent;
private UpdateLocationRunnable updateLocationRunnable;
private LocationManager locationManager;
private int marker = 0;
private Location lastLocation;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
ImageButton happyPlaceBtn = (ImageButton) findViewById(R.id.ib_happy_place);
happyPlaceBtn.setOnClickListener(this);
ImageButton homeBtn = (ImageButton) findViewById(R.id.ib_home);
homeBtn.setOnClickListener(this);
ImageButton resetBtn = (ImageButton) findViewById(R.id.ib_reset);
resetBtn.setOnClickListener(this);
setUpMapIfNeeded();
}
/**
* Called when a view has been clicked.
*
* #param v The view that was clicked.
*/
#Override
public void onClick(View v) {
MyPlaces place;
switch (v.getId()) {
case R.id.ib_happy_place:
Toast.makeText(this, "You Clicked Happy Place", Toast.LENGTH_SHORT).show();
place = happyPlace;
moveToLocation(place);
break;
case R.id.ib_home:
Toast.makeText(this, "You Clicked Home", Toast.LENGTH_SHORT).show();
place = home;
moveToLocation(place);
break;
case R.id.ib_reset:
Toast.makeText(this, "Resetting Our Map", Toast.LENGTH_SHORT).show();
if (updateLocationRunnable != null) {
updateLocationRunnable.interrupt();
}
googleApiClient.disconnect();
googleMap.clear();
myFences.clear();
setUpMap();
break;
}
}
#Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
this.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
Log.i(TAG, "Setup MOCK Location Providers");
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
Log.i(TAG, "GPS Provider");
locationManager.addTestProvider(LocationManager.GPS_PROVIDER, false, true, false, false, false, false, false, Criteria.POWER_HIGH, Criteria.ACCURACY_FINE);
locationManager.setTestProviderEnabled(LocationManager.GPS_PROVIDER, true);
Log.i(TAG, "Network Provider");
locationManager.addTestProvider(LocationManager.NETWORK_PROVIDER, true, false, true, false, false, false, false, Criteria.POWER_MEDIUM, Criteria.ACCURACY_FINE);
locationManager.setTestProviderEnabled(LocationManager.NETWORK_PROVIDER, true);
}
#Override
protected void onPause() {
this.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
// Interrupt our runnable if we're going into the background or exiting
if (updateLocationRunnable != null) {
updateLocationRunnable.interrupt();
}
Log.i(TAG, "Cleanup Our Fields");
locationManager.removeTestProvider(LocationManager.GPS_PROVIDER);
locationManager.removeTestProvider(LocationManager.NETWORK_PROVIDER);
locationManager = null;
updateLocationRunnable = null;
super.onPause();
}
#Override
protected void onStop() {
googleApiClient.disconnect();
super.onStop();
}
/**
* 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 #googleMap} 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 (googleMap == null) {
// Try to obtain the map from the SupportMapFragment.
googleMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
// Check if we were successful in obtaining the map.
if (googleMap != null) {
setUpMap();
}
}
}
/**
* This is where we can add markers or lines, add listeners or move the camera.
* <p/>
* This should only be called once and when we are sure that {#link #googleMap} is not null.
*/
private void setUpMap() {
googleMap.setBuildingsEnabled(true);
// PRES 1
/*
1. Create a "Place" that will become a Geofence
2. Add a place marker on our Map
3. Add our place to our list of Geofences
4. Repeat for each place
*/
// Add a place with a Geofence
happyPlace = new MyPlaces("Pier # Folly Beach", "This is my Happy Place!", new LatLng(32.652411, -79.938063), 10000, 10, R.drawable.ic_palm_tree);
addPlaceMarker(happyPlace);
addFence(happyPlace);
// Add a place with a Geofence
// Work 39.3336585, -84.3146718
// Home 39.2697455, -84.269921
home = new MyPlaces("Home", "This is where I live.", new LatLng(39.3336585, -84.3146718), 10000, 10, R.drawable.ic_home);
addPlaceMarker(home);
addFence(home);
// Add a place w/o a Geofence
MyPlaces charleston = new MyPlaces("Charleston, SC", "This is where I want to live!", new LatLng(32.8210454, -79.9704779), 0, 10, R.drawable.ic_heart);
addPlaceMarker(charleston);
addFence(charleston);
/*
After all your places have been created and markers added you can monitor your fences.
*/
monitorFences(myFences);
googleMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
#Override
public void onMapClick(LatLng latLng) {
if (updateLocationRunnable != null && updateLocationRunnable.isAlive() && !updateLocationRunnable.isInterrupted()) {
updateLocationRunnable.interrupt();
}
updateLocationRunnable = new UpdateLocationRunnable(locationManager, latLng);
updateLocationRunnable.start();
MyPlaces touchedPlace = new MyPlaces(String.format("Marker %1$d", ++marker), "", latLng, 65, 12, 0);
addPlaceMarker(touchedPlace);
}
});
}
/**
* Add a map marker at the place specified.
*
* #param place the place to take action on
*/
private void addPlaceMarker(MyPlaces place) {
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(place.getCoordinates())
.title(place.getTitle());
if (!TextUtils.isEmpty(place.getSnippet())) {
markerOptions.snippet(place.getSnippet());
}
if (place.getIconResourceId() > 0) {
markerOptions.icon(BitmapDescriptorFactory.fromResource(place.getIconResourceId()));
}
googleMap.addMarker(markerOptions);
drawGeofenceAroundTarget(place);
}
/**
* If our place has a fence radius greater than 0 then draw a circle around it.
*
* #param place the place to take action on
*/
private void drawGeofenceAroundTarget(MyPlaces place) {
if (place.getFenceRadius() <= 0) {
// Nothing to draw
return;
}
CircleOptions circleOptions = new CircleOptions();
circleOptions.center(place.getCoordinates());
circleOptions.fillColor(Color.argb(0x55, 0x00, 0x00, 0xff));
circleOptions.strokeColor(Color.argb(0xaa, 0x00, 0x00, 0xff));
circleOptions.radius(place.getFenceRadius());
googleMap.addCircle(circleOptions);
}
/**
* Update our map's location to the place specified.
*
* #param place the place to take action on
*/
private void moveToLocation(final MyPlaces place) {
// Move the camera instantly to "place" with a zoom of 5.
if (place.getTitle().equals("Charleston, SC")) {
googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(place.getCoordinates(), place.getDefaultZoomLevel()));
}
// Fly to our new location and then set the correct zoom level for the given place.
googleMap.animateCamera(CameraUpdateFactory.newLatLng(place.getCoordinates()), new GoogleMap.CancelableCallback() {
#Override
public void onFinish() {
googleMap.animateCamera(CameraUpdateFactory.zoomTo(place.getDefaultZoomLevel()), 2000, null);
}
#Override
public void onCancel() {
// Nothing to see here.
}
});
}
/**
* If our place has a fence radius > 0 then add it to our monitored fences.
*
* #param place the place to take action on
*/
private void addFence(MyPlaces place) {
if (place.getFenceRadius() <= 0) {
// Nothing to monitor
return;
}
Geofence geofence = new Geofence.Builder()
.setCircularRegion(place.getCoordinates().latitude, place.getCoordinates().longitude, place.getFenceRadius())
.setRequestId(place.getTitle()) // every fence must have an ID
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT) // can also have DWELL
.setExpirationDuration(Geofence.NEVER_EXPIRE) // how long do we care about this geofence?
//.setLoiteringDelay(60000) // 1 min.
.build();
myFences.add(geofence);
}
/**
* Connect our GoogleApiClient so we can begin monitoring our fences.
*
* #param fences our list of Geofences to monitor
*/
private void monitorFences(List<Geofence> fences) {
if (fences.isEmpty()) {
throw new RuntimeException("No fences to monitor. Call addPlaceMarker() First.");
}
// PRES 2
googleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
googleApiClient.connect();
}
#Override
public void onConnected(Bundle bundle) {
/*
TODO
1. Display a spinner in the progress bar while we're waiting for location
2. When connected & not null update map position to location
3. If location null try again once every 10 seconds until we get an answer or quit after x minutes
4. ?
*/
Toast.makeText(this, "GoogleApiClient Connected", Toast.LENGTH_SHORT).show();
lastLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
String lastLocationMessage;
if (lastLocation == null) {
lastLocationMessage = "Last Location is NULL";
moveToLocation(home);
} else {
lastLocationMessage = String.format("Last Location (%1$s, %2$s)", lastLocation.getLatitude(), lastLocation.getLongitude());
moveToLocation(new MyPlaces("Last Location", "I am here.", new LatLng(lastLocation.getLatitude(), lastLocation.getLongitude()), 0, 13, 0));
}
Toast.makeText(this, lastLocationMessage, Toast.LENGTH_SHORT).show();
// PRES 3
geofencePendingIntent = getRequestPendingIntent();
PendingResult<Status> result = LocationServices.GeofencingApi.addGeofences(googleApiClient, myFences, geofencePendingIntent);
result.setResultCallback(this);
}
#Override
public void onConnectionSuspended(int i) {
Toast.makeText(this, "GoogleApiClient Connection Suspended", Toast.LENGTH_SHORT).show();
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Toast.makeText(this, "GoogleApiClient Connection Failed", Toast.LENGTH_SHORT).show();
}
#Override
public void onResult(Status status) {
String toastMessage;
// PRES 4
if (status.isSuccess()) {
toastMessage = "Success: We Are Monitoring Our Fences";
} else {
toastMessage = "Error: We Are NOT Monitoring Our Fences";
}
Toast.makeText(this, toastMessage, Toast.LENGTH_SHORT).show();
}
/**
* Returns the current PendingIntent to the caller.
*
* #return The PendingIntent used to create the current set of geofences
*/
public PendingIntent getRequestPendingIntent() {
return createRequestPendingIntent();
}
/**
* Get a PendingIntent to send with the request to add Geofences. Location
* Services issues the Intent inside this PendingIntent whenever a geofence
* transition occurs for the current list of geofences.
*
* #return A PendingIntent for the IntentService that handles geofence
* transitions.
*/
private PendingIntent createRequestPendingIntent() {
if (geofencePendingIntent != null) {
return geofencePendingIntent;
} else {
Intent intent = new Intent(this, GeofenceTransitionReceiver.class);
intent.setAction("geofence_transition_action");
return PendingIntent.getBroadcast(this, R.id.geofence_transition_intent, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
}
// /////////////////////////////////////////////////////////////////////////////////////////
// // UpdateLocationRunnable //
// /////////////////////////////////////////////////////////////////////////////////////////
private Location createMockLocation(String locationProvider, double latitude, double longitude) {
Location location = new Location(locationProvider);
location.setLatitude(latitude);
location.setLongitude(longitude);
location.setAccuracy(1.0f);
location.setTime(System.currentTimeMillis());
/*
setElapsedRealtimeNanos() was added in API 17
*/
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) {
location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
}
try {
Method locationJellyBeanFixMethod = Location.class.getMethod("makeComplete");
if (locationJellyBeanFixMethod != null) {
locationJellyBeanFixMethod.invoke(location);
}
} catch (Exception e) {
// There's no action to take here. This is a fix for Jelly Bean and no reason to report a failure.
}
return location;
}
// /////////////////////////////////////////////////////////////////////////////////////////
// // CreateMockLocation //
// /////////////////////////////////////////////////////////////////////////////////////////
class UpdateLocationRunnable extends Thread {
private final LocationManager locMgr;
private final LatLng latlng;
Location mockGpsLocation;
Location mockNetworkLocation;
UpdateLocationRunnable(LocationManager locMgr, LatLng latlng) {
this.locMgr = locMgr;
this.latlng = latlng;
}
/**
* Starts executing the active part of the class' code. This method is
* called when a thread is started that has been created with a class which
* implements {#code Runnable}.
*/
#Override
public void run() {
try {
Log.i(TAG, String.format("Setting Mock Location to: %1$s, %2$s", latlng.latitude, latlng.longitude));
/*
Location can be finicky. Iterate over our desired location every second for
NUMBER_OF_LOCATION_ITERATIONS seconds to help it figure out where we want it to
be.
*/
for (int i = 0; !isInterrupted() && i <= NUMBER_OF_LOCATION_ITERATIONS; i++) {
mockGpsLocation = createMockLocation(LocationManager.GPS_PROVIDER, latlng.latitude, latlng.longitude);
locMgr.setTestProviderLocation(LocationManager.GPS_PROVIDER, mockGpsLocation);
mockNetworkLocation = createMockLocation(LocationManager.NETWORK_PROVIDER, latlng.latitude, latlng.longitude);
locMgr.setTestProviderLocation(LocationManager.NETWORK_PROVIDER, mockNetworkLocation);
Thread.sleep(LOCATION_ITERATION_PAUSE_TIME);
}
} catch (InterruptedException e) {
Log.i(TAG, "Interrupted.");
// Do nothing. We expect this to happen when location is successfully updated.
} finally {
Log.i(TAG, "Done moving location.");
}
}
}
}
stack trace:
09-26 11:08:07.870 10417-10417/com.androidfu.example.geofences E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.androidfu.example.geofences, PID: 10417
java.lang.RuntimeException: Unable to resume activity {com.androidfu.example.geofences/com.androidfu.example.geofences.GeofenceExampleLauncher}: java.lang.SecurityException: com.androidfu.example.geofences from uid 10170 not allowed to perform MOCK_LOCATION
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3121)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3152)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2499)
at android.app.ActivityThread.access$900(ActivityThread.java:157)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1356)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5525)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620)
Caused by: java.lang.SecurityException: com.androidfu.example.geofences from uid 10170 not allowed to perform MOCK_LOCATION
at android.os.Parcel.readException(Parcel.java:1599)
at android.os.Parcel.readException(Parcel.java:1552)
at android.location.ILocationManager$Stub$Proxy.addTestProvider(ILocationManager.java:1096)
at android.location.LocationManager.addTestProvider(LocationManager.java:1298)
at com.androidfu.example.geofences.MapsActivity.onResume(MapsActivity.java:120)
at android.app.Instrumentation.callActivityOnResume(Instrumentation.java:1258)
at android.app.Activity.performResume(Activity.java:6347)
at android.app.ActivityThread.performResumeActivity(ActivityThread.java:3110)
at android.app.ActivityThread.handleResumeActivity(ActivityThread.java:3152) 
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2499) 
at android.app.ActivityThread.access$900(ActivityThread.java:157) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1356) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:148) 
at android.app.ActivityThread.main(ActivityThread.java:5525) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:730) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:620) 
I guess you have not allowed mock locations from phones developer options.
It should be under Debug section.

getLastLocation() always null after reinstall

I seem to have a problem that I just can't figure out.
I am creating an application that requires Location Services with Android. The application needs to constantly poll for location.
This code had been working for months, and then when I uninstalled it from my phone and reinstalled it, the location is suddenly returning null.
Here is the LocationProvider class, which grabs the location using a Google API client:
public class LocationProvider implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener {
public abstract 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 callback) {
mGoogleApiClient = new GoogleApiClient.Builder(context)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mLocationCallback = callback;
// Create the LocationRequest object
mLocationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(3 * 1000) // 10 seconds, in milliseconds
.setFastestInterval(1 * 1000); // 1 second, in milliseconds
mContext = context;
}
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.");
Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (location == null) {
//----------------
//----------------
Log.i(TAG, "couldnt get location");
noLocationEnabledDialog();
/*LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
mLocationCallback.handleNewLocation(location); */
}
else {
/* Log.i(TAG, "couldnt get location");
noLocationEnabledDialog(); */
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
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());
}
}
public void noLocationEnabledDialog(){
AlertDialog.Builder setLocationDialog = new AlertDialog.Builder(mContext);
setLocationDialog.setTitle(R.string.location_message_title);
setLocationDialog.setMessage(R.string.location_message);
/*Button takes user to settings*/
setLocationDialog.setPositiveButton(R.string.affirmative, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent settingsIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivity(settingsIntent);
}
});
/*If no location, close the activity*/
setLocationDialog.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
//do nothing....yet
}
});
setLocationDialog.show();
}
#Override
public void onLocationChanged(Location location) {
mLocationCallback.handleNewLocation(location);
Log.i(TAG, "New location received ");
} }
I have also tried turning on Google Maps to grab a location on the device, hoping that it would use the location grabbed from Maps. Curiously, the location icon showed up in the top bar before reinstalling and it no longer shows. Does anyone know why reinstalling the application would cause this error? I am running this on a Samsung Galaxy s6 running Android 6.0.1
Thank you very much!
Well, it appears I have answered my own question. I am a serious derp.
Marshmallow requires that individual apps ask for permission for location and such. Since the previous installation had a different target API, it didnt need that and the manifest sufficed.
I brought the target API down to 22 and that was it. In the future, I will need to ask for permission. This question answers it quite well:
Permission issues for location in android Marshmallow applicaton

Support for multiple device in google maps in android

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.

Handling Location updates

I am trying to create a page that will outlay (using Google Maps) a race circuit and will use a dot of some kind to show and update the users current location.
The code I have for this is:
public class TopGearLocationTracker extends FragmentActivity implements
//Specifies methods that Location Services calls when a location client
//is connected or disconnected.//
GooglePlayServicesClient.ConnectionCallbacks,
//Specifies a method that Location Services calls if an error occurs while
//attempting to connect the location client. This method uses the previously-
//defined showErrorDialog method to display an error dialog that attempts to
//fix the problem using Google Play services.
GooglePlayServicesClient.OnConnectionFailedListener,
//The callback method that Location Services invokes to send a location update
//to your application is specified in the LocationListener interface, in the method
//onLocationChanged(). The incoming argument is a Location object containing the
//location's latitude and longitude. The following snippet shows how to specify
//the interface and define the method:
LocationListener
{
// Global constants
/*
* 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;
// Global variable to hold the current location
Location mCurrentLocation;
private GoogleMap aMap;
// Global constants
// Milliseconds per second
private static final int MILLISECONDS_PER_SECOND = 1000;
// Update frequency in seconds
public static final int UPDATE_INTERVAL_IN_SECONDS = 5;
// Update frequency in milliseconds
private static final long UPDATE_INTERVAL =
MILLISECONDS_PER_SECOND * UPDATE_INTERVAL_IN_SECONDS;
// The fastest update frequency, in seconds
private static final int FASTEST_INTERVAL_IN_SECONDS = 1;
// A fast frequency ceiling in milliseconds
private static final long FASTEST_INTERVAL =
MILLISECONDS_PER_SECOND * FASTEST_INTERVAL_IN_SECONDS;
// Define an object that holds accuracy and frequency parameters
LocationRequest mLocationRequest;
// Global variables
LocationClient mLocationClient;
boolean mUpdatesRequested;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.top_gear_location_tracker);
// Set the map up
// Set the map to Top Gear track location
LatLng topGearTrack = new LatLng(51.116492, -0.541767);
aMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map)).getMap();
aMap.getUiSettings().setAllGesturesEnabled(false);
aMap.setMapType(GoogleMap.MAP_TYPE_SATELLITE);
aMap.setMyLocationEnabled(true);
aMap.moveCamera(CameraUpdateFactory.newLatLngZoom(topGearTrack, 15));
setUpMapIfNeeded();
// Create the LocationRequest object
mLocationRequest = LocationRequest.create();
// Use high accuracy
mLocationRequest.setPriority(
LocationRequest.PRIORITY_HIGH_ACCURACY);
// Set the update interval to 5 seconds
mLocationRequest.setInterval(UPDATE_INTERVAL);
// Set the fastest update interval to 1 second
mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
// Open the shared preferences
//mPrefs = getSharedPreferences("SharedPreferences",
//Context.MODE_PRIVATE);
// Get a SharedPreferences editor
//mEditor = mPrefs.edit();
/*
* Create a new location client, using the enclosing class to
* handle callbacks.
*/
mLocationClient = new LocationClient(this, this, this);
// Start with updates turned off
mUpdatesRequested = false;
}
public void setUpMapIfNeeded()
{
//Do a null check to confirm that we have not already instantiated the map.
if (aMap == null)
{
aMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.map))
.getMap();
//Check if we were successful in obtaining the map.
if (aMap != null)
{
//The Map is verified. It is now safe to manipulate the map.
}
}
}
/*
* Called when the Activity becomes visible.
*/
#Override
protected void onStart()
{
super.onStart();
// Connect the client.
mLocationClient.connect();
}
/*
* Called when the Activity is no longer visible.
*/
#Override
protected void onStop()
{
// Disconnecting the client invalidates it.
mLocationClient.disconnect();
super.onStop();
}
// *************** CHECK FOR GOOGLE PLAY SERVICES *************** //
#SuppressWarnings("unused")
private boolean servicesConnected()
{
// 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.");
// Continue
return true;
// Google Play services was not available for some reason
}
else
{
// Get the error code
// 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();
// Set the dialog in the DialogFragment
errorFragment.setDialog(errorDialog);
// Show the error dialog in the DialogFragment
errorFragment.show(getSupportFragmentManager(),
"Location Updates");
}
}
return false;
}
// 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;
}
}
/*
* 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 :
/*
* Try the request again
*/
break;
}
}
}
// ******************** CALLBACK METHODS AND INTERFACES ******************** //
/*
* 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
Toast.makeText(this, "Connected", Toast.LENGTH_SHORT).show();
// If already requested, start periodic updates
if (mUpdatesRequested)
{
mLocationClient.requestLocationUpdates(mLocationRequest, this);
}
}
/*
* Called by Location Services if the connection to the
* location client drops because of an error.
*/
#Override
public void onDisconnected()
{
// Display the connection status
Toast.makeText(this, "Disconnected. 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 cancelled 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.
*/
showErrorDialog(connectionResult.getErrorCode());
}
}
private void showErrorDialog(int errorCode)
{
new AlertDialog.Builder(this)
.setMessage(String.valueOf(errorCode))
.setPositiveButton(android.R.string.ok,
new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int id)
{
dialog.dismiss();
}
}).show();
}
// Define the callback method that receives location updates
#Override
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();
}
}
When I try to load this 'page' by clicking a button from a previous page it doesn't load up. I was at least expecting the map (of Top Gear test track) to load up.
What could be stopping the map from loading up?
Is my approach to creating what I'm after correct?
I have pretty much followed:
http://developer.android.com/training/location/retrieve-current.html
http://developer.android.com/training/location/receive-location-updates.html
(I haven't bothered with the Shared Preferences thing).
I think to test it I would be best to use my home location lat/lang but for the moment I can't get the map to appear? This was tested on my HTC One so shouldn't be a Google Play Services issue as the screen that loads this one is a static (except zoom in/out) Map of the same place.
I appreciate this is a 'large' question and I would appreciate feedback from people that have experience/created a 'location-aware' application.
Thanks.
You may refer to the article https://software.intel.com/en-us/articles/implementing-map-and-geofence-features-in-android-business-apps
Add Android Manifest permissions:
<uses-permission android:name=”android.permission.INTERNET"/>
and
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
<meta-data
android:name="com.google.android.maps.v2.API_KEY"
android:value="copy your API Key here"/>
To add a map fragment:
and
…
private static final LatLng CHANDLER = new LatLng(33.455,-112.0668);
…
private static final StoreLocation[] ALLRESTURANTLOCATIONS = new StoreLocation[] {
new StoreLocation(new LatLng(33.455,-112.0668), new String("Phoenix, AZ")),
new StoreLocation(new LatLng(33.5123,-111.9336), new String("SCOTTSDALE, AZ")),
new StoreLocation(new LatLng(33.3333,-111.8335), new String("Chandler, AZ")),
new StoreLocation(new LatLng(33.4296,-111.9436), new String("Tempe, AZ")),
new StoreLocation(new LatLng(33.4152,-111.8315), new String("Mesa, AZ")),
new StoreLocation(new LatLng(33.3525,-111.7896), new String("Gilbert, AZ"))
};
…
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.geolocation_view);
mMap = ((MapFragment) getFragmentManager().findFragmentById(R.id.storelocationmap)).getMap();
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(CHANDLER, ZOOM_LEVEL));
Drawable iconDrawable = getResources().getDrawable(R.drawable.ic_launcher);
Bitmap iconBmp = ((BitmapDrawable) iconDrawable).getBitmap();
for(int ix = 0; ix < ALLRESTURANTLOCATIONS.length; ix++) {
mMap.addMarker(new MarkerOptions()
.position(ALLRESTURANTLOCATIONS[ix].mLatLng)
.icon(BitmapDescriptorFactory.fromBitmap(iconBmp)));
}
Then you add the LocationListener and the location update callbacks.

Categories

Resources