أجهزة استشعار الموضع

يوفّر نظام Android الأساسي جهازَي استشعار يتيحان لك تحديد موضع الجهاز، وهما أداة استشعار المجال المغناطيسي الأرضي ومقياس التسارع. توفّر منصة Android أيضًا أداة استشعار تتيح لك تحديد مدى قرب شاشة الجهاز من جسم معيّن (يُعرف ذلك باسم أداة استشعار التقارب). يستند مستشعر الحقل المغناطيسي الأرضي ومستشعر التقارب إلى الأجهزة. تضيف معظم الشركات المصنّعة للهواتف الجوّالة والأجهزة اللوحية أداة استشعار المجال المغناطيسي الأرضي. وبالمثل، عادةً ما يضيف مصنعو الهواتف المحمولة أداة استشعار التقارب لتحديد الحالات التي يتم فيها تثبيت الهاتف المحمول بالقرب من وجه المستخدم (على سبيل المثال، أثناء مكالمة هاتفية). ولتحديد اتجاه الجهاز، يمكنك استخدام القراءات التي يعرضها مقياس التسارع وجهاز استشعار المجال المغناطيسي الجغرافي.

ملاحظة: تم إيقاف أداة استشعار الاتجاه نهائيًا في الإصدار Android 2.2 (مستوى واجهة برمجة التطبيقات 8)، وتم إيقاف نوع أداة استشعار الاتجاه نهائيًا في الإصدار 4.4W من نظام التشغيل Android (مستوى واجهة برمجة التطبيقات 20).

تكون أدوات استشعار الموقع الجغرافي مفيدة لتحديد الموقع الجغرافي للجهاز في الإطار المرجعي العالمي. على سبيل المثال، يمكنك استخدام أداة استشعار الحقل المغناطيسي الجغرافي مع مقياس التسارع لتحديد موضع الجهاز بالنسبة إلى القطب الشمالي المغناطيسي. يمكنك أيضًا استخدام أجهزة الاستشعار هذه لتحديد اتجاه الجهاز في إطار مرجعي لتطبيقك. لا تُستخدَم عادةً أدوات استشعار الموقع لرصد حركة الجهاز، مثل الاهتزاز أو الميل أو الدفع (لمزيد من المعلومات، يُرجى الاطّلاع على أجهزة استشعار الحركة).

يعرض كلّ من أداة استشعار الحقل المغناطيسي الأرضي ومقياس التسارع صفائف متعددة الأبعاد لقيم أداة الاستشعار لكل SensorEvent. على سبيل المثال، يقدّم قياس الحقل المغناطيسي الأرضي قيمًا لمعدّل شدّة الحقل المغناطيسي لكلّ من محاور الإحداثيات الثلاثة أثناء حدث قياس واحد. وبالمثل، يقيس مقياس التسارع التسارع الذي يُطبَّق على الجهاز أثناء حدث أداة الاستشعار. لمزيد من المعلومات عن أنظمة الإحداثيات التي تستخدمها أجهزة الاستشعار، يُرجى الاطّلاع على أنظمة إحداثيات أجهزة الاستشعار. يقدّم أداة استشعار التقارب قيمة واحدة لكل حدث من أحداث أداة الاستشعار. يلخّص الجدول 1 أدوات استشعار الموقع الجغرافي التي تتوفّر على نظام Android الأساسي.

الجدول 1: أدوات استشعار الموقع الجغرافي المتوافقة مع نظام التشغيل Android

أداة استشعار بيانات أحداث أجهزة الاستشعار الوصف وحدات القياس
TYPE_GAME_ROTATION_VECTOR SensorEvent.values[0] مكوّن متجه الدوران على محور x (x * sin(θ/2)) بدون وحدة
SensorEvent.values[1] مكوّن متجّه الالتفاف على طول محور ص (ص * sin(θ/2))
SensorEvent.values[2] مكوّن متجه الالتفاف على محور z (z * sin(θ/2))
TYPE_GEOMAGNETIC_ROTATION_VECTOR SensorEvent.values[0] مكوّن متجه الدوران على محور x (x * sin(θ/2)) بدون وحدة
SensorEvent.values[1] مكوّن متجّه الالتفاف على طول محور ص (ص * 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] شدة المجال المغناطيسي الأرضي (بدون معايرة الحديد الصلب) على طول المحور ص.
SensorEvent.values[2] شدة المجال المغناطيسي الأرضي (بدون معايرة الحديد الصلب) على طول محور z
SensorEvent.values[3] تقدير الانحياز الحديدي على طول محور x
SensorEvent.values[4] تقدير تحيز الحديد على طول المحور ص.
SensorEvent.values[5] تقدير الانحياز الحديدي على طول محور z
TYPE_ORIENTATION1 SensorEvent.values[0] السمت (زاوية حول المحور z). الدرجات
SensorEvent.values[1] الانحدار (الزاوية حول المحور x)
SensorEvent.values[2] الدوران (الزاوية حول المحور الصادي)
TYPE_PROXIMITY SensorEvent.values[0] المسافة من العنصر2 سم

1تم إيقاف هذا المستشعر نهائيًا في Android 2.2 (المستوى 8 لواجهة برمجة التطبيقات)، وتم إيقاف نوع هذا المستشعر نهائيًا في Android 4.4W (المستوى 20 لواجهة برمجة التطبيقات). يوفّر إطار عمل أداة الاستشعار طرقًا بديلة للحصول على اتجاه الجهاز، والتي تتم مناقشتها في مقالة احتساب اتجاه الجهاز.

2 لا توفر بعض أدوات استشعار التقارب سوى قيمًا ثنائية تمثل القيم القريبة والبعيدة فقط.

استخدام أداة استشعار متجه دوران اللعبة

إنّ أداة استشعار اتجاه دوران اللعبة متطابقة مع أداة استشعار اتجاه الدوران، باستثناء أنّها لا تستخدِم الحقل المغناطيسي الأرضي. وبالتالي، لا يشير محور Y إلى الشمال، بل إلى مرجع آخر. يُسمح لهذا المرجع بالتحرك بنفس ترتيب المقدار الذي ينحرف فيه الجيروسكوب حول المحور Z.

ولأنّ أداة استشعار متجه دوران اللعبة لا تستخدِم الحقل المغناطيسي، تكون الدورات النسبية أكثر دقة ولا تتأثر بتغييرات الحقل المغناطيسي. استخدِم هذا المستشعر في لعبة إذا لم تكن مهتمًا باتجاه الشمال، ولم يكن متجه الالتفاف العادي يناسب احتياجاتك بسبب اعتماده على الحقل المغناطيسي.

يوضّح لك الرمز التالي كيفية الحصول على مثيل لمتجه اتجاه الدوران التلقائي في اللعبة sensor:

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);

يحتسب النظام زوايا الاتجاه باستخدام أداة استشعار المجال المغناطيسي الجغرافي في الجهاز مع مقياس التسارع في الجهاز. باستخدام هذين أداة الاستشعار، يقدّم النظام بيانات عن زوايا الميل التالية:

  • السمت (درجات الدوران حول المحور -z). هذه هي الزاوية بين اتجاه بوصلة الجهاز الحالي والاتجاه الشمالي المغناطيسي. إذا كانت الحافة العلوية للجهاز مواجهة للشمال المغناطيسي، تكون الزاوية المحورية 0 درجة، وإذا كانت الحافة العلوية مواجهة للجنوب، تكون الزاوية المحورية 180 درجة. وبالمثل، إذا كانت الحافة العلوية مواجهة الشرق، تكون الزاوية سمتية 90 درجة، وإذا كانت الحافة العلوية مواجهة الغرب، تكون الزاوية سمتية 270 درجة.
  • الميل (درجات الدوران حول محور x) هذه هي الزاوية بين مستوى موازٍ لشاشة الجهاز وسطح موازٍ للأرض. إذا مسكْت الجهاز بشكل موازٍ للأرض مع توجيه الحافة السفلية إليك، ثم إمالة الحافة العلوية للجهاز باتجاه الأرض، سيصبح زاوية الميل موجبة. يؤدي الميل في الاتجاه المقابل، وهو تحريك الحافة العلوية للجهاز بعيدًا عن الأرض، إلى أن يصبح زاوية الميل سالبة. يتراوح نطاق القيم بين -90 درجة و 90 درجة.
  • اللف (درجات الدوران حول المحور ص) هذه هي الزاوية بين سطح مستوٍ عمودي على شاشة الجهاز وسطح مستوٍ عمودي على الأرض. إذا كنت تمسك بالجهاز بشكل موازٍ للأرض مع وضع الحافة السفلية بالقرب منك وإمالة الحافة اليسرى للجهاز نحو الأرض، تصبح زاوية الدوران موجبة. عند الميل في الاتجاه противоположном الذي يتمثل في تحريك الحافة اليمنى للجهاز نحو الأرض، يؤدي ذلك إلى أن تصبح زاوية الانحراف سالبة. يتراوح نطاق القيم بين -180 درجة و180 درجة.

ملاحظة: تم تغيير تعريف الدوران في أداة الاستشعار ليعكس الغالبية العظمى من عمليات التنفيذ في النظام البيئي لأجهزة الاستشعار الجغرافية.

يُرجى العلم أنّ هذه الزوايا تعمل وفقًا لنظام إحداثيات مختلف عن النظام المستخدَم في الطيران (للانحراف والانحدار والدوران). في نظام الطيران، يقع المحور x على طول الجانب الطويل للطائرة، من الذيل إلى الأنف.

يحصل جهاز استشعار الاتجاه على بياناته من خلال معالجة بيانات الاستشعار الأولية من أداة قياس السرعة وجهاز استشعار الحقل المغناطيسي الأرضي. تقلّ دقة أداة استشعار الاتجاه ودقتها بسبب المعالجة الكبيرة التي يتم إجراؤها عليها. وعلى وجه التحديد، لا يمكن الاعتماد على هذا الجهاز إلا عندما تساوي زاوية اللفّة 0. نتيجةً لذلك، تم إيقاف أداة استشعار الاتجاه نهائيًا في الإصدار 2.2 من نظام التشغيل Android (المستوى 8 لواجهة برمجة التطبيقات)، وتم إيقاف نوع أداة استشعار الاتجاه نهائيًا في الإصدار 4.4W من نظام التشغيل Android (المستوى 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 (المستوى 31 لواجهة برمجة التطبيقات) أو الإصدارات الأحدث، تكون أداة الاستشعار هذه محدودة للمعدل.

يقدّم هذا المستشعر بيانات القوة الخام للحقل (بالميكرو تسلا) لكل محور من محاور الإحداثيات الثلاثة. لا تحتاج عادةً إلى استخدام أداة الاستشعار هذه مباشرةً. بدلاً من ذلك، يمكنك استخدام أداة استشعار اتجاه الدوران لتحديد الحركة الدورانية الأولية أو يمكنك استخدام أداة استشعار مقياس التسارع والحقل المغناطيسي الأرضي مع طريقة getRotationMatrix() للحصول على مصفوفة الدوران ومصفوفة الميل. يمكنك بعد ذلك استخدام هذه المصفوفات مع الطريقتَين getOrientation() وgetInclination() للحصول على بيانات الزاوية الأفقية والميل المغناطيسي الأرضي.

ملاحظة: عند اختبار تطبيقك، يمكنك تحسين دقة أداة الاستشعار من خلال تلويح الجهاز بحركة رقم 8.

استخدام مقياس المغناطيسية الذي لم تتم معايرته

يشبه مقياس المغناطيسية الذي لم تتم معايرته جهاز استشعار المجال المغناطيسي الأرضي، باستثناء أنّه لا يتم تطبيق معايرة الحديد الصلب على المجال المغناطيسي. لا تزال عملية المعايرة التي تم إجراؤها في المصنع وعملية مُعدِّل الحرارة سارية على الحقل المغناطيسي. إنّ مقياس المغناطيسية غير المعاير مفيد للتعامل مع تقديرات الحديد الصلب الخاطئة. بشكل عام، سيكون 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);

يُستخدَم عادةً جهاز استشعار التقارب لتحديد المسافة بين رأس الشخص ووجه جهاز الهاتف (على سبيل المثال، عندما يجري المستخدم مكالمة هاتفية أو يتلقّاها). تعرِض معظم أدوات قياس كثافة الاشعة تحت الحمراء المسافة المطلقة، بالسنتيمتر، ولكن بعضها لا تعرِض سوى قيم "قريب" و"بعيد".

ملاحظة: في بعض طُرز الأجهزة، يكون أداة استشعار التقارب تحت الشاشة، ما قد يؤدي إلى ظهور نقطة وامض على الشاشة في حال تفعيلها عندما تكون الشاشة مفعَّلة.

يوضّح لك الرمز التالي كيفية استخدام أداة استشعار التقارب:

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().

يجب عليك أيضًا قراءة