برمجة الأندرويد

برمجة تطبيق شات الدرس الثالث

<< الدرس السابق

الدرس التالى >>

فى الدرس السابق قمنا بعمل الـ Session Managent لإدارة تسجيل دخول والاحتفاظ بتسجيل دخول المستخدم والان لدينا التطبيق يمكن التسجيل وتسجيل الدخول والوصل للصفحة الرئيسية وبالطبع تختلف تطبيقات الشات عن بعضها البعض فى هيكلتها ربما ترغب فى ان تكون الصفحة الرئيسية تحتوى على قائمة من   كل المستخدمين مع توضيح المستخدمين المتصلين الان  (يمكنك عمل حقل isOnline من خصائص المستخدم فى الجدول الموجود اون لاين وعند فتح التطبيق من قبل المستخدم تقوم بعمل هذه القيمة 1 مثلا وعندما يذهب التطبيق للخلفية تقوم بارسال طلب للـ server وجعل هذه القيمة 0 وتحدث قائمة الاعضاء وحالاتهم هل متصلين ام لا )يمكنك الضغط على أحدهم وبدأ المحادثة معه مباشرة هذا احد الاشكال التى يمكن ان يسير بها تطبيق الشات البعض يمكن أن يعرض قائمة الـ chat rooms ويختار العضو غرفة للدخول والتحدث بها مثل غرف الشات الشائعة وأيا كانت الطريقة التى ستختارها فسيتطلب منك تنفيذها العمل على الجهتين جهة السيرفر وفى حالتنا هذه بالـ php and mysql وكذلك جهة الاندرويد وسنقوم بعمل التطبيق الخاص بنا بنظام غرف الشات اى نريد للعضو بعد تسجيل الدخول أن يجد مجموعة من غرف الشات

 

ستلاحظ أن الغرفة الواحده عباره عن title و descriotion وبالطبع لها id وبمجرد فتح الصفحة الرئيسية نريد ظهور قائمة غرف الشات للمستخدم وبالطبع ستأتى من الapi او الباك اند الذى نقوم ببرمجته لذلك الان نحتاج لعمل جدول الchat rooms ونحتاج لعمل  3 ملفات الان add-chat-room.php ، get-all-chat-rooms.php ، delete-chat-room لكى يتم التعامل مع هذا الجدول من خلالهم لذلك الان سأذهب لقاعدة البيانات وأقوم بإنشاء الجدول

فقط خانة الاسم وخانة الوصف وفى حالة اذا احتجنا الى عمود اخر فى اى وقت يمكننا اضافته بشكل عادى

الان نريد برمجة ملفات php لتتعامل مع هذا الجدول تدخل البيانات وتستدعيها وتحذفها  .

 

ملف add-chat-rooms.php

 

معظم السطور واضحة وشرحناها سابقا فى الدرس الأول  لذلك نقوم برفع الملف وبدء التجربة باستخدام postman

الان نجرب ان نرفق الـ JSON كاملا فى ال body  يحتوى على  اسم الغرفة والوصف

نذهب الى جدول غرف الشات وسنجد أنه تم اضافة الغرفة

 

الان لدينا الملف add-chat-room.php جاهز .

 

ملف delete-chat-room.php

ومعظم السطور مشروحة سابقا ويعتبر الجديد هو $_POST وهى عباره عن جلب القيمة التى أرسلها المستخدم كبارميتر حيث أننا هنا لا نستقبل الـ body ولا نريد Json من الاندرويد الامر بسيط نريد فقط id الغرفة وسيتم حذفها وفى السطر 16 استخدمنا الميثود delete الخاصة بـ Marei DB وقمنا باعطائها بارميتر اسم الجدول ثم استخدمنا الميثود where اى عندما id = room_id الذى ارسله ال client او تطبيق الاندرويد .

نقوم برفع الملف للإستضافة ثم نقوم باختباره بواسطة الـ postman

وعندما نرفق id الغرفة وحاليا لا يوجد سوى غرفة واحده ب id رقم 1 لذلك سنرسله للحذف فلنجرب

 

 

ونجد أنه تم حذف الغرفة واذا قمنا بتصفح جدول الـ chat rooms فسنجد أنه فارغ

 

والان نحتاج نحتاج لعمل ملف get-all-chat-rooms.php والذى كما قلنا سيجب لنا كل غرف الشات المتاحة والتى سنعرضها للمستخدم للاختيار منها

 

ملف get-all-chat-rooms.php

فقط echo ثم نستخدم Marei DB الميثود table نعطيها اسم الجدول ثم الميثود get

نقوم باضافة عدد غرف باستخدام الملف السابق الخاص بال add ثم نقوم  برفع هذا  الملف والتجربة

الان لدينا ال api الخاص بغرف الشات جاهز وملخصه كالتالى :

يمكننا ايضا عمل edit-chat-room.php لتحديث بيانات الغرفة لكن لن أقوم بتضمين هذا الخيار ضمن التطبيق يمكنك عمله اذا اردت وتستخدم الميثود update فى Marei DB

ننتقل الان الى الأندرويد

 

الـ Android 

سنقوم بإضافة الريكوستس او الـ Calles الى ملف API كالتالى :

وطبعا لم نقم بإنشاء الـ Model الخاص بالـ ChatRoom بعد لذلك سنقوم بإنشائه الان

ولاحظ انه يحتوى على id رغم اننا فى الارسال عند اضافة غرفة لا نرسل الـ id لكن اذا كانت هناك بيانات اضافية مرسلة ل php فلا بأس بها اما فى الاستقبال فى getAllChatRooms فكل غرفة لها id وسنحتاجه بالتأكيد لذلك عند يس عمل هذا الـ Model فى الحالتين بدلا من عمل Model لكل حالة بدون حاجه حقيقية لهذا الامر .

 

الان يختفى التنبيه وتصبح جاهزة

الان حان وقت تصميم الـ RecyclerView الخاصة بعرض غرف الشات فى الرئيسية سنبدأ بتصميم الـ Row وسيكون كالتالى :

 

 

ثم نقوم بكتابة كلاس الـ Adapter

نذهب للـ MainActivity لجعله يعرض غرف الشات بها سنقوم باضافة RecyclerView وتعريفها فى الجافا ثم عمل LayoutManager لها لتكون Linear بالاضافة الى انشاء اتصال بواسطة Retrofit لجلب البيانات

وستجد أن الميثود getChatRooms ميثود عادية تقوم بجلب غرف الشات باستخدام Call يتم بواسطة Retrofit استخدمنا FUtilsProgress لاظهار علامة التحميل فقط وهو يعتمد على لون الـ accent color حاليا وسوف نقوم بتطوير مكتبة Futils مستقبلا ليتم اسناد اللون يدويا لكن الان استخدم المكتبة للتسهيل ويمكنك الاستغناء عن الـ FUtilsProgress واستخدام Progress عادى اثناء التطبيق .

 

نقوم بتشغيل التطبيق وسنجد أن غرف الشات قد ظهرت

 

 

يفضل أيضا ان تقوم بعمل Cancel للطلب فى onDestroy حتى يتم ايقاف الـ Retrofit Call فى حالة توقف الاكتيتفى لحفظ الموارد ولكى لا تواجه اى اخطاء عندما ينتهى الاتصال ولا يجد الاكتيتيفى موجود وظاهر

وذلك كالتالى

وفى onDestroy

 

الى الان كل شىء يبدو جيدا لكن نريد جعل مستخدم هو الـ Admin ويستطيع التحكم فى غرف الشات يقوم بحذفها أو إضافة غرفة شات جديدة بالإضافة الى ذلك نريد عند تسجيل الدخول فى الـ Json ان يعود لنا اسم المستخدم لنعرضه فى الـ Toolbar بالأعلى لذلك سنعود لجدول الـ users لنجرى تعديل عليه لاضافة خاصية الـ admin للمستخدم وكذلك العودة باسم المستخدم لعرضه

وفكرة جعل مستخدم admin هى اننا نقوم باضافة حقل ضمن جدول اليوزر ونطلق عليه isAdmin مثلا وفى حالة كان هذا المستخدم admin يعود لنا بالقيمة 1 فى حالة عضو عادى يعود لنا بالقيمة 0 او true و false لا فرق فى ذلك وهذا ما سنفعله الان سنذهب لجدول الـ users ونضيف هذا العمود او الحقل وقيمته الافتراضية للجميع 0

 

وسأجعل المستخدم الاول admin بجعل قيمة is_user_admin = 1 كالتالى

الان نعود لملف الـ php الخاص بالـ login  وهو ملف login-user.php لنجعله يعود لنا ببيانات المستخدم اذا كانت بيانات الدخول صحيحة .

الاشياء الجديدة والمعدلة على ملف login-user.php مشار اليها بالاسهم الحمراء كل ما فعلناه استخدمنا الميثود select فى Marei DB وكذلك الميثود first وبالتالى سيعود لنا الناتج على هيئة JSONObject والذى وضعناه ضمن الراجع عند تسجيل الدخول ليكون الناتج عند تسجيل الدخول كالتالى

واذا تغيرت صيغة الـ JSON القادم للأندرويد يجب أن نقوم بتعديل الـ Object الذى يستقبل هذا الـ Json فى الأندرويد

وبما أن الـ MainResponse ليس خاصا بحالة تسجيل الدخول فقط ويستخدم مع عدة أمور أخرى لذلك لن اقوم بتعديله وسننشىء أوبجكت جديد معتمد على الـ Json الجديد وسنطلق عليه LoginResponse

 

ثم نعدل نوع الـ Call او الراجع فى ملف الـ API للـ LoginResponse كالتالى

الان بالنسبة للـ User  الذى يرسل كبارميتر والذى يستخدم لحفظ بيانات المستخدم فى الـ Realm بواسطة الـ Session لا يحتوى على خيار is_user_admin لذلك سنضيفه حيث أننا فى عدة أماكن فى التطبيق قد نحتاج لنعرف هل المستخدم الحالى Admin ام لا لنظهر له اشياء اضافية تخص التحكم وما الى ذلك لذلك سنقوم بالتعديل واضافة isAdmin وكذلك id المستخدم لاننا سنحتاجه لاحقا

ولاحظ أنهم ليس لديهم serialized name ولا نحتاجه هنا لاننا عندما نستخدم الكلاس User فى تسجيل الدخول كباراميتر للميثود loginUser فى Retrofit نرسل الايميل والباسورد فقط ليتم التحقق منهم لذلك باقى الاشياء سترسل خالية وسيتم تجاهلها من قبل php لاننا لم نستدعيها ولم نستخدمها هناك فى ملف login-user.php

 

الان يجب علينا الذهاب لصفحة LoginActivity لكى نقوم بالتعديل الازم على Retrofit وتخزين البيانات بشكل صحيح فاذا ذهبنا الان سنجدها كالتالى

سنستبدل  كل MainResponse بـ LoginResponse

بالاضافة للاستبدال قمنا بسحب الـ id والـ isAdmin و الـ username من البيانات القادمة من السيرفر عند نجاح تسجيل الدخول  وتخزينهم بالاضافة لبيانات اليوزر الذى ادخلها من قبل عند تسجيل الدخول وحفظ الجميع فى الـ Session لنستطيع استدعائها لاحقا.

وستلاحظ انى لا استخدم Setters او Getters حاليا يمكنك استخدامهم اذا اردت لكن لم استخدمهم لانى لست فى حاجه اليهم وللوصول لعناصر الكلاس اثناء  اسهل بدلا من getxxx.ثم getxxx و setxxx   وهكذا ولاننا لا نحتاج الى سوى عمل اسناد للقيمة ولن نقوم باى عمليات اخرى .

الان نعود للـ MainActivity لنجعل الToolbar يرحب باسم المستخدم كما فى التصميم واضافة زر + كـ FAB يظهر  للـ Admin فقط ليستطيع إضافة غرفة.

 

 

نذهب الان لكود الجافا لجعل الاسم فى title الترحيب وكذلك اخفاء الـ FAB اذا لم يكن من سجل الدخول هو الـ Admin كالتالى :

 

الان عند الضغط على زر الـ FAB نريد أن يظهر Dialog للأدمن ليستطيع إضافة بيانات الغرفة وسأستخدم الـ DialogFragment لهذا الغرض

نقوم بتصميم شكل الـ Dialog كالتالى

نقوم بتعريف المكونات فى الجافا باستخدام الـ ButterKnife

 

نقوم الان بعمل الميثود add Room والتى ستستخدم لإضافة الغرفة

مثل ما فعلنا فى السابق استخدمنا Retofit وهنا اعطيناه الـ chatRoom كباراميتر وعند نجاح قمنا بعمل Toast ثم تحدث الـ ChatRooms فى الـ MainActivity عن طريق استدعاء الـميثود reloadChatRooms والتى لا تفعل شىء سوى استدعاء ميثود تحميل الـ ChatRooms  :

 

ونقوم باستخدام الميثود  addChatRoom عند الضغط على زر add من جهة المستخدم كالتالى :

 

ثم نقوم بالتجربة

 

 

 

 

ونجد ان الغرفة تم اضافتها بنجاح

 

الان يتبقى لنا حذف الغرفة

يمكنك عملها بأكثر من سيناريو مثلا اظهار زر delete او عمل implement لـ onLongClick على الايتم ثم تظهر للأدمن نافذه هل تريد حذف و yes او no الخ .. لكنى للتسيهل سأستخدم موضوع الـ swip اى عندما يقوم الـ Admin بعمل swip للجانب الايسر من الشاشة سيتم حذف الغرفة

وسنستخدم ItemTouchHelper لتنفيذ ذلك  فى اخر كلاس MainActivity سنقوم بعمل التالى :

وطبعا الـ ItemTouchHelper يدعم التحريك لترتيب عناصر الـ RecyclerView ايضا فتجد الميثود onMove وكذلك الميثود onSwip والتى قمنا بكتابة كود الحذف بداخلها ليتم تنفيذه اذا قام اليوزر بعمل swip ناحية اليسار وهو ما حددناه فى الكونستراكتور فى السطر الاول والقيمة 0 خاصة بالـ directions لا نحتاج اليها هنا .حيث قمنا بجلب الـ postion الخاص بالـAdapter عند الايتم التى تم عمل swip عندها لكى نحصل على الـ id الخاص بالغرفة فى السطر التالى ثم نستخدمه فى Retrofit  وعند نجاح الامر نقوم بعمل حذف للغرفة من list الشات المعروضة حاليا واعلام الادابتر ان هذه الـ item حذفت ليقوم بحذفها .

نعود للاعلى اذا كان المستخدم Admin

وفى حالة المستخدم ليس Admin لا نقوم بربط هذا الـ Helper ولن يتاح له عمل Swip

يمكنك تشغيل التطبيق والتجربة الان

لكن عند عمل swift تكون خلفية العنصر بيضاء نريد جعلها باللون الاحمر كعلامة تنبيه للمستخدم لذلك نقوم بعمل override للميثود onChildDraw داخل الـ ItemHelper كالتالى :

 

نقوم الان بالتجربة

 

عند تسجيل الدخول  بعضوية الـ Admin  

يوجد FAB ويستيطع المستخدم حذف الغرفة عن طريق الـ swip

 

عند تسجيل الدخول بعضوية  عادية

لا يوجد FAB لا يستطيع المستخدم اضافة غرف شات أو عمل swip لحذفها .

 

 

تم تحديث ملفات المشروع على Github للأندرويد وللـ php.

 

<< الدرس السابق

الدرس التالى >>

السابق
برمجة تطبيق شات الدرس الثانى
التالي
برمجة تطبيق شات الدرس الرابع

تعليقان

أضف تعليقا

  1. محمد قال:

    شكرا جدا احلى مدونة وبستفيد منها جدا الله يكرمك

اترك تعليقاً

This site uses Akismet to reduce spam. Learn how your comment data is processed.