Easy Tutorial
❮ Programmer Facial Package Summary Android Tutorial Touchlistener Ontouchevent ❯

10.11 Sensor Special (2) — Orientation Sensor

Classification Android Basic Tutorial

Introduction to This Section:

In the previous section, we studied some basic concepts of sensors and learned the methods of using them. This section will introduce the usage of the orientation sensor. Let's start the content of this section~


1. The Concept of the Three-Dimensional Coordinate System:

In the Android platform, the sensor framework usually represents a value using a standard three-dimensional coordinate system. Taking the orientation sensor to be discussed in this section as an example, determining a direction also requires a three-dimensional coordinate, after all, our device cannot always be held horizontally, right? The direction values returned by Android are a float array with a length of 3, containing three directional values! The official API documentation has a figure like this: sensors_overview

If you can't understand the picture, then write a textual explanation:


2. The Three Values of the Orientation Sensor

In the previous section, it was mentioned that the callback method of the sensor: onSensorChanged with the parameter SensorEvent event, the value type of event is Float[], and there are at most three elements, and the orientation sensor just has three elements, all of which represent degrees! The corresponding meanings are as follows:

values[0]: Azimuth angle, the angle at which the phone rotates around the Z-axis. 0 represents North, 90 represents East, 180 represents South, and 270 represents West. If the value of values[0] is exactly one of these four values, and the phone is placed horizontally, then the front of the phone is facing these four directions, which can be used to write a compass!

values[1]: Tilt angle, the degree to which the phone is tilted, which changes when the phone tilts around the X-axis. The value range is between [-180,180]. If you put the phone on the table, and the table is completely horizontal, the value of values[1] should be 0, of course, very few tables are absolutely horizontal. From the top of the phone start lifting, until the phone rotates 180 degrees along the X-axis (at this time the screen is placed horizontally on the table). During this rotation process, the value of values[1] will change from 0 to -180, that is, when the phone is lifted, the value of values[1] will gradually decrease until it equals -180; and if you start lifting from the bottom of the phone, until the phone rotates 180 degrees along the X-axis, at this time the value of values[1] will change from 0 to 180. We can use the characteristic of value[1] in combination with value[2] to implement a level meter!

value[2]: Roll angle, the rolling angle along the Y-axis, the value range is: [-90,90]. Suppose you place the phone screen up horizontally on the table, and if the table is flat, the value of values[2] should be 0. Lift the phone from the left side, the value of values[2] will gradually decrease, until it is perpendicular to the phone placement, at this time the value of values[2] is -90, from the right side it is 0-90; if you continue to roll to the right or left in the vertical position, the value of values[2] will continue to change between -90 and 90!

If you don't quite understand, it's okay, we will write a demo to verify the changes in these three values~


3. A Simple Demo to Help Us Understand the Changes in These Three Values:

Running effect picture :

Implementation code :

Layout code: activity_main.xml :

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="5dp">

    &lt;TextView
        android:id="@+id/tv_value1"
        android:layout_width="wrap_content"

```java
mTextPaint.setColor(Color.GRAY);
mTextPaint.setTextSize(64);
mTextPaint.setStyle(Paint.Style.FILL);
@Override
protected void onDraw(Canvas canvas) {
    super.onDraw(canvas);
    canvas.drawText(msg, sWidth / 4, sWidth / 2, mTextPaint);
}

// Update compass degree
public void setDegree(float degree)
{
    // Set sensitivity
    if(Math.abs(dec - degree) >= 2 )
    {
        dec = degree;
        int range = 22;
        String degreeStr = String.valueOf(dec);

        // Point to true north
        if(dec > 360 - range && dec < 360 + range)
        {
            msg = "True North " + degreeStr + "°";
        }

        // Point to true east
        if(dec > 90 - range && dec < 90 + range)
        {
            msg = "True East " + degreeStr + "°";
        }

        // Point to true south
        if(dec > 180 - range && dec < 180 + range)
        {
            msg = "True South " + degreeStr + "°";
        }

        // Point to true west
        if(dec > 270 - range && dec < 270 + range)
        {
            msg = "True West " + degreeStr + "°";
        }

        // Point to northeast
        if(dec > 45 - range && dec < 45 + range)
        {
            msg = "Northeast " + degreeStr + "°";
        }

        // Point to southeast
        if(dec > 135 - range && dec < 135 + range)
        {
            msg = "Southeast " + degreeStr + "°";
        }

        // Point to southwest
        if(dec > 225 - range && dec < 225 + range)
        {
            msg = "Southwest " + degreeStr + "°";
        }

        // Point to northwest
        if(dec > 315 - range && dec < 315 + range)
        {
            msg = "Northwest " + degreeStr + "°";
        }
    }
}

@Override
public void run() {
    while(!Thread.currentThread().isInterrupted())
    {
        try
        {
            Thread.sleep(100);
        }
        catch(InterruptedException e)
        {
            Thread.currentThread().interrupt();
        }
        postInvalidate();
    }
}
}

MainActivity.java :

public class MainActivity extends AppCompatActivity implements SensorEventListener {

    private CompassView cView;
    private SensorManager sManager;
    private Sensor mSensorOrientation;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        cView = new CompassView(MainActivity.this);
        sManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        mSensorOrientation = sManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
        sManager.registerListener(this, mSensorOrientation, SensorManager.SENSOR_DELAY_UI);
        setContentView(cView);
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        cView.setDegree(event.values[0]);
    }

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

    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        sManager.unregisterListener(this);
    }
}

This is a very simple prototype of a compass. If you are interested, you can draw your own compass and pointer, and then implement a more aesthetically pleasing compass.


5. Download the example code for this section:

SensorDemo2.zip

SensorDemo3.zip


Summary of this section:

>

Well, this section introduced the most commonly used orientation sensor in Android, its simple usage, and wrote an example of a compass. To complete the compass, we only used the value of values[0]. We can also use the other two values to measure whether a place is flat, that is, to make a spirit level. If you have time, you can write one to play with.

That's it, thank you.

-1.0 Android Basic Tutorial

-1.0.1 Latest Android Basic Tutorial Catalog for 2015

-1.1 Background and System Architecture Analysis

-1.2 Development Environment Setup

-1.2.1 Developing Android APPs with Eclipse + ADT + SDK

-1.2.2 Developing Android APPs with Android Studio

-[1.3 Solving SDK

❮ Programmer Facial Package Summary Android Tutorial Touchlistener Ontouchevent ❯