Sujet du capteur (2) – Capteur de direction


Introduction à cette section :

Dans la section précédente, nous avons appris quelques concepts de base des capteurs et appris les routines d'utilisation des capteurs. Le capteur que cette section vous présente est l'utilisation du capteur de direction. D'accord, commençons cette section ~


1 Le concept de système de coordonnées tridimensionnel :

Dans. sur la plateforme Android, le cadre du capteur utilise généralement un système de coordonnées tridimensionnelles standard pour représenter une valeur. Prenez cette section Prenons l'exemple du capteur de direction. La détermination d'une direction nécessite également des coordonnées tridimensionnelles. Après tout, notre équipement ne peut pas durer éternellement. Ils sont tous placés horizontalement. La valeur de direction que nous renvoie Android est un tableau plat d'une longueur de 3, comprenant trois directions. valeur! Il y a une telle image dans la documentation officielle de l'API : sensors_overview

1.png

Si vous ne comprenez pas l'image, écrivez en bas d'une explication textuelle :

  • Direction de l'axe X : de gauche à droite dans la direction horizontale de l'écran. Si le téléphone n'est pas un carré, le côté le plus court doit le faire. être horizontal Placer, le côté le plus long doit être placé verticalement.
  • Direction de l'axe Y : Partant du coin inférieur gauche de l'écran et pointant dans la direction verticale vers le haut de l'écran
  • Axe Z direction : Lorsqu'il est placé horizontalement, pointez dans la direction du ciel

2. Trois valeurs du capteur de direction

Comme mentionné dans la section précédente. , la méthode de rappel du capteur : onSensorChanged Paramètres de l'événement SensorEvent, événement Le type de valeur est Float[] et comporte au plus trois éléments, tandis que le capteur de direction comporte exactement trois éléments, tous représentant des degrés ! Les significations correspondantes sont les suivantes :

valeurs[0] : angle d'azimut, l'angle auquel le téléphone tourne autour de l'axe Z. 0 signifie Nord, 90 signifie Est. 180 signifie plein sud (Sud) et 270 signifie plein ouest (Ouest). Si la valeur de valeurs[0] se trouve être ces quatre valeurs, Et si le téléphone mobile est placé horizontalement, alors l'avant actuel du téléphone mobile se trouve dans ces quatre directions. Vous pouvez l'utiliser pour. Écrivez une boussole !

valeurs[1] : Angle d'inclinaison, à quel point le téléphone s'incline. Cette valeur change lorsque le téléphone s'incline autour de l'axe x. valeur La plage est comprise entre [-180,180]. Si le téléphone est placé sur le bureau et que celui-ci est complètement horizontal, les valeurs 1 doivent être est 0, bien sûr, peu de tables sont absolument horizontales. Commencez à soulever depuis le haut du téléphone jusqu'à ce que le téléphone pivote de 180 degrés le long de l'axe x (à ce moment, l'écran Campagne placée horizontalement sur la table). Au cours de ce processus de rotation, la valeur des valeurs[1] passera de 0 à -180, c'est-à-dire que le téléphone est levé Lorsque , la valeur des valeurs1 deviendra progressivement plus petite jusqu'à ce qu'elle soit égale à -180 ; lors de l'ajout, commencez à soulever depuis le bas du téléphone jusqu'à ce que le téléphone se déplace le long du x- axe Rotation de 180 degrés. À ce moment, la valeur des valeurs[1] passera de 0 à 180. Nous pouvons utiliser cette fonctionnalité de valeur[1] pour combiner value[2] pour implémenter une règle plate !

valeur[2] : angle de défilement, l'angle de défilement le long de l'axe Y, la plage de valeurs est : [-90,90], en supposant que l'écran du téléphone mobile est placé horizontalement vers le haut Sur le bureau, si le bureau est plat à ce moment-là, la valeur de valeurs2 doit être 0. Soulevez progressivement le téléphone du côté gauche, la valeur des valeurs[2] va Diminuez progressivement jusqu'à ce qu'il soit placé verticalement par rapport au téléphone. À ce stade, la valeur des valeurs [2] est de -90, et à partir de la droite, elle est de 0 à 90 ; Lorsque vous continuez à faire défiler vers la droite ou la gauche, la valeur des valeurs[2] continuera de changer entre -90 et 90 !

Si vous ne le comprenez pas très bien, ce n'est pas grave. Écrivons une démo pour le vérifier ~


3. :

Exécution des rendus :

2.gif

Code d'implémentation :

Code de mise en page :

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">

    <TextView
        android:id="@+id/tv_value1"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text="方位角"
        android:textSize="18sp"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/tv_value2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text="倾斜角"
        android:textSize="18sp"
        android:textStyle="bold" />

    <TextView
        android:id="@+id/tv_value3"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="10dp"
        android:text="滚动角"
        android:textSize="18sp"
        android:textStyle="bold" /></LinearLayout>

MainActivity.java

public class MainActivity extends AppCompatActivity implements SensorEventListener {

    private TextView tv_value1;
    private TextView tv_value2;
    private TextView tv_value3;
    private SensorManager sManager;
    private Sensor mSensorOrientation;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        sManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        mSensorOrientation = sManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
        sManager.registerListener(this, mSensorOrientation, SensorManager.SENSOR_DELAY_UI);
        bindViews();
    }

    private void bindViews() {
        tv_value1 = (TextView) findViewById(R.id.tv_value1);
        tv_value2 = (TextView) findViewById(R.id.tv_value2);
        tv_value3 = (TextView) findViewById(R.id.tv_value3);
    }

    @Override
    public void onSensorChanged(SensorEvent event) {
        tv_value1.setText("方位角:" + (float) (Math.round(event.values[0] * 100)) / 100);
        tv_value2.setText("倾斜角:" + (float) (Math.round(event.values[1] * 100)) / 100);
        tv_value3.setText("滚动角:" + (float) (Math.round(event.values[2] * 100)) / 100);
    }

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

    }
}

Le code est très simple~, si vous voulez vraiment expérimenter les changements de ceux-ci trois valeurs, exécutez-le vous-même. Allumez simplement le programme sur votre téléphone et vous saurez ~


4. Un exemple simple de boussole textuelle

Écrivons une version textuelle simple de la boussole pour vivez l'expérience Lorsque le texte est affiché Lorsque vous faites face au sud, cela signifie un téléphone portable. Directement devant se trouve le sud !

Exécution de rendus :

3.gif

Implémentation du code :

Vue personnalisée :

CompassView.java

/**
 * Created by Jay on 2015/11/14 0014.
 */
public class CompassView extends View implements Runnable{

    private Paint mTextPaint;
    private int sWidth,sHeight;
    private float dec = 0.0f;
    private String msg  = "正北 0°";

    public CompassView(Context context) {
        this(context, null);
    }

    public CompassView(Context context, AttributeSet attrs) {
        super(context, attrs);
        sWidth = ScreenUtil.getScreenW(context);
        sHeight = ScreenUtil.getScreenH(context);
        init();
        new Thread(this).start();
    }



    public CompassView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    private void init() {

        mTextPaint = new Paint();
        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);
    }

    // 更新指南针角度
    public void setDegree(float degree)
    {
        // 设置灵敏度
        if(Math.abs(dec - degree) >= 2 )
        {
            dec = degree;
            int range = 22;
            String degreeStr = String.valueOf(dec);

            // 指向正北
            if(dec > 360 - range && dec  90 - range && dec  180 - range && dec  270 - range && dec  45 - range && dec  135 - range && dec  225 - range && dec  315 - range && dec < 315 + range)
            {
                msg = "西北 " + 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);
    }
}

C'est le prototype d'une boussole très simple. Si vous êtes intéressé, vous pouvez la dessiner. vous-même une boussole et un pointeur, puis mettez en œuvre un Belle boussole ~


5. Téléchargez l'exemple de code dans cette section :

SensorDemo2.zip

SensorDemo3.zip


Résumé de cette section :

D'accord, cette section vous présente les capteurs de direction les plus couramment utilisés sous Android, ainsi que leur utilisation simple, et J'ai écrit un exemple de boussole Pour compléter la boussole, nous n'utilisons qu'une seule valeur[0] et utilisons les deux autres. Nous pouvons également l'utiliser pour mesurer si un certain endroit est à plat, c'est-à-dire pour créer une règle de niveau. Si vous avez le temps, vous pouvez en écrire une pour vous amuser. D'accord, c'est tout, merci~4.jpg