Пакетирование датчика Android из перезапущенного сервиса переднего плана - PullRequest
0 голосов
/ 27 ноября 2018

Это дополнительный вопрос к Как использовать Android Sensor Batching без AlarmManager .

Как указано в связанном вопросе, касающемся частоты очистки аппаратного FIFO, в разделе «Дозирование датчиков» в документации 4.4 предлагается:

Использовать, чторасчет для установки будильника с помощью AlarmManager, который вызывает ваш Сервис (который реализует SensorEventListener) для очистки датчика.

Я настроил AlarmManager для периодического перезапуска Сервиса, нопроцесс регистрации прослушивателя в OnCreate() в Сервисе, по-видимому, сбрасывает FIFO, а последующий вызов flush() просто возвращает несколько событий, так как прослушиватель был недавно зарегистрирован.События, произошедшие с момента последнего вызова Сервиса, теряются.

Итак, где и как я могу зарегистрировать прослушиватель только один раз при первом вызове Сервиса, чтобы я мог сбросить события, которые произошли между вызовами Сервиса?

Вот что я получилдо сих пор:

public class ExampleService extends Service implements SensorEventListener2{

private SensorManager sensorManager;
private List<Sensor> sensors;
private Sensor sensor;

private long numevents;

@Override
public void onCreate() {
    super.onCreate();

    // Create notification required for foreground service
    Intent notificationIntent = new Intent(this, MainActivity.class);
    PendingIntent pendingIntent = PendingIntent.getActivity(this,
            0, notificationIntent, 0);

    Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
            .setContentTitle("Example Service")
            .setContentText("MyNotification")
            .setSmallIcon(R.drawable.ic_android)
            .setContentIntent(pendingIntent)
            .build();

    startForeground(1, notification);

    // Get the sensor manager and register this ExampleService instance as a listener
    sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);

    sensors = sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER);

    if (sensors.size() > 0)
        sensor = sensors.get(0);

    sensorManager.registerListener(this, sensor,
            20000 /* 50Hz  */,
            20000000 /* maxBatchReportLatencyUs 20 seconds */);


    // PROBLEM - the FIFO queue gets reset by the previous line, 
    // and only a handful of events, if any, get flushed
    numevents = 0;
    sensorManager.flush(this);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Log.v("onStartCommand","started");
    return START_NOT_STICKY;
}


@Override
public void onSensorChanged(SensorEvent event) {
    if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
        numevents += 1L;
    }
}


@Override
public void onFlushCompleted(Sensor sensor) {
    Log.v("onFlushCompleted","Num flushed events "+numevents);

    // set a new alarm to invoke this service again in 10 seconds
    Intent serviceIntent = new Intent(this, ExampleService.class);
    PendingIntent pendingServiceIntent = PendingIntent.getForegroundService(this, 0, serviceIntent, 0);
    AlarmManager alarm = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
    alarm.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+10000, pendingServiceIntent);

    // Stop this service
    this.stopSelf();
}

@Override
public void onDestroy() {
    Log.v("onDestroy","stopped");
    super.onDestroy();

    if (sensorManager != null) {
        sensorManager.unregisterListener(this);
    }
    sensorManager = null;
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}


@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}

}

...