Сенсор Android зарегистрирует слушателя в отдельном потоке

Я написал сервис для регистрации значений акселерометра в фоновом режиме. Идея состоит в том, чтобы зарегистрироваться для слушателя датчика и записать значения в хранилище. Я включил StrictMode.enableDefaults() в MainActivity приложения (не в службе), чтобы проверить, работает ли служба в своем собственном потоке. Но это не так! Я не знаю, в чем проблема... У меня есть этот класс AsyncTask, который я надеялся решить проблему, но, по-видимому, этого не произошло (это внутри службы, и его метод выполнения вызывается из метода onCreate службы .

private class LogTask extends AsyncTask<Void, Void, Void> {

    @Override
    protected Void doInBackground(Void... voids) {

        mListener = new SensorEventListener() {
            @Override
            public void onSensorChanged(SensorEvent sensorEvent) {

                String formatted = String.valueOf(System.currentTimeMillis())
                        + "\t" + String.valueOf(sensorEvent.timestamp)
                        + "\t" + String.valueOf(sensorEvent.values[0])
                        + "\t" + String.valueOf(sensorEvent.values[1])
                        + "\t" + String.valueOf(sensorEvent.values[2])
                        + "\r\n";

                //if (mIsServiceStarted && mFileStream != null && mLogFile.exists()) {
                if (mFileStream != null && mLogFile.exists()) {

                    try {
                        mFileStream.write(formatted.getBytes());
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }

            @Override
            public void onAccuracyChanged(Sensor sensor, int accuracy) {

            }
        };

        mSensorManager.registerListener(
                mListener, mSensor, SensorManager.SENSOR_DELAY_FASTEST
        );

        return null;
    }
}

StrictMode в журнале cat специально указывает, что следующая строка отменяет политику:

mFileStream.write(formatted.getBytes());

StrictMode policy violation; ~duration=0 ms: android.os.StrictMode$StrictModeDiskWriteViolation: policy=31 violation=1
            at android.os.StrictMode$AndroidBlockGuardPolicy.onWriteToDisk(StrictMode.java:1092)

Может кто-нибудь сказать мне, что происходит не так? Вот полный код моего сервиса, если требуется: http://pastebin.com/NRm376BL


person Saeid Yazdani    schedule 22.04.2014    source источник


Ответы (2)


Я обнаружил, что проблема в том, что я должен создать HandlerThread и Handler и передать обработчик перегрузке метода registerListener. Если вы не предоставите этот аргумент, прослушиватель будет обрабатываться основным потоком, и в большинстве случаев это не то, что вы ищете.

Для примера реализации проверьте этот код: особенно для обработки прослушивателя датчика в другом потоке, а не в основном потоке.

http://pastebin.com/QuHd0LNU

person Saeid Yazdani    schedule 22.04.2014

В Котлине есть реализация для запуска сенсора в потоке. Значения датчика можно обрабатывать в onSensorChanged.

class LightManager(context: Context) : SensorEventListener {

    private val sensorManager: SensorManager?
    private val lightSensor: Sensor?
    private var handlerThread: HandlerThread? = null

    init {
        this.sensorManager = context.getSystemService(Context.SENSOR_SERVICE) as SensorManager?
        this.lightSensor = sensorManager?.getDefaultSensor(Sensor.TYPE_LIGHT)
        this.handlerThread = HandlerThread(LightManager::class.java.simpleName)
        this.handlerThread?.start()
        val handler = Handler(this.handlerThread?.looper)
        this.sensorManager?.registerListener(this, this.lightSensor, SensorManager.SENSOR_DELAY_NORMAL, handler)
    }

    fun onStop() {
        sensorManager?.unregisterListener(this)
        if (this.handlerThread?.isAlive == true)
            this.handlerThread?.quitSafely()
    }

    override fun onAccuracyChanged(p0: Sensor?, p1: Int) {
    }

    override fun onSensorChanged(p0: SensorEvent?) {
        //handle your value here with p0?.values?.get(0)?.toInt() for example
    }

}
person Kevin ABRIOUX    schedule 14.05.2018