เซ็นเซอร์ตำแหน่ง

แพลตฟอร์ม Android มีเซ็นเซอร์ 2 ตัวที่ช่วยให้คุณระบุตำแหน่งของอุปกรณ์ได้ ได้แก่ เซ็นเซอร์สนามแม่เหล็กโลกและตัวตรวจวัดความเร่ง Android แพลตฟอร์มของแพลตฟอร์มยังมีเซ็นเซอร์ที่ให้คุณระบุระยะห่างของใบหน้าของ อุปกรณ์หมายถึงวัตถุ (หรือที่เรียกว่าพร็อกซิมิตีเซ็นเซอร์) เซ็นเซอร์สนามแม่เหล็กและพร็อกซิมิตีเซ็นเซอร์ทำงานด้วยฮาร์ดแวร์ พบบ่อยที่สุด ผู้ผลิตโทรศัพท์มือถือและแท็บเล็ตมีเซ็นเซอร์สนามแม่เหล็กโลก ในทำนองเดียวกัน โดยปกติแล้วผู้ผลิตโทรศัพท์มือถือจะมีพร็อกซิมิตีเซ็นเซอร์เพื่อระบุว่า ถือโทรศัพท์ไว้ใกล้ใบหน้าของผู้ใช้ (เช่น ขณะใช้โทรศัพท์ การโทร) หากต้องการระบุการวางแนวของอุปกรณ์ คุณสามารถใช้ค่าที่อ่านได้จากตัวตรวจวัดความเร่งของอุปกรณ์และเซ็นเซอร์สนามแม่เหล็กโลก

หมายเหตุ: เซ็นเซอร์การวางแนวได้รับการเลิกใช้งานแล้วใน Android 2.2 (API ระดับ 8) และเลิกใช้งานประเภทเซ็นเซอร์การวางแนวใน Android 4.4W (API ระดับ 20)

เซ็นเซอร์ตำแหน่งมีประโยชน์ในการระบุตำแหน่งทางกายภาพของอุปกรณ์ใน กรอบอ้างอิงของโลกได้ ตัวอย่างเช่น คุณสามารถใช้สนามแม่เหล็กโลก เซ็นเซอร์ร่วมกับตัวตรวจวัดความเร่งเพื่อกำหนดตำแหน่งของอุปกรณ์ เมื่อเทียบกับขั้วโลกเหนือแม่เหล็ก และคุณยังใช้เซ็นเซอร์เหล่านี้เพื่อ กำหนดการวางแนวของอุปกรณ์ในกรอบอ้างอิงของแอปพลิเคชันของคุณ โดยปกติแล้ว เซ็นเซอร์ตำแหน่งไม่ได้ใช้เพื่อตรวจสอบการเคลื่อนไหวของอุปกรณ์ เช่น การเขย่า การเอียง หรือแรงผลัก (ดูข้อมูลเพิ่มเติมที่หัวข้อเซ็นเซอร์ตรวจจับการเคลื่อนไหว)

เซ็นเซอร์สนามแม่เหล็กโลกและเซ็นเซอร์วัดความเร่งจะแสดงผลอาร์เรย์หลายมิติของค่าเซ็นเซอร์สำหรับ SensorEvent แต่ละรายการ เช่น เซ็นเซอร์สนามแม่เหล็กโลกจะให้ค่าความแรงของสนามแม่เหล็กโลกสำหรับแกนพิกัดทั้ง 3 แกนในระหว่างเหตุการณ์ของเซ็นเซอร์แต่ละครั้ง ในทำนองเดียวกัน เซ็นเซอร์ตัวตรวจวัดความเร่งวัดความเร่งที่ใช้กับอุปกรณ์ระหว่าง เหตุการณ์เซ็นเซอร์ สำหรับข้อมูลเพิ่มเติมเกี่ยวกับระบบพิกัดที่ใช้ ตามเซ็นเซอร์ โปรดดู ระบบพิกัดเซ็นเซอร์ พร็อกซิมิตีเซ็นเซอร์มีค่าเดียว สำหรับแต่ละเหตุการณ์เซ็นเซอร์ ตารางที่ 1 สรุปตำแหน่งเซ็นเซอร์ที่ ที่ได้รับการสนับสนุนบนแพลตฟอร์ม Android

ตารางที่ 1 เซ็นเซอร์ตำแหน่งที่รองรับในแพลตฟอร์ม Android

เซ็นเซอร์ ข้อมูลเหตุการณ์เซ็นเซอร์ คำอธิบาย หน่วยวัด
TYPE_GAME_ROTATION_VECTOR SensorEvent.values[0] คอมโพเนนต์เวกเตอร์การหมุนตามแกน x (x * sin(การเป็นสมาชิก/2)) ไม่มีหน่วย
SensorEvent.values[1] คอมโพเนนต์เวกเตอร์การหมุนตามแกน y (y * sin(θ/2))
SensorEvent.values[2] องค์ประกอบเวกเตอร์การหมุนตามแกน z (z * sin(θ/2))
TYPE_GEOMAGNETIC_ROTATION_VECTOR SensorEvent.values[0] คอมโพเนนต์เวกเตอร์การหมุนตามแกน x (x * sin(θ/2)) ไม่มีหน่วย
SensorEvent.values[1] คอมโพเนนต์เวกเตอร์การหมุนตามแกน y (y * sin(θ/2))
SensorEvent.values[2] ส่วนประกอบของเวกเตอร์การหมุนตามแกน z (z * sin(เพื่อไม่ให้เป็นความจริง/2))
TYPE_MAGNETIC_FIELD SensorEvent.values[0] ความแรงของสนามแม่เหล็กโลกตามแกน x μT
SensorEvent.values[1] ความแรงของสนามแม่เหล็กโลกตามแกน Y
SensorEvent.values[2] ความแรงของสนามแม่เหล็กโลกตามแกน z
TYPE_MAGNETIC_FIELD_UNCALIBRATED SensorEvent.values[0] ความแรงของสนามแม่เหล็กโลก (ไม่มีการสอบเทียบด้วยเหล็กแข็ง) ตามแนวแกน x μT
SensorEvent.values[1] ความแรงของสนามแม่เหล็กโลก (ไม่มีการปรับเทียบเหล็กแข็ง) ตามแกน Y
SensorEvent.values[2] ความแรงของสนามแม่เหล็กโลก (ไม่มีการสอบเทียบด้วยเหล็กแข็ง) ตามแนวแกน z
SensorEvent.values[3] การประมาณค่าการให้น้ำหนักพิเศษของเหล็กตามแกน x
SensorEvent.values[4] การประมาณค่าอคติเหล็กตามแกน Y
SensorEvent.values[5] การประมาณการให้น้ำหนักพิเศษเหล็กตามแกน z
TYPE_ORIENTATION1 SensorEvent.values[0] อาซิมุท (มุมรอบแกน Z) องศา
SensorEvent.values[1] ระดับ (มุมรอบแกน X)
SensorEvent.values[2] หมุน (ทำมุมรอบแกน Y)
TYPE_PROXIMITY SensorEvent.values[0] ระยะห่างจากวัตถุ2 ซม.

1 เซ็นเซอร์นี้เลิกใช้งานแล้วใน Android 2.2 (API ระดับ 8) และเลิกใช้งานเซ็นเซอร์ประเภทนี้ใน Android 4.4W (API ระดับ 20) เฟรมเวิร์กเซ็นเซอร์แสดงวิธีการทางเลือกในการรับอุปกรณ์ ซึ่งอธิบายไว้ในหัวข้อการประมวลผล การวางแนวของอุปกรณ์

2 พร็อกซิมิตีเซ็นเซอร์บางรุ่นจะระบุค่าไบนารีเท่านั้น แสดงถึงระยะใกล้และไกล

ใช้เซ็นเซอร์เวกเตอร์การหมุนเกม

เซ็นเซอร์เวกเตอร์การหมุนของเกมจะเหมือนกับเซ็นเซอร์เวกเตอร์การหมุน ยกเว้นจะไม่ใช้สนามแม่เหล็กโลก ดังนั้น แกน Y จึงไม่ได้ชี้ไปทางทิศเหนือ แต่ชี้ไปยังข้อมูลอ้างอิงอื่น การอ้างอิงดังกล่าวได้รับอนุญาตให้ลอยตาม ซึ่งมีลำดับขนาดเท่ากับเครื่องวัดการหมุนจะลอยรอบแกน Z

เนื่องจากเซ็นเซอร์เวกเตอร์การหมุนเกมไม่ได้ใช้สนามแม่เหล็ก การหมุนแบบสัมพัทธ์ มีความถูกต้องมากขึ้น และไม่ได้รับผลกระทบจากการเปลี่ยนแปลงสนามแม่เหล็ก ใช้เซ็นเซอร์นี้ในเกมหากไม่สนใจว่าทิศเหนืออยู่ตรงไหน และเวกเตอร์การหมุนปกติไม่ตรงกับความต้องการของคุณเนื่องจากอาศัยสนามแม่เหล็ก

โค้ดต่อไปนี้แสดงวิธีขอรับอินสแตนซ์ของเวกเตอร์การหมุนเริ่มต้นของเกม เซ็นเซอร์:

Kotlin

private lateinit var sensorManager: SensorManager
private var sensor: Sensor? = null
...
sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_GAME_ROTATION_VECTOR)

Java

private SensorManager sensorManager;
private Sensor sensor;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_GAME_ROTATION_VECTOR);

ใช้เซ็นเซอร์เวกเตอร์การหมุนแม่เหล็กภูมิศาสตร์

เซ็นเซอร์เวกเตอร์การหมุนของสนามแม่เหล็กโลกคล้ายกับเซ็นเซอร์เวกเตอร์การหมุน แต่ไม่ได้ใช้ไจโรสโคป ความแม่นยำของเซ็นเซอร์นี้จะต่ำกว่าเซ็นเซอร์เวกเตอร์การหมุนปกติ แต่จะใช้พลังงานน้อยลง ใช้เซ็นเซอร์นี้ต่อเมื่อต้องการรวบรวมการหมุนเท่านั้น ข้อมูลในเบื้องหลังโดยไม่ต้องใช้แบตเตอรี่มากเกินไป เซ็นเซอร์นี้มีประโยชน์มากที่สุดเมื่อใช้ ร่วมกับการทำงานแบบกลุ่ม

โค้ดต่อไปนี้แสดงวิธีรับอินสแตนซ์ของเซ็นเซอร์เวกเตอร์การหมุนของสนามแม่เหล็กโลกเริ่มต้น

Kotlin

private lateinit var sensorManager: SensorManager
private var sensor: Sensor? = null
...
sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR)

Java

private SensorManager sensorManager;
private Sensor sensor;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR);

คำนวณการวางแนวของอุปกรณ์

ด้วยการคำนวณการวางแนวของอุปกรณ์ คุณสามารถตรวจสอบตำแหน่งของ ที่สัมพันธ์กับกรอบอ้างอิงของโลก (โดยเฉพาะอย่างยิ่ง แม่เหล็กไฟฟ้า ขั้วโลกเหนือ) รหัสต่อไปนี้แสดงวิธีการคำนวณ การวางแนว:

Kotlin

private lateinit var sensorManager: SensorManager
...
// Rotation matrix based on current readings from accelerometer and magnetometer.
val rotationMatrix = FloatArray(9)
SensorManager.getRotationMatrix(rotationMatrix, null, accelerometerReading, magnetometerReading)

// Express the updated rotation matrix as three orientation angles.
val orientationAngles = FloatArray(3)
SensorManager.getOrientation(rotationMatrix, orientationAngles)

Java

private SensorManager sensorManager;
...
// Rotation matrix based on current readings from accelerometer and magnetometer.
final float[] rotationMatrix = new float[9];
SensorManager.getRotationMatrix(rotationMatrix, null,
    accelerometerReading, magnetometerReading);

// Express the updated rotation matrix as three orientation angles.
final float[] orientationAngles = new float[3];
SensorManager.getOrientation(rotationMatrix, orientationAngles);

ระบบจะคำนวณมุมการวางแนวโดยใช้เซ็นเซอร์สนามแม่เหล็กโลกของอุปกรณ์ร่วมกับเครื่องวัดความเร่งของอุปกรณ์ การใช้ 2 อย่างนี้ เซ็นเซอร์ของฮาร์ดแวร์ ระบบจะให้ข้อมูลสำหรับ 3 สิ่งต่อไปนี้ มุมการวางแนว:

  • อาซิมุท (องศาการหมุนรอบแกน -z) นี่คือ มุมระหว่างทิศทางเข็มทิศปัจจุบันของอุปกรณ์และทิศเหนือของแม่เหล็ก หากขอบด้านบนของอุปกรณ์หันไปทางทิศเหนือแม่เหล็ก มุมเอียงจะเป็น 0 องศา หากขอบด้านบนหันไปทางทิศใต้ มุมเอียงจะเป็น 180 องศา ในทำนองเดียวกัน ถ้าขอบด้านบนหันไปทางทิศตะวันออก แอซิมัทจะเท่ากับ 90 องศา และถ้าขอบบน หันหน้าไปทางทิศตะวันตก ส่วนแอซิมัทอยู่ที่ 270 องศา
  • ระดับความสูงต่ำ (องศาการหมุนรอบแกน x) นี่คือ มุมระหว่างระนาบที่ขนานกับหน้าจอของอุปกรณ์กับระนาบขนาน ลงด้านล่าง หากคุณถืออุปกรณ์ให้ขนานกับพื้นโดยให้ขอบด้านล่างอยู่ใกล้คุณมากที่สุดและเอียงขอบด้านบนของอุปกรณ์ลงสู่พื้น มุมเอียงจะกลายเป็นบวก การเอียงไปในทิศทางตรงกันข้าม ซึ่งก็คือการเลื่อนขอบด้านบนของอุปกรณ์ให้ห่างจากพื้น จะทำให้มุมเอียงเป็นลบ ช่วงของค่าคือ -90 องศา ถึง 90 องศา
  • การพลิก (องศาการหมุนรอบแกน y) นี่คือ มุมระหว่างระนาบตั้งฉากกับหน้าจออุปกรณ์และระนาบ ตั้งฉากกับพื้น หากคุณถืออุปกรณ์ให้ขนานกับพื้นโดยให้ขอบด้านล่างอยู่ใกล้กับคุณมากที่สุดและเอียงขอบด้านซ้ายของอุปกรณ์ลงสู่พื้น มุมการกลิ้งจะเป็นค่าบวก การเอียงไปในทิศทางตรงกันข้าม ซึ่งก็คือการเลื่อนขอบด้านขวาของอุปกรณ์ลงสู่พื้น จะทำให้มุมการพลิกเป็นค่าลบ ช่วงของค่าคือ -180 องศาถึง 180 องศา

หมายเหตุ: คำจำกัดความของ Roll ของเซ็นเซอร์มีการเปลี่ยนแปลงเพื่อให้สอดคล้องกับการใช้งานส่วนใหญ่ในระบบนิเวศของเซ็นเซอร์ตรวจจับตำแหน่ง

โปรดสังเกตว่ามุมเหล่านี้ทำงานที่ระบบพิกัดต่างจากระบบพิกัด ใช้ในการบิน (สำหรับการเอียง ระดับเสียงสูง และการหมุน) ในระบบการบิน แกน x ตามแนวยาวของระนาบ ตั้งแต่หางไปจนถึงจมูก

เซ็นเซอร์ตรวจจับการวางแนวดึงข้อมูลมาจากการประมวลผลข้อมูลดิบของเซ็นเซอร์ จากตัวตรวจวัดความเร่งและเซ็นเซอร์สนามแม่เหล็กโลก เนื่องจากต้อง การประมวลผลที่เกี่ยวข้อง ตลอดจนความแม่นยำและความแม่นยำของการวางแนว เซ็นเซอร์ลดลง เซ็นเซอร์นี้เชื่อถือได้เฉพาะเวลาที่หมุน มุมเท่ากับ 0 ด้วยเหตุนี้ เราจึงเลิกใช้งานเซ็นเซอร์การวางแนวใน Android 2.2 (API ระดับ 8) และเลิกใช้งานประเภทเซ็นเซอร์การวางแนวใน Android 4.4W (API ระดับ 20) เราขอแนะนำให้คุณใช้เมธอด getRotationMatrix() ร่วมกับเมธอด getOrientation() เพื่อคํานวณค่าการวางแนวแทนการใช้ข้อมูลดิบจากเซ็นเซอร์การวางแนว ดังที่แสดงในตัวอย่างโค้ดต่อไปนี้ ในขั้นตอนนี้ คุณสามารถใช้วิธี remapCoordinateSystem() เพื่อแปลงค่าการวางแนวเป็นเฟรมอ้างอิงของแอปพลิเคชัน

Kotlin

class SensorActivity : Activity(), SensorEventListener {

    private lateinit var sensorManager: SensorManager
    private val accelerometerReading = FloatArray(3)
    private val magnetometerReading = FloatArray(3)

    private val rotationMatrix = FloatArray(9)
    private val orientationAngles = FloatArray(3)

    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main)
        sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
    }

    override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {
        // Do something here if sensor accuracy changes.
        // You must implement this callback in your code.
    }

    override fun onResume() {
        super.onResume()

        // Get updates from the accelerometer and magnetometer at a constant rate.
        // To make batch operations more efficient and reduce power consumption,
        // provide support for delaying updates to the application.
        //
        // In this example, the sensor reporting delay is small enough such that
        // the application receives an update before the system checks the sensor
        // readings again.
        sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)?.also { accelerometer ->
            sensorManager.registerListener(
                    this,
                    accelerometer,
                    SensorManager.SENSOR_DELAY_NORMAL,
                    SensorManager.SENSOR_DELAY_UI
            )
        }
        sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD)?.also { magneticField ->
            sensorManager.registerListener(
                    this,
                    magneticField,
                    SensorManager.SENSOR_DELAY_NORMAL,
                    SensorManager.SENSOR_DELAY_UI
            )
        }
    }

    override fun onPause() {
        super.onPause()

        // Don't receive any more updates from either sensor.
        sensorManager.unregisterListener(this)
    }

    // Get readings from accelerometer and magnetometer. To simplify calculations,
    // consider storing these readings as unit vectors.
    override fun onSensorChanged(event: SensorEvent) {
        if (event.sensor.type == Sensor.TYPE_ACCELEROMETER) {
            System.arraycopy(event.values, 0, accelerometerReading, 0, accelerometerReading.size)
        } else if (event.sensor.type == Sensor.TYPE_MAGNETIC_FIELD) {
            System.arraycopy(event.values, 0, magnetometerReading, 0, magnetometerReading.size)
        }
    }

    // Compute the three orientation angles based on the most recent readings from
    // the device's accelerometer and magnetometer.
    fun updateOrientationAngles() {
        // Update rotation matrix, which is needed to update orientation angles.
        SensorManager.getRotationMatrix(
                rotationMatrix,
                null,
                accelerometerReading,
                magnetometerReading
        )

        // "rotationMatrix" now has up-to-date information.

        SensorManager.getOrientation(rotationMatrix, orientationAngles)

        // "orientationAngles" now has up-to-date information.
    }
}

Java

public class SensorActivity extends Activity implements SensorEventListener {

    private SensorManager sensorManager;
    private final float[] accelerometerReading = new float[3];
    private final float[] magnetometerReading = new float[3];

    private final float[] rotationMatrix = new float[9];
    private final float[] orientationAngles = new float[3];

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        // Do something here if sensor accuracy changes.
        // You must implement this callback in your code.
    }

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

        // Get updates from the accelerometer and magnetometer at a constant rate.
        // To make batch operations more efficient and reduce power consumption,
        // provide support for delaying updates to the application.
        //
        // In this example, the sensor reporting delay is small enough such that
        // the application receives an update before the system checks the sensor
        // readings again.
        Sensor accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        if (accelerometer != null) {
            sensorManager.registerListener(this, accelerometer,
                SensorManager.SENSOR_DELAY_NORMAL, SensorManager.SENSOR_DELAY_UI);
        }
        Sensor magneticField = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
        if (magneticField != null) {
            sensorManager.registerListener(this, magneticField,
                SensorManager.SENSOR_DELAY_NORMAL, SensorManager.SENSOR_DELAY_UI);
        }
    }

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

        // Don't receive any more updates from either sensor.
        sensorManager.unregisterListener(this);
    }

    // Get readings from accelerometer and magnetometer. To simplify calculations,
    // consider storing these readings as unit vectors.
    @Override
    public void onSensorChanged(SensorEvent event) {
        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
          System.arraycopy(event.values, 0, accelerometerReading,
              0, accelerometerReading.length);
        } else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
            System.arraycopy(event.values, 0, magnetometerReading,
                0, magnetometerReading.length);
        }
    }

    // Compute the three orientation angles based on the most recent readings from
    // the device's accelerometer and magnetometer.
    public void updateOrientationAngles() {
        // Update rotation matrix, which is needed to update orientation angles.
        SensorManager.getRotationMatrix(rotationMatrix, null,
            accelerometerReading, magnetometerReading);

        // "rotationMatrix" now has up-to-date information.

        SensorManager.getOrientation(rotationMatrix, orientationAngles);

        // "orientationAngles" now has up-to-date information.
    }
}

โดยปกติแล้วคุณไม่จำเป็นต้องประมวลผลข้อมูลหรือกรองข้อมูล มุมการวางแนวของอุปกรณ์ดิบนอกเหนือจากการแปลเซ็นเซอร์ กับกรอบอ้างอิงของแอปพลิเคชันของคุณ

ใช้เซ็นเซอร์สนามแม่เหล็กโลก

เซ็นเซอร์สนามแม่เหล็กไฟฟ้าช่วยให้คุณตรวจสอบการเปลี่ยนแปลงของสนามแม่เหล็กโลกได้ โค้ดต่อไปนี้แสดงวิธีรับอินสแตนซ์ของเซ็นเซอร์สนามแม่เหล็กไฟฟ้าเริ่มต้น

Kotlin

private lateinit var sensorManager: SensorManager
private var sensor: Sensor? = null
...
sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD)

Java

private SensorManager sensorManager;
private Sensor sensor;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);

หมายเหตุ: หากแอปกำหนดเป้าหมายเป็น Android 12 (API ระดับ 31) ขึ้นไป เซ็นเซอร์นี้จะจำกัดอัตรา

เซ็นเซอร์นี้จะให้ข้อมูลความแรงของสนามแม่เหล็กดิบ (ใน μT) สำหรับแกนพิกัดทั้ง 3 แกน โดยปกติแล้ว คุณไม่จำเป็นต้องใช้เซ็นเซอร์นี้โดยตรง แต่คุณใช้เซ็นเซอร์เวกเตอร์การหมุนเพื่อระบุการเคลื่อนไหวแบบหมุนดิบ หรือใช้ตัวตรวจวัดความเร่งและเซ็นเซอร์สนามแม่เหล็กโลกร่วมกับเมธอด getRotationMatrix() เพื่อรับเมทริกซ์การหมุนและเมทริกซ์ความลาดเอียงแทนได้ จากนั้นคุณสามารถใช้เมทริกซ์เหล่านี้กับวิธีการ getOrientation() และ getInclination() เพื่อรับข้อมูลแนวราบและแนวเอียงของสนามแม่เหล็กโลก

หมายเหตุ: เมื่อทดสอบแอป คุณสามารถปรับปรุงความแม่นยำของเซ็นเซอร์ได้โดยโบกอุปกรณ์เป็นเลข 8

ใช้เครื่องวัดค่าความเข้มข้นของสนามแม่เหล็กที่ไม่ได้ปรับเทียบ

เครื่องวัดค่าความเข้มข้นของสนามแม่เหล็กที่ไม่ได้ปรับเทียบจะคล้ายกับเซ็นเซอร์สนามแม่เหล็กโลก ยกเว้นว่าไม่มีการปรับเทียบสนามแม่เหล็กด้วยเหล็กแข็ง การปรับเทียบจากโรงงานและการชดเชยอุณหภูมิจะยังคงมีผลกับสนามแม่เหล็ก แมกนีตometers ที่ไม่ได้ปรับเทียบมีประโยชน์ในการจัดการการประมาณเหล็กแข็งที่ไม่ดี โดยทั่วไป geomagneticsensor_event.values[0] จะใกล้กับ uncalibrated_magnetometer_event.values[0] - uncalibrated_magnetometer_event.values[3] กล่าวคือ

calibrated_x ~= uncalibrated_x - bias_estimate_x

หมายเหตุ: เซ็นเซอร์ที่ไม่ได้ปรับเทียบจะให้ผลลัพธ์ดิบมากกว่าและอาจมีค่าเบี่ยงเบนบ้าง แต่การวัดค่าจะมีความผันผวนน้อยกว่าจากการแก้ไขที่ใช้การปรับเทียบ แอปพลิเคชันบางอย่างอาจชอบผลลัพธ์ที่ไม่มีการปรับเทียบเหล่านี้ ซึ่งมีความราบรื่นและมากกว่า เชื่อถือได้ ตัวอย่างเช่น หากแอปพลิเคชันพยายามดำเนินการฟิวชันเซ็นเซอร์ของตนเอง การเริ่มใช้การปรับเทียบอาจทำให้ผลลัพธ์ผิดเพี้ยนไปได้

นอกจากสนามแม่เหล็กแล้ว เครื่องมือวัดสนามแม่เหล็กที่ไม่ได้ปรับเทียบยังแสดงค่าความเบี่ยงเบนของเหล็กแข็งโดยประมาณในแต่ละแกนด้วย โค้ดต่อไปนี้แสดงวิธีรับอินสแตนซ์ของ เครื่องวัดค่าความเข้มข้นของสนามแม่เหล็กเริ่มต้นที่ไม่มีการปรับเทียบ:

Kotlin

private lateinit var sensorManager: SensorManager
private var sensor: Sensor? = null
...
sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED)

Java

private SensorManager sensorManager;
private Sensor sensor;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED);

ใช้พร็อกซิมิตีเซ็นเซอร์

พร็อกซิมิตีเซ็นเซอร์ช่วยให้คุณทราบว่าวัตถุอยู่ห่างจากอุปกรณ์เท่าใด โค้ดต่อไปนี้แสดงวิธีรับอินสแตนซ์ของเซ็นเซอร์ตรวจหาบุคคลในบริเวณใกล้เคียงเริ่มต้น

Kotlin

private lateinit var sensorManager: SensorManager
private var sensor: Sensor? = null
...
sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY)

Java

private SensorManager sensorManager;
private Sensor sensor;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);

เซ็นเซอร์ตรวจหาบุคคลในบริเวณใกล้เคียงมักใช้เพื่อระบุระยะห่างระหว่างศีรษะของบุคคลกับหน้าของอุปกรณ์มือถือ (เช่น เมื่อผู้ใช้กำลังโทรออกหรือรับสาย) เซ็นเซอร์ตรวจหาบุคคลส่วนใหญ่จะแสดงผลระยะทางสัมบูรณ์เป็น cm แต่บางรุ่นจะแสดงเฉพาะค่าใกล้และไกล

หมายเหตุ: พร็อกซิมิตีเซ็นเซอร์ในอุปกรณ์บางรุ่นจะอยู่ ใต้หน้าจอ ซึ่งอาจทำให้มีจุดกะพริบปรากฏขึ้นบนหน้าจอหากเปิดใช้ขณะที่หน้าจออยู่ เปิดอยู่

โค้ดต่อไปนี้แสดงวิธีใช้เซ็นเซอร์ตรวจหาบุคคลในบริเวณใกล้เคียง

Kotlin

class SensorActivity : Activity(), SensorEventListener {

    private lateinit var sensorManager: SensorManager
    private var proximity: Sensor? = null

    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main)

        // Get an instance of the sensor service, and use that to get an instance of
        // a particular sensor.
        sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
        proximity = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY)
    }

    override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {
        // Do something here if sensor accuracy changes.
    }

    override fun onSensorChanged(event: SensorEvent) {
        val distance = event.values[0]
        // Do something with this sensor data.
    }

    override fun onResume() {
        // Register a listener for the sensor.
        super.onResume()

        proximity?.also { proximity ->
            sensorManager.registerListener(this, proximity, SensorManager.SENSOR_DELAY_NORMAL)
        }
    }

    override fun onPause() {
        // Be sure to unregister the sensor when the activity pauses.
        super.onPause()
        sensorManager.unregisterListener(this)
    }
}

Java

public class SensorActivity extends Activity implements SensorEventListener {
    private SensorManager sensorManager;
    private Sensor proximity;

    @Override
    public final void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // Get an instance of the sensor service, and use that to get an instance of
        // a particular sensor.
        sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        proximity = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
    }

    @Override
    public final void onAccuracyChanged(Sensor sensor, int accuracy) {
        // Do something here if sensor accuracy changes.
    }

    @Override
    public final void onSensorChanged(SensorEvent event) {
        float distance = event.values[0];
        // Do something with this sensor data.
    }

    @Override
    protected void onResume() {
        // Register a listener for the sensor.
        super.onResume();
        sensorManager.registerListener(this, proximity, SensorManager.SENSOR_DELAY_NORMAL);
      }

    @Override
    protected void onPause() {
        // Be sure to unregister the sensor when the activity pauses.
        super.onPause();
        sensorManager.unregisterListener(this);
    }
}

หมายเหตุ: พร็อกซิมิตีเซ็นเซอร์บางตัวจะแสดงผลค่าฐานสองที่แสดงถึง "ใกล้" หรือ "ไกล" ในกรณีนี้ เซ็นเซอร์มักจะรายงานค่าช่วงสูงสุดในสถานะ "ไกล" และค่าที่น้อยกว่าในสถานะ "ใกล้" โดยปกติแล้วค่าไกลคือค่าที่มากกว่า 5 ซม. แต่ค่านี้อาจแตกต่างกันไปในแต่ละเซ็นเซอร์ คุณระบุระยะสัญญาณสูงสุดของเซ็นเซอร์ได้โดยใช้เมธอด getMaximumRange()

คุณควรอ่าน