Android sensor registerListener in a separate thre

2019-08-23 07:00发布

I have wrote a service to log accelerometer values in background. The idea is to register for sensor listener and write the values to storage. I have enabled the StrictMode.enableDefaults() in the MainActivity of the app (not in the service) to check if the service runs on its own thread. But it does not! I don't know what is the problem...I have this AsyncTask class that I hoped to take care of the problem but it apparently did not (this is inside the service and its execute method is called from the onCreate method of the service.

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 in log cat specially points that the following line is voiding the policy:

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)

Can someone tell me what is going wrong? Here is the full code of my service if requried: http://pastebin.com/NRm376BL

2条回答
倾城 Initia
2楼-- · 2019-08-23 07:15

I found out that the problem is, I should create a HandlerThread and a Handler and pass the handler to an overload of registerListener method. If you dont provide this argument the listener will be handled by the main thread and most of the time this isn't what you are looking for.

For an example implementation check this code: particularly for handling sensor listener on another thread not by main thread

http://pastebin.com/QuHd0LNU

查看更多
姐就是有狂的资本
3楼-- · 2019-08-23 07:40

There is an implementation in Kotlin to start a sensor on a thread. For sensor's values can be handle in 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
    }

}
查看更多
登录 后发表回答