英文:
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论