My service works with android 7.1.1 but not with android 9

时间:2019-03-26 18:51:05

标签: android android-service android-location android-broadcastreceiver

My app uses a background service to listen to GPS position changes. It works on android 7.1.1 (even if my activity is closed or the screen is turn off). When I tried it on android 9 (with the AVD) it only works when the activity is in the foreground, otherwise not. It looks like the service is stopped when the app is closed. minSdkVersion is set to 23. Why app have different behavior on different API? Android does not guarantee the compatibility of apps on newer OS versions?

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>

How can I change code to avoid this problem?

2 个答案:

答案 0 :(得分:2)

我了解您阅读了以下内容: https://developer.android.com/about/versions/oreo/background

与后台服务(尤其是Android 9中的GPS)相关的变化很多。请注意这一点(因此,针对API23并不是解决方案):

  

默认情况下,这些更改仅影响以Android 8.0(API级别26)或更高版本为目标的应用。但是,即使该应用的目标API级别低于26,用户也可以在“设置”屏幕上为任何应用启用这些限制。您可能需要更新您的应用以符合新的限制。

您现在可以做什么以及我们如何使其在我们的应用程序中起作用。将您的服务迁移到与Android 9兼容。我建议使用:

startForegroundService()

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

显示有关您的应用程序正在运行的通知(即使用户退出应用程序,这也会使您的应用程序正常运行-Android操作系统会限制您的服务)

定位API23也是一个坏主意,因为这个原因:

  

从2019年8月1日开始,Google Play要求新应用程序的目标至少是Android 9.0(API级别28),并且应用程序更新的目标是从2019年11月1日开始的Android 9.0。在这些日期之前,新应用程序和应用程序更新必须以至少是Android 8.0(API级别26)。

TL; DR 1.将服务迁移到前台 2.创建简单的通知,告诉您的应用程序正在运行 3.使用startForeground()启动服务

答案 1 :(得分:0)

Android一直在稳步发展,以限制对后台应用程序的访问。定位服务受Android 8限制。

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