defhlt
defhlt

Reputation: 1784

From Java to Scala: SensorManager

Scala/Android newbie question. I'm trying to rewrite this simple code from Java to Scala. Java working code:

private final SensorEventListener mAccListener = new SensorEventListener() {
    public void onSensorChanged(SensorEvent event) {
        // ... some code
    }
};


@Override    
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    findViewById(R.id.start).setOnClickListener(this);        

    mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
    mAccSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

    mSensorManager.registerListener(mAccListener, mAccSensor,
            SensorManager.SENSOR_DELAY_GAME);
}

...and Scala:

package com.example.hello

import android.app.Activity
import android.content.Context
import android.content.Context
import android.hardware.Sensor
import android.hardware.SensorManager
import android.os.Bundle
import android.os.Bundle
import android.view.View.OnClickListener
import android.view.View
import android.view.View
import android.widget.Toast
import android.widget.Toast
import android.hardware.SensorEventListener

class HelloAndroid extends Activity {

  def mAccListener (v: View) {
    // ... some code
  }

  override def onCreate(savedInstanceState : Bundle) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.main)

    findViewById(R.id.start).setOnClickListener(new View.OnClickListener() {
      def onClick(v: View) {
        Toast.makeText(v.getContext, "Hello World", Toast.LENGTH_LONG).show()
      }
    })

        val mSensorManager = getSystemService(Context.SENSOR_SERVICE).asInstanceOf[SensorManager]
        val mAccSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)

        mSensorManager.registerListener(mAccListener(_), mAccSensor,
                SensorManager.SENSOR_DELAY_GAME)

  }
}

The error is Eclipe states:

Multiple markers at this line
    - missing arguments for method mAccListener in class HelloAndroid; follow this method with `_' if you want to treat it as a partially applied function
    - overloaded method value registerListener with alternatives: (android.hardware.SensorEventListener,android.hardware.Sensor,Int,android.os.Handler)Boolean <and> 
     (android.hardware.SensorEventListener,android.hardware.Sensor,Int)Boolean <and> (android.hardware.SensorListener,Int,Int)Boolean <and> (android.hardware.SensorListener,Int)Boolean 
     cannot be applied to (android.view.View => Unit, android.hardware.Sensor, Int)

As I understand Scala can't find out which class to call method from? How can I fix it?

Upvotes: 1

Views: 756

Answers (2)

defhlt
defhlt

Reputation: 1784

It works after these corrections:

class HelloAndroid extends Activity {

    def mAccListener() :SensorListener = new SensorListener {
        def onSensorChanged(x1: Int, x2: Array[Float]) = {
            var t=findViewById(R.id.acc).asInstanceOf[TextView]
            var x = x2(0).toString
            t.setText(x)
        }

        def onAccuracyChanged(a: Int, b: Int) = {
          //TODO
        }
    }

    override def onCreate(savedInstanceState : Bundle) {

    //...            

        mSensorManager.registerListener(mAccListener, SensorManager.SENSOR_DELAY_GAME)

  }
}

But what I don't understand is why in Java and Scala the same function takes different values. It is as inconvenient as it is confusing:

+-------------------+------------------------------+---------------------------+
| Api Function      | Java                         | Scala                     |
+-------------------+------------------------------+---------------------------+
| onSensorChanged   | SensorEvent event            | x1: Int, x2: Array[Float] |
| onAccuracyChanged | Sensor sensor, int accuracy  | a: Int, b: Int            |
+-------------------+------------------------------+---------------------------+

Can somebody explain it?

Upvotes: 0

James Iry
James Iry

Reputation: 19367

"mAccListener(_)" creates a function of type android.view.View => Unit. But there's no version of registerListener that takes such a function.

The Java version is passing in a SensorListener. Shouldn't the Scala version do the same?

You're probably thinking of an implicit conversion from View => Unit to SensorListener... if so, you need to build it yourself.

Upvotes: 1

Related Questions