Search code examples
androidclojureclojure-java-interop

cast class to SensorEventListener


I'm trying to register SensorEventListener but my listener has wrong type.

Here's what I tried:

;; listener
(gen-class
:name com.spython.pushupcounter.main.sensor-listener
:implements [android.hardware.SensorEventListener]
:prefix "-"
:methods [[onAccuracyChanged [android.hardware.Sensor Integer] void]
                    [onSensorChanged [android.hardware.SensorEvent] void]])

(def listener com.spython.pushupcounter.main.sensor-listener)
(.registerListener sensor-manager listener proximitySensor 2)

Looks like I need to cast listener to SensorEventListener, right?
How can I do this?


Solution

  • Symbols matching a class name, like com.spython.pushupcounter.main.sensor-listener resolve to instances of java.lang.Class. So your listener is a Class, which is not what you want. It should be instead an instance of com.spython.pushupcounter.main.sensor-listener. Instances can be created using standard instantiation syntax (com.spython.pushupcounter.main.sensor-listener.) - note a . at the end - syntax sugar for new. But even after you fix this, the code won't work. (gen-class) is tricky to use this way. It only generates the class if AOT compilation is used and does nothing otherwise. You also have to provide the implementation for SensorEventListener methods.

    A better approach is to use (reify), which returns an object that implements desired interface(s). For example:

    (defn listener []
      (reify
        android.hardware.SensorEventListener
        (onAccuracyChanged [_ sensor accuracy] 
          (comment onAccuracyChanged implementation here))
        (onSensorChanged [_ event]
          (comment onSensorChanged implementation here))))
    
    (.registerListener sensor-manager (listener) proximitySensor 2)