我开发了一个旅行应用程序(api 25),应用程序使用手机的位置来计算速度(和其他参数)。 该位置由负责打印(并在db上保存)各种参数的服务承担。 我在android oreo上管理服务时遇到问题,当调用表单在后台运行时,服务会阻止其活动。 该应用程序在android-n上完美运行,但不幸的是在android-o上我有这个问题。
调用表单的一部分是:
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
LocationUpdatesService.LocalBinder binder = (LocationUpdatesService.LocalBinder) service;
mService = binder.getService();
mBound = true;
}
@Override
public void onServiceDisconnected(ComponentName name) {
mService = null;
mBound = false;
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
Intent serviceIntent = new Intent(this, LocationUpdatesService.class);
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.O){
startForegroundService(serviceIntent);
}
bindService(serviceIntent, mServiceConnection,
Context.BIND_AUTO_CREATE);
}
start_stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
final LocationManager manager = (LocationManager) getSystemService( Context.LOCATION_SERVICE );
if (start_stop.getText().toString() == "start") {
//chiedo aggiornamenti
requestLocationUpdatesON();
start_stop.setText("stop");
}
else {
requestLocationUpdatesOFF();
}
}
});
mapFrag = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
mapFrag.getMapAsync(this);
}
public void requestLocationUpdatesOFF(){
mService.removeLocationUpdates();
//mFusedLocationClient.removeLocationUpdates(mLocationCallback);
}
public void requestLocationUpdatesON(){
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (ContextCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
//Location Permission already granted
//mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
mService.requestLocationUpdates();
mGoogleMap.setMyLocationEnabled(true);
} else {
//Request Location Permission
checkLocationPermission();
}
}
else {
//mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
mService.requestLocationUpdates();
mGoogleMap.setMyLocationEnabled(true);
}
}
@Override
protected void onDestroy() {
NotificationManager notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(3129999);
unbindService(mServiceConnection);
super.onDestroy();
}
服务:
@Override
public void onCreate() {
//wake-lock per impedire la chiusura dell'app in sleepmode
mPM = (PowerManager)getSystemService(Context.POWER_SERVICE);
mWL = mPM.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP |PowerManager.ON_AFTER_RELEASE,
"MyWakelockTag");
mWL.acquire(10000);
Log.i("MyWakeLockTag", "onCreate");
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel channel1 = new NotificationChannel(
CHANNEL_1_ID,
"Channel 1",
NotificationManager.IMPORTANCE_MIN
);
channel1.setDescription("This is Channel 1");
channel1.setSound(null,null);
channel1.enableLights(false);
channel1.setLightColor(Color.BLUE);
channel1.enableVibration(false);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(channel1);
}
}
public void requestLocationUpdates() {
//sendNotification();
if(!primaVoltaCronometro){
resumeCronometro();
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
sendNotificationOreo();
}
else {
sendNotification();
}
Log.i("Servizio", "Requesting location updates");
//Utils.setRequestingLocationUpdates(this, true);
startService(new Intent(getApplicationContext(), LocationUpdatesService.class));
try {
mFusedLocationClient.requestLocationUpdates(mLocationRequest,
mLocationCallback, Looper.myLooper());
} catch (SecurityException unlikely) {
//Utils.setRequestingLocationUpdates(this, false);
Log.e("Servizio", "Lost location permission. Could not request updates. " + unlikely);
}
}
public void sendNotificationOreo() {
//mi serve per far aprire il MapsActivity al click della notifica
Intent notificationIntent = new Intent(this, MapsActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent intent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notificationManager = NotificationManagerCompat.from(this);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_1_ID)
.setSmallIcon(android.R.color.transparent)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setCategory(NotificationCompat.CATEGORY_MESSAGE)
.setContentIntent(intent)
.setOngoing(true)
.setContent(contentView)
.build();
if(primaVoltaCronometro) {
startForeground(1,notification);
long BasePerIcronometri = SystemClock.elapsedRealtime();
cronometroInvisibile.setBase(BasePerIcronometri);
contentView.setChronometer(R.id.chronometerNot, BasePerIcronometri, "\uD83C\uDFC3%s\uD83D\uDCA8", true);
cronometroInvisibile.start();
primaVoltaCronometro=false;
}
notificationManager.notify(1, notification);
}
@Override
public void onDestroy() {
mWL.release();
Log.i("MyWakeLockTag", "onCreate");
super.onDestroy();
}
我知道android oreo限制了很多服务,我希望我可以帮助有类似问题的人
答案 0 :(得分:0)
当我在开发者指南上阅读“背景处理指南”时,我记得这一点
Android 8.0(API级别26)进一步限制了后台行为等 在后台获取位置并释放缓存的唤醒锁。
src :https://developer.android.com/guide/background/
这不是解决方案,但希望它会有所帮助...