Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/204.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 安卓&x27;s SensorManager无法有效地注销侦听器_Android - Fatal编程技术网

Android 安卓&x27;s SensorManager无法有效地注销侦听器

Android 安卓&x27;s SensorManager无法有效地注销侦听器,android,Android,我的应用程序创建了一个服务,该服务覆盖onstart命令以创建传感器管理器,并将传感器事件监听器连接到其中一个传感器: public class AccelerometerService extends Service { private SensorManager sensorManager; private Sensor sensor; private SensorEventListener activeListener; // ... @Over

我的应用程序创建了一个
服务
,该服务覆盖onstart命令以创建
传感器管理器
,并将
传感器事件监听器
连接到其中一个传感器:

public class AccelerometerService extends Service {
    private SensorManager sensorManager;
    private Sensor sensor;
    private SensorEventListener activeListener; 
    // ...

    @Override
    public int onStartCommand(Intent intent, int flags, int startid) {
        // ...

        sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        sensor = sensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION);
        activeListener = new SensorEventListener() {
            @Override
            public void onAccuracyChanged(Sensor sensor, int accuracy) {

            }

            @Override
            public void onSensorChanged(SensorEvent event) {
                Log.i("PluckLock", "" + event.values[0]);
            }
        };

        sensorManager.registerListener(activeListener, sensor, SensorManager.SENSOR_DELAY_NORMAL);

        return START_STICKY;
    }

    // ...
}
完整代码可在上获得

我想覆盖
服务
onDestroy()
方法,并在其中杀死传感器:

sensorManager.unregisterListener(activeListener);
但是当我这么做的时候,实际上什么都没有发生!My
onSensorChanged()
listener继续从加速计(或软件线性加速度传感器,在我的情况下)接收正确的值。当然,这个问题在下面的文章中引用:

始终确保禁用不需要的传感器,尤其是在活动暂停时。否则可能会在几个小时内耗尽电池电量

只要屏幕真正解锁,我的应用程序只需敲击加速计。我已经实现了(并验证了)
BroadcastReceiver
s的正确功能,它在手机锁定时破坏了
服务
,并成功调用了它的
onDestroy()
方法。但是,一旦我尝试注销侦听器,实际上什么都不会发生

我发现有几个人在问这个问题,但没有下定决心

我只能假设这是一个API错误,一旦我开始从这些传感器获取数据,就真的没有好办法杀死它们。我已尝试将
传感器管理器
传感器
传感器事件监听器
设置为空,并尝试向管理器注册空传感器监听器。这些都不会对投票产生任何影响

我目前的“变通方法”对电池寿命几乎没有影响。我在类的定义中有一个私有布尔值,我根据是否需要传感器值将其设置为
true
false
。在我的
onSensorChanged()
方法中,如果传感器侦听器应该处于非活动状态,我会立即
返回
。但到那时,一切都为时已晚:在我能够离开
onSensorChanged()
方法之前,操作系统(获取传感器值)所做的工作首当其冲,所以只要我的服务还在运行,电池的寿命仍然是可怕的

我这里真正的问题,除非有奇迹般的真正解决方案,是我能做些什么来停止获取传感器值?显然,此时取消注册传感器侦听器不起作用;即使将所有内容设置为null并销毁服务也没有效果。但必须有某种方式向操作系统表明,我的应用程序不再需要使用传感器值。是否有什么方法可以杀死我的整个应用程序,只在手机解锁时重新启动它?也许这会让操作系统知道我的应用不再需要值。真的,任何合法地停止轮询传感器,但给我某种方式重新启动它的解决方案,即使代码很难看,都会让我感到高兴


我的项目的最低API级别是9。

我面临类似的问题

防止传感器耗尽电池电量的解决方法

我使用了一个静态布尔值
mIsSensorUpdateEnabled
。当您想停止从传感器获取值时,将其设置为“false”。 在onSensorChanged()方法中,检查布尔变量的值,然后再次调用以注销传感器。这一次,它起作用了。传感器将被取消注册,您将不再使用SensorChanged回调

    public class MainActivity extends Activity implements SensorEventListener{
        private static boolean mIsSensorUpdateEnabled = false;
        private SensorManager mSensorManager;
        private Sensor mAccelerometer;

        @override
        protected void onCreate(){
            mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        }

        private startSensors(){
            mAccelerometer =  mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
            int delay = 100000; //in microseconds equivalent to 0.1 sec
            mSensorManager.registerListener(this,
                        mAccelerometer,
                        delay
                );
            mIsSensorUpdateEnabled =true;
        }

        private stopSensors(){
             mSensorManager.unregisterListener(this, mAccelerometer);
             mIsSensorUpdateEnabled =false;
        }


        @Override
        public void onSensorChanged(SensorEvent event) {
            if (!mIsSensorUpdateEnabled) {
                stopSensors();
                Log.e("SensorMM", "SensorUpdate disabled. returning");
                return;
            }
            //Do other work with sensor data
        }
    }`

我也有同样的问题。最后,我可以通过将sensorManager对象设置为null来启用传感器读取。因此,sensorManager无法注册任何侦听器。当您想要读取传感器数据时,调用startRegister方法来定义sensorManager对象和侦听器。这是我的密码:

public class SensorReadingClass implements SensorEventListener {

    public SensorReadingClass(Service c){
        this.mContext=c;
        mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
        if (mSensorManager != null) {
            // list available sensors and power consumption
            List<Sensor> sensors = mSensorManager.getSensorList(Sensor.TYPE_ALL);
        } else {
            if(DBG) Log.e(TAG, "Could not get SensorManager instance");
        }
    }

    public float getHeartRate(){
        Log.d(TAG,"Heart Rate return value: " + heartRate);
        return heartRate;
    }

    public void startSensorListeners() {
        Log.d(TAG, "startSensorListeners");

        if(mSensorManager==null){
            mSensorManager = (SensorManager) mContext.getSystemService(Context.SENSOR_SERVICE);
        }

        readSensors=true;

        mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
        mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_HEART_RATE), SensorManager.SENSOR_DELAY_NORMAL);
        mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER), SensorManager.SENSOR_DELAY_NORMAL);
        mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE), SensorManager.SENSOR_DELAY_NORMAL);

        Log.d(TAG, "Sensor started: " + mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL));

    }

    public void stopSensorListeners() {
        Log.d(TAG, "stopSensorListeners");

        if(mSensorManager!=null) {
            mSensorManager.unregisterListener(this);
            mSensorManager=null;
        }

        Log.d(TAG, "Sensor stoppped: " + mSensorManager);
        readSensors=false;

    }

    @Override
    public void onSensorChanged(SensorEvent event) {

            String key = event.sensor.getName();
            float values = event.values[0];
            Sensor sensor = event.sensor;

            if (sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
                accellerometerEvent++;                  // this is event counts when sensor changes, this counts all the events changings. It shouldnt be necessary though
                accellerometerSensor = values + " " + event.values[1] + " " + event.values[2] + " " + accellerometerEvent; // This is the string for value and seen event count.

            }

            if (sensor.getType() == Sensor.TYPE_HEART_RATE) {
                heartRateEvent++;
                heartRateSensor = values + " " + heartRateEvent;
                heartRate = values;

            }

            if (sensor.getType() == Sensor.TYPE_STEP_COUNTER) {
                stepCounterEvent++;
                stepCounterSensor = values + " " + stepCounterEvent;

            }

            if (sensor.getType() == Sensor.TYPE_GYROSCOPE) {
                gyroscopeEvent++;
                try {
                    gyroscopeSensor = values + " " + event.values[1] + " " + event.values[2] + " " + gyroscopeEvent;
                } catch (Exception e) {
                }

            }

            lastTime = System.currentTimeMillis();
        }

    @Override
    // since we will always capture the data whether it changes or not, we don't need this method
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        return;
    }

}
公共类SensorReadingClass实现SensorEventListener{
公共感知阅读类(服务c){
this.mContext=c;
msSensorManager=(SensorManager)mContext.getSystemService(Context.SENSOR\u服务);
如果(mSensorManager!=null){
//列出可用的传感器和功耗
List sensors=msSensorManager.getSensorList(Sensor.TYPE_ALL);
}否则{
if(DBG)Log.e(标记“无法获取SensorManager实例”);
}
}
公共浮动getHeartRate(){
Log.d(标签,“心率返回值:”+心率);
返回心率;
}
public void startSensorListeners(){
Log.d(标记“startSensorListeners”);
如果(mSensorManager==null){
msSensorManager=(SensorManager)mContext.getSystemService(Context.SENSOR\u服务);
}
readSensors=true;
mSensorManager.registerListener(这是mSensorManager.getDefaultSensor(传感器类型\加速计),SensorManager.Sensor\延迟\正常);
mSensorManager.registerListener(这是mSensorManager.getDefaultSensor(Sensor.TYPE\u HEART\u RATE),SensorManager.Sensor\u DELAY\u NORMAL);
mSensorManager.registerListener(此,mSensorManager.getDefaultSensor(传感器.类型\步进\计数器),SensorManager.传感器\延迟\正常);
msSensorManager.registerListener(这是,msSensorManager.getDefaultSensor(传感器.类型\陀螺仪),SensorManager.传感器\延迟\正常);
Log.d(标签,“传感器启动:”+mSensorManager.registerListener(此,mSensorManager.getDefaultSensor(传感器.类型\加速计),传感器管理器.传感器\延迟\正常));
}
public void stopSensorListeners(){
Log.d(标记“stopSensorListeners”);
如果(mSensorManager!=null){
mSensorManager.unregisterListener(此);
mSensorManager=null;
}
日志d(标签“传感器停止:”+mSensorManager);
readSensors=false;
}
@凌驾
传感器更改时的公共无效(传感器事件){
String key=event.sensor.getName();
浮动值=事件值[0];
传感器