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

转载 2015年11月19日 11:50:24
由于写论文需要,需要用手机加速度采集数据,关于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()方法中,结果可行了,把代码放上来。 


public class AccleratePersist extends Activity {
    private static final String TAG = "AccleratePersist";
    private static final int DELAY = SensorManager.SENSOR_DELAY_NORMAL;
    private static boolean STOP = true;// 开始暂停按钮


    private SensorManager mSensorManager;
    private WakeLock mWakeLock;
    private TextView accView;// 显示加速度值
    private StringBuilder builder = new StringBuilder();
    private long lastTimestamp = 0;


    private PersistService mySerivece;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        accView = (TextView) this.findViewById(R.id.accValue);
        final Button stopButton = (Button) this.findViewById(R.id.stopButton);// 停止测量按钮
        final Button clearButton = (Button) this.findViewById(R.id.clear); // 清除数据


        View.OnClickListener onClickListener = new View.OnClickListener() {


            @Override
            public void onClick(View view) {
                if (view == stopButton) {
                    STOP = !STOP;
                    setMeasure();
                } else if (view == clearButton) {
                    builder = new StringBuilder();
                    accView.setText("");
                }
            }


            @SuppressLint("Wakelock")
            private void setMeasure() {
                if (STOP) {// 停止键按下后,取消监听,是否电源
                    stopButton.setText("继续");
                    mSensorManager.unregisterListener(mySerivece);
                    mWakeLock.release();
                } else {
                    stopButton.setText("停止");
                    mWakeLock.acquire();// 屏幕熄后,CPU继续运行
                    mSensorManager
                            .registerListener(
                                    mySerivece,
                                    mSensorManager
                                            .getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
                                    DELAY);
                }
            }


        };
        clearButton.setOnClickListener(onClickListener);
        stopButton.setOnClickListener(onClickListener);
        mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        mySerivece = new PersistService();
        PowerManager manager = (PowerManager) getSystemService(Context.POWER_SERVICE);
        mWakeLock = manager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);// CPU保存运行
        IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);// 屏幕熄掉后依然运行
        filter.addAction(Intent.ACTION_SCREEN_OFF);
        registerReceiver(mySerivece.mReceiver, filter);
    }


    class PersistService extends Service implements SensorEventListener {


        private float[] accValue = new float[3];


        public BroadcastReceiver mReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {


                if (!STOP
                        && !intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
                    return;
                }
                if (mSensorManager != null) {//取消监听后重写监听,以保持后台运行
                    mSensorManager.unregisterListener(PersistService.this);
                    mSensorManager
                            .registerListener(
                                    PersistService.this,
                                    mSensorManager
                                            .getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
                                    SensorManager.SENSOR_DELAY_NORMAL);
                }


            }


        };


        public void onAccuracyChanged(Sensor sensor, int accuracy) {
            Log.i(TAG, "PersistService.onAccuracyChanged().");
        }


        public void onSensorChanged(SensorEvent sensorEvent) {
            if (sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
                Log.i(TAG, "PersistService.TYPE_ACCELEROMETER.");
                accValue = sensorEvent.values;
                for (int i = 0; i < 3; i++) {
                    builder.append((int) accValue[i]);
                    builder.append(",");
                }
                builder.append((sensorEvent.timestamp - lastTimestamp) / 1000000);// 采样时间差
                builder.append("\n");
                accView.setText(builder.toString());
                lastTimestamp = sensorEvent.timestamp;
            }


        }        
        @Override
        public IBinder onBind(Intent intent) {
            // TODO Auto-generated method stub
            return null;
        }        


    }
}



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

android 保证屏幕黑屏之后线程可以继续运行

android 保证屏幕黑屏之后线程可以继续运行
  • jhope
  • jhope
  • 2016年12月19日 11:39
  • 2217

Android中如何让Service不被一键清理且在息屏后保活

MarsDaemon库的使用及其出现的问题的解决 最近碰到这么一个需求,就是从服务器获取一个时间,每天在这个时间提醒用户,所以首先需要创建一个服务,让它能够长期运行在后台,且不被手机管理软件杀死,但...
  • cn_1937
  • cn_1937
  • 2016年12月29日 23:18
  • 2588

通过Google内置计步器和加速度传感器制作android计步程序(附源码)

最近需要做一个计步程序,在网站上研究了一些别人写的程序代码,比较普遍实用的是根据API大小,使用Google内置计步器或加速度传感器进行计步。但是网上源代码的注释很少,经过了一番波折,自己终于有了头绪...
  • WTunique
  • WTunique
  • 2017年01月17日 11:26
  • 9167

Android加速度传感器应用之晃动次数测试(摇一摇)

Android加速度传感器
  • u013046885
  • u013046885
  • 2016年06月08日 19:29
  • 993

Android实战简易教程<三十一>(基于加速度传感器的摇一摇功能实例)

下面我们来看一下微信摇一摇功能的模拟实现,我们是基于手机加速度传感器实现该功能,实现方法比较简单。  MainActivity.java: MainActivity.java: package com...
  • scholar_man
  • scholar_man
  • 2015年09月28日 09:21
  • 950

Android加速度传感器原理

这里我们将通过一个”摇一摇”应用来说明如何使用加速度传感器.但在开发之前,我们先对加速度传感器进行一些简单的介绍。 加速的是描述物体运动速度变化快慢的物理量,以m/s2为单位。在静止时,加速...
  • CCCrunner
  • CCCrunner
  • 2017年08月07日 14:11
  • 183

Android中使用加速度传感器

在Android中使用加速度传感器可以帮助我们识别手机的姿态及运动状态。 使用加速度传感器与其他传感器的方法大致相同,通过调用系统API就可以实现。分为以下几步: 1.获取SensorManage...
  • ucxiii
  • ucxiii
  • 2016年09月22日 01:25
  • 2942

android光照、加速度传感器

android的光照、加速度传感器android的传感器,用法大致一致,所以知道一两个的用法,基本都能很轻松的使用其他传感器。监听接口那需要传三个参数,第一个是listener的实例,第二个是Sens...
  • chenxuanhe1995
  • chenxuanhe1995
  • 2017年02月05日 10:54
  • 139

Android开发,项目中实现的摇一摇功能。使用加速度传感器SensorEventListener

package com.lvbin.yaoyiyao;import java.text.SimpleDateFormat;import java.util.Date;import android.ha...
  • lb8811682
  • lb8811682
  • 2015年02月02日 16:38
  • 405

Android加速度传感器实现“摇一摇”,带手机振动

由于代码有点多,所以就分开写了,注释还算详细,方便学习 Activity package com.lmw.android.test; import android.app.Activity;...
  • OnlyOneCoder
  • OnlyOneCoder
  • 2013年01月07日 15:11
  • 9298
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Android--保持加速度传感器在屏幕关闭后运行(收集)
举报原因:
原因补充:

(最多只允许输入30个字)