我的Android应用程序中有一个位置管理器,有时可以使用。有时我会运行该应用程序,它会获得位置更新(有一些错误(。有时我会运行它,它会每隔几秒钟抛出此错误而不会收到任何位置更新:
E/IzatSvc_PassiveLocListener: Exiting with error onLocationChanged line 152 "1"
这是我管理位置事件的类:
package com.company.AppName;
import android.app.job.JobParameters;
import android.app.job.JobService;
import android.content.Context;
import android.content.Intent;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
public class LocationListenerService extends JobService {
private static final String TAG = "LocationListenerService";
private LocationManager locationManager = null;
private LocationListener locationListener = null;
private String locationProvider = null;
public LocationListenerService() {}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
@Override
public boolean onStartJob(JobParameters params) {
Log.i(TAG, "onStartJob");
startLocationManager(params);
return true;
}
@Override
public boolean onStopJob(JobParameters params) {
Log.i(TAG, "onStopJob");
return false;
}
public void startLocationManager(JobParameters params) {
if(locationManager != null) return;
Criteria criteria = new Criteria();
criteria.setAccuracy(Criteria.ACCURACY_FINE);
// criteria.setPowerRequirement(Criteria.POWER_LOW);
criteria.setAltitudeRequired(false);
criteria.setBearingRequired(false);
locationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
locationProvider = locationManager.getBestProvider(criteria, true);
locationListener = new LocationListener();
if (locationProvider != null) {
Log.v(TAG, "Location provider: " + locationProvider);
} else {
Log.e(TAG, "Location provider is null. Location events will not work.");
return;
}
if (locationListener == null) {
Log.e(TAG, "Location listener is null. Location events will not work.");
return;
}
// Finish job after first time updating location with the server
NativeApp.shared().getLocationData((NativeApp app, String response) -> {
Log.i(TAG, "Received location data response. Finishing job.");
jobFinished(params, true);
});
try {
locationManager.requestLocationUpdates(locationProvider, 0, 0, locationListener);
} catch (java.lang.SecurityException ex) {
Log.e(TAG, "fail to request location update, ignore", ex);
} catch (IllegalArgumentException ex) {
Log.e(TAG, "network provider does not exist, " + ex.getMessage());
}
}
private class LocationListener implements android.location.LocationListener {
@Override
public void onLocationChanged(Location location) {
if(location == null) {
Log.w(TAG, "onLocationChanged skipped: null location");
return;
}
Log.i(TAG, "onLocationChanged: " + location.toString());
NativeApp.shared().updateLocation(location);
}
@Override
public void onProviderDisabled(String provider) {
Log.i(TAG, "onProviderDisabled: " + provider);
}
@Override
public void onProviderEnabled(String provider) {
Log.i(TAG, "onProviderEnabled: " + provider);
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
Log.i(TAG, "onStatusChanged: " + provider);
}
}
}
为什么会这样?为什么位置更新有时有效,而其他时候无效?
编辑:放弃几个小时并重新运行后,该应用程序仍然反复抛出错误,但大约 10 秒后记录此并开始接收位置更新:
E/XTCC-6.1.2.10: [FDAL_OSListener] handleLocationUpdate: failed: 2
D/LocationManagerService: incoming location: gps
I/LgeGnssLocationProvider: Intent - android.location.GPS_FIX_CHANGE
D/LgeGnssLocationProvider: GPS_FIX_CHANGE_ACTION! , mGpsNavigating =true
D/LocationManagerService: incoming location: gps
设备/版本信息:
该设备是运行Android 8.0.0的LG G6(LG-H872(。
这是我的AndroidManifest.xml文件的内容:
<?xml version='1.0' encoding='utf-8'?>
<manifest android:hardwareAccelerated="true" android:versionCode="10000" android:versionName="1.0.0" package="com.company.AppName" xmlns:android="http://schemas.android.com/apk/res/android">
<supports-screens android:anyDensity="true" android:largeScreens="true" android:normalScreens="true" android:resizeable="true" android:smallScreens="true" android:xlargeScreens="true" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application android:hardwareAccelerated="true" android:icon="@mipmap/icon" android:label="@string/app_name" android:supportsRtl="true">
<activity android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale" android:label="@string/activity_name" android:launchMode="singleTop" android:name="MainActivity" android:screenOrientation="portrait" android:theme="@android:style/Theme.DeviceDefault.NoActionBar" android:windowSoftInputMode="adjustResize">
<intent-filter android:label="@string/launcher_name">
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider android:authorities="${applicationId}.provider" android:exported="false" android:grantUriPermissions="true" android:name="org.apache.cordova.camera.FileProvider">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/camera_provider_paths" />
</provider>
<service android:enabled="true" android:name="com.company.AppName.LocationListenerService" android:permission="android.permission.BIND_JOB_SERVICE" />
<service android:exported="false" android:name="com.company.AppName.AppFirebaseMessagingService">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
</application>
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="26" />
</manifest>
long milliseconds = 5000; // 5 seconds
float minimusDistance = 5.5; // 5.5m distance from current location
locationManager.requestLocationUpdates(locationProvider, milliseconds, minimusDistance, locationListener);
试试这个片段。希望它能解决你的问题。
这只会发生,因此,您没有提供获取位置更新的最小间隔和最小距离。这就是您收到此错误的原因。
这是链接检查一下 - 请求位置更新
此位置更新因安卓版本而异。最近Android在奥利奥引入了后台位置限制,其中说:
当你的应用位于前台时,你应该会收到位置 根据您的要求进行更新。当你的应用进入 后台,你的应用只会收到几次位置更新 每小时(位置更新间隔将来可能会调整 基于系统影响和开发人员的反馈(。
Android 建议使用融合位置 API 的原因如下,您必须针对您的场景考虑它,例如:
如果您的应用需要访问包含以下内容的位置记录 时间频繁更新,使用融合位置的批处理版本 提供程序 API 元素,例如 FusedLocationProviderAPI 接口。 当应用在后台运行时,此 API 会收到 用户的位置比非批处理 API 更频繁。保持 但是请注意,您的应用仍然只会批量接收更新 每小时几次。
请参阅以下链接以获取更好的方法:
https://github.com/googlesamples/android-play-location/tree/master/LocationUpdatesForegroundService/app
https://codelabs.developers.google.com/codelabs/background-location-updates-android-o/index.html#0
注意:"O"后台位置限制仅在您的应用不再位于前台时启动。
如果以上两个链接对您不起作用,请告诉我。
我遇到了同样的问题,因为我的设备(通用移动GM8d(8.1操作系统更新到Android 9(Pie(。之后,我尝试使用LocationManager以以下方式获取位置:
LocationManager locationManager = (LocationManager) context.getSystemService(LOCATION_SERVICE);
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
0,
0,
new LocationListener() {
@Override
public void onLocationChanged(Location location) {
double latitude = location.getLatitude();
double longitude = location.getLongitude();
}
});
但是,在Android 9更新后,我遇到了同样的错误。对于解决方案,请执行以下步骤:
- 已重新启动的设备。
- 之后,打开地图应用程序(地图(。这样,GPS将通过本机系统处于活动状态。
- 之后,清除应用程序的缓存和存储,然后将其从设备中卸载。
- 在 Android Studio 的顶部栏上,文件>使缓存失效/重新启动...
- 最后,在设备上运行应用程序
- 位置将在13-24秒内完成,具体取决于您所在的地区。
做!