有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

单独线程中的java Android传感器注册器Listener

我已经编写了一个服务来在后台记录加速计值。其思想是注册传感器侦听器并将值写入存储器。我已经启用了应用程序(不在服务中)的MainActivity中的StrictMode.enableDefaults()来检查服务是否在自己的线程上运行。但事实并非如此!我不知道是什么问题。。。我有一个AsyncTask类,我希望解决这个问题,但它显然没有(它在服务内部,它的execute方法是从服务的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;
    }
}

log cat中的StrictMode特别指出以下行正在使策略无效:

mFileStream.write(formatted.getBytes());

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

有人能告诉我出了什么问题吗?以下是我的服务的完整代码(如果需要): http://pastebin.com/NRm376BL


共 (2) 个答案

  1. # 1 楼答案

    我发现问题是,我应该创建一个HandlerThread和一个Handler并将处理程序传递给一个重载的registerListener方法。如果你不提供这个参数,监听器将由主线程处理,大多数时候这不是你想要的

    对于一个示例实现,请检查以下代码:特别是在另一个线程(而不是主线程)上处理传感器侦听器

    http://pastebin.com/QuHd0LNU

  2. # 2 楼答案

    Kotlin中有一个在线程上启动传感器的实现。传感器的值可以在传感器更改中处理

    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
        }
    
    }