• Android--保持加速度传感器在屏幕关闭后运行(收集)


      由于写论文需要,需要用手机加速度采集数据,关于android加速度传感器的介绍网上一抓一大把,但大多都是大同小异,跟官网文档差不多。自己写了个取加速度传感器的APK,发现数据有点不对劲,原理屏幕一关后,系统就自动把各种传感器给停掉了,网上找了很久,发现一些可用的资源。

    1、查看手机是否支持锁屏后继续运行传感器

      有些手机可以支持后台取传感器数据,有些手机不行,这与硬件厂商具体实现有关,像GPS这些传感器都是很耗电的,厂商也是出于电源管理的考虑,这里是一个不完全列表,总结哪些软件支持屏幕关闭后依然运行传感器。这里更有一款APK(Accelerometer Frequency)专门查看你的手机是否支持。

      如果你的手机不支持,那还是不要折腾了,换了设备试试。

    2、实现方法

      我主要参考了

      1)http://blog.kozaxinan.com/2012/08/using-accelerometer-when-screen-off_16.html

      2)http://stackoverflow.com/questions/9982433/android-accelerometer-not-working-when-screen-is-turned-off

      星期天我按他们的方法实现了一下,主要思想就是申请锁屏后CPU不休眠:

    PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);  PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Tag");
    wl.acquire();
    ..
    wl.release();

      我把service写成activity的一个内部类,而我把申请电源管理的命令放在了service的Oncreate()方法里,之前一直纳闷,明明我的手机检测支持的,锁屏后还是没有取数据,而且连接USB时,锁屏后继续取加速度传感器数据,而拔掉USB后就停了,到处找原因,后来才发现service的OnCreate()方法没执行,坑了我。

      丑又丑点,我把电源管理申请放在了Activity的onCreate()方法中,结果可行了,把代码放上来。 

    复制代码
      1 public class AccleratePersist extends Activity {
      2     private static final String TAG = "AccleratePersist";
      3     private static final int DELAY = SensorManager.SENSOR_DELAY_NORMAL;
      4     private static boolean STOP = true;// 开始暂停按钮
      5 
      6     private SensorManager mSensorManager;
      7     private WakeLock mWakeLock;
      8     private TextView accView;// 显示加速度值
      9     private StringBuilder builder = new StringBuilder();
     10     private long lastTimestamp = 0;
     11 
     12     private PersistService mySerivece;
     13 
     14     @Override
     15     protected void onCreate(Bundle savedInstanceState) {
     16         super.onCreate(savedInstanceState);
     17         setContentView(R.layout.activity_main);
     18         accView = (TextView) this.findViewById(R.id.accValue);
     19         final Button stopButton = (Button) this.findViewById(R.id.stopButton);// 停止测量按钮
     20         final Button clearButton = (Button) this.findViewById(R.id.clear); // 清除数据
     21 
     22         View.OnClickListener onClickListener = new View.OnClickListener() {
     23 
     24             @Override
     25             public void onClick(View view) {
     26                 if (view == stopButton) {
     27                     STOP = !STOP;
     28                     setMeasure();
     29                 } else if (view == clearButton) {
     30                     builder = new StringBuilder();
     31                     accView.setText("");
     32                 }
     33             }
     34 
     35             @SuppressLint("Wakelock")
     36             private void setMeasure() {
     37                 if (STOP) {// 停止键按下后,取消监听,是否电源
     38                     stopButton.setText("继续");
     39                     mSensorManager.unregisterListener(mySerivece);
     40                     mWakeLock.release();
     41                 } else {
     42                     stopButton.setText("停止");
     43                     mWakeLock.acquire();// 屏幕熄后,CPU继续运行
     44                     mSensorManager
     45                             .registerListener(
     46                                     mySerivece,
     47                                     mSensorManager
     48                                             .getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
     49                                     DELAY);
     50                 }
     51             }
     52 
     53         };
     54         clearButton.setOnClickListener(onClickListener);
     55         stopButton.setOnClickListener(onClickListener);
     56         mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
     57         mySerivece = new PersistService();
     58         PowerManager manager = (PowerManager) getSystemService(Context.POWER_SERVICE);
     59         mWakeLock = manager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);// CPU保存运行
     60         IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);// 屏幕熄掉后依然运行
     61         filter.addAction(Intent.ACTION_SCREEN_OFF);
     62         registerReceiver(mySerivece.mReceiver, filter);
     63     }
     64 
     65     class PersistService extends Service implements SensorEventListener {
     66 
     67         private float[] accValue = new float[3];
     68 
     69         public BroadcastReceiver mReceiver = new BroadcastReceiver() {
     70             @Override
     71             public void onReceive(Context context, Intent intent) {
     72 
     73                 if (!STOP
     74                         && !intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
     75                     return;
     76                 }
     77                 if (mSensorManager != null) {//取消监听后重写监听,以保持后台运行
     78                     mSensorManager.unregisterListener(PersistService.this);
     79                     mSensorManager
     80                             .registerListener(
     81                                     PersistService.this,
     82                                     mSensorManager
     83                                             .getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
     84                                     SensorManager.SENSOR_DELAY_NORMAL);
     85                 }
     86 
     87             }
     88 
     89         };
     90 
     91         public void onAccuracyChanged(Sensor sensor, int accuracy) {
     92             Log.i(TAG, "PersistService.onAccuracyChanged().");
     93         }
     94 
     95         public void onSensorChanged(SensorEvent sensorEvent) {
     96             if (sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
     97                 Log.i(TAG, "PersistService.TYPE_ACCELEROMETER.");
     98                 accValue = sensorEvent.values;
     99                 for (int i = 0; i < 3; i++) {
    100                     builder.append((int) accValue[i]);
    101                     builder.append(",");
    102                 }
    103                 builder.append((sensorEvent.timestamp - lastTimestamp) / 1000000);// 采样时间差
    104                 builder.append("
    ");
    105                 accView.setText(builder.toString());
    106                 lastTimestamp = sensorEvent.timestamp;
    107             }
    108 
    109         }        
    110         @Override
    111         public IBinder onBind(Intent intent) {
    112             // TODO Auto-generated method stub
    113             return null;
    114         }        
    115 
    116     }
    117 }
    复制代码

       记得加一个权限:  <uses-permission android:name="android.permission.WAKE_LOCK" />

      有问题欢迎交流。

     转载请注明出处:http://www.cnblogs.com/fengfenggirl

  • 相关阅读:
    查找算法
    顺序表和链表
    队列
    Redis系列教材 (二)- 运行
    Redis系列教材 (一)- windows教程
    Maven系列教材 (十三)- Eclipse 中创建父子-聚合项目
    Maven系列教材 (十一)- 使用Eclipse导入一个Maven风格的SSM项目
    Maven系列教材 (十)- 使用Eclipse创建一个Maven风格的SSM项目
    Maven系列教材 (九)- 在Eclipse中创建maven风格的java web项目
    Maven系列教材 (八)- 用命令行创建Maven风格的java web项目
  • 原文地址:https://www.cnblogs.com/taoweiji/p/3620329.html
Copyright © 2020-2023  润新知