为了让我的服务发挥作用,我陷入了困境,我相信我刚刚进行了合并.我正在try 创建一个步进计数器服务,它使用一个处理器,该处理器上实现了一个步进计数器传感器.每6小时,我想用步数信息更新我的服务器,在接近一天结束时重置步数,并在我的处理程序上设置另一个alert ,以便每6小时执行相同的操作.处理程序还定期向活动发送数据,以读取其记录的步数.
然而,一切正常,但我无法在广播接收器中获得我的处理程序的实例.因此,永远不会设置另一个alert ,也永远不会重置步骤.有人能帮我吗?
具体来说,广播接收器(StepCounterHandler handler = StepCounterHandler.getInstance();
)中的第一行代码在我的测试中总是返回null.
这是我的代码:
Android Manifest.xml:
<receiver android:name=".Account.StepCounterService.StepCountUpdaterAlarm"
android:exported="true">
</receiver>
<service
android:enabled="true"
android:process=":stepCounterService"
android:name=".Account.StepCounterService.StepCounterService" />
StepCounterHandler.java:
public class StepCounterHandler extends Handler implements SensorEventListener {
private boolean onSensorChangedFirstCall = true;
private int previousSteps;
private int cumulativeSteps;
private List<String> debugInfo = new ArrayList<String>() {};
private static StepCounterHandler stepCounterHandler;
public static StepCounterHandler getInstance(Context callingContext, Looper looper) {
if(stepCounterHandler == null) stepCounterHandler = new StepCounterHandler(callingContext, looper);
Log.d("MyService", "setting handler instance:" + (stepCounterHandler == null));
return stepCounterHandler;
}
public static StepCounterHandler getInstance()
{
if(stepCounterHandler == null) return null;
return stepCounterHandler;
}
private StepCounterHandler(Context callingContext, Looper looper) {
super(looper);
SensorManager sensorManager = (SensorManager) callingContext.getSystemService(Context.SENSOR_SERVICE);
Sensor stepSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
setAlarm(callingContext);
if (stepSensor != null) {
sensorManager.registerListener(this, stepSensor, SensorManager.SENSOR_DELAY_UI);
} else {
Toast.makeText(callingContext, "No step sensor has been detected on this device.", Toast.LENGTH_SHORT).show();
}
}
public void setAlarm(Context context)
{
AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, katibh.project.walkersquest.Account.StepCounterService.StepCountUpdaterAlarm.class);
intent.setFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.DAY_OF_YEAR, -1);
calendar.set(Calendar.HOUR_OF_DAY, 23);
calendar.set(Calendar.MINUTE, 50);
calendar.set(Calendar.SECOND, 00);
SimpleDateFormat formatter= new SimpleDateFormat("yyyy-MM-dd 'at' HH:mm:ss z");
Date date = new Date(System.currentTimeMillis());
debugInfo.add("Attempted update at:" + formatter.format(date));
while(calendar.getTimeInMillis() < System.currentTimeMillis())
{
calendar.add(Calendar.MINUTE, 1);
}
debugInfo.add("Attempting next update at:" + calendar.getTime());
// CANNOT RUN ALARM EVERY MINUTE IN setAndAllowWhileIdle, ONE MINUTE ALARM IS FOR TESTING PURPOSES
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
// alarmManager.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
// } else {
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);
// }
}
@Override
public void handleMessage(@NonNull Message msg) {
super.handleMessage(msg);
}
@Override
public void onSensorChanged(SensorEvent event) {
int totalSteps = (int) event.values[0];
if(onSensorChangedFirstCall)
{
previousSteps = totalSteps;
onSensorChangedFirstCall = false;
}
cumulativeSteps = totalSteps - previousSteps;
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
public synchronized int getCumulativeSteps()
{
cumulativeSteps = (int)(5000.0 * new Random().nextDouble());
return cumulativeSteps;
}
public synchronized void resetStepsCounter() {
cumulativeSteps = 0;
previousSteps = 0;
onSensorChangedFirstCall = true;
}
}
Broadcast Receiver:
public class StepCountUpdaterAlarm extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//Handler is null here when i the code below is executed.
StepCounterHandler handler = StepCounterHandler.getInstance();
//Do something...
sendToServer(handler.getCumultiveSteps)
handler.setAlarm(context);
if(isTimeToReset())
handler.resetStepsCounter();
}
private boolean isTimeToReset()
{
Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, 23);
calendar.set(Calendar.MINUTE, 50);
calendar.set(Calendar.SECOND, 00);
return calendar.getTimeInMillis() < System.currentTimeMillis();
}
}
上面的例子设置并应该每分钟触发一次alert (出于测试目的),所以我使用set
方法.我知道setAndAllowWhileIdle
每15分钟只能发送一次,但主要问题是我无法在接收器中获取处理程序的实例.它总是返回null,我不知道为什么.