简体   繁体   English

当应用程序移至后台时,在前台服务中获取位置更新不起作用

[英]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选项,您的应用程序将能够在后台监听位置变化

UPDATE:更新:

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.

相关问题 从后台删除应用程序时也无法获取位置更新 - Not getting location updates when App is removed from background also 当应用程序被破坏或进入后台时,Android 位置服务停止工作 - Android location service stop working when app destroyed or goes in background 为什么前台服务从后台删除应用程序后无法正常工作? - Why foreground Service not working after removing app from the background? 后台服务无法正常运行 - Background service isn't working properly 在服务中频繁获取位置更新 - Getting Location Updates frequently in Service 当应用程序从后台进入前台时,onBackPress() 不起作用 - onBackPress() is not working when app comes to foreground from background 灵活的应用内更新在前台而不是后台下载 - Flexible in-app updates download in the foreground rather than the background 运行前台服务时如何检测当前的前台应用程序 - How to detect current foreground app when foreground service is running 后台执行服务 - Background and foreground Service For Execution 当应用程序被杀死时,WorkManager 是否应该已经在工作,或者它是否需要附加一个前台服务? - Android工作室 - Should WorkManager already be working when the app is killed, or does it need to have a foreground service attached? - Android Studio
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM