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

Posted

技术标签:

【中文标题】我的服务适用于 android 7.1.1 但不适用于 android 9【英文标题】:My service works with android 7.1.1 but not with android 9 【发布时间】:2019-08-17 06:17:29 【问题描述】:

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

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>

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

【问题讨论】:

【参考方案1】:

我知道你读到这个: 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),并且应用更新从 2​​019 年 11 月 1 日起面向 Android 9.0。在这些日期之前,新应用和应用更新必须面向 Android 9.0至少 Android 8.0(API 级别 26)。

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

【讨论】:

在我的情况下,它适用于 Android 9,但它不适用于搭载 Android 9 的三星 S9。奇怪..【参考方案2】:

Android 一直在稳步限制后台应用的访问权限。从 Android 8 开始,位置服务受到限制。

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

【讨论】:

以上是关于我的服务适用于 android 7.1.1 但不适用于 android 9的主要内容,如果未能解决你的问题,请参考以下文章

正在尝试在 Android 设备上检索位置...适用于模拟器,但不适用于真实设备

PHP 图片上传适用于本地主机,但不适用于 GoDaddy 服务器

适用于 Android 2.2 但不适用于 Android 2.3

JSON仅适用于Debug模式,但不适用于android中的apk文件

FloatingActionButton 示例适用于 Android Studio,但不适用于 Eclipse

focus-within 适用于 Android 浏览器,但不适用于 iOS