我的服务适用于 android 7.1.1 但不适用于 android 9

My service works with android 7.1.1 but not with android 9

我的应用程序使用后台服务来侦听 GPS 位置变化。它适用于 android 7.1.1(即使我的 activity 已关闭或屏幕已关闭)。当我在 android 9(使用 AVD)上尝试它时,它仅在 activity 位于前景时有效,否则无效。应用程序关闭时,服务似乎已停止。 minSdkVersion 设置为 23。为什么应用程序在不同 API 上有不同的行为? Android 不保证应用程序在较新的 OS 版本上的兼容性?

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        /**code to request permission*/

        startService(new Intent(this, EventControllerService.class));

    }
}

public final class EventControllerService extends Service {
    private final static int MIN_TIME_FOR_GPS_UPDATES = 1;
    private final static float MIN_METER_FOR_GPS_UPDATES = 10.0f;
    private static NotificationManager mNotificationManager;
    private final BroadcastReceiver receiverDNDChange = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            //work on receive
        }
    };
    private final EventControllerService self = this;
    private final LocationListener locationListener = new LocationListener() {
        @Override
        public void onLocationChanged(Location location) {            
            Toast.makeText(self, "DENTRO", Toast.LENGTH_LONG).show();
            try {
                //work to do on position change
            } catch (SecurityException ignored) {                
                stopSelf();
            }
        }

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
        }

        @Override
        public void onProviderEnabled(String provider) {
        }

        @Override
        public void onProviderDisabled(String provider) {
        }
    };

    @Override
    public void onCreate() {
        super.onCreate();        
        try {
            mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

            IntentFilter filter = new IntentFilter();
            filter.addAction(NotificationManager.ACTION_INTERRUPTION_FILTER_CHANGED);
            registerReceiver(receiverDNDChange, filter);

            LocationManager mLocationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
            mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME_FOR_GPS_UPDATES, MIN_METER_FOR_GPS_UPDATES, locationListener);
        } catch (SecurityException ignored) {           
            stopSelf();
        }
    }

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
}

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="marcomantovani.pcd.silentmap">

    <uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />


    <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"
        tools:ignore="AllowBackup,GoogleAppIndexingWarning">
        <service android:name=".EventControllerService"/>
        <receiver android:name="marcomantovani.pcd.silentmap.AutoStart">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

如何更改代码以避免此问题?

Android 一直在稳步推进以限制对后台应用程序的访问权限。定位服务从 Android 8.

开始受到限制

参考: https://developer.android.com/about/versions/oreo/android-8.0-changes#abll

我了解到您阅读了这篇文章: https://developer.android.com/about/versions/oreo/background

Android9 中有许多与后台服务相关的更改,尤其是 GPS。另请注意(因此针对 API23 不是解决方案):

By default, these changes only affect apps that target Android 8.0 (API level 26) or higher. However, users can enable these restrictions for any app from the Settings screen, even if the app targets an API level lower than 26. You may need to update your app to comply with the new limitations.

您现在可以做什么以及我们如何让它在我们的应用程序中发挥作用。迁移您的服务以兼容 Android 9. 我建议使用:

startForegroundService()

在前台为 运行 提供服务。这是一个很小的变化。只需更改一个标志并以这种方式启动您的服务。

显示您的应用程序正在运行的通知(这将使您的应用程序保持运行,即使用户离开应用程序,否则 - Android OS 将限制您的服务)

以 API23 为目标也是一个坏主意,因为:

Starting August 1, 2019, Google Play requires that new apps target at least Android 9.0 (API level 28), and that app updates target Android 9.0 from November 1, 2019. Until these dates, new apps and app updates must target at least Android 8.0 (API level 26).

长话短说;博士 1.将服务迁移到前台 2. 创建简单的通知,告诉用户应用正在运行 3.用startForeground()

启动服务