1. مقدّمة
نحمل الهواتف معنا في كل مكان، ولكن حتى الآن، كان من الصعب على التطبيقات تعديل تجربة المستخدم لتناسب البيئة والنشاط المتغيّرين باستمرار.
لإجراء ذلك في السابق، كان المطوّرون يستغرقون وقتًا طويلاً في الهندسة لدمج إشارات مختلفة (الموقع الجغرافي، وأجهزة الاستشعار، وما إلى ذلك) لتحديد وقت بدء نشاط معيّن أو انتهائه، مثل المشي أو القيادة. والأسوأ من ذلك، عندما تتحقّق التطبيقات بشكل مستقل ومتواصل من التغييرات في نشاط المستخدم، يتأثّر عمر البطارية سلبًا.
تعمل Activity Recognition Transition API على حلّ هذه المشاكل من خلال توفير واجهة برمجة تطبيقات بسيطة تنفّذ جميع عمليات المعالجة نيابةً عنك وتخبرك فقط بما يهمّك فعلاً، أي عندما يتغيّر نشاط المستخدم. ما عليك سوى أن يشترك تطبيقك في عملية انتقال في الأنشطة التي تهمّك، وستُعلمك واجهة برمجة التطبيقات بالتغييرات.
على سبيل المثال، يمكن لتطبيق مراسلة أن يطلب "إخباري عندما يدخل المستخدم إلى مركبة أو يخرج منها" لضبط حالة المستخدم على "مشغول". وبالمثل، يمكن لتطبيق رصد أماكن وقوف السيارات أن يطلب "إخباري عندما يخرج المستخدم من السيارة ويبدأ في المشي" لحفظ الموقع الجغرافي الذي أوقف فيه المستخدم سيارته.
في هذا الدرس التطبيقي حول الترميز، ستتعرّف على كيفية استخدام Activity Recognition Transition API لتحديد الوقت الذي يبدأ فيه المستخدم نشاطًا مثل المشي أو الركض أو يتوقف عنه.
المتطلّبات الأساسية
الإلمام بتطوير تطبيقات Android وبعض أساسيات عمليات رد الاتصال
ما ستتعلمه
- التسجيل في عمليات انتقال النشاط
- معالجة هذه الأحداث
- إلغاء التسجيل في عمليات الانتقال بين الأنشطة عندما لا تكون هناك حاجة إليها
المتطلبات
- استوديو Android Bumblebee
- جهاز Android أو محاكي Android
2- الخطوات الأولى
استنساخ مستودع مشروع البداية
لمساعدتك في البدء بأسرع ما يمكن، أعددنا لك مشروعًا للمبتدئين يمكنك الاستفادة منه. إذا كان لديك git مثبَّتًا، يمكنك ببساطة تنفيذ الأمر أدناه. (يمكنك التحقّق من ذلك عن طريق كتابة git --version في الوحدة الطرفية أو سطر الأوامر والتأكّد من تنفيذه بشكل صحيح).
git clone https://github.com/android/codelab-activity_transitionapi
إذا لم يكن لديك git، يمكنك الحصول على المشروع كملف zip:
استيراد المشروع
ابدأ "استوديو Android"، واختَر "فتح مشروع حالي في استوديو Android" من شاشة الترحيب وافتح دليل المشروع.
بعد تحميل المشروع، قد يظهر لك أيضًا تنبيه بأنّ Git لا يتتبّع جميع التغييرات المحلية، ويمكنك النقر على تجاهل أو على X في أعلى يسار الشاشة. (لن يتم إرسال أي تغييرات إلى مستودع Git).
في أعلى يمين نافذة المشروع، من المفترض أن يظهر لك ما يشبه الصورة أدناه إذا كنت في طريقة العرض Android. (إذا كنت في طريقة عرض المشروع، عليك توسيع المشروع لرؤية الشيء نفسه).

هناك رمزا مجلد (base وcomplete)، ويُعرف كل منهما باسم "وحدة".
يُرجى العِلم أنّ "استوديو Android" قد يستغرق عدة ثوانٍ لتجميع المشروع في الخلفية للمرة الأولى. خلال هذه الفترة، سيظهر لك رمز انتظار في شريط الحالة في أسفل "استوديو Android":

ننصحك بالانتظار إلى أن تنتهي هذه العملية قبل إجراء تغييرات على الرمز. سيسمح ذلك لـ استوديو Android بجلب جميع المكوّنات الضرورية.
بالإضافة إلى ذلك، إذا ظهرت لك رسالة تطلب منك إعادة التحميل لكي تصبح تغييرات اللغة سارية، انقر على "نعم".
التعرّف على المشروع المبدئي
حسنًا، تم إعداد ميزة "التعرّف على الأنشطة" وأصبحت جاهزة للاستخدام. سنستخدم الوحدة base، وهي نقطة البداية لهذا الدرس العملي. بمعنى آخر، ستضيف الرمز من كل خطوة إلى base.
يمكن استخدام الوحدة complete للتحقّق من عملك أو للرجوع إليها في حال مواجهة أي مشاكل.
نظرة عامة على المكوّنات الرئيسية:
-
MainActivity: يحتوي على جميع الرموز اللازمة للتعرّف على النشاط.
إعداد المحاكي
إذا كنت بحاجة إلى مساعدة في إعداد محاكي Android، يُرجى الرجوع إلى المقالة تشغيل تطبيقك.
تشغيل مشروع البداية
لننفّذ تطبيقنا.
- وصِّل جهاز Android بالكمبيوتر أو ابدأ محاكيًا.
- في شريط الأدوات، اختَر إعدادات
baseمن أداة الاختيار المنسدلة وانقر على المثلث الأخضر (تشغيل) بجانبها:

- من المفترض أن يظهر لك التطبيق أدناه:

- لا ينفِّذ التطبيق أي إجراءات حاليًا سوى طباعة رسالة. سنضيف الآن ميزة "التعرّف على النشاط".
ملخّص
في هذه الخطوة، تعرّفنا على ما يلي:
- الإعداد العام لدرس تطبيقي حول الترميز
- أساسيات تطبيقنا
- كيفية نشر تطبيقك
3- مراجعة المكتبة وإضافة إذن إلى ملف البيان
لاستخدام Transition API في تطبيقك، يجب تعريف اعتمادية لواجهة برمجة التطبيقات Google Location and Activity Recognition وتحديد الإذن com.google.android.gms.permission.ACTIVITY_RECOGNITION في بيان التطبيق.
- ابحث عن TODO: Review play services library required for activity recognition في ملف build.gradle. لا يتطلّب هذا الإجراء (الخطوة 1) اتّخاذ أي إجراء، ما عليك سوى مراجعة التبعية المعلَن عنها التي نطلبها. يجب أن يظهر على النحو التالي:
// TODO: Review play services library required for activity recognition.
implementation 'com.google.android.gms:play-services-location:19.0.1'
- في وحدة
base، ابحث عن TODO: Add both activity recognition permissions to the manifest فيAndroidManifest.xmlوأضِف الرمز أدناه إلى العنصر<manifest>.
<!-- TODO: Add both activity recognition permissions to the manifest. -->
<!-- Required for 28 and below. -->
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
<!-- Required for 29+. -->
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
يجب أن تبدو التعليمات البرمجية الآن على النحو التالي:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp">
<!-- TODO: Add both activity recognition permissions to the manifest. -->
<!-- Required for 28 and below. -->
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
<!-- Required for 29+. -->
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
...
</manifest>
كما هو موضّح في التعليقات، عليك إضافة إذن ثانٍ لنظام التشغيل Android 10. هذا الإذن مطلوب لإذن التشغيل الذي تمت إضافته في الإصدار 29 من واجهة برمجة التطبيقات.
هذا كل شيء! يمكن لتطبيقك الآن إتاحة ميزة التعرّف على الأنشطة، ما عليك سوى إضافة الرمز البرمجي للحصول عليها.
تشغيل التطبيق
شغِّل تطبيقك من "استوديو Android". يجب أن يبدو تمامًا كما هو. لم نضيف أي رمز لتتبُّع عمليات الانتقال حتى الآن، وسنتناول ذلك في القسم التالي.
4- التحقّق من أذونات وقت التشغيل أو طلبها في Android
على الرغم من أنّنا نغطّي الأذونات في الإصدار 28 من واجهة برمجة التطبيقات والإصدارات الأقدم، علينا توفير أذونات وقت التشغيل في الإصدار 29 من واجهة برمجة التطبيقات والإصدارات الأحدث:
- في
MainActivity.java، سنتحقّق مما إذا كان المستخدم يستعمل الإصدار 10 من نظام التشغيل Android (المستوى 29) أو إصدارًا أحدث، وفي حال كان الأمر كذلك، سنتحقّق من أذونات التعرّف على النشاط. - في حال عدم منح الأذونات، سننقل المستخدم إلى شاشة البداية (
PermissionRationalActivity.java) لتوضيح سبب حاجة التطبيق إلى الإذن والسماح له بالموافقة عليه.
مراجعة الرمز البرمجي للتحقّق من إصدار Android
في الوحدة base، ابحث عن TODO: Review check for devices with Android 10 (29+) في MainActivity.java. من المفترض أن يظهر لك مقتطف الرمز هذا.
ملاحظة: لا يتضمّن هذا القسم أي إجراءات.
// TODO: Review check for devices with Android 10 (29+).
private boolean runningQOrLater =
android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q;
كما ذكرنا سابقًا، يجب الحصول على الموافقة على إذن التشغيل android.permission.ACTIVITY_RECOGNITION في الإصدار 10 من نظام التشغيل Android والإصدارات الأحدث. نستخدم هذا الإجراء البسيط لتحديد ما إذا كنا بحاجة إلى التحقّق من أذونات التشغيل أم لا.
مراجعة عملية التحقّق من إذن التشغيل للتعرّف على النشاط إذا لزم الأمر
في الوحدة base، ابحث عن TODO: Review permission check for 29+ في MainActivity.java. من المفترض أن يظهر لك مقتطف الرمز هذا.
ملاحظة: لا يتضمّن هذا القسم أي إجراء.
// TODO: Review permission check for 29+.
if (runningQOrLater) {
return PackageManager.PERMISSION_GRANTED == ActivityCompat.checkSelfPermission(
this,
Manifest.permission.ACTIVITY_RECOGNITION
);
} else {
return true;
}
نستخدم المتغيّر الذي أنشأناه في الخطوة السابقة لمعرفة ما إذا كنّا بحاجة إلى التحقّق من أذونات التشغيل.
في الإصدارات Q والإصدارات الأحدث، نتحقّق من إذن التشغيل ونعرض النتيجة. هذا الإجراء هو جزء من طريقة أكبر تُعرف باسم activityRecognitionPermissionApproved()، وتتيح للمطوّر معرفة ما إذا كنّا بحاجة إلى طلب إذن أم لا من خلال مكالمة بسيطة واحدة.
طلب أذونات وقت التشغيل وتفعيل/إيقاف عمليات الانتقال الخاصة بميزة "التعرّف على النشاط"
في الوحدة base، ابحث عن TODO: Enable/Disable تتبُّع النشاط and ask for permissions if needed في MainActivity.java. أضِف الرمز أدناه بعد التعليق.
// TODO: Enable/Disable activity tracking and ask for permissions if needed.
if (activityRecognitionPermissionApproved()) {
if (activityTrackingEnabled) {
disableActivityTransitions();
} else {
enableActivityTransitions();
}
} else {
// Request permission and start activity for result. If the permission is approved, we
// want to make sure we start activity recognition tracking.
Intent startIntent = new Intent(this, PermissionRationalActivity.class);
startActivityForResult(startIntent, 0);
}
هنا نسأل عمّا إذا تمت الموافقة على ميزة "التعرّف على النشاط". إذا كان الأمر كذلك وكانت ميزة "التعرّف على النشاط" مفعّلة، سنوقفها. وبخلاف ذلك، نفعّله.
في حال عدم الموافقة على الإذن، ننقل المستخدم إلى نشاط شاشة البداية الذي يوضّح سبب حاجتنا إلى الإذن ونسمح له بتفعيله.
مراجعة رمز طلب الحصول على إذن
في الوحدة base، ابحث عن TODO: مراجعة طلب الحصول على إذن التعرّف على النشاط في PermissionRationalActivity.java. من المفترض أن يظهر لك مقتطف الرمز هذا.
ملاحظة: لا يتضمّن هذا القسم أي إجراء.
// TODO: Review permission request for activity recognition.
ActivityCompat.requestPermissions(
this,
new String[]{Manifest.permission.ACTIVITY_RECOGNITION},
PERMISSION_REQUEST_ACTIVITY_RECOGNITION)
هذا هو الجزء الأكثر أهمية في "السجلّ" وهو الجزء الذي يجب مراجعته. يؤدي الرمز إلى تشغيل طلب الحصول على الإذن عندما يطلبه المستخدم.
بخلاف ذلك، يعرض الصف PermissionRationalActivity.java سببًا يوضّح للمستخدم لماذا يجب الموافقة على إذن التعرّف على النشاط (وهي أفضل الممارسات). يمكن للمستخدم إما النقر على الزر لا شكرًا أو الزر متابعة (الذي يؤدي إلى تشغيل الرمز البرمجي أعلاه).
يمكنك مراجعة الملف إذا أردت معرفة المزيد من المعلومات.
5. تسجيل/إلغاء تسجيل أداة استقبال لعمليات انتقال الأنشطة
قبل إعداد رمز التعرّف على النشاط، نريد التأكّد من أنّ النشاط يمكنه التعامل مع إجراءات الانتقال التي يطلقها النظام.
إنشاء BroadcastReceiver للانتقال
في الوحدة base، ابحث عن TODO: Create a BroadcastReceiver to listen for activity transitions في MainActivity.java. الصِق المقتطف أدناه.
// TODO: Create a BroadcastReceiver to listen for activity transitions.
// The receiver listens for the PendingIntent above that is triggered by the system when an
// activity transition occurs.
mTransitionsReceiver = new TransitionsReceiver();
تسجيل BroadcastReceiver للانتقال
في الوحدة base، ابحث عن TODO: Register a BroadcastReceiver to listen for activity transitions في MainActivity.java. (يظهر في onStart()). الصِق المقتطف أدناه.
// TODO: Register a BroadcastReceiver to listen for activity transitions.
registerReceiver(mTransitionsReceiver, new IntentFilter(TRANSITIONS_RECEIVER_ACTION));
أصبح لدينا الآن طريقة لتلقّي إشعارات عند ظهور انتقالات النشاط من خلال PendingIntent.
Unregister BroadcastReceiver
في وحدة base، ابحث عن Unregister activity transition receiver when user leaves the app في MainActivity.java. (يظهر في onStop()).الصِق المقتطف أدناه.
// TODO: Unregister activity transition receiver when user leaves the app.
unregisterReceiver(mTransitionsReceiver);
من أفضل الممارسات إلغاء تسجيل جهاز استقبال عند إيقاف Activity.
6. إعداد انتقالات الأنشطة وطلب التعديلات
لبدء تلقّي إشعارات بشأن تغييرات الأنشطة، عليك تنفيذ ما يلي:
- عنصر ActivityTransitionRequest يحدّد نوع النشاط والانتقال.
- دالة ردّ الاتصال PendingIntent التي يتلقّى تطبيقك من خلالها الإشعارات لمزيد من المعلومات، اطّلِع على مقالة استخدام نية معلّقة.
إنشاء قائمة ActivitiyTransitions يجب اتّباعها
لإنشاء عنصر ActivityTransitionRequest، عليك إنشاء قائمة بعناصر ActivityTransition التي تمثّل عملية الانتقال التي تريد تتبُّعها. يتضمّن عنصر ActivityTransition البيانات التالية:
- نوع النشاط، ويتم تمثيله بواسطة فئة DetectedActivity تتيح واجهة برمجة التطبيقات Transition API الأنشطة التالية:
- نوع انتقال، ويتم تمثيله بواسطة فئة ActivityTransition. أنواع الانتقالات هي:
في الوحدة base، ابحث عن TODO: Add activity transitions to track في MainActivity.java. أضِف الرمز أدناه بعد التعليق.
// TODO: Add activity transitions to track.
activityTransitionList.add(new ActivityTransition.Builder()
.setActivityType(DetectedActivity.WALKING)
.setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_ENTER)
.build());
activityTransitionList.add(new ActivityTransition.Builder()
.setActivityType(DetectedActivity.WALKING)
.setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_EXIT)
.build());
activityTransitionList.add(new ActivityTransition.Builder()
.setActivityType(DetectedActivity.STILL)
.setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_ENTER)
.build());
activityTransitionList.add(new ActivityTransition.Builder()
.setActivityType(DetectedActivity.STILL)
.setActivityTransition(ActivityTransition.ACTIVITY_TRANSITION_EXIT)
.build());
يضيف هذا الرمز عمليات الانتقال التي نريد تتبُّعها إلى قائمة كانت فارغة سابقًا.
إنشاء PendingIntent
كما ذكرنا سابقًا، نحتاج إلى PendingIntent إذا أردنا تلقّي تنبيه بشأن أي تغييرات في ActivityTransitionRequest، لذا قبل إعداد ActivityTransitionRequest، علينا إنشاء PendingIntent.
في الوحدة base، ابحث عن TODO: Initialize PendingIntent that will be triggered when a activity transition occurs في MainActivity.java. أضِف الرمز أدناه بعد التعليق.
// TODO: Initialize PendingIntent that will be triggered when a activity transition occurs.
Intent intent = new Intent(TRANSITIONS_RECEIVER_ACTION);
mActivityTransitionsPendingIntent =
PendingIntent.getBroadcast(MainActivity.this, 0, intent, 0);
أصبح لدينا الآن PendingIntent يمكننا تشغيله عند حدوث أحد ActivityTransition.
إنشاء ActivityTransitionRequest وطلب الحصول على آخر الأخبار
يمكنك إنشاء عنصر ActivityTransitionRequest من خلال تمرير قائمة ActivityTransitions إلى فئة ActivityTransitionRequest.
في الوحدة base، ابحث عن إنشاء طلب والاستماع إلى تغييرات النشاط في MainActivity.java. أضِف الرمز أدناه بعد التعليق.
// TODO: Create request and listen for activity changes.
ActivityTransitionRequest request = new ActivityTransitionRequest(activityTransitionList);
// Register for Transitions Updates.
Task<Void> task =
ActivityRecognition.getClient(this)
.requestActivityTransitionUpdates(request, mActivityTransitionsPendingIntent);
task.addOnSuccessListener(
new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void result) {
activityTrackingEnabled = true;
printToScreen("Transitions Api was successfully registered.");
}
});
task.addOnFailureListener(
new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
printToScreen("Transitions Api could NOT be registered: " + e);
Log.e(TAG, "Transitions Api could NOT be registered: " + e);
}
});
لنراجع التعليمات البرمجية. أولاً، ننشئ ActivityTransitionRequest من قائمة انتقالات الأنشطة.
ActivityTransitionRequest request = new ActivityTransitionRequest(activityTransitionList);
بعد ذلك، نسجّل لتلقّي إشعارات بشأن تغييرات الأنشطة من خلال تمرير مثيل ActivityTransitionRequest وكائن PendingIntent الذي أنشأناه في الخطوة الأخيرة إلى طريقة requestActivityTransitionUpdates(). تعرض الدالة requestActivityTransitionUpdates() الكائن Task الذي يمكنك التحقّق من نجاحه أو فشله، كما هو موضّح في مجموعة الرموز البرمجية التالية:
// Register for Transitions Updates.
Task<Void> task =
ActivityRecognition.getClient(this)
.requestActivityTransitionUpdates(request, mActivityTransitionsPendingIntent);
task.addOnSuccessListener(
new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void result) {
activityTrackingEnabled = true;
printToScreen("Transitions Api was successfully registered.");
}
});
task.addOnFailureListener(
new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
printToScreen("Transitions Api could NOT be registered: " + e);
Log.e(TAG, "Transitions Api could NOT be registered: " + e);
}
});
بعد التسجيل بنجاح لتلقّي إشعارات بشأن تغيير النشاط، يتلقّى تطبيقك إشعارات في PendingIntent المسجَّل. نضبط أيضًا متغيرًا يشير إلى أنّ ميزة تتبُّع النشاط مفعّلة لنعرف ما إذا كان علينا إيقافها أو تفعيلها إذا نقر المستخدم على الزر مرة أخرى.
إزالة التحديثات عند إغلاق التطبيق
من المهم إزالة تحديثات الانتقال عند إغلاق التطبيق.
في الوحدة base، ابحث عن إيقاف الاستماع إلى تغييرات النشاط في MainActivity.java. أضِف الرمز أدناه بعد التعليق.
// TODO: Stop listening for activity changes.
ActivityRecognition.getClient(this).removeActivityTransitionUpdates(mActivityTransitionsPendingIntent)
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
activityTrackingEnabled = false;
printToScreen("Transitions successfully unregistered.");
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
printToScreen("Transitions could not be unregistered: " + e);
Log.e(TAG,"Transitions could not be unregistered: " + e);
}
});
الآن، علينا استدعاء الطريقة التي تحتوي على الرمز أعلاه عند إيقاف التطبيق.
في الوحدة base، ابحث عن TODO: Disable activity transitions when user leaves the app في MainActivity.java في onPause(). أضِف الرمز أدناه بعد التعليق.
// TODO: Disable activity transitions when user leaves the app.
if (activityTrackingEnabled) {
disableActivityTransitions();
}
هذا كل ما يتعلّق بتتبُّع التغييرات في عمليات الانتقال بين الأنشطة. الآن، ما علينا سوى معالجة التحديثات.
7. معالجة الأحداث
عندما يحدث انتقال النشاط المطلوب، يتلقّى تطبيقك ردّ اتصال Intent. يمكن استخراج عنصر ActivityTransitionResult من Intent، والذي يتضمّن قائمة بعناصر ActivityTransitionEvent. يتم ترتيب الأحداث حسب التسلسل الزمني، على سبيل المثال، إذا طلب تطبيق نوع النشاط IN_VEHICLE عند الانتقالَين ACTIVITY_TRANSITION_ENTER وACTIVITY_TRANSITION_EXIT، سيتلقّى عنصر ActivityTransitionEvent عندما يبدأ المستخدم القيادة، وعنصرًا آخر عندما ينتقل المستخدم إلى أي نشاط آخر.
لنضِف الرمز البرمجي للتعامل مع هذه الأحداث.
في الوحدة base، ابحث عن TODO: Extract activity transition information from listener في MainActivity.java في onReceive()من BroadcastReceiver الذي أنشأناه سابقًا. أضِف الرمز أدناه بعد التعليق.
// TODO: Extract activity transition information from listener.
if (ActivityTransitionResult.hasResult(intent)) {
ActivityTransitionResult result = ActivityTransitionResult.extractResult(intent);
for (ActivityTransitionEvent event : result.getTransitionEvents()) {
String info = "Transition: " + toActivityString(event.getActivityType()) +
" (" + toTransitionType(event.getTransitionType()) + ")" + " " +
new SimpleDateFormat("HH:mm:ss", Locale.US).format(new Date());
printToScreen(info);
}
}
سيؤدي ذلك إلى تحويل المعلومات إلى String وطباعتها على الشاشة.
بهذا تكون قد انتهيت. جرِّب تشغيل التطبيق.
ملاحظة مهمة: يصعب إعادة إنتاج تغييرات النشاط على المحاكي، لذا ننصحك باستخدام جهاز فعلي.
من المفترض أن تتمكّن من تتبُّع تغييرات النشاط.
للحصول على أفضل النتائج، ثبِّت التطبيق على جهاز فعلي وتجوّل في المكان. :)
8. مراجعة الرمز
لقد أنشأت تطبيقًا بسيطًا يتتبّع عمليات الانتقال بين الأنشطة ويدرجها على الشاشة.
يمكنك قراءة الرمز بالكامل لمراجعة ما أنجزته والتعرّف بشكل أفضل على طريقة عمله.