我的服务适用于 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),并且应用更新从 2019 年 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文件