我使用下面的应用程序代码从GPS每秒接收位置更新,并打印输出到日志。只要应用程序在前台,这对我来说就很好,但是当它被移动到后台时,更新就会停止,直到它被带回前台。
我在清单
中有这些权限<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.android.hardware.location.gps"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
这是服务类
public class GoogleService extends Service implements LocationListener {
boolean isGPSEnable = false;
boolean isNetworkEnable = false;
double latitude, longitude;
LocationManager locationManager;
Location location;
private Handler mHandler = new Handler();
private Timer mTimer = null;
long notify_interval = 1000;
public static String str_receiver = "servicetutorial.service.receiver";
Intent intent;
public GoogleService() {
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
mTimer = new Timer();
mTimer.schedule(new TimerTaskToGetLocation(), 5, notify_interval);
intent = new Intent(str_receiver);
fn_getlocation();
}
@Override
public void onLocationChanged(Location location) {
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
private void fn_getlocation() {
locationManager = (LocationManager) getApplicationContext().getSystemService(LOCATION_SERVICE);
isGPSEnable = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
isNetworkEnable = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnable && !isNetworkEnable) {
} else {
if (isNetworkEnable) {
location = null;
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000, 0, this);
if (locationManager != null) {
location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null) {
Log.e("latitude", location.getLatitude() + "");
Log.e("longitude", location.getLongitude() + "");
latitude = location.getLatitude();
longitude = location.getLongitude();
fn_update(location);
}
}
}
if (isGPSEnable) {
location = null;
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0, this);
if (locationManager != null) {
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null) {
Log.e("latitude", location.getLatitude() + "");
Log.e("longitude", location.getLongitude() + "");
latitude = location.getLatitude();
longitude = location.getLongitude();
fn_update(location);
}
}
}
}
}
private class TimerTaskToGetLocation extends TimerTask {
@Override
public void run() {
mHandler.post(new Runnable() {
@Override
public void run() {
fn_getlocation();
}
});
}
}
private void fn_update(Location location) {
intent.putExtra("latitude", location.getLatitude() + "");
intent.putExtra("longitude", location.getLongitude() + "");
sendBroadcast(intent);
}
}
timertasktotlocation工作正常。前台是Logcat
2021-08-21 02:29:42.400 8904-8904/com.websarva.wings.android.notification4 E/get_longitude:135.22084902
2021-08-21 02:29:43.416 8904-8904/com.websarva.wings.android.notification4 E/get_latitude:34.8317199
2021-08-21 02:29:43.416 8904-8904/com.websarva.wings.android.notification4 E/get_longitude:135.2209639
2021-08-21 02:29:43.431 8904-8904/com.websarva.wings.android.notification4 E/get_latitude:34.83170759
2021-08-21 02:29:43.431 8904-8904/com.websarva.wings.android.notification4 E/get_longitude:135.22084902
这是后台的Logcat。
2021-08-21 02:30:28.748 8904-8904/com.websarva.wings.android.notification4 E/get_latitude:34.83170759
2021-08-21 02:30:28.749 8904-8904/com.websarva.wings.android.notification4 E/get_longitude:135.22084902
2021-08-21 02:30:28.766 8904-8904/com.websarva.wings.android.notification4 E/get_latitude:34.83170759
2021-08-21 02:30:28.766 8904-8904/com.websarva.wings.android.notification4 E/get_longitude:135.22084902
还需要做些什么呢?
考虑将服务作为前台启动,并显示此类服务的通知或使用WorkManager。Google官方建议如下:
"如果你的应用程序的API级别为26或更高,当应用程序本身不在前台时,系统会对运行后台服务施加限制。例如,在大多数情况下,您不应该从后台访问位置信息。相反,使用WorkManager来安排任务。https://developer.android.com/guide/components/services
你可以在https://androidwave.com/foreground-service-android-example/这样的网页上找到例子我已经检查过这种方法,它适用于你的情况。
关于WorkManager,您也可以使用https://developer.android.com/topic/libraries/architecture/workmanager