Why FusedLocationApi (onLocationChanged) is not called in API > 23? - android

I have a service that get locations ,this service good work on API < 23 but on API > 23 don't get any location with Network .It just get me location with gps .
public class TrackLocationService extends Service implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, LocationListener {
private static final long SYNCHRONIZATION_INTERVAL = 60 * 60 * 1000;
private static boolean isServiceRunning;
private static final String TAG = "SADASDQWREQWRwerwer";
private int notificationId = 9999;
private GoogleApiClient googleApiClient;
private TrackLocationApplication app;
private DataHelper dataHelper;
public static boolean isServiceRunning() {
return isServiceRunning;
}
private static void setIsServiceRunning(boolean isServiceRunning) {
TrackLocationService.isServiceRunning = isServiceRunning;
EventBus.getDefault().post(AppEvent.SERVICE_STATE_CHANGED);
}
public TrackLocationService() {
}
#Override
public void onCreate() {
super.onCreate();
Log.d(TAG, "onCreate");
app = (TrackLocationApplication) getApplication();
dataHelper = DataHelper.getInstance(getApplicationContext());
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "onStartCommand");
createGoogleApiClient();
connectGoogleApiClient();
TrackLocationService.setIsServiceRunning(true);
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy");
stopLocationUpdates();
cancelNotification();
app.setStartLocation(null);
TrackLocationService.setIsServiceRunning(false);
}
#Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public void onLocationChanged(Location location) {
Log.d(TAG, "onLocationChanged");
if (app.getStartLocation() == null) {
app.setStartLocation(location);
}
Log.i("ASDASDASDASDA", location.getLatitude() + "" + location.getLongitude());
updateLocationData(location);
}
#Override
public void onConnected(Bundle bundle) {
Log.d(TAG, "onConnected");
startLocationUpdates();
}
#Override
public void onConnectionSuspended(int i) {
Log.d(TAG, "onConnectionSuspended");
}
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.d(TAG, "onConnectionFailed");
}
#Override
public void onTaskRemoved(Intent rootIntent) {
super.onTaskRemoved(rootIntent);
Log.d(TAG, "onTaskRemoved");
}
private void createGoogleApiClient() {
googleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
private void connectGoogleApiClient() {
if (googleApiClient != null) {
if (!(googleApiClient.isConnected() || googleApiClient.isConnecting())) {
googleApiClient.connect();
} else {
Log.d(TAG, "Client is connected");
startLocationUpdates();
}
} else {
Log.d(TAG, "Client is null");
}
}
private void startLocationUpdates() {
Log.i("ASDASDASDASDA", "1");
LocationRequest locationRequest = app.createLocationRequest();
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
scheduleDataSynchronization();
}
private void stopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(
googleApiClient, this);
stopDataSynchronization();
}
private void scheduleDataSynchronization() {
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, TrackLocationSyncReceiver.class);
PendingIntent alarmIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(),
SYNCHRONIZATION_INTERVAL, alarmIntent);
}
private void stopDataSynchronization() {
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, TrackLocationSyncReceiver.class);
PendingIntent alarmIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
alarmManager.cancel(alarmIntent);
}
private void updateLocationData(Location location) {
Location startLocation = app.getStartLocation();
double latitude = location.getLatitude();
double longitude = location.getLongitude();
float distance = Utils.distFromCoordinates((float) startLocation.getLatitude(),
(float) startLocation.getLongitude(),
(float) latitude,
(float) longitude);
String timeText = Utils.formatTime(System.currentTimeMillis());
long date = System.currentTimeMillis();
dataHelper.saveLocation(LocationData.getInstance(latitude, longitude, "2"));
updateNotification(timeText);
}
private void updateNotification(String text) {
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(getString(R.string.qomGardy))
.setContentText(text);
Intent resultIntent = new Intent(this, GetNumberActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(GetNumberActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT
);
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = mBuilder.build();
mNotificationManager.notify(notificationId, notification);
}
private void cancelNotification() {
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.cancel(notificationId);
}
private void synchronizeData() {
new AsyncTask<Void, Void, TrackLocationResponse>() {
private List<LocationData> locations;
#Override
protected TrackLocationResponse doInBackground(Void[] params) {
TrackLocationResponse response = null;
//locations = dataHelper.getLocationsToSync();
if (locations != null && locations.size() > 0) {
String deviceId = TrackLocationPreferencesManager.getDeviceId(getApplicationContext());
String userName = TrackLocationPreferencesManager.getUserName(getApplicationContext());
TrackLocationRequest request = TrackLocationRequest.getInstance(locations, deviceId, userName);
ITrackLocationClient client = new TrackLocationClient();
response = client.addTrack(request);
if (response != null && response.getStatus() == TrackLocationResponse.RESPONSE_CODE_OK) {
Log.d("TrackLocationSync", "Synced " + locations.size() + " items");
//dataHelper.markLocationsSynced(locations);
}
} else {
Log.d("TrackLocationSync", "No data to be synced");
}
return response;
}
#Override
protected void onPostExecute(TrackLocationResponse response) {
super.onPostExecute(response);
if (response != null && response.getStatus() == TrackLocationResponse.RESPONSE_CODE_OK) {
String message = null;
List<FriendResult> results = response.getResult();
if (results != null && results.size() > 0) {
StringBuilder messageBuilder = new StringBuilder();
messageBuilder.append("Hi from ");
for (FriendResult r : results) {
messageBuilder.append(" ");
messageBuilder.append(r.getTitle());
messageBuilder.append(",");
}
messageBuilder.deleteCharAt(messageBuilder.length() - 1);
message = messageBuilder.toString();
} else {
message = "Sync " + locations.size() + " items at " + Utils.formatTime(System.currentTimeMillis());
}
updateNotification(message);
}
}
}.execute();
}
}
I added these permission in my manifest for API > 23 :
<uses-permission-sdk-23 android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission-sdk-23 android:name="android.permission.ACCESS_FINE_LOCATION" />
don't called onLocationChanged() !
In my activity I get all of permissions.

On API 23+ you need to request permissions in runtime, not in the manifest:
Requesting Permissions at Run Time
Edit: In the code you posted you do not do ActivityCompat.requestPermissions only check for permissions, and as I said in 23+ you have to request the permissions at runtime, if you do it somewhere else, please add the code as well.
PS: you just need to implement the TODO: you have
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;}

Related

Location Update not working in OPPO, VIVO and MI Phones on Oreo

I am updating the location in the background every 5 minutes.
I checked below code in Android Oreo and above in Samsung and Motorola Devices. It is working fine. But when I checked in MI, OPPO and VIVO, location is not updating if I remove an application from recent task.
I checked this solution but didn't work.
public class GpsTracker extends Service
implements GoogleApiClient.OnConnectionFailedListener, GoogleApiClient.ConnectionCallbacks, LocationListener {
final static int REQUEST_LOCATION = 199;
private static final String TAG = GpsTracker.class.getSimpleName();
private static final int PERMISSIONS_REQUEST_PLAYLOCATION = 2000;
private static final int PERMISSIONS_REQUEST_LOCATION = 2001;
public static boolean IS_SERVICE_RUNNING = false;
protected LocationManager locationManager;
private PowerManager pm;
private PowerManager.WakeLock wl;
private Handler handler = new Handler();
private boolean mPlayLocationPermissionGranted;
private boolean mLocationPermissionGranted;
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
private Location mCurrentLocation;
private LocationTypes locationTypes = LocationTypes.HEARTBEAT;
private GPSTrackerVM gpsTrackerVM;
private boolean noConnect = true;
private Runnable periodicUpdate = new Runnable() {
#Override
public void run() {
handler.postDelayed(periodicUpdate, 5 * 60 * 1000 - SystemClock.elapsedRealtime() % 1000);
// whatever you want to do below
Utils.Log(TAG, "run: Service");
locationTypes = LocationTypes.HEARTBEAT;
buildGoogleApiClient();
}
};
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent.getAction() != null) {
showNotification();
Utils.Log(TAG, "onStartCommand: " + intent.getAction());
switch (intent.getAction()) {
case AppConfig.ACTION.START_FOREGROUND_ACTION:
Utils.Log(TAG, "Uploading Start");
locationTypes = LocationTypes.HEARTBEAT;
handler.post(periodicUpdate);
break;
case AppConfig.ACTION.START_DAY:
locationTypes = LocationTypes.IN;
buildGoogleApiClient();
break;
case AppConfig.ACTION.END_DAY:
locationTypes = LocationTypes.OUT;
buildGoogleApiClient();
break;
}
}
return START_STICKY;
}
#Override
public void onCreate() {
gpsTrackerVM = new GPSTrackerVM(MyApp.getInstance());
pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyApp:GpsTracker");
wl.acquire();
}
#Override
public void onDestroy() {
IS_SERVICE_RUNNING = false;
super.onDestroy();
wl.release();
}
private void mStopService() {
Utils.Log(TAG, "Sync Stop");
if (handler != null) {
handler.removeCallbacks(periodicUpdate);
}
if (mGoogleApiClient != null) {
mGoogleApiClient.disconnect();
}
stopForeground(true);
stopSelf();
}
private void showNotification() {
if (!IS_SERVICE_RUNNING) {
String channelId = AppConfig.NOTIFICATION_ID.SYNC_CHANNEL;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
channelId = createmNotificationChannel();
}
Intent notificationIntent = new Intent();
notificationIntent.setAction(AppConfig.ACTION.MAIN_ACTION);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent, 0);
Bitmap icon = BitmapFactory.decodeResource(getResources(),
R.drawable.ic_logo_notification);
Notification notification = new NotificationCompat.Builder(this, channelId)
.setContentTitle(getString(R.string.app_name))
.setTicker(getString(R.string.res_sync))
.setContentText(getString(R.string.res_sync))
.setSmallIcon(R.drawable.ic_logo_notification)
.setPriority(Notification.PRIORITY_DEFAULT)
.setLargeIcon(Bitmap.createScaledBitmap(icon, 128, 128, false))
.setContentIntent(pendingIntent)
.setOngoing(true)
.build();
startForeground(AppConfig.NOTIFICATION_ID.FOREGROUND_SERVICE_SYNC,
notification);
IS_SERVICE_RUNNING = true;
}
}
#RequiresApi(api = Build.VERSION_CODES.O)
private String createmNotificationChannel() {
String channelId = AppConfig.NOTIFICATION_ID.SYNC_CHANNEL;
String channelName = AppConfig.NOTIFICATION_ID.SYNC_CHANNEL;
NotificationChannel chan = new NotificationChannel(channelId,
channelName, NotificationManager.IMPORTANCE_DEFAULT);
chan.setLightColor(Color.BLUE);
chan.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
NotificationManager service = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
service.createNotificationChannel(chan);
return channelId;
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
public synchronized void buildGoogleApiClient() {
if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
retrieveCurrentLocation();
return;
}
mGoogleApiClient = new GoogleApiClient.Builder(MyApp.getInstance())
.addConnectionCallbacks(this)
.addApi(LocationServices.API)
.build();
createLocationRequest();
mGoogleApiClient.connect();
}
public synchronized void stopLocationUpdates() {
if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
// mGoogleApiClient.disconnect();
}
}
private void createLocationRequest() {
long UPDATE_INTERVAL_IN_MILLISECONDS = 100000;
long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS =
UPDATE_INTERVAL_IN_MILLISECONDS / 2;
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
#Override
public void onConnected(#Nullable Bundle bundle) {
retrieveCurrentLocation();
}
private void retrieveCurrentLocation() {
Log.d(TAG, "retrieveCurrentLocation: 11");
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
// get GPS status
boolean checkGPS = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (!checkGPS) {
Utils.Log(TAG, "retrieveCurrentLocation: GPS is Off");
updateCurrentLocation(null, "GPS is Turned Off");
return;
}
if (!hasLocationPermissions()) {
Utils.Log(TAG, "retrieveCurrentLocation: Location Permission Denied");
updateCurrentLocation(null, "Location Permission Denied");
return;
}
LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
.addLocationRequest(mLocationRequest);
builder.setAlwaysShow(true);
PendingResult<LocationSettingsResult> result =
LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient,
builder.build());
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
#Override
public void onResult(#NonNull LocationSettingsResult result) {
mPlayLocationPermissionGranted = false;
final Status status = result.getStatus();
final LocationSettingsStates states = result.getLocationSettingsStates();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
mPlayLocationPermissionGranted = true;
requestLocations();
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
mPlayLocationPermissionGranted = false;
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
Utils.Log(TAG, "retrieveCurrentLocation: GPS is On, but they need to allow location access from Settings");
updateCurrentLocation(null, "GPS is On, but they need to allow location access from Settings");
break;
}
}
});
}
private void requestLocations() {
Log.d(TAG, "requestLocations: 11");
try {
mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (mCurrentLocation == null) {
noConnect = true;
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
if (noConnect) {
updateCurrentLocation(null, "GPS is On, but your device needs one restart to continue locating the device.");
}
}
}, 1000);
}
// updateCurrentLocation(mCurrentLocation);
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,
mLocationRequest, this);
} catch (SecurityException ex) {
ex.printStackTrace();
}
}
private boolean hasLocationPermissions() {
if (ActivityCompat.checkSelfPermission(MyApp.getInstance(),
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED
&&
ActivityCompat.checkSelfPermission(MyApp.getInstance(),
Manifest.permission.ACCESS_COARSE_LOCATION)
== PackageManager.PERMISSION_GRANTED
) {
mLocationPermissionGranted = true;
} else {
mLocationPermissionGranted = false;
}
return mLocationPermissionGranted;
}
#Override
public void onLocationChanged(Location location) {
Utils.LogW(TAG, "onLocationChanged: " + location.toString());
if (noConnect) {
noConnect = false;
}
updateCurrentLocation(location, "None");
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
Log.d(TAG, "onConnectionFailed: ");
}
#Override
public void onConnectionSuspended(int i) {
Log.d(TAG, "onConnectionSuspended: ");
}
public void updateCurrentLocation(Location location, String remark) {
mCurrentLocation = location;
GPSData gpsData = new GPSData(UUID.randomUUID().toString());
gpsData.setLatitude(location == null ? 0 : location.getLatitude());
gpsData.setLongitude(location == null ? 0 : location.getLongitude());
gpsData.setAddress("None");
gpsData.setRemarks(remark);
gpsData.setTimeStamp(System.currentTimeMillis() / 1000L);
gpsData.setLocationType(locationTypes.getValue());
// Log.w(TAG, "updateCurrentLocation: " + location);
stopLocationUpdates();
if (locationTypes == LocationTypes.IN) {
Utils.Log(TAG, "In Success ");
Intent startIntent = new Intent(this, GpsTracker.class);
startIntent.setAction(AppConfig.ACTION.START_FOREGROUND_ACTION);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(startIntent);
} else {
startService(startIntent);
}
} else if (locationTypes == LocationTypes.OUT) {
Utils.Log(TAG, "out Success ");
mStopService();
} else if (locationTypes == LocationTypes.HEARTBEAT) {
Utils.Log(TAG, "HEARTBEAT Success ");
}
serverUpdate(gpsData);
}
private void serverUpdate(GPSData gpsData) {
gpsTrackerVM.updateLocation(gpsData);
}
public void onPermissionGrantStatus(boolean isGratned) {
Log.d(TAG, "onPermissionGrantStatus() called with: isGratned = [" + isGratned + "]");
}
}
In AndroidManifest.xml
<service android:name=".services.GpsTracker" />

How to lock my screen and my app will continue running

I have an app that records users location and draws a polyline.I want to know how to do that when the user locks his screen.I've implemented a foreground service so the user can do whatever he wants in his phone but it doesn't work if the user turns the screen off.Any ideas?I've seen the wake lock but they are only for not letting the screen turned off.
UPDATE
Here is the foreground service that runs when the user presses a button from the activity
public class MyForeGroundService extends Service implements LocationListener {
private static final String TAG_FOREGROUND_SERVICE = "FOREGROUND_SERVICE";
public static final String ACTION_START_FOREGROUND_SERVICE = "ACTION_START_FOREGROUND_SERVICE";
public static final String ACTION_STOP_FOREGROUND_SERVICE = "ACTION_STOP_FOREGROUND_SERVICE";
public static final String ACTION_PAUSE = "ACTION_PAUSE";
public static final String ACTION_PLAY = "ACTION_PLAY";
public static PolylineOptions line;
private LocationManager locationManager;
public static int steps = 0;
public MyForeGroundService() {
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public void onCreate() {
super.onCreate();
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,
3000,
1, this);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null) {
String action = intent.getAction();
switch (action) {
case ACTION_START_FOREGROUND_SERVICE:
startForegroundService();
break;
case ACTION_STOP_FOREGROUND_SERVICE:
stopForegroundService();
break;
case ACTION_PLAY:
Intent openMap= new Intent(this,Map.class);
startActivity(openMap);
break;
case ACTION_PAUSE:
break;
}
}
return super.onStartCommand(intent, flags, startId);
}
/* Used to build and start foreground service. */
private void startForegroundService() {
Log.d(TAG_FOREGROUND_SERVICE, "Start foreground service.");
// Create notification default intent.
Intent intent = new Intent(this,Map.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
// Create notification builder.
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
//Go back to Map activity if user press at the notification
builder.setContentIntent(pendingIntent)
.setContentTitle("gEKOning...")
.setContentText("Tap to open gEKOn app");
builder.setWhen(System.currentTimeMillis());
builder.setSmallIcon(R.mipmap.ic_launcher);
Bitmap largeIconBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.strava);
builder.setLargeIcon(largeIconBitmap);
// Make the notification max priority.
builder.setPriority(Notification.PRIORITY_MAX);
// Make head-up notification.
builder.setFullScreenIntent(pendingIntent, true);
// Build the notification.
Notification notification = builder.build();
// Start foreground service.
startForeground(1, notification);
}
private void stopForegroundService() {
Log.d(TAG_FOREGROUND_SERVICE, "Stop foreground service.");
// Stop foreground service and remove the notification.
stopForeground(true);
// Stop the foreground service.
stopSelf();
}
#Override
public void onLocationChanged(Location location) {
String locationProvider = LocationManager.NETWORK_PROVIDER;
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;
}
location = locationManager.getLastKnownLocation(locationProvider);
try {
line.add(new LatLng(location.getLatitude(), location.getLongitude()));
GMap.addMarker(new MarkerOptions().position(new LatLng(location.getLatitude(), location.getLongitude())).title(""));
GMap.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(location.getLatitude(), location.getLongitude()), 16.0f));
steps++;
} catch (NullPointerException e) {
//Toast.makeText(this.getBaseContext(), "gyhg" + e.toString(), Toast.LENGTH_LONG).show();
}
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
#Override
public void onProviderEnabled(String s) {
}
#Override
public void onProviderDisabled(String s) {
}
}
you can create a background service that it works when user lock screen or close your app from background
you must create service with this way:
first create a Service class like this:
public class LocationService extends Service implements GoogleApiClient.ConnectionCallbacks {
public static double latitude;
public static double longitude;
private int retryGPS = 0;
private int retryNetwork = 0;
private Handler handler;
private Runnable runnable;
private GoogleApiClient mGoogleApiClient;
private LocationManager mLocationManager;
private LocationListener[] mLocationListeners = new LocationListener[]{
new LocationListener(LocationManager.GPS_PROVIDER),
};
private static final int LOCATION_INTERVAL = 0;
private static final float LOCATION_DISTANCE = 1;
private static final String TAG = "LocationService";
#Override
public void onCreate() {
buildGoogleApiClient();
initializeLocationManager();
locationRequest();
handler = new Handler();
runnable = new Runnable() {
#Override
public void run() {
sendLocation();
}
};
sendLocation();
}
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addApi(LocationServices.API)
.build();
}
private void initializeLocationManager() {
if (mLocationManager == null) {
mLocationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
}
}
private void locationRequest() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mLocationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER, LOCATION_INTERVAL, LOCATION_DISTANCE,
mLocationListeners[0]);
}
private void sendLocation() {
//TODO: you can use location here
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(final Intent intent, int flags, int startId) {
if (!mGoogleApiClient.isConnected())
mGoogleApiClient.connect();
return START_STICKY;
}
#Override
public void onConnected(Bundle bundle) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (location != null) {
latitude = location.getLatitude();
longitude = location.getLongitude();
} else {
try {
Thread.sleep(3000);
onConnected(null);
} catch (Exception e) {
e.printStackTrace();
}
}
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onDestroy() {
handler.removeCallbacks(runnable);
if (mLocationManager != null) {
for (LocationListener mLocationListener : mLocationListeners) {
try {
mLocationManager.removeUpdates(mLocationListener);
} catch (Exception e) {
e.printStackTrace();
}
}
}
super.onDestroy();
}
private class LocationListener implements android.location.LocationListener, ActivityCompat.OnRequestPermissionsResultCallback {
Location mLastLocation;
public LocationListener(String provider) {
Log.d(TAG, "LocationListener: " + provider);
mLastLocation = new Location(provider);
}
#Override
public void onLocationChanged(final Location location) {
mLastLocation.set(location);
latitude = location.getLatitude();
longitude = location.getLongitude();
Log.d(TAG, "onLocationChanged: { latitude: " + latitude + " ,longitude: " + longitude + " , accuracy: " + location.getAccuracy() + " }");
}
#Override
public void onProviderDisabled(String provider) {
Log.d(TAG, "onProviderDisabled: " + provider);
}
#Override
public void onProviderEnabled(String provider) {
Log.d(TAG, "onProviderEnabled: " + provider);
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.d(TAG, "onStatusChanged: " + status);
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
}
}
}
then register service in manifest:
<service
android:name=".service.LocationService"
android:enabled="true"
android:process=":process" />
then start service from any activity or fragment :
public static void mStopService(Context context) {
context.stopService(new Intent(context, LocationService.class));
}
public static void mStartService(Context context) {
context.startService(new Intent(context, LocationService.class));
}

GeofenceIntentService not getting triggered on geofence enter

I'm trying to create geofences without google maps (just service that triggers PendingIntent when user is in geofence area). The problem is that I'm not able to get response when user enters geofence location. Here is my code from service class:
public class GeofenceBackgroundService extends Service implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
LocationListener,
ResultCallback<Status> {
private GoogleApiClient googleApiClient;
private GeofencingClient mGeofencingClient;
private LocationRequest locationRequest;
private PendingIntent geoFencePendingIntent;
private final int GEOFENCE_REQ_CODE = 0;
private static final String GEOFENCE_REQ_ID = "My Geofence";
private static final float GEOFENCE_RADIUS = 500.0f;
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
/*mGeofencingClient = LocationServices.getGeofencingClient(this);*/
googleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
googleApiClient.connect();
locationRequest = LocationRequest.create()
.setInterval(10000)
.setFastestInterval(5000)
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
return START_STICKY;
}
#Override
public void onConnected(Bundle dataBundle) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
Geofence geofence = createGeofence();
GeofencingRequest geofenceRequest = createGeofenceRequest(geofence);
addGeofence(geofenceRequest);
}
#Override
public void onConnectionSuspended(int i) {
googleApiClient.connect();
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
#Override
public void onLocationChanged(Location location) {
if (location != null) {
Log.e("TAG", "Location changed " + location.getLatitude() +" " + location.getLongitude());
}
}
private Geofence createGeofence() {
return new Geofence.Builder()
.setRequestId(GEOFENCE_REQ_ID)
.setCircularRegion(35.3140045, 103.4839695, GEOFENCE_RADIUS)
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.setNotificationResponsiveness(1000)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT)
.build();
}
private GeofencingRequest createGeofenceRequest(Geofence geofence) {
return new GeofencingRequest.Builder()
.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER)
.addGeofence(geofence)
.build();
}
private PendingIntent createGeofencePendingIntent() {
if (geoFencePendingIntent != null)
return geoFencePendingIntent;
/*Intent intent = new Intent("com.receive.ACTION_RECEIVE_GEOFENCE");
PendingIntent geoFencePendingIntent = PendingIntent.getBroadcast( getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
return geoFencePendingIntent;*/
Intent intent = new Intent(this, GeofenceTransitionsIntentService.class);
return PendingIntent.getService(this, GEOFENCE_REQ_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
private void addGeofence(GeofencingRequest request) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
LocationServices.GeofencingApi.addGeofences(googleApiClient, request, createGeofencePendingIntent()).setResultCallback(this);
}
#Override
public void onResult(#NonNull Status status) {
if ( status.isSuccess() ) {
} else {
}
}
#Override
public void onDestroy() {
super.onDestroy();
googleApiClient.disconnect();
}}
Also I tried to use both IntentService and Broadcast receiver and declared them properly in android manifest file

Geofence Notification not get when app is in background.

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

Starting a BroadcastReceiver from activity

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

Categories

Resources