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);
但是当我这么做的时候,实际上什么都没有发生!MyonSensorChanged()
listener继续从加速计(或软件线性加速度传感器,在我的情况下)接收正确的值。当然,这个问题在下面的文章中引用:
始终确保禁用不需要的传感器,尤其是在活动暂停时。否则可能会在几个小时内耗尽电池电量
只要屏幕真正解锁,我的应用程序只需敲击加速计。我已经实现了(并验证了)BroadcastReceiver
s的正确功能,它在手机锁定时破坏了服务
,并成功调用了它的onDestroy()
方法。但是,一旦我尝试注销侦听器,实际上什么都不会发生
我发现有几个人在问这个问题,但没有下定决心
传感器管理器
、传感器
和传感器事件监听器
设置为空,并尝试向管理器注册空传感器监听器。这些都不会对投票产生任何影响
我目前的“变通方法”对电池寿命几乎没有影响。我在类的定义中有一个私有布尔值,我根据是否需要传感器值将其设置为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];
传感器