I am trying to implement geofencing in an app. As soon as user enters in the radius of geofence a notification is shown to the user and I have tried the below code but not getting notifications.Latitude and longitude are based on my location inside radius of geofencing.Any help will be appreciated :
MainActivity.java
public class MainActivity extends AppCompatActivity implements LocationListener{
PendingIntent mGeofencePendingIntent;
public static final int CONNECTION_FAILURE_RESOLUTION_REQUEST = 100;
private List<Geofence> mGeofenceList;
private GoogleApiClient mGoogleApiClient;
public static final String TAG = "Activity";
LocationRequest mLocationRequest;
double currentLatitude = 23.0023593, currentLongitude = 72.6665668;
Boolean locationFound;
protected LocationManager locationManager;
protected LocationListener locationListener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState == null) {
mGeofenceList = new ArrayList<Geofence>();
int resp = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (resp == ConnectionResult.SUCCESS) {
initGoogleAPIClient();
createGeofences(currentLatitude, currentLongitude);
} else {
Log.e(TAG, "Your Device doesn't support Google Play Services.");
}
// Create the LocationRequest object
mLocationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(1000)
.setFastestInterval(1000);
}
}
public void initGoogleAPIClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(connectionAddListener)
.addOnConnectionFailedListener(connectionFailedListener)
.build();
mGoogleApiClient.connect();
}
private GoogleApiClient.ConnectionCallbacks connectionAddListener =
new GoogleApiClient.ConnectionCallbacks() {
#Override
public void onConnected(Bundle bundle) {
Log.i(TAG, "onConnected");
Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (location == null) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, MainActivity.this);
} else {
currentLatitude = location.getLatitude();
currentLongitude = location.getLongitude();
Log.i(TAG, currentLatitude + " WORKS " + currentLongitude);
createGeofences(currentLatitude, currentLongitude);
}
try {
LocationServices.GeofencingApi.addGeofences(
mGoogleApiClient,
getGeofencingRequest(),
getGeofencePendingIntent()
).setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(Status status) {
if (status.isSuccess()) {
Log.i(TAG, "Saving Geofence");
} else {
Log.e(TAG, "Registering geofence failed: " + status.getStatusMessage() +
" : " + status.getStatusCode());
}
}
});
} catch (SecurityException securityException) {
Log.e(TAG, "Error");
}
}
#Override
public void onConnectionSuspended(int i) {
Log.e(TAG, "onConnectionSuspended");
}
};
public void createGeofences(double latitude, double longitude) {
String id = UUID.randomUUID().toString();
Geofence fence = new Geofence.Builder()
.setRequestId(id)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT)
.setCircularRegion(latitude, longitude, 1000)
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.build();
mGeofenceList.add(fence);
}
private GoogleApiClient.OnConnectionFailedListener connectionFailedListener =
new GoogleApiClient.OnConnectionFailedListener() {
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.e(TAG, "onConnectionFailed");
}
};
private GeofencingRequest getGeofencingRequest() {
GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER);
builder.addGeofences(mGeofenceList);
return builder.build();
}
private PendingIntent getGeofencePendingIntent() {
if (mGeofencePendingIntent != null) {
return mGeofencePendingIntent;
}
Intent intent = new Intent(this, GeofenceTransitionsIntentService.class);
return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
#Override
public void onLocationChanged(Location location) {
currentLatitude = location.getLatitude();
currentLongitude = location.getLongitude();
Log.i(TAG, "onLocationChanged");
}
}
GeofenceTransitionsIntentService.java
public class GeofenceTransitionsIntentService extends IntentService {
private static final String TAG = "GeofenceTransitions";
public GeofenceTransitionsIntentService() {
super("GeofenceTransitionsIntentService");
}
#Override
protected void onHandleIntent(Intent intent) {
Log.i(TAG, "onHandleIntent");
GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
if (geofencingEvent.hasError()) {
//String errorMessage = GeofenceErrorMessages.getErrorString(this,
// geofencingEvent.getErrorCode());
Log.e(TAG, "Goefencing Error " + geofencingEvent.getErrorCode());
return;
}
int geofenceTransition = geofencingEvent.getGeofenceTransition();
Log.i(TAG, "geofenceTransition = " + geofenceTransition + " Enter : " + Geofence.GEOFENCE_TRANSITION_ENTER + "Exit : " + Geofence.GEOFENCE_TRANSITION_EXIT);
if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER || geofenceTransition == Geofence.GEOFENCE_TRANSITION_DWELL){
showNotification("Entered", "Entered the Location");
}
else if(geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) {
Log.i(TAG, "Showing Notification...");
showNotification("Exited", "Exited the Location");
} else {
showNotification("Error", "Error");
Log.e(TAG, "Error ");
}
}
public void showNotification(String text, String bigText) {
NotificationManager notificationManager =
(NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingNotificationIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("Title")
.setContentText(text)
.setContentIntent(pendingNotificationIntent)
.setStyle(new NotificationCompat.BigTextStyle().bigText(bigText))
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true)
.build();
notificationManager.notify(0, notification);
}
}
Manifest.xml file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="example.com.geofincingdemo">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".GeofenceTransitionsIntentService"
android:exported="true" />
</application>
</manifest>
My GPS is also on with high accuracy and I am running on API Level 23.
Related
I am working on google geofence. I want to implement feature like UBER - when I enter or exit 100 meter radius, notification will come. I am getting the latitude and longitude from google places api which will be my geofence. Here is my MapActivity:
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, LocationListener {
private GoogleMap mMap;
String Longitude, Latitude;
Location ll;
final String TAG = "GPS";
private long UPDATE_INTERVAL = 2 * 1000; /* 10 secs */
private long FASTEST_INTERVAL = 2000; /* 2 sec */
static final int MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1;
GoogleApiClient gac;
LocationRequest locationRequest;
int PLACE_AUTOCOMPLETE_REQUEST_CODE = 1;
PlaceAutocompleteFragment autocompleteFragment;
Marker markerDesti, markerCurrentLoc;
LatLng DestiLoc;
double LatDesti, latCurrent;
double LonDesti, lngCurrent;
private static final int REQUEST_CODE_PERMISSION = 2;
String mPermission = Manifest.permission.ACCESS_FINE_LOCATION;
PendingIntent mGeofencePendingIntent;
ArrayList<Geofence> mGeofenceList;
private GeofencingClient mGeofencingClient;
TextView TestBtn;
LocationRequest mLocationRequest;
private GeofancingResultCallBack geofancingResultCallBack;
public static final class Constants {
public static int GEOFENCE_RADIUS_IN_METERS = 1000;
public static int GEOFENCE_EXPIRATION_IN_MILLISECONDS = 1000;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
TestBtn = (TextView) findViewById(R.id.TestBtn);
isGooglePlayServicesAvailable();
if (!isLocationEnabled())
showAlert();
locationRequest = new LocationRequest();
locationRequest.setInterval(UPDATE_INTERVAL);
locationRequest.setFastestInterval(FASTEST_INTERVAL);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
gac = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
//========================= PLACES API DROP DOWN============================//
mGeofencingClient = LocationServices.getGeofencingClient(this);
mGeofenceList = new ArrayList<>();
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
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;
}
mMap.setMyLocationEnabled(true);
getPlacesApi();
}
#Override
protected void onStart() {
gac.connect();
super.onStart();
}
#Override
protected void onStop() {
gac.disconnect();
super.onStop();
}
#Override
public void onLocationChanged(Location location) {
if (location != null) {
updateUI(location);
}
}
#Override
public void onConnected(#Nullable Bundle bundle) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(MapsActivity.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
return;
}
Log.d(TAG, "onConnected");
ll = LocationServices.FusedLocationApi.getLastLocation(gac);
Log.d(TAG, "LastLocation: " + (ll == null ? "NO LastLocation" : ll.toString()));
Log.e("MYLatLonLocationService", ll.toString());
Latitude = Double.toString(ll.getLatitude());
Longitude = Double.toString(ll.getLongitude());
Toast.makeText(getApplicationContext(), Latitude + "\n" + Longitude, Toast.LENGTH_LONG).show();
Log.e("Lat&Lon", Latitude + "\n" + Longitude);
latCurrent = ll.getLatitude();
lngCurrent = ll.getLongitude();
LatLng locCurrent = new LatLng(latCurrent, lngCurrent);
markerCurrentLoc = mMap.addMarker(new MarkerOptions()
.position(locCurrent)
.title("My 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(gac, locationRequest, this);
}
//=========== DRAW CURRENT LOCATION==============//
private void drawAllMarker() {
LatLng locCurrent = new LatLng(latCurrent, lngCurrent);
//mMap.addMarker(new MarkerOptions().position(locCurrent).title("My Location"));
markerCurrentLoc = mMap.addMarker(new MarkerOptions()
.position(locCurrent)
.title("My Location"));
/*mMap.moveCamera(CameraUpdateFactory.newLatLng(locCurrent));
CameraPosition cameraPosition = new CameraPosition.Builder().target(
locCurrent).zoom(13).build();
mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));*/
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(gac, locationRequest, this);
}
//=========== onRequestPermissionsResult ==============//
#Override
public void onRequestPermissionsResult(
int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
switch (requestCode) {
case MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(MapsActivity.this, "Permission was granted!", Toast.LENGTH_LONG).show();
try {
LocationServices.FusedLocationApi.requestLocationUpdates(
gac, locationRequest, this);
} catch (SecurityException e) {
Toast.makeText(MapsActivity.this, "SecurityException:\n" + e.toString(), Toast.LENGTH_LONG).show();
}
} else {
Toast.makeText(MapsActivity.this, "Permission denied!", Toast.LENGTH_LONG).show();
}
return;
}
}
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Toast.makeText(MapsActivity.this, "onConnectionFailed: \n" + connectionResult.toString(),
Toast.LENGTH_LONG).show();
Log.d("DDD", connectionResult.toString());
}
private void updateUI(Location loc) {
Log.d(TAG, "updateUI");
/*tvLatitude.setText(Double.toString(loc.getLatitude()));
tvLongitude.setText(Double.toString(loc.getLongitude()));
tvTime.setText(DateFormat.getTimeInstance().format(loc.getTime()));*/
TestBtn.setText(Double.toString(loc.getLatitude()));
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
return;
}
ll = LocationServices.FusedLocationApi.getLastLocation(gac);
Log.d(TAG, "LastLocation: " + (ll == null ? "NO LastLocation" : ll.toString()));
Log.e("MYLatLonLocationService", ll.toString());
Latitude = Double.toString(ll.getLatitude());
Longitude = Double.toString(ll.getLongitude());
Toast.makeText(getApplicationContext(), Latitude + "\n" + Longitude, Toast.LENGTH_LONG).show();
Log.e("Lat&Lon", Latitude + "\n" + Longitude);
if (markerCurrentLoc != null) {
markerCurrentLoc.remove();
latCurrent = ll.getLatitude();
lngCurrent = ll.getLongitude();
LatLng locCurrent = new LatLng(latCurrent, lngCurrent);
markerCurrentLoc = mMap.addMarker(new MarkerOptions()
.position(locCurrent)
.title("My Location"));
CameraPosition cameraPosition = new CameraPosition.Builder().target(
locCurrent).zoom(12).build();
mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
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(gac, locationRequest, this);
}else {
latCurrent = ll.getLatitude();
lngCurrent = ll.getLongitude();
LatLng locCurrent = new LatLng(latCurrent, lngCurrent);
markerCurrentLoc = mMap.addMarker(new MarkerOptions()
.position(locCurrent)
.title("My Location"));
markerCurrentLoc = mMap.addMarker(new MarkerOptions()
.position(locCurrent)
.title("My Location"));
CameraPosition cameraPosition = new CameraPosition.Builder().target(
locCurrent).zoom(12).build();
mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
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(gac, locationRequest, this);
}
}
private boolean isLocationEnabled() {
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) ||
locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
}
private boolean isGooglePlayServicesAvailable() {
final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
GoogleApiAvailability apiAvailability = GoogleApiAvailability.getInstance();
int resultCode = apiAvailability.isGooglePlayServicesAvailable(this);
if (resultCode != ConnectionResult.SUCCESS) {
if (apiAvailability.isUserResolvableError(resultCode)) {
apiAvailability.getErrorDialog(this, resultCode, PLAY_SERVICES_RESOLUTION_REQUEST)
.show();
} else {
Log.d(TAG, "This device is not supported.");
finish();
}
return false;
}
Log.d(TAG, "This device is supported.");
return true;
}
private void showAlert() {
final AlertDialog.Builder dialog = new AlertDialog.Builder(this);
dialog.setTitle("Enable Location")
.setMessage("Your Locations Settings is set to 'Off'.\nPlease Enable Location to " +
"use this app")
.setPositiveButton("Location Settings", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
Intent myIntent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(myIntent);
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface paramDialogInterface, int paramInt) {
}
});
dialog.show();
}
//=========================== PLACES API=======================//
public void getPlacesApi() {
autocompleteFragment = (PlaceAutocompleteFragment)
getFragmentManager().findFragmentById(R.id.place_autocomplete_fragment);
autocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
#Override
public void onPlaceSelected(Place place) {
// TODO: Get info about the selected place.
Log.i(TAG, "Place: " + place.getName());
if (markerDesti != null) {
markerDesti.remove();
LatDesti = place.getLatLng().latitude;
LonDesti = place.getLatLng().longitude;
Log.e("LatLonDest", String.valueOf(LatDesti));
DestiLoc = new LatLng(LatDesti, LonDesti);
markerDesti = mMap.addMarker(new MarkerOptions()
.position(DestiLoc)
.title("My Destination"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(DestiLoc));
CameraPosition cameraPosition = new CameraPosition.Builder().target(
DestiLoc).zoom(12).build();
mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
mGeofenceList.add(new Geofence.Builder()
.setRequestId("120")
.setCircularRegion(
LatDesti,
LonDesti,
Constants.GEOFENCE_RADIUS_IN_METERS
)
.setExpirationDuration(Constants.GEOFENCE_EXPIRATION_IN_MILLISECONDS)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER |
Geofence.GEOFENCE_TRANSITION_EXIT)
.build());
//geofancingResultCallBack.regesterAllGeofance();
//geofancingResultCallBack.myUpdateGeoFance(LatDesti, LonDesti);
//geofancingResultCallBack.getGeofencingRequest();
//geofancingResultCallBack.getmPendingIntent();
} else {
LatDesti = place.getLatLng().latitude;
LonDesti = place.getLatLng().longitude;
Log.e("LatLonDest", String.valueOf(LatDesti));
DestiLoc = new LatLng(LatDesti, LonDesti);
markerDesti = mMap.addMarker(new MarkerOptions()
.position(DestiLoc)
.title("My Destination"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(DestiLoc));
CameraPosition cameraPosition = new CameraPosition.Builder().target(
DestiLoc).zoom(12).build();
mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
mGeofenceList.add(new Geofence.Builder()
.setRequestId("120")
.setCircularRegion(
LatDesti,
LonDesti,
Constants.GEOFENCE_RADIUS_IN_METERS
)
.setExpirationDuration(Constants.GEOFENCE_EXPIRATION_IN_MILLISECONDS)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER |
Geofence.GEOFENCE_TRANSITION_EXIT)
.build());
//geofancingResultCallBack.regesterAllGeofance();
//geofancingResultCallBack.myUpdateGeoFance(LatDesti, LonDesti);
//geofancingResultCallBack.getGeofencingRequest();
//geofancingResultCallBack.getmPendingIntent();
}
if (ActivityCompat.checkSelfPermission(MapsActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
return;
}
mGeofencingClient.addGeofences(getGeofencingRequest(), getGeofencePendingIntent())
.addOnSuccessListener(MapsActivity.this, new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void aVoid) {
// Geofences added
Log.e("Geofencing Location service Api Client", "successfully added");
}
})
.addOnFailureListener(MapsActivity.this, new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
// Failed to add geofences
Log.e("Geofencing Location service Api Client", "unsuccessful");
}
});
//============================================================================================//
}
#Override
public void onError(Status status) {
// TODO: Handle the error.
Log.i(TAG, "An error occurred: " + status);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
//autocompleteFragment.onActivityResult(requestCode, resultCode, data);
if (requestCode == PLACE_AUTOCOMPLETE_REQUEST_CODE) {
if (resultCode == RESULT_OK) {
Place place = PlaceAutocomplete.getPlace(this, data);
Log.i(TAG, "Place:" + place.toString());
} else if (resultCode == PlaceAutocomplete.RESULT_ERROR) {
Status status = PlaceAutocomplete.getStatus(this, data);
Log.i(TAG, status.getStatusMessage());
} else if (requestCode == RESULT_CANCELED) {
}
}
}
//============================== GEO FANCING=================================//
private GeofencingRequest getGeofencingRequest() {
GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER);
builder.addGeofences(mGeofenceList);
return builder.build();
}
private PendingIntent getGeofencePendingIntent() {
// Reuse the PendingIntent if we already have it.
if (mGeofencePendingIntent != null) {
return mGeofencePendingIntent;
}
Intent intent = new Intent(this, BroadcastReciver.class);
// We use FLAG_UPDATE_CURRENT so that we get the same pending intent back when
// calling addGeofences() and removeGeofences().
mGeofencePendingIntent = PendingIntent.getService(this, 0, intent, PendingIntent.
FLAG_UPDATE_CURRENT);
return mGeofencePendingIntent;
}
}
and my broadcast receiver is
public class BroadcastReciver extends BroadcastReceiver {
//Placer Geofence intent action name
public static final String INTENT_ACTION_TRIGGER_FIRED = "com.placer.action.TRIGGER_FIRED";
public static final String TAG1 = GeofanceBroadCastReciver.class.getSimpleName();
private static final String TAG = "GeofenceTransitions";
public BroadcastReciver() {
}
#Override
public void onReceive(Context context, Intent intent) {
/*GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
if (geofencingEvent.hasError()){
Log.e(TAG,String.format("Error code :%d",geofencingEvent.getErrorCode()));
return;
}
int geofenceTransition = geofencingEvent.getGeofenceTransition();
if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER){
Log.e("Geo Fance ENTER","Geo Fance ENTER");
Toast.makeText(context, "Geo Fance ENTER", Toast.LENGTH_SHORT).show();
}else if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT){
Log.e("Geo Fance EXIT","Geo Fance EXIT");
Toast.makeText(context,"Geo Fance EXIT",Toast.LENGTH_SHORT).show();
}
else {
Log.e(TAG,String.format("Unknown Transition :%",geofenceTransition));
return;
}
sendNotification(context,geofenceTransition);*/
if (intent.getAction().equals(INTENT_ACTION_TRIGGER_FIRED)) {
Log.e("ReciverWorking","ReciverWorking");
GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
if (geofencingEvent.hasError()) {
Log.e(TAG, "Goefencing Error " + geofencingEvent.getErrorCode());
return;
}
// Get the transition type.
int geofenceTransition = geofencingEvent.getGeofenceTransition();
Log.i(TAG, "geofenceTransition = " + geofenceTransition + " Enter : " + Geofence.GEOFENCE_TRANSITION_ENTER + "Exit : " + Geofence.GEOFENCE_TRANSITION_EXIT);
if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER || geofenceTransition == Geofence.GEOFENCE_TRANSITION_DWELL){
showNotification("Congrats!!!", "You have reached your destination..",context);
Toast.makeText(context,"Enter the Location",Toast.LENGTH_SHORT).show();
}
else if(geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) {
Log.i(TAG, "Showing Notification...");
showNotification("Exited", "Exited the Location",context);
Toast.makeText(context,"Exited the Location",Toast.LENGTH_SHORT).show();
} else {
// Log the error.
showNotification("Error", "Error",context);
Log.e(TAG, "Error ");
}
}else {
throw new UnsupportedOperationException("Not yet implemented");
}
}
private void sendNotification(Context context,int transationType){
Intent notificationIntent = new Intent(context,MapsActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addParentStack(MapsActivity.class);
stackBuilder.addNextIntent(notificationIntent);
PendingIntent notificationpendingIntent = stackBuilder.getPendingIntent(0,PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
if (transationType == Geofence.GEOFENCE_TRANSITION_ENTER){
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setContentTitle("Entered");
}else if (transationType == Geofence.GEOFENCE_TRANSITION_EXIT) {
builder.setSmallIcon(R.mipmap.ic_launcher);
builder.setContentTitle("Exit");
}
builder.setContentText("Touch to launch the app");
builder.setContentIntent(notificationpendingIntent);
builder.setAutoCancel(true);
NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, builder.build());
}
public void showNotification(String text, String bigText,Context context) {
// 1. Create a NotificationManager
NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
// 2. Create a PendingIntent for AllGeofencesActivity
Intent intent = new Intent(context, MapsActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingNotificationIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
// 3. Create and send a notification
Notification notification = new NotificationCompat.Builder(context)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("Congrats!!!")
.setContentText("You Have reached the destination")
.setContentIntent(pendingNotificationIntent)
.setStyle(new NotificationCompat.BigTextStyle().bigText(bigText))
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true)
.build();
notificationManager.notify(0, notification);
}
the Android Manifest is:
<?xml version="1.0" encoding="utf-8"?>
<!--
The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
Google Maps Android API v2, but you must specify either coarse or fine
location permissions for the 'MyLocation' functionality.
-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-feature android:name="android.hardware.location.gps" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="#string/google_maps_key" />
<activity
android:name=".main.MapsActivity"
android:label="#string/title_activity_maps">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name=".adapters.GeofenceTransitionsIntentService"
android:exported="true" />
<receiver
android:name="com.map.pallabedp.locationbasedtracking.main.BroadcastReciver"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="com.placer.action.TRIGGER_FIRED" />
<action android:name="my.action.string" />
<action android:name="com.map.pallabedp.locationbasedtracking.main.BroadcastReciver"/>
</intent-filter>
</receiver>
</application>
The problem is i am not getting any notification. Please help..
I am really stuck at this point.Geofence really works fine when app is in forground that is notification comes properly. but when app goes is in background notification not comes.
I want like this when app is in background my geofence never expired and and get notified if user is outside the fence.
Also attached the code below:-
public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener,
ResultCallback<Status> {
protected static final int REQUEST_CHECK_SETTINGS = 0x1;
GoogleApiClient googleApiClient;
private MapFragment mapFragment;
private static final String TAG = MainActivity.class.getSimpleName();
private GoogleMap map;
private Location lastLocation;
private static final String NOTIFICATION_MSG = "NOTIFICATION MSG";
SharedPreferences pref;
SharedPreferences.Editor editor;
public static Intent makeNotificationIntent(Context context, String msg) {
Intent intent = new Intent(context, MainActivity.class);
intent.putExtra(NOTIFICATION_MSG, msg);
return intent;
}
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//setContentView(R.layout.activity_geofence);
pref = PreferenceManager.getDefaultSharedPreferences(MainActivity.this);
editor = pref.edit();
initGMaps();
createGoogleApi();
}
private void initGMaps() {
//mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
//mapFragment.getMapAsync(this);
}
private void createGoogleApi() {
Log.d(TAG, "createGoogleApi()");
if (googleApiClient == null) {
googleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
}
#Override
protected void onStart() {
super.onStart();
googleApiClient.connect();
settingsrequest();
}
public void settingsrequest() {
LocationRequest locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(30 * 1000);
locationRequest.setFastestInterval(5 * 1000);
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(locationRequest);
builder.setAlwaysShow(true); //this is the key ingredient
PendingResult<LocationSettingsResult> result =
LocationServices.SettingsApi.checkLocationSettings(googleApiClient, builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
#Override
public void onResult(LocationSettingsResult result) {
final Status status = result.getStatus();
final LocationSettingsStates state = result.getLocationSettingsStates();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
// All location settings are satisfied. The client can initialize location
// requests here.
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
// Location settings are not satisfied. But could be fixed by showing the user
// a dialog.
try {
// Show the dialog by calling startResolutionForResult(),
// and check the result in onActivityResult().
status.startResolutionForResult(MainActivity.this, REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException e) {
// Ignore the error.
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
// Location settings are not satisfied. However, we have no way to fix the
// settings so we won't show the dialog.
break;
}
}
});
}
#Override
protected void onStop() {
super.onStop();
// Disconnect GoogleApiClient when stopping Activity
googleApiClient.disconnect();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
// Check for the integer request code originally supplied to startResolutionForResult().
case REQUEST_CHECK_SETTINGS:
switch (resultCode) {
case Activity.RESULT_OK:
startLocationUpdates();
break;
case Activity.RESULT_CANCELED:
settingsrequest();//keep asking if imp or do whatever
break;
}
break;
}
}
#Override
public void onConnected(#Nullable Bundle bundle) {
// googleApiClient.disconnect();
Log.i(TAG, "onConnected()");
getLastKnownLocation();
//recoverGeofenceMarker();
startGeofence();
}
private final int REQ_PERMISSION = 999;
// Check for permission to access Location
private boolean checkPermission() {
Log.d(TAG, "checkPermission()");
// Ask for permission if it wasn't granted yet
return (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED);
}
// Asks for permission
private void askPermission() {
Log.d(TAG, "askPermission()");
ActivityCompat.requestPermissions(
this,
new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
REQ_PERMISSION
);
}
private void getLastKnownLocation() {
Log.d(TAG, "getLastKnownLocation()");
if (checkPermission()) {
lastLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
if (lastLocation != null) {
Log.i(TAG, "LasKnown location. " +
"Long: " + lastLocation.getLongitude() +
" | Lat: " + lastLocation.getLatitude());
writeLastLocation();
startLocationUpdates();
} else {
Log.w(TAG, "No location retrieved yet");
startLocationUpdates();
}
} else askPermission();
}
private void writeActualLocation(Location location) {
//textLat.setText("Lat: " + location.getLatitude());
//textLong.setText("Long: " + location.getLongitude());
markerLocation(new LatLng(location.getLatitude(), location.getLongitude()));
}
private void writeLastLocation() {
writeActualLocation(lastLocation);
}
private Marker locationMarker;
private void markerLocation(LatLng latLng) {
Log.i(TAG, "markerLocation(" + latLng + ")");
String title = latLng.latitude + ", " + latLng.longitude;
MarkerOptions markerOptions = new MarkerOptions()
.position(latLng)
.title(title);
if (map != null) {
if (locationMarker != null)
locationMarker.remove();
locationMarker = map.addMarker(markerOptions);
float zoom = 14f;
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, zoom);
map.animateCamera(cameraUpdate);
}
}
// Start Geofence creation process
private void startGeofence() {
Log.i(TAG, "startGeofence()");
Geofence geofence = createGeofence();
GeofencingRequest geofenceRequest = createGeofenceRequest(geofence);
addGeofence(geofenceRequest);
}
private static final long GEO_DURATION = 60 * 60 * 1000;
private static final String GEOFENCE_REQ_ID = "My Geofence";
private static final float GEOFENCE_RADIUS = 500.0f; // in meters
// Create a Geofence
private Geofence createGeofence() {
Log.d(TAG, "createGeofence");
//Intent i = getIntent();
//double la = i.getDoubleExtra("latitude", 0);
//double lo = i.getDoubleExtra("longitude", 0);
return new Geofence.Builder()
.setRequestId(GEOFENCE_REQ_ID)
.setCircularRegion(18.457532, 73.867746, GEOFENCE_RADIUS)
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_EXIT)
.build();
}
// Create a Geofence Request
private GeofencingRequest createGeofenceRequest(Geofence geofence) {
Log.d(TAG, "createGeofenceRequest");
return new GeofencingRequest.Builder()
.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_EXIT)
.addGeofence(geofence)
.build();
}
private PendingIntent geoFencePendingIntent;
private static final int GEOFENCE_REQ_CODE = 0;
private PendingIntent createGeofencePendingIntent() {
Log.d(TAG, "createGeofencePendingIntent");
if (geoFencePendingIntent != null)
return geoFencePendingIntent;
Intent intent = new Intent("com.aol.android.geofence.ACTION_RECEIVE_GEOFENCE");
return PendingIntent.getBroadcast(
this, GEOFENCE_REQ_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
// Add the created GeofenceRequest to the device's monitoring list
private void addGeofence(GeofencingRequest request) {
Log.d(TAG, "addGeofence");
if (checkPermission())
LocationServices.GeofencingApi.addGeofences(
googleApiClient,
request,
createGeofencePendingIntent()
).setResultCallback(this);
}
#Override
public void onConnectionSuspended(int i) {
Log.w(TAG, "onConnectionSuspended()");
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Log.w(TAG, "onConnectionFailed()");
}
private LocationRequest locationRequest;
// Defined in mili seconds.
// This number in extremely low, and should be used only for debug
private final int UPDATE_INTERVAL = 1000;
private final int FASTEST_INTERVAL = 900;
// Start location Updates
private void startLocationUpdates() {
Log.i(TAG, "startLocationUpdates()");
locationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(UPDATE_INTERVAL)
.setFastestInterval(FASTEST_INTERVAL);
if (checkPermission())
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
}
#Override
public void onLocationChanged(Location location) {
Log.d(TAG, "onLocationChanged [" + location + "]");
lastLocation = location;
writeActualLocation(location);
}
#Override
public void onResult(#NonNull Status status) {
Log.i(TAG, "onResult: " + status);
if (status.isSuccess()) {
// saveGeofence();
//drawGeofence();
} else {
// inform about fail
}
}
}
also attached Reciever code:-
public class GeofenceReciever extends BroadcastReceiver {
private static final String TAG = "BootReceiver";
Context contextBootReceiver;
Intent intent;
public static final int GEOFENCE_NOTIFICATION_ID = 0;
SharedPreferences pref;
SharedPreferences.Editor editor;
#Override
public void onReceive(Context context, Intent intent) {
this.contextBootReceiver = context;
this.intent = intent;
pref = PreferenceManager.getDefaultSharedPreferences(context);
editor = pref.edit();
GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
// Handling errors
if (geofencingEvent.hasError()) {
String errorMsg = getErrorString(geofencingEvent.getErrorCode());
Log.e(TAG, errorMsg);
return;
}
int geoFenceTransition = geofencingEvent.getGeofenceTransition();
// Check if the transition type is of interest
if (geoFenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) {
// Get the geofence that were triggered
Log.d("Trnsition", "Exited");
List<Geofence> triggeringGeofences = geofencingEvent.getTriggeringGeofences();
String geofenceTransitionDetails = getGeofenceTrasitionDetails(geoFenceTransition, triggeringGeofences);
// Send notification details as a String
//if (feedback.equalsIgnoreCase("F;1;")) {
// String temp = feedback;
sendNotification(geofenceTransitionDetails);
}
}
private String getGeofenceTrasitionDetails(int geoFenceTransition, List<Geofence> triggeringGeofences) {
// get the ID of each geofence triggered
ArrayList<String> triggeringGeofencesList = new ArrayList<>();
for (Geofence geofence : triggeringGeofences) {
triggeringGeofencesList.add(geofence.getRequestId());
}
String status = "Some switches are on";
if (geoFenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER)
System.out.println(status);
return status + TextUtils.join(", ", triggeringGeofencesList);
}
private void sendNotification(String msg) {
//intent = new Intent(contextBootReceiver, MainActivity.class);
//intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
//contextBootReceiver.startActivity(intent);
Log.i(TAG, "sendNotification: " + msg);
// Intent to start the main Activity
Intent notificationIntent = MainActivity.makeNotificationIntent(
contextBootReceiver, msg
);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(contextBootReceiver);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(notificationIntent);
PendingIntent notificationPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
// Creating and sending Notification
NotificationManager notificatioMng =
(NotificationManager) contextBootReceiver.getSystemService(Context.NOTIFICATION_SERVICE);
notificatioMng.notify(
GEOFENCE_NOTIFICATION_ID,
createNotification(msg, notificationPendingIntent));
}
// Create notification
private Notification createNotification(String msg, PendingIntent notificationPendingIntent) {
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(contextBootReceiver);
notificationBuilder
.setSmallIcon(R.drawable.ic_action_location)
.setColor(Color.RED)
.setContentTitle(msg)
.setContentText("Droidhomes Notification!")
.setContentIntent(notificationPendingIntent)
.setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE | Notification.DEFAULT_SOUND)
.setAutoCancel(true);
return notificationBuilder.build();
}
private static String getErrorString(int errorCode) {
switch (errorCode) {
case GeofenceStatusCodes.GEOFENCE_NOT_AVAILABLE:
return "GeoFence not available";
case GeofenceStatusCodes.GEOFENCE_TOO_MANY_GEOFENCES:
return "Too many GeoFences";
case GeofenceStatusCodes.GEOFENCE_TOO_MANY_PENDING_INTENTS:
return "Too many pending intents";
default:
return "Unknown error.";
}
}
}
Write your service like this:
public class GeoFencingService extends Service{
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//write your notification code here
//use START_STICKY if you want your service keep running else use START_NOT_STICKY
return Service.START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
//use this method to communicate with your activity
return null;
}
}
for detailed explanation have a look at these two links:
https://developer.android.com/guide/components/services.html
http://www.vogella.com/tutorials/AndroidServices/article.html
Let me know if any more help is required
So Far :-
When user in same(under fence area) it gives notification "user enters in area" is ok.But same user leave fence area its not notified.
This is my code:-
public class MainActivity extends AppCompatActivity implements
GoogleApiClient.ConnectionCallbacks,GoogleApiClient.OnConnectionFailedListener,
LocationListener, OnMapReadyCallback, GoogleMap.OnMapClickListener, GoogleMap.OnMarkerClickListener,
ResultCallback<Status>
{
private static final String TAG = MainActivity.class.getSimpleName();
private GoogleMap map;
private GoogleApiClient googleApiClient;
private Location lastLocation;
private TextView textLat, textLong;
private MapFragment mapFragment;
private static final String NOTIFICATION_MSG = "NOTIFICATION MSG";
// Create a Intent send by the notification
public static Intent makeNotificationIntent(Context context, String msg) {
Intent intent = new Intent(context, MainActivity.class);
intent.putExtra(NOTIFICATION_MSG, msg);
return intent;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textLat = (TextView) findViewById(R.id.lat);
textLong = (TextView) findViewById(R.id.lon);
// initialize GoogleMaps
initGMaps();
// create GoogleApiClient
createGoogleApi();
}
// Create GoogleApiClient instance
private void createGoogleApi() {
Log.d(TAG, "createGoogleApi()");
if (googleApiClient == null) {
googleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
}
#Override
protected void onStart() {
super.onStart();
// Call GoogleApiClient connection when starting the Activity
googleApiClient.connect();
}
#Override
protected void onStop() {
super.onStop();
// Disconnect GoogleApiClient when stopping Activity
googleApiClient.disconnect();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.geofence: {
startGeofence();
return true;
}
case R.id.clear: {
clearGeofence();
return true;
}
}
return super.onOptionsItemSelected(item);
}
private final int REQ_PERMISSION = 999;
// Check for permission to access Location
private boolean checkPermission() {
Log.d(TAG, "checkPermission()");
// Ask for permission if it wasn't granted yet
return (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED);
}
// Asks for permission
private void askPermission() {
Log.d(TAG, "askPermission()");
ActivityCompat.requestPermissions(
this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
REQ_PERMISSION
);
}
// Verify user's response of the permission requested
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
Log.d(TAG, "onRequestPermissionsResult()");
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQ_PERMISSION: {
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// Permission granted
getLastKnownLocation();
} else {
// Permission denied
permissionsDenied();
}
break;
}
}
}
// App cannot work without the permissions
private void permissionsDenied() {
Log.w(TAG, "permissionsDenied()");
// TODO close app and warn user
}
// Initialize GoogleMaps
private void initGMaps() {
mapFragment = (MapFragment) getFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
// Callback called when Map is ready
#Override
public void onMapReady(GoogleMap googleMap) {
Log.d(TAG, "onMapReady()");
map = googleMap;
map.setOnMapClickListener(this);
map.setOnMarkerClickListener(this);
}
#Override
public void onMapClick(LatLng latLng) {
Log.d(TAG, "onMapClick(" + latLng + ")");
//markerForGeofence(latLng);
}
#Override
public boolean onMarkerClick(Marker marker) {
Log.d(TAG, "onMarkerClickListener: " + marker.getPosition());
return false;
}
private LocationRequest locationRequest;
// Defined in mili seconds.
// This number in extremely low, and should be used only for debug
private final int UPDATE_INTERVAL = 1000;
private final int FASTEST_INTERVAL = 900;
// Start location Updates
private void startLocationUpdates() {
Log.i(TAG, "startLocationUpdates()");
locationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(UPDATE_INTERVAL)
.setFastestInterval(FASTEST_INTERVAL);
if (checkPermission())
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
}
#Override
public void onLocationChanged(Location location) {
Log.d(TAG, "onLocationChanged [" + location + "]");
lastLocation = location;
writeActualLocation(location);
}
// GoogleApiClient.ConnectionCallbacks connected
#Override
public void onConnected(#Nullable Bundle bundle) {
Log.i(TAG, "onConnected()");
getLastKnownLocation();
recoverGeofenceMarker();
startGeofence();
}
// GoogleApiClient.ConnectionCallbacks suspended
#Override
public void onConnectionSuspended(int i) {
Log.w(TAG, "onConnectionSuspended()");
}
// GoogleApiClient.OnConnectionFailedListener fail
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Log.w(TAG, "onConnectionFailed()");
}
// Get last known location
private void getLastKnownLocation() {
Log.d(TAG, "getLastKnownLocation()");
if (checkPermission()) {
lastLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
if (lastLocation != null) {
Log.i(TAG, "LasKnown location. " +
"Long: " + lastLocation.getLongitude() +
" | Lat: " + lastLocation.getLatitude());
writeLastLocation();
startLocationUpdates();
} else {
Log.w(TAG, "No location retrieved yet");
startLocationUpdates();
}
} else askPermission();
}
private void writeActualLocation(Location location) {
textLat.setText("Lat: " + location.getLatitude());
textLong.setText("Long: " + location.getLongitude());
markerLocation(new LatLng(location.getLatitude(), location.getLongitude()));
}
private void writeLastLocation() {
writeActualLocation(lastLocation);
}
private Marker locationMarker;
private void markerLocation(LatLng latLng) {
Log.i(TAG, "markerLocation(" + latLng + ")");
String title = latLng.latitude + ", " + latLng.longitude;
MarkerOptions markerOptions = new MarkerOptions()
.position(latLng)
.title(title);
if (map != null) {
if (locationMarker != null)
locationMarker.remove();
locationMarker = map.addMarker(markerOptions);
float zoom = 14f;
CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng, zoom);
map.animateCamera(cameraUpdate);
}
}
// Start Geofence creation process
private void startGeofence() {
Log.i(TAG, "startGeofence()");
Geofence geofence = createGeofence();
GeofencingRequest geofenceRequest = createGeofenceRequest(geofence);
addGeofence(geofenceRequest);
}
private static final long GEO_DURATION = 60 * 60 * 1000;
private static final String GEOFENCE_REQ_ID = "My Geofence";
private static final float GEOFENCE_RADIUS = 200.0f; // in meters
// Create a Geofence
private Geofence createGeofence() {
Log.d(TAG, "createGeofence");
return new Geofence.Builder()
.setRequestId(GEOFENCE_REQ_ID)
.setCircularRegion(18.478122, 73.890158, GEOFENCE_RADIUS)
.setExpirationDuration(GEO_DURATION)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_EXIT)
.build();
}
// Create a Geofence Request
private GeofencingRequest createGeofenceRequest(Geofence geofence) {
Log.d(TAG, "createGeofenceRequest");
return new GeofencingRequest.Builder()
.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER)
.addGeofence(geofence)
.build();
}
private PendingIntent geoFencePendingIntent;
private static final int GEOFENCE_REQ_CODE = 0;
private PendingIntent createGeofencePendingIntent() {
Log.d(TAG, "createGeofencePendingIntent");
if (geoFencePendingIntent != null)
return geoFencePendingIntent;
Intent intent = new Intent(this, GeofenceTrasitionService.class);
return PendingIntent.getService(
this, GEOFENCE_REQ_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
// Add the created GeofenceRequest to the device's monitoring list
private void addGeofence(GeofencingRequest request) {
Log.d(TAG, "addGeofence");
if (checkPermission())
LocationServices.GeofencingApi.addGeofences(
googleApiClient,
request,
createGeofencePendingIntent()
).setResultCallback(this);
}
#Override
public void onResult(#NonNull Status status) {
Log.i(TAG, "onResult: " + status);
if (status.isSuccess()) {
drawGeofence();
} else {
// inform about fail
}
}
// Draw Geofence circle on GoogleMap
private Circle geoFenceLimits;
private void drawGeofence() {
Log.d(TAG, "drawGeofence()");
if (geoFenceLimits != null)
geoFenceLimits.remove();
CircleOptions circleOptions = new CircleOptions()
.center(new LatLng(18.478122, 73.890158))
.strokeColor(Color.argb(50, 70, 70, 70))
.fillColor(Color.argb(100, 150, 150, 150))
.radius(GEOFENCE_RADIUS);
geoFenceLimits = map.addCircle(circleOptions);
}
private final String KEY_GEOFENCE_LAT = "GEOFENCE LATITUDE";
private final String KEY_GEOFENCE_LON = "GEOFENCE LONGITUDE";
// Saving GeoFence marker with prefs mng
private void saveGeofence() {
Log.d(TAG, "saveGeofence()");
SharedPreferences sharedPref = getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
// editor.putLong(KEY_GEOFENCE_LAT, Double.doubleToRawLongBits(geoFenceMarker.getPosition().latitude));
// editor.putLong(KEY_GEOFENCE_LON, Double.doubleToRawLongBits(geoFenceMarker.getPosition().longitude));
editor.apply();
}
// Recovering last Geofence marker
private void recoverGeofenceMarker() {
drawGeofence();
}
// Clear Geofence
private void clearGeofence() {
Log.d(TAG, "clearGeofence()");
LocationServices.GeofencingApi.removeGeofences(
googleApiClient,
createGeofencePendingIntent()
).setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(#NonNull Status status) {
if (status.isSuccess()) {
// remove drawing
removeGeofenceDraw();
}
}
});
}
private void removeGeofenceDraw() {
Log.d(TAG, "removeGeofenceDraw()");
}
}
To get notification:-
public class GeofenceTrasitionService extends IntentService {
private static final String TAG = GeofenceTrasitionService.class.getSimpleName();
public static final int GEOFENCE_NOTIFICATION_ID = 0;
public GeofenceTrasitionService() {
super(TAG);
}
#Override
protected void onHandleIntent(Intent intent) {
GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
// Handling errors
if ( geofencingEvent.hasError() ) {
String errorMsg = getErrorString(geofencingEvent.getErrorCode() );
Log.e( TAG, errorMsg );
return;
}
int geoFenceTransition = geofencingEvent.getGeofenceTransition();
// Check if the transition type is of interest
if (geoFenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT ) {
// Get the geofence that were triggered
List<Geofence> triggeringGeofences = geofencingEvent.getTriggeringGeofences();
String geofenceTransitionDetails = getGeofenceTrasitionDetails(geoFenceTransition, triggeringGeofences );
// Send notification details as a String
sendNotification( geofenceTransitionDetails );
}
}
private String getGeofenceTrasitionDetails(int geoFenceTransition, List<Geofence> triggeringGeofences) {
// get the ID of each geofence triggered
ArrayList<String> triggeringGeofencesList = new ArrayList<>();
for ( Geofence geofence : triggeringGeofences ) {
triggeringGeofencesList.add( geofence.getRequestId() );
}
String status = null;
if ( geoFenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT )
status = "Exiting ";
return status + TextUtils.join( ", ", triggeringGeofencesList);
}
private void sendNotification( String msg ) {
Log.i(TAG, "sendNotification: " + msg );
// Intent to start the main Activity
Intent notificationIntent = MainActivity.makeNotificationIntent(
getApplicationContext(), msg
);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(notificationIntent);
PendingIntent notificationPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
// Creating and sending Notification
NotificationManager notificatioMng =
(NotificationManager) getSystemService( Context.NOTIFICATION_SERVICE );
notificatioMng.notify(
GEOFENCE_NOTIFICATION_ID,
createNotification(msg, notificationPendingIntent));
}
// Create notification
private Notification createNotification(String msg, PendingIntent notificationPendingIntent) {
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this);
notificationBuilder
.setSmallIcon(R.drawable.ic_action_location)
.setColor(Color.RED)
.setContentTitle(msg)
.setContentText("Geofence Notification!")
.setContentIntent(notificationPendingIntent)
.setDefaults(Notification.DEFAULT_LIGHTS | Notification.DEFAULT_VIBRATE | Notification.DEFAULT_SOUND)
.setAutoCancel(true);
return notificationBuilder.build();
}
private static String getErrorString(int errorCode) {
switch (errorCode) {
case GeofenceStatusCodes.GEOFENCE_NOT_AVAILABLE:
return "GeoFence not available";
case GeofenceStatusCodes.GEOFENCE_TOO_MANY_GEOFENCES:
return "Too many GeoFences";
case GeofenceStatusCodes.GEOFENCE_TOO_MANY_PENDING_INTENTS:
return "Too many pending intents";
default:
return "Unknown error.";
}
}
}
As per tutorial i see:- there are 3 notification trigger
1.Enter 2.Dwell 3.Exit
I dont know how did i get notified when it leave the fence so far as in code i tried Exit.But no luck.
Ok i understand so just need to change the function :-
private GeofencingRequest createGeofenceRequest(Geofence geofence) {
Log.d(TAG, "createGeofenceRequest");
return new GeofencingRequest.Builder()
.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_EXIT)
.addGeofence(geofence)
.build();
}
Here i did changed My initial trigger with Exit
"GeofencingRequest.INITIAL_TRIGGER_EXIT"
and got perfect output.
This work for both enter and exit
private GeofencingRequest createGeofenceRequest(Geofence geofence) {
return new GeofencingRequest.Builder()
.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_EXIT|GeofencingRequest.INITIAL_TRIGGER_ENTER)
.addGeofence(geofence)
.build();
I am trying to add geofence when I receive it in FirebaseMessagingService. I am successfully able to add a geofence but for some reason, it doesn't fire. I have tried to debug and see what the problem is. But I simply can't figure out what the problem is. If anyone can point out the mistake. I would highly appreciate it.
This is my manifest
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<service
android:name=".GeofenceTrasitionService"
android:exported="true"/>
<service
android:name=".FirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
<service android:name=".FirebaseInstanceIDService">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT" />
</intent-filter>
</service>
Now when I receive that particular message to add a geofence only then I add it in my onReceive().
public class FirebaseMessagingService extends FirebaseMessagingService implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Log.i(TAG, "message_received");
Map<String, String> data = remoteMessage.getData();
String messageType = data.get("messageType");
switch (messageType) {
case "NewLocationAdded": {
if (checkPermission()) {
Completable.create(new CompletableOnSubscribe() {
#Override
public void subscribe(#io.reactivex.annotations.NonNull CompletableEmitter e) throws Exception {
GEOFENCE_REQ_CODE_STRING = data.get("locationid");
locationName = data.get("locationname");
interval = Long.parseLong(data.get("interval"));
fastestInterval = Long.parseLong(data.get("fastestinterval"));
locationRadius = Long.parseLong(data.get("locationradius"));
SharedPreferences sharedPreferences = getSharedPreferences("UserDetails", MODE_PRIVATE);
DatabaseReference databaseReference = com.google.firebase.database.FirebaseDatabase
.getInstance()
.getReference("Locations" + "/" + sharedPreferences.getString("UserID", "") + "/" + GEOFENCE_REQ_CODE_STRING);
GeoFire geoFire = new GeoFire(databaseReference);
geoFire.getLocation("Location", new LocationCallback() {
#Override
public void onLocationResult(String key, GeoLocation location) {
x = location.latitude;
y = location.longitude;
}
#Override
public void onCancelled(DatabaseError databaseError) {
}
});
latLng = new LatLng(x, y);
createGoogleApi();
mGoogleApiClient.connect();
}
}).observeOn(Schedulers.io()).subscribeOn(Schedulers.computation())
.subscribe(new DisposableCompletableObserver() {
#Override
public void onComplete() {
}
#Override
public void onError(#io.reactivex.annotations.NonNull Throwable e) {
Log.i(TAG, e.toString());
}
});
} else {
//Show Notitfication To Give Permission
}
break;
}
}
This works as expected. and when my mGoogleApiClient is connected I add my geofence.
#Override
public void onConnected(#Nullable Bundle bundle) {
Log.i(TAG, "Connected to GoogleApiClient");
startLocationUpdates();
Geofence geofence = createGeofence(latLng, locationRadius, GEOFENCE_REQ_CODE_STRING);
GeofencingRequest geofenceRequest = createGeofenceRequest(geofence);
addGeofence(geofenceRequest);
}
I will include the above-written functions for clarity. What they do is pretty staright forward.
// Create GoogleApiClient instance
private void createGoogleApi() {
Log.i(TAG, "createGoogleApi()");
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
}
// Start location Updates
private void startLocationUpdates() {
Log.i(TAG, "startLocationUpdates()");
locationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(300)
.setFastestInterval(200);
if (checkPermission())
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, locationRequest, this);
}
// Create a Geofence
private Geofence createGeofence(LatLng latLng, float radius, String locationid) {
Log.i(TAG, "createGeofence");
return new Geofence.Builder()
.setRequestId(locationid)
.setCircularRegion(latLng.latitude, latLng.longitude, radius)
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER
| Geofence.GEOFENCE_TRANSITION_EXIT | Geofence.GEOFENCE_TRANSITION_DWELL)
.setLoiteringDelay(30)
.build();
}
// Create a Geofence Request
private GeofencingRequest createGeofenceRequest(Geofence geofence) {
Log.i(TAG, "createGeofenceRequest");
return new GeofencingRequest.Builder()
.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER)
.addGeofence(geofence)
.build();
}
// Add the created GeofenceRequest to the device's monitoring list
private void addGeofence(GeofencingRequest request) {
Log.i(TAG, "addGeofence");
if (checkPermission()) {
LocationServices.GeofencingApi.addGeofences(mGoogleApiClient, request, createGeofencePendingIntent())
.setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(#NonNull Status status) {
Log.i(TAG, "onResult: " + status);
if (status.isSuccess()) {
saveGeofence();
// drawGeofence();
} else {
Log.i(TAG, "I failed in addGeofence()");
}
}
});
}
}
private PendingIntent createGeofencePendingIntent() {
Log.i(TAG, "createGeofencePendingIntent");
if (geoFencePendingIntent != null)
return geoFencePendingIntent;
Intent intent = new Intent(this, GeofenceTrasitionService.class);
return PendingIntent.getService(this, GEOFENCE_REQ_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
private void saveGeofence() {
Log.i(TAG, "saveGeofence()");
ArrayList<String> stringArrayList = new ArrayList<String>();
SharedPreferences sharedPreferences = getSharedPreferences("Locations", MODE_PRIVATE);
if (sharedPreferences.contains("GeofenceReqIDs")) {
stringArrayList.addAll(sharedPreferences.getStringSet("GeofenceReqIDs", null));
}
SharedPreferences.Editor editor = sharedPreferences.edit();
stringArrayList.add(GEOFENCE_REQ_CODE_STRING);
Set<String> stringSet = new HashSet<String>();
stringSet.addAll(stringArrayList);
editor.putStringSet("GeofenceReqIDs", stringSet);
editor.apply();
}
I know I have shared a lot of code, but I did it for clarity to my problem. I also posted logs. Lemme share them as well.
checkPermission()
createGoogleApi()
Connected to GoogleApiClient
startLocationUpdates()
checkPermission()
createGeofence
createGeofenceRequest
addGeofence
checkPermission()
createGeofencePendingIntent
onLocationChanged [Location[fused 25.314668,55.495936 acc=21 et=+5d3h47m13s84ms]]
onResult: Status{statusCode=SUCCESS, resolution=null}
saveGeofence()
If anyone can point out the problem. I would really appreciate it :)
I'm trying to start a BroadcastReceiver from an activity - and it seems the receiver doesnt start and I dont get any output in logCat for it.
Im trying to start the receiver by doing this:
Intent intent = new Intent();
intent.setAction(getPackageName()+".mybroadcast");
sendBroadcast(intent);
Also here is my receiver class:
public class TriggerReceiver extends BroadcastReceiver implements
GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
private Vibrator v;
private CountDownTimer timer;
private final long INTERVAL = 1000;
private final long TWO_MINUTES = INTERVAL * 60 * 2;
// === variables
private Context context;
private final String TAG = TriggerReceiver.class.getSimpleName();
#Override
public void onReceive(Context context, Intent intent) {
this.context = context;
Log.e(TAG, "Trigger receiver starting");
v = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
mRequestingLocationUpdates = false;
buildGoogleApiClient();
mGoogleApiClient.connect();
}
//
private void startTimer(final Location location) {
String message = context.getString(R.string.emergency_text).replace("/location here/", getMapLink(location));
sendSMS(message);
showNotification();
Log.e(TAG, " sending sms and this is the location " + location.getLatitude() + " " + location.getLongitude());
timer = new CountDownTimer(TWO_MINUTES, INTERVAL) {
#Override
public void onTick(long millisUntilFinished) {
Log.e(TAG, "Tick " + (millisUntilFinished / 1000));
int elapsedTime = (int) ((millisUntilFinished / 1000) % 60);
int minutes = (int) ((millisUntilFinished / 1000) / 60);
Log.e(TAG, elapsedTime + " | " + minutes);
if (minutes == 2) {
minutes = 1;
elapsedTime = 60;
}
}
//TODO start activity and pass extras to intent
#Override
public void onFinish() {
startTimer(mCurrentLocation);
}
}.start();
}
private void sendSMS(String message) {
ArrayList<Contact> contacts = ((BaseActivity) context).getContacts();
for (Contact contact : contacts) {
sendSMSmsg(contact.getNumber(), message);
}
}
private void stopTimer() {
timer.cancel();
}
/*location*/
/**
* Provides the entry point to Google Play services.
*/
protected GoogleApiClient mGoogleApiClient;
/**
* Stores parameters for requests to the FusedLocationProviderApi.
*/
protected LocationRequest mLocationRequest, quickLocationRequest;
/**
* Represents a geographical location.
*/
protected Location mCurrentLocation, mLastLocation;
protected Boolean mRequestingLocationUpdates;
/**
* 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(context)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
createLocationRequest();
}
protected void createLocationRequest() {
LocationRequest mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(110000);
mLocationRequest.setFastestInterval(55000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
protected void startLocationUpdates() {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}
protected void doQuickLocationUpdate() {
quickLocationRequest = new LocationRequest();
quickLocationRequest.setInterval(1000);
quickLocationRequest.setFastestInterval(500);
quickLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
// 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, quickLocationRequest, this);
}
protected void stopLocationUpdates() {
//TODO add this in onbackpresses and onStop
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
}
#Override
public void onConnected(Bundle connectionHint) {
Log.i(TAG, "Connected to GoogleApiClient");
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
if (mLastLocation != null) {
startTimer(mLastLocation);
} else {
doQuickLocationUpdate();
}
if (mCurrentLocation == null) {
mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
Log.d(TAG, "onConnected mCurrentLocation = " + mCurrentLocation.getLatitude());
}
if (mRequestingLocationUpdates) {
startLocationUpdates();
}
}
#Override
public void onLocationChanged(Location location) {
mCurrentLocation = location;
if (quickLocationRequest != null) {
quickLocationRequest = null;
}
if (timer == null) {
startTimer(location);
}
Log.d(TAG, "onLocationChanged mCurrentLocation = " + mCurrentLocation.getLatitude());
}
#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 void sendSMSmsg(String phoneNumber, String message) {
v.vibrate(50);
// ArrayList<PendingIntent> sentPendingIntents = new ArrayList<PendingIntent>();
// ArrayList<PendingIntent> deliveredPendingIntents = new ArrayList<PendingIntent>();
// PendingIntent sentPI = PendingIntent.getBroadcast(context, 0,
// new Intent(context, SmsSentReceiver.class), 0);
// PendingIntent deliveredPI = PendingIntent.getBroadcast(context, 0,
// new Intent(context, SmsDeliveredReceiver.class), 0);
// try {
// SmsManager sms = SmsManager.getDefault();
// ArrayList<String> mSMSMessage = sms.divideMessage(message);
// for (int i = 0; i < mSMSMessage.size(); i++) {
// sentPendingIntents.add(i, sentPI);
// deliveredPendingIntents.add(i, deliveredPI);
// }
// sms.sendMultipartTextMessage(phoneNumber, null, mSMSMessage,
// sentPendingIntents, deliveredPendingIntents);
//
// } catch (Exception e) {
// e.printStackTrace();
// }
}
public void showNotification() {
NotificationCompat.Builder mBuilder;
if (Build.VERSION.SDK_INT >= 16) {
mBuilder = new NotificationCompat.Builder(context)
.setSmallIcon(R.mipmap.sosicon)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setContentTitle(context.getString(R.string.app_name))
.setAutoCancel(true)
.setContentText(context.getString(R.string.notification_text));
// Creates an explicit intent for an Activity in your app
Intent resultIntent = new Intent();
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT
);
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(10142, mBuilder.build());
}
}
public String getMapLink(Location location) {
if (location != null) {
Log.d(TAG, "http://maps.google.com/maps?z=12&t=m&q=loc:" + location.getLatitude() + "+" + location.getLongitude());
return "http://maps.google.com/maps?z=12&t=m&q=loc:" + location.getLatitude() + "+" + location.getLongitude();
} else {
return null;
}
}
//
}
and also the declaration in the manifest:
<receiver
android:name=".TriggerReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="PACKAGENAME.mybroadcast" />
</intent-filter>
</receiver>
So what can be wrong here and why is the receiver not starting?
Thanks