5

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:

  • Location services are set to High Accuracy
  • Wi-Fi and mobile data are enabled
  • Application is granted location permissions
  • Google Services are added to the project
  • Google Services and Play Store are up to date and installed on the device
  • Disabled battery optimizations (testing purpose)

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!

Domin
  • 1,075
  • 1
  • 11
  • 28
  • At what point do you set the `mGeofencingClient` and which context do you provide it? –  Jan 01 '19 at 17:31
  • I've updated the code. I set `mGeofencingClient` in the begin of `onCreate` and provide `getApplicationContext`. – Domin Jan 01 '19 at 17:35
  • And have you added LocationServices to the GoogleApiClient - (I'm just running through a checklist of things my app does - no need to post code) (1000 is the API error code)? –  Jan 01 '19 at 17:43
  • Do you mean Gradle implementation or I should programmatically add LocationServices to the GoogleApiClient? If programmatically (in the code) I haven't, because I used LocationManager – Domin Jan 01 '19 at 17:55
  • Okay, I made a little mess here. in my code I have LocationManager which requests LocationUpdates from `GPS_PROVIDER` and `NETWORK_PROVIDER`. I don't have instance of `GoogleApiClient`. 1000 is shown as API error code – Domin Jan 01 '19 at 18:20
  • I set up my own test project with your code and it was successful on an emulator. You may have in the OP - but on what call does the error come out? –  Jan 01 '19 at 18:50
  • Could you upload your test project source code, so that I will check it out? I can't understand where might be the problem. – Domin Jan 01 '19 at 18:54
  • The error occurs in `setGeofences` method, where I add onSuccess and onFailure listeners – Domin Jan 01 '19 at 18:55

2 Answers2

9

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.

  • Thanks for your sample. The funniest thing is that, I still get the same error (1000). So in your case, in `onSuccess` in `addOnSuccessListener` it logs you, that geofences are set up succesfully? – Domin Jan 01 '19 at 19:09
  • correct - might as well specify your target api level and testing device. –  Jan 01 '19 at 19:11
  • I've tried on both physical and emulator with different APIs level - since 26 to 28 – Domin Jan 01 '19 at 19:17
  • Post your app's build.gradle - so I can be sure I'm using same library levels - I'm using `com.google.android.gms:play-services-location:16.0.0` –  Jan 01 '19 at 19:19
  • unfortunately I'm using the same too – Domin Jan 01 '19 at 19:20
  • I was able to recreate your error: see this post (at bottom): https://androidforums.com/threads/error-adding-geofence-on-android-8.1289302/ - if and when you get the "improve" dialog I said "disagree" and the error occurred - and flipped mode again to get the "agree" prompt and it works - so maybe you disagreed at some point? If this works for you I'll post a few screen shots for the next person - doesn't really explain anything though. –  Jan 01 '19 at 19:47
  • I've just took apart and cleaned all Google Services data and have done it so far and it helped me. I'm running custom software and to get this pop up window I had to enter Google Maps(lol) and then just accept. Anyway, Google should mention to do this so. Thank you for your help. – Domin Jan 01 '19 at 20:12
0

for android oreo to android S make sure to access setting high priority because geofence need that or it became error 1000

fun ceksetting(){
val builder = LocationSettingsRequest.Builder()
        .addLocationRequest(locationRequest)
val locationRequest = LocationRequest()
    locationRequest!!.interval = 50000
    locationRequest!!.fastestInterval = 50000
    locationRequest!!.smallestDisplacement = 170f // 170 m = 0.1 mile
    locationRequest!!.priority = LocationRequest.PRIORITY_HIGH_ACCURACY //set according to your app function
    val client: SettingsClient = LocationServices.getSettingsClient(requireActivity())
    val task: Task<LocationSettingsResponse> = client.checkLocationSettings(builder.build())
    task.addOnSuccessListener { locationSettingsResponse ->
       //here call your geofence
    }

    task.addOnFailureListener { exception ->
        if (exception is ResolvableApiException){
            // Location settings are not satisfied, but this can be fixed
            // by showing the user a dialog.
            try {
                // Show the dialog by calling startResolutionForResult(),
                // and check the result in onActivityResult().
                exception.startResolutionForResult(requireActivity(),
                    REQUEST_CHECK_SETTINGS)
            } catch (sendEx: IntentSender.SendIntentException) {
                // Ignore the error.
            }
        }
    }
}
reza rahmad
  • 1,009
  • 10
  • 16