Search code examples
androidgoogle-play-servicesandroid-locationandroid-geofence

Geofences not being added on Android Oreo


I'm not being able to add Geofences in my android App, A similar question was asked here before: Error adding geofences in Android (status code 1000) I have gone to Settings->Location and changed my location mode to High Accuracy and Tried adding the Geofences still it gives me the Error, My Device is Oneplus 3T running on Android 8.0. Also each time i change my Location Mode to High accuracy and if i Reboot my Device, surprisingly the location mode changes back again to "Device only" Mode.

I'm following this tutorial to implement Geofence: Android Location Proximity Alert

The logcat (stack trace) of the problem is shown:

2018-10-19 17:52:48.737 10711-11144/? I/GeofencerStateMachine: addGeofences called by com.example.rohit.geofencefundo
2018-10-19 17:52:48.745 10711-11059/? W/GeofencerStateMachine: Ignoring addGeofence because network location is disabled.
2018-10-19 17:52:48.781 26524-26524/com.example.rohit.geofencefundo W/System.err: com.google.android.gms.common.api.ApiException: 1000: 
2018-10-19 17:52:48.783 26524-26524/com.example.rohit.geofencefundo W/System.err:     at com.google.android.gms.common.internal.ApiExceptionUtil.fromStatus(Unknown Source:4)
2018-10-19 17:52:48.783 26524-26524/com.example.rohit.geofencefundo W/System.err:     at com.google.android.gms.common.internal.zai.zaf(Unknown Source:2)
2018-10-19 17:52:48.783 26524-26524/com.example.rohit.geofencefundo W/System.err:     at com.google.android.gms.common.internal.zaj.onComplete(Unknown Source:6)
2018-10-19 17:52:48.784 26524-26524/com.example.rohit.geofencefundo W/System.err:     at com.google.android.gms.common.api.internal.BasePendingResult.zaa(Unknown Source:172)
2018-10-19 17:52:48.784 26524-26524/com.example.rohit.geofencefundo W/System.err:     at com.google.android.gms.common.api.internal.BasePendingResult.setResult(Unknown Source:131)
2018-10-19 17:52:48.785 26524-26524/com.example.rohit.geofencefundo W/System.err:     at com.google.android.gms.common.api.internal.BaseImplementation$ApiMethodImpl.setResult(Unknown Source:36)
2018-10-19 17:52:48.785 26524-26524/com.example.rohit.geofencefundo W/System.err:     at com.google.android.gms.internal.location.zzba.zza(Unknown Source:22)
2018-10-19 17:52:48.785 26524-26524/com.example.rohit.geofencefundo W/System.err:     at com.google.android.gms.internal.location.zzan.dispatchTransaction(Unknown Source:41)
2018-10-19 17:52:48.786 26524-26524/com.example.rohit.geofencefundo W/System.err:     at com.google.android.gms.internal.location.zzb.onTransact(Unknown Source:22)
2018-10-19 17:52:48.786 26524-26524/com.example.rohit.geofencefundo W/System.err:     at android.os.Binder.execTransact(Binder.java:692)

My Manifest File:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.rohit.geofencefundo">
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <meta-data
            android:name="com.google.android.gms.version"
            android:value="@integer/google_play_services_version" />
        <meta-data
            android:name="com.google.android.geo.API_KEY"
            android:value="AIzaSyD0tTCVxdhFVzNdOZ6RJtkBba91xBdSb5A"/>
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>

        </activity>
        <service android:name=".LocationAlertIntentService" android:allowBackup="true"></service>
    </application>



</manifest>

My MainActivity:

package com.example.rohit.geofencefundo;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.Geofence;
import com.google.android.gms.location.GeofencingClient;
import com.google.android.gms.location.GeofencingRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;

import java.util.ArrayList;
import java.util.Map;

public class MainActivity extends AppCompatActivity implements OnMapReadyCallback {
    private static final int LOC_PERM_REQ_CODE = 1;
    //meters
    private static final int GEOFENCE_RADIUS = 2500;
    //in milli seconds
    private static final int GEOFENCE_EXPIRATION = 6000;
    private GoogleMap mMap;



    private GeofencingClient geofencingClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);




       /* geofencingClient = LocationServices.getGeofencingClient(this);
        showCurrentLocationOnMap();*/



        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.g_map);
        mapFragment.getMapAsync(this);

        geofencingClient = LocationServices.getGeofencingClient(this);




    }
    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        mMap.getUiSettings().setZoomControlsEnabled(true);
        mMap.setMinZoomPreference(15);

        showCurrentLocationOnMap();

        mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
            @Override
            public void onMapClick(LatLng latLng) {
                addLocationAlert(latLng.latitude, latLng.longitude);
            }
        });
    }
    @SuppressLint("MissingPermission")
    private void showCurrentLocationOnMap() {
        if (isLocationAccessPermitted()) {
            requestLocationAccessPermission();
        } else if (mMap != null) {
            mMap.setMyLocationEnabled(true);
        }
    }
    /*public void addFence(View view){

        addLocationAlert(28.360596,75.5863917); //28.360596 75.5863917  budh bhavan
        addLocationAlert( 28.3603219,75.5868534); //ram marg

    }*/






    /*@SuppressLint("MissingPermission")
    private void showCurrentLocationOnMap() {
        if (isLocationAccessPermitted()) {
            requestLocationAccessPermission();
        }
    }*/

    private boolean isLocationAccessPermitted() {
        if (ContextCompat.checkSelfPermission(this,
                android.Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED) {
            return true;
        } else {
            return false;
        }
    }

    private void requestLocationAccessPermission() {
        ActivityCompat.requestPermissions(this,
                new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
                LOC_PERM_REQ_CODE);
    }

    @SuppressLint("MissingPermission")
    private void addLocationAlert(double lat, double lng) {
        if (isLocationAccessPermitted()) {
            requestLocationAccessPermission();
        } else {
            String key = "" + lat + "-" + lng;
            Geofence geofence = getGeofence(lat, lng, key);
           /* geofencingClient.addGeofences(getGeofencingRequest(geofence),
                    getGeofencePendingIntent())
                    .addOnCompleteListener(new OnCompleteListener<Void>() {
                        @Override
                        public void onComplete(@NonNull Task<Void> task) {
                            if (task.isSuccessful()) {
                                Toast.makeText(MainActivity.this,
                                        "Location alter has been added",
                                        Toast.LENGTH_SHORT).show();
                            } else {
                                Toast.makeText(MainActivity.this,
                                        "Location alter could not be added",
                                        Toast.LENGTH_SHORT).show();
                            }
                        }
                    });*/


            geofencingClient.addGeofences(getGeofencingRequest(geofence),
                    getGeofencePendingIntent())
                    .addOnSuccessListener(this, new OnSuccessListener<Void>() {
                        @Override
                        public void onSuccess(Void aVoid) {
                            Toast.makeText(MainActivity.this, "added", Toast.LENGTH_SHORT).show();

                        }
                    })
                    .addOnFailureListener(this, new OnFailureListener() {
                        @Override
                        public void onFailure(@NonNull Exception e) {

                            Toast.makeText(MainActivity.this, e.toString(), Toast.LENGTH_SHORT).show();
                            e.printStackTrace();

                        }
                    });


        }
    }

    private void removeLocationAlert() {
        if (isLocationAccessPermitted()) {
            requestLocationAccessPermission();
        } else {
            geofencingClient.removeGeofences(getGeofencePendingIntent())
                    .addOnCompleteListener(new OnCompleteListener<Void>() {
                        @Override
                        public void onComplete(@NonNull Task<Void> task) {
                            if (task.isSuccessful()) {
                                Toast.makeText(MainActivity.this,
                                        "Location alters have been removed",
                                        Toast.LENGTH_SHORT).show();
                            } else {
                                Toast.makeText(MainActivity.this,
                                        "Location alters could not be removed",
                                        Toast.LENGTH_SHORT).show();
                            }
                        }
                    });
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults) {
        switch (requestCode) {
            case LOC_PERM_REQ_CODE: {
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    showCurrentLocationOnMap();
                    Toast.makeText(MainActivity.this,
                            "Location access permission granted, you try " +
                                    "add or remove location allerts",
                            Toast.LENGTH_SHORT).show();
                }
                return;
            }

        }
    }

    private PendingIntent getGeofencePendingIntent() {
        Intent intent = new Intent(this, LocationAlertIntentService.class);
        return PendingIntent.getService(this, 0, intent,
                PendingIntent.FLAG_UPDATE_CURRENT);
    }

    private GeofencingRequest getGeofencingRequest(Geofence geofence) {
        GeofencingRequest.Builder builder = new GeofencingRequest.Builder();

        builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_DWELL);
        builder.addGeofence(geofence);
        return builder.build();
    }

    private Geofence getGeofence(double lat, double lang, String key) {
        return new Geofence.Builder()
                .setRequestId(key)
                .setCircularRegion(lat, lang, GEOFENCE_RADIUS)
                .setExpirationDuration(Geofence.NEVER_EXPIRE)
                .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER |
                        Geofence.GEOFENCE_TRANSITION_DWELL)
                .setLoiteringDelay(10000)
                .build();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.main_menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.remove_loc_alert:
                removeLocationAlert();
                return true;
            default:
                return super.onOptionsItemSelected(item);

        }
    }


}

The LocationAlertIntentService is the same as shown in the tutorial which I'm referring to.

My Build.gradle (Module:app)

apply plugin: 'com.android.application'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.example.rohit.geofencefundo"
        minSdkVersion 19
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    implementation 'com.google.android.gms:play-services-location:16.0.0'
    implementation 'com.google.android.gms:play-services-maps:16.0.0'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}

EDIT: here are my App screenshots of the Error Error GeoFence

EDIT2: I tested this on my Friend's mobile and the geo fence was being "added" on his he had Redmi which was running on Android 7, so it seems to be a problem with my device, any suggestions on how i can fix it?


Solution

  • Fixed the Problem, I had to change my location mode to "Battery Saver" and then the google location sharing thing popped up, then i clicked on "Allow sharing of data" after which I'm being able to add the Geofences normally in my App.