手机计步



package com.apicloud.MobileSportService;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.Service;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.os.Build;
import android.os.IBinder;
import android.os.PowerManager.WakeLock;
import android.support.v4.app.NotificationCompat;
import android.util.Log;

import com.apicloud.MobileSportService.pojo.StepData;
import com.apicloud.MobileSportService.utils.DbUtils;

//service负责后台的需要长期运行的任务
// 计步器服务
// 运行在后台的服务程序,完成了界面部分的开发后
// 就可以开发后台的服务类StepService
// 注册或注销传感器监听器,在手机屏幕状态栏显示通知,与StepActivity进行通信,走过的步数记到哪里了???
@SuppressLint("SimpleDateFormat")
@TargetApi(Build.VERSION_CODES.CUPCAKE)
public class StepCounterService extends Service {

 public static Boolean FLAG = false;// 服务运行标志

 private SensorManager mSensorManager;// 传感器服务
 private StepDetector detector;// 传感器监听对象
 private Thread thread; // 定义线程对象
 private WakeLock mWakeLock;// 屏幕灯
 
 private NotificationManager nm;
    private NotificationCompat.Builder builder;

 private long startTimer = 0;// 开始时间

 @Override
 public IBinder onBind(Intent intent) {
  // TODO Auto-generated method stub
  return null;
 }
 
  /**
     * 更新通知
     */
    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
 private void updateNotification() {
        builder = new NotificationCompat.Builder(this);
        builder.setPriority(Notification.PRIORITY_MIN);
        Notification notification = builder.build();
        startForeground(0, notification);
        nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        nm.notify(R.string.app_name, notification);
    }

 @Override
 public void onCreate() {
  // TODO Auto-generated method stub
  super.onCreate();

  FLAG = true;// 标记为服务正在运行

  // 创建监听器类,实例化监听对象
  detector = new StepDetector(this);

  // 获取传感器的服务,初始化传感器
  mSensorManager = (SensorManager) this.getSystemService(SENSOR_SERVICE);
  // 注册传感器,注册监听器
  mSensorManager.registerListener(detector, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_FASTEST);
  updateNotification();
  DbUtils.createDb(getApplicationContext(), "mobile_sport");
  saveDB();
 }

 /**
  * 每次调用startService(Intent)的时候,
 * 都会调用该Service对象的onStartCommand(Intent,int,int)方法,
 * 然后在onStartCommand方法中做一些处理。
 */
  @SuppressLint("NewApi")
 @Override
  public int onStartCommand(Intent intent, int flags, int startId) {
  Log.e("TrafficService", "startCommand");
  /*
  * START_STICKY:如果service进程被kill掉,保留service的状态为开始状态,但不保留递送的intent对象。
 * 随后系统会尝试重新创建service,由于服务状态为开始状态,所以创建服务后一定会调用onStartCommand(Intent,int,int)方法。如果在此期间没有任何启动命令被传递到service,那么参数Intent将为null。
 * START_NOT_STICKY:“非粘性的”。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统不会自动重启该服务。
 * START_REDELIVER_INTENT:重传Intent。使用这个返回值时,如果在执行完onStartCommand后,服务被异常kill掉,系统会自动重启该服务,并将Intent的值传入。
 * START_STICKY_COMPATIBILITY:START_STICKY的兼容版本,但不保证服务被kill后一定能重启。
 * */
 flags = START_REDELIVER_INTENT;//如果服务被异常kill掉,系统会自动重启该服务
 return super.onStartCommand(intent, flags, startId);
  }
 @TargetApi(Build.VERSION_CODES.ECLAIR)
 @Override
 public void onDestroy() {
  super.onDestroy();
  FLAG = false;// 服务停止
  nm.cancelAll();
  //取消前台进程
        stopForeground(true);
  if (detector != null) {
   mSensorManager.unregisterListener(detector);
  }

  if (mWakeLock != null) {
   mWakeLock.release();
  }
 }

 private void saveDB() {
  if (thread == null) {
   thread = new Thread() {// 子线程用于监听当前步数的变化
    @Override
    public void run() {
     super.run();
     int tempStep = 0;
     while (true) {
      try {
       Thread.sleep(5000);
      } catch (InterruptedException e) {
       e.printStackTrace();
      }
      if (StepCounterService.FLAG) {
       tempStep = StepDetector.CURRENT_SETP;
       StepDetector.CURRENT_SETP = 0;
       SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
       if(tempStep>0){
        startTimer = System.currentTimeMillis()/1000;
        List<StepData> list = DbUtils.getQueryByWhere(StepData.class, "timstamp", new String[]{startTimer+""});
              if (list.size() == 0 || list.isEmpty()) {
                  StepData data = new StepData();
                  data.setStepCount(tempStep + "");
                  data.setTimes((df.format(new Date())));
                  data.setTimstamp(startTimer);
                  DbUtils.insert(data);
              } else if (list.size() == 1) {
                  StepData data = list.get(0);
                  data.setStepCount(tempStep + "");
                  DbUtils.update(data);
              } 
       }
            tempStep = 0;
      }
     }
    }
   };
   thread.start();
  }
 }
}


package com.apicloud.MobileSportService;

import android.annotation.TargetApi;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Build;
import android.util.Log;
//走步检测器,用于检测走步并计数
@TargetApi(Build.VERSION_CODES.CUPCAKE)
public class StepDetector implements SensorEventListener {

 public static int CURRENT_SETP = 0;

 public static float SENSITIVITY = 3;   //SENSITIVITY灵敏度

 private float mLastValues[] = new float[3 * 2];
 private float mScale[] = new float[2];
 private float mYOffset;
 private static long end = 0;
 private static long start = 0;

 /**
  * 最后加速度方向
  */
 private float mLastDirections[] = new float[3 * 2];
 private float mLastExtremes[][] = { new float[3 * 2], new float[3 * 2] };
 private float mLastDiff[] = new float[3 * 2];
 private int mLastMatch = -1;

 /**
  * 传入上下文的构造函数
  *
  * @param context
  */
 public StepDetector(Context context) {
  // TODO Auto-generated constructor stub
  super();
  int h = 480;
  mYOffset = h * 0.5f;
  mScale[0] = -(h * 0.5f * (1.0f / (SensorManager.STANDARD_GRAVITY * 2)));
  mScale[1] = -(h * 0.5f * (1.0f / (SensorManager.MAGNETIC_FIELD_EARTH_MAX)));
  
 }

 @SuppressWarnings("deprecation")
 @Override
 public void onSensorChanged(SensorEvent event) {
  Sensor sensor = event.sensor;
  synchronized (this) {
   if (sensor.getType() == Sensor.TYPE_ORIENTATION) {
   } else {
    int j = (sensor.getType() == Sensor.TYPE_ACCELEROMETER) ? 1 : 0;
    if (j == 1) {
     float vSum = 0;
     for (int i = 0; i < 3; i++) {
      final float v = mYOffset + event.values[i] * mScale[j];
      vSum += v;
     }
     int k = 0;
     float v = vSum / 3;

     float direction = (v > mLastValues[k] ? 1: (v < mLastValues[k] ? -1 : 0));
     if (direction == -mLastDirections[k]) {
      // Direction changed
      int extType = (direction > 0 ? 0 : 1); // minumum or
      // maximum?
      mLastExtremes[extType][k] = mLastValues[k];
      float diff = Math.abs(mLastExtremes[extType][k]- mLastExtremes[1 - extType][k]);
      //Log.i("StepDetector", "diff:=====================>> " + diff);
      if (diff > SENSITIVITY) {
       boolean isAlmostAsLargeAsPrevious = diff > (mLastDiff[k] * 2 / 3);
       boolean isPreviousLargeEnough = mLastDiff[k] > (diff / 3);
       boolean isNotContra = (mLastMatch != 1 - extType);

       if (isAlmostAsLargeAsPrevious && isPreviousLargeEnough && isNotContra) {
        end = System.currentTimeMillis();
        if (end - start > 800) {// 此时判断为走了一步
         Log.i("StepDetector", "CURRENT_SETP:" + CURRENT_SETP);
         CURRENT_SETP++;
         mLastMatch = extType;
         start = end;
        }
       } else {
        mLastMatch = -1;
       }
      }
      mLastDiff[k] = diff;
     }
     mLastDirections[k] = direction;
     mLastValues[k] = v;
    }
   }
  }
 }

 @Override
 public void onAccuracyChanged(Sensor sensor, int accuracy) {
  // TODO Auto-generated method stub
 }

  OnSensorChangeListener onSensorChangeListener;

     public interface OnSensorChangeListener {
         void onChange();
     }

  public OnSensorChangeListener getOnSensorChangeListener() {
   return onSensorChangeListener;
  }

  public void setOnSensorChangeListener(
    OnSensorChangeListener onSensorChangeListener) {
   this.onSensorChangeListener = onSensorChangeListener;
  }
 
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值