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

huangapple go评论81阅读模式
英文:

Get Step Sensor Data in background and store in SharedPreference/SQLite

问题

我已经尝试了很多方法来在后台获取传感器数据并将值存储到共享首选项或SQLite中但它们都没有起作用我认为这是因为Android Oreo的后台限制

我尝试过

- 使用广播接收器的闹钟管理器Alarm Manager
- 使用服务的闹钟管理器Alarm Manager
- 现在我正在使用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);
    }

> Work

    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;
    }
英文:

I have tried many ways to get sensor data in background and store the value into shared preference or SQLite, but none of them work. I think it is because of the Android Oreo Background restriction stuff.

I have tried

  • Alarm Manager with Broadcast Receiver
  • Alarm Manager with Service

and now I'm using the WorkManager. Not really working either. What am I doing wrong? Is it impossible to get sensor data in background now? Is there any other alternative way?

> 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);
}

> Work

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;
}

答案1

得分: 0

典型的后台收集传感器数据的方法是使用前台服务

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

英文:

The typical approach to collect sensor data in the background is using a foreground service.

SharedPreferences are not an ideal way to store sensor data. I recommend that you store the sensor data in a .csv file or a database.

huangapple
  • 本文由 发表于 2020年9月3日 20:45:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/63723982.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定