Androidطلاب معسكرات برمج

المستشعرات الموجودة بأجهزة الأندرويد وكيفية برمجتها والتعامل معها

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

معظم أجهزة الأندرويد تحتوي بداخلها على مستشعر بل الكثير من المستشعرات وليس مستشعر واحد منها مستشعر الضغط الجوي , شدة الاضائة , سرعة الحركة , الجاذبية , الدوران ..الخ , على سبيل المثال مستشعر القرب Proximity sensor فهو يستخدم في العديد من الهواتف و الغرض من هذا المستشعر هو قفل الشاشة عند تقريب الأذن من السماعة خلال المكالمات حتى لا يتسبب ضغط الوجه على الشاشة بقطع الإتصال وذلك يحصل من خلال التقاط الآشعة تحت الحمراء الصادرة عن الجسم.

أنواع المستشعرات :
  • Hardware

عبارة عن شريحة إلكترونية داخل الجهزة وهي تستمد بياناتها عن طريق القياس المباشر .

  • Software

ليست شريحة إلكترونية بل تحاكي مستشعرات ال hardware و تستمد بياناتها من واحد أو أكثر من مستشعرات ال hardware وتسمى أحيا ًنا المستشعرات الافتراضية أو المستشعرات الاصطناعية.

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

أنواع المستشعرات المدعومة من قبل نظام الأندرويد

النوع

الحساس

Sensor

Hardware

التسارع

(Acceleration)

ACCELEROMETER

Hardware

درجة الحرارة

TEMPERATURE

(thermometers)

Software or Hardware

الجاذبية

GRAVITY

Hardware

جيروسكوب

GYROSCOPE

Hardware

الإضائة

LIGHT

Hardware

الحقل المغناطيسي

MAGNETIC_FIELD

Software

الدوران

ORIENTATION

Hardware

الضغط

PRESSURE

(barometers)

Hardware

القرب

PROXIMITY

Hardware

الكاميرا

Camera

Hardware

البصمة

Fingerprint

Hardware

الميكروفون

Microphone

Hardware

نظام ملاحة

GPS

Software or Hardware

حركات كبيرة

significant motion

Software or Hardware

عدَّاد الخطوات

step counter

منصة الأندرويد تدعم ثلاث فئات واسعة من أجهزة الإستشعار

 هذة المجموعة من المستشعرات تستخدم لقياس التسارع وتشمل هذة الفئة مجموعة من المستشعرات وهم Accelerometers  مقياس التسارع , Gravity sensors مستشعر الجاذبية, Gyroscopes الجيرسكوب, Rotational vector sensors مستشعر الدوران.

هذة المجموعة من المستشعرات تستخدم لقياس عوامل البيئة المختلفة , مثل  ambient air temperature درجة حرارة الهواء, pressure الضغط الجوي, illumination شدة الاضائة, humidity الرطوبة.

هذه المجموعة من المستشعرات تستخدم فى تحديد المكان الفعلي للجهاز وتشمل هذة الفئة مستشعرات التوجية والمغناطيسية geomagnetic.

الوصول إلى المستشعرات الموجودة في الجهاز برمجيا

الخطوات :
  1. الاستعلام عن طريق مدير المستشعرات (  Sensor Manager  ) عن المستشعرات المتاحة واسترداد معلومات حول بيانات مستشعر معين.
  2. تخصيص و تسجيل مستمع ( Sensor listener  ) لبيانات المستشعر المطلوب.
  3. تخصيص ردة فعل  على بيانات المستشعر  الواردة.
الوصول إلى مدير المستشعرات (Sensor Manager)

 إطار استشعار الأندرويد Android sensor framework عبارة عن مجموعة من الكلاسات التى تساعدك فى الكشف عن المستشعرات الموجودة بالجهاز والتعامل معها.

وهذه الكلاسات هي:

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

 

 

    • يحتوي على المعلومات التي يتم تمريرها إلى التطبيق عندما يكون لدى جهاز المستشعر معلومات للإبلاغ عنها (أي عند حدوث حدث event مثلا عندما اضائة صفحة الجهاز تقل أو عند حركة الجهاز).
    • يستخدم لتوليد كائن يقدم معلومات عن حدث المستشعر. 
      • يحتوي الكائن من هذا الكلاس على المعلومات التالية:
        • بيانات المستشعر.
        • نوع المستشعر الذي أنشأ الحدث.
        • دقة البيانات.
        • الطابع الزمني للحدث

 

  • تستخدم لاستقبال الاشعارات من مدير المستشعرات Sensor Manager
  • عند حصول تغيير في قيم أو دقة المستشعر.

الحصول على قائمة  المستشعرات المتاحة في الجهاز

ملف MainActivity.java

public class MainActivity extends AppCompatActivity {
  1 
private SensorManager mgr;
  2
private TextView txtList;
 
@Override
  protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);


   3 mgr = (SensorManager) getSystemService(Context.SENSOR_SERVICE);       
txtList = (TextView) findViewById(R.id.sensorslist);


   4 List<Sensor> sensorList = mgr.getSensorList(Sensor.TYPE_ALL);


   5 StringBuilder strBuilder = new StringBuilder();


   6 for (Sensor s : sensorList) {
         strBuilder.append(s.getName() + “\n”);
       }


       txtList.setVisibility(View.VISIBLE);


   7 txtList.setText(strBuilder);


   }
}
شرح الكود
  1. للوصول الى مستشعرات الجهاز نقوم بتعريف نموذج من كلاس  SensorManager.
  2. تعريف نموذج من ال TextView  الذي سوف يتم عرض أسماء المستشعرات المتوفرة في الجهاز عن طريقه .
  3. للوصول الى الكلاس SensorManager نستخدم الدالة getSystemService  وإعطائه المتغير SENSOR_SERVICE .
  4. الحصول على قائمة المستشعرات  المتوفرة على الجهاز على  شكل قائمة من النوع Sensor عن طريق استدعاء الدالة getSensorList و اعطائها الثابت TYPE_ALL  (يشير هذا الثابت إلى جميع المستشعرات المتاحة) أو نستخدم ثوابت خاصة مثل TYPE_GYROSCOPE ,   TYPE_LINEAR_ACCELERATION أو TYPE_GRAVITY   للحصول على مستشعر من نوع معين .
  5. تعريف نموذج من ال StringBuilder لتخزين أسماء المستشعرات.
  6. حلقة for   لمرور قائمة المستشعرات المخزنة في  sensorList و الحصول على كل مستشعر، ومن ثم نحصل على الاسم الرسمي للمستشعر باستخدام الدالة  getName واضافته على التوالي في strBuilder و فصل كل سطر من قائمة الأسماء المخزنة في strBuilder  بقيمة خاصة line.separator، وعادةً ما يكون رمز السطر الجديد : \n.
  7. عرض محتويات  strBuilder في  عارض النص txtList.

للحصول على الكود كامل يمكنك زيارة رابط المستودع على github من هنا

 

تسجيل المستمع لأحداث المستشعر  SensorEventListener

المستشعرات تعمل بشكل منحصر لتطبيق واحد ولا يمكن لتطبيقين استخدام مستشعر واحد لذا نحتاج إلى تسجيل و إلغاء تسجيل المستمع لأحداث المستشعر SensorEventListener  في كل توقف و استئناف للتطبيق، فنقوم بتسجيل و إلغاء تسجيل  SensorEventListener   داخل الدالتين onResume و onPause.

تسجيل المستمع لأحداث المستشعر

نستخدم الدالة registerListener بإعطائها المستشعر المراد تفعيله و ثابت يعين مدى سرعة الإبلاغ عن البيانات الجديدة من المستشعر. 

يمكن لأجهزة الاستشعار الإبلاغ عن الكثير من البيانات بسرعة كبيرة، ولكن المزيد من البيانات المبلغ عنها تعني أن الجهاز يستهلك طاقة أكبر. 

نحتاج أن نأخذ بالاعتبار أقل مقدار من البيانات اللازمة لذا نستخدم الثابت SENSOR_DELAY_NORMAL  في الحالة العادية، أما  في حال تطبيقات أكثر كثافة للبيانات مثل الألعاب فقد تحتاج إلى معدل أسرع مثل SENSOR_DELAY_GAME or SENSOR_DELAY_FASTEST.


إلغاء تسجيل المستمع لأحداث المستشعر

إلغاء تفعيل جميع المستشعرات عن طريق الدالة SensorManager.unregisterListener في داخل الدالة onPause يحد من استخدام الطاقة عندما يكون التطبيق غير ظاهر على الشاشة.

 

تطبيق يحاكي ردة الفعل لتسارع الجهاز  بتغيير لون الواجهة

تعد مستشعرات الحركة مثل مقياس التسارع  ACCELEROMETER أو الجيروسكوب  GYROSCOPE مفيدة لمراقبة حركة الأجهزة مثل الإمالة أو الاهتزاز أو الدوران أو التأرجح، و خاصة للألعاب ، يمكن من خلاله تحديد اتجاه (شمال / جنوب /  شرق / غرب) وإمالة الجهاز. 

على سبيل المثال، يمكن أن تسمح للمستخدم بالتحكم في التسارع للأمام أو للخلف، والتحكم في التوجيه بالإمالة لليمين أو اليسار في الألعاب. 

مستشعر التسارع يقيس التسارع المطبق على الجهاز ، بما في ذلك قوة الجاذبية.

ملف MainActivity.java

public class MainActivity extends AppCompatActivity implements SensorEventListener {


private SensorManager sensorManager;
private boolean color = false;
private View view;
private Long lastUpdate;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
view = findViewById(R.id.mainLayout);

1 view.setBackgroundColor(Color.RED);
2 sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);

3 lastUpdate = System.currentTimeMillis();

}

@Override
public void onSensorChanged(SensorEvent event) {
4 if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
getAccelerometer(event);
}
}

private void getAccelerometer(SensorEvent event) {
5 float[] values = event.values;
6 // Movement
float x = values[0];
float y = values[1];
float z = values[2];
float accelationSquareRoot = (x * x + y * y + z * z)
/ (SensorManager.GRAVITY_EARTH * SensorManager.GRAVITY_EARTH);
7 long actualTime = event.timestamp;
if (accelationSquareRoot >= 2) //
{
8 if (actualTime – lastUpdate < 200) {
return;
}
lastUpdate = actualTime;

if (color) {
view.setBackgroundColor(Color.RED);
} else {
view.setBackgroundColor(Color.GREEN);
}
color = !color;
}
}

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}

@Override
protected void onResume() {
super.onResume();
9 // register this class as a listener for the orientation and
// accelerometer sensors
sensorManager.registerListener(this,
sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_FASTEST);
}

@Override
protected void onPause() {
10 // unregister listener
super.onPause();
sensorManager.unregisterListener(this);
}
}

شرح الكود
  1. تعيين لون الأحمر خلفية للواجهة الرئيسية .
  2. للوصول الى الكلاس SensorManager نستخدم الدالة getSystemService وإعطائه المتغير SENSOR_SERVICE.
  3.  نقوم بتخزين الوقت الحالي للنظام بالملي ثانية.
  4. داخل الدالة onSensorChanged نستخرج بيانات المستشعر عن طريق الكائن event
  5. نخزن البيانات عن طريق المستشعر داخل مصفوفة باسم values.
  6. التأكد من إذا ما كان الجهاز قد اهتز أم لا  بحساب حجم التسارع , حجم التسارع هو الجذر التربيعي لمجموع المربعات لكل مكون ، sqrt(x ^ 2 + y ^ 2 + z ^ 2)، حدث المستشعر SensorEvent يخزن البيانات عن طريق المستشعر داخل مصفوفة باسم values التي تحتوي  هنا في مقياس التسارع على بيانات موضع الجهاز في الفضاء في المحاور X ، Y ، Z المخزنة بالترتيب في مصفوفة ذو بعدين values[0], values[1], values[2] وحدة البيانات، (m/s^2)، واعتمادا على نوع المستشعر تتعين المصفوفة.
  7. نقوم بتخزين الوقت الذي أنشأ فيه البيانات   event.timestamp (مستشعرات الجهاز حساسة بشكل لا يصدق. عند حمل الجهاز في يدك، فإنه يتحرك باستمرار ، بغض النظر عن مدى ثبات يدك. والنتيجة هي أنه يتم استدعاء الدالة onSensorChanged عدة مرات في الثانية. لا نحتاج إلى كل هذه البيانات ، لذا نحتاج إلى التأكد من أننا سنأخذ عينات من البيانات التي نحصل عليها من مقياس التسارع بالجهاز. فنقوم بتخزين الوقت الحالي للنظام في actualTime ونتحقق مما إذا مرت 200 مللي ثانية منذ آخر مرة تم فيها استدعاء onSensorChanged)
  8. یتم تغيير لون الخلفية من أحمر للاخضر  و العكس في كل حركة للجهاز خلال 200 ملي ثانية.
  9. تسجيل المستمع لأحداث المستشعر داخل الدالة onResume
  10. إلغاء تسجيل المستمع لأحداث المستشعر داخل الدالة onPause

للحصول على الكود كامل يمكنك زيارة رابط المستودع على github من هنا

 

المراجع

  1. https://google-developer-training.github.io/android-developer-advanced-course-practicals/unit-1- expand-the-user-experience/lesson-3-sensors/3-1-p-working-with-sensor-data/3-1-p-working-with-sensor-data.html
  2. https://developer.android.com/guide/topics/sensors/sensors_overview
  3. http://www.tahlildadeh.com/ArticleDetails/استفاده-از-Android-Sensor-Manager
  4. https://books.google.com.sa/books?hl=en&lr=&id=dZjo-254FucC&oi=fnd&pg=PR27&dq=android+sensors&ots=m4hNOuhD4m&sig=MMm-vokaEqrj0PjzLMhwy4NLq6A&redir_esc=y#v=onepage&q&f=false
  5. https://google-developer-training.github.io/android-developer-advanced-course-practicals/unit-1-expand-the-user-experience/lesson-3-sensors/3-1-p-working-with-sensor-data/3-1-p-working-with-sensor-data.html

اترك تعليق