Open ashbash0697 opened 6 years ago
Hi, I have the same problem and change the Lines: 233 and 236 in MainActivity.java:
Intent intent = new Intent(getApplicationContext(), GeofenceBroadcastRutaReceiver.class); // We use FLAG_UPDATE_CURRENT so that we get the same pending intent back when calling // addGeofences() and removeGeofences(). mGeofencePendingIntent = PendingIntent.getBroadcast(mContext, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
========== Context mContext; @Override protected void onCreate(Bundle savedInstanceState) { mContext = this; }
Please tell me the best solution for Geofencing. I use a ForeGroundService with a notification on Top instead of the IntentService as it wasnt working. and have a PendingIntent to receive the entry/exit events . But still My geofencing solution doesnt work at all.
Same thing here, geofencing doesn't trigger when the app is closed. Geofencing only works with foreground service.
Would be great it someone at google could make a statement.
@pramodit do you use the BroadcastReceiver
like in the sample?
Now it works fine for me . I used a JobScheduler and scheduling the job every now and then as this background thread gets killed in Android Oreo due to Background Execution Limits . @DevEddy Please try with the JobService . It worked like a charm to me
Hi @pramodit I am glad that it works for you now.
Could you provide some snippets how you're doing this? I would be very thankful.
Sure @DevEddy This is how i am doing it . I use this JobService and reschedule it every 1 secs in Android O to make sure the OS dont kill my service. /**
@TargetApi(21) public class OreoJobService extends JobService {
private JobParameters mParams;
//Assuming it takes maximum 5 seconds for
private String TAG = "OreoJobService";
public boolean onStartJob(JobParameters params) {
this.mParams = params;
String command = params.getExtras().getString("command");
if (command != null && command.equals("stop")) {
this.endJob();
return false;
} else {
if (MyApplication.getInstance().geoFencePendingIntent == null) {
if (params.getExtras().containsKey("fromJobScheduler")) {
String geoFences = MyApplication.getInstance().fetchGeoFences();
if (geoFences != null) {
List<Fence> fencesList = new Gson().fromJson(geoFences, new TypeToken<List<Fence>>() {
}.getType());
MyApplication.getInstance().createGeoFences(fencesList);
}
}
} else {
Log.e(TAG, "onStartJob: scheduling job ");
this.scheduleJob(10000);
}
return true;
}
}
void endJob() {
this.jobFinished(this.mParams, false);
}
void scheduleJob(long interval) {
ComponentName serviceName = new ComponentName(this.getPackageName(), OreoJobService.class.getName());
PersistableBundle extras = new PersistableBundle();
extras.putString("command", "start");
extras.putInt("fromJobScheduler", 1);
JobInfo jobInfo = (new JobInfo.Builder(VariableConstants_Fortees.GEOFENCE_JOB_ID, serviceName))
.setExtras(extras).setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.setMinimumLatency(interval)
.setOverrideDeadline(interval)
.build();
JobScheduler jobScheduler = (JobScheduler) this.getSystemService(Context.JOB_SCHEDULER_SERVICE);
assert jobScheduler != null;
jobScheduler.schedule(jobInfo);
this.endJob();
}
public boolean onStopJob(JobParameters params) {
return false;
}
}
###################### And here's my logic for scheduling ##########################
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
ComponentName serviceName = new ComponentName(this, OreoJobService.class.getName());
PersistableBundle extras = new PersistableBundle();
extras.putString("command", "start");
JobInfo jobInfo = (new JobInfo.Builder(VariableConstants_Fortees.GEOFENCE_JOB_ID, serviceName))
.setExtras(extras).setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.setMinimumLatency(1L)
.setOverrideDeadline(1L)
.build();
JobScheduler jobScheduler = (JobScheduler) this.getSystemService(Context.JOB_SCHEDULER_SERVICE);
try {
jobScheduler.schedule(jobInfo);
} catch (IllegalArgumentException errorMessage) {
errorMessage.printStackTrace();
}
}
Can you share the working sample if its possible?I am trying for this solution last one week
@pramodit Does your solution still work ? I have tried everything at this point
Yes it still works like a charm for me @kraghu
If you want it to make it optimised for every other locations , you could use a WorkManager which is compatabile for all regions such as for china, where there are no GooglePlayServices , it uses FirebaseDispatcher, AlarmManager for some devices and JobScheduler wherever necessary @kraghu :)
JobService for Geofences project
please send me geofence project
Sure @DevEddy This is how i am doing it . I use this JobService and reschedule it every 1 secs in Android O to make sure the OS dont kill my service. /**
- JobService for Geofences above Android Oreo
- @author Pramod
- @SInCE 16-Sept-2018. */
@TargetApi(21) public class OreoJobService extends JobService {
private JobParameters mParams; //Assuming it takes maximum 5 seconds for private String TAG = "OreoJobService"; public boolean onStartJob(JobParameters params) { this.mParams = params; String command = params.getExtras().getString("command"); if (command != null && command.equals("stop")) { this.endJob(); return false; } else { if (MyApplication.getInstance().geoFencePendingIntent == null) { if (params.getExtras().containsKey("fromJobScheduler")) { String geoFences = MyApplication.getInstance().fetchGeoFences(); if (geoFences != null) { List<Fence> fencesList = new Gson().fromJson(geoFences, new TypeToken<List<Fence>>() { }.getType()); MyApplication.getInstance().createGeoFences(fencesList); } } } else { Log.e(TAG, "onStartJob: scheduling job "); this.scheduleJob(10000); } return true; } } void endJob() { this.jobFinished(this.mParams, false); } void scheduleJob(long interval) { ComponentName serviceName = new ComponentName(this.getPackageName(), OreoJobService.class.getName()); PersistableBundle extras = new PersistableBundle(); extras.putString("command", "start"); extras.putInt("fromJobScheduler", 1); JobInfo jobInfo = (new JobInfo.Builder(VariableConstants_Fortees.GEOFENCE_JOB_ID, serviceName)) .setExtras(extras).setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) .setMinimumLatency(interval) .setOverrideDeadline(interval) .build(); JobScheduler jobScheduler = (JobScheduler) this.getSystemService(Context.JOB_SCHEDULER_SERVICE); assert jobScheduler != null; jobScheduler.schedule(jobInfo); this.endJob(); } public boolean onStopJob(JobParameters params) { return false; }
}
###################### And here's my logic for scheduling ##########################
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
ComponentName serviceName = new ComponentName(this, OreoJobService.class.getName()); PersistableBundle extras = new PersistableBundle(); extras.putString("command", "start"); JobInfo jobInfo = (new JobInfo.Builder(VariableConstants_Fortees.GEOFENCE_JOB_ID, serviceName)) .setExtras(extras).setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY) .setMinimumLatency(1L) .setOverrideDeadline(1L) .build(); JobScheduler jobScheduler = (JobScheduler) this.getSystemService(Context.JOB_SCHEDULER_SERVICE); try { jobScheduler.schedule(jobInfo); } catch (IllegalArgumentException errorMessage) { errorMessage.printStackTrace(); } }
@pramodit why you create geofences every time in service
MyApplication.getInstance().createGeoFences(fencesList);
Because Android Oreo and above doesn't provide frequent location update,
Don't we need to call location update service in the background? I am confused :(
@RameshPokharel Hey am not creating the fences its just named that way. i am just registering them once for all . i get the fences from an API call and then i use them. if it's already created then i don't recreate the fences
Hi, I am using the example code of geofencing, it does not seem to work the broadcast receiver is not being called, I've tried many solutions nothing seems to work