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

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

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

ننصحك أيضًا بقراءة