طَبِّقْهاتعلّم المبدأ، وطبّقه بيدكمقرر 251 · برمجة الأجهزة الذكية
الدرس 6 · الوحدة 3: التفاعل مع مكوّنات الجهاز والمستشعرات

التفاعل مع مكوّنات الجهاز: مقدمة المستشعرات

بوّابة المقرر: الجهاز يستشعر العالم، وتطبيقك يستجيب. ⏱ نحو 40 دقيقة.

بعد هذا الدرس ستستطيع أن:
  • تعدّد مستشعرات الجهاز الذكيّ واستخداماتها.
  • تفهم أن المستشعر مصدرٌ متدفّق نشترك فيه.
  • تقرأ مستشعرًا حيًّا بخطّاف وباشتراكٍ يدويّ.
  • تعرف دور دالّة الإلغاء في منع تسرّب الذاكرة.

١ما الذي يميّز الجهاز الذكيّ؟

الفرق الجوهريّ بين تطبيق الهاتف وصفحة الويب هو المستشعرات: أجهزةٌ صغيرة تقيس العالم حول الجهاز وتُغذّي تطبيقك ببياناتٍ حيّة.

المستشعريقيساستخدامٌ نموذجيّ
التسارع/الإمالةميل الجهاز وحركتهألعاب، مستوى، عدّ خطوات
الضوءسطوع المحيطسطوع تلقائيّ، وضع ليليّ
الموقع GPSخطّ العرض والطولخرائط، توصيل، طقس
الكاميراالصور والفيديومسح، تصوير، QR
البطاريةالشحن ووضع التوفيرترشيد الأداء

٢نمط القراءة: اشترك فيُحدّثك

المستشعر مصدرٌ متدفّق: لا تسأله مرّةً، بل تشترك فيه فيُنادي دالّتك كلّما تغيّرت القيمة. في React نربط ذلك بالحالة عبر useEffect — أو نستخدم خطّافًا جاهزًا يفعل ذلك عنّا:

الطريقةكيفمتى
SmartDevice.useBattery()خطّافٌ يعيد القيمة الحيّةالأسهل داخل مكوّن
SmartDevice.onBattery(cb)اشتراكٌ يدويّ يعيد دالّة إلغاءخارج React أو لتحكّمٍ دقيق
SmartDevice.get("battery")قراءةٌ لحظيّة واحدةقيمةٌ آنيّة بلا متابعة

٣أول مستشعر حيّ: البطارية

نقرأ البطارية بخطّاف useBattery. حرّك منزلق البطارية وزرّ التوفير في لوحة المستشعرات وراقب الاستجابة:

import { View, Text, StyleSheet } from 'react-native';import { useBattery } from 'smartdevice'; export default function App() {  const bat = useBattery();  const color = bat.level < 20 ? '#C62828' : bat.level < 50 ? '#E8820C' : '#2E7D32';  return (    <View style={styles.box}>      <Text testID="pct" style={[styles.pct, { color }]}>{bat.level}%</Text>      <View style={styles.barBg}>        <View style={[styles.barFill, { width: bat.level + '%', backgroundColor: color }]} />      </View>      <Text style={styles.note}>{bat.saver ? '🔋 وضع التوفير مفعّل' : 'وضع عاديّ'}</Text>    </View>  );} const styles = StyleSheet.create({  box: { padding: 24, alignItems: 'center' },  pct: { fontSize: 44, fontWeight: 'bold' },  barBg: { width: 180, height: 14, backgroundColor: '#eee', borderRadius: 7, marginTop: 10, overflow: 'hidden' },  barFill: { height: 14 },  note: { marginTop: 10, fontSize: 15 },});

شريط التعبئة عرضه = مستوى البطارية. منطقك (اللون، النصّ) يستجيب لكل حركة.

٤اشتراكٌ يدويّ خارج الخطّاف

أحيانًا تحتاج الاشتراك يدويًّا. onBattery يستقبل دالّةً تُنادى بالقيمة، ويعيد دالّة إلغاء نستدعيها في تنظيف useEffect (سنتعمّق في دورة الحياة في الدرس 15):

import { useState, useEffect } from 'react';import SmartDevice from 'smartdevice'; function useLowBattery() {  const [low, setLow] = useState(false);  useEffect(() => {    const stop = SmartDevice.onBattery((b) => setLow(b.level < 20));    return stop;                    // إلغاء الاشتراك عند إزالة المكوّن  }, []);  return low;}

الاشتراك يُنشأ مرة (مصفوفة اعتماديّات فارغة)، ودالّة الإلغاء تمنع تسرّب الذاكرة. هذا هو النمط الذي تبنى عليه كل قراءات المستشعرات.

توقّع وتحقّق

ما الذي يميّز الجهاز الذكيّ عن صفحة الويب؟

المستشعر مصدرٌ:

أسهل طريقةٍ لقراءة مستشعرٍ داخل مكوّن:

دالّة الإلغاء التي يعيدها الاشتراك تُستخدم لـ:

الخلاصة

تحدٍّ برمجي: تنبيه بطارية

متوسط

اقرأ البطارية واعرض تنبيهًا يتغيّر مع المستوى.

المطلوب:
  • استورد useBattery من smartdevice.
  • اعرض <Text testID="level"> فيه المستوى %.
  • اعرض <Text testID="msg">: إن كان أقل من 20 «اشحن الآن» وإلا «البطارية جيدة».
👀 اعرض الناتج المطلوب (وجرّبه)
✓ التحقق الآلي من حلّك:
  • الكود يعمل بلا أخطاء في Console
  • المستوى الابتدائيّ 80%
  • الرسالة الابتدائيّة «البطارية جيدة»
  • استُخدم useBattery

💡 تلميح 1
القيمة الابتدائيّة للبطارية 80% فالرسالة «جيدة».
💡 تلميح 2
الشرط: bat.level < 20.

حاول بنفسك أولًا؛ للمسألة أكثر من حلّ صحيح.

import { View, Text, StyleSheet } from 'react-native';import { useBattery } from 'smartdevice'; export default function App() {  const bat = useBattery();  const low = bat.level < 20;  return (    <View style={{ padding: 20 }}>      <Text testID="level" style={styles.lvl}>{bat.level}%</Text>      <Text testID="msg" style={{ color: low ? '#C62828' : '#2E7D32' }}>        {low ? 'اشحن الآن' : 'البطارية جيدة'}      </Text>    </View>  );} const styles = StyleSheet.create({  lvl: { fontSize: 36, fontWeight: 'bold', color: '#E8820C' },});
انتقل إلى تقييم الدرساختيار من متعدد، وصح وخطأ، وأكمل الفراغ، وتتبّع الناتج.ابدأ التقييم ←

📝 معلم؟ أرسل ملاحظة للمؤلف عن هذا الدرس