Question

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

Était-ce utile?

La solution

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

Autres conseils

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
    }

}
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top