zoukankan      html  css  js  c++  java
  • Android学习小记-----监听并保存传感器数据,让service后台运行(保持CPU运转

    最近做了一个Demo,监听手机中传感器的数据,并将数据保存到手机文件中,发现数据会有丢失的现象。

    经过多次测试,发现系统进入深度休眠了,之后service会停止,虽然增加了service自动启动的功能,但是还会导致数据中断一段时间。如果屏幕一直亮着会比较耗电,所以亮屏这种方法直接Pass掉。那么怎么保证service一直运行不会中断呢?

    1,PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);通过Context.getSystemService().方法获取PowerManager实例。

    2,然后通过PowerManager的newWakeLock((int flags, String tag)来生成WakeLock实例。int Flags指示要获取哪种WakeLock,不同的Lock对cpu 、屏幕、键盘灯有不同影响。

    3,获取WakeLock实例后通过acquire()获取相应的锁,然后进行其他业务逻辑的操作,最后使用release()释放(释放是必须的)。

    关于int flags

    各种锁的类型对CPU 、屏幕、键盘的影响:

    PARTIAL_WAKE_LOCK:保持CPU 运转,屏幕和键盘灯有可能是关闭的。

    SCREEN_DIM_WAKE_LOCK:保持CPU 运转,允许保持屏幕显示但有可能是灰的,允许关闭键盘灯

    SCREEN_BRIGHT_WAKE_LOCK:保持CPU 运转,允许保持屏幕高亮显示,允许关闭键盘灯

    FULL_WAKE_LOCK:保持CPU 运转,保持屏幕高亮显示,键盘灯也保持亮度

    权限获取

    要进行电源的操作需要在AndroidManifest.xml中声明该应用有设置电源管理的权限。

    1 <uses-permission android:name="android.permission.WAKE_LOCK" />

    另外WakeLock的设置是 Activiy 级别的,不是针对整个Application应用的。

    在Android中,申请WakeLock可以让进程持续执行即使手机进入睡眠模式,在Service的onCreate()方法中加入以下代码,申请WakeLock:

     1 WakeLock m_wklk;
     2       
     3     @Override
     4     public void onCreate() {
     5         super.onCreate();
     6         PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
     7         m_wklk = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, DeviceSensorService.class.getName());
     8         m_wklk.acquire();
     9         //………………
    10     }

    申请了WakeLock要记得释放,否则手机可能无法进入休眠状态。在onDestroy()方法中加入:

    1     public void onDestroy() {
    2         
    3         if (m_wklk != null) {
    4             m_wklk.release();
    5             m_wklk = null;
    6         }
    7     };

    完整的监听sensor数据代码如下:

      1 /**
      2  * 加速度传感,陀螺仪,压力传感器,数据收集
      3  * 
      4  */
      5 
      6 import java.text.SimpleDateFormat;
      7 
      8 import android.app.Service;
      9 import android.content.Context;
     10 import android.content.Intent;
     11 import android.hardware.Sensor;
     12 import android.hardware.SensorEvent;
     13 import android.hardware.SensorEventListener;
     14 import android.hardware.SensorManager;
     15 import android.os.IBinder;
     16 import android.os.PowerManager;
     17 import android.os.PowerManager.WakeLock;
     18 import android.util.Log;
     19 
     20 public class DeviceSensorService extends Service {
     21     private static final String TAG = "DeviceSensorService";
     22     Sensor sensorAcc, sensoGyros, sensoPress;
     23     SensorManager sm;
     24     WakeLock m_wklk;
     25      
     26     @Override  
     27     public void onCreate() {  
     28         super.onCreate(); 
     29         if (sm == null) {
     30             sm = (SensorManager) getApplicationContext().getSystemService(
     31                     Context.SENSOR_SERVICE);
     32         }
     33         /*List<Sensor> sensors = sm.getSensorList(Sensor.TYPE_GYROSCOPE);
     34         if (sensors.size() > 0){
     35             Sensor sensor = sensors.get(0);
     36             sm.registerListener(this,
     37                     sensor, SensorManager.SENSOR_DELAY_NORMAL);
     38         }*/
     39         
     40         // 加速度感应器
     41         Sensor sensorAcc = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
     42         // 陀螺仪
     43         Sensor sensoGyros = sm.getDefaultSensor(Sensor.TYPE_GYROSCOPE);
     44         // 压力
     45         Sensor sensoPress = sm.getDefaultSensor(Sensor.TYPE_PRESSURE);
     46         
     47         /*
     48          * 最常用的一个方法 注册事件 
     49          * 参数1 :SensorEventListener监听器 
     50          * 参数2 :Sensor 一个服务可能有多个Sensor实现,此处调用getDefaultSensor获取默认的Sensor
     51          * 参数3 :模式 可选数据变化的刷新频率,采样率
     52          * SENSOR_DELAY_FASTEST,100次左右
     53          * SENSOR_DELAY_GAME,50次左右
     54          * SENSOR_DELAY_UI,20次左右
     55          * SENSOR_DELAY_NORMAL,5次左右
     56          */
     57         sm.registerListener(mySensorListener, sensorAcc,
     58                 SensorManager.SENSOR_DELAY_NORMAL); //以普通采样率注册监听器
     59         sm.registerListener(mySensorListener, sensoGyros,
     60                 SensorManager.SENSOR_DELAY_NORMAL);
     61         sm.registerListener(mySensorListener, sensoPress,
     62                 SensorManager.SENSOR_DELAY_NORMAL);
     63         
     64         PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); 
     65         m_wklk = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, DeviceSensorService.class.getName()); 
     66         m_wklk.acquire();
     67         
     68     }
     69     
     70     @Override
     71     public IBinder onBind(Intent intent) {
     72         return null;
     73     }
     74 
     75     @Override
     76     public int onStartCommand(Intent intent, int flags, int startId) {
     77         Log.i(TAG, "zhangjieqiong onStartCommand");
     78 //        return super.onStartCommand(intent, flags, startId);
     79         return Service.START_STICKY; 
     80     }
     81     
     82     public void onDestroy() {
     83         if (sm != null) {
     84             sm.unregisterListener(mySensorListener);
     85             mySensorListener = null;
     86         }
     87         if (m_wklk != null) {
     88             m_wklk.release();
     89             m_wklk = null;
     90         }
     91     };
     92 
     93     /*
     94      * SensorEventListener 接口的实现,需要实现两个方法 
     95      * 方法1 onSensorChanged 当数据变化的时候被触发调用 
     96      * 方法2 onAccuracyChanged 当获得数据的精度发生变化的时候被调用,比如突然无法获得数据时
     97      */
     98     private SensorEventListener mySensorListener = new SensorEventListener() {
     99         
    100         public void onSensorChanged(SensorEvent sensorEvent) {
    101             synchronized (this) {
    102                 int type = sensorEvent.sensor.getType();
    103                 
    104                 SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss:SSS ");
    105                 String date = sDateFormat.format(new java.util.Date());
    106                 
    107                 switch (type) {
    108                 case Sensor.TYPE_ACCELEROMETER://加速度
    109 //                    acc_count++;
    110                     float X_lateral = sensorEvent.values[0];
    111                     float Y_longitudinal = sensorEvent.values[1];
    112                     float Z_vertical = sensorEvent.values[2];
    113                     MyLog.i("Accelerometer.txt", "Accelerometer", date + ","
    114                             + X_lateral + "," + Y_longitudinal + "," + Z_vertical
    115                             + ";");
    116                     
    117                     Log.i("sensor", "Accelerometer:"+ date + ", "
    118                             + X_lateral + "," + Y_longitudinal + "," + Z_vertical
    119                             + ";");
    120                     
    121                     break;
    122                 case Sensor.TYPE_GYROSCOPE://陀螺仪
    123     //                gyro_count++;
    124                     float X_laterals = sensorEvent.values[0];
    125                     float Y_longitudinals = sensorEvent.values[1];
    126                     float Z_verticals = sensorEvent.values[2];
    127                     MyLog.i("Gyproscope.txt", "Gyproscope", date + ","
    128                             + X_laterals + "," + Y_longitudinals + ","
    129                             + Z_verticals + ";");
    130                     Log.i("sensor", "Gyproscope:"+ date + ", "
    131                             + X_laterals + "," + Y_longitudinals + ","
    132                             + Z_verticals + ";");
    133                     break;
    134                 case Sensor.TYPE_PRESSURE://压力
    135     //                pres_count++;
    136                     float X_lateralss = sensorEvent.values[0];
    137                     MyLog.i("Pressure.txt", "Pressure", date + "," + X_lateralss
    138                             + ";");
    139                     Log.i("sensor", "Pressure:"+ date + "," + X_lateralss
    140                             + ";");
    141                     break;
    142                 default:
    143                     break;
    144                 }
    145             }
    146         }
    147 
    148         public void onAccuracyChanged(Sensor sensor, int accuracy) {
    149             Log.i("sensor", "onAccuracyChanged-----sensor"+ sensor + ",acc:" + accuracy);
    150             
    151         }
    152     };
    153 }

    关于保存数据到文件可以参考上一篇博客:http://www.cnblogs.com/zjqlogs/p/5488798.html

    注:这样处理会比较耗电。

    参考:http://www.cnblogs.com/GnagWang/archive/2011/02/27/1966611.html

    参考:http://blog.sina.com.cn/s/blog_474928c90100xpg9.html

  • 相关阅读:
    【CF932F】Escape Through Leaf 启发式合并set维护凸包
    【CF932E】Team Work/【BZOJ5093】图的价值 数学+NTT
    【CF917D】Stranger Trees 树形DP+Prufer序列
    【CF914G】Sum the Fibonacci 快速??变换模板
    【CF772D】Varying Kibibits FWT
    【CF802C】Heidi and Library (hard) 费用流
    【CF802L】Send the Fool Further! (hard) 高斯消元
    【CF809D】Hitchhiking in the Baltic States Splay
    【CF815D】Karen and Cards 单调栈+扫描线
    【CF819D】Mister B and Astronomers EXGCD
  • 原文地址:https://www.cnblogs.com/zjqlogs/p/5528047.html
Copyright © 2011-2022 走看看