You are on page 1of 239

‫ب‬‫ط‬‫ت‬

‫بناء ي ات الأبدروبد‬
‫ق‬
‫يف نظم املعلومات اجلغرافية‬
‫(اجلزء األول)‬

‫د‪ /‬رشا صابر نوفل‬

‫‪2022/ 2021‬‬
‫بناء تطبيقات األندر ويد‬

‫يف نظم املعلومات اجلغرافية‬

‫اجلزء األول‬

‫د‪ /‬رشا صابر نوفل‬

‫مجيع احلقوق حمفوظة للمؤلف‬

‫ال يجوز نشر جزء من هذا الكتاب أو طباعته أو نقله‬

‫أو ترجمته بأي طريقة دون موافقة المؤلف الخطية‬

‫‪2022 - 2021‬‬
‫بسم هللا الرحمن الرحيم‬

‫"وقل رب زدنى علما"‬

‫صدق هللا العظ مي‬


‫سورة طه اآلية ‪114‬‬
‫اهداء‬
‫ي‬‫س‬‫ال سك ف‬
‫إلى روح و دى ا به الله ح ابه‬
‫ن‬ ‫ج‬

‫إلى امى اطال الله فى عمرها‬


‫إلى منلى الأعلى الأسناذ الدكيور جمعه ذاواذ‬
‫إلى ابنائى اسماء واذهم‬
‫تقديم‬

‫بسم اهلل الرمحن الرحيم والصالة والسالم على أشرف اخللق سيدنا ونبينا حممد صل اهلل عليه وسلم أما بعد؛ جاء هذا الكتاب " بناء‬

‫تطبيقات األندرويد يف نظم املعلومات اجلغرافية ؛ ليوضح األساسيات اليت جيب معرفتها عند بناء تطبيقات األندرويد واليت تستخدم‬

‫كتطبيقات لنظم املعلومات اجلغرافية ؛ فتزايد استخدامات األندرويد وانتشاره مع العامة ؛ مع أمهيته ومرونته يف التعامل ؛ ظهرت‬

‫تطبيقات األندرويد واملتخصصة يف نظم املعلومات اجلغرافية ؛ سواء تطبيقات خاصة جبمع البيانات من امليدان ؛ أو التطبيقات اخلاصة‬

‫بتحليل البيانات ؛ أو التطبيقات اخلاصة بالتنبؤ باألحوال اجلوية وحالة الطقس ؛ والعديد من التطبيقات األخرى ‪.‬‬

‫وللتطرق اىل كيفية بناء تطبيقات األندرويد بصفة عامة والتطبيقات املتخصصة يف نظم املعلومات اجلغرافية بصفة خاصة جيب معرفة‬

‫بعض األساسيات ولذا جاء الباب األول من الكتاب بأساسيات لغة اجلافا؛ وهى اللغة اليت نستخدمها فى التطبيقات باألبواب التالية من‬

‫الكتاب ؛ والباب الثاني شرح كيفية التعامل مع األندرويد أستوديو وكيفية ضبط إعدادات التطبيق اخلاص بى وكيفية اختيار‬

‫الشكل املناسب له " باستخدام لغة اجلافا" ؛ والباب الثالث واألخري عن تطبيقات األندرويد فى نظم املعلومات اجلغرافية ؛ فى البداية‬

‫نعرض كيفية استخدام خرائط جوجل ؛ ثم استخدام خرائط ‪ open Street map‬؛ ثم انشاءتطبيقات االندرويد‬

‫باستخدام‪ ArcGIS Runtime SDK‬واخريا انشاء تطبيق للحصول على بيانات الطقس ‪.‬‬

‫واهلل وىل التوفيق‬

‫رشا نوفل‬
‫فهرس الموضوعات‬

‫رقم الصفحة‬ ‫املوضوع‬

‫أ‬ ‫اآلية القرآنية‪.‬‬

‫ب‬ ‫إهداء‪.‬‬

‫ج‬ ‫تقديم ‪.‬‬

‫د‬ ‫فهرس الموضوعات‪.‬‬


‫‪1‬‬ ‫مقدمة ‪.‬‬
‫‪2‬‬ ‫الباب األول ‪ :‬أساسيات لغة اجلافا ‪.‬‬
‫‪4-3‬‬ ‫مقدمة ‪.‬‬
‫‪15-5‬‬ ‫الفصل األول ‪ :‬ماهية لغة الجافا‪.‬‬
‫‪23-16‬‬ ‫الفصل الثاني المتغيرات في لغة الجافا ‪.variables‬‬

‫‪30-24‬‬ ‫الفصل الثالث العوامل والشروط في لغة الجافا‪.‬‬


‫‪36-31‬‬ ‫الفصل الرابع‪ :‬الحلقات التكرارية في الجافا ‪.Loops‬‬

‫‪39-37‬‬ ‫الفصل الخامس‪ :‬المصفوفات ‪ Array‬في لغة الجافا‪.‬‬


‫‪43-40‬‬ ‫الفصل السادس الدوال فى لغة الجافا ‪.Method‬‬
‫‪47-44‬‬ ‫الفصل السابع‪ :‬الكائن والكالس في الجافا‪.‬‬
‫‪48‬‬ ‫الباب الثاني ‪ :‬تعلم برجمة األندرويد باألندرويد استوديو‬
‫‪49‬‬ ‫مقدمة‪.‬‬
‫‪67-50‬‬ ‫الفصل الثامن‪ :‬تهيئة العمل باألندر ويد استوديو‪.‬‬
‫‪70 – 68‬‬ ‫الفصل التاسع ‪:‬المتغيرات في االندرويد استوديو‪.‬‬
‫‪83-71‬‬ ‫الفصل العاشر ‪:‬تغيير خلفيات العناصر ‪.‬‬
‫‪105-84‬‬ ‫الفصل الحادي عشر‪ Web view :‬في االندرويد استوديو‪.‬‬
‫‪110-106‬‬ ‫الفصل الثاني عشر ‪ :‬تحويل موقع الويب الى تطبيق اندرويد‪.‬‬
‫‪117-111‬‬ ‫تغيير صورة واجهة التطبيق الخاص بي‪.‬‬
‫‪130-118‬‬ ‫الفصل الثالث عشر ‪ :‬انشاء تطبيق بواجهات متعددة‪.‬‬
‫‪134 -130‬‬ ‫العرض األفقي للواجهة في التطبيق‪:‬‬
‫‪137- 135‬‬ ‫استخراج ملف ‪ APK‬من المشروع المقام على‬
‫االندرويد استوديو‪.‬‬
‫‪138‬‬ ‫الباب الثالث ‪ :‬تطبيقات األندرويد فى نظم املعلومات اجلغرافية‬
‫‪139‬‬ ‫مقدمة‪.‬‬
‫‪153 - 140‬‬ ‫الفصل الرابع عشر التعامل مع خرائط جوجل في االندرويد استوديو‪.‬‬
‫‪168 - 154‬‬ ‫الفصل الخامس عشر ‪ :‬استخدام خريطة ‪.open street map‬‬
‫‪169‬‬ ‫الفصل السادس عشر‪ :‬تطبيقات االندرويد باستخدام‪: ArcGIS Runtime SDK‬‬
‫‪175- 170‬‬ ‫عرض خريطة األساس على التطبيق ‪.‬‬
‫تغيير خريطة األساس‪.‬‬
‫‪175‬‬
‫‪On Touch Listener‬‬
‫‪177‬‬
‫إضافة االرجاع الجغرافي للخريطة ‪.‬‬
‫‪179‬‬
‫عرض ثالثي األبعاد على االندرويد‪.‬‬
‫‪181‬‬
‫‪Camera‬‬
‫‪185‬‬
‫إضافة طبقات للتطبيق الخاص بى ‪.‬‬
‫‪187‬‬
‫إضافة قائمة مهام الى الخريطة‪.‬‬
‫‪208-193‬‬
‫‪229- 209‬‬ ‫الفصل السابع عشر‪ :‬انشاء تطبيق للحصول على بيانات الطقس‪.‬‬

‫‪231-230‬‬ ‫قائمة املراجع واملصادر‬


‫د‪ /‬رشا صابر نوفل‬ ‫مقدمة‬ ‫بناء تطبيقات االندرويد يف نظم املعلومات اجلغرافية‬

‫مقدمة‪:‬‬

‫لقد غيرت تكنولوجيا الهواتف المحمولة بشكل كبير طريقة تواصلنا وتفاعلنا مع العالم الخارجي؛ فمع زيادة‬

‫استخدام الهواتف المحمولة وتقدم تقنيات معلومات اتصاالت المعلومات ‪ ،‬ظهرت نظم المعلومات الجغرافية‬

‫المتنقلة لتوفير جمع البيانات في الوقت الحقيقي وتحديثها ‪ ،‬وجعلت الوصول إلى نظم المعلومات الجغرافية‬

‫أسرع وأكثر سهولة ؛ فاندماج نظم المعلومات الجغرافية مع الهواتف المحمولة قامت على توسيع عمليات جمع‬

‫البيانات وتحليلها ؛ حيث أصبح الميدانيين لديهم القدرة على جمع البيانات المكانية وتخزينها وتحريرها ومعالجتها‬

‫وتحليلها وعرضها بطريقة سهلة وغير مكلفة وفعالة‪.‬‬

‫وبمعنى أخر أن تطبيقات الهواتف الذكية المحمولة فى نظم المعلومات الجغرافية تساعدنا على الوصول الى‬

‫قواعد البيانات في أي وقت وأي مكان ؛ والفكرة تكون فى أن النظام يكون متوفر على ويب والبيانات موجودة‬

‫على ‪ SERVER‬؛ والمستخدمين قادرين على الوصول الى البيانات والنظام بأكمله من خالل هواتفهم ‪.‬‬

‫وفى هذا الكتاب نوضح كيفية الدخول الى عالم برمجة تطبيقات األندرويد المتعلقة بنظم المعلومات‬
‫الجغرافية‪.‬‬

‫‪1‬‬
‫الباب الأول‬

‫اساسباب لغة الجافا‬


‫د‪ /‬رشا صابر نوفل‬ ‫مقدمة‬ ‫الباب األول‪ :‬أساسيات لغة اجلافا‬

‫مقدمة‪:‬‬

‫البرمجة‪ :‬هي عملية كتابة تعليمات وأوامر محددة نخبر به الحاسوب بما يجب تنفيذه؛ وهي أداتنا الوحيدة‬
‫لتحويل المتطلبات البشرية الى برامج حاسوبية‪.‬‬

‫وجهاز الحاسب األلى؛ عبارة عن جهاز الكتر ونى يفهم قيمتين فقط هما تيار كهربائي يمر وتيار كهربائي ال‬
‫يمر وهو ما يسمى في الفيزياء ("دائرة مفتوحة ودائرة مغلقة ")؛ هذا التسلسل ينتج منه بيانات هذه البيانات حتى‬
‫يتم معالجتها بالحاسب األلى يتم تمثيلها بشكل ثنائي (صفر؛ واحد) ويسمى بالنظام الثنائي " ‪.binary System‬‬

‫وهذا يشكل صعوبة عند طلب تنفيذ األوامر من الحاسوب فال يستطيع العنصر البشرى ترجمة األمر الى‬
‫(‪ )0,1‬لذلك يأتي دور لغات البرمجة‪.‬‬

‫لغات البرمجة‪:‬‬

‫اللغة بصفة عامة هي وسيلة للتعبير عن األفكار وتسجيلها؛ وهناك لغات من حولنا ال تطلب التحدث مثل لغة‬
‫الجسد فهي قادرة على التعبير عن مشاعرنا دون قول كلمة واحدة‪.‬‬

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

‫فأجهزة الكمبيوتر تحتاج إلى لغة وتسمى هذه اللغة بلغة اآللة وتعتبر هذه اللغة لغة بدائية فجميع أجهزة‬
‫الكمبيوتر حتى المعقد منها للغاية من الناحية التقنية تخلو من الذكاء؛ فيمكن وصف الكمبيوتر بالكلب المدرب‬
‫تدريب عالي فهو يستجيب فقط لألوامر؛ وتسمى قائمة األوامر بالـ ‪ IL‬أو ‪.ILS‬‬

‫فلغة البرمجة هي اللغات الوسيطة بين االنسان والحاسب األلى وهى اللغة التي يفهمها الحاسب االلى ؛‬
‫وهناك لغات البرمجة المنخفضة المستوى واللغات العالية المصدر مثل لغة الجافا‪.‬‬

‫طرق التحويل من لغة برمجة عالية المصدر إلى لغة اآللة ‪-:‬‬

‫التحويل البرمجى ‪ :‬حيث يتم ترجمة البرنامج المصدر مرة واحدة وبذلك يتم تكرار هذا اإلجراء فى كل مرة نقوم‬
‫فيها بالتعديل على التعليمات البرمجية‪.‬‬

‫ترجمة ‪ :‬حيث يتم ترجمة البرنامج فى كل مرة يتم تشغيله ؛ ويطلق على البرنامج الذى يقوم بهذا األداء "‬
‫مترجماً" حيث يفسر الشفرة فى كل مرة يعتزم فيها تشغيل البرنامج‪.‬‬

‫‪3‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫مقدمة‬ ‫الباب األول‪ :‬أساسيات لغة اجلافا‬

‫المترجم نوعيين‪:‬‬

‫‪ :Interpreter‬حيث يتم إدخال الكود اليه ويخرجه فى صورة يفهمها الجهاز " الـ ‪ out put‬؛ يحدد الخطأ‬
‫ومكانه بمجرد الحصول علي خطأ يتوقف حتي اصالح الخطأ‪.‬‬

‫‪ :Compiler‬يأخذ الكود ويحوله إلى ‪ Object code‬ثم إلى ‪ Executor‬ثم المخرج النهائي ؛ هذا المترجم‬
‫يقوم بإظهار الخطأ ويكمل عملية الترجمة ؛ ويظهر الخطأ مجمع‪.‬‬

‫جاء هذا الباب ليشرح أساسيات هذه اللغة من خالل سبعة فصول بداية من معرفة كيفية انشاء ملف جافا؛‬
‫المتغيرات؛ العوامل ؛ الشروط ؛ الحلقات التك اررية ؛ الدوال ؛المصفوفات ؛‪ Class‬و ‪. object‬‬

‫‪4‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫ماهية لغة اجلافا‬ ‫الفصل األول‬

‫الفصل األول‪ :‬ماهية لغة اجلافا‬

‫الجافا ‪ :Java‬هي لغة برمجة عالية المستوى ابتكرها ‪ James Gosling‬في عام ‪ 1991‬أثناء عمله في‬
‫مختبرات شركة ‪ Sun Microsystems‬وذلك الستخدامها بمثابة العقل المفكر المستخدم لتشغيل األجهزة‬
‫الذكية‪.‬‬
‫عام ‪ 1995‬تم تطويرها لبناء تطبيقات للويب؛ السيرفرات؛ سطح المكتب؛ الهواتف والروبوتات‪.‬‬

‫شكل يوضح طريقة عمل برنامج مكتوب بلغة الجافا‪.‬‬

‫‪https://harmash.com/java/java-environment-setup/‬‬

‫لغة برمجة يمكن استخدامها لـ‬

‫‪ -‬عمل تطبيق يعمل على مواقع الويب‪.‬‬


‫‪ -‬برامج سطح المكتب مثل برامج الفوتوشوب‪.‬‬
‫‪ -‬تصميم العاب لالندرويد‪.‬‬
‫‪ -‬انترنت األشياء‪.‬‬
‫‪ -‬العديد من التطبيقات األخرى‪.‬‬

‫أهمية لغة الجافا‪:‬‬

‫‪ -‬لغة قوية حيث يمكن من خاللها برمجة تطبيقات قوية وخالية من األخطاء مع وجود ميزة تعديل األخطاء‬
‫أثناء البرمجة‪.‬‬
‫‪ -‬متعددة االستخدامات‪.‬‬

‫‪5‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫ماهية لغة اجلافا‬ ‫الفصل األول‬

‫‪ -‬يمكن تنفيذ تطبيق يعمل على أكثر من األنظمة مثل ‪Android ,Unix ,Linux ,OS Mac ,Windows‬‬
‫إلخ‪.‬‬
‫‪ -‬التطبيقات والبرامج المكتوبة بلغة الجافا تعمل بشكل سريع ألن معالجة الجافا سريعة‪.‬‬

‫يتم حفظ ملف الجافا بامتداد دوت جافا ويقوم الـ ‪ Compiler‬بتحويل الملف الى ‪ Byte code‬ثم يقوم ‪JVM‬‬
‫؛ بالتحويل الى أوامر يفهماه نظام التشغيل لتنفيذ األوامر المطلوبة ‪.‬‬

‫‪ : JVM‬اختصار ‪ Java Virtual Machine‬؛ ( جهاز الجافا االفتراضي)‪.‬‬

‫‪ : JRE‬اختصار لـ ‪Java Runtime Environment‬؛ ( بيئة تشغيل الجافا) والتي تتيح تشغيل برامج‬
‫الجافا على نظام التشغيل ؛ وهى تحتوى على ‪.JVM‬‬

‫‪ : JDK‬اختصار لـ ‪ Java Development Kit‬؛ حزمة تطوير الجافا التي يستخدمها المطور لتطوير‬
‫برامج بلغة الجافا والتي تحتوى على ‪. JRE‬‬

‫تجهيز بيئة العمل ‪:‬‬

‫‪6‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫ماهية لغة اجلافا‬ ‫الفصل األول‬

‫نقوم بعمل ‪. Run‬‬

‫‪7‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫ماهية لغة اجلافا‬ ‫الفصل األول‬

‫بدء العمل مع ‪: Visual Studio Code‬‬

‫نفتح الـ ‪ Visual Studio Code‬نقوم بعمل ملف جديد يتم حفظ الملف بامتداد ) ‪ ) .java‬؛‬

‫‪0‬‬

‫‪8‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫ماهية لغة اجلافا‬ ‫الفصل األول‬

‫نقوم بكتابة أول كود في الجافا وذلك على النحو التالى ؛‬

‫‪ -‬كتابة ‪ class‬؛ واختيار من القائمة المنسدلة ( مراعاة كتابة األحرف صغيرة)؛ ووضع اسم للـ ‪class‬‬
‫"يفضل تسمية اسم الـ ‪ Class‬األساسى بنفس اسم مجلد الجافا النه قد يعطى خطأ "‬
‫‪ -‬كتابة األمر ‪main‬‬

‫‪ -‬كتابة األمر ‪ System‬مع مراعاة الحرف األول كبير؛ ثم ‪ out‬ثم ‪ printIn‬ووضع الكلمة المراد‬
‫طباعتها‪.‬‬
‫‪-‬‬ ‫;)"‪System.out.println("Rasha_Nofal‬‬

‫لتصبح النافذة على النحو التالي؛ يتم اختيار ‪ Run‬من النافذة‬

‫‪9‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫ماهية لغة اجلافا‬ ‫الفصل األول‬

‫فيتم الطباعة على النحو الموضح أدناه‬

‫ملحوظة‪ :‬ال يدعم الجافا طباعة األحرف العربية؛ فإذا تم كتابة الحروف بالعربية للطباعة تظهر على‬
‫شكل حروف غير مرتبة على النحو التالي؛‬

‫‪10‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫ماهية لغة اجلافا‬ ‫الفصل األول‬

‫ولحل هذه المشكلة يتم ضبط اإلعدادات وذلك من ‪ View‬ثم ‪Extensions‬؛‬

‫من ‪Debugger for Java‬؛ ومن ترس االعدادات؛ نختار ‪Extensions Settings‬‬

‫‪11‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫ماهية لغة اجلافا‬ ‫الفصل األول‬

‫نختار عرض النتيجة على ‪console‬‬

‫بعد ذلك عند عمل ‪Run‬؛ تظهر الطباعة في جزء ‪ CONSOLE‬كما موضح أدناه؛‬

‫‪12‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫ماهية لغة اجلافا‬ ‫الفصل األول‬

‫كتابة تعليقات داخل الجافا‪:‬‬


‫التعليق‪ :‬هي عبارات يتم كتابتها داخل الملف البرمجي لشرح ما يتم كتابته من أكواد حتى يتسنى للمطور فهم‬
‫الخطوات واألكواد فيما بعد ‪.‬‬
‫لعمل تعليق من سطر واحد ‪ // :‬ثم كتابة التعليق‪.‬‬
‫لعمل تعليق أكتر من سطر ‪:‬‬

‫*‪/‬‬
‫هنا يتم كتابة التعليقات‬
‫فى أكثر من سطر‬
‫‪*/‬‬
‫انشاء الـ ‪ Class‬داخل الجافا‪:‬‬
‫معنى ‪ :class‬هي عبارة عن اسم يحمل مجموعة من الخصائص؛ ويمكن تعريفها بانها حاوية كبيرة تحتوى‬
‫على الكود كله " متغيرات – دوال ‪ ....‬الخ ‪.‬‬
‫كتابة ‪class‬؛ ثم اختيار اسم له مع االخذ في االعتبار ما يلى‪:‬‬
‫‪ -‬ال يوجد مسافات عند كتابة االسم‪.‬‬
‫‪ -‬ال يمكن استخدام الرموز واألشكال‪.‬‬
‫‪ -‬ال يمكن أن يبدأ االسم برقم‪.‬‬
‫‪ -‬يفضل ان يكون اسم بنفس اسم ملف الجافا الذي تم إنشاؤه‪.‬‬

‫‪13‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫ماهية لغة اجلافا‬ ‫الفصل األول‬

‫بعد ذلك يتم انشاء ‪ method‬داخل الكالس ؛ وليكن ‪ main‬؛ وداخل عنصر هذا ال‪ method‬يتم كتابة األوامر‬
‫المطلوب تنفيذها ويتم تنفيذها بمجرد الضغط على ‪ Run‬؛ بينما ‪ Debug‬فتعنى إيجاد األخطاء‪.‬‬

‫لعرض البيانات بالجافا يتم عن طريق عنصر ) ( ‪ System.out.printIn‬وداخل األقواس يتم كتابة‬
‫البيانات المراد طباعتها على حسب نوعها فلو بيانات نصية يتم وضعها داخل " " ‪.‬‬

‫ملحوظة‪ :‬قد يظهر خطأ عند عمل ‪ Run‬؛‬

‫ويتم حل هذا الخطأ من قائمة ‪ file‬؛ ثم اختيار ‪ open folder‬؛ واختيار ملف الجافا المستخدم ؛ ثم‬
‫‪ select folder‬؛ ثم اختيار‬

‫‪14‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫ماهية لغة اجلافا‬ ‫الفصل األول‬

‫الفرق بين ‪ printIn‬؛ ‪: print‬‬

‫‪ : PrintIn‬يتم طباعة األوامر كل أمر فى سطر جديد ‪.‬‬

‫‪ : Print‬يتم الطباعة فى نفس السطر ‪.‬‬

‫‪15‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫املتغريات يف لغة اجلافا‬ ‫الفصل الثاني‬

‫الفصل الثاني املتغريات يف لغة اجلافا‪variables :‬‬


‫المتغير‪ :‬هو عبارة عن اسم يحمل قيمة أو بيانات محددة؛ سواء قيمة نصية أو رقمية؛ وعند اختيار اسم‬
‫المتغير ال بد من األخذ في االعتبار ما يلى‪:‬‬

‫‪ -‬يبدأ اسم المتغير بحرف صغير‪.‬‬


‫‪ -‬يمكن أن يبدأ اسم المتغير بعالمة _ أو ‪.$‬‬
‫‪ -‬ال يمكن أن يبدأ اسم المتغير باألشكال والرموز أو يحتوى عليها ماعدا _ و ‪.$‬‬
‫‪ -‬لغة الجافا حساسة جدا في حالة األحرف فينبغي التركيز عند الكتابة‪.‬‬
‫‪ -‬ال يبدأ اسم المتغير برقم ‪.‬‬
‫‪ -‬ال يمكن استخدام المسافات في اسم المتغير‪.‬‬
‫‪ -‬ال يمكن استخدام الكلمات المحجوزة في الجافا " وهي تكتب باللون األزرق او البنفسج"‪.‬‬
‫الكلمات المحجوزة في لغة الجافا‪.‬‬

‫‪16‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫املتغريات يف لغة اجلافا‬ ‫الفصل الثاني‬

‫المتغيرات أنواع هي‪:‬‬

‫المتغيرات النصية‪Strings :‬‬

‫يتم كتابة المتغيرات النصية عن طريق كتابة‬

‫‪ " String‬مع مراعاة حرف ‪ S‬من األحرف الكبيرة " ثم كتابة اسم المتغير ثم كتابة قيمة المتغير داخل " ثم‬
‫انهاء السطر بـ ;‬

‫يتم عرض البيانات عن طريق عنصر ‪System‬؛ وذلك على النحو الموضح؛‬

‫ولطباعة قيمة المتغير مع وجود األقواس " " يتم ذلك عن طريق "\" اسم المتغير\"" ؛ كما موضح‬

‫‪17‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫املتغريات يف لغة اجلافا‬ ‫الفصل الثاني‬

‫وإلضافة النص فى سطر جديد يتم ذلك عن طريق كتابة ‪ \n‬؛ حرف الـ ‪ n‬اختصار لـ ‪new line‬‬

‫‪ : \t‬يتم اضافتها لمحاذة النص قليال‪.‬‬

‫لكتابة النص باألحرف الكبيرة يستخدم ‪.)toUpperCase ( method‬‬

‫‪18‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫املتغريات يف لغة اجلافا‬ ‫الفصل الثاني‬

‫ولتغيير الى األحرف الصغيرة ‪. toLowerCase‬‬

‫ولمعرفة عدد األحرف فى النص يستخدم األمر ‪. length‬‬

‫ملحوظة ‪ :‬عدد األحرف فى النص ‪ 10‬؛ وتم كتابة العدد ‪ 11‬وذلك ألن الجافا تحسب المسافة ‪.‬‬

‫تستخدم ‪ : indexof‬لمعرفة مكان حرف معين أو كلمة محددة داخل ملف الجافا؛ حيث يتم عرض المكان‬
‫بالرقم ( الحرف رقم ‪ 6‬مثال) ؛ مع األخذ فى االعتبار أنه إذا تكرر الحرف فى أكثر من موقع يتم ذكر مكان‬
‫أول تمركز ألول حرف يقابله‪.‬‬

‫‪19‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫املتغريات يف لغة اجلافا‬ ‫الفصل الثاني‬

‫لدمج النصوص فى متغيرات مختلفة ‪:‬‬

‫يمكن ذلك عن طريق استخدام ‪+‬‬

‫ويمكن أيضاً عن طريق ؛ ‪ .contact‬كما موضح‬

‫‪20‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫املتغريات يف لغة اجلافا‬ ‫الفصل الثاني‬
‫المتغيرات الرقمية‪:‬‬

‫وهى نوعان ‪ integer‬لألرقام الصحيحة و ‪ float‬لألرقام العشرية ‪.‬‬

‫وهناك مجموعة من المتغيرات الرقمية ‪ integer‬حسب قيمة الرقم ؛ فهناك‬

‫‪ -‬بايت ‪ : byte‬يستخدم لألرقام الصغيرة (‪ ) bits 8‬؛ ( األرقام ‪ 2‬مع القوة ‪ 2 " 7‬أس ‪ )" 7‬؛ أي‬
‫ان أصغر عدد يتم تخزينه يكون ( ‪ 127‬؛ ‪.) 127-‬‬
‫‪ : Short -‬وتكون (‪. ) bits 16‬‬
‫‪ : Int -‬ويكون (‪( .) bits 32‬أي الرقم ‪ 2‬مع القوة ‪ )"2^31 " 31‬أي أكبر عدد يتم تخزينه هو‬
‫‪.2147483648‬‬
‫‪ : Long -‬يكون (‪.)bits 64‬‬

‫طريقة انشاء متغير رقمى فى الجافا ‪:‬‬

‫‪ -‬يتم تحديد نوع المتغير الرقمى أوال " أي نوع من األنواع السابقة"‬
‫‪ -‬يتم كتابة اسم المتغير ‪.‬‬
‫‪ -‬يتم تحديد قيمة المتغير ‪.‬‬

‫اذا تم كتابة رقم غير مطابق لنوع المتغير يظهر خطأ؛‬

‫‪21‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫املتغريات يف لغة اجلافا‬ ‫الفصل الثاني‬

‫أما بالنسبة للمتغيرات الرقمية من نوع ‪:float‬‬

‫فى نوعان ‪ : float‬لتخزين ‪. " bites 32‬‬

‫ملحوظة ‪ :‬يتم كتابة حرف ‪ f‬بعد كتابة قيمة المتغير ‪.‬‬

‫‪ : Doubles‬لتخزين ‪ .bites 64‬وتكتب كما يتضح من نافذة الشاشة التالية‪.‬‬

‫المتغيرات من نوع ‪: character‬‬

‫‪ -‬تستخدم لتخزين الرموز واألشكال الخاصة أو لتخزين رقم واحد أو حرف واحد وحتى األشكال‬
‫والرموز رمز واحد فقط‪.‬‬
‫‪ -‬تكتب فى الجافا ‪. char‬‬

‫‪22‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫املتغريات يف لغة اجلافا‬ ‫الفصل الثاني‬

‫المتغيرات من نوع ‪: Boolean‬‬

‫وهى المتغيرات التي تحمل بيانات من نوع ‪ true‬أو ‪ false‬؛‬

‫‪23‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫العوامل والشروط يف لغة اجلافا‬ ‫الفصل الثالث‬

‫الفصل الثالث ‪ :‬العوامل والشروط يف لغة اجلافا‪:‬‬

‫العوامل الرياضية أو الحسابية " ‪ :"Arithmetic Operators‬وتضم الطرح ‪ -‬والجمع ‪ +‬والضرب *‬


‫والقسمة" و ‪ %‬و – ‪ -‬و ‪ ++‬و = ‪ -‬و = * و =‪. /‬‬

‫تستخدم ‪ - -‬لطرح رقم من الناتج ؛ ‪ + +‬إلضافة رقم للناتج ؛ تكتب كما موضح‬
‫;‪int y = 12‬‬
‫;‪y--‬‬
‫أو‬ ‫;‪--y‬‬
‫;‪++y‬‬
‫أو‬ ‫;‪y++‬‬
‫;)‪System.out.println( y‬‬
‫}‬
‫}‬

‫استخدام العوامل = ‪ -‬و = * و =‪. /‬‬

‫‪24‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫العوامل والشروط يف لغة اجلافا‬ ‫الفصل الثالث‬

‫العوامل التي تستخدم في المقارنات (‪: )Comparison Operators‬‬


‫وتشمل == تساوى ؛ ال تساوى =! ؛ < أكبر من ؛ > أصغر من ؛ =< أكبر من أو يساوى ؛ => أصغر‬
‫من أو يساوى ‪.‬‬

‫العوامل التي تستخدم في وضع شروط منطقية (‪:)Logical Operators‬‬


‫وهى && وتعنى ‪ and‬؛ || وهى بمعنى ‪ or‬؛ ! وتعنى ال يساوى ( يتم عرض طرق كتابتهم فى الدروس‬
‫التالية )‪.‬‬

‫‪25‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫العوامل والشروط يف لغة اجلافا‬ ‫الفصل الثالث‬

‫العوامل التي تستخدم إلعطاء قيم للمتغيرات (‪:)Assignment Operators‬‬

‫‪https://harmash.com/java/java-operators/‬‬ ‫المصدر‪:‬‬

‫العوامل التي تستخدم للتعامل مع الـ ‪:)Bitwise Operators( bits‬‬

‫‪https://harmash.com/java/java-operators/‬‬ ‫المصدر‪:‬‬

‫‪26‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫العوامل والشروط يف لغة اجلافا‬ ‫الفصل الثالث‬

‫اجلمل الشرطية يف لغة اجلافا‪:‬‬

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

‫تطبيق (‪:) IF ……. Else‬‬

‫معناها إذا كان الشرط صحيح نفذ الكود ؛ وإذا كان الشرط خطأ نفذ كود أخر؛ وتكتب كما يلى‬
‫{) ( ‪if‬‬

‫}‬
‫{‪else‬‬

‫}‬

‫وإذا أردنا كتابة شرطان داخل الجملة الشرطية يتم إضافة ‪else if‬‬
‫{) ( ‪if‬‬

‫}‬
‫{)(‪else if‬‬

‫}‬
‫{‪else‬‬

‫}‬
‫}‬
‫}‬

‫مثال توضيحى ‪:‬‬

‫‪27‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫العوامل والشروط يف لغة اجلافا‬ ‫الفصل الثالث‬

‫تستخدم العوامل فى الجمل الشرطية سواء العوامل المنطقية وهى‬

‫= = ‪ :‬وتعنى يساوى ‪.‬‬

‫=! ‪ :‬ال يساوى ‪.‬‬

‫= < ‪ :‬أصغر من أو يساوى ‪.‬‬

‫=> ‪ :‬أكبر من أو يساوى ‪.‬‬

‫< ‪ :‬أصغر من ‪.‬‬

‫‪:‬أكبر من ‪.‬‬ ‫>‬

‫‪28‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫العوامل والشروط يف لغة اجلافا‬ ‫الفصل الثالث‬

‫أو العوامل الشرطية وهى ‪:‬‬

‫&& ‪ : and‬تستخدم الضافة أكثر من شرط داخل ‪ if‬الواحدة ؛ وينبغى تنفيذ الشرطين الموجودين داخل‬
‫الجملة الشرطية ‪.‬‬

‫‪29‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫العوامل والشروط يف لغة اجلافا‬ ‫الفصل الثالث‬

‫|| ‪ : or‬تستخدم في حالة اذا أردنا أحد الشرطين فقط صحيحة ‪.‬‬

‫! ‪ : not‬ووضعها يعنى أنه فى حالة تحقق الشرط لن يتم التنفيذ ؛ واذا لم يتحقق الشرط يتم التنفيذ؛‬

‫وتكتب كما موضح بالشاشة التالية ؛‬

‫‪30‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫احللقات التكرارية يف اجلافا‬ ‫الفصل الرابع‬

‫الفصل الرابع‪ :‬احللقات التكرارية يف اجلافا ‪:Loops‬‬

‫نستخدم الحلقات ( ‪ ) Loops‬بهدف تكرار نفس الكود عدة مرات ؛ أي أن أي كود نريده أن يتنفذ عدة مرات‬
‫نقوم بكتابته داخل حلقة فتقوم هي بإعادة تنفيذ الكود قدر ما شئنا ضمن شروط معينة نقوم نحن بتحديدها‪.‬‬

‫أنواع الحلقات في الجافا‪:‬‬

‫‪ : For Loop‬ستخدم الحلقة ‪ for‬في حال كان عدد المرات التي سيعاد فيها تنفيذ الكود معروفا ؛ ويتم‬
‫كتابته كما يلى ؛‬

‫‪31‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫احللقات التكرارية يف اجلافا‬ ‫الفصل الرابع‬
‫‪ :While Loop‬يفضل استخدام الحلقة ‪ while‬في حال كان عدد المرات التي سيعاد فيها تنفيذ الكود غير‬
‫معروف‪.‬‬

‫‪ : Do While Loop‬يفضل استخدام الحلقة ‪ do while‬في حال كان عدد المرات التي سيعاد فيها تنفيذ‬
‫الكود غير معروف و بنفس الوقت يجب أن يتنفذ مرة واحدة على األقل‬

‫وفى هذه الحالة يتم تنفيذ الشرط داخل الـ ‪ do‬أوال ثم يتحقق من الشرط في ‪ while‬؛ وتكتب كما يلى؛‬

‫‪32‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫احللقات التكرارية يف اجلافا‬ ‫الفصل الرابع‬

‫استخدام ‪ continue‬و ‪ break‬في‪: loop‬‬


‫الجملة ‪ break‬فإنها‬ ‫تنفذ‬ ‫ان‬ ‫بمجرد‬ ‫الجملة ‪.switch‬‬ ‫في‬ ‫و‬ ‫‪loops‬‬ ‫في‬ ‫تستخدم‪break‬‬
‫توقف الـ ‪ scope‬بأكمله و تخرج منه و تمسحه من الذاكرة ثم تنتقل للكود الذي يليه في البرنامج‪.‬‬

‫‪33‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫احللقات التكرارية يف اجلافا‬ ‫الفصل الرابع‬
‫تستخدم ‪ continue‬مع الحلقات فقط " ‪ "loops‬؛ حيث نستخدمها لتجاوز تنفيذ كود معين في الحلقة‪.‬‬

‫الجملة ‪:switch‬‬
‫‪ switch‬نستخدمها إذا كنا نريد اختبار قيمة متغير معين مع الئحة من االحتماالت نقوم نحن بوضعها‪ ,‬و إذا‬
‫تساوت هذه القيمة مع أي احتمال وضعناه ستتنفذ األوامر التي وضعناها في هذا االحتمال فقط‪.‬‬
‫كل احتمال نضعه يسمى ‪.case‬تكتب كما موضح ‪:‬‬

‫‪34‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫احللقات التكرارية يف اجلافا‬ ‫الفصل الرابع‬

‫ملحوظة‪ :‬لسنا بحاجة لوضع ‪ break‬للحالة األخيرة ألن البرنامج سيخرج من الجملة ‪ switch‬في جميع‬
‫األحوال‪.‬‬

‫في حالة أن نريد طباعة جملة في حالة عدم تطابق المتغير مع جميع الحاالت التي تم احتمالها ؛ يتم ذلك‬
‫عن طريق األمر ‪ default‬؛‬

‫‪35‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫احللقات التكرارية يف اجلافا‬ ‫الفصل الرابع‬

‫مثال أخر‪:‬‬

‫‪36‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫املصفوفات يف لغة اجلافا‬ ‫الفصل اخلامس‬

‫الفصل اخلامس‪ :‬املصفوفات ‪ Array‬يف لغة اجلافا‬

‫المصفوفة‪ :‬عبارة عن كائن يحتوي على مجموعة عناصر من نفس النوع يتم تخزينها بجوار بعضها في‬
‫الذاكرة؛ بمعنى آخر المصفوفة عبارة عن كائن يمكنه تخزين عدة قيم من نفس النوع‪.‬‬
‫يتم التمييز بين عناصر المصفوفة من خالل رقم محدد يعطى لكل عنصر يسمى بالـ ‪index‬؛ أول عنصر‬
‫فيها يتم تخزينه في الـ ‪ index‬رقم ‪.0‬‬

‫ملحوظة‪ :‬عدد عناصر المصفوفة ثابت؛ أي أنه بمجرد تحديده ال يمكننا تغييره ؛ لكن يمكن تغيير قيم هذه‬
‫العناصر في أي وقت‪.‬‬

‫فوائد الـ ‪: Array‬‬


‫‪ -‬تقليل عدد المتغيرات المتشابهة ؛ فمثالً إذا كنا نريد تعريف ‪ 10‬متغيرات نوعهم ‪ int‬نقوم بتعريف‬
‫مصفوفة واحدة تتألف من ‪ 10‬عناصر‪.‬‬

‫‪ -‬يسهل تطوير الكود فإذا قمنا بتخزين المعلومات داخل مصفوفة نستطيع تعديلهم و مقارنتهم أو‬
‫استدعاؤهم مرة واحدة بكود صغير جداً باستخدام الحلقات‪.‬‬

‫‪ -‬نستطيع الوصول ألي عنصر من خالل ‪.index‬‬


‫يمكن كتابة ‪ Array‬بهذه الطريقة‬

‫‪37‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫املصفوفات يف لغة اجلافا‬ ‫الفصل اخلامس‬
‫لكن إذا كانت البيانات يتم تنفيذها على طالب الجامعة كلهم فتصبح هذه الطريقة صعبة التنفيذ لذلك يتم‬
‫كتابة المصفوفة عن طريق الـ ‪ loop‬وتنفذ بهذه الطريقة ؛‬

‫ولعمل مصفوفة من البيانات الرقمية ؛‬

‫ملحوظة ‪ :‬إذا لم يتم عمل البرامج ويظهر خطأ على الرغم من الكتابة الصحيحة لألكواد ؛ إذن فيحتاج‬
‫البرنامج الى استدعاء مكتبة الـ ‪ Array‬؛ ويتم استدعاؤها كما يلى‬

‫‪38‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫املصفوفات يف لغة اجلافا‬ ‫الفصل اخلامس‬
‫;‪import java.util.Arrays‬‬
‫‪ For each‬فى الجافا ‪:‬‬

‫تستخدم لعرض بيانات الـ ‪ Array‬؛ فى المثال التالى ؛ تم تعريف متغير من نوع النصى وتم تسميته ؛‬
‫‪ Arc_GIS‬وتم وضع عناصره داخل مصفوفة ؛وتم وضع متغير ثاى داخل الـ ‪ for‬مع مراعاة أنه يجب أن‬
‫يكون من نفس النوع " نصى" ؛ وتم تسميته ‪ Geography‬؛ وطلبنا عرض البيانات الموجودة داخل هذا‬
‫المتغير الثانى‪ Geography‬؛ فنجده يشتق بيانات المتغير ‪ Arc_GIS‬كما موضح ‪.‬‬

‫‪ Object Array‬فى الجافا ‪:‬‬

‫لعمل ‪ Object‬من نوع ‪ Array‬؛‬

‫‪39‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫الدوال يف لغة اجلافا‬ ‫الفصل السادس‬

‫الفصل السادس الدوال فى لغة اجلافا ‪:Method‬‬


‫الدوال "‪ : "Method‬هي عبارة عن مجموعة أوامر مجمعة في مكان واحد و تتنفذ عندما نقوم باستدعائها؛‬
‫تحتوي الجافا على عدد كبير من الدوال الجاهزة التي يمكن استعمالها مباشرًة ‪.‬‬
‫يتم كتابة ‪ Method‬داخل الـ ‪ class‬؛ فالجدير بالذكر أن السطر األول الذى يتم إنشاؤه من األمر ‪ main‬؛‬
‫يعتبر ‪ Method‬؛ لكنها عامة‬
‫{ )‪public static void main(String[] args‬‬

‫والـ ‪ Method‬نوعان النوع األول ‪ void‬والنوع الثاني ‪return‬‬


‫الـ ‪ void‬يستخدم فى حالة أن ‪ Method‬ال يقوم بإعادة القيمة عندما يتم تشغيلها ‪.‬‬

‫مثال للـ ‪ Method‬من نوع ‪void‬‬

‫كما يمكن وضع ‪ parameter‬للـ ‪ Method‬على النحو الموضح ؛‬

‫‪40‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫الدوال يف لغة اجلافا‬ ‫الفصل السادس‬

‫‪:return‬‬ ‫الـ ‪ method‬من نوع‬

‫يستخدم عندما نريد إعادة البيانات عند التشغيل ؛ لذا يتطلب تحديد نوع البيانات قبل كتابة ‪method‬‬

‫مثال السترجاع بيانات رقمية‪:‬‬

‫‪41‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫الدوال يف لغة اجلافا‬ ‫الفصل السادس‬

‫‪ Local data‬فى لغة الجافا ‪:‬‬

‫يستخدم ‪ object‬الـ‪ Local data‬فى لغة الجافا لتحديد السنة والشهر واليوم ؛ الستخدام ‪ Local data‬؛‬
‫يتم كتابتها داخل الكالس ؛ نجد تلقائيا تم استيرادها ؛ ثم إعطائها اسم " تم تسميتها ‪ Local data‬؛ وذلك‬
‫على النحو الموضح ؛‬

‫‪42‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫الدوال يف لغة اجلافا‬ ‫الفصل السادس‬

‫استخدام ‪ try – catch- finally‬فى لغة الجافا ‪:‬‬

‫يتم كتابة ‪ try‬؛ ثم كتابة األوامر المراد تنفيذها‬

‫واخل األقواس يتم كتابة ‪ catch‬؛‬

‫وداخل الـ ‪ catch‬؛ يتم كتابة )‪ (Exception error‬وتعنى باستثناء ؛ وفائدتها انه فى حالة كتابة أوامر‬
‫خطأ يتم تنفيذ األوامر المتبقية دون تعطيل البرنامج ويستثنى األوامر الخاطئة ‪.‬‬

‫ثم نكتب األمر ‪ finally‬وداخله يتم كتابة األوامر المراد تنفيذها فى حالة وجود خطأ فى األوامر الموجودة‬
‫داخل الـ ‪catch‬‬

‫وللتوضيح أكثر تم وضع خطأ فى الـ ‪ try‬حيث تم طلب طباعة ‪ cars 6‬وطول البيانات ‪ 3‬فقط ؛ ونضع فى‬
‫الـ ‪ catch‬االمر المراد طباعته اذا وجد خطأ ؛ كما يتضح‬

‫‪43‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫الكائن والكالس يف اجلافا‬ ‫الفصل السابع‬

‫الفصل السابع‪ :‬الكائن والكالس يف اجلافا‪:‬‬

‫‪ : Class‬يمكن تعريف ‪ Class‬بمنتهى البساطة بأنها هى عبارة عن حاوية أو حقيبة يتم فيها جمع الدوال‬
‫والقيم الخاصة بالبيانات أيا كان نوعها ‪.‬‬

‫‪ Object:‬كل شيء في البرنامج الخاص بنا عبارة عن ‪ Object‬وله نوع محدد ؛ و ‪ Object‬هو نسخة‬
‫‪ Copy‬من ‪ class‬الخاصة بنا ‪.‬‬

‫حيث أن المبرمجين أثناء تنفيذهم للغة تخيلوا أن المستخدم يمكنه التعامل مع أنواع متعددة من البيانات ؛ فقد‬
‫تكون أرقام أو حروف ( ‪ ) String‬أو الدمج بينهم ولتعدد هذه البيانات تم عمل حقيبة لتحوى هذه البيانات‬
‫وتسمي ‪ class‬؛ وكل حقيبة ال بد وأن تتناسب مع البيانات التي تحويها ‪.‬‬

‫ويمكن الشرح بمثال هناك شركة سيارات تقوم بعمل تصميم للسيارة التي تنتجها وهذا التصميم يتم تطبيقه‬
‫باختالف األلوان ويمكن تطويره أيضاً ؛ فالتصميم األساسي للسيارة هو الـ ‪ class‬؛ والسيارات المختلفة المنتجة‬
‫من هذا التصميم تسمى ‪ Object‬؛ فهناك ‪ Object1‬و ‪ Object 2‬إلخ‪.‬‬

‫باإلضافة الى أن كل ‪ Object‬له ‪ Actions‬و ‪.Attributes‬‬

‫‪ Actions‬هى دوال مثلها مثل أى دوال لكنها بتوضع فى ‪ class‬ولذلك تسمى ‪ Actions‬؛ وأى ‪Actions‬‬
‫يعتبر ‪ Attribute‬؛ ولكن ‪ Attribute‬ال يعتبر‪ Actions‬الن ‪ Actions‬يكون فيها فعل ‪ action‬مثل فتح‬
‫الباب ؛ زيادة اإلضاءة و الـ ‪ Attribute‬ليس بها فعل فهى مجرد خاصية ‪.‬‬

‫‪ Attribute‬وتعرف أيضا بالـ ‪ properties‬هى مجرد قيمة أو خاصية توضع للـ ‪ object‬أو النسخة الخاصة‬
‫بي ‪.‬‬

‫يمكن تنفيذ ذلك فى ملف الجافا وذلك على النحو التالي ‪:‬‬

‫يتم انشاء ملفين جافا؛ ملف نسميه ‪ GIS_programes‬؛ وملف أخر نسميه ‪ programs_data‬؛‬

‫داخل ملف ‪ GIS_programes‬نقوم بإنشاء الـ ‪ class‬األساسى " يفضل تسميته بنفس اسم الملف كما‬
‫سبق وأن ذكرنا " ؛ فيتم تسميته ‪GIS_programes‬‬

‫داخل الـ ‪ class‬يتم كتابة األمر ‪main‬‬

‫‪44‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫الكائن والكالس يف اجلافا‬ ‫الفصل السابع‬

‫وفى الملف الثانى ‪ programs_data‬نقوم بعمل ‪ class‬نقوم بانشاء متغيرات داخل الـ ‪class‬؛ لتحتوى‬
‫على البيانات المراد اضافتها فى بيانات البرامج ؛ كاسم البرنامج ؛ تاريخ إصداره ؛ إمكانيات البرنامج؛ الخ ؛‬

‫للوصول الى بيانات هذا الملف من الملف األساسى يتم ذلك عن طريق إنشاء ‪ object‬باسم الـ ‪" class‬‬
‫‪ " program_data‬وإعطاءه اسم متغير وليكن‪ program 1‬؛ ثم نكتب األمر ‪ new‬ونحدد اسم األوبجيكت‬
‫مرة أخرى ؛‬

‫‪45‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫الكائن والكالس يف اجلافا‬ ‫الفصل السابع‬

‫؛ كل كما علينا بعد ذلك كتابة المتغير ‪ program 1‬دوت واستيراد البيانات المرادة من الملف األخر كما‬
‫موضح ؛‬

‫يتم تكرار ذلك للبرامج األخرى ؛ ولطباعة البيانات‬


‫"‪System.out.println("name"+ program1.name+"\n"+"Date‬‬
‫;) ‪+program1.Date+"\n"+"Capabilities"+program1.Capabilities‬‬

‫‪46‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫الكائن والكالس يف اجلافا‬ ‫الفصل السابع‬

‫ليصبح فى النهاية الملف على النحو الموضح بالصورة‬

‫‪47‬‬
‫الباب الباني‬
‫تعلم برمجة الأندر وند باستجدام الأندروند استود وت‬
‫د‪ /‬رشا صابر نوفل‬ ‫مقدمة‬ ‫الباب الثاني‪ :‬تعلم برجمة األندر ويد باستخدام األندرويد أستوديو‬

‫مقدمة‪:‬‬

‫االندرويد استوديو هو نظام مجانى لتطبيقات االندوريود (برنامج يتم من خالله كتابه برمجيات)‪ ،‬من قبل‬
‫شركة جوجل؛ هذه البيئة توفر لك مجموعه من المكتبات والتصاميم الجاهزة لعمل تطبيقات مخصصه تعمل‬
‫على نظام االندرويد يمتاز بسهولة االستخدام؛ المرونة؛ األكواد مختصرة ؛ يوفر ‪ unit testing‬؛ والتي تقوم‬
‫بفحص األكواد ‪.‬‬

‫قبل االندرويد استوديو كان يتم برمجة تطبيقات األندرويد على بيئة تسمى باكليبس‪ (Eclipse) ،‬؛ولكنها‬
‫كانت بيئة مجهده بعض الشيء‪ ،‬وكل خطوة كانت تحتاج انشاء التصاميم الخاصة بها ؛ بخالف بيئة اندرويد‬
‫التي توفر كميه كبيره من التصاميم الجاهزة ‪.‬‬
‫مميزات نظام االندرويد‪:‬‬

‫‪ -‬سهولة نشر التطبيق الخاص بك من خالل الجوجل ستور "متجر اندوريود" أو متجر األمازون‪.‬‬
‫‪ -‬بيئة التطوير مجانية‪.‬‬
‫‪ -‬الربح من التطبيقات‪.‬‬

‫وفيما يلى يتم عرض كيفية التعامل مع األندرويد استوديو وذلك فى ستة فصول بداية من تحميل النظام‬
‫والمتغيرات وتغيير خلفية التطبيق الخاص بى و كيفية عرض العناصر وتغيير خصائصها ومعرفة كيف يمكن‬
‫عمل تطبيق بواجهات متعددة ؛ وكيف يمكننا تحويل تطبيق ويب إلى تطبيق أندرويد واالنتهاء حتى يتم حفظ‬
‫الملف الخاص بنا واستخراج المشروع بملف ‪APK.‬‬

‫وللتطرق لموضوع بناء تطبيقات أندرويد فى نظم المعلومات الجغرافية ال بد من معرفة أساسيات الجافا ؛ ثم‬
‫بعد ذلك التعرف على كيفية استخدام األندرويد استوديو إلنشاء التطبيقات بصفة عامة؛ ثم بعد ذلك تطبيق‬
‫هذه العناصر على تطبيقات فى نظم المعلومات الجغرافية‪.‬‬

‫‪49‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫هتيئة العمل باألندر ويد استوديو‬ ‫الفصل الثامن‬

‫الفصل الثامن‪ :‬تهيئة العمل باألندر ويد استوديو‪:‬‬

‫للعمل مع تطبيق أندرويد استوديو ؛ يتم تحميله من الرابط التالي ؛‬

‫‪Download Android Studio and SDK tools | Android Developers‬‬

‫‪ -‬أفتح أندرويد أستوديو‬

‫أختار ‪start new android project‬‬

‫‪50‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫هتيئة العمل باألندر ويد استوديو‬ ‫الفصل الثامن‬

‫نضع اسم التطبيق؛ ثم الدومين " نقوم بعمل دومين خاص بنا" ‪my anoroid.com‬‬

‫‪51‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫هتيئة العمل باألندر ويد استوديو‬ ‫الفصل الثامن‬

‫التأكد من بعض االعدادات‪ :‬من‬

‫ثم تفتح النافذة التالية ؛ نتأكد أن هناك نسخة واحدة على األقل محددة‪.‬‬

‫وظائف مجلدات االندرويد استوديو‪:‬‬

‫‪52‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫هتيئة العمل باألندر ويد استوديو‬ ‫الفصل الثامن‬

‫المجلد األول ‪ app‬ويحتوى على ‪:‬‬

‫مجلد ‪ manifests‬ويحتوى على ملف يسمى ‪ : Android mainfestes‬حيث تحتوى على نافذة مضاف‬
‫اليها أكواد تلقائيا ؛ ويمكن إضافة الصالحيات التي ترغبها من المستخدم عند استخدام التطبيق الخاص بك؛‬
‫مثل استخدام االنترنت؛ الوصول الى الصور والفيديو‪.‬‬

‫مجلد ‪ : java‬يوجد به ثالثة مجالت‬

‫‪53‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫هتيئة العمل باألندر ويد استوديو‬ ‫الفصل الثامن‬

‫المجلد األول والثانى ‪ com.codershiyar :‬و هى مجلدات تجريبية يوجد بداخله ملف ‪main activity‬‬
‫حيث يمكن وضع ملفات الجافا بداخله ؛ ويحتوى على الملفات الرئيسية لعمل اى تطبيق اندرويد استوديو‪.‬‬

‫مجلد ‪ :res‬ويوجد بها‬

‫‪ : drawable‬لوضع الصور وانشاء خلفيات عبر لغة ‪.xml‬‬

‫المجلد ‪ layout‬ويوجد بها واجهات التطبيق الخاص بنا ‪.‬‬

‫‪:Mapmap‬عند إضافة اى ايقونات يتم اضافتها هنا ‪.‬‬

‫‪: Values‬وتحتوى على األلوان والنصوص واشكال التطبيق ‪.‬‬

‫‪:Gradle Scripts‬وهو القسم األهم ويحتوى على‬

‫عند الضغط على ‪ build.gradle‬؛ نجد نظام االندرويد المراد عمل التطبيق عليه ؛ نجد مكتوب أخر اصدار‬
‫اندرويد ‪ 30.3‬؛ يتم التغيير الى اإلصدار المطلوب ؛ رقم اصدار التطبيق " ‪ " versionCode‬و "‬
‫‪" versionname‬وفى كل مرة نحتاج تحديث التطبيق يتم كتابة اصدار جديد للتطبيق‪.‬‬

‫‪54‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫هتيئة العمل باألندر ويد استوديو‬ ‫الفصل الثامن‬

‫تشغيل الهاتف وربطه ببرنامج اندرويد استوديو كمحاكى للتطبيق‪:‬‬

‫‪ -‬يتم توصيل الهاتف بالجهاز بوصلة ‪ usp‬؛ يتم اختيار " نقل الملفات"‪.‬‬
‫‪ -‬الدخول على اعدادات الهاتف ‪.‬‬
‫‪ -‬الذهاب الى حول الهاتف‪.‬‬
‫‪ -‬الدخول على اإلصدار‪.‬‬
‫‪ -‬رقم اإلصدار يتم الضغط عليه أكثر من مرة حتى تظهر رسالة تم اإلضافة الى المتطورين‪.‬‬

‫‪ -‬الرجوع الى االعدادات‪.‬‬


‫‪ -‬اعدادات إضافية؛ نجده أضاف "خيارات المطور"‬

‫‪55‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫هتيئة العمل باألندر ويد استوديو‬ ‫الفصل الثامن‬

‫الدخول عليها ؛ ثم تشغيل تصحيح أخطاء ‪USB‬‬ ‫‪-‬‬

‫‪56‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫هتيئة العمل باألندر ويد استوديو‬ ‫الفصل الثامن‬

‫‪ -‬تظهر رسالة الصالحية باستخدام الهاتف كمطور يتم الموافقة عليها‪.‬‬

‫‪57‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫هتيئة العمل باألندر ويد استوديو‬ ‫الفصل الثامن‬

‫‪ -‬على االندرويد استوديو نجد ان الهاتف ظهر تلقائيا على البرنامج ‪.‬‬

‫يتم عمل تشغيل ‪ Run‬؛ نجده ظهر على الهاتف الخاص بنا‪.‬‬

‫‪58‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫هتيئة العمل باألندر ويد استوديو‬ ‫الفصل الثامن‬

‫‪59‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫هتيئة العمل باألندر ويد استوديو‬ ‫الفصل الثامن‬

‫لتجربة التطبيق على الهواتف؛ يتم توصيل هاتف بالجهاز ؛ لكن اذا كان جهازى مواصفاته محدودة يمكن‬
‫اضافة هاتف محاكى الى التطبيق وذلك عن طريق الخطوات التالية‪:‬‬

‫تظهر الشاشة التالية ؛ يتم الضغط على ‪Create Viritual Device‬‬

‫ثم اختار ‪ phone‬من النافذة التالية؛‬

‫‪60‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫هتيئة العمل باألندر ويد استوديو‬ ‫الفصل الثامن‬

‫ثم نحدد احد الهواتف وليكن ‪ 4.65 720 (Galaxy Ne‬ثم ‪next‬‬

‫تظهر نافذة اختار منها ‪ R‬ثم ‪ Dwnload‬ثم ‪ accept‬ثم ‪. finsh‬‬

‫فيظهر الهاتف كما موضح‬

‫ولتجربة التطبيق‪:‬‬

‫من الشريط واختار الهاتف المراد تجربة التطبيق عليه كما موضح بلقطة الشاة التالية؛‬

‫‪61‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫هتيئة العمل باألندر ويد استوديو‬ ‫الفصل الثامن‬

‫ثم أضغط على ‪run‬‬


‫تحميل محاكى للعمل مع االندرويد استوديو‪:‬‬
‫ليعطى هاتف محاكى لتجربة التطبيقات ؛‬
‫يتم تحميل ‪GENYMOTIOM‬‬
‫يتم الدخول على الرابط التالى ‪:‬‬
‫‪Account Login – Genymotion Android Emulator‬‬

‫انشاء حساب عليه‬

‫يتم التحقق عبر البريد االلكترونى ثم التحميل ؛‬

‫‪62‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫هتيئة العمل باألندر ويد استوديو‬ ‫الفصل الثامن‬

‫ثم عمل تصطيب على الجهاز‪.‬‬

‫والعداد المحاكى داخل االندرويد استوديو؛ يتم فتح االندرويد استوديو ومن ‪ file‬؛ أختار ‪ Setting‬؛‬

‫ثم ‪ plugins‬؛ وأبحث عن اسم المحاكى ؛‬

‫‪63‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫هتيئة العمل باألندر ويد استوديو‬ ‫الفصل الثامن‬

‫ثم عمل ‪install‬‬

‫ثم عمل ‪ restart‬؛ ونفتح برنامح المحاكى ؛ ونقوم بتسجيل الدخول ؛‬


‫أختار ‪personal use‬‬

‫‪64‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫هتيئة العمل باألندر ويد استوديو‬ ‫الفصل الثامن‬

‫ثم الموافقة على الشروط ؛ ثم ‪next‬؛ تظهر النافذة التالية ؛‬

‫من ‪ Android API‬؛ يتم اختيار االندرويد األعلى ؛ ليتم التجربة على أحدث إصدارات الهواتف ؛ تم اختيار‬
‫اندرويد ‪ 9‬؛‬

‫ومن عالمة ‪ +‬يتم إضافة األجهزة ؛ أختار جهاز منهم للتجربة ؛ تم اختيار النسخة االفتراضة طبقا‬
‫لمواصفات الجهاز الخاص بى ؛ ثم دبل كليك عليها ؛ ثم ‪install‬؛‬

‫‪65‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫هتيئة العمل باألندر ويد استوديو‬ ‫الفصل الثامن‬

‫وبعد االنتهاء ؛ نقوم بعمل ‪Start‬؛ ويتم تشغيله في كل مرة نريد استخدامه مع االندرويد استوديو ‪.‬‬

‫‪66‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫هتيئة العمل باألندر ويد استوديو‬ ‫الفصل الثامن‬

‫‪: ConstraintLayout‬‬

‫عند فتح واجهة التطبيق " النشاء مشروع جديد " نجد ‪ ConstraintLayout‬؛ وبها عبارة داخل عنصر‬
‫‪ Text view‬العبارة هي " ‪ "hello world‬؛ كما موضح بلقطة الشاشة التالية‪.‬‬

‫ما فائدة ‪: ConstraintLayout‬‬

‫يتم إضافة جميع العناصر الى واجهة التطبيق بداخله مثل إضافة نص أو صورة أو أزرار وكذلك التحكم في‬
‫هذه العناصر‪.‬‬

‫‪67‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫املتغريات يف األندر ويد استوديو‬ ‫الفصل التاسع‬

‫الفصل التاسع ‪:‬املتغريات يف االندرويد استوديو‪:‬‬

‫أي عناصر داخل االندرويد استوديو يمكن اضافتىها والتحكم فيها عن طريق المتغيرات على النحو التالى ‪:‬‬

‫لو تم فتح واجهة التطبيق من ‪. Layout‬؛ ثم ‪ activity_main.xml‬؛ نجد عناصر االندرويد استوديو‬
‫داخل ‪palette‬؛ وما يتم اضافته يظهر على واجهة التطبيق " مثل عبارة ‪ Hello World‬الموجودة ؛ ويمكن‬
‫حذف العبارة ووضع ‪ Button‬للتطبيق وذلك على النحو الموضح؛‬

‫‪ -‬يتم اختيار العبارة المراد حذفها ثم كليك يمين ؛ ‪.delete‬‬


‫‪ -‬يتم سحب الـ ‪ button‬وافالتها مكان العبارة التي تم مسحها ‪.‬‬
‫‪ -‬يتم التحكم في مكان الزرار ؛ عن طريق تحريكه على واجهة التطبيق ووضعه في المكان المناسب‪.‬‬

‫‪68‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫املتغريات يف األندر ويد استوديو‬ ‫الفصل التاسع‬
‫ومن خالل الضغط على ‪ attributes‬؛ يظهر لنا العنصر " يتم التحكم فيه حتى نتمكن من عدم‬
‫وجود أخطاء" ؛ وال بد من عرض األرقام في ثالثة نواحى من العنصر على األقل حتى تختفى‬
‫األخطاء‪.‬‬

‫‪ -‬يتم وضع اسم ‪ id‬للعنصر الذى تم اضافته مع مالحظة ال يمكن تكرار اسم ‪ id‬ومراعاة ان االسم‬
‫يكون باللغة اإلنجليزية ؛ وال يقبل كتابة الرموز والمسافات ‪.‬‬
‫‪ -‬تاتى مرحلة التحكم بالعنصر داخل ملف الجافا ؛‬
‫‪ -‬يتم كتابة عنصر ‪ Button‬في ملف الجافا ‪ mainActivity.java‬مع مراعاة ان الحرف األول من‬
‫الكلمة كابتل‪.‬‬
‫‪ -‬يتم إضافة ;‪ import android.widget.Button‬تلقائيا ‪.‬‬
‫‪ -‬نكتب اسم المتغير( أحرف صغيرة)‪.‬‬
‫‪ -‬يتم إضافة باقى عناصر التحكم التي تمكننا من التحكم في ال‪button‬‬

‫‪Button button = (Button) findViewById(R.id.button); -‬‬


‫يعد ذلك يمكننا التحكم في العنصر باسم المتغير ؛ كما يلى ‪:‬‬

‫‪69‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫املتغريات يف األندر ويد استوديو‬ ‫الفصل التاسع‬
‫الضاقة كلمات " اضغط هنا"‬
‫"(‪button.setText‬اضغط هنا;)"‬

‫ثم يتم عمل ‪ run‬على هاتفى على النحو التالى‪:‬‬

‫وبنفس الطريقة يتم إضافة جميع العناصر الى التطبيق‪.‬‬

‫‪70‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫تغيري خلفيات العناصر‬ ‫الفصل العاشر‬

‫الفصل العاشر ‪:‬تغيري خلفيات العناصر‬

‫الضافة لون جديد ؛ من ‪ res‬؛ ثم ‪values‬؛ أفتح ‪colors.xml‬‬

‫يتم إضافة اللون ؛ حيث يتم تسمية العنصر ووضع ‪ id‬له‬

‫>‬ ‫=‪</color> "red"<color name‬‬

‫وإضافة قيمة اللون من الموقع التالى ‪:‬‬

‫‪https://www.materialpalette.com/‬‬

‫‪71‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫تغيري خلفيات العناصر‬ ‫الفصل العاشر‬

‫فيما يلى إضافة اللون األحمر واألصفر‪.‬‬

‫لتغير لون خلفية ‪ Constraintlayout‬؛ والذى يتم وضع العناصر بها؛‬

‫ومن ‪ Activity _main.xml‬؛ يتم وضع‬

‫"‪android:background="@color/red‬‬

‫‪72‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫تغيري خلفيات العناصر‬ ‫الفصل العاشر‬

‫يمكن تغيير اللون بطريقة أخرى؛ عند طريق الضغط على العنصر ؛ ثم اختيار شاشة الـ‪ desine‬؛ والبحث‬
‫في قائمة البحث عن ‪ background‬؛ ثم اختيار اللون المناسب؛ كما موضح‪.‬‬

‫لتغيير لون نص الكتابة ‪:‬‬

‫يتم تحديد العنصر الذى يوجد به الكتابة " عنصر ‪ " button‬في المثال ؛ والبحث عن‪text color‬‬

‫واختيار اللون " أبيض"‬

‫‪73‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫تغيري خلفيات العناصر‬ ‫الفصل العاشر‬

‫ليكون على النحو التالى‪:‬‬

‫لوضع خلفية صورة ‪:‬‬

‫يتم نسخ الصورة المراد وضعها خلفية ولصقها داخل مجلد ‪.drawable‬‬

‫ثم تظهر الرسالة التالية ؛ يتم وضع اسم للصورة؛‬

‫‪74‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫تغيري خلفيات العناصر‬ ‫الفصل العاشر‬

‫ثم يتم اختيار الخلفية من نافذة تغيير اللون السابقة ؛ ولكن يتم اختيار المجلد ثم اختيار الصورة‪.‬‬

‫تم تغيير لون الـ ‪ bouuton‬للون األحمر حتى يظهر على الخلفية ؛ فيصبح شكل التطبيق على النحو‬
‫التالى‪:‬‬

‫‪75‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫تغيري خلفيات العناصر‬ ‫الفصل العاشر‬

‫‪: Layouts‬‬

‫عند فتح اعدادات الـ ‪ Layouts‬؛ نجد انه يوجد نوعين من ‪ LinearLayout‬النوع األول ‪" horizonta‬‬
‫حيث يسمح بوضع العناصر بجوار بعضها البعض" ؛ النوع الثانى وهو ‪ vertical‬ويسمح بوضع العناصر‬
‫فوق بعضها‪.‬‬

‫مع االخذ في االعتبار إمكانية وضع طريقة الـ ‪ layout‬أي كان نوعها داخل ‪ Constraint Layout‬؛ أو‬
‫اضافتها بداخلها ؛ ففي الحالتين تعمل جيدا‪.‬فنالحظ بمجرد اضافته ضمن‪ Constraint Layout‬أخدت‬
‫ارتفاع وعرض الشاشة بالكامل كما موضح بالصورة التالية ‪.‬‬

‫‪76‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫تغيري خلفيات العناصر‬ ‫الفصل العاشر‬

‫يمكن بعد ذلك التحكم في حجمها واضافة عناصر لها كاضافة مجموعة أزرار نجده تم وضعها فوق البعض‬
‫بها كما موضح‬

‫ويمكن تغيير نوع العرض من خال فتح وضع الـ‪ split‬وتعديل النوع في الكود من ‪ vertical‬ألى ‪horizonta‬‬

‫‪77‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫تغيري خلفيات العناصر‬ ‫الفصل العاشر‬

‫نجده غير االزرار الى جوار بعضها كما موضح ؛‬

‫كما يمكن أيضا التعديل على العرض االساسى للتطبيق ‪ Constraint Layout‬وتحويله الى‬
‫‪ LinearLayout‬وذلك عن طريق اعدادات الكود ومسح الكود بأول السطر ووضع مكانه‬

‫نجده تم تغيير العرض األساسى ‪ Constraint Layout‬الى ‪. LinearLayout‬‬

‫‪78‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫تغيري خلفيات العناصر‬ ‫الفصل العاشر‬

‫وإذا أردنا اختيار اى نوع من النوعين السابقين ‪ vertical‬أو ‪ horizonta‬يتم كتابة‬


‫=‪android:orientation‬‬
‫واختيار النوع كما موضح ‪:‬‬

‫‪79‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫تغيري خلفيات العناصر‬ ‫الفصل العاشر‬

‫تنفيذ األوامر بالنقر على العناصر داخل االندرويد استوديو‪:‬‬

‫هناك طريقتين‬

‫يتم انشاء االمر ضمن الـ‪ class‬الخاص بواجهة التطبيق الذى يحتوى على العنصر المراد وذلك على النحو‬
‫التالى ‪:‬‬

‫‪ -‬يتم فتح نافذة ‪. main Activity.java‬‬


‫‪ -‬يتم انشاء ‪ method‬من نوع ‪ puplic‬من نوع ‪ void‬ويتم تحديد اسم ‪method‬‬
‫‪public void display(){ -‬‬

‫}‬
‫‪ -‬يتم وضع داخل األقواس األمر ‪ View‬مع مراعاة الحرف األول كبير ووضع متغير بنفس االسم‬
‫‪ " view‬أحرف صغيرة‪.‬‬
‫‪ -‬يتم كتابة ;‪ import android.view.View‬تلقائيا واذا لم يتم كتابتها فنكتبها‬
‫نحن‪ ".‬بمجرد كتابة ‪ import‬تكتب "‪.‬‬

‫‪80‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫تغيري خلفيات العناصر‬ ‫الفصل العاشر‬

‫نضع األمر داخل ‪ " method‬األمر المراد تنفيذه عند الضغط على العنصر" ؛ فمثال للتطبيق على‬
‫تغيير خلفية التطبيق باختيار لون محدد بالنقر على الزر ؛ يتم وضع األوامر الخاصة بذلك على‬
‫النحو الموضح أدناه‬
‫‪ -1‬يتم وضع ‪ id‬للواجهة المستخدمة ‪ Constraint Layout‬باسم ‪.home‬‬
‫‪ -2‬يتم وضع متغير‪ ConstraintLayout‬نسميه ‪ home‬ونكتب نوع المتغير داخل االقواس ؛ ثم‬
‫تحديده من خالل ‪. id‬‬
‫‪ -3‬يتم كتابة اسم المتغير ‪ home‬ثم تحديد العناصر المراد تغييرها " الخلفية عن طريق االلون" وهذا‬
‫كما موضح باالكواد التالية ‪.‬‬

‫)‪ConstraintLayout home =(ConstraintLayout‬‬


‫;)‪findViewById(R.id.home‬‬
‫‪home.setBackgroundColor(getResources().getColor(R.color‬‬
‫;))‪.design_default_color_error‬‬

‫‪ -‬وبهذا نكون قد أنشأنا ‪ method‬؛ متبقى لنا استدعاؤه ؛فمثال نريد استدعاؤه على الزر المنشىء مثبقا‬

‫‪81‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫تغيري خلفيات العناصر‬ ‫الفصل العاشر‬

‫نأتى على ‪ Design‬؛ نحدد العنصر" الزر" ثم في البحث نبحث عن ‪ on Click‬؛ ثم نختار اسم‬ ‫‪-‬‬
‫‪ method‬؛‬

‫‪ -‬وبهذا تم استدعاء الميثود بحيث مجرد النقر على الزر يتم تنفيذ األوامر التي تم كتابتها داخل الميثود‬
‫" تغيير خلفية التطبيق"‪.‬‬
‫‪ -‬يتم عمل ‪ run‬نجده تم التنفيذ ‪.‬‬

‫الضافة عنصر أخر ؛ كإضافة ‪: image view‬‬

‫‪ -‬يتم اضافتها ؛ ثم اختيار ‪ id‬لها ونسميه وليكن ‪. image view2‬‬

‫‪ -‬نأتى على نافذة ‪ main Activity.java‬ونكتب العنصر ‪ Image view‬مع مراعاة الحرف األول كبير؛ ثم‬
‫نقوم بعمل متغير باالسم "نفس االسم حروف صغيرة" ‪.‬‬

‫‪ -‬ثم تحديد اسم المتغير ؛ ووضع ‪setOnClickListener(new‬‬


‫‪ View.OnClickListener‬نجده وضع الميثود تلقائيا‪.‬‬

‫‪ -‬يتم إضافة االمر المراد تنفيذه داخل الميثود مثلما حدث من قبل ؛ فمثال يتم وضع نفس األمر السابق‬
‫مع تغيير اللون ‪.‬‬

‫‪82‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫تغيري خلفيات العناصر‬ ‫الفصل العاشر‬

‫ملحوظة ‪ :‬إذا لم يتم وضع العناصر ؛ يتم تعيين مركز ارتكازهم مرة أخرى ‪.‬‬

‫‪83‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫‪ Web view‬يف األندر ويد استوديو‬ ‫الفصل احلادي عشر‬

‫الفصل احلادي عشر‪ Web view :‬يف االندرويد استوديو‪:‬‬

‫تسمح لك ‪ web view‬بعرض الويب من خالل التطبيق الخاص بك وتصفح الويب من خالله؛‬

‫و‪web setting‬؛ تقوم بإعداد ال‪. Web view‬‬

‫طريقة استخدام ‪ web view‬داخل االندرويد استوديو‪:‬‬

‫على قائمة البحث يتم البحث عن ‪web View‬‬

‫يتم سحبها وافالتها بالتطبيق؛ يتم اضافتها تلقائيا على واجهة التطبيق بنسبة ‪match_parent( 100%‬‬

‫‪84‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫‪ Web view‬يف األندر ويد استوديو‬ ‫الفصل احلادي عشر‬

‫يتم التحكم في عرضها فمثال يتم عرضها ‪dp 300‬‬

‫يتم وضع ‪ id‬لعنصر ‪ web view‬للتحكم فيه من خالل ملف جافا " أسميه ‪ " web view‬مع مراعاة أن‬
‫يكون الحرف األول صغير‪.‬‬

‫‪ -‬نذهب الى ملف الجافا ؛ نقوم بعمل متغير لعنصر ‪ " Web View‬الحرف األول كبير من كل كلمة"‬
‫؛ ثم نسمى المتغير وليكن ‪ ( = web view‬نضع قيمة العنصر مرة أخرى)‪.‬‬
‫‪ -‬بعد ذلك يتم تحديد عنوان ‪ url‬المراد تصفحه عبر التطبيق ؛ وذلك من خالل تحديد اسم المتغير ثم ‪.‬‬
‫ثم )(‪ loadUrl‬ووضع الموقع المراد تصفحه داخل االقواس؛"تم وضح عنوان صفحة الفيس بوك‬
‫الخاصة بى"‬

‫‪85‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫‪ Web view‬يف األندر ويد استوديو‬ ‫الفصل احلادي عشر‬

‫ولعرض الويب ضمن التطبيق يستخدم ؛ اسم المتغير ثم ‪ setWebviewClinet‬؛ وبدون كتابة هذه‬
‫الخاصية ؛ يتطلب التطبيق الدخول على الرابط السابق والخروج من التطبيق‪.‬‬
‫;))(‪webView.setWebViewClient(new WebViewClient‬‬
‫بعد ذلك يتم انشاء متغير من نوع ‪ websetting‬لعمل اعدادات على الـ ‪webview‬‬

‫ولتكملة اعدادات الوصول الى ملفات الهاتف يتم الذهاب الى ملف ‪manifests‬‬

‫يتم تحديد صالحية االنترنت أوال‬


‫‪<uses-permission‬‬
‫"‪android:name="android.permission.INTERNET‬‬
‫ثم صالحية إمكانية قراءة الملفات على النحو الموضح‬

‫‪86‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫‪ Web view‬يف األندر ويد استوديو‬ ‫الفصل احلادي عشر‬

‫بعد ذلك يتم عمل ‪ run‬للتطبيق ؛ نجده عرض الويب على التطبيق على الهاتف‪.‬‬

‫‪87‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫‪ Web view‬يف األندر ويد استوديو‬ ‫الفصل احلادي عشر‬

‫ولكن هناك مشكلة بسيطة ؛ عند العودة من زر العودة الخاص بالهاتف يتم الخروج من التطبيق بدال من‬
‫العودة خطوة ويتم حل ذلك عن طريق؛ عمل ‪ " method‬وهو ‪ method‬جاهز عبر االندرويد استوديو"‬
‫يسمى ‪ onKeyDown‬؛ ونضع بداخله شرط ؛ أذا تم الضغط على زر العودة يتم العودة للخطوة السابقة‬
‫مع وضع شرط أخر وهو أن الـ ‪ webview‬قادر على العودة ‪.‬‬

‫ملحوظة " نجد أنه غير قادر على استدعاء الـ ‪ " webview‬ظهرت باللون األحمر “داخل هذا ‪" method‬‬
‫فيتم عمل تعديل بسيط " حيث يتم عمل المتغير ضمن ال‪ class‬وداخل ‪ method‬؛ وبدل انشاء متغير‬
‫جديد يتم تحديده ؛ كما موضح بالشاشة أدناه ؛‬

‫واستكمال الشرط ؛‬
‫‪@Override‬‬
‫‪public boolean onKeyDown(int KeyCode, KeyEvent‬‬
‫{)‪event‬‬
‫&& ‪if (KeyCode==KeyEvent.KEYCODE_BACK‬‬
‫{))(‪webView.canGoBack‬‬
‫;)(‪webView.goBack‬‬
‫;‪return true‬‬

‫‪88‬‬
‫ رشا صابر نوفل‬/‫د‬ ‫ يف األندر ويد استوديو‬Web view ‫الفصل احلادي عشر‬

}
return super .onKeyDown(KeyCode,event);
}
}
‫ نجد أنه للدخول على الموقع والتصفح عند الدخول على اى شيء داخل الويب ؛ للعودة‬run ‫وبعد عمل‬
.‫بمجرد الضغط على زر العودة يتم ذلك‬
: ‫لتصبح الصفة في النهاية‬
package com.example.rsaha_app;
import androidx.appcompat.app.AppCompatActivity;
import androidx.constraintlayout.widget.ConstraintLayout;
import android.os.Bundle;
import android.view.KeyEvent;
import android.view.View;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.ImageView;
public class MainActivity extends AppCompatActivity {
WebView webView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = (WebView)findViewById(R.id.webview);

webView.loadUrl("https://www.facebook.com/DrRashaNofal/");
webView.setWebViewClient(new WebViewClient());
WebSettings webSettings = webView.getSettings();
‫للسماح بالجافا سكريبت يتم عمل بعض االعدادت منها‬ //
webSettings.setJavaScriptEnabled(true);
‫المكانية التخزين المؤقت‬ //
webSettings.setDomStorageEnabled(true);
‫المكانية التكبير والتصغير‬ //
webSettings.setDisplayZoomControls(true);
webSettings.setSupportZoom(true);
‫التحاة الوصول الى الملفات على الهاتف‬ //
webSettings.setAllowContentAccess(true);
webSettings.setAllowFileAccess(true);
‫للعمل مع جميع األجهزة‬ //
webSettings.setUseWideViewPort(true);
}
@Override

89
‫ رشا صابر نوفل‬/‫د‬ ‫ يف األندر ويد استوديو‬Web view ‫الفصل احلادي عشر‬
public boolean onKeyDown(int KeyCode, KeyEvent event){
if (KeyCode==KeyEvent.KEYCODE_BACK &&
webView.canGoBack()){
webView.goBack();
return true;
}
return super .onKeyDown(KeyCode,event);
}

90
‫د‪ /‬رشا صابر نوفل‬ ‫‪ Web view‬يف األندر ويد استوديو‬ ‫الفصل احلادي عشر‬

‫لضبط مجموعة عناصر أخرى داخل ‪:webview‬‬

‫‪ :Loadurl‬حيث يتم ربطها بصورة مثال أو زر؛ وللضغط على الصورة يتم الوصول الى الموقغ ‪.‬‬

‫‪ -‬في البداية يتم طريقة عرض التطبيق إلى )‪ LinearLayout(vertical‬؛سبق وأن ذكرنا ‪.‬‬
‫‪ -‬يتم إضافة ‪ Button‬ويتم كتابة النص المراد ظهوره على الزرار وليكن " ‪ " YouTube‬؛ حيث يتم‬
‫االنتقال من التطبيق الى قناة اليويتيوب الخاصة بى ؛ وتغيير لون الخلفية ؛ ولون الكتابة وحجم‬
‫الخط ونوعه ؛‬

‫‪91‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫‪ Web view‬يف األندر ويد استوديو‬ ‫الفصل احلادي عشر‬

‫نحتاج تنفيذ األمر عند الضغط على الزر؛ وذلك عن طريق عمل ‪ method‬من نوع ‪void‬؛ يتم تسميته‬
‫‪ LoadUrl‬؛ واضافة متغير داخله من نوع ‪ view view‬؛ وبعد ذلك استدعاء الـ ‪ webview‬ثم‬
‫‪ LoadUrl method‬؛ وهذه األنواع تكون جاهزة داخل االندرويد استوديو ؛ ثم نضع رابط المطلوب‪.‬‬

‫بعد ذلك يتم استدعاء ‪ onClick‬؛ بتحديد الـ‪ button‬والبحث عن ‪ onClick‬واختيار اسم الزر " الذى‬
‫سبق وأن وضعناه"‪.‬‬

‫‪92‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫‪ Web view‬يف األندر ويد استوديو‬ ‫الفصل احلادي عشر‬

‫ثم عمل ‪ run‬؛ فيظهر التطبيق على الهاتف وبالضغط على الزرار يتم الوصول الى موقع اليويتيوب‬
‫الخاص بى على النحو الموضح؛‬

‫‪93‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫‪ Web view‬يف األندر ويد استوديو‬ ‫الفصل احلادي عشر‬

‫‪ :Goback‬للرجوع الى الخلف مثلما يحدث في الويب‪.‬‬

‫‪ :Reload‬لعمل تحديث " مثل تصفح الويب أيضا"‪.‬‬

‫‪ : Go forward‬للذهاب خطوة لألمام ‪.‬‬

‫يتم إضافة أيقونات خاصة ؛ وذلك عن طريق‬

‫تظهر النافذة التالية؛‬

‫‪94‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫‪ Web view‬يف األندر ويد استوديو‬ ‫الفصل احلادي عشر‬

‫بالضغط مرتين على الصورة الموجودة فى ‪ ClipArt‬؛ تظهر نافذة األيقونات ؛‬

‫نختار االيقونة الخاصة ؛ ثم نحدد اللون المناسب ونضع اسم لها ثم ‪ ok‬؛ ثم ‪ next‬؛ ثم ‪. finsh‬‬

‫بعد ذلك يتم إضافة ‪ linear layout‬من نوع ‪ horizon‬لعرض العناصر بجوار بعضها البعض؛ وضبط‬
‫ارتفاعها وليكن ‪P 500dp‬‬

‫‪95‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫‪ Web view‬يف األندر ويد استوديو‬ ‫الفصل احلادي عشر‬

‫يتم إضافة الصور بها وذلك من تحديد ‪ comaa‬ثم ‪ image view‬سحبها وافالتها داخل الـ‪layout‬‬

‫‪96‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫‪ Web view‬يف األندر ويد استوديو‬ ‫الفصل احلادي عشر‬

‫تظهر الصورة ؛ يتم اختيار الصورة المطلوبة ؛ثم ‪ok‬‬

‫يتم وضع عالمات للـ‪ Reload‬و‪ forward‬أيضاً‪.‬‬

‫ملحوظة ‪ :‬يظهر لنا خطأ؛ الصالحه‬

‫يتم عرض الخطأ؛‬

‫‪97‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫‪ Web view‬يف األندر ويد استوديو‬ ‫الفصل احلادي عشر‬

‫نجده يطلب منا وضع الجملة داخل ‪ buildgradleapp‬؛ فيتم وضعها ثم عمل ‪Synce Now‬‬

‫نجده تم تصحيح األخطاء؛ يتبقي لنا ربط هذه العناصر بالضغط عليها ؛‬

‫ال‪ method‬األول والخاص بالـ‪goback‬‬

‫‪98‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫‪ Web view‬يف األندر ويد استوديو‬ ‫الفصل احلادي عشر‬

‫ثم نحددها من ‪ Onclick‬؛‬

‫وبنفس الطريقة يتم عمل ال‪ Reload‬و‪forward‬‬

‫ضبط الفيديو ليعمل بملء الشاشة داخل الـ‪: webview‬‬

‫عند تحويل موقع الويب الى تطبيق أندرويد ؛ وتصفح الويب من خالل التطبيق ؛ نجد ان الفيديوهات ال‬
‫يمكن عرضها " ملئ الشاشة" كما في الويب؛ قامت شركة جوجل بعمل ‪ class‬جاهز يمكننا استخدامه هنا‬
‫في التطبيق ؛ حيث يتم وضعه داخل ‪ MainActivty-java‬الخاص بالتطبيق ؛ ضمن الكالس األساسي ؛‬
‫وخارج الـ ‪ method onCreate‬؛ " مكان لصق الـ ‪ "class‬في لقطة الشاشة التالية‪:‬‬

‫‪99‬‬
‫ رشا صابر نوفل‬/‫د‬ ‫ يف األندر ويد استوديو‬Web view ‫الفصل احلادي عشر‬

‫كالس للسماح للفيديو بوضع ملء الشاشة‬//


private class MyChrome extends WebChromeClient {

private View mCustomView;


private CustomViewCallback mCustomViewCallback;
protected FrameLayout mFullscreenContainer;
private int mOriginalOrientation;
private int mOriginalSystemUiVisibility;

MyChrome() {}

public Bitmap getDefaultVideoPoster()


{
if (mCustomView == null) {
return null;
}
return
BitmapFactory.decodeResource(getApplicationContext().getResource
s(), 2130837573);
}

public void onHideCustomView()


{

((FrameLayout)getWindow().getDecorView()).removeView(this.mCusto

100
‫ رشا صابر نوفل‬/‫د‬ ‫ يف األندر ويد استوديو‬Web view ‫الفصل احلادي عشر‬
mView);
this.mCustomView = null;

getWindow().getDecorView().setSystemUiVisibility(this.mOriginalS
ystemUiVisibility);
setRequestedOrientation(this.mOriginalOrientation);
this.mCustomViewCallback.onCustomViewHidden();
this.mCustomViewCallback = null;
}

public void onShowCustomView(View paramView,


CustomViewCallback paramCustomViewCallback)
{
if (this.mCustomView != null)
{
onHideCustomView();
return;
}
this.mCustomView = paramView;
this.mOriginalSystemUiVisibility =
getWindow().getDecorView().getSystemUiVisibility();
this.mOriginalOrientation = getRequestedOrientation();
this.mCustomViewCallback = paramCustomViewCallback;

((FrameLayout)getWindow().getDecorView()).addView(this.mCustomVi
ew, new FrameLayout.LayoutParams(-1, -1));
getWindow().getDecorView().setSystemUiVisibility(3846);
}
}
.‫ الخاص بنا‬webview‫ثم نقوم بربطه بالـ‬
webView.setWebChromeClient(new MyChrome());

101
‫د‪ /‬رشا صابر نوفل‬ ‫‪ Web view‬يف األندر ويد استوديو‬ ‫الفصل احلادي عشر‬

‫تشغيل ‪ OnPageFinished‬و ‪ onPageStarted‬في واجهة ‪WebViewClient‬‬

‫على نفس الصفحة السابقة وبعد أقواس () ‪ WebViewClien‬نضع األقواس} { ؛ ثم نكتب‬

‫ثم نكرر ‪onPageFinished‬‬

‫وداخل الـ‪ method‬يتم إضافة األوامر التي نرغب في تنفيذها كل مرة يتم تحميل صفحات ‪. webview‬؛‬
‫وليكن وضع رسالة عند التحميل ؛ بدء التحميل وأهال بك ؛ وعند االنتهاء نضع رسالة ؛ تم التحميل‬

‫‪102‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫‪ Web view‬يف األندر ويد استوديو‬ ‫الفصل احلادي عشر‬

‫‪ getTitle ) Methods‬و‪ ( getUrl method‬داخل واجهة ‪: WebView‬‬


‫‪ :getUrl method‬تستخدم للحصول على ‪ url‬للصفحة التي يتم عرضها على ‪webview‬‬

‫‪ : getTitle‬للحصول على عنوان الصفحة ؛‬

‫نقوم بعمل متغير من نوع ‪ string‬؛ ونسمى المتغير اسم ثم نستدعى الـ ‪method‬‬

‫‪103‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫‪ Web view‬يف األندر ويد استوديو‬ ‫الفصل احلادي عشر‬

‫وبهذا يتم تخزين عنوان الـويب الذى يتم تصفحه من خالل التطبيق الخاص بى وكذلك ‪ Url‬؛ ولكن بهذا‬
‫يتم تخزينه مرة واحدة ؛ وقد يستدعى األمر في التطبيق الى الدخول في أكثر من قسم داخل التطبيق ؛‬
‫فكيف يتم التخزين في كل مرة ؛‬

‫فيتم عمل ذلك داخل ‪ method‬الـ ‪ onPageFinished‬حيث يتم وضع نفس المتغيرات كما هو موضح‬

‫التطبيق ‪:‬‬

‫يتم اضافة ‪ button‬ونسميه ‪ title‬؛ ونقوم بإضافة ‪ plaintext‬داخل الـ ‪ webview ,‬ونعطيه ‪ id‬وليكن ‪url‬‬
‫؛ داخل الـ‪ class‬المسئول عن هذه الواجهة " ‪“ mainActivity‬يتم عمل متغييرين ؛ للعنصرين ‪ button‬و‬
‫‪plaintext‬‬

‫‪104‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫‪ Web view‬يف األندر ويد استوديو‬ ‫الفصل احلادي عشر‬

‫وداخل ‪ onPageFinished‬يتم كتابة المتغيرات ويتم عمل الرسالة التي تظهر كتعليق" لعدم الحاجة‬
‫اليها حاليا"‪.‬‬

‫‪105‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫حتويل موقع الويب اىل تطبيق أند رويد‬ ‫الفصل الثاني عشر‬

‫الفصل الثاني عشر ‪ :‬حتويل موقع الويب اىل تطبيق اندرويد‬

‫يمكن تحويل ملفات تم انشاؤها بالـ‪ html , css ,JS‬الى تطبيق باالندرويد استوديو‬

‫‪ -‬لدينا مشروع تم انشاؤه على ويب ؛ من االندرويد استوديو ؛ نفتح المجلد ‪manifests‬؛‬
‫نضع إمكانية عمل التطبيق على االنترنت؛‬

‫‪ -‬نفتح ‪Layout‬؛ ثم الواجهة المسئولة عن عرض التطبيق " ‪."activity _main.xml‬‬


‫‪ -‬إضافة ‪web view‬؛ لواجهة التطبيق ‪.‬‬
‫‪ -‬نعطيه ‪ id‬؛ وليكن ‪.web‬‬
‫‪ -‬بعد ذلك يتم تحديد ملفات ‪ html‬وذلك عن طريق ؛‬

‫‪106‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫حتويل موقع الويب اىل تطبيق أند رويد‬ ‫الفصل الثاني عشر‬

‫‪ -‬تظهر لنا نافذة نضغط على ‪ finsh‬؛ نجده أنشىء لنا ملف جديد‬

‫‪ -‬يتم نسخ جميع الملفات والصور الخاصة بالويب ولصقها داخل هذا المجلد الجديد‬

‫‪107‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫حتويل موقع الويب اىل تطبيق أند رويد‬ ‫الفصل الثاني عشر‬

‫مع مراعاة ان أسماء الملفات تكون مكتوبة باإلنجليزية‪.‬‬


‫‪ -‬يمكننا التعديل بسهولة على ملف ‪ html‬من االندرويد استوديو‪.‬‬
‫‪ -‬نفتح ملف الجافا المسئول عن واجهة التطبيق ‪ mainactivty‬ونقوم بعمل متغير ‪webview‬؛ وذلك‬
‫لفتح الملفات من خالل الـ ‪ webview‬الذى أنشأناه ‪.‬‬

‫‪108‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫حتويل موقع الويب اىل تطبيق أند رويد‬ ‫الفصل الثاني عشر‬

‫نقوم بنفس الخطوات السابق شرحها من حيث استدعاء المتغير و‪ LoadUrl‬؛ ولكن هنا يتم وضع‬ ‫‪-‬‬
‫مسار ملف ‪ html‬؛ حيث يتم كتابة أي مسار داخل االندرويد استوديو بالشكل _‪file:///android‬‬
‫اسم الملف بدون‪ / s‬ثم اسم ملف ‪ html‬وصيغته"‪.‬‬

‫‪ -‬بعد ذلك نقوم بعمل االعدادات الخاصة بظهور الويب كما سبق وان ذكرناها في الدروس السابقة‪.‬‬

‫‪ -‬يتم عمل ‪ run‬يظهر التطبيق ‪.‬‬

‫‪109‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫حتويل موقع الويب اىل تطبيق أند رويد‬ ‫الفصل الثاني عشر‬

‫‪110‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫حتويل موقع الويب اىل تطبيق أند رويد‬ ‫الفصل الثاني عشر‬

‫تغيري صورة واجهة التطبيق اخلاص بي‪:‬‬

‫مثال مطلوب وضع صورة مختلفة عن التي تظهر على الهاتف ؛‬

‫البداية ؛ الصور المتوفرة نجدها في ملف ‪ mipmap :‬داخل مجلد ‪ res‬؛ وهى صورة واحدة وبمقاسات‬
‫مختلفة ؛كما موضح‪:‬‬

‫لتغيير الصورة ووضع صورة خاصة بتطبيقى ‪:‬‬

‫من ‪ app‬كلييك يمين؛ ثم ‪ New‬؛ واختار ‪image Asset‬‬

‫تظهر النافذة التالية ؛ نختار من األعلى )‪Launcher Icons (Legecyonly‬‬

‫‪111‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫حتويل موقع الويب اىل تطبيق أند رويد‬ ‫الفصل الثاني عشر‬

‫ثم اختيار ‪ image‬؛ فتكون نافذة تحميل الصورة ؛ يتم تحميلها من ملفات الجهاز‪.‬‬

‫‪112‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫حتويل موقع الويب اىل تطبيق أند رويد‬ ‫الفصل الثاني عشر‬

‫تظهر الصورة المختارة وبمقاييس مختلفة للتتناسب مع كافة األجهزة؛ يمكن ضبط لون الخلفية والتحكم في‬
‫شكل الصورة كما موضح بلقطة الشاشة التالية ‪:‬‬

‫بعد االنتهاء من االعدادات يتم الضغط على ‪ next‬ثم ‪.finsh‬‬

‫‪113‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫حتويل موقع الويب اىل تطبيق أند رويد‬ ‫الفصل الثاني عشر‬

‫تغيير اسم التطبيق‪:‬‬

‫يتم تغيير اسم التطبيق على النحو التالى‪:‬‬

‫يتم فتح ملف ‪ strings‬الموجود ضمن مجلد ‪Values‬؛‬

‫يظهر اسم التطبيق هنا‪:‬‬

‫يتم التغيير الى االسم المطلوب؛‬

‫‪114‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫حتويل موقع الويب اىل تطبيق أند رويد‬ ‫الفصل الثاني عشر‬

‫تغيير اسم ‪ package‬التطبيق الخاص بى‪:‬‬

‫أثناء انشاء التطبيق ؛ يتم اليام بعمل اسم ‪ package‬للتطبيق ؛‬

‫لو أردنا التعديل على هذا االسم بعد االنتهاء من انشاء التطبيق ؛‬

‫ونبحث عن المجلد الذى يحمل اسم ال‪package‬‬

‫‪115‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫حتويل موقع الويب اىل تطبيق أند رويد‬ ‫الفصل الثاني عشر‬

‫يفضل قبل تغيير االسم البحث في الـ‪ googleplay‬عن االسم الجديد هل هو متوفر أم ال ‪.‬‬

‫‪116‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫حتويل موقع الويب اىل تطبيق أند رويد‬ ‫الفصل الثاني عشر‬

‫ثم الضغط على ‪ Do Refactor‬التي تظهر أسفل الشاشة‬

‫اال أن هناك بعض الملفات لم يتم تغيير االسم بها ؛ فيتم تغيريها ؛ نفتح ‪ Build gradle‬؛‬

‫فنجد االسم القديم‬

‫فيتم تغييرها الى االسم الجديد ؛ ثم ‪.Sync Now‬‬

‫ثم فتح مجلد ‪ manifests‬والتأكد من تغيير اسم ‪. package‬‬

‫‪117‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫انشاء تطبيق بواجهات متعددة‬ ‫الفصل الثالث عشر‬

‫الفصل الثالث عشر ‪ :‬انشاء تطبيق بواجهات متعددة‬

‫فمثال لدينا تطبيق من واجهة ونريد التنقل الى واجهات أخرى عير أزرار أو عبارات محددة؛‬

‫يتم اختيار واجهة جديدة للتطبيق من خالل‬

‫أختار الواجهة المراد اضافتها؛ وليكن واجهة خرائط جوجل؛‬

‫‪118‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫انشاء تطبيق بواجهات متعددة‬ ‫الفصل الثالث عشر‬

‫‪-‬أعطى اسم للواجهة ثم ‪.finish‬‬

‫‪ -‬لو أردنا االنتقال الى الواجهة الجديدة من خالل زر بالواجهة األساسية للتطبيق ؛ يتم إضافة الزر ؛ وكتابة‬
‫النص الخاص بالزر وليكن (‪.( GPS‬‬

‫‪ -‬نفتح ‪ mainactivty‬؛ نقوم بإنشاء ‪ method‬جديد من نوع ‪ void‬؛ ونحدد فيه الدخول على الواجهة‬
‫الجديدة من خالل ‪ object‬داخل االندرويد استوديو يسمى ‪Intent‬‬

‫‪ -‬يتبقى لنا استدعاء الواجهة عند النقر على الزر‬

‫‪119‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫انشاء تطبيق بواجهات متعددة‬ ‫الفصل الثالث عشر‬

‫ربط التطبيق برابط وفتحه خارج التطبيق ‪:‬‬

‫تم إضافة ‪ image view‬الى واجهة التطبيق؛ اعطناه ‪ id‬وليكن ‪rasha‬؛ لكى نضغط على الصورة يتم‬
‫توصيلنا بالرابط وفتحه خارج التطبيق نذهب على صفحة الجافا الخاصة بالتطبيق ونقوم بعمل ‪ method‬؛‬
‫ونكمل باقى األوامر كما موضح بلقطة الشاشة التالية ؛‬

‫يتبقى لنا استدعاء الصورة لنعطيها األمر عند الضغط على الصورة يتم تحويلنا الى الرابط ؛ يتم تحديد‬
‫العنصر " الصورة " والبحث عن ‪ OnClick‬؛ واختيار العنصر " من خالل اسم الـ‪. id‬‬

‫‪120‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫انشاء تطبيق بواجهات متعددة‬ ‫الفصل الثالث عشر‬

‫‪121‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫انشاء تطبيق بواجهات متعددة‬ ‫الفصل الثالث عشر‬

‫طريقة عرض رسالة ترحيبية على واجهة التطبيق؛‬

‫‪ -‬أنشئ ‪ Method‬من نوع ‪ void‬؛ أسميه على سبيل المثال ‪. toast‬‬


‫‪ -‬أنشئ متغير من نوع ‪ Toast‬؛ نجده أضاف في األعلى ;‪ import android.widget.Toast‬؛‬
‫ان لم يتم اضافتها يتم وضعها بنفسك‪.‬‬
‫‪ -‬ضع اسم للمتغير وليكن ‪ message‬؛ ونكتب بداخله األوامر التالية ؛‬
‫‪Toast.makeText (getApplicationContext ()," -‬دكتورة‬
‫رشا نوفل ترحب بكم‪ ",Toast.‬هنا نجد خيارين)‬

‫‪ :LENGTH_LONG -‬عرض الرسالة لمدة من ثانية الى ثانيتين‪.‬‬


‫‪ :LENGTH_SHORT -‬عرضها من نصف ثانية الى ثانية‪.‬‬
‫‪ -‬ولعرض الرسالة بمجرد فتح التطبيق يتم كتابة الـ‪ method‬داخل الـ‪Activity _main‬‬
‫;)( ‪ toast‬لتصبح الصفحة في النهاية على النحو التالى ‪:‬‬

‫‪122‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫انشاء تطبيق بواجهات متعددة‬ ‫الفصل الثالث عشر‬

‫‪.setGravity‬‬ ‫وللتحكم في عرض الرسالة ؛ نضيف قبل تنفيذ االمر األخير اسم المتغير ثم‬
‫‪(Gravity.CENTER,0,0‬‬

‫ولوضعها في أي جهة ؛ باليمين باليسار يتم إضافة‬

‫‪Handler Class‬و‪Runnable‬‬

‫هي كالسات جاهزة داخل االندرويد استوديو ؛ لتحديد مدة لتنفيذ األوامر ؛‬
‫لتأخير تنفيذ األوامر نحتاج الى ‪ Handler object‬و أوبجكت أخر من نوع ‪ Runnable‬؛‬
‫ويكتب على النحو التالى " األوبجكت – اسم متغير – ثم = ‪ new‬ثم تحديد األوبجكت مرة أخرى على‬
‫النحو التالى ؛‬

‫‪123‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫انشاء تطبيق بواجهات متعددة‬ ‫الفصل الثالث عشر‬

‫ثم نقوم بإعداد الرسالة‬

‫لتحديد الفترة المطلوبة ؛ " بعد فترة ؟ تظهر الرسالة بعد أن يتم استدعاء الـ ‪ method‬؛ بكتابة األوامر‬
‫التالية ؛‬

‫وفى النهاية يتم كتابة اسم الـ ‪ method‬في األعلى حتى يتم ظهور الرسالة بعد فتح التطبيق مباشرة ؛ لتكون‬
‫النافذة كما يلى ؛‬

‫‪124‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫انشاء تطبيق بواجهات متعددة‬ ‫الفصل الثالث عشر‬

‫وإذا أردنا تكرار تنفيذ األوامر كل فترة زمنية محددة ؛ يتم إضافة نفس الرسالة السابقة ضمن الـ‪method‬‬
‫األساسية بعد كل العناصر الموجودة‬

‫وبهذا يتم تنفيذ االمر وظهور الرسالة بعد خمس ثوانى ؛ وتكرار ظهورها كل خمس ثوانى ؛ وللتحكم في تكرار‬
‫التنفيذ من عدمه " يعنى ان المستخدم هو الذى يتحكم اذا كان يريد تكرار تنفيذ األمر أم ال "‬

‫‪125‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫انشاء تطبيق بواجهات متعددة‬ ‫الفصل الثالث عشر‬

‫أو أن هناك زر على واجهة التطبيق ؛ فبمجرد الضغط يتم التوقف عن تنفيذ األمر وظهور الرسالة‬

‫‪ -‬يتم عمل ‪ button‬واسميه ‪start‬‬


‫يثم عمل ‪ method‬جديد‬ ‫‪-‬‬

‫ثم التحكم في الزرار عن طريق ‪OnCklick‬‬

‫التحقق من اتصال الهاتف باإلنترنت من خالل تطبيقك الخاص ( شبكة واى فاى أو بيانات الهاتف)‪:‬‬

‫لعمل ذلك يتم أوال توصيل التطبيق باإلنترنت؛ في نافذة ‪manifest‬‬

‫بعد ذلك يتم وضع األوامر والشروط التالية داخل صفحة ‪ java‬الخاصة بواجهة التطبيق ؛‬

‫‪126‬‬
‫ رشا صابر نوفل‬/‫د‬ ‫انشاء تطبيق بواجهات متعددة‬ ‫الفصل الثالث عشر‬

ConnectivityManager connMgr =
(ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
boolean isWifiConn = false;
boolean isMobileConn = false;
for (Network network : connMgr.getAllNetworks()) {
NetworkInfo networkInfo =
connMgr.getNetworkInfo(network);
if (networkInfo.getType() ==
ConnectivityManager.TYPE_WIFI) {
isWifiConn |= networkInfo.isConnected();
}
if (networkInfo.getType() ==
ConnectivityManager.TYPE_MOBILE) {
isMobileConn |= networkInfo.isConnected();
}
}

getNetworkInfo ‫ ؛‬getAllNetwork ‫ملحوظة يظهر خطأ على‬

127
‫د‪ /‬رشا صابر نوفل‬ ‫انشاء تطبيق بواجهات متعددة‬ ‫الفصل الثالث عشر‬

‫؛ وبفحص الخطأ يقول أن هذه األوامر ال تعمل مع اندرويد ‪ 19‬فال بد من تغير االندوريد الى ‪ 21‬أقل شىء‬

‫فنفتح ‪ Build gradle app‬ونغير اإلصدار الى ‪21‬‬

‫ثم ‪ synce Now‬؛ فتم تصحيح الخطأ ‪.‬‬

‫ولو أردنا وضع شروط محددة ؛ فمثال لو أردنا وضع شروط اذا كان المستخدم غير متصل بشبكة البيانات‬
‫أو شبكة الوافاى ؛ ويوضع شرط ما ؛‬

‫فمثال يمكن ظهور رسالة للمستخدم في حالة الهاتف غير متصل باالنترنت ؛‬

‫وفى حالة إذا كان المستخدم متصل بالشبكة بالواى فاى او بالبيانات " أي إحداهما " ويتم وضع شروط‬
‫محددة ؛ وذلك على النحو التالى ؛‬

‫‪128‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫انشاء تطبيق بواجهات متعددة‬ ‫الفصل الثالث عشر‬

‫نالحظ أن التظليل خلف الكود مختلف ؛ فلو شاهدنا المالحظات على الشرط نجده يقول أنه يمكن اختصار‬
‫الكود‬

‫فبالضغط على ‪ Simplify‬؛ يتم وضع اختصار الكود‪.‬‬

‫واذا أردنا وضع شرط إذا كان المستخدم غير متصل بشبكة الوافاى‬
‫{)‪ if (isWifiConn==false‬يتم وضع الشرط هنا‬

‫}‬

‫وعلى نفس المنوال ؛اذا أردنا وضع شرط إذا كان المستخدم غير متصل بشبكة بيانات الهاتف‬
‫{)‪ if (isMobileConn==false‬يتم وضع الشرط هنا‬
‫}‬

‫‪129‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫انشاء تطبيق بواجهات متعددة‬ ‫الفصل الثالث عشر‬

‫‪130‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫انشاء تطبيق بواجهات متعددة‬ ‫الفصل الثالث عشر‬

‫العرض األفقي للواجهة يف التطبيق‪:‬‬

‫من واجهة التطبيق‬

‫فينم إضافة الوضع االفقى؛ فيمكن عمل التصميم المناسب للوضع االفقى كيفما شئت ؛‬

‫وللعرض على أجهزة التابلت‬

‫‪131‬‬
‫ رشا صابر نوفل‬/‫د‬ ‫انشاء تطبيق بواجهات متعددة‬ ‫الفصل الثالث عشر‬

:" Swipe refresh "‫ بالسحب على شاشة االندرويد‬Refresh ‫لعمل‬

‫ ؛‬Gridview ‫ أو‬Listview ‫ أو‬webview ‫تقوم هذه الميزة على إما‬


‫ الى واجهة التطبيق؛‬webview ‫تم إضافة‬
: ‫ ؛ يتم وضع الكود التالى‬Build_gradle ‫في‬
implementation
'androidx.swiperefreshlayout:swiperefreshlayout:1.0.0'

swiperefresh ‫ الستدعاء مكتبة‬dependencies ‫ضمن عنصر‬

Sync Now ‫ثم عمل‬


‫ ؛‬Actavity mainxml ‫ومن واجهة‬
webview‫يتم وضع الكود التالى ؛ قبل الـ‬
<androidx.swiperefreshlayout.widget.SwipeRefreshLayout
android:id="@+id/swipe"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="50dp"
tools:ignore="MissingClass">

‫ من ضمنها بقفل الكود بـ‬webview‫ويتم وضع الـ‬


</androidx.swiperefreshlayout.widget.SwipeRefreshLayout>

132
‫د‪ /‬رشا صابر نوفل‬ ‫انشاء تطبيق بواجهات متعددة‬ ‫الفصل الثالث عشر‬

‫على صفحة الجافا الرئيسية ؛ ونقوم بعمل متغير من نوع ‪Swiprefresh‬‬


‫;‪SwipeRefreshLayout swip‬‬
‫يتم تحديد المتغير وذلك بعمل ‪ id‬للعنصر ‪swip‬‬ ‫ومن ضمن الـ‪method OnCreate‬‬

‫‪133‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫انشاء تطبيق بواجهات متعددة‬ ‫الفصل الثالث عشر‬

‫‪134‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫انشاء تطبيق بواجهات متعددة‬ ‫الفصل الثالث عشر‬

‫استخراج ملف ‪ APK‬من املشروع املقام على االندرويد استوديو‪:‬‬

‫‪ APK‬هي صيغة ملفات التي تستخدم في تثبيت وتطبيقات االندرويد؛‬

‫تظهر النافذة التالية؛ يتم تحديد ‪ APK‬منها‬

‫تظهر لنا نافذة ؛ فال بد من انشاء مفتاح الستخراج الملف بهذه الصيغة ؛ ملحوظة هذا المفتاح ال بد من‬
‫حفظه ألننا بحاجة اليه في كل مرة نحتاج استخراج ملف بصيغة‪. APK‬‬

‫‪135‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫انشاء تطبيق بواجهات متعددة‬ ‫الفصل الثالث عشر‬

‫ففي النافذة نختار ‪Create new‬؛‬

‫تظهر نافذة ؛ نختار مسار حفظ المفتاح ؛ وإنشاء كلمة مرور ووضع البيانات الشخصية؛ اسم المدينة‬
‫والمحافظة ورمز الدولة ؛‬

‫تظهر الشاشة التالية ؛ نختار ‪next‬‬

‫‪136‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫انشاء تطبيق بواجهات متعددة‬ ‫الفصل الثالث عشر‬

‫تظهر النافذة التالية ؛ نحدد مكان حفظ الملف؛ وتختار الخيارات الموضحة ؛ ثم ‪finsh‬‬

‫‪137‬‬
‫الباب البالث‬
‫ف‬ ‫غ‬ ‫ج‬‫ل‬ ‫ا‬ ‫م‬ ‫ل‬ ‫مع‬‫ل‬‫ا‬ ‫ظ‬ ‫ن‬ ‫ف‬ ‫ن‬ ‫ن‬ ‫ق‬‫ي‬‫ب‬‫ط‬‫ت‬
‫اب الأ در و د ي م و اب را بة‬
‫د‪ /‬رشا صابر نوفل‬ ‫مقدمة‬ ‫الباب الثالث‪ :‬تطبيقات األندر ويد يف نظم املعلومات اجلغرافية‬

‫مقدمة‪:‬‬

‫تزايدت أهمية تطبيقات نظم المعلومات الجغرافية التي تتعامل مع انظمة األندرويد في األونة األخيرة؛‬

‫فتطبيقات األندرويد المتعلقة بنظم المعلومات الجغرافية صممت للمستخدمين حتى تمكنهم من التعامل مع‬

‫البيانات الجغرافية المكانية من خالل هواتفهم المحمولة ‪ ،‬كما تساعد هذه التطبيقات على متابعة البيانات‬

‫وتحديثها ‪ ،‬وهى وسيلة مرنة إلدارة البيانات‪.‬‬

‫كما أن لتطبيقات االندرويد أهمية كبيرة في مجاالت نظم المعلومات الجغرافية ليس فقط في كونها أدوات‬

‫لجمع البيانات من الميدان وتحريرها إال أنها تساهم مع انترنت األشياء في الحصول على ‪Real Time Data‬‬

‫؛ ومن ثم تكوين ‪ Big Data‬؛ وأصبحت تقنية تستخدم لإلنذار فى حاالت الحوادث أو اإلنذارات المبكرة لحدوث‬

‫الكوارث ؛ وبالتالي فأصبحت تساعد على اتخاذ القرار المناسب سواء للمستخدم البسيط أو المتخصص فى نظم‬

‫المعلومات الجغرافية‪.‬‬

‫وسوف نوضح في هذا الباب كيفية استخدام خرائط جوجل وخرائط الـ ‪ open street map‬؛ النشاء تطبيق‬

‫خاص بنا ؛ وبعد ذلك نعرض كيفية استخدام ‪ ArcGIS Runtime SDK‬؛ وفى نهاية الباب يتم شرح كيفية‬

‫بناء تطبيق ويب للحصول على بيانات الطقس وذلك باستخدام ‪. map weather open‬‬

‫‪139‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫التعامل مع خرائط جوجل يف االندرويد أستوديو‬ ‫الفصل الرابع عشر‬

‫الفصل الرابع عشر التعامل مع خرائط جوجل يف االندرويد استوديو‪:‬‬

‫تظهر النافذة الخاصة بجوجل ماب؛ نذهب الى مطور جوجل للحصول على ‪ api‬الخاص بى ؛‬

‫‪ -‬يتم الدخول على الموقع من الرابط التالى‪:‬‬

‫‪/https://developers.google.com/maps‬‬
‫‪ -‬يتم تسجيل الدخول الى حساب جوجل الخاص بى‪.‬‬

‫‪140‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫التعامل مع خرائط جوجل يف االندرويد أستوديو‬ ‫الفصل الرابع عشر‬

‫‪141‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫التعامل مع خرائط جوجل يف االندرويد أستوديو‬ ‫الفصل الرابع عشر‬

‫‪142‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫التعامل مع خرائط جوجل يف االندرويد أستوديو‬ ‫الفصل الرابع عشر‬

‫ادخل على ‪ Library‬؛ أختار نوع ‪API‬؛‬

‫‪143‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫التعامل مع خرائط جوجل يف االندرويد أستوديو‬ ‫الفصل الرابع عشر‬

‫الدخول على ‪ ، Credentials‬ثم ‪CREATE CREDENTIALS‬‬

‫‪144‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫التعامل مع خرائط جوجل يف االندرويد أستوديو‬ ‫الفصل الرابع عشر‬

‫نعود الى االندرويد استوديو ونقوم بعمل اإلعدادت التالية‬

‫‪145‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫التعامل مع خرائط جوجل يف االندرويد أستوديو‬ ‫الفصل الرابع عشر‬

‫ونضع ‪ API‬الخاص بنا؛ في مجلد ‪google map api‬‬

‫في ملف ‪ manifest‬؛ نضع ‪ permission‬الخاص بإمكانية التطبيق باالتصال على االنترنت ‪.‬‬

‫‪146‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫التعامل مع خرائط جوجل يف االندرويد أستوديو‬ ‫الفصل الرابع عشر‬

‫نالحظ أنه في ‪map activity java‬؛ يوجد احداثيات لمدينة سيدنى ؛ يمكن تغييرها باالحداثيات المطلوبة ؛‬

‫تم تغيير االحداثيات الى مصر؛‬

‫‪147‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫التعامل مع خرائط جوجل يف االندرويد أستوديو‬ ‫الفصل الرابع عشر‬

‫لعمل زووم يتم تغيير الكود " أسفل االحداثيات الى ‪newLatLongZoom‬‬

‫‪148‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫التعامل مع خرائط جوجل يف االندرويد أستوديو‬ ‫الفصل الرابع عشر‬

‫ونضع رقم للـ‪zoom‬‬


‫‪mMap.moveCamera (CameraUpdateFactory.newLatLngZoom‬‬
‫;))‪(egypt,15‬‬
‫وفى ‪ title‬يمكن وضع عنوان محدد " مدينة منوف"‬

‫‪149‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫التعامل مع خرائط جوجل يف االندرويد أستوديو‬ ‫الفصل الرابع عشر‬

‫المكانية تغيير خريطة األساس الى ‪satellite‬؛ الضافة إمكانية عمل زووم ‪:‬‬

‫‪150‬‬
‫ رشا صابر نوفل‬/‫د‬ ‫التعامل مع خرائط جوجل يف االندرويد أستوديو‬ ‫الفصل الرابع عشر‬

‫لتغيير عالمة الموقع ؛‬

‫ ؛ ونضيف الكود التالى ؛‬arraw1 ‫ ؛ واسميها‬drawable ‫ننسخ صورة ونضعها في‬

‫لتتغيير اللوكيشن بواسطة المستخدم؛ فعندما يضغط المستخدم على الشاشة تظهر عالمة اللوكيشن ؛‬
mMap.setOnMapClickListener (new
GoogleMap.OnMapClickListener () {
@Override
public void onMapClick(@NonNull
@org.jetbrains.annotations.NotNull LatLng latLng) {
Toast.makeText (MapsActivity.this, latLng
.latitude + ","+latLng.latitude,
Toast.LENGTH_LONG).show ();
mMap.addMarker (new MarkerOptions
().position (latLng).title ("location")
);
}
});
}

151
‫د‪ /‬رشا صابر نوفل‬ ‫التعامل مع خرائط جوجل يف االندرويد أستوديو‬ ‫الفصل الرابع عشر‬

‫لكن لو أردنا مسح عالمة الموقع القديمة ووضع عالمة جديدة؛ يتم إضافة ;)( ‪mMap.clear‬‬

‫ملحوظة ‪ :‬التطبيق االن لم يمكن تصديره والعمل معه من قبل المستخدمين ألنه على نظام ‪ debug‬؛ وهو‬
‫نظام تجريبى للتطبيق ؛‬

‫‪152‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫التعامل مع خرائط جوجل يف االندرويد أستوديو‬ ‫الفصل الرابع عشر‬

‫فال بد من تغييره الى نظام ‪release‬‬

‫وبالتالي يتطلب منا وضع ‪ api‬داخل مجلد الخاص بالخريطة في ‪release‬؛‬

‫فمن ‪ file‬؛ نفتح المجلد الذى يحفظ به المشروع ونفتح ‪ app‬؛ ثم مجلد ‪ release‬؛ داخل ‪value‬؛ نجد ملف‬
‫‪ map,api‬؛يتم فتحه ولصق ‪ api‬بداخله ؛‬

‫‪153‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫استخدام خريطة ‪open street map‬‬ ‫الفصل اخلامس عشر‬

‫الفصل اخلامس عشر ‪ :‬استخدام خريطة ‪open street map‬‬

‫الدخول على اللينك‬

‫‪ https://github.com/osmdroid/osmdroid‬؛ ثم نسخ اللينك كما موضح بالصورة‬

‫الدخول على ‪ Build gradile‬واضافة الرابط الذى تم نسخه على النحو التالى‪:‬‬

‫‪154‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫استخدام خريطة ‪open street map‬‬ ‫الفصل اخلامس عشر‬

‫ثم تغيير اإلصدار ؛ حيث يتم نقل اإلصدار من الموقع السابق ذكر‪:‬‬

‫ويتم اضافته للكود السابق نسخه مكان كلمة >‪ <VERGIN‬؛ ليصبح على النحو التالي‪:‬‬

‫'‪implementation 'org.osmdroid:osmdroid-android: 6.1.10‬‬

‫نجد وجد خطأ في السطر الذى يليله ؛ يتم تصحيحه باختيار اإلصدار المناسب‬

‫‪155‬‬
‫ رشا صابر نوفل‬/‫د‬ open street map ‫استخدام خريطة‬ ‫الفصل اخلامس عشر‬

‫ليصبح‬
testImplementation 'junit:junit:'

Sync Now ‫ثم الضغط على‬

:‫ ونكتب العناصر التالية‬Android manifestes ‫ ثم نفتح الملف‬، manifestes ‫فتح المجلد‬


<uses-permission
android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION"/>

156
‫د‪ /‬رشا صابر نوفل‬ ‫استخدام خريطة ‪open street map‬‬ ‫الفصل اخلامس عشر‬

‫يتم فتح الـ‪ Layout‬على النحو الموضح أدناه‪:‬‬

‫يظهر التطبيق على النحو الموضح ؛ ويتم مسح العناصر الموضحة بلقطة الشاشة؛ ‪TextView‬‬

‫‪157‬‬
‫ رشا صابر نوفل‬/‫د‬ open street map ‫استخدام خريطة‬ ‫الفصل اخلامس عشر‬

‫ويتم وضع ما يلى‬


<org.osmdroid.views.MapView
android:id= "@+id/map"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>

‫ ؛ نضيف‬Main Activityjava ‫في نافذة‬

: ‫ثم نضع األكواد التالية‬

158
‫ رشا صابر نوفل‬/‫د‬ open street map ‫استخدام خريطة‬ ‫الفصل اخلامس عشر‬

ctx = getApplicationContext ();


Configuration.getInstance ().load (ctx ,

‫ ؛ نختار االختيار التالى ؛‬Configuration ‫مع مراعاة عند كتابة‬

‫واستكمال كتابة األكواد التالية؛‬


PreferenceManager.getDefaultSharedPreferences (ctx));
map =findViewById (R.id.map);
map.setTileSource
(TileSourceFactory.DEFAULT_TILE_SOURCE);
mapController = map.getController ();
mapController.setZoom (initialzoom);
Configuration.getInstance ().load (ctx,
PreferenceManager.getDefaultSharedPreferences (ctx));
map =findViewById (R.id.map);
map.setTileSource
(TileSourceFactory.DEFAULT_TILE_SOURCE);
mapController = map.getController ();
mapController.setZoom (initialzoom);

: ‫نالحظ ظهور خطأ ؛ يتم تصحيحه كما يلى‬

float ‫فيتم إضافة متغير من نوع‬

‫وأخيرا يتم يتم إضافة الكود التالى ؛‬


mapController.setCenter (initialCentre);
‫واضافة اعداداته ؛‬

159
‫د‪ /‬رشا صابر نوفل‬ ‫استخدام خريطة ‪open street map‬‬ ‫الفصل اخلامس عشر‬

‫عند عمل ‪ run‬للتطبيق تظهر الخريطة على النحو التالى ؛‬

‫‪160‬‬
‫ رشا صابر نوفل‬/‫د‬ open street map ‫استخدام خريطة‬ ‫الفصل اخلامس عشر‬

MainActivity.java ‫يتم إضافة األكواد التالية في مجلد‬


‫ الخاصة بإيجاد المواقع؛‬Strings ‫ ؛ وإعدادت‬GPS‫أكواد لعمل زووم ؛ إمكانية الوصول للـ‬

‫ثم‬

‫ ؛ ويتم تصحيح الخطأ بها؛‬getLocationPermission ‫ثم إضافة‬

getLocationPermission‫وضع شرط للـ‬


private void getLocationPermission() {
// check prmission
if (ActivityCompat.checkSelfPermission
(MainActivity.this ,permission[0]) !=
PackageManager.PERMISSION_GRANTED){
// NOT GRENTED
// do relvant acthion

161
‫ رشا صابر نوفل‬/‫د‬ open street map ‫استخدام خريطة‬ ‫الفصل اخلامس عشر‬

if
(ActivityCompat.shouldShowRequestPermissionRationale
(MainActivity.this, permission[0])){
AlertDialog.Builder builder = new
AlertDialog.Builder (MainActivity.this);
");‫اذن الموقع‬ builder.setTitle ("
‫هذا التطبيق يتطلب الوصول‬ builder.setMessage ("
");‫الى الموقع‬
", new ‫موافق‬ builder.setPositiveButton ("
DialogInterface.OnClickListener () {
@Override
public void onClick(DialogInterface
dialog, int which) {
}
});
", new ‫الغاء‬ builder.setPositiveButton ("
DialogInterface.OnClickListener () {
@Override
public void onClick(DialogInterface
dialog, int which) {
}
});
builder.show ();
} else if (appPrefs.getBoolean (permission[0] ,
false)){
} else {

}
SharedPreferences.Editor editor =appPrefs.edit ();
editor.putBoolean (permission[0] , true );
editor.commit ();
} else {

‫يتم نسخ األكواد مرة أخرى من‬


AlertDialog.Builder builder = new AlertDialog.Builder
(MainActivity.this);
");‫اذن الموقع‬builder.setTitle ("
");‫تمكين الوصول الى الموقع‬builder.setMessage ("
", new ‫السماح‬builder.setPositiveButton ("

162
‫ رشا صابر نوفل‬/‫د‬ open street map ‫استخدام خريطة‬ ‫الفصل اخلامس عشر‬

DialogInterface.OnClickListener () {
@Override
public void onClick(DialogInterface
dialogInterface, int i) {
dialogInterface.cancel ();
}
});
", new ‫إلغاء‬builder.setPositiveButton ("
DialogInterface.OnClickListener () {
@Override
public void onClick(DialogInterface
dialogInterface, int i) {
dialogInterface.cancel ();
}
});
builder.show ();

‫ووضعها باالسفل كما موضح‬

):MainActivity java ‫واستكمال األكواد كما موضح أدناه ؛ (مجلد‬

163
‫ رشا صابر نوفل‬/‫د‬ open street map ‫استخدام خريطة‬ ‫الفصل اخلامس عشر‬

package com.example.datacolection_app;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.icu.text.CaseMap;
import android.net.Uri;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.provider.Settings;
import android.widget.Toast;
import org.osmdroid.api.IMapController;
import org.osmdroid.config.Configuration;
import
org.osmdroid.tileprovider.tilesource.TileSourceFactory;
import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapView;
public class MainActivity extends AppCompatActivity {
MapView map = null;
Context ctx = null;
IMapController mapController = null;
float initialzoom = 15;
GeoPoint initialCentre = new GeoPoint (30.0, 31.0);
// PREFS
SharedPreferences appPrefs = null;
//CONSTANTS
private static final int REQUEST_GPS = 9001;
private static final int
REQUEST_PERMISSION_SETTINGS = 1001;
//PERMISSION STRINGS
String[] permission = new

164
‫ رشا صابر نوفل‬/‫د‬ open street map ‫استخدام خريطة‬ ‫الفصل اخلامس عشر‬

String[]{Manifest.permission.ACCESS_FINE_LOCATION};

@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate (savedInstanceState);
setContentView (R.layout.activity_main);
// CONFIGURATION
ctx = getApplicationContext ();
Configuration.getInstance ().load (ctx,
PreferenceManager.getDefaultSharedPreferences (ctx));
// MAP INITALITE
map = (MapView) findViewById (R.id.map);
// TILESOURCE
map.setTileSource (TileSourceFactory.MAPNIK);
// MAP CONNECTOR , ZOOM , CENTER
mapController = map.getController ();
mapController.setZoom (initialzoom);
mapController.setCenter (initialCentre);
//INIT PREFS
appPrefs = getSharedPreferences ("GISAppPrefs",
MODE_PRIVATE);
getLocationPermission ();
}

private void getLocationPermission() {


// check prmission
if (ActivityCompat.checkSelfPermission
(MainActivity.this ,permission[0]) !=
PackageManager.PERMISSION_GRANTED){
// NOT GRENTED
// do relvant acthion
if
(ActivityCompat.shouldShowRequestPermissionRationale
(MainActivity.this, permission[0])){
AlertDialog.Builder builder = new
AlertDialog.Builder (MainActivity.this);
");‫اذن الموقع‬ builder.setTitle ("
‫هذا التطبيق يتطلب‬ builder.setMessage ("
");‫الوصول الى الموقع‬

165
‫ رشا صابر نوفل‬/‫د‬ open street map ‫استخدام خريطة‬ ‫الفصل اخلامس عشر‬

", ‫السماح‬ builder.setPositiveButton ("


new DialogInterface.OnClickListener () {
@Override
public void onClick(DialogInterface
dialogInterface, int which) {
ActivityCompat.requestPermissions
(MainActivity.this , permission ,REQUEST_GPS);
dialogInterface.cancel ();
}
});
", new ‫الغاء‬ builder.setPositiveButton ("
DialogInterface.OnClickListener () {
@Override
public void onClick(DialogInterface
dialogInterface, int which) {
dialogInterface.cancel ();
}
});
builder.show ();
} else if (appPrefs.getBoolean (permission[0]
, false)){
AlertDialog.Builder builder = new
AlertDialog.Builder (MainActivity.this);
");‫اذن الموقع‬ builder.setTitle ("
‫تمكين الوصول الى‬ builder.setMessage ("
");‫الموقع من االعدادات‬
", new ‫السماح‬ builder.setPositiveButton ("
DialogInterface.OnClickListener () {
@Override
public void onClick(DialogInterface
dialogInterface, int which) {
dialogInterface.cancel ();
Intent intent = new Intent
(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts
("Package",getPackageName (),null);
intent.setData (uri);
startActivityForResult
(intent,REQUEST_PERMISSION_SETTINGS);
}

166
‫ رشا صابر نوفل‬/‫د‬ open street map ‫استخدام خريطة‬ ‫الفصل اخلامس عشر‬

});
", new ‫الغاء‬ builder.setPositiveButton ("
DialogInterface.OnClickListener () {
@Override
public void onClick(DialogInterface
dialogInterface, int which) {
dialogInterface.cancel ();

}
});
builder.show ();
} else {
ActivityCompat.requestPermissions
(MainActivity.this , permission ,REQUEST_GPS);
}
SharedPreferences.Editor editor =appPrefs.edit
();
editor.putBoolean (permission[0] , true );
editor.commit ();
} else {
//greanted
getGPSLocation ();
}
}

@Override
public void onRequestPermissionsResult(int
requestCode, @NonNull
@org.jetbrains.annotations.NotNull String[]
permissions, @NonNull
@org.jetbrains.annotations.NotNull int[] grantResults)
{
super.onRequestPermissionsResult (requestCode,
permissions, grantResults);
if (requestCode == REQUEST_GPS){
if (grantResults.length>0 &&
grantResults[0] == PackageManager.PERMISSION_GRANTED){
getGPSLocation ();
} else {
‫غير‬ Toast.makeText (MainActivity.this,"

167
‫ رشا صابر نوفل‬/‫د‬ open street map ‫استخدام خريطة‬ ‫الفصل اخلامس عشر‬

",Toast.LENGTH_LONG ).show ();‫قادر للوصول الى الموقع‬


}

}
}

private void getGPSLocation () {

}
}

168
‫د‪ /‬رشا صابر نوفل‬ ‫تطبيقات األندر ويد باستخدام ‪ArcGIS Runtime SDK‬‬ ‫الفصل السادس عشر‬

‫الفصل السادس عشر‪ :‬تطبيقات االندرويد باستخدام‪ArcGIS Runtime SDK‬‬

‫إعدادات العمل ‪:‬‬

‫‪https://developers.arcgis.com/android/‬‬ ‫يتم تسجيل الدخول الى موقع ‪developers‬‬

‫خطوة مهمة للعمل مع تطبيقات االندرويد في ‪GIS‬‬

‫يتم تثبيت ‪ Android SDK‬من الموقع‬


‫‪https://developers.arcgis.com/downloads/#android‬‬

‫‪ :SDK‬اختصار لـ ‪Software Development Kit‬؛ وهى األدوات واالضافات التي يستخدمها مطورى‬
‫االندرويد ‪.‬‬

‫يكون ملف مضغوط ؛ يتم فك الملف ؛ نجد أنه يوجد ملف ‪ libs‬؛ بداخله ملفات ؛ يتم نسخها ولصقها داخل‬
‫المجلد ‪ libs‬؛ في برنامج االندرويد استوديو ؛ حتى يتم الوصول الى الخرائط‪.‬‬

‫مع مراعاة األخذ في االعتبار اصدار النسخة التي تم تثبيتها ؛ حيث أنها هي التي تستخدم في الحصول‬
‫على الخرائط‪.‬؛ هنا تم استخدام نسخة ‪. 10.0.1‬‬

‫‪169‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫تطبيقات األندر ويد باستخدام ‪ArcGIS Runtime SDK‬‬ ‫الفصل السادس عشر‬

‫عرض خريطة األساس على التطبيق ‪:‬‬

‫‪ -‬فتح االندرويد استوديو؛ نحتاج اجراء بعض التعديالت ؛ نفتح ملف ‪. build.gradle‬‬
‫يكتب الكود التالى والخاص باستدعاء خريطة ايزرى‬ ‫‪-‬‬

‫{ ‪maven‬‬
‫'‪url 'https://esri.jfrog.io/artifactory/arcgis‬‬
‫}‬

‫وفى ملف )‪ build_ gradle(module‬؛ وفى جزء ‪dependencies‬‬


‫ويتم إضافة الكود التالى‪ :‬؛‬
‫'‪compile 'com.esri.arcgisruntime:arcgis-android:100.1.0‬‬

‫‪170‬‬
‫ رشا صابر نوفل‬/‫د‬ ArcGIS Runtime SDK ‫تطبيقات األندر ويد باستخدام‬ ‫الفصل السادس عشر‬

.SynceNow ‫ ثم‬-
: ‫ التالية‬permission ‫ ؛ يتم وضع‬manifests ‫ وفى‬-
<uses-permission android:name="android.permission.INTERNET"
/>
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-feature android:glEsVersion="0x00020000"
android:required="true" />

‫في الجزء الخاص بعرض واجهة التطبيق‬


‫ ووضع االكواد الخاصة بعرض خريطة أساس‬textView ‫ ومسح الجزء الخاص بـ‬split ‫؛ ثم اختيار وضع‬
‫بهذا الشكل‬

:‫واضافة االكواد التالية‬


<com.esri.arcgisruntime.mapping.view.MapView
android:id="@+id/map1"

171
‫ رشا صابر نوفل‬/‫د‬ ArcGIS Runtime SDK ‫تطبيقات األندر ويد باستخدام‬ ‫الفصل السادس عشر‬

android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
tools:ignore="MissingClass"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"/>

:Main Activity Java ‫وبعد ذلك في نافذة‬


:MapViea ‫يتم عمل متغير‬
private MapView mv;
: ‫وبعد ذلك إضافة االكواد التالية‬

mv = (MapView)findViewById(R.id.map1);
ArcGISMap map = new

172
‫ رشا صابر نوفل‬/‫د‬ ArcGIS Runtime SDK ‫تطبيقات األندر ويد باستخدام‬ ‫الفصل السادس عشر‬

ArcGISMap(Basemap.Type.STREETS_VECTOR, 31.0, 30.0,11);


mv.setMap(map);
}
import class ‫نجد خطأ نقف بالماوس حتى تنبثق نافذة نختار منها‬

‫وأخي اًر اضافة األكواد التالية‬


@Override
protected void onPause() {
super.onPause ();
mv.pause ();
}

@Override
protected void onResume() {
super.onResume ();
mv.resume ();
}

173
‫د‪ /‬رشا صابر نوفل‬ ‫تطبيقات األندر ويد باستخدام ‪ArcGIS Runtime SDK‬‬ ‫الفصل السادس عشر‬

‫عند عمل ‪run‬؛ وجدنا أخطاء ‪:‬‬

‫األول ‪ :‬أن نظام االندرويد ‪ 19‬؛ولكى يعمل ال بد وأن يكون بدء من ‪23‬‬

‫في نافذة ‪Build gradil app‬‬

‫الثانى ‪ :‬يطلب منى وضع الكود التالى داخل ‪build gradle‬‬


‫{ ‪android‬‬
‫'‪ndkVersion '21.3.6528147‬‬
‫}‬

‫الخطأ الثالث ‪ :‬يطلب مسح ملف ‪ ndk-bundle‬من المجلد ‪Local‬؛ داخل ‪ AddData‬؛ والموجود داخل‬
‫ملف ‪ users‬؛ على الجهاز ‪.‬النه يتعارض مع متطلبات التطبيق‪.‬‬

‫‪174‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫تطبيقات األندر ويد باستخدام ‪ArcGIS Runtime SDK‬‬ ‫الفصل السادس عشر‬

‫لتغيير خريطة األساس‪:‬‬

‫في نافذة الـ‪ Main Activity Java‬؛‬

‫عند الـ‪ Type‬؛يتم تغيير خريطة األساس؛ على النحو الموضح أدناه ‪.‬‬

‫‪175‬‬
‫ رشا صابر نوفل‬/‫د‬ ArcGIS Runtime SDK ‫تطبيقات األندر ويد باستخدام‬ ‫الفصل السادس عشر‬

30°55‫و‬30°27'50‫إلضافة نقطة على التطبيق؛ بإحداثيات النقاط ؛ فمثال أريد وضع موقع مدينة منوف‬
.MainActivity Java ‫يتم إضافة النقطة بالكود التالى في نافذة‬
ArcGISMap myMap = new
ArcGISMap(Basemap.createNationalGeographic());
Viewpoint myViewpoint = new
Viewpoint(30.27,30.55,200000);
myMap.setInitialViewpoint(myViewpoint);

176
‫ رشا صابر نوفل‬/‫د‬ ArcGIS Runtime SDK ‫تطبيقات األندر ويد باستخدام‬ ‫الفصل السادس عشر‬

On Touch Listener:

‫ لالعدادات السابق ذكرها ؛‬set.OnTouchListener ‫يتم إضافة‬


mv.setOnTouchListener (new
DefaultMapViewOnTouchListener (this , mv){
@Override
public boolean onSingleTapConfirmed(MotionEvent e)
{
Toast.makeText (getApplicationContext (), "map
is tapped ! ", Toast.LENGTH_SHORT).show ();
return true;
}
});

:‫ استرداد مقياس الرسم‬: Retrieve Map Scale

‫إضافة الكود التالى؛‬


String myMapScale = String.valueOf(mv.getMapScale());
Toast.makeText(getApplicationContext(), "The current map scale
is: " + myMapScale, Toast.LENGTH_SHORT).show();return true;

177
‫د‪ /‬رشا صابر نوفل‬ ‫تطبيقات األندر ويد باستخدام ‪ArcGIS Runtime SDK‬‬ ‫الفصل السادس عشر‬

‫ثم عمل ‪ run‬؛‬

‫‪178‬‬
‫ رشا صابر نوفل‬/‫د‬ ArcGIS Runtime SDK ‫تطبيقات األندر ويد باستخدام‬ ‫الفصل السادس عشر‬

: ‫إضافة االرجاع الجغرافى للخريطة‬


String myMapSpatialRef =
String.valueOf(mv.getSpatialReference().getWkid());
Toast.makeText(getApplicationContext(), "The current map spatial
ref wkid is: " + myMapSpatialRef, Toast.LENGTH_SHORT).show();

179
‫د‪ /‬رشا صابر نوفل‬ ‫تطبيقات األندر ويد باستخدام ‪ArcGIS Runtime SDK‬‬ ‫الفصل السادس عشر‬

‫‪180‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫تطبيقات األندر ويد باستخدام ‪ArcGIS Runtime SDK‬‬ ‫الفصل السادس عشر‬

‫عرض ثالثى األبعاد على االندرويد‪:‬‬


‫‪ -‬يكتب الكود التالى والخاص باستدعاء خريطة ايزرى‬
‫{ ‪maven‬‬
‫'‪url 'https://esri.jfrog.io/artifactory/arcgis‬‬
‫}‬

‫وفى ملف )‪ build_ gradle(module‬؛ وفى جزء ‪dependencies‬‬


‫ويتم إضافة الكود التالى‪ :‬؛‬
‫'‪compile 'com.esri.arcgisruntime:arcgis-android:100.1.0‬‬

‫‪181‬‬
‫ رشا صابر نوفل‬/‫د‬ ArcGIS Runtime SDK ‫تطبيقات األندر ويد باستخدام‬ ‫الفصل السادس عشر‬

.SynceNow ‫ ثم‬-
: ‫ التالية‬permission ‫ ؛ يتم وضع‬manifests ‫ وفى‬-
<uses-permission android:name="android.permission.INTERNET"
/>
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-feature android:glEsVersion="0x00020000"
android:required="true" />

‫في الجزء الخاص بعرض واجهة التطبيق‬


‫ ووضع االكواد الخاصة بعرض خريطة أساس‬textView ‫ ومسح الجزء الخاص بـ‬split ‫؛ ثم اختيار وضع‬
:‫واضافة االكواد التالية‬

<com.esri.arcgisruntime.mapping.view.SceneView
android:id="@+id/map1"android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:layout_marginTop="8dp"
android:layout_marginBottom="8dp"/>

182
‫ رشا صابر نوفل‬/‫د‬ ArcGIS Runtime SDK ‫تطبيقات األندر ويد باستخدام‬ ‫الفصل السادس عشر‬

:Main Activity Java ‫وبعد ذلك في نافذة‬


:MapViea ‫يتم عمل متغير‬
private SceneView sv;
: ‫وبعد ذلك إضافة االكواد التالية‬
sv = (SceneView) findViewById(R.id.map1);
ArcGISScene myScene = new
ArcGISScene(Basemap.createImagery());
sv.setScene(myScene);
}
@Override
protected void onPause(){
super.onPause();sv.pause();}
@Override
protected void onResume(){
super.onResume();sv.resume();}
}

183
‫د‪ /‬رشا صابر نوفل‬ ‫تطبيقات األندر ويد باستخدام ‪ArcGIS Runtime SDK‬‬ ‫الفصل السادس عشر‬

‫ويمكن تغيير خريطة األساس؛‬

‫‪184‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫تطبيقات األندر ويد باستخدام ‪ArcGIS Runtime SDK‬‬ ‫الفصل السادس عشر‬

‫‪Camera‬‬

‫في نافذة ‪ MainActivity Java‬؛ يتم إضافة الكود التالى ‪:‬‬


‫‪Camera myCamera = new‬‬
‫‪Camera(35.59520,138.78045,2719.97086,195.47934,79.35755‬‬
‫;)‪2,0.0‬‬
‫;)‪sv.setViewpointCamera(myCamera‬‬
‫يظهر خطأ ؛‬

‫يتم الضغط على ‪ import class‬واختيار أول نوع‬

‫‪185‬‬
‫ رشا صابر نوفل‬/‫د‬ ArcGIS Runtime SDK ‫تطبيقات األندر ويد باستخدام‬ ‫الفصل السادس عشر‬

Data Set elvation

strings ‫؛‬value ‫ ؛‬res ‫في مجلد‬

: ‫ويتم وضع الكود التالى‬


<string
name="elevation3dUrl">"http://elevation3d.arcgis.com/ar
cgis/rest/services/WorldElevation3D/Terrain3D/ImageServ
er"</string>

: ‫ ؛ يتم إضافة الكود التالى‬MainActivity Java ‫و في نافذة‬


ArcGISTiledElevationSource myElevation = new
ArcGISTiledElevationSource (getString
(R.string.elevation3dUrl));
myScene.getBaseSurface ().getElevationSources
().add (myElevation);
}

186
‫د‪ /‬رشا صابر نوفل‬ ‫تطبيقات األندر ويد باستخدام ‪ArcGIS Runtime SDK‬‬ ‫الفصل السادس عشر‬

‫إضافة طبقات للتطبيق الخاص بى ‪:‬‬

‫الحصول على رابط الطبقات ‪:‬‬

‫رفع الملفات على االنترنت ‪:‬‬

‫عمل تسجيل دخول الى ‪ Arc gis on line‬من برنامج االرك ‪ GIS‬ديسك توب من ‪ file‬واختار ‪Sine‬‬
‫‪ in‬وتسجيل الدخول ثم عمل ‪ Share‬مرة أخرى وأختار من النافذة التالية ‪ host‬الخاص بى على االرك‬
‫اونالين‪.‬‬

‫‪187‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫تطبيقات األندر ويد باستخدام ‪ArcGIS Runtime SDK‬‬ ‫الفصل السادس عشر‬

‫لو اردنا عمل تعديل على البيانات ؛ على االونالين يتم اختيار ‪feature Access‬‬

‫ظهرت النافذة التالية ؛ فال بد من تصحيح األخطاء الموجودة بها؛‬

‫‪188‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫تطبيقات األندر ويد باستخدام ‪ArcGIS Runtime SDK‬‬ ‫الفصل السادس عشر‬

‫الخطأ األول يطلب إضافة ‪ Tag‬؛ فيتم وضع ‪ add tag‬في خانة ‪ Tags‬؛ ثم الضغط على ‪ Analyze‬؛‬
‫والذهاب الى الخطأ الثاني والضغط عليه دبل كليك ؛ يطلب وضع وصف فيتم وضعه ثم الضغط على‬
‫‪ Analyze‬وفى النهاية يتم الضغط على ‪.Publish‬‬

‫الدخول على االرك اونالين ؛ على ‪ Contant‬؛ أفتح المشروع المراد رفعه على التطبيق ؛ أسفل الشاشة‬
‫نجد رابط ‪ URL‬؛ الخاص بالمشروع‬

‫يتم نسخ الرابط ؛ ولصقه في متصفح الانترنت ؛ والدخول على الرابط ؛ نجد الطبقات الخاصة بنا ؛‬

‫‪189‬‬
‫ رشا صابر نوفل‬/‫د‬ ArcGIS Runtime SDK ‫تطبيقات األندر ويد باستخدام‬ ‫الفصل السادس عشر‬

‫ندخل على الطبقة المطلوبة وننسخ الرابط الخاص بها ؛‬

‫ للخريطة ويتم إضافة بعض التعديالت واالكواد‬3D ‫ أو‬2D ‫على نفس اعدادات السابقة ؛ سواء العرض‬
Main Activity Java ‫التالية على واجهة‬
private MapView mvMapView;
private ArcGISMap mvMap;
private ServiceFeatureTable mvServiceFeatureTable ;
private FeatureLayer mvFeatureLayer;
private String
featureLayerUrl="https://services8.arcgis.com/c9p1i7LVL
mrhn2tm/ArcGIS/rest/services/%d8%a7%d8%b3%d8%aa%d8%ae%d
8%af%d8%a7%d9%85%d8%a7%d8%aa/FeatureServer/0";

190
‫ رشا صابر نوفل‬/‫د‬ ArcGIS Runtime SDK ‫تطبيقات األندر ويد باستخدام‬ ‫الفصل السادس عشر‬

‫واضافة ما يلى لنفس الواجهة مع مراعاة تغيير االحداثيات وخريطة األساس‬


mvMapView = findViewById (R.id.map1);
mvMap = new
ArcGISMap(Basemap.Type.IMAGERY_WITH_LABELS,
30.44,30.98,11);
mvServiceFeatureTable=new ServiceFeatureTable
(featureLayerUrl);
mvFeatureLayer=new FeatureLayer
(mvServiceFeatureTable);
mvMap.getOperationalLayers ().add (mvFeatureLayer);
mvMapView.setMap(mvMap);
mvServiceFeatureTable = new ServiceFeatureTable
(featureLayerUrl);
mvFeatureLayer = new FeatureLayer
(mvServiceFeatureTable);

191
‫د‪ /‬رشا صابر نوفل‬ ‫تطبيقات األندر ويد باستخدام ‪ArcGIS Runtime SDK‬‬ ‫الفصل السادس عشر‬

‫‪192‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫تطبيقات األندر ويد باستخدام ‪ArcGIS Runtime SDK‬‬ ‫الفصل السادس عشر‬

‫إضافة قائمة مهام الى الخريطة‪:‬‬

‫بعد إضافة االعدادات األساسية الخاصة بمجلد ‪ Buildgradle‬واضافة الـ ‪ prmission‬في مجلد‬
‫‪ manifest‬و‪ MainActivity Java‬كما سبق وأن ذكرنا في اعدادت إضافة خريطة األساس ؛ يتم تغيير‬
‫عرض ال‪Lay out‬الى ‪ Linear‬؛ ثم نعطى احجام للخريطة ولباقى أجزاء الشاشة حيث يتم تقسيم الشاشة الى‬
‫جزئيين جزء علوى للمهام وجزء أسفل للخريطة‬

‫ويتم ذلك على مجلد ‪ activity_main.xml‬وذلك على النحو الموضح؛‬

‫‪193‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫تطبيقات األندر ويد باستخدام ‪ArcGIS Runtime SDK‬‬ ‫الفصل السادس عشر‬

‫يتم إضافة باقى عناصر المطلوبة للتصميم ؛ فنحتاج جزء خاص بالمهام فيتم تقسيم التصميم كيفما شئت ؛‬
‫وفيمال يلى توضيح ما قمت به في المثال ؛ تم إضافة ‪ Edit Text‬؛ ‪Button‬‬

‫بعد ذلك يتم وضع ‪List View‬؛ واضافة الخريطة كما موضح‬

‫وضع الـ ‪ id‬لكل العناصر ‪MapView , EditorText, Button ,ListView‬‬


‫"‪android:id="@+id/mwEditorText‬‬
‫"‪android:id="@+id/mvButton‬‬
‫"‪android:id="@+id/mvListView‬‬
‫"‪android:id="@+id/mvMapView‬‬

‫‪194‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫تطبيقات األندر ويد باستخدام ‪ArcGIS Runtime SDK‬‬ ‫الفصل السادس عشر‬

‫‪195‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫تطبيقات األندر ويد باستخدام ‪ArcGIS Runtime SDK‬‬ ‫الفصل السادس عشر‬

‫بعد ذلك يتم عمل متغيرات داخل مجلد ‪ MainActivity.Java‬لهذه العناصر؛ واعدادات المتغيرات على‬
‫النحو التالى ؛‬

‫بعد ذلك يتم عمل اعدادات الـ‪ Button‬الستخدامه بالـ ‪Oncklick‬؛‬


‫‪mvButton.setOnClickListener (new View.OnClickListener‬‬
‫{ )(‬
‫‪@Override‬‬
‫{ )‪public void onClick(View v‬‬

‫}‬
‫;)}‬

‫وبهذا نكون انشانا التصميم بكافه عناصره ومتغيراته ؛‬

‫‪196‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫تطبيقات األندر ويد باستخدام ‪ArcGIS Runtime SDK‬‬ ‫الفصل السادس عشر‬

‫بعد ذلك يتبقى لنا قائمة عرض المهام والتي تستخدم بالضغط عليها فيتم عمل مصفوفة‬

‫‪197‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫تطبيقات األندر ويد باستخدام ‪ArcGIS Runtime SDK‬‬ ‫الفصل السادس عشر‬

‫يتم وضع الشروط الخاصة بعمل القائمة والمصفوفة ؛‬

‫عند عمل ‪ run‬يظهر التطبيق على النحو التالى ؛‬

‫‪198‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫تطبيقات األندر ويد باستخدام ‪ArcGIS Runtime SDK‬‬ ‫الفصل السادس عشر‬

‫لكن الحظنا انه اذا تم كتابة خطأ ال يمكننا مسح الـ‪ task‬والمكانية حذف الـ ‪task‬‬

‫العدادات الموقع ‪:‬‬

‫في مجلد ‪ Mainfest‬اذن الوصول الى الموقع‬

‫في ملف الجافا ؛ يتم عمل متغيير‬

‫‪199‬‬
‫ رشا صابر نوفل‬/‫د‬ ArcGIS Runtime SDK ‫تطبيقات األندر ويد باستخدام‬ ‫الفصل السادس عشر‬

‫؛‬Strings ‫وفى مجلد‬

‫واضافة؛‬

‫ثم إضافة باقى االعدادات على النحو التالى؛‬


private void setupLocationDisplay() {
mLocationDisplay = mvMapView.getLocationDisplay
();

mLocationDisplay.addDataSourceStatusChangedListener
(dataSourceStatusChangedEvent -> {
if (dataSourceStatusChangedEvent.isStarted
() || dataSourceStatusChangedEvent.getError () == null)
{
return;
}
int requestPermissionCode = 2;
String[] requestPermissions = new
String[]{Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION};

if (!(ContextCompat.checkSelfPermission
(MainActivity.this, requestPermissions[0]) ==
PackageManager.PERMISSION_GRANTED

200
‫ رشا صابر نوفل‬/‫د‬ ArcGIS Runtime SDK ‫تطبيقات األندر ويد باستخدام‬ ‫الفصل السادس عشر‬

&&
ContextCompat.checkSelfPermission (MainActivity.this,
requestPermissions[1]) ==
PackageManager.PERMISSION_GRANTED)) {
ActivityCompat.requestPermissions
(MainActivity.this, requestPermissions,
requestPermissionCode);
} else {
String message = String.format ("Error
in DataSourceStatusChangedListener:%s",

dataSourceStatusChangedEvent.getSource
().getLocationDataSource ().getError ().getMessage ());
Toast.makeText (MainActivity.this,
message, Toast.LENGTH_LONG).show ();
}
});
mLocationDisplay.setAutoPanMode
(LocationDisplay.AutoPanMode.COMPASS_NAVIGATION);
mLocationDisplay.startAsync ();
}

public void onRequestPermissionResult(int


requestCode , @NonNull String [] Permissions , @NonNull
int [] grantResults){
if (grantResults.length > 0 &&
grantResults[0]== PackageManager.PERMISSION_GRANTED){
mLocationDisplay.startAsync ();
}else {
Toast.makeText
(MainActivity.this,getResources ().getString
(R.string.location_permission_denied),Toast.LENGTH_LONG
).show ();
}
}
@Override
protected void onPause(){
mvMapView.pause ();
super.onPause ();

201
‫ رشا صابر نوفل‬/‫د‬ ArcGIS Runtime SDK ‫تطبيقات األندر ويد باستخدام‬ ‫الفصل السادس عشر‬

}
@Override
protected void onResume(){
super.onResume ();
mvMapView.resume ();
}

}
import ‫ ؛ تم البحث عن الخطأ ؛ فوجدنا ضرورة عمل‬Permission ‫نجد وجود خطأ على كلمة‬
import android.Manifest;
‫وحذف‬
import java.util.jar.Manifest;

"‫وتكون المجلدات على النحو الموضح " لمراجعة األكواد‬

ActivityMain
<?xml version="1.0" encoding="utf-8"?>

<LinearLayout
android:orientation="vertical"
android:weightSum="10"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"

202
‫ رشا صابر نوفل‬/‫د‬ ArcGIS Runtime SDK ‫تطبيقات األندر ويد باستخدام‬ ‫الفصل السادس عشر‬
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<LinearLayout
android:weightSum="10"
android:orientation="horizontal"
android:layout_weight="9"
android:layout_width="match_parent"
android:layout_height="match_parent">

<EditText
android:id="@+id/mvEditText"
android:layout_weight="2"
android:layout_width="match_parent"
android:layout_height="match_parent">
</EditText>

<Button
android:id="@+id/mvButton"
android:layout_weight="8"
android:text="Add Task"
android:layout_width="match_parent"
android:layout_height="match_parent">
</Button>
</LinearLayout>

<LinearLayout
android:weightSum="10"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">

<ListView
android:id="@+id/mvListView"
android:layout_width="match_parent"
android:layout_height="330dp"
android:layout_weight="5">

</ListView>

<com.esri.arcgisruntime.mapping.view.MapView
android:id="@+id/mvMapView"
android:layout_width="match_parent"
android:layout_height="313dp"

203
‫ رشا صابر نوفل‬/‫د‬ ArcGIS Runtime SDK ‫تطبيقات األندر ويد باستخدام‬ ‫الفصل السادس عشر‬
android:layout_weight="5">

</com.esri.arcgisruntime.mapping.view.MapView>

</LinearLayout>

</LinearLayout>

Activity java
package com.example.map5_task;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;

import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;

import com.esri.arcgisruntime.mapping.ArcGISMap;
import com.esri.arcgisruntime.mapping.Basemap;
import com.esri.arcgisruntime.mapping.view.LocationDisplay;
import com.esri.arcgisruntime.mapping.view.MapView;

import java.sql.Array;
import java.util.ArrayList;
import android.Manifest;

public class MainActivity extends AppCompatActivity {


private MapView mvMapView;
private EditText mvEditText;
private Button mvButton;
private ListView mvListView;
private ArrayList<String> mvItems;
private ArrayAdapter mvAdapter;
private LocationDisplay mLocationDisplay;
@Override
protected void onCreate(Bundle savedInstanceState) {

204
‫ رشا صابر نوفل‬/‫د‬ ArcGIS Runtime SDK ‫تطبيقات األندر ويد باستخدام‬ ‫الفصل السادس عشر‬
super.onCreate (savedInstanceState);
setContentView (R.layout.activity_main);
mvEditText = findViewById (R.id.mvEditText);
mvListView = findViewById (R.id.mvListView);
mvMapView = findViewById (R.id.mvMapView);
mvButton = findViewById (R.id.mvButton);

mvItems = new ArrayList<> ();


mvAdapter = new ArrayAdapter<> (this,
android.R.layout.simple_list_item_1, mvItems);
mvListView.setAdapter (mvAdapter);

mvButton.setOnClickListener (new View.OnClickListener ()


{
@Override
public void onClick(View v) {
String taskdata = mvEditText.getText ().toString
();
if (taskdata.equals ("")) {
Toast.makeText (MainActivity.this, "Task
Cannot be empty", Toast.LENGTH_LONG).show ();
} else {
mvAdapter.add (taskdata);
}
}

});

deletTask ();

ArcGISMap mvMap = new ArcGISMap ();


mvMap.setBasemap (Basemap.createOpenStreetMap ());
mvMapView.setMap (mvMap);
setupLocationDisplay ();
}

private void deletTask() {


mvListView.setOnItemLongClickListener (new
AdapterView.OnItemLongClickListener () {
@Override
public boolean onItemLongClick(AdapterView<?>
parent, View view, int position, long id) {
Toast.makeText (MainActivity.this, "you have
deleted a task", Toast.LENGTH_LONG).show ();
mvItems.remove (position);
mvAdapter.notifyDataSetChanged ();

205
‫ رشا صابر نوفل‬/‫د‬ ArcGIS Runtime SDK ‫تطبيقات األندر ويد باستخدام‬ ‫الفصل السادس عشر‬
return true;
}
});
}

private void setupLocationDisplay() {


mLocationDisplay = mvMapView.getLocationDisplay ();

mLocationDisplay.addDataSourceStatusChangedListener
(dataSourceStatusChangedEvent -> {
if (dataSourceStatusChangedEvent.isStarted () ||
dataSourceStatusChangedEvent.getError () == null) {
return;
}
int requestPermissionCode = 2;
String[] requestPermissions = new
String[]{Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION};

if (!(ContextCompat.checkSelfPermission
(MainActivity.this, requestPermissions[0]) ==
PackageManager.PERMISSION_GRANTED
&& ContextCompat.checkSelfPermission
(MainActivity.this, requestPermissions[1]) ==
PackageManager.PERMISSION_GRANTED)) {
ActivityCompat.requestPermissions
(MainActivity.this, requestPermissions, requestPermissionCode);
} else {
String message = String.format ("Error in
DataSourceStatusChangedListener:%s",
dataSourceStatusChangedEvent.getSource
().getLocationDataSource ().getError ().getMessage ());
Toast.makeText (MainActivity.this, message,
Toast.LENGTH_LONG).show ();
}
});
mLocationDisplay.setAutoPanMode
(LocationDisplay.AutoPanMode.COMPASS_NAVIGATION);
mLocationDisplay.startAsync ();
}

public void onRequestPermissionResult(int requestCode ,


@NonNull String [] Permissions , @NonNull int [] grantResults){
if (grantResults.length > 0 && grantResults[0]==
PackageManager.PERMISSION_GRANTED){
mLocationDisplay.startAsync ();
}else {

206
‫ رشا صابر نوفل‬/‫د‬ ArcGIS Runtime SDK ‫تطبيقات األندر ويد باستخدام‬ ‫الفصل السادس عشر‬
Toast.makeText (MainActivity.this,getResources
().getString
(R.string.location_permission_denied),Toast.LENGTH_LONG).show
();
}
}
@Override
protected void onPause(){
mvMapView.pause ();
super.onPause ();
}
@Override
protected void onResume(){
super.onResume ();
mvMapView.resume ();
}

:Mainfests

<?xml version="1.0" encoding="utf-8"?>


<manifest
xmlns:android="http://schemas.android.com/apk/res/andro
id"
package="com.example.map5_task">
<uses-permission
android:name="android.permission.INTERNET" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE
" />
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION"
/>
<uses-feature android:glEsVersion="0x00020000"
android:required="true" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"

207
‫ رشا صابر نوفل‬/‫د‬ ArcGIS Runtime SDK ‫تطبيقات األندر ويد باستخدام‬ ‫الفصل السادس عشر‬

android:theme="@style/Theme.Map5_task">
<activity android:name=".MainActivity">
<intent-filter>
<action
android:name="android.intent.action.MAIN" />

<category
android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>

</manifest>

:Strings
<resources>
<string name="app_name">map5_task</string>
<string name="location_permission_denied"> User denied
permission for device location</string>
</resources>

‫ ؛ وال داعى للصقها النها تكرار للدروس‬Build gradle ‫مع األخذ في االعتبار األعدادت على مجلدات‬
. ‫السابقة‬

208
‫د‪ /‬رشا صابر نوفل‬ ‫انشاء تطبيق للحصول على بيانات الطقس‬ ‫الفصل السابع عشر‬

‫الفصل السابع عشر‪ :‬انشاء تطبيق للحصول على بيانات الطقس‬

‫فى هذا الفصل يتم انشاء تطبيق يستخدم للحصول على بيانات الطقس ليتم تطبيق معظم األساسيات التي‬
‫تعلمناها فى األجزاء السابقة من الكتاب ويستخدم موقع ‪ openweathermap‬للحصول على البيانات ؛ وفيما‬
‫يلى شرح كيفية انشاء هذا التطبيق ؛‬

‫‪ -‬الحصول على ‪ API‬لخريطة الطقس من الموقع ‪https://openweathermap.org/api‬‬

‫يتم عمل حساب على الموقع ومن ثم تسجيل الدخول الى الموقع ؛ والدخول الى ‪ API‬نجد المفتاح الخاص‬
‫بنا‪P‬‬

‫‪1‬‬

‫‪ -‬فتح مشروع جديد في االندرويد استوديو‪:‬‬

‫‪209‬‬
‫ رشا صابر نوفل‬/‫د‬ ‫انشاء تطبيق للحصول على بيانات الطقس‬ ‫الفصل السابع عشر‬

weathear4 ‫؛ واسمها‬drawble‫يتم نسخ خلفية للتطبيق ولصقها في مجلد الـ‬

‫ ؛ واجراء االعدادات التالية‬Linear Layout ‫ الى‬Layout‫يتم تعديل الـ‬


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:background="@drawable/weathear4"
android:orientation="vertical"
android:padding="16dp">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Weather Applcation"
android:textColor="@color/white"
android:textSize="40dp" />

<LinearLayout
android:layout_width="match_parent"

210
‫ رشا صابر نوفل‬/‫د‬ ‫انشاء تطبيق للحصول على بيانات الطقس‬ ‫الفصل السابع عشر‬

android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">

<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:id="@+id/etCity"
android:ems="10"
android:hint="Enter City Name"
android:inputType="textPersonName" />

<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:ems="10"
android:id="@+id/etCountry"
android:hint="Enter Country Code (Optional)"
android:inputType="textPersonName" />

<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/btnGet"
android:layout_marginBottom="10dp"
android:background="#0070c7"
android:onClick="getWeatherDetails"
android:text="Get"
android:textColor="@color/white"
app:backgroundTint="@null" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="150dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/tvResult"/>
</ScrollView>
</LinearLayout>

</LinearLayout>

‫هناك خطأ يتم تصحيحه على النحو الموضح‬

211
‫د‪ /‬رشا صابر نوفل‬ ‫انشاء تطبيق للحصول على بيانات الطقس‬ ‫الفصل السابع عشر‬

‫الكود‪:‬‬

‫‪212‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫انشاء تطبيق للحصول على بيانات الطقس‬ ‫الفصل السابع عشر‬

‫‪213‬‬
‫ رشا صابر نوفل‬/‫د‬ ‫انشاء تطبيق للحصول على بيانات الطقس‬ ‫الفصل السابع عشر‬

‫ليكون التصميم على النحو التالى؛‬

‫؛‬build gradle ‫وفى مجلد‬


implementation 'com.android.volley:volley:1.1.1'

‫ ؛‬MainJava ‫وفى مجلد‬


EditText etCity,etCountry;
TextView tvResult;
private final String url =
"http://api.openweathermap.org/data/2.5/weather";
private final String appied =
‫ الخاص بخريطة‬API ‫"مفتاح‬465f85e34fcbe74363cbf48e82185ee7"; //

214
‫ رشا صابر نوفل‬/‫د‬ ‫انشاء تطبيق للحصول على بيانات الطقس‬ ‫الفصل السابع عشر‬

‫الطقس‬
DecimalFormat df = new DecimalFormat ("#.##");
‫ثم‬
etCity = findViewById (R.id.etCity);
etCountry = findViewById (R.id.etCountry);
tvResult = findViewById (R.id.tvResult);

‫واستكمال الشروط التالية؛‬


String temPUR1 = "";
String City = etCity.getText ().toString ().trim ();
String Country = etCountry.getText ().toString ().trim ();
if (City.equals ("")){
tvResult.setText ("City field can not be empty!");
}else {
if (! Country.equals ("")){
temPUR1 = url + "?q" + City + "," + Country + "& appid="
+ appied;
}else {
temPUR1 = url + "?q" + City + "& appid=" + appied;

215
‫ رشا صابر نوفل‬/‫د‬ ‫انشاء تطبيق للحصول على بيانات الطقس‬ ‫الفصل السابع عشر‬

‫ثم كتابة‬
StringRequest stringRequest = new StringRequest
(Request.Method.POST, temPUR1, new Response.Listener<String> ()
{
@Override
public void onResponse(String response) {
Log.d ("response", response);
}
},new Response.ErrorListener (){
@Override
public void onErrorResponse(VolleyError error) {

‫فيظهر خطأ يتم تصحيحه على النحو الموضح ادناه؛‬

216
‫د‪ /‬رشا صابر نوفل‬ ‫انشاء تطبيق للحصول على بيانات الطقس‬ ‫الفصل السابع عشر‬

‫وأخي ار إضافة رسالة‬


‫‪Toast.makeText (getApplicationContext (),error.toString ().trim‬‬
‫;)( ‪(),Toast.LENGTH_LONG).show‬‬

‫‪217‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫انشاء تطبيق للحصول على بيانات الطقس‬ ‫الفصل السابع عشر‬

‫ثم نقوم بعمل ملف تأمين الشبكة نأتى على مجلد ‪res‬‬

‫ثم‬

‫وانشاء ملف ‪ xml‬؛ ووضع فيه أمان الشبكة‬

‫‪218‬‬
‫د‪ /‬رشا صابر نوفل‬ ‫انشاء تطبيق للحصول على بيانات الطقس‬ ‫الفصل السابع عشر‬

‫‪219‬‬
‫ رشا صابر نوفل‬/‫د‬ ‫انشاء تطبيق للحصول على بيانات الطقس‬ ‫الفصل السابع عشر‬

‫مسح ما يوجد بالمجلد وكتابة‬


<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config cleartextTrafficPermitted="true"/>
</network-security-config>

Mainfest ‫وفى مجلد‬

220
‫د‪ /‬رشا صابر نوفل‬ ‫انشاء تطبيق للحصول على بيانات الطقس‬ ‫الفصل السابع عشر‬

‫وضع إمكانية الوصول الى االنترنت ؛ ووضع ملف أمان الشبكة‬

‫نعود الى ملف الجافا‬


‫‪RequestQueue requestQueue = Volley.newRequestQueue‬‬
‫;))( ‪(getApplicationContext‬‬
‫;)‪requestQueue.add (stringRequest‬‬

‫ثم كتابة‬

‫‪221‬‬
‫ رشا صابر نوفل‬/‫د‬ ‫انشاء تطبيق للحصول على بيانات الطقس‬ ‫الفصل السابع عشر‬

String OutPut= "";


try {
JSONObject jsonResponse = new JSONObject
(response);
‫ولتصحيح الخطأ؛‬

: ‫ثم استكمال األكواد كما يلى‬


String OutPut= "";
try {
JSONObject jsonResponse = new JSONObject (response);
JSONArray jsonArray = jsonResponse.getJSONArray ("weather");
JSONObject jsonObjectWeather = jsonArray.getJSONObject (0);
String description = jsonObjectWeather.getString
("description");
JSONObject jsonObjectMain = jsonResponse.getJSONObject
("main");
double temp = jsonObjectMain.getDouble ("temp") - 237.15;
double feelslike = jsonObjectMain.getDouble ("feels_like") -
237.15;
float pressure = jsonObjectMain.getInt ("pressure");
int humidity = jsonObjectMain.getInt ("humidity");
JSONObject jsonObjectWind = jsonResponse.getJSONObject
("wind");
String wind = jsonObjectWind.getString ("speed");
JSONObject jsonObjectClouds = jsonResponse.getJSONObject
("clouds");
String clouds = jsonObjectClouds.getString ("all");
JSONObject jsonObjectSys = jsonResponse.getJSONObject
("sys");
String countryName = jsonObjectSys.getString ("country");
String cityName = jsonResponse.getString ("name");
tvResult.setTextColor (Color.rgb (68,134,199));
OutPut += "Current weather of " + cityName + "(" +

222
‫ رشا صابر نوفل‬/‫د‬ ‫انشاء تطبيق للحصول على بيانات الطقس‬ ‫الفصل السابع عشر‬

countryName + ")"
+ "\n Temp : " + df.format (temp) + " °C "
+ "\n Fells Like : " + df.format (feelslike) + "°C
"
+"\n Humidity : "+ humidity + "%"
+"\n Description : " + description
+ "\n Wind Speed : " + wind + "m/s (meters per
second)"
+ "\n Cloudiness : " + clouds + "%"
+ "\n pressure : " + pressure + "hpa";
tvResult.setText (OutPut);

223
‫ رشا صابر نوفل‬/‫د‬ ‫انشاء تطبيق للحصول على بيانات الطقس‬ ‫الفصل السابع عشر‬

:Main Java ‫لتصبح مجلد‬


package com.example.weatherapp;

import androidx.appcompat.app.AppCompatActivity;

import android.graphics.Color;
import android.os.Bundle;
import android.provider.CalendarContract;
import android.util.Log;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.text.DecimalFormat;

public class MainActivity extends AppCompatActivity {


EditText etCity,etCountry;
TextView tvResult;
private final String url =
"http://api.openweathermap.org/data/2.5/weather";
private final String appied =
"465f85e34fcbe74363cbf48e82185ee7"; // ‫ مفتاح‬API ‫بخريطة الخاص‬
‫الطقس‬
DecimalFormat df = new DecimalFormat ("#.##");

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate (savedInstanceState);
setContentView (R.layout.activity_main);
etCity = findViewById (R.id.etCity);
etCountry = findViewById (R.id.etCountry);
tvResult = findViewById (R.id.tvResult);
}

public void getWeatherDetails(View view) {

224
‫ رشا صابر نوفل‬/‫د‬ ‫انشاء تطبيق للحصول على بيانات الطقس‬ ‫الفصل السابع عشر‬

String temPUR1 = "";


String City = etCity.getText ().toString ().trim ();
String Country = etCountry.getText ().toString ().trim
();
if (City.equals ("")){
tvResult.setText ("City field can not be empty!");
}else {
if (! Country.equals ("")){
temPUR1 = url + "?q" + City + "," + Country + "&
appid=" + appied;
}else {
temPUR1 = url + "?q" + City + "& appid=" +
appied;

}
StringRequest stringRequest = new StringRequest
(Request.Method.POST, temPUR1, new Response.Listener<String> ()
{
@Override
public void onResponse(String response) {
//Log.d ("response", response);
String OutPut= "";
try {
JSONObject jsonResponse = new JSONObject
(response);
JSONArray jsonArray =
jsonResponse.getJSONArray ("weather");
JSONObject jsonObjectWeather =
jsonArray.getJSONObject (0);
String description =
jsonObjectWeather.getString ("description");
JSONObject jsonObjectMain =
jsonResponse.getJSONObject ("main");
double temp = jsonObjectMain.getDouble
("temp") - 237.15;
double feelslike =
jsonObjectMain.getDouble ("feels_like") - 237.15;
float pressure = jsonObjectMain.getInt
("pressure");
int humidity = jsonObjectMain.getInt
("humidity");
JSONObject jsonObjectWind =
jsonResponse.getJSONObject ("wind");
String wind = jsonObjectWind.getString
("speed");
JSONObject jsonObjectClouds =
jsonResponse.getJSONObject ("clouds");

225
‫ رشا صابر نوفل‬/‫د‬ ‫انشاء تطبيق للحصول على بيانات الطقس‬ ‫الفصل السابع عشر‬

String clouds =
jsonObjectClouds.getString ("all");
JSONObject jsonObjectSys =
jsonResponse.getJSONObject ("sys");
String countryName =
jsonObjectSys.getString ("country");
String cityName = jsonResponse.getString
("name");
tvResult.setTextColor (Color.rgb
(68,134,199));
OutPut += "Current weather of " +
cityName + "(" + countryName + ")"
+ "\n Temp : " + df.format
(temp) + " °C "
+ "\n Fells Like : " + df.format
(feelslike) + "°C "
+"\n Humidity : "+ humidity +
"%"
+"\n Description : " +
description
+ "\n Wind Speed : " + wind +
"m/s (meters per second)"
+ "\n Cloudiness : " + clouds +
"%"
+ "\n pressure : " + pressure +
"hpa";
tvResult.setText (OutPut);

} catch (JSONException e) {
e.printStackTrace ();
}
}
},new Response.ErrorListener (){
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText (getApplicationContext
(),error.toString ().trim (),Toast.LENGTH_LONG).show ();

}
});
RequestQueue requestQueue = Volley.newRequestQueue
(getApplicationContext ());
requestQueue.add (stringRequest);
}
}
}

226
‫د‪ /‬رشا صابر نوفل‬ ‫انشاء تطبيق للحصول على بيانات الطقس‬ ‫الفصل السابع عشر‬

‫‪227‬‬
‫ رشا صابر نوفل‬/‫د‬ ‫انشاء تطبيق للحصول على بيانات الطقس‬ ‫الفصل السابع عشر‬

Activitymain ‫مجلد‬
android:padding="16dp">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="Weather Applcation"
android:textColor="@color/purple_700"
android:textSize="35dp" />

<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">

<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginBottom="10dp"
android:id="@+id/etCity"
android:ems="10"
android:hint="Enter City Name"
android:inputType="textPersonName" />

<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content"

228
‫ رشا صابر نوفل‬/‫د‬ ‫انشاء تطبيق للحصول على بيانات الطقس‬ ‫الفصل السابع عشر‬

android:layout_marginBottom="10dp"
android:ems="10"
android:id="@+id/etCountry"
android:hint="Enter Country Code (Optional)"
android:inputType="textPersonName" />

<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/btnGet"
android:layout_marginBottom="10dp"
android:background="#0070c7"
android:onClick="getWeatherDetails"
android:text="Get"
android:textColor="@color/white"
app:backgroundTint="@null" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="150dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/tvResult"/>
</ScrollView>
</LinearLayout>

</LinearLayout>

229
‫د‪ /‬رشا صابر نوفل‬ ‫قائمة املراجع واملصادر‬ ‫بناء تطبيقات االندرويد يف نظم املعلومات اجلغرافية‬

‫قائمة املراجع واملصادر‪:‬‬

‫أوالً‪ - :‬المراجع باللغة العربية‪-:‬‬

‫‪ .1‬إبراهيم؛ محمد محمود ؛ أساسيات البرمجة بلغة الجافا الجزء األول ‪.2019‬‬
‫‪ .2‬أحمد ؛ عادل مبارك ؛ تطوير تطبيقات أندرويد ‪.2013‬‬
‫‪ .3‬األغا ؛ إياد محمد قاسم ؛ أساسيات برمجة تطبيقات األندرويد ؛ ‪. 2018‬‬
‫‪ .4‬الضبى ؛ سعد ؛ تعلم الجافا ببساطة ؛ مكتبة نور؛ ‪.2017‬‬
‫‪ .5‬رحمة إمام ؛ االندرويد ستوديو بالعربي خطوة بخطوة ؛‪. 2019‬‬
‫‪ .6‬عبد المجيد ؛ محمد الجيالني ؛ سلسلة تعليم تصميم وتطوير تطبيقات أندرويد ؛‪.2012‬‬
‫‪ .7‬عزب؛ محمد عزب ؛ برمجة أندرويد ( المهام المتقدمة)؛ ‪.2013‬‬
‫‪ .8‬غازى ؛ عميد صالح ؛ البرمجة باستخدام لغة الجافا ؛ ‪.2015‬‬
‫‪ .9‬مساعد ؛ أحمد عباس محمد ؛ برمجة واجهات المستخدم فى لغة الجافا ‪.2011‬‬
‫وائل علواني ‪ -‬محمد بدوي ؛ تعلم تطوير التطبيقات على أجهزة أندرويد ببساطة ؛‪.2018‬‬ ‫‪.10‬‬

‫ثانياً‪ -:‬المراجع باللغة األجنبية ‪-:‬‬

‫‪1- Andy Gup , Building Applications with the ArcGIS Runtime SDK for Android , Esri ,2013.‬‬
‫‪2- Antonio Remírez Remírez , Introducción a ArcGIS Runtime for Android , 2015.‬‬
‫‪3- Jay Chen, Justin Colville, Developing Mapping Applications with ArcGIS Runtime SDK for‬‬
‫‪Windows Mobile,Esri , 2013.‬‬
‫‪4- Rama Chintapalli, ArcGIS Runtime SDK for Android Building App , Esri, 2020.‬‬

‫‪230‬‬
‫ رشا صابر نوفل‬/‫د‬ ‫قائمة املراجع واملصادر‬ ‫بناء تطبيقات االندرويد يف نظم املعلومات اجلغرافية‬

: ‫ مصادر من األنترنت‬-:ً‫ثالثا‬
:‫المواقع‬

1- https://harmash.com/java.
2- https://www.codecademy.com/learn/learn-java.
3- https://www.javacodegeeks.com/.

:‫قنوات من اليوتيوب‬
4-
5- https://www.youtube.com/channel/UCgntwWFdMDPq0eNhaQ0LHIQ
6- https://www.youtube.com/channel/UCBNZ0VoN2u_4NT8kbmGgUzQ
7- https://www.youtube.com/channel/UCgCXcfk5uEraWkpE9wlRwgw
8- https://www.youtube.com/channel/UCgCXcfk5uEraWkpE9wlRwgw

231
‫ رشا صابر نوفل‬/‫د‬ ‫بناء تطبيقات االندرويد يف نظم املعلومات اجلغرافية‬

Building Android Applications


In
Geographic Information Systems
)part 1(

Dr/ Rasha Saber Nofal

1
2020/2022

You might also like