当调用表单在后台运行时,该服务会阻止其活动

时间:2018-06-10 18:24:47

标签: android service android-8.0-oreo

我开发了一个旅行应用程序(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限制了很多服务,我希望我可以帮助有类似问题的人

1 个答案:

答案 0 :(得分:0)

当我在开发者指南上阅读“背景处理指南”时,我记得这一点

  

Android 8.0(API级别26)进一步限制了后台行为等   在后台获取位置并释放缓存的唤醒锁。


src https://developer.android.com/guide/background/
这不是解决方案,但希望它会有所帮助...