上一篇见:
Android计步器的实现(1)
2.时间戳工具
public abstract class Util4Pedometer {
/**
* @return milliseconds since 1.1.1970 for today 0:00:00
*/
public static long getToday() {
Calendar c = Calendar.getInstance();
c.setTimeInMillis(System.currentTimeMillis());
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);
return c.getTimeInMillis();
}
}
3.获取当天的步数
以往的步数建议服务器获取。
获取当天步数代码:
/**
* 使用该方法前必须对context进行初始化
*/
public class StepsCountTool {
public static Context context;
/**
* 获得当天的步数,若步数异常重置步数
* 这里返回String是因为方便往服务器提交数据时加密(如:RSA)
*/
public static String getTodaySteps() {
if (null == context) {
return "0";
}
int result = 0;
Database db = Database.getInstance(context);
long today = Util4Pedometer.getToday();
result = db.getSteps(today) + db.getSensorSteps(today);
if (0 > result) {
db.updateSteps(today, -db.getSteps(today));
db.updateSensorSteps(today, 0);
result = 0;
}
return result + "";
}
}
4.计步器服务的实现
计步器要一直在后台运行就使用到了Service,如果不能一直运行则某些情况会使计数偏小,关于如何保活,这是个问题,这里只尽可能的使服务唤醒
(请自行解决,最后会给出源码,仅供参考)。
计步服务代码:
@TargetApi(Build.VERSION_CODES.KITKAT)
public class SensorListener extends Service implements SensorEventListener {
public static boolean isShutdowning = false;
private Database db;
public static int steps = 0;
private final static int MICROSECONDS_IN_ONE_MINUTE = 60000000;
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
@Override
public void onSensorChanged(final SensorEvent event) {
if (isShutdowning) {
return;
}
StepsCountTool.getTodaySteps();
Sensor sensor = event.sensor;
if (sensor.getType() != Sensor.TYPE_STEP_COUNTER) {
return;
}
steps = (int) event.values[0];
db = Database.getInstance(this);
long today = Util4Pedometer.getToday();
long yesterDay = today - 24 * 60 * 60 * 1000;
int correctSensorSteps;
int off = db.getOffStatus(yesterDay);
if (off == 0) {
correctSensorSteps = steps - db.getSensorSteps(yesterDay);
if (correctSensorSteps < 0) {
db.updateOffStatus(yesterDay, 1);
db.updateSteps(today, db.getSensorSteps(today));
db.updateSensorSteps(today, steps);
} else {
if (db.getSensorSteps(today) <= 0) {
db.updateSteps(today, -correctSensorSteps);
}
db.updateSensorSteps(today, correctSensorSteps);
}
} else if (off == 1) {
correctSensorSteps = steps;
db.updateSensorSteps(today, correctSensorSteps);
} else {
}
}
@Override
public IBinder onBind(final Intent intent) {
return null;
}
@Override
public int onStartCommand(final Intent intent, int flags, int startId) {
if (isShutdowning) {
return START_STICKY;
}
db = Database.getInstance(this);
db.updateOffStatus(Util4Pedometer.getToday(), 0);
((AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE))
.set(AlarmManager.RTC, System.currentTimeMillis() + AlarmManager.INTERVAL_HOUR,
PendingIntent.getService(getApplicationContext(), 2,
new Intent(this, SensorListener.class),
PendingIntent.FLAG_UPDATE_CURRENT));
return START_STICKY;
}
@Override
public void onCreate() {
super.onCreate();
reRegisterSensor();
}
@Override
public void onTaskRemoved(final Intent rootIntent) {
super.onTaskRemoved(rootIntent);
((AlarmManager) getSystemService(Context.ALARM_SERVICE))
.set(AlarmManager.RTC, System.currentTimeMillis() + 500, PendingIntent
.getService(this, 3, new Intent(this, SensorListener.class), 0));
}
@Override
public void onDestroy() {
super.onDestroy();
if (null != db) {
db.close();
}
try {
SensorManager sm = (SensorManager) getSystemService(SENSOR_SERVICE);
sm.unregisterListener(this);
} catch (Exception e) {
e.printStackTrace();
}
reRegisterSensor();
}
@TargetApi(19)
private void reRegisterSensor() {
if (Build.VERSION.SDK_INT < 19) {
return;
}
SensorManager sm = (SensorManager) getSystemService(SENSOR_SERVICE);
if (null == sm) {
} else {
}
try {
sm.unregisterListener(this);
} catch (Exception e) {
e.printStackTrace();
}
if (null == sm.getDefaultSensor(Sensor.TYPE_STEP_COUNTER)) {
} else {
}
sm.registerListener(this, sm.getDefaultSensor(Sensor.TYPE_STEP_COUNTER),
SensorManager.SENSOR_DELAY_NORMAL, 5 * MICROSECONDS_IN_ONE_MINUTE);
}
}
5.手机正常关机的处理
/**
* 监听到关机广播后,如下处理
*/
public class ShutdownReceiver extends BroadcastReceiver {
@TargetApi(Build.VERSION_CODES.KITKAT)
@Override
public void onReceive(final Context context, final Intent intent) {
if (!"android.intent.action.ACTION_SHUTDOWN".equals(intent.getAction())) {
return;
}
context.getSharedPreferences("pedometer", Context.MODE_PRIVATE).edit()
.putBoolean("correctShutdown", true).commit();
SensorListener.isShutdowning = true;
Database db = Database.getInstance(context);
long today = Util4Pedometer.getToday();
long yesterDay = today - 24 * 60 * 60 * 1000;
int correctSensorSteps = 0;
int off = db.getOffStatus(yesterDay);
if (off == 0) {
correctSensorSteps = SensorListener.steps - db.getSensorSteps(yesterDay);
db.updateSteps(today, correctSensorSteps);
} else if (off == 1) {
correctSensorSteps = SensorListener.steps;
db.updateSteps(today, correctSensorSteps);
} else {
}
db.updateSensorSteps(today, 0);
db.updateOffStatus(yesterDay, 1);
db.updateOffStatus(today, 1);
db.updateAll();
db.close();
}
}
到这里大体思路都实现了,其他代码等我发布源码后查看。