Sensors API: ما هي، أنواع الحساسات والعمل مع المستشعرات

المؤلف: IT Sectr نُشر: 2026-03-26 وقت القراءة: 10 دق

Sensors API هي واجهة منصة Android للوصول إلى مستشعرات الأجهزة. توفر API طريقة موحدة للحصول على البيانات من مقياس التسارع، الجيروسكوب، مقياس المغناطيسية، مستشعر الضوء وغيرها من المستشعرات. وفقًا لـ Google, 2026، أكثر من 95% من أجهزة Android الحديثة مزودة بثلاثة أنواع على الأقل من المستشعرات، مما يفتح فرصًا واسعة لتطوير تطبيقات حساسة للسياق.

النقاط الرئيسية

  • Sensors API — واجهة Android موحدة للعمل مع مستشعرات الأجهزة.
  • ثلاث فئات — مستشعرات Motion وPosition وEnvironment بمبادئ قياس مختلفة.
  • SensorManager — خدمة نظام للحصول على قائمة المستشعرات وتسجيل المستمعين.
  • معدل التحديث يتم تعيينه عبر ثوابت SENSOR_DELAY من NORMAL إلى FASTEST.
  • المستشعرات الافتراضية — Gravity وRotation Vector وLinear Acceleration تعتمد على مزيج من المستشعرات المادية.

ما هو Sensors API في Android؟

Sensors API هي واجهة برمجية لإطار عمل Android توفر للمطورين الوصول إلى مستشعرات الأجهزة للجهاز المحمول. API جزء من Android SDK منذ الإصدار 1.0 ومتاح عبر حزمة android.hardware. تقوم الواجهة بتجريد الاختلافات بين تطبيقات المستشعرات من مختلف المصنعين — Qualcomm وMediaTek وSamsung Exynos — وتوفر نموذجًا موحدًا للعمل مع المستشعرات.

الميزات الرئيسية لـ Sensors API

تتيح API ثلاث عمليات رئيسية: الحصول على قائمة بالمستشعرات المتاحة، وتسجيل المستمعين لتلقي البيانات، وإدارة معدل التحديث. SensorManager يعمل كنقطة وصول مركزية لجميع العمليات. يقوم النظام بإخطار التطبيق عبر رد الاتصال onSensorChanged، ويمرر كائن SensorEvent بمصفوفة من قيم float.

تطور Sensors API

على مدار وجود Android، مرت API بعدة مراحل من التطوير. الإصدار 2.3 (Gingerbread) قدم دعم المعالجة المجمعة — تجميع أحداث المستشعر لتقليل استهلاك الطاقة. Android 4.0 (Ice Cream Sandwich) أضاف المستشعرات الافتراضية Gravity وLinear Acceleration. بدءًا من Android 8.0، قام النظام بتقييد الوصول الخلفي إلى المستشعرات لتعزيز الخصوصية.

kotlin
val sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
val sensorList: List<Sensor> = sensorManager.getSensorList(Sensor.TYPE_ALL)
sensorList.forEach { sensor ->
    Log.d("المستشعرات", "${sensor.name} — ${sensor.type}")
}

القيود والمتطلبات

ليست كل الأجهزة لديها نفس مجموعة المستشعرات. يجب على التطبيق التحقق من توفر مستشعر معين قبل تسجيل مستمع. محاكي Android يدعم فقط مجموعة محدودة من المستشعرات — مقياس التسارع ومقياس المغناطيسية. اختبار المستشعرات الأخرى يتطلب جهازًا فعليًا. بدءًا من Android 12، يجب على التطبيقات الإعلان عن استخدام المستشعرات في البيان.

أنواع مستشعرات Android: Motion, Position, Environment

يصنف Android جميع المستشعرات إلى ثلاث فئات: Motion وPosition وEnvironment. مستشعرات Motion تشمل مقياس التسارع والجيروسكوب وعداد الخطى. مستشعرات Position تشمل مقياس المغناطيسية والتوجيه. مستشعرات Environment تشمل الضوء والضغط ودرجة الحرارة والرطوبة.

الفئةالمستشعراتالنوع (ثابت)مادي/افتراضي
Motionمقياس التسارعTYPE_ACCELEROMETERمادي
MotionالجيروسكوبTYPE_GYROSCOPEمادي
Motionعداد الخطىTYPE_STEP_COUNTERمادي
MotionGravityTYPE_GRAVITYافتراضي
Positionمقياس المغناطيسيةTYPE_MAGNETIC_FIELDمادي
PositionRotation VectorTYPE_ROTATION_VECTORافتراضي
EnvironmentالضوءTYPE_LIGHTمادي
EnvironmentالضغطTYPE_PRESSUREمادي

مستشعرات Motion: مقياس التسارع والجيروسكوب

مقياس التسارع يقيس التسارع بوحدة م/ث² على طول ثلاثة محاور — X وY وZ. تشمل القيم الجاذبية (9.8 م/ث² على طول المحور Z في حالة السكون). يقيس الجيروسكوب السرعة الزاوية بوحدة راد/ث — سرعة دوران الجهاز حول كل محور. يُستخدم مزيج هذين المستشعرين في الملاحة والألعاب وتطبيقات الواقع المعزز.

kotlin
class SensorActivity : Activity(), SensorEventListener {
    override fun onSensorChanged(event: SensorEvent) {
        if (event.sensor.type == Sensor.TYPE_ACCELEROMETER) {
            val x = event.values[0]
            val y = event.values[1]
            val z = event.values[2]
            textView.text = "X: $x, Y: $y, Z: $z"
        }
    }
    override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {}
}

مستشعرات Position: مقياس المغناطيسية والتوجيه

مقياس المغناطيسية (TYPE_MAGNETIC_FIELD) يقيس المجال المغناطيسي بوحدة ميكروتسلا (µT) على طول ثلاثة محاور. يُستخدم كبوصلة رقمية — بالاقتران مع مقياس التسارع، يحدد سمت الجهاز. Rotation Vector هو مستشعر افتراضي يدمج بيانات الجيروسكوب ومقياس التسارع ومقياس المغناطيسية لتحديد دقيق للتوجيه.

مستشعرات Environment: الضوء والضغط ودرجة الحرارة

مستشعر الضوء (TYPE_LIGHT) يقيس مستوى الإضاءة المحيطة بوحدة لوكس (lx). يُستخدم للضبط التلقائي لسطوع الشاشة. مستشعر الضغط (TYPE_PRESSURE) يقيس الضغط الجوي بوحدة هيكتوباسكال (hPa) — يُستخدم في تطبيقات الملاحة لتحديد الارتفاع فوق مستوى سطح البحر.

كيف تعمل بنية Sensors API

Sensors API مبني على بنية خادم-عميل. يعمل التطبيق كعميل، وSensorManager كخدمة نظام Android. عندما يسجل التطبيق مستمعًا عبر registerListener، يتواصل SensorManager مع HAL (طبقة تجريد الأجهزة) — برنامج تشغيل مستشعر منخفض المستوى يعمل على مستوى نواة Linux.

دورة حياة حدث المستشعر

يتلقى برنامج تشغيل HAL بيانات خام من شريحة الأجهزة، ويصفي الضوضاء، وينقلها لأعلى المكدس — عبر SensorService (عملية نظام) إلى التطبيق. تُنقل البيانات ككائن SensorEvent يحتوي على مصفوفة من قيم float values وطابع زمني بالنانو ثانية. يعتمد معدل الأحداث على وضع التسليم المحدد.

أوضاع تسليم الأحداث

عند تسجيل مستمع، يحدد المطور التأخير المطلوب بين الأحداث باستخدام الثوابت SENSOR_DELAY_NORMAL (200 مللي ثانية) وSENSOR_DELAY_UI (60 مللي ثانية) وSENSOR_DELAY_GAME (20 مللي ثانية) وSENSOR_DELAY_FASTEST (0 مللي ثانية — أقصى معدل). قد يختلف المعدل الفعلي — يقوم النظام بتحسين استهلاك الطاقة.

kotlin
val sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
sensorManager.registerListener(
    this,
    sensor,
    SensorManager.SENSOR_DELAY_GAME
)

المعالجة المجمعة (Batch Processing)

بدءًا من Android 2.3، تدعم المستشعرات الوضع المجمع — تتراكم الأحداث في مخزن FIFO ويتم تسليمها في دفعة واحدة. يسمح ذلك للمعالج بالبقاء في وضع السكون لفترة أطول، مما يقلل استهلاك الطاقة بنسبة تصل إلى 60%. يعتمد حجم المخزن على شريحة المستشعر ويتم تحديده في الحقل Sensor.fifoMaxEventCount.

استخدام SensorManager للوصول إلى المستشعرات

SensorManager هي خدمة نظام متاحة عبر getSystemService(Context.SENSOR_SERVICE). توفر طرقًا للحصول على قائمة المستشعرات، والحصول على مستشعر افتراضي معين، وتسجيل/إلغاء تسجيل المستمعين. SensorManager هو مفرد — مثيل واحد للتطبيق بأكمله.

التحقق من توفر المستشعر

قبل استخدام المستشعر، يجب التحقق من توفره. الطريقة getDefaultSensor(type) تعيد null إذا كان المستشعر غير موجود على الجهاز. الحصول على null دون تحقق سيؤدي إلى NullPointerException عند تسجيل المستمع. الطريقة getSensorList(type) تعيد قائمة بجميع المستشعرات.

kotlin
fun checkSensorAvailability(type: Int): Boolean {
    val sensorManager =
        getSystemService(Context.SENSOR_SERVICE) as SensorManager
    return sensorManager.getDefaultSensor(type) != null
}

// الاستخدام:
if (checkSensorAvailability(Sensor.TYPE_GYROSCOPE)) {
    Log.d("مستشعر", "الجيروسكوب متاح")
}

تسجيل وإلغاء تسجيل المستمع

يتم تسجيل المستمع عبر registerListener(listener, sensor, delay). مهم: يجب إلغاء تسجيل المستمع في طريقة onPause() عبر unregisterListener(listener). إذا لم يتم ذلك، سيستمر التطبيق في تلقي أحداث المستشعر، مما يستنزف البطارية حتى في الخلفية. يعرض Android 8+ تحذيرًا في logcat حول المستمعين غير المسجلين.

معالجة تغيرات الدقة

يتم استدعاء طريقة onAccuracyChanged(sensor, accuracy) عندما تتغير دقة المستشعر. القيم: SENSOR_STATUS_ACCURACY_HIGH وMEDIUM وLOW وUNRELIABLE. عند استلام UNRELIABLE، يجب تجاهل بيانات المستشعر حتى استعادة الدقة. على سبيل المثال، يتطلب مقياس المغناطيسية معايرة — هز الجهاز على شكل ثمانية.

أمثلة كود للعمل مع المستشعرات بلغة Kotlin

دعونا نلقي نظرة على أمثلة عملية لاستخدام Sensors API في تطبيقات Android بلغة Kotlin. المثال الأول — تحديد اتجاه الشاشة باستخدام مقياس التسارع. الثاني — قراءة بيانات مقياس المغناطيسية مع المعايرة. الثالث — كاشف الخطى باستخدام عداد الخطى.

تحديد اتجاه الجهاز

يتم استخدام مزيج من مقياس التسارع ومقياس المغناطيسية لتحديد الاتجاه. الطريقة SensorManager.getRotationMatrix() تحسب مصفوفة التدوير، وgetOrientation() تستخرج زوايا الميل واللف والسمت. السمت — الزاوية بالنسبة للشمال المغناطيسي بالراديان.

kotlin
val gravity = FloatArray(3)
val geomagnetic = FloatArray(3)
val rotationMatrix = FloatArray(9)
val orientation = FloatArray(3)

SensorManager.getRotationMatrix(
    rotationMatrix, null, gravity, geomagnetic
)
SensorManager.getOrientation(rotationMatrix, orientation)
// orientation[0] — azimuth, [1] — pitch, [2] — roll
val azimuthDeg = Math.toDegrees(orientation[0].toDouble())

كاشف الخطى باستخدام عداد الخطى

عداد الخطى (TYPE_STEP_COUNTER) يعيد إجمالي عدد الخطوات التي قام بها المستخدم منذ آخر إعادة تشغيل للجهاز. يعمل المستشعر على مستوى الأجهزة — يكون نشطًا حتى عندما لا يكون التطبيق قيد التشغيل. للحصول على الخطوات لكل جلسة، تحتاج إلى حفظ القيمة الأولية وحساب الفرق.

kotlin
var initialSteps = 0
var isInitialized = false

override fun onSensorChanged(event: SensorEvent) {
    if (event.sensor.type == Sensor.TYPE_STEP_COUNTER) {
        if (!isInitialized) {
            initialSteps = event.values[0].toInt()
            isInitialized = true
        }
        val currentSteps = event.values[0].toInt()
        val sessionSteps = currentSteps - initialSteps
        Log.d("الخطوات", "الخطوات لكل جلسة: $sessionSteps")
    }
}

السطوع التكيفي باستخدام مستشعر الضوء

يتيح مستشعر الضوء تكييف الواجهة مع ظروف البيئة. في الإضاءة المنخفضة (أقل من 10 لوكس)، يمكنك التبديل إلى الوضع الداكن. في ضوء الشمس الساطع (أكثر من 10000 لوكس)، يمكنك زيادة التباين. يتم استخدام متوسط متحرك لآخر 5 قيم لتصفية الضوضاء.

المستشعرات الافتراضية وخوارزميات الدمج

يوفر Android العديد من المستشعرات الافتراضية التي ليس لها مقابل مادي مباشر. المستشعر الافتراضي يحسب قراءاته بناءً على مزيج من المستشعرات المادية. يقلل هذا العبء على المطور — النظام نفسه ينفذ خوارزميات دمج البيانات.

Gravity وLinear Acceleration

مستشعر Gravity (TYPE_GRAVITY) يستخرج المكون الجاذبي من قراءات مقياس التسارع باستخدام مرشح تمرير منخفض. Linear Acceleration (TYPE_LINEAR_ACCELERATION)، على العكس، يزيل الجاذبية ويترك فقط التسارع الخطي للجهاز. مجموع Gravity وLinear Acceleration يعطي قراءات مقياس التسارع الخام.

Rotation Vector

Rotation Vector — المستشعر الافتراضي الأكثر تعقيدًا. يجمع بيانات من الجيروسكوب (تغيرات عالية التردد)، ومقياس التسارع (متجه الجاذبية)، ومقياس المغناطيسية (الاتجاه بالنسبة للشمال). النتيجة هي كواتيرنيون يصف الاتجاه المطلق للجهاز في الفضاء. يُستخدم في تطبيقات الواقع المعزز وخوذات الواقع الافتراضي.

Game Rotation Vector

Game Rotation Vector — نسخة مبسطة من Rotation Vector بدون استخدام مقياس المغناطيسية. يعطي هذا دقة أقل للسمت لكن معدل تحديث أعلى واستقرارًا أكبر. يُوصى به للألعاب حيث يكون زمن الوصول المنخفض مهمًا وليس الاتجاه المطلق بالنسبة للشمال.

تحسين استهلاك الطاقة عند العمل مع المستشعرات

المستشعرات من بين مكونات الجهاز الأكثر استهلاكًا للطاقة. يمكن لمقياس التسارع والجيروسكوب عند أقصى معدل استقصاء استنزاف البطارية في 3–4 ساعات من التشغيل المستمر. تحسين استخدام المستشعرات هو مهمة حرجة لأي تطبيق يستخدم Sensors API.

اختيار التأخير الأمثل

لا تستخدم SENSOR_DELAY_FASTEST دون داعٍ. لرسوم متحركة لواجهة المستخدم، يكفي SENSOR_DELAY_UI (60 مللي ثانية). لكشف اتجاه الشاشة — SENSOR_DELAY_NORMAL (200 مللي ثانية). كلما زاد المعدل، زاد الوقت الذي يقضيه المعالج في حالة نشطة. الفرق بين NORMAL وFASTEST يصل إلى 10 مرات في استهلاك الطاقة.

إلغاء تسجيل المستمعين في الخلفية

بدءًا من Android 8.0 (API 26)، تتلقى التطبيقات في الخلفية أحداث المستشعرات بمعدل مخفض. في Android 12+، يتطلب الوصول الخلفي لمستشعرات Motion وPosition الإذن BODY_SENSORS_BACKGROUND. قم بإلغاء تسجيل المستمع عندما ينتقل التطبيق إلى الخلفية — هذا يطيل عمر بطارية الجهاز.

المعالجة المجمعة ومخزن FIFO

استخدم المعالجة المجمعة عبر الطريقة registerListener(listener, sensor, delay, maxReportLatencyUs). المعامل maxReportLatencyUs يحدد أقصى زمن وصول لتسليم الأحداث بالميكروثانية. بقيمة 1000000 (ثانية واحدة)، تتراكم الأحداث في مخزن FIFO للمستشعر ويتم تسليمها مرة واحدة في الثانية — يستيقظ المعالج بشكل أقل.

الأسئلة الشائعة

ما المستشعرات الموجودة في جميع أجهزة Android؟

المجموعة الدنيا هي مقياس التسارع ومقياس المغناطيسية. هذان المستشعران موجودان في أكثر من 95% من الأجهزة. الجيروسكوب ومستشعر الضوء ومستشعر القرب — في 70–80% من الموديلات الحديثة. المستشعرات الأخرى (الضغط ودرجة الحرارة والرطوبة وعداد الخطى) أقل شيوعًا وتعتمد على فئة سعر الجهاز.

ما الفرق بين TYPE_ACCELEROMETER وTYPE_LINEAR_ACCELERATION؟

TYPE_ACCELEROMETER يعيد التسارع الكامل بما في ذلك الجاذبية (9.8 م/ث²). TYPE_LINEAR_ACCELERATION يعيد التسارع بدون الجاذبية — فقط تسارع حركة الجهاز. إذا كان الجهاز ساكنًا، سيظهر مقياس التسارع 9.8 م/ث² على طول المحور Z، بينما سيظهر Linear Acceleration 0 على جميع المحاور.

كيف أتحقق مما إذا كان المستشعر المطلوب متاحًا على الجهاز؟

استخدم getPackageManager().hasSystemFeature() مع الثوابت المناسبة: FEATURE_SENSOR_ACCELEROMETER وFEATURE_SENSOR_GYROSCOPE وFEATURE_SENSOR_PROXIMITY وغيرها. طريقة بديلة هي استدعاء getDefaultSensor(type) والتحقق مما إذا كانت النتيجة null. الطريقة الأولى مفضلة للتحقق أثناء التهيئة.

لماذا تتقلب قيم المستشعر وكيفية تنعيمها؟

البيانات الخام من المستشعرات تحتوي على ضوضاء. للتنعيم، استخدم مرشح تمرير منخفض: newValue = alpha * rawValue + (1 — alpha) * previousValue. معامل alpha من 0.1–0.3 يوفر توازنًا جيدًا بين الاستجابة والنعومة. للجيروسكوب، يتم أيضًا تطبيق مرشح تمرير عالٍ لإزالة انجراف الصفر.

هل يمكن استخدام المستشعرات في الخلفية؟

نعم، ولكن مع قيود. بدءًا من Android 8.0، ينخفض معدل أحداث المستشعر للتطبيقات في الخلفية. بدءًا من Android 12، يتطلب الوصول إلى المستشعرات في الخلفية الإذن BODY_SENSORS_BACKGROUND. للعمل في الخلفية، يُوصى باستخدام Foreground Service مع إشعار.

الخلاصة

  • Sensors API — واجهة Android موحدة للحصول على بيانات من مستشعرات الأجهزة عبر SensorManager.
  • ثلاث فئات — Motion (مقياس التسارع، الجيروسكوب)، Position (مقياس المغناطيسية) وEnvironment (الضوء، الضغط) بمبادئ تشغيل وتطبيقات مختلفة.
  • المستشعرات الافتراضية — Gravity وLinear Acceleration وRotation Vector تعتمد على دمج بيانات المستشعرات المادية وليس لها مقابل مادي.
  • التحسين — اختيار التأخير الصحيح (SENSOR_DELAY_NORMAL, UI, GAME, FASTEST) واستخدام المعالجة المجمعة يقلل استهلاك الطاقة بنسبة تصل إلى 60%.
  • القيود — Android 8+ يقلل معدل المستشعرات في الخلفية، Android 12+ يتطلب BODY_SENSORS_BACKGROUND للوصول الخلفي.
  • التحقق الأساسي — قبل تسجيل مستمع، تحقق من توفر المستشعر عبر getDefaultSensor أو hasSystemFeature.
  • استخدم مرشح تمرير منخفض لتنعيم الضوضاء وألغِ تسجيل المستمع عند الانتقال إلى الخلفية لتوفير البطارية.

سنقوم بتطوير تطبيق جوال جاهز

تقدم IT Sectr تطبيقات iOS وAndroid للشركات الناشئة والشركات منذ عام 2017. سوف نقدم لك النصح ونقترح أفضل حل.

مناقشة المشروع

اقرأ أيضًا