在后台获取步进传感器数据并存储在SharedPreference / SQLite中

问题描述

我尝试了多种方法获取后台的传感器数据并将其值存储到共享的首选项或sqlite中,但是它们都不起作用。我认为这是由于Android Oreo Background的限制。

我尝试过

  • 带有广播接收器的警报管理器
  • 带服务的警报管理器

,现在我正在使用WorkManager。也没有真正的工作。我究竟做错了什么?现在不可能在后台获取传感器数据吗?还有其他替代方法吗?

MainActivity.java

protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    localDatabaseHelper = new LocalDatabaseHelper(getApplicationContext());
    sharedPreferences = getSharedPreferences("TEST STORAGE",MODE_PRIVATE);

    sensorManager = (SensorManager) getApplicationContext().getSystemService(Context.SENSOR_SERVICE);
    stepSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);

    WorkManager.getInstance(getApplicationContext()).cancelAllWorkByTag("Update-Shared-Preference");
    WorkRequest updateSharedPreference = new OneTimeWorkRequest.Builder(UpdateStepWork.class)
            .addTag("Update-Shared-Preference")
            .build();

    WorkManager.getInstance(getApplicationContext()).enqueue(updateSharedPreference);
}

工作

public class UpdateStepWork extends Worker implements SensorEventListener {

private SharedPreferences sharedPreferences;
private SensorManager sensorManager;
private Sensor stepSensor;
private LocalDatabaseHelper localDatabase;

public UpdateStepWork(@NonNull Context context,@NonNull WorkerParameters workerParams) {
    super(context,workerParams);
}

@NonNull
@Override
public Result doWork() {

    Log.i("WORK","STARTED");
    sharedPreferences = getApplicationContext().getSharedPreferences("TEST STORAGE",Context.MODE_PRIVATE);
    sensorManager = (SensorManager) getApplicationContext().getSystemService(Context.SENSOR_SERVICE);
    stepSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
    localDatabase = new LocalDatabaseHelper(getApplicationContext());

    WorkManager.getInstance(getApplicationContext()).cancelAllWorkByTag("Update-Shared-Preference");
    WorkRequest updateSharedPreference = new OneTimeWorkRequest.Builder(UpdateStepWork.class)
            .setinitialDelay(5,TimeUnit.SECONDS)
            .addTag("Update-Shared-Preference")
            .build();

    WorkManager.getInstance(getApplicationContext()).enqueue(updateSharedPreference);

    sensorManager.unregisterListener(this,stepSensor);
    if(sensorManager.registerListener(this,stepSensor,SensorManager.SENSOR_DELAY_norMAL)){
        return Worker.Result.success();
    }else
        return Worker.Result.failure();
}



@Override
public void onSensorChanged(SensorEvent event) {
    int steps = (int) event.values[0];

    Log.i("Steps from sensor",steps + "");

    if(sharedPreferences.edit().putInt("steps",steps).commit()){
        Log.i("Shared Preference","SUCCESS STORED: " + steps);

        if(localDatabase.updateDailyData(steps)){
            Log.i("LOCAL DATABASE","SUCCESS AT " + getCurrentTimeStamp());
            Cursor data = localDatabase.getData();

            while (data.movetoNext()) {
                Log.i("DATA",data.getString(0) + "    " + data.getInt(1));
            }
        }

    }else{
        Log.i("Shared Preference","Failed STORED: " + steps);
    }
    sensorManager.unregisterListener(this,stepSensor);
    sensorManager = null;
}

解决方法

在后台收集传感器数据的典型方法是使用foreground service

SharedPreferences不是存储传感器数据的理想方法。我建议您将传感器数据存储在.csv文件或数据库中。