Video Demo
Our code for today will run just like this.
Files Needed
You need to create your own compass image. For this example, I'm using a stock photo. Your image must be a PNG with transparent background, do not use this jpg file I used.
Let's Code
Here's our MainActivity.java
package com.example.compassapp; 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.view.animation.Animation; import android.view.animation.RotateAnimation; import android.widget.ImageView; import android.widget.TextView; public class MainActivity extends Activity implements SensorEventListener { // define the display assembly compass picture private ImageView image; // record the compass picture angle turned private float currentDegree = 0f; // device sensor manager private SensorManager mSensorManager; TextView tvHeading; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // our compass image image = (ImageView) findViewById(R.id.imageViewCompass); // TextView that will tell the user what degree is he heading tvHeading = (TextView) findViewById(R.id.tvHeading); // initialize your android device sensor capabilities mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE); } @Override protected void onResume() { super.onResume(); // for the system's orientation sensor registered listeners mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_GAME); } @Override protected void onPause() { super.onPause(); // to stop the listener and save battery mSensorManager.unregisterListener(this); } @Override public void onSensorChanged(SensorEvent event) { // get the angle around the z-axis rotated float degree = Math.round(event.values[0]); tvHeading.setText("Heading: " + Float.toString(degree) + " degrees"); // create a rotation animation (reverse turn degree degrees) RotateAnimation ra = new RotateAnimation( currentDegree, -degree, Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f); // how long the animation will take place ra.setDuration(210); // set the animation after the end of the reservation status ra.setFillAfter(true); // Start the animation image.startAnimation(ra); currentDegree = -degree; } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { // not in use } }
Our layout file activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:background="#fff" > <TextView android:id="@+id/tvHeading" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_centerHorizontal="true" android:layout_marginBottom="40dp" android:layout_marginTop="20dp" android:text="Heading: 0.0" /> <ImageView android:id="@+id/imageViewCompass" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/tvHeading" android:layout_centerHorizontal="true" android:src="@drawable/img_compass" /> </RelativeLayout>
Some notes
My app orientation is locked to portrait mode.
There are no special permissions in the Manifest file.
Further Readings
Android SensorManager
Android RotateAnimation
Android Motion Sensors
For FREE programming tutorials, click the red button below and subscribe! :)
website