The problem occurs on Android older than Oreo and both Oreo and newer.
I can't get geofences working even though following steps are done:
I've checked with the following code if GPS_PROVIDER
and NETWORK_PROVIDER
are enabled:
@Override
protected void onResume() {
super.onResume();
LocationManager manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
Log.e("Provider", "Provider is not avaible");
} else if (manager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
Log.v("Provider", "GPS Provider is avaible");
}
if (!manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){
Log.e("Network Provider", "Provider is not avaible");
} else if (manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){
Log.v("Network Provider", "provider is avaible");
}
}
Those both above gave me positive result, so problem can't be here.
Exact error:
E/Geofence: com.google.android.gms.common.api.ApiException: 1000:
I set mGeofencingClient
in the begin of onCreate
:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGeofencingClient = LocationServices.getGeofencingClient(getApplicationContext());
I set geofences with the following code:
mGeofenceList.add(
new Geofence.Builder()
.setRequestId("blablabla")
.setCircularRegion(50.32, 43.23, 232)
.setExpirationDuration(-1L)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER |
Geofence.GEOFENCE_TRANSITION_EXIT)
.build());
// }
PermissionCheck mPermissionCheck = new PermissionCheck();
if (!mPermissionCheck.isPermissionGranted(getApplicationContext())){
mPermissionCheck.askForPermission(MainActivity.this);
return;
}
setGeofences();
}
private GeofencingRequest getGeofencingRequest(){
if (mGeofenceList.isEmpty()){
return null;}
Log.v("mGeofenceList", mGeofenceList.toString());
GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER |
GeofencingRequest.INITIAL_TRIGGER_EXIT);
builder.addGeofences(mGeofenceList);
return builder.build();
}
private PendingIntent getGeofencePendingIntent(){
if (mGeofencePendingIntent != null){
return mGeofencePendingIntent;
}
Intent intent = new Intent(getApplicationContext(), Geofencing.class);
mGeofencePendingIntent = PendingIntent.getService(getApplication(),
0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
return mGeofencePendingIntent;
}
@SuppressLint("MissingPermission")
private void setGeofences(){
GeofencingRequest geofencingRequest = getGeofencingRequest();
PendingIntent pi = getGeofencePendingIntent();
mGeofencingClient.addGeofences(geofencingRequest, pi)
.addOnSuccessListener(MainActivity.this, new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
Log.d("Geofences", "geofencing set up succesfully");
Toast.makeText(MainActivity.this, "Geofences set up", Toast.LENGTH_SHORT).show();
}
})
.addOnFailureListener(MainActivity.this, new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.e("Geofence", e.toString());
LocationManager manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
Log.e("Provider", "Provider is not avaible");
}
if (!manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){
Log.e("Network Provider", "Provider is not avaible");
}
}
});
}
This code is almost the same as from Google Documentation. Manifest permission:
<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.network"/>
<uses-feature android:name="android.hardware.location.gps"/>
Gradle:
implementation 'com.google.android.gms:play-services-maps:16.0.0'
implementation 'com.google.android.gms:play-services-location:16.0.0'
Can anyone see the mystake I could have done? Thanks in advance!
OK this is a minimal working program for geofences based on you OP - just to rule out your code implementation - there's a couple other interfaces implemented for other tests so ignore.
"Working" means it successfuly adds the geofence.:
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, LocationListener, ActivityCompat.OnRequestPermissionsResultCallback {
private List<Geofence> mGeofenceList = new ArrayList<>();
private GeofencingClient gfc;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
gfc = LocationServices.getGeofencingClient(getApplicationContext());
mGeofenceList.add(new Geofence.Builder().setRequestId("aa").setCircularRegion(50.32, 43.23, 232).setExpirationDuration(-1L).setTransitionTypes(
Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT).build());
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
// Check Permissions Now
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
1);
}
else {
setGeofences();
}
}
private GeofencingRequest getGeofencingRequest(){
if (mGeofenceList.isEmpty()){
return null;}
Log.v("mGeofenceList", mGeofenceList.toString());
GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER |
GeofencingRequest.INITIAL_TRIGGER_EXIT);
builder.addGeofences(mGeofenceList);
return builder.build();
}
private PendingIntent mGeofencePendingIntent;
private PendingIntent getGeofencePendingIntent(){
if (mGeofencePendingIntent != null){
return mGeofencePendingIntent;
}
Intent intent = new Intent(getApplicationContext(), Object.class);
mGeofencePendingIntent = PendingIntent.getService(getApplication(),
0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
return mGeofencePendingIntent;
}
@SuppressLint("MissingPermission")
private void setGeofences(){
GeofencingRequest geofencingRequest = getGeofencingRequest();
PendingIntent pi = getGeofencePendingIntent();
gfc.addGeofences(geofencingRequest, pi)
.addOnSuccessListener(this, new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
Log.d("Geofences", "geofencing set up succesfully");
Toast.makeText(MapsActivity.this, "Geofences set up", Toast.LENGTH_SHORT).show();
}
})
.addOnFailureListener(MapsActivity.this, new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
Log.e("Geofence", e.toString());
LocationManager manager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER)){
Log.e("Provider", "Provider is not avaible");
}
if (!manager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){
Log.e("Network Provider", "Provider is not avaible");
}
}
});
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
setGeofences();
}
}
After some investigation I found I could recreate the 1000 error code with this code sample. It is based on this forum post: https://androidforums.com/threads/error-adding-geofence-on-android-8.1289302/
So to follow those directions (to fix - but I flipped them to recreate and then fix):
Use phone "Settings | Security & location | Location | Mode" - toggle between "High accuracy, Battery saving or Device only" until you get this prompt (the settings path will vary depending on android build):
In this example code - if you respond with "DISAGREE", the example code will generate the 1000 error code; if you repeat and respond with "AGREE" it will be successful in adding the geofence.