由于写论文需要,需要用手机加速度采集数据,关于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("\n");
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