Android Oreo 上未添加地理围栏

Posted

技术标签:

【中文标题】Android Oreo 上未添加地理围栏【英文标题】:Geofences not being added on Android Oreo 【发布时间】:2019-03-24 08:43:14 【问题描述】:

我无法在我的 android 应用程序中添加地理围栏,之前在这里问过一个类似的问题:Error adding geofences in Android (status code 1000) 我已经转到设置->位置并将我的位置模式更改为高精度并尝试添加地理围栏仍然给我错误,我的设备是在 Android 8.0 上运行的 Oneplus 3T。 此外,每次我将位置模式更改为高精度时,如果我重新启动设备,令人惊讶的是,位置模式会再次更改回“仅限设备”模式。

我正在按照本教程实施地理围栏:Android Location Proximity Alert

显示问题的logcat(堆栈跟踪):

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)

我的清单文件:

<?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>

我的主要活动:

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);

        
    



LocationAlertIntentService 与我所指的教程中显示的相同。

我的 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'

编辑:这是我的错误应用截图 Error GeoFence

EDIT2:我在朋友的手机上测试了这个,地理围栏被“添加”到他的 Redmi 上运行 Android 7,所以这似乎是我的设备的问题,有什么建议可以解决吗?

【问题讨论】:

【参考方案1】:

解决了这个问题,我不得不将我的位置模式更改为“省电模式”,然后弹出了谷歌位置共享的东西,然后我点击了“允许共享数据”,之后我就可以添加地理围栏了通常在我的应用程序中。

【讨论】:

以上是关于Android Oreo 上未添加地理围栏的主要内容,如果未能解决你的问题,请参考以下文章

尝试设置地理围栏时 GEOFENCE_NOT_AVAIBLE(代码 1000)

无法在 Android 中添加地理围栏,因为“网络位置已禁用”

Android - 需要添加超过 100 个地理围栏

Android地理围栏不会触发一次位置关闭和再次打开[重复]

仅使用 gps 定位模式的 Android 地理围栏监控

Android 地理围栏是不是能够在重启后幸存下来?