teaching machines

CS 436 Lecture 22 – Sensors

November 11, 2014 by . Filed under cs436, fall 2014, lectures.

Code

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                tools:context=".MyActivity">

  <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:text="Heading"
    android:id="@+id/headingLabel"
    android:layout_alignParentBottom="true"
    android:layout_centerHorizontal="true"/>

  <view
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    class="org.twodee.compass.NeedleView"
    android:id="@+id/NeedleView"
    android:layout_centerVertical="true"
    android:layout_centerHorizontal="true"/>

</RelativeLayout>

MainActivity.java

package org.twodee.compass;

import android.app.Activity;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.widget.TextView;


public class MainActivity extends Activity implements SensorEventListener {
  private TextView headingLabel;
  private NeedleView nv;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    nv = (NeedleView) findViewById(R.id.NeedleView);
  }

  @Override
  protected void onResume() {
    super.onResume();

    SensorManager sm = (SensorManager) getSystemService(SENSOR_SERVICE);
    Sensor mag = sm.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
    sm.registerListener(this, mag, SensorManager.SENSOR_DELAY_GAME);

  }

  @Override
  public void onSensorChanged(SensorEvent event) {
    //event.values;
    float theta = (float)Math.toDegrees(Math.atan2(event.values[0],event.values[1]));
    nv.setAngle(theta);
  }

  @Override
  protected void onPause() {
    super.onPause();
    SensorManager sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
    sensorManager.unregisterListener(this);

  }

  @Override
  public void onAccuracyChanged(Sensor sensor,
                                int accuracy) {

  }
}

NeedleView.java

package org.twodee.compass;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

public class NeedleView extends View{
  private Paint paint;
  private float angle;
  public NeedleView(Context context,
                    AttributeSet attrs) {
    super(context, attrs);
    paint = new Paint();
    paint.setColor(Color.argb(255, 255, 51, 153));
    paint.setStrokeWidth(5f);
    angle = 0;
  }

  public void setAngle(float angle){
    this.angle = angle;
    invalidate();
  }

  @Override
  protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.translate(canvas.getWidth()/2, canvas.getHeight()/2);
    canvas.rotate(angle);
    canvas.scale(1f,-1f);
    canvas.drawLine(0f,0f,0f,600f,paint);
  }
}

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
                xmlns:tools="http://schemas.android.com/tools"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                android:id="@+id/overall"
                tools:context=".MainActivity">


  <TextView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:textAppearance="?android:attr/textAppearanceLarge"
    android:text="Large Text"
    android:id="@+id/yprLabel"
    android:layout_centerVertical="true"
    android:layout_centerHorizontal="true"/>

</RelativeLayout>

MainActivity.java

package org.twodee.lonelyphone;

import android.app.Activity;
import android.graphics.Color;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;


public class MainActivity extends Activity implements SensorEventListener {
  private TextView readingsLabel;
  private View overall;
  private Ringtone ringtone;

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    readingsLabel = (TextView) findViewById(R.id.yprLabel);
    overall = findViewById(R.id.overall);

    ringtone = RingtoneManager.getRingtone(this, RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE));
  }

  @Override
  protected void onResume() {
    super.onResume();

    SensorManager sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
    Sensor accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_GAME);
  }

  @Override
  protected void onPause() {
    super.onPause();

    SensorManager sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
    sensorManager.unregisterListener(this);
  }

  @Override
  public void onSensorChanged(SensorEvent event) {
    readingsLabel.setText(String.format("%.1f, %.1f, %.1f", event.values[0], event.values[1], event.values[2]));

    float threshold = 1.5f;

    if (Math.abs(event.values[0]) < threshold &&
        Math.abs(event.values[1]) < threshold &&
        Math.abs(SensorManager.STANDARD_GRAVITY - event.values[2]) < threshold) {
      overall.setBackgroundColor(Color.GREEN);
      if (!ringtone.isPlaying()) {
        ringtone.play();
      }
    } else {
      overall.setBackgroundColor(Color.RED);
      if (ringtone.isPlaying()) {
        ringtone.stop();
      }
    }
  }

  @Override
  public void onAccuracyChanged(Sensor sensor,
                                int accuracy) {

  }
}