package sushi.hardcore.droidfs import android.content.Context import android.hardware.Sensor import android.hardware.SensorEvent import android.hardware.SensorEventListener import android.hardware.SensorManager import android.view.Surface import java.lang.ref.WeakReference import java.util.* class SensorOrientationListener(context: Context) { private val mSensorEventListener: SensorEventListener private val mSensorManager: SensorManager init { mSensorEventListener = NotifierSensorEventListener() mSensorManager = context.getSystemService(Context.SENSOR_SERVICE) as SensorManager } private val mListeners = ArrayList>(1) private var orientation = Surface.ROTATION_0 private fun onResume() { mSensorManager.registerListener( mSensorEventListener, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL ) } private fun onPause() { mSensorManager.unregisterListener(mSensorEventListener) } private inner class NotifierSensorEventListener : SensorEventListener { override fun onSensorChanged(event: SensorEvent) { val x = event.values[0] val y = event.values[1] var newOrientation: Int = orientation if (x < 5 && x > -5 && y > 5) newOrientation = Surface.ROTATION_0 else if (x < -5 && y < 5 && y > -5) newOrientation = Surface.ROTATION_270 else if (x < 5 && x > -5 && y < -5) newOrientation = Surface.ROTATION_180 else if (x > 5 && y < 5 && y > -5) newOrientation = Surface.ROTATION_90 if (orientation != newOrientation) { orientation = newOrientation notifyListeners() } } override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {} } interface Listener { fun onOrientationChange(newOrientation: Int) } fun addListener(listener: Listener) { if (get(listener) == null) // prevent duplications mListeners.add(WeakReference(listener)) if (mListeners.size == 1) { onResume() // this is the first client } } fun remove(listener: Listener) { val listenerWR = get(listener) remove(listenerWR) } private fun remove(listenerWR: WeakReference?) { if (listenerWR != null) mListeners.remove(listenerWR) if (mListeners.size == 0) { onPause() } } private operator fun get(listener: Listener): WeakReference? { for (existingListener in mListeners) if (existingListener.get() === listener) return existingListener return null } private fun notifyListeners() { val deadListeners = ArrayList>() for (wr in mListeners) { if (wr.get() == null) deadListeners.add(wr) else wr.get()!!.onOrientationChange(orientation) } // remove dead references for (wr in deadListeners) { mListeners.remove(wr) } } }