Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Android

วิธีตรวจสอบว่ามือถือ Android รองรับเซ็นเซอร์ Game Rotation Vector หรือไม่

ภาพรวม

ตัวอย่างนี้สาธิตวิธีตรวจสอบการรองรับเซ็นเซอร์ TYPE_GAME_ROTATION_VECTOR ซึ่งให้ค่า Rotation Vector (Quaternion) โดยไม่ใช้ Magnetometer เหมาะสำหรับ Gaming และ VR ที่ไม่ต้องการทิศทางแม่เหล็กโลก

ขั้นตอนการสร้างโปรเจกต์

ขั้นตอนที่ 1: สร้างโปรเจกต์ใหม่

Android Studio → File → New Project → Empty Activity

ขั้นตอนที่ 2: Layout (res/layout/activity_main.xml)

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
    xmlns:app="https://schemas.android.com/apk/res-auto"
    xmlns:tools="https://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:gravity="center"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/actionEvent"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_marginTop="30dp"
        android:textSize="40sp"
        android:gravity="center" />

</LinearLayout>

ขั้นตอนที่ 3: โค้ดหลัก (src/MainActivity.java)

package com.example.myapplication;

import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorManager;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.RequiresApi;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;

public class MainActivity extends AppCompatActivity {

    TextView textView;
    SensorManager sensorManager;

    @RequiresApi(api = Build.VERSION_CODES.N)
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        TextView actionEvent = findViewById(R.id.actionEvent);
        sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);

        // ตรวจสอบ Game Rotation Vector
        Sensor gameRotationVector = sensorManager.getDefaultSensor(Sensor.TYPE_GAME_ROTATION_VECTOR);
        
        if (gameRotationVector != null) {
            actionEvent.setText("รองรับ Game Rotation Vector");
            
            String info = String.format(
                "Name: %s\nVendor: %s\nVersion: %d\n" +
                "Max Range: %.2f\nResolution: %.2f\nPower: %.2f mA\nMin Delay: %d µs",
                gameRotationVector.getName(),
                gameRotationVector.getVendor(),
                gameRotationVector.getVersion(),
                gameRotationVector.getMaximumRange(),
                gameRotationVector.getResolution(),
                gameRotationVector.getPower(),
                gameRotationVector.getMinDelay()
            );
            actionEvent.append("\n\n" + info);
        } else {
            actionEvent.setText("ไม่รองรับ Game Rotation Vector\n(ต้องมี Gyroscope + Accelerometer)");
        }
    }
}

ข้อมูลเซ็นเซอร์ TYPE_GAME_ROTATION_VECTOR

คุณสมบัติรายละเอียด
API Levelเพิ่มใน API 18 (Android 4.3)
ประเภทVirtual/Composite Sensor (Sensor Fusion)
รูปแบบข้อมูลQuaternion (x, y, z, w) หรือ Rotation Vector (x, y, z)
ขึ้นอยู่กับGyroscope + Accelerometer (ไม่ใช้ Magnetometer)
Driftมี Drift น้อยกว่า Gyroscope เพียงอย่างเดียว

Game Rotation Vector vs Rotation Vector

คุณสมบัติTYPE_GAME_ROTATION_VECTORTYPE_ROTATION_VECTOR
ใช้ Magnetometerไม่ใช้ใช้ (สำหรับ Absolute heading)
Reference FrameRelative (Device frame)Absolute (World frame - Magnetic North)
Drift (Yaw)มี Drift ตามเวลาไม่มี Drift (Locked to Magnetic North)
เหมาะสำหรับGaming, VR, Relative rotationNavigation, Compass, AR
Calibrationไม่ต้อง Calibrateต้อง Calibrate (หมุนรูป 8)

การใช้งานจริง

  • Mobile Gaming: ควบคุมมุมมอง/การเล็งด้วยการหมุนโทรศัพท์
  • VR Apps: Head tracking สำหรับ Cardboard/Daydream (ไม่ต้องการ Compass)
  • 3D Model Viewer: หมุนโมเดล 3D ด้วยการเคลื่อนไหวอุปกรณ์
  • Camera Apps: Stabilization, Panorama stitching

ตัวอย่างการแปลง Quaternion เป็น Euler Angles

// event.values = [x, y, z, w] (Quaternion) หรือ [x, y, z] (Rotation Vector)
float[] quaternion = new float[4];
if (event.values.length == 3) {
    // Rotation Vector -> Quaternion
    SensorManager.getQuaternionFromVector(quaternion, event.values);
} else {
    System.arraycopy(event.values, 0, quaternion, 0, 4);
}

// Quaternion -> Euler Angles (Degrees)
float[] rotationMatrix = new float[9];
SensorManager.getRotationMatrixFromVector(rotationMatrix, quaternion);
float[] orientation = new float[3];
SensorManager.getOrientation(rotationMatrix, orientation);

float azimuth = (float) Math.toDegrees(orientation[0]);   // Z-axis rotation
float pitch = (float) Math.toDegrees(orientation[1]);     // X-axis rotation  
float roll = (float) Math.toDegrees(orientation[2]);      // Y-axis rotation

ข้อควรระวัง

  • ต้องมี Gyroscope + Accelerometer ทั้งคู่
  • Yaw (Azimuth) จะ Drift ตามเวลา เพราะไม่มี Magnetometer Anchor
  • เหมาะสำหรับ Relative rotation (การหมุนสัมพัทธ์) ไม่ใช่ Absolute heading
  • ใน Manifest: <uses-feature android:name="android.hardware.sensor.gyroscope" android:required="true" /> (โดยนัย)