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

问题描述 投票:0回答:2

我的应用程序使用后台服务来收听GPS位置变化。它适用于Android 7.1.1(即使我的活动已关闭或屏幕关闭)。当我在android 9(使用AVD)上尝试它时,它仅在活动位于前台时才起作用,否则不起作用。应用程序关闭时,服务似乎已停止。 minSdkVersion设置为23.为什么app在不同的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>

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

android android-service android-location android-broadcastreceiver
2个回答
2
投票

我明白你读到这个:https://developer.android.com/about/versions/oreo/background

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

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

您现在可以做些什么,以及我们如何在我们的应用程序中使用它。将您的服务迁移到与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()启动服务


0
投票

Android一直在稳步地限制在后台访问应用程序。 Android 8限制了位置服务。

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

© www.soinside.com 2019 - 2024. All rights reserved.