دروس تطوير تطبيقات الأندرويد 3


درس تطوير تطبيقات الأندرويد 3

  
- طريقة عرض النص.
 قمنا بتغيير النص الذي أردنا إظهاره عن طريق ملف ال main.xml، كما في الصورة
ما نود الآن عمله هو إيضاح إمكانية عدم استعمال الدالة
setContentView(R.layout.main);
والتي تقوم بعرض الواجهة التي حُددت معالمها ومحتوياتها باستخدام ملف main.xml. الهدف من عرض هذه النقطة هو التركيز على أهمية ملفات ال XML التي تسهل الأداء بشكل أكبر وأكثر فعالية.
ببساطة (باستخدام ملفات الدرس السابق) قم بمسح:
TextView

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="@string/hello"
من main.xml ليصبح محتوى الملف بعدها:


الآن في ملف HelloWorldArdroid.java قم باستدعاء المكتبة التالية:
import android.widget.TextView;
عبر هذه المكتبة، سنقوم باستعمال عنصر الواجهة النصية TextView بتعريف كائن Object داخل دالة onCreate على النحو التالي:
TextView HelloWorldText = new TextView(this);
لا يخفى على مبرمج الجافا الغرض من تمرير this عند استدعاء الدوال البرمجية في الجافا Functions/Methods. وفي هذه الحالة، this تستخدم للدلالة على أن الكائن المنشأ ينتمي للسياق البرمجي الحالي المتمثل بمجموعة السياق  Context Class والتي هي أحد أسلاف Ancestors المجموعة التي نعمل عليها حاليا (بتتبع التسلسل الهرمي نجد أن: HelloWorldArdroid extends Activity extends ApplicationContext extends Context).
الآن نقوم باستعمال الدالة setText لتعيين النص الذي نريد الكائن HelloWorldText أن يحمله:
HelloWorldText.setText("Hello World");
والآن نطلب من setContentView أن تعرض الكائن على النحو التالي:
setContentView(HelloWorldText);
المحتوى النهائي للملف:
package android_programming_series.HelloWorldArdroid;

import android.app.Activity;

import android.os.Bundle;

import android.widget.TextView;

public class HelloWorldArdroid extends Activity {

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

TextView HelloWorldText = new TextView(this);

HelloWorldText.setText("Hello World");

setContentView(HelloWorldText);

}

}
مشكلة هذه الطريقة تكمن في أنها تعرض عنصرا واحدا فقط (أو واجهة واحدة كالواجهة النصية أعلاه). لذلك سنقوم من الآن وصاعدا باستخدام ملف XML لإضافة العناصر والواجهات بمختلف أنواعها.
- شرح طريقة إظهار صورة في التطبيق.
يمكنكم استكمال العمل على المشروع الحالي أو انشاء مشروع جديد تحت أي مسمى، مثلا HelloWorldImage. علينا إنشاء صورة لنقوم بعرضها. اخترت الصورة التالية
وقمت بحفظها تحت مجلد drawable_hdpi.
نقوم بفتح ملف الmain.xml ونضيف بداية العنصر الخاص بالواجهة الرسومية (صورة) وهو <ImageView. ثم نقوم بعدها بإضافة الخصائص التالية:
android:id="@+id/imageviewar"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:src="@drawable/imageviewar"
تقوم الخاصية الأولى بتوليد رقم خاصID بالعنصر المسمى imageviewar حيث يتم التعامل مع الواجهات Viewsعبر أرقامها الخاصة تتحكم الخاصيتان اللاحقتان بطول وعرض الصورة. أما الخاصية الأخيرة فعن طريقها يتم تحديد مصدر الصورة (وهو تحت مجلد drawable بغض النظر عن تفرعات المجلد).
ملف ال XML:

الملف المصدري هو كالتالي:
package android_programmers_guide.HelloWorldImage;

import android.app.Activity;

import android.os.Bundle;

public class HelloWorldImage extends Activity {

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

}

}
التطبيق في الجهاز الافتراضي:

قبل تعريف ال Intents، علينا التفريق بين مفهومين: التطبيق Application و النشاط Activity. التطبيق هو عبارة عن نشاط واحد أو أكثر. في تطبيق الرسائل النصية مثلا، كل اختيار يمثل نشاطا. بمعنى، خيار كتابة الرسائل هو نشاط، وخيار عرض الرسائل هو نشاط مختلف وهكذا.
النوايا Intents بكل بساطة هي وسيلة لتمرير المعلومات من نشاط لآخر وبكلمات أخرى، تمرير ما ينوي فعله المبرمج بين الأنشطة. ولكنها تستخدم فقط في حالة وددنا استخدام نشاط خارج التطبيق الذي نعمل عليه. مثلا، اذا أراد المبرمج من تطبيقه أن يأخذ كلمة معينة من المستخدم ليبحث عنها بين ملفات النظام فإنه سيقوم بتصميم نشاط تحتوي واجهته على حقل نصي يمكن للمستخدم الكتابة فيها، وما يتم ادخاله يتم تمريره الى نظام الأندرويد تحت نية عمل بحث في ملفات النظام (وال Intent اسمه في هذه الحالة: SEARCH_ACTION) الذي يستقبل الطلب ويفهم النية\المعلومة المرغوب تحقيقها ويستدعي بدوره نشاط البحث Search Activity. نلاحظ أن النية تم تمريرها الى نشاط خارج التطبيق، وهو نشاط يقوم عليه نظام التشغيل. بالنسبة للأنشطة التي ذكرتها في معرض حديثي عن تطبيق الرسائل النصية، فهي أنشطة داخل التطبيق الواحد ولا يتم استخدام مفهوم النوايا Intents عليها
هناك نوعان من النوايا، نوايا النشاط Activity Intents و النوايا واسعة الانتشار Broadcast Intents. النوع الأول هو ما قمنا بشرحه. بينما النوع الثاني فهو نوع عكسي نوعا ما. النوع الثاني عبارة عن رسائل يرسلها نظام التشغيل للأنشطة العاملة التي يمكنها التفاعل مع هذه الرسائل بحسب وظيفتها. مثلا نجد أن النية المسماة CAMERA_BUTTON_ACTION يتم اطلاقه عند تشغيل الكاميرا. اضغط هنا للاطلاع على ال Intents المتاحة لكل نوع: Activity Action Intents ، Broadcast Intents.
ستتضح الصورة بشكل أكبر في نهاية هذا الدرس.
ما سنقوم به هو التالي: سنقوم بكتابة تطبيق يحتوي على حقل نصي\رقمي يتيح للمستخدم ادخال رقم ويوجد في أسفل الحقل زر بمجرد الضغط عليه، يتم الاتصال بالرقم المدخل.
سنبدأ بملف ال main.xml: (أفترض الآن أنكم تفهمون محتواه دون الحاجة الى شرح)

تم شرح الغرض من عنصر TextView من قبل. بالنسبة لعنصر EditText فهو يعني الحقل النصي القابل للتغيير (الحقل الذي سيتم ادخال الرقم فيه). عنصر الزر Button وهو الزر الذي بضغطه سيتم الاتصال.
بالنسبة لملف ArdroidCaller.java نقوم بداية باستدعاء المكتبات التالية:
import android.app.Activity;

import android.os.Bundle;

import android.content.Intent;

import android.net.Uri;

import android.widget.Button;

import android.widget.EditText;

import android.view.View;
تتضح نسبيا مهمة كل مكتبة بمجرد قراءة اسمها باستثناء الرابعة والأخيرة اللتان سنرى الغرض من استدعائهما قريبا.
public class ArdroidCaller extends Activity {

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

final EditText phoneNumber = (EditText) this.findViewById(R.id.phoneNumber);

final Button callButton = (Button) this.findViewById(R.id.callButton);

نلاحظ في السطرين الأخيرين كيفية استدعاء المؤشر الذي يشير الى الرقم ID الخاص بالعنصر. لاحظوا أننا قمنا بعمل Downcast في كلا السطرين لأن مخرج الدالة findViewById هو من نوع View.
أعتقد أن العديدين ممن برمجوا بلغة الجافا كانوا قد مروا على برمجة واجهات المستخدم User Interface وتحديدا برمجة الأزرار Buttons واستخدموا أحد مفاهيم برمجة الجافا وهو مبدأ المجموعات المجهولة Anonymous Classes الذي يستخدم عادة في كتابة setOnClickListener المسؤول عن متابعة الزر وتنفيذ عدد من الأوامر عند ضغط الزر من قبل المستخدم.
callButton.setOnClickListener(new Button.OnClickListener() {

public void onClick(View v)

{
المفترض أن نقوم باستدعاء ال Intent المسؤول عن الاتصال ويسمى ACTION_CALL وأن نقوم بدمجه مع الرقم المدخل وارساله الى نظام التشغيل. وهذا ما يحصل باستخدام:
Intent callIntent = new Intent(Intent.ACTION_CALL,Uri.parse("tel:" + phoneNumber.getText()));
ثم نطلب من نظام التشغيل إطلاق النشاط الخاص بعمل المكالمة:
callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
لاحظ أن FLAG_ACTIVITY_NEW_TASK تعني اطلاق النشاط كمهمة جديدة، وهناك في الواقع عدة أوامر توضح الكيفية التي يريد المبرمج عبرها اطلاق النشاط، فمثلا يوجد: FLAG_MULTIPLE_TASK_LAUNCH التي تقوم بإطلاق النشاط حتى لو أنه يعمل في الأصل (نسخة ثانية من النشاط)، وغيرها.
في النهاية سنطلب من النظام تشغيل ال Intent عبر:
startActivity(callIntent);
اذا، يصبح الملف في النهاية كما يلي:
package android_programming_series.ArdroidCaller;

import android.app.Activity;

import android.os.Bundle;

import android.content.Intent;

import android.net.Uri;

import android.widget.Button;

import android.widget.EditText;

public class ArdroidCaller  extends Activity {

/** Called when the activity is first created. */

@Override

public void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.main);

final EditText phoneNumber = (EditText) this.findViewById(R.id.phoneNumber);

final Button callButton = (Button) this.findViewById(R.id.callButton);

callButton.setOnClickListener(new Button.OnClickListener() {

public void onClick(View v)

{

Intent callIntent = new Intent(Intent.ACTION_CALL,Uri.parse("tel:" + phoneNumber.getText()));

callIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

startActivity(callIntent);
قبل تشغيل البرنامج، بقي لدينا مسألة صغيرة. هل لاحظت عند تنصيبك للتطبيقات على جهازك أنك تُسأل عما اذا كنت تصرح للتطبيق باستخدام الانترنت مثلا أو الاطلاع على رسائلك وغيرها؟ هذه هي الأذونات Permissions المرتبطة بالتطبيقات التي يجب أن توافق عيها ليعمل البرنامج بشكل صحيح.
ما قمنا به في تطبيقنا لا يختلف حالا عن باقي التطبيقات، فاستخدام خاصية الاتصال تحتاج اذن المستخدم. لذلك، في ملف الاعدادات العامة ArdroidCaller Manifest.xml ، نضيف سطر ال XML التالي:
ليصبح ملف  ArdroidCaller Manifest.xml كاملا:
الآن نشغل التطبيق على الجهاز الافتراضي لنرى التالي:
 
وبالضغط على زر الاتصال Call يظهر:

شارك الموضوع

مواضيع ذات صلة