Почему акселерометр не запустился вовремя или не извлек данные нормально?

#android #multithreading #sensors

#Android #многопоточность #датчики

Вопрос:

Я пишу приложение, которое по расписанию запускает акселерометр каждые 15 секунд и запускает его через 10 секунд для извлечения данных датчика. Я запускаю акселерометр с помощью AlarmManager и продолжаю его работу с помощью wakelock, когда экран гаснет. Но я обнаружил, что иногда:

  1. Акселерометр не может извлекать данные через некоторые периоды. Я имею в виду, что он был запущен в соответствии с logcat, но нет никаких данных датчика, затем он закрывается и запускается снова без данных.
  2. Я не знаю, почему акселерометр больше не запускался через несколько периодов, а раньше все было в порядке. Я обнаружил, что logcat сообщает «у прослушивателя с binder android.os.BinderProxy не существует акселерометра». Я не знаю почему.

ниже приведен код ядра:

Activity.java

 Intent intent = new Intent(getApplicationContext(),SensorService.class);
PendingIntent pendingIntent = PendingIntent.getService(getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
long curTime = Calendar.getInstance().getTimeInMillis();
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, curTime, _intervalTime, pendingIntent);  
  

SensorService.java

 public void onStart(Intent intent, int startId) {

        new Thread(new Runnable(){

            public void run() {
                // TODO Auto-generated method stub
                wl.acquire();
                Log.d(TAG,"I'm bright!");
                try {
                    Thread.sleep(_delayClose);// kill self after _delayClose ms
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
                stopSelf();// SensorService.this.stopSelf()
            }

        }).start();

        this.mSensorManager.registerListener( _sensorHandle, 
                accSensor, 
                sensorDelay)
}
public void onDestroy() {
    // TODO Auto-generated method stub
    super.onDestroy();
    this.mSensorManager.unregisterListener(_sensorHandle);
    Log.d(TAG,"TIEM UP");
    if(wl.isHeld())
    {
        wl.release();   
    }
}
  

Ответ №1:

Я предполагаю, что при такой частой регистрации и отмене регистрации sensor listener должны возникать значительные накладные расходы, плюс накладные расходы AlarmManager.

Учитывая, что вам так часто нужны данные с датчиков, как насчет того, чтобы просто зарегистрировать вашего слушателя и заставить его внутренне управлять, когда он должен и не должен делать что-то полезное с получаемыми образцами?

 public class SensorSamplrActivity extends Activity {
    private final static String TAG = "samplr";
    private final static int SAMPLE_INTERVAL_SECS = 15;
    private final static int SAMPLE_DURATION_SECS = 10;

    private SensorManager mSensorManager;
    private long whenToStartSample = System.currentTimeMillis();
    private long whenToEndSample = System.currentTimeMillis()   SAMPLE_DURATION_SECS;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
        mSensorManager.registerListener(mSensorListener, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),SensorManager.SENSOR_DELAY_GAME);
    }

    private SensorEventListener mSensorListener = new SensorEventListener() {

        @Override
        public void onAccuracyChanged(Sensor arg0, int arg1) {
            // TODO Auto-generated method stub
        }

        @Override
        public void onSensorChanged(SensorEvent event) {
            long now = System.currentTimeMillis();
            if (now < whenToStartSample){
                // ignore the event amp; wait for next time to sample
                Log.d(TAG,"ignoring events for "   (whenToStartSample - now)   "ms");
                return;
            }

            if (whenToStartSample <= now amp;amp; whenToEndSample > now){
                Log.d(TAG,"Do something with this event @ "   now);
            }
            else {
                // we've gone past whenToEndSample so reset timers
                whenToStartSample = now   (SAMPLE_INTERVAL_SECS * 1000);
                whenToEndSample = whenToStartSample   (SAMPLE_DURATION_SECS * 1000) ;
            }
        }
    };

    @Override
    public void onDestroy(){
        super.onDestroy();
        mSensorManager.unregisterListener(mSensorListener);
    }
}
  

Комментарии:

1. то есть вы имеете в виду, что AlarmManager может планировать не так, как я хочу? Скучно, что я не могу снова появиться, когда что-то идет не так. Поэтому я не могу гарантировать, сколько раз или после того, как что-то пошло не так. Но ваш совет должен быть полезен. Спасибо.

2. Кстати, вы знаете, что частота дискретизации датчика будет ниже даже на 0,5 Гц, когда телефон почти неподвижен? Я беспокоюсь о том, что это остановит себя с задержкой на несколько секунд.

3. Вопрос AlarmMgr: я не know…it просто кажется неудобным способом пероидальной выборки, и вы говорите, что это не работает, поэтому я предлагаю вам решить проблему по-другому. Что касается вопроса остановки: Если вы включите wakelock, он не остановится, и слушатель просто продолжит прослушивание и будет получать события по мере их возникновения.