1. مقدّمة
نحمل الهواتف معنا في كل مكان، ولكن حتى الآن، كان من الصعب على التطبيقات تعديل تجربتها لتتلاءم مع البيئة والأنشطة المتغيّرة باستمرار لدى المستخدم.
لإجراء ذلك في السابق، كان المطوّرون يقضون وقتًا هندسيًا قيّمًا في دمج إشارات مختلفة (الموقع الجغرافي وأجهزة الاستشعار وما إلى ذلك) لتحديد وقت بدء نشاط مثل المشي أو القيادة أو انتهائه. والأسوأ من ذلك، عندما تتحقّق التطبيقات بشكل مستقل ومستمر من التغييرات في نشاط المستخدم، ينخفض عمر البطارية.
تحلّ واجهة برمجة التطبيقات Activity Recognition Transition API هذه المشاكل من خلال توفير واجهة برمجة تطبيقات بسيطة تُجري جميع عمليات المعالجة نيابةً عنك وتُعلمك فقط بما يهمّك فعلاً: عندما يتغيّر نشاط المستخدم. ما عليك سوى اشتراك تطبيقك في عملية انتقال في الأنشطة التي تهمّك، وستُعلمك واجهة برمجة التطبيقات بالتغييرات.
على سبيل المثال، يمكن لتطبيق المراسلة أن يطلب "إبلاغي عندما يدخل المستخدم مركبة أو يغادرها" لضبط حالة المستخدم على "مشغول". وبالمثل، يمكن لتطبيق رصد مواقف السيارات أن يطلب،"إبلاغي عندما يغادر المستخدم المركبة ويبدأ المشي"، لحفظ موقع وقوف السيارة الخاص بالمستخدم.
في هذا الدرس التطبيقي حول الترميز، ستتعرّف على كيفية استخدام Activity Recognition Transition API لتحديد الحالات التي يبدأ فيها المستخدم نشاطًا معيّنًا أو يتوقف عنه، مثل المشي أو الركض.
المتطلّبات الأساسية
الإلمام بتطوير تطبيقات Android وبعض الإلمام بوظائف الاستدعاء
ما ستتعرّف عليه
- التسجيل في عمليات انتقال الأنشطة
- معالجة هذه الأحداث
- إلغاء التسجيل في عمليات نقل الأنشطة عندما لا تكون مطلوبة بعد الآن
المتطلبات
- Android Studio Bumblebee
- جهاز Android أو محاكي
2- الخطوات الأولى
استنساخ مستودع المشروع الأوّلي
لبدء استخدام هذه الميزة في أسرع وقت ممكن، أعددنا مشروعًا تمهيديًا يمكنك الاستفادة منه. إذا كان git مثبّتًا، يمكنك ببساطة تنفيذ الأمر أدناه. (يمكنك التحقّق من ذلك عن طريق كتابة git --version
في المحطة الطرفية / سطر الأوامر والتأكّد من تنفيذه بشكل صحيح).
git clone https://github.com/android/codelab-activity_transitionapi
إذا لم يكن لديك git، يمكنك الحصول على المشروع كملف zip:
استيراد المشروع
ابدأ Android Studio، واختَر "فتح مشروع حالي في Android Studio" من شاشة الترحيب وافتح دليل المشروع.
بعد تحميل المشروع، قد يظهر لك أيضًا تنبيه بأنّ Git لا يتتبّع جميع التغييرات المحلية، ويمكنك النقر على تجاهل أو X في أعلى يسار الصفحة. (لن يتم دفع أي تغييرات إلى مستودع Git).
في أعلى يمين نافذة المشروع، من المفترض أن يظهر لك ما يلي إذا كنت في طريقة عرض Android. (إذا كنت في طريقة عرض المشروع، عليك توسيع المشروع للاطّلاع على الإجراء نفسه).
هناك رمزان للمجلدات هما (base
وcomplete
)، ويُعرف كل منهما باسم "وحدة".
يُرجى العِلم أنّه قد يستغرق "استوديو Android" عدة ثوانٍ لتجميع المشروع في الخلفية للمرة الأولى. خلال هذه الفترة، سيظهر لك مؤشر تدوير في شريط الحالة في أسفل Android Studio:
ننصحك بالانتظار إلى حين اكتمال هذا الإجراء قبل إجراء تغييرات على الرمز البرمجي. سيسمح ذلك لـ Android Studio بسحب جميع المكوّنات اللازمة.
بالإضافة إلى ذلك، إذا ظهرت لك رسالة تطلب منك إعادة تحميل الصفحة لتفعيل تغييرات اللغة أو ما شابه ذلك، انقر على "نعم".
فهم المشروع الأوّلي
حسنًا، تم الانتهاء من الإعداد ويمكنك الآن إضافة ميزة "التعرّف على الأنشطة". سنستخدم وحدة 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 (مهام مُهمّة: مراجعة مكتبة "خدمات Play" المطلوبة لميزة "التعرّف على الأنشطة") في ملف 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 (29) من Android أو إصدارًا أحدث، وإذا كان الأمر كذلك، سنتحقق من أذونات التعرّف على الأنشطة. - في حال عدم منح الأذونات، سنوجّه المستخدم إلى شاشة البداية (
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 activity tracking 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: Review permission request for activity recognition (مهام مُهمّة: مراجعة طلب الإذن بالتعرّف على النشاط) في 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.
إلغاء تسجيل BroadcastReceiver
في وحدة base
، ابحث عن إلغاء تسجيل مستلِم عملية نقل النشاط عندما يغادر المستخدم التطبيق في MainActivity.java
. (يظهر في onStop()
).الصِق المقتطف أدناه.
// TODO: Unregister activity transition receiver when user leaves the app.
unregisterReceiver(mTransitionsReceiver);
من أفضل الممارسات إلغاء تسجيل جهاز استقبال عند إيقاف Activity
.
6. إعداد عمليات انتقال الأنشطة وطلب التعديلات
لبدء تلقّي إشعارات بشأن انتقال الأنشطة، عليك تنفيذ ما يلي:
- عنصر ActivityTransitionRequest الذي يحدّد نوع النشاط والانتقال
- دالة استدعاء PendingIntent التي يتلقّى تطبيقك الإشعارات من خلالها لمزيد من المعلومات، يُرجى الاطّلاع على استخدام نية في انتظار المراجعة.
إنشاء قائمة بعمليات انتقال الأنشطة التي تريد متابعتها
لإنشاء عنصر 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: استخراج معلومات انتقال النشاط من المستمع في 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. مراجعة الرمز
لقد أنشأت تطبيقًا بسيطًا يتتبّع عمليات النقل في "النشاط" ويعرضها على الشاشة.
يمكنك قراءة الرمز البرمجي بالكامل لمراجعة ما فعلته والحصول على فكرة أفضل عن كيفية عمله معًا.