在后台服务中注册传感器管理器监听器

3
我有一个为 Cordova 应用编写的 Android 后台服务,我想通过 sensorManager 与加速度计进行交互。
我觉得我已经很接近了,但还差一点。
由于某些原因,sensorManager.registerListener 似乎无法触发 onSensorChanged 方法 - 我正在从 MyService(我的后台服务类)每5秒检查一次 X 值。
根据我所读的,这与需要对 registerListener 进行处理有关,但我不确定是什么或如何处理。
以下是我的代码(为了可读性而缩减):
    class AccelListener implements SensorEventListener
    {

        public AccelListener(Context ctx) {
            mCtx = ctx;
            sensorManager = (SensorManager) mCtx.getSystemService(Context.SENSOR_SERVICE);
        }

        public int start() {
             List<Sensor> list = this.sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER);

            if ((list != null) && (list.size() > 0)) {
              this.mSensor = list.get(0);
              this.sensorManager.registerListener(this, this.mSensor, SensorManager.SENSOR_DELAY_UI);
               } 

            return this.status;
        }

        public void onSensorChanged(SensorEvent event) {


            if (this.accuracy >= SensorManager.SENSOR_STATUS_ACCURACY_MEDIUM) {
                this.timestamp = System.currentTimeMillis();
                this.x = event.values[0];
                this.y = event.values[1];
                this.z = event.values[2];
            }
        }
    }

    public class MyService extends BackgroundService 
    {

        protected JSONObject doWork() {
            JSONObject result = new JSONObject();
            Context thisContext = getApplicationContext();
            AccelListener objAccel = new AccelListener(thisContext);
            int intAccelReturn = objAccel.start();
            setInterval(function()
            {
                result.put("OUTPUT", objAccel.x);
            },5000);

}

非常感谢您的帮助。

谢谢。

O.

4个回答

0

我不知道这是否是你的问题,但我认为

List<Sensor> list = this.sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER);
if ((list != null) && (list.size() > 0)) {
  this.mSensor = list.get(0);
  this.sensorManager.registerListener(this, this.mSensor, SensorManager.SENSOR_DELAY_UI);
}

可以转换为更简单的形式
this.mSensor = this.sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
sensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_UI);

你的问题可能是你从未调用函数start(或者至少在你发布的代码中没有这样做)。

你能打印一下intAccelReturn的值吗?它可能会提供一些线索。你确定你的手机实际上有一个加速度计吗?最好的做法是在onSensorChanged函数中添加一个@Override注释,这样如果父类中没有该名称的函数,则会报错。请参见this link 以了解如何创建后台服务。你也没有调用MyService.doWork(你在实际的代码中调用了吗?)。


该死,我以为你已经破解了它!!!但是我意识到我刚才错过了发布的代码中的start() - 我现在已经编辑好了 - 有什么想法? - ojsglobal

0

另一个区别是

List<Sensor> list= 
this.sensorManager.getSensorList(Sensor.TYPE_ACCELEROMETER);
if ((list != null) && (list.size() > 0)) {
  this.mSensor = list.get(0);
  this.sensorManager.registerListener(this, this.mSensor,     
  SensorManager.SENSOR_DELAY_UI);
}

并且

this.mSensor = this.sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
sensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_UI);

在第二个例子中,是否引用了DefaultSensor而不是列表中的任何传感器。您确定索引为0的传感器实例是您想要引用的吗?

敬礼


0
将您的类AccelListener本身作为服务。
public class AccelListener extends Service implements SensorEventListener{...}

在你的初始化方法(startCommand、constructor、intentReceived或者其他你使用的方法)中,进行如下初始化:
    if (mSensorManager==null){
        mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    }

    if (mSensorAccelerometer == null){ 
        mSensorAccelerometer = mSensorManager.getDefaultSensor(Sensor. TYPE_ACCELEROMETER);
        mSensorManager.registerListener(this, mSensorAccelerometer, SensorManager.SENSOR_DELAY_UI);
    }   

然后重写onSensorChanged方法

@Override
public void onSensorChanged(SensorEvent event) { 
    // do stuff
}

0

需要检查的一些事情。

  1. onSensorChanged 是否真的被调用了,但因为你对准确度进行了测试,所以它被丢弃了?我可以想象,由于 UI 刷新率只提供大约每秒 2-3 个样本,可能不被认为是那么准确,但足以知道是否应该旋转屏幕。
  2. 这个测试时设备是否在移动,还是只是放在你的桌子上?只有当某些东西发生变化(设备在移动)时才会报告值,因此空闲设备不应提供任何样本。
  3. 屏幕关闭并且你没有使用 PARTIAL_WAKE_LOCK。如果你希望加速计在屏幕关闭时继续向你发送样本,则需要部分唤醒锁定以防止 CPU 进入睡眠状态(如果你不释放唤醒锁定,这可能对电池寿命不利)。它需要在 AndroidManifest.xml 中添加 <uses-permission>android.permission.WAKE_LOCK</uses-permission>。然后在你的启动中,你将不得不做这样的事情:

`

// Assuming mLock is a class level PowerManager.WakeLock so it can be released later
PowerManager pm = (PowerManager)mCtx.getSystemService(Context.POWER_SERVICE);

mLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Accel");
mLock.acquire();

`


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接