[英]getting location updates in foreground service isn't working when app is moved to background
i'm using the below app code to recieve locations updates from the GPS every 5 seconds and print an output to the log.我正在使用以下应用程序代码每 5 秒从 GPS 接收位置更新,并将 output 打印到日志中。 this works fine for me as long as the app is in foreground, but the updates stop when it is moved to background until it is being brought back to foreground.只要应用程序处于前台,这对我来说就很好,但是当它移动到后台时更新会停止,直到它被带回前台。 i'm using galaxy s20 (android 10) to run and debug, and the application is set to never be put to sleep (android setting).我正在使用galaxy s20(android 10)来运行和调试,并且应用程序设置为永不休眠(android设置)。 here is the full process description:这是完整的过程描述:
i have these permissions at the manifest:我在清单上有这些权限:
<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" />
this is the main activity that enables the GPS and creates the service:这是启用 GPS 并创建服务的主要活动:
public class MainActivity extends AppCompatActivity {
private LocationManager _locManager;
private Intent _scanServiceIntent;
public void onStart()
{
super.onStart();
boolean gps_enabled = _locManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (gps_enabled)
{
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.INTERNET}, 1);
_scanServiceIntent = new Intent(this, ScanService.class);
startService(_scanServiceIntent);
}
}
}
this is the service class - i'm creating a notification in order to make the serice run all the time - even when the app goes to background:这是服务 class - 我正在创建通知以使服务始终运行 - 即使应用程序进入后台:
public class ScanService extends Service {
private LocationListener _locListener;
private LocationManager _locManager;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
super.onStartCommand(intent, flags, startId);
String NOTIFICATION_CHANNEL_ID = "com.tandenkore.mychannel";
PendingIntent pendingIntent = PendingIntent.getActivity(this,0,intent,0);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
Notification notification = notificationBuilder.setOngoing(true)
.setContentTitle("App is running in background")
.setPriority(NotificationManager.IMPORTANCE_MAX)
.setCategory(Notification.CATEGORY_SERVICE)
.setContentIntent(pendingIntent)
.build();
startForeground(300, notification);
return START_STICKY;
}
@Override
public void onCreate() {
_locListener = new MyLocationListener();
_locManager = (LocationManager)getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
_locManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 0, _locListener);
}
@Override
public void onDestroy() {
super.onDestroy();
stopForeground(true);
_locManager.removeUpdates(_locListener);
}
class MyLocationListener implements LocationListener {
@Override
public void onLocationChanged(Location location)
{
Log.v(TAG, "location changes");
}
}
}
when i debug it on the device and the application is in the foreground, i am getting an output in logcat of "location changes" line every 5 seconds.当我在设备上调试它并且应用程序在前台时,我每 5 秒在“位置更改”行的 logcat 中得到一个 output。 this is the behavior i am looking for.这是我正在寻找的行为。 the problem happens when the app is going to background, then i receive the following in logcat:当应用程序进入后台时会出现问题,然后我在 logcat 中收到以下内容:
2021-04-11 00:00:26.648 26160-26160/com.tandenkore.application V/application: location changes
2021-04-11 00:00:31.657 26160-26160/com.tandenkore.application V/application: location changes
2021-04-11 00:00:36.656 26160-26160/com.tandenkore.application V/application: location changes
2021-04-11 00:00:41.656 26160-26160/com.tandenkore.application V/application: location changes
2021-04-11 00:00:46.653 26160-26160/com.tandenkore.application V/application: location changes
2021-04-11 00:00:50.170 7241-7307/? E/RequestManager_FLP: [LocationManager] Paused by AppOps 7e14624(Listener) gps interval=5000 from com.tandenkore.application (10367)
2021-04-11 00:00:50.173 7241-7307/? I/RequestManager_FLP: onOpChanged, op=0 / packageName=com.tandenkore.application
2021-04-11 00:00:50.174 7241-7307/? I/PackageInfoManager_FLP: checkLocationAccess for com.tandenkore.application[gps,5000,100], result is false
but after this last message - no more updates until i bring the app back to the foreground.但是在这最后一条消息之后 - 在我将应用程序带回前台之前不再进行更新。 i want it to keep it running ALL the time - what else needs to be done for this?我希望它一直保持运行 - 为此还需要做什么?
According to the official documentation:根据官方文档:
When a feature in your app requests background location on a device that runs Android 10 (API level 29), the system permissions dialog includes an option named Allow all the time.当您的应用程序中的某个功能请求运行 Android 10(API 级别 29)的设备上的后台位置时,系统权限对话框包含一个名为“始终允许”的选项。 If the user selects this option, the feature in your app gains background location access.如果用户选择此选项,您应用中的功能将获得后台位置访问权限。
On Android 11 (API level 30) and higher, however, the system dialog doesn't include the Allow all the time option.但是,在 Android 11(API 级别 30)及更高版本上,系统对话框不包括始终允许选项。 Instead, users must enable background location on a settings page, as shown in figure 3.相反,用户必须在设置页面上启用后台定位,如图 3 所示。
So you need to see this option named Allow all the time in the Setting page of your application因此,您需要在应用程序的“设置”页面中始终看到名为“允许”的选项
for that you must have this permission in your manifest:为此,您必须在清单中拥有此权限:
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
On API 30 devices, and below so that the Allow All the time option will be visible in the Dialog you must Add the "Manifest.permission.ACCESS_BACKGROUND_LOCATION"
when you ask the user to grant them permission.在 API 30 设备及以下设备上,当您要求用户授予他们权限时,“允许所有时间”选项将在对话框中可见,您必须添加"Manifest.permission.ACCESS_BACKGROUND_LOCATION"
。 as below如下
ActivityCompat.requestPermissions(MainActivity.this,
new String[]{Manifest.permission.ACCESS_BACKGROUND_LOCATION ,Manifest.permission.ACCESS_COARSE_LOCATION,Manifest.permission.ACCESS_FINE_LOCATION},
1);
as you see the dialog has the Allow all the time如您所见,对话框始终显示“允许”
But on the Android Api 30 and higher you must invite the user to check this option manually against the API < 30但是在 Android Api 30 及更高版本上,您必须邀请用户手动对照 API < 30 检查此选项
So if you want to load the Setings page you can use this method:所以如果你想加载设置页面,你可以使用这个方法:
// load the permission setting screen
private void loadPermissionPage(Activity context) {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", context.getPackageName(), null);
intent.setData(uri);
context.startActivityForResult(intent, 0);
}
And finally if you check the Allow all the time option your application will be able to listen to the location changes in the background最后,如果您选中Allow all time选项,您的应用程序将能够在后台监听位置变化
For Android 30 and higher you can ask the user to garant the Background Location by opening the location permission pages directly using this line of code:对于 Android 30 及更高版本,您可以通过直接使用以下代码行打开位置权限页面来要求用户保证后台位置:
requestPermissions(new String[]{Manifest.permission.ACCESS_BACKGROUND_LOCATION}, REQUEST_CODE);
For more information see the Request background location有关更多信息,请参阅请求后台位置
Mention the android.foregroundServiceType="location"
in the service tag in the AndroidManifest.xml file.在AndroidManifest.xml文件的服务标签中提及android.foregroundServiceType="location"
。
Example:例子:
<service
android:name=".LocationServicePackage.LocationService"
android:foregroundServiceType="location"
android:enabled="true"
android:exported="true" />
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.