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 中添加地理围栏,因为“网络位置已禁用”