javaandroidgeolocationandroid-geofence

GEOFENCE_NOT_AVAIBLE (code 1000) while trying to set up geofence


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!


Solution

  • 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):

    enter image description here

    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.