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

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

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

问题

  1. 我已经尝试了很多方法来在后台获取传感器数据并将值存储到共享首选项或SQLite但它们都没有起作用我认为这是因为Android Oreo的后台限制
  2. 我尝试过
  3. - 使用广播接收器的闹钟管理器Alarm Manager
  4. - 使用服务的闹钟管理器Alarm Manager
  5. - 现在我正在使用WorkManager但它也没有真正起作用我做错了什么现在在后台获取传感器数据是不可能的吗还有其他替代的方法吗
  6. > MainActivity.java
  7. protected void onCreate(Bundle savedInstanceState) {
  8. super.onCreate(savedInstanceState);
  9. setContentView(R.layout.activity_main);
  10. localDatabaseHelper = new LocalDatabaseHelper(getApplicationContext());
  11. sharedPreferences = getSharedPreferences("TEST STORAGE", MODE_PRIVATE);
  12. sensorManager = (SensorManager) getApplicationContext().getSystemService(Context.SENSOR_SERVICE);
  13. stepSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
  14. WorkManager.getInstance(getApplicationContext()).cancelAllWorkByTag("Update-Shared-Preference");
  15. WorkRequest updateSharedPreference = new OneTimeWorkRequest.Builder(UpdateStepWork.class)
  16. .addTag("Update-Shared-Preference")
  17. .build();
  18. WorkManager.getInstance(getApplicationContext()).enqueue(updateSharedPreference);
  19. }
  20. > Work
  21. public class UpdateStepWork extends Worker implements SensorEventListener {
  22. private SharedPreferences sharedPreferences;
  23. private SensorManager sensorManager;
  24. private Sensor stepSensor;
  25. private LocalDatabaseHelper localDatabase;
  26. public UpdateStepWork(@NonNull Context context, @NonNull WorkerParameters workerParams) {
  27. super(context, workerParams);
  28. }
  29. @NonNull
  30. @Override
  31. public Result doWork() {
  32. Log.i("WORK", "STARTED");
  33. sharedPreferences = getApplicationContext().getSharedPreferences("TEST STORAGE", Context.MODE_PRIVATE);
  34. sensorManager = (SensorManager) getApplicationContext().getSystemService(Context.SENSOR_SERVICE);
  35. stepSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
  36. localDatabase = new LocalDatabaseHelper(getApplicationContext());
  37. WorkManager.getInstance(getApplicationContext()).cancelAllWorkByTag("Update-Shared-Preference");
  38. WorkRequest updateSharedPreference = new OneTimeWorkRequest.Builder(UpdateStepWork.class)
  39. .setInitialDelay(5, TimeUnit.SECONDS)
  40. .addTag("Update-Shared-Preference")
  41. .build();
  42. WorkManager.getInstance(getApplicationContext()).enqueue(updateSharedPreference);
  43. sensorManager.unregisterListener(this, stepSensor);
  44. if(sensorManager.registerListener(this, stepSensor, SensorManager.SENSOR_DELAY_NORMAL)){
  45. return Worker.Result.success();
  46. }else
  47. return Worker.Result.failure();
  48. }
  49. @Override
  50. public void onSensorChanged(SensorEvent event) {
  51. int steps = (int) event.values[0];
  52. Log.i("Steps from sensor", steps + "");
  53. if(sharedPreferences.edit().putInt("steps", steps).commit()){
  54. Log.i("Shared Preference", "SUCCESS STORED: " + steps);
  55. if(localDatabase.updateDailyData(steps)){
  56. Log.i("LOCAL DATABASE", "SUCCESS AT " + getCurrentTimeStamp());
  57. Cursor data = localDatabase.getData();
  58. while (data.moveToNext()) {
  59. Log.i("DATA", data.getString(0) + " " + data.getInt(1));
  60. }
  61. }
  62. }else{
  63. Log.i("Shared Preference", "FAILED STORED: " + steps);
  64. }
  65. sensorManager.unregisterListener(this, stepSensor);
  66. sensorManager = null;
  67. }
英文:

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

  1. protected void onCreate(Bundle savedInstanceState) {
  2. super.onCreate(savedInstanceState);
  3. setContentView(R.layout.activity_main);
  4. localDatabaseHelper = new LocalDatabaseHelper(getApplicationContext());
  5. sharedPreferences = getSharedPreferences("TEST STORAGE", MODE_PRIVATE);
  6. sensorManager = (SensorManager) getApplicationContext().getSystemService(Context.SENSOR_SERVICE);
  7. stepSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
  8. WorkManager.getInstance(getApplicationContext()).cancelAllWorkByTag("Update-Shared-Preference");
  9. WorkRequest updateSharedPreference = new OneTimeWorkRequest.Builder(UpdateStepWork.class)
  10. .addTag("Update-Shared-Preference")
  11. .build();
  12. WorkManager.getInstance(getApplicationContext()).enqueue(updateSharedPreference);
  13. }

> Work

  1. public class UpdateStepWork extends Worker implements SensorEventListener {
  2. private SharedPreferences sharedPreferences;
  3. private SensorManager sensorManager;
  4. private Sensor stepSensor;
  5. private LocalDatabaseHelper localDatabase;
  6. public UpdateStepWork(@NonNull Context context, @NonNull WorkerParameters workerParams) {
  7. super(context, workerParams);
  8. }
  9. @NonNull
  10. @Override
  11. public Result doWork() {
  12. Log.i("WORK", "STARTED");
  13. sharedPreferences = getApplicationContext().getSharedPreferences("TEST STORAGE", Context.MODE_PRIVATE);
  14. sensorManager = (SensorManager) getApplicationContext().getSystemService(Context.SENSOR_SERVICE);
  15. stepSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
  16. localDatabase = new LocalDatabaseHelper(getApplicationContext());
  17. WorkManager.getInstance(getApplicationContext()).cancelAllWorkByTag("Update-Shared-Preference");
  18. WorkRequest updateSharedPreference = new OneTimeWorkRequest.Builder(UpdateStepWork.class)
  19. .setInitialDelay(5, TimeUnit.SECONDS)
  20. .addTag("Update-Shared-Preference")
  21. .build();
  22. WorkManager.getInstance(getApplicationContext()).enqueue(updateSharedPreference);
  23. sensorManager.unregisterListener(this, stepSensor);
  24. if(sensorManager.registerListener(this, stepSensor, SensorManager.SENSOR_DELAY_NORMAL)){
  25. return Worker.Result.success();
  26. }else
  27. return Worker.Result.failure();
  28. }
  29. @Override
  30. public void onSensorChanged(SensorEvent event) {
  31. int steps = (int) event.values[0];
  32. Log.i("Steps from sensor", steps + "");
  33. if(sharedPreferences.edit().putInt("steps", steps).commit()){
  34. Log.i("Shared Preference", "SUCCESS STORED: " + steps);
  35. if(localDatabase.updateDailyData(steps)){
  36. Log.i("LOCAL DATABASE", "SUCCESS AT " + getCurrentTimeStamp());
  37. Cursor data = localDatabase.getData();
  38. while (data.moveToNext()) {
  39. Log.i("DATA", data.getString(0) + " " + data.getInt(1));
  40. }
  41. }
  42. }else{
  43. Log.i("Shared Preference", "FAILED STORED: " + steps);
  44. }
  45. sensorManager.unregisterListener(this, stepSensor);
  46. sensorManager = null;
  47. }

答案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:

确定