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

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

ملاحظة: تم إيقاف أداة استشعار الاتجاه نهائيًا في Android 2.2 (المستوى 8 من واجهة برمجة التطبيقات)، وتم إيقاف نوع أداة استشعار الاتجاه نهائيًا في Android 4.4W (المستوى 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] شدة المجال المغناطيسي الأرضي (بدون معايرة الحديد الصلب) على طول المحور س. μ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] الدوران (الزاوية حول المحور y).
TYPE_PROXIMITY SensorEvent.values[0] المسافة من العنصر2 سم

1تم إيقاف أداة الاستشعار هذه نهائيًا في الإصدار 2.2 من نظام التشغيل Android (واجهة برمجة التطبيقات). المستوى 8)، وتم إيقاف نوع أداة الاستشعار هذا في Android 4.4W (مستوى واجهة برمجة التطبيقات 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);

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

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

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

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

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

ملاحظة: إذا كان تطبيقك يستهدف الإصدار 12 من نظام التشغيل Android (المستوى 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().

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