我在这里遇到了一些问题,我不知道如何解决。
我使用的是一个简单的服务,它注册了一个StepDetector(不是我想要自己处理步骤的计数器)。它开始粘贴。
另外,我实现了BroadcastReceiver。它侦听BOOT_Completed和Service_Destroyed。据我所知,它在重启或强制退出应用程序时效果很好。它继续在Realm-Database中计算和存储数据。
进一步解释:我将Step-Data存储在两个表中。
将它们存储在perHour-Basis上,这意味着所采取的每一步都会写入corepodonding Hour-Row。 例: 第5小时 - 采取60步 第7小时 - 30步采取
将它们存储在perDay-Basis上。这里存储了当天所有步骤。
我的onStartCommand看起来像这样:
manager = (SensorManager)getSystemService(SENSOR_SERVICE);
stepDetectorSensor = manager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR);
manager.registerListener(this, stepDetectorSensor, SensorManager.SENSOR_DELAY_FASTEST);
return Service.START_STICKY;
这是我的onSensorChanged
if(stamp == 0){
stamp = event.timestamp;
}
if(stamp != event.timestamp) {
RealmConfiguration config = new RealmConfiguration.Builder()
.deleteRealmIfMigrationNeeded()
.build();
Realm realm = Realm.getInstance(config);
realm.executeTransaction(new Realm.Transaction() {
@Override
public void execute(Realm realm) {
Date date = new Date();
DailyValues dailyValues = realm.where(DailyValues.class).equalTo("type", DailyValues.STEPS).findAll()
.where().equalTo("Day", date.getDay()).findAll()
.where().equalTo("Month", date.getMonth()).findAll()
.where().equalTo("Year", date.getYear()).findFirst();
ValuesPerHour valuesPerHour = realm.where(ValuesPerHour.class).equalTo("type", ValuesPerHour.STEPS).findAll()
.where().equalTo("hour", date.getHours()).findAll()
.where().equalTo("day", date.getDay()).findFirst();
if (dailyValues != null) {
dailyValues.Value += 1;
} else {
RealmResults<ValuesPerHour> row = realm
.where(ValuesPerHour.class).equalTo("type", ValuesPerHour.STEPS).findAll()
.where().notEqualTo("day",date.getDay()).findAll();
row.deleteAllFromRealm();
dailyValues = realm.createObject(DailyValues.class);
dailyValues.Day = date.getDay();
dailyValues.Month = date.getMonth();
dailyValues.Year = date.getYear();
dailyValues.Value = 1;
dailyValues.type = dailyValues.STEPS;
}
if (valuesPerHour != null)
valuesPerHour.value += 1;
else {
valuesPerHour = realm.createObject(ValuesPerHour.class);
valuesPerHour.value = 1;
valuesPerHour.hour = date.getHours();
valuesPerHour.day = date.getDay();
valuesPerHour.type = valuesPerHour.STEPS;
}
}
});
stamp = event.timestamp;
}
这不是最终版本,因此可能存在一些设计缺陷,但正如您所看到的,我看看是否已有数据用于&#34;今天&#34;由日月和年确定。如果有,请添加一个步骤。如果没有,请添加一行,向其添加一个步骤并清除perHour-Table。 然后我用perHour-Table做几乎相同的事情来更新它。
我的onDestroy()
super.onDestroy();
Intent broadcastIntent = new Intent(".RestartSensor");
sendBroadcast(broadcastIntent);
只需发送重启内容即可。 最后但并非最不重要的是,Receivers onReceive-Methode:
context.startService(new Intent(context, StepCounterService.class));
Log.i("Restart", "Restarted");
Manifest也很好,因为我在Force-Close和Restart of Phone上得到了步数。 让我疯狂的唯一一件事是,当新的一天到来时,我开始移动手机而不首先启动应用程序,没有注册任何步骤。 只有在启动应用程序后,一切正常。
编辑:正确的ATM我使用startForeground来避免这个问题。但应用程序喜欢 sHealth在没有任何粘性通知的情况下完成此操作。所以基本上我想知道如何重新启动服务,无论发生什么。
正如评论中所提到的,onDestroy不会一直被调用,因此无法保证重启。 另一个问题可能是Android将应用程序置于打瞌睡(?)中,所以也许我需要一个Wakelock?
我不认为这是关于读/写方法,因为它适用于任何其他情况。
答案 0 :(得分:0)
嗯,我想我现在已经开始工作了。 我希望有人会评论是否存在错误或不良做法。 如果你看到任何东西,请帮我修理它。 此外,我需要知道这种方法是否会耗尽电池电量。
我的方法有两种机制在接收器中工作。
这是我的onReceive() - Methode:
AlarmManager alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Intent intentReciever = new Intent(context, SensorRestartBroadcastReceiver.class);
PendingIntent alarmIntent = PendingIntent.getBroadcast(context, 0, intentReciever, 0);
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 5*1000,
5*1000, alarmIntent);
if(isServiceRunning(context,StepCounterService.class) == false){
sMonitorServiceIntent = new Intent(context, StepCounterService.class);
startWakefulService(context,sMonitorServiceIntent);
Log.i("BroadcastReceiver", "Restarted");
}
else{
Log.i("BroadcastReceiver", "Is running");
}
如您所见,isServiceRunning被调用,如下所示:
ActivityManager am = (ActivityManager) context
.getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo serviceInfo : am
.getRunningServices(Integer.MAX_VALUE)) {
String className1 = serviceInfo.service.getClassName();
String className2 = serviceClass.getName();
if (className1.equals(className2)) {
return true;
}
}
return false;
它只是检查此服务的实例是否已在运行。 如果没有,请重新启动服务,否则无需执行任何操作。
问题是: ATM我通过MainActivity启动服务并保存实例。 这样我就可以调用Service.Stop来启动服务中的onDestroy。
当我通过广播启动服务时,活动会调用该服务 我不能调用Service.Stop,这导致服务不能重新创建自己。 我尝试过这个。使用活动 - &gt;广播 - &gt;如果服务或应用程序被杀,服务将导致无计数。
我目前的做法是检查MainActivity是否正在运行Service。如果没有,请运行它。 Service在onStartCommand()中调用对Receiver的初始调用,以确保Receiver开始运行。