لوحة المتصدرين
المحتوى الأكثر حصولًا على سمعة جيدة
المحتوى الأعلى تقييمًا في 12/18/20 في كل الموقع
-
اريد اسم برنامج يكون بسيط لعمل اديتينج للفيديو بس يكون بيلغى background noise .. بس يكون برنامج بسيط انا لا اريد كامتازيا ستوديو1 نقطة
-
Question#1) Write a function called reverse_order to do the following; Get the user to enter .some text and print it out in reverse order1 نقطة
-
السلام عليكم انا عايز اشغل في بيئة برمجية للغة سي بمعني برنامج اشغل عليها1 نقطة
-
مرحباً أحمد، لم أفهم سؤالك جيدا إذا كنت تريد برنامج تكتب عليه برامج بلغة c أو لغة c++ بإمكانك إستخدام برنامج Code Blocks ما تحتاج إلى فهمه أن لغة سي تحتاج إلى برنامج ثاني إسمه مترجم (compiler) و مهمته هي تحويل الشيفرات من لغة سي إلى لغة آلة لتنفيذها و من أشهرها : GCC Visual ++c على العموم بإمكانك تنصيب محرر نصوص أو أكواد ثم تنصيب المترجم لوحده لكن برنامج code Blocks يوفر الإثنين و هو عبارة عن بيئة عمل متكاملة مفتوحة المصدر، ويتم إستخدام المترجم GCC من خلال المشروع MinGW لترجمة أكواد السي، ويعتبر خيار جيد للبرمجة بلغة الس ويمكنك تحميل الحزمة البرمجية الخاصة بـ Code Blocks من خلال الموقع الخاص به ثم تختار نظام التشغيل الذي تستخدمه حاليا، وتختار الإصدار الذي ينتهي بـ mingw-setup، وهو الإصدار الذي يحتوي على المترجم GCC. بالتوفيق.1 نقطة
-
مرحبا، يوجد IDE مخصص للغة ++C وأنا استخدمه ويحوي على مترجم اللغة و يعمل بكفائة اسمه CodeBlocks يمكنك تحميله من هنا قم بتحميل النسخة: codeblocks-20.03mingw-setup.exe لأنها تحوي جميع الملحقات مع المترجم GCC/G++/GFortran compiler and GDB debugger from MinGW-W64 project ، بعد التثبيت إدخل إلى إعدادت البيئة واختر المترجم المناسب يوجد أيضا Visual Studio لكنه ثقيل على الجهاز لا أنصحك به حاليا ربما تقوم بتحميله لمشاريع محددة في المستقبل.1 نقطة
-
مرحباً بك أحمد, برمجة تطبيقات الهاتف تستهلك الكثير من الرام لذا فيجب التركيز على سعة الرام فكلما كانت سعة الرام أكبر كان إستخدام Android Studio أفضل فلا يقلك الرام عن 8GB ,أما بالنسبة للمعالج فالمعالجات الجديدة جيدة سواء كان من شركة intel أو AMD مع أن المقارنة بينهم من ناحية الأداء يكون لصالح معالجات AMD فمثلا معالج Intel Core i5-10210U يكافئ معالج AMD Ryzen 5 3500U وفي بعض الأمور أفضل منه ولكن بسعر أرخص ولكرت الشاشة الخارجي لا يقلك عن 2GB سواء كان AMD أو Nvidia مع التفضيل ل Nvidia لأنها في كروت الشاشة أفضل من AMD ,وأيضاً لا ننسى الذاكرة فيجب عليك الحصول على ذاكرة SSD على الأقل تكون 128GB من أجل تنزيل الويندوز عليها وبعض البرامج الأساسية فهذا سيزيد من سرعة الجهاز ويرفع الأداء ولو كانت m.2 سيكون أفضل. بالنسبة للشركة المصنعة فأظن أن كل من شركة HP, Dell and Lenovo لديهم لابتوبات بواصفات جيدة مع جودة جيدة. لكنك ذكرت حاسوب وليس لابتوب لذا سأفرض أنه جهاز حاسوب ومع ذلك سيكون نفس المواصفات التي ذكرتها. في حال كنت تستطيع أضافة المزيد من مساحة الرام فلتفعل.1 نقطة
-
1- أكتبي برنامج لطباعة الشكل التالي _*_*_ _*_*_ _*_*_ 2-اكتبي برنامج يطلب من المستخدم ادخال نص يحتوي على مسافة و يقوم باستبدال الجزء الأيمن بالأيسر و العكس . Enter a string: hello word The result is: word hello1 نقطة
-
مرحبًا @شمس رائد, لمشكلة الاولى , سوف نحتفظ بشكل المطلوب طباعته داخل مصفوفة و من ثم عمل حلقة تكرار for loop مع (range(3 حتى تقوم بعمل ثلاث مرات , داخل هذه الحلقة هنالك حلقة تكرار آخرى تقوم بطابعة الشكلة المطلوب , الشيفرة : chars = ["_", "*", "_", "*", "_"] #الشكلة المطلوب for i in range(3): # حلقة تعمل 3 مرات for char in chars: # حلقة طباعة الشكل print(char,end='') print("\n") المشكلة الثانية , سوف نقوم بحفظ نص المستخدم في متغير user_input و إعادة تعين المتغير ولكن نقوم بتحويل الرقم الى مصفوفة , كل كلمة في النص ستكون عنصر في المصفوفة حتى يسهل علينا عكس ترتيب الكلمات , الشيفرة : user_input = input("Type in 2 words: ") #نحتفظ بنص داخل هذا المتغير user_input = user_input.split(' ') #نقوم بتحويل المتغير الى مصفوفة , كل عنصر هو كلمة # split() هي دالة من بايثون تقوم بتغير النص الى مصفوفة user_input = [i for i in user_input[::-1]] # هنا نعيد المصفوفة مرة آخرى الى نص # ولكن هذه المرة بطريقة عكسية وذلك بإستخدام المعامل [1-::] # هذا المعامل يقوم بإعادة عناصر المصفوفة بعكس for i in user_input: print(i)1 نقطة
-
مرحبا، السؤال الأول: لدينا نص نريد طباعته 3 مرات، نعرف متحول نخزن فيه النص ثم نطبع النص مضروبا بعدد التكرارات (هذا مسموح بلغة بايثون ومن خصائصها) n\ يعبر عن سطر جديد (نهاية السطر) text = "_*_*_\n" print(3 * text) السؤال الثاني: نقوم بتفريق السلسة النصية text إلى مصفوفة بالاعتماد على المحرف " " (فراغ) و نقوم بعكس النتيجة باستخدام reversed و نطبع النتيجة. text الأولى تحوي سلسة نصية أما الثانية مصفوفة من كلمتين مع تغيير آخر محرف لخرج التابع print إلى فراغ حتى لايطبع سطرا جديدا إنما فراغ (لتبقى الكلمتين على نفس السطر) text = input('enter a text with space:') text = reversed(text.split(" ")) for i in text: print(i, end = ' ')1 نقطة
-
مرحبًا @محمد كمال صيام, لا يوجد هنالك دالة من البايثون لعكس النص لكن يمكن فعل ذلك بأكثر من طريقة و أسهل طريقة لعكس النص هي بإستخدام المعامل [1-::] و تسمى slice statement أي [1-::] وتعني البدء في نهاية النص والانتهاء عند الموضع 0 (index 0) ، والتحرك بالخطوة -1 ، سالب واحد ، مما يعني خطوة واحدة إلى الوراء , المثال : def reverse_order(user_str): user_str = user_str[::-1] print(user_str) reverse_order("Hello") النتيجة : olleH طريقة ثانية هي بإستخدام حلقة for loop , نقوم في كل تكرار عند الحلقة بحفظ حرف من النص في نص جديد في المقدمة حتى يتم عكس النص كاملا : def reverse_order(user_str): new_str = "" for i in user_str: new_str = i + str print(new_str)1 نقطة
-
مرحبا، هو طريقة لاختبار البرنامج، إذا كان موقع ويب أو تطبيق هاتف .. يعمل على تمثيل مخدم server افتراضي، يحوي قاعدة بيانات. تقوم انت بالاتصال على رابط URL محدد، فيرسل لك الموقع بيانات، ثم تقوم أنت بعرضها في برنامجك. اي باختصار أداة تدريبية تستخدمها في حال لم يكن لديك قاعدة بيانات، هو يمثل خدمة API اي ترسل بيانات خام. عند طلب اي رابط مع تمرير بارامترات معينة، سيعطيك الموقع بيانات متوافقة بشكل اساسي، تستقبل انت البيانات في background process و تعرضها في List view او قوائم أخرى. تعمل اتصال HTTP للرابط المراد، ثم تقوم ببناء قائمة لعرض النتائج إن شرح استخدامها يتطلب الكثير من كتابة الأكواد و تضمين مكتبات للأندرويد وجدت سلسة تعليمية قصيرة ارجو ان تكون مفيدة الرابط بالتوفيق1 نقطة
-
يتميز نظام تشغيل أندرويد بوجود شريط أعلى الشاشة يمُد المستخدم بالعديد من المعلومات الهامة من ضمنها الإشعارات التي ترسلها التطبيقات. فالإشعارات هي جزء من واجهة المستخدم لكنها تظهر خارج التطبيق لإعلام المستخدم بحدث معين، مما يُمكّن المستخدم من عرضه والتفاعل معه بينما يستخدم تطبيقًا آخر. ويحتوي الإشعار على رسالة مختصرة عن هذا الحدث. ويظهر الإشعار عند حدوثه كأيقونة تعبر عن التطبيق في شريط الحالة أعلى الشاشة، ويمكنك معرفة تفاصيله عند سحب درج الإشعارات والضغط على الإشعار. هناك عدة خطوات لصنع الإشعارات من داخل تطبيقك: صنع كائن البناء الخاص بالإشعار من الصنف Notification.Builder Notification.Builder mBuilder = new Notification.Builder(this); من خلال هذا الكائن يمكننا التحكم في الخصائص الخاصة بالإشعار مثل عنوان الإشعار، الأيقونة المستخدمة، التحكم في الأولوية، التحكم في المهام التي يستطيع القيام بها عند الضغط عليه وغيرهم من الخصائص المختلفة. تخصيص الحد الأدنى من الخصائص للإشعار بعد الحصول على كائن البناء نبدأ في التحكم في خصائص الإشعار، وهناك بعض الخصائص الأساسية اللازم توافرها في الإشعار وهي: الأيقونة الخاصة بالإشعار. عنوان الإشعار. المحتوى الخاص بالإشعار. mBuilder.setSmallIcon(R.drawable.msg_icon); mBuilder.setContentTitle("New Message"); mBuilder.setContentText("Hi, This is the message text."); ويوجد العديد من الخصائص الأخرى التي يمكنك استخدامها حسب حاجة التطبيق لها. بناء الإشعار بالخصائص السابقة يتم ذلك باستدعاء التابع ()build والحصول على كائن من Notification. Notification notif = mBuilder.build(); إظهار الإشعار في درج الإشعارات يوفر أندرويد الصنف NotificationManager لإدارة الإشعارات من حيث إصدار الإشعار، تعديل الإشعار بعد إصداره أو إلغاء الإشعار برمجيًا. لذا يجب أولًا الحصول على كائن من هذا الصنف وذلك عن طريق استدعاء الدالة ()getSystemService وتمرير الثابت NOTIFICATION_SERVICE والذي يعني طلب الخدمات الخاصة بالإشعارات من خدمات النظام. وسيتم استخدام الدالة ()getSystemService كثيرًا عند الحاجة لطلب خدمات من النظام. NotificationManager notifyMngr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); بعد ذلك نستدعي التابع ()notify باستخدام الكائن من NotificationManager ليظهر الإشعار في الحال، وتمرير رقم مميز له يُعبر عن الإشعار ليُستخدم هذا الرقم فيما بعد للتعديل على الإشعار أو إلغائه، كما يتم تمرير الإشعار الذي تم بنائه من قبل. int notificationId = 103; notifyMngr.notify(notificationId, notif); تطبيق 1 سنقوم في هذا التطبيق بتجربة الخطوات السابق شرحها لتكوين التطبيق مثل الصورة التالية: أولًا نبدأ بصنع واجهة المستخدم البسيطة في ملف activity_main.xml: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Show Notification" android:id="@+id/shw_notification"/> </LinearLayout> بعد ذلك ننتقل إلى الشيفرة الخاصة بالتطبيق في MainActivity.java باتباع الخطوات ذاتها لصنع الإشعار عند الضغط على الزر. package apps.noby.simplenotification; import android.app.Activity; import android.app.Notification; import android.app.NotificationManager; import android.os.Bundle; import android.view.View; import android.widget.Button; public class MainActivity extends Activity { private Button shwbtn; private String title; private String detailText; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); shwbtn = (Button) findViewById(R.id.shw_notification); title = "New Message"; detailText ="Hi, This is the message text."; shwbtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //Step 1 Notification.Builder mBuilder = new Notification.Builder(MainActivity.this); //Step 2 mBuilder.setSmallIcon(R.drawable.ic_message); mBuilder.setContentTitle(title); mBuilder.setContentText(detailText); //Step 3 Notification notif = mBuilder.build(); //Step 4 NotificationManager notifyMngr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); int notificationId = 103; notifyMngr.notify(notificationId,notif); } }); } } ثم نقوم بتجربة التطبيق على المحاكي للتأكد من عمله كما ينبغي. تطبيق 2 في التطبيق السابق عند الضغط على الإشعار لا يحدث شيئ، لذا في هذا التطبيق سنقوم بفتح نشاط جديد يعرض تفاصيل الإشعار أو ما نريد من معلومات عند الضغط على الإشعار. ولفتح نشاط جديد داخل التطبيق سنستخدم Intent ولكن سنقوم بتغليف الكائن من Intent داخل كائن آخر من PendingIntent وفائدة هذا التغليف هو أنه لا يمكن استخدام الكائن من Intent خارج التطبيق، والإشعار كما ذكرنا يُعرض خارج حدود التطبيق لذا يقوم PendingIntent بإعطاء الصلاحية للتطبيقات الأخرى أو النظام والذي نُرسل إليه PendingIntent القدرة على تنفيذ الأوامر كأنها تتم داخل تطبيقك. أولًا نقوم بصنع نشاط جديد يُدعى ResultActivity. ثانيًا سنقوم بتعديل الشيفرة الخاصة بـ MainActivity.java وإضافة كائن من Intent. Intent intent = new Intent(MainActivity.this,ResultActivity.class); ونستطيع إرسال بيانات إلى النشاط الآخر بنفس الطريقة المستخدمة في الدروس السابقة. intent.putExtra(DESC_KEY,detailText); ثم نقوم بتغليف الكائن داخل PendingIntent: PendingIntent pIntent = PendingIntent.getActivity(MainActivity.this , 0 , intent , PendingIntent.FLAG_UPDATE_CURRENT); والخطوة الأخيرة هي وضع هذا Intent ضمن خصائص الإشعار باستخدام كائن البناء: mBuilder.setContentIntent(pIntent); لتُصبح الشيفرة النهائية لملف MainActivity.java بعد التعديل هي: package apps.noby.simplenotification; import android.app.Activity; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button; public class MainActivity extends Activity { private Button shwbtn; private String title; private String detailText; public final static String DESC_KEY ="descriptionKey"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); shwbtn = (Button) findViewById(R.id.shw_notification); title = "New Message"; detailText ="Hi, This is the message text."; shwbtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //Step 1 Notification.Builder mBuilder = new Notification.Builder(MainActivity.this); //Step 2 mBuilder.setSmallIcon(R.drawable.ic_message); mBuilder.setContentTitle(title); mBuilder.setContentText(detailText); Intent intent = new Intent(MainActivity.this,ResultActivity.class); intent.putExtra(DESC_KEY,detailText); PendingIntent pIntent = PendingIntent.getActivity(MainActivity.this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT); mBuilder.setContentIntent(pIntent); //Step 3 Notification notif = mBuilder.build(); //Step 4 NotificationManager notifyMngr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); int notificationId = 103; notifyMngr.notify(notificationId,notif); } }); } } ولم نقم بتغيير شيء في ملف الواجهة activity_main.xml. الآن لعرض التفاصيل التي سترسل إلى النشاط الجديد ResultActivity.java نبدأ في صنع واجهة المستخدم الخاصة بالنشاط ثم بتغيير الشيفرة الخاصة به ولا يوجد اختلاف بينها وبين الطريقة المستخدمة في الدروس السابقة. <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="25sp" android:id="@+id/desc"/> </LinearLayout> package apps.noby.simplenotification; import android.content.Intent; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; import android.widget.TextView; public class ResultActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_result); TextView tv = (TextView) findViewById(R.id.desc); Intent intent = getIntent(); String description = intent.getExtras().getString(MainActivity.DESC_KEY); tv.setText(description); } } ثم نقوم بتجربة التطبيق على المحاكي. تطبيق 3 لاحظ أنه عند الضغط على الإشعار في التطبيق السابق يقوم بفتح نشاط جديد ولكن يظل الإشعار متواجدًا في درج الإشعارات رغم عرضه والتفاعل معه لذا سنقوم في هذا التطبيق بتغيير بسيط حتى يختفي الإشعار بمجرد التفاعل معه. في شيفرة التطبيق السابق بداخل الملف MainActivity.java سنقوم بتعديل السطور الخاصة بالخطوة الثانية لتُصبح. mBuilder.setContentTitle(title); mBuilder.setContentText(detailText); mBuilder.setAutoCancel(true); Intent intent = new Intent(MainActivity.this,ResultActivity.class); intent.putExtra(DESC_KEY,detailText); قمنا فقط بإضافة السطر الخاص باستدعاء التابع ()setAutoCancel وتمرير القيمة true باستخدام كائن البناء، والآن عند تجربة التطبيق بعد هذا التعديل ستجد أنه يقوم بإزالة الإشعار بمجرد الضغط عليه. تطبيق 4 يتم استخدام الشكل السابق بكثرة خاصة في تطبيقات المحادثة أو رسائل البريد حيث يتم عرض صورة المستخدم وبجانبها بحجم صغير الأيقونة الخاصة بالتطبيق. ولصنع ذلك يتم استدعاء التابع ()setLargeIcon باستخدام كائن البناء وتمرير له الصورة المراد عرضها بحجم كبير. لكن هناك شرط وهو أن تكون الصورة بصيغة Bitmap ولأننا حتى الآن نقوم في الدروس باستخدام الصور المتواجدة في مجلد drawable لذا ينبغي قبل تمريرها للتابع ()setLargeIcon أن نقوم بتحويلها إلى Bitmap ويتم ذلك عن طريق الخطوة التالية. Bitmap img = BitmapFactory.decodeResource(MainActivity.this.getResources(), R.drawable.ic_person); ثم بعد ذلك تمريرها كما سبق لبناء الإشعار. mBuilder.setLargeIcon(img); لتُصبح الشيفرة الكاملة الخاصة بالملف MainActivity.java هي: package apps.noby.simplenotification; import android.app.Activity; import android.app.Notification; import android.app.NotificationManager; import android.app.PendingIntent; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.view.View; import android.widget.Button; public class MainActivity extends Activity { private Button shwbtn; private String title; private String detailText; public final static String DESC_KEY ="descriptionKey"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); shwbtn = (Button) findViewById(R.id.shw_notification); title = "New Message"; detailText ="Hi, This is the message text."; shwbtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //Step 1 Notification.Builder mBuilder = new Notification.Builder(MainActivity.this); //Step 2 mBuilder.setSmallIcon(R.drawable.ic_message); Bitmap img = BitmapFactory.decodeResource(MainActivity.this.getResources(), R.drawable.ic_person); mBuilder.setLargeIcon(img); mBuilder.setContentTitle(title); mBuilder.setContentText(detailText); mBuilder.setAutoCancel(true); Intent intent = new Intent(MainActivity.this,ResultActivity.class); intent.putExtra(DESC_KEY,detailText); PendingIntent pIntent = PendingIntent.getActivity(MainActivity.this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT); mBuilder.setContentIntent(pIntent); //Step 3 Notification notif = mBuilder.build(); //Step 4 NotificationManager notifyMngr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); int notificationId = 103; notifyMngr.notify(notificationId,notif); } }); } } ليعمل التطبيق كما هو متوقع على المحاكي. تطبيق 5 في بعض الأحيان نحتاج إلى التفاعل السريع للمستخدم مع التطبيق دون الحاجة لفتح التطبيق أو لتوفير أكثر من اختيار لفتح أجزاء محددة في التطبيق. للقيام بذلك نستخدم التابع ()addAction والذي يمكننا من إضافة زر إلى الإشعار. PendingIntent pIntent = PendingIntent.getActivity(MainActivity.this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT); mBuilder.setContentIntent(pIntent); mBuilder.addAction(R.drawable.ic_reply,"Reply",pIntent); mBuilder.addAction(R.drawable.ic_content_copy,"Copy",pIntent); //Step 3 Notification notif = mBuilder.build(); ولاستخدام هذا التابع نقوم بتمرير صورة لتظهر داخل الزر، النص الخاص بالزر وأخيرًا كائن من PendingIntent ليتم تنفيذه عند الضغط على هذا الزر. ويمكنك عمل ()addAction حتى ثلاث مرات فقط، ويمكن لكل زر أن يكون له PendingIntent مختلف خاص به ليقوم بتنفيذ أمر مختلف وفي المثال السابق لشرح الفكرة تم استخدام PendingIntent واحد. والآن نقوم بتشغيل التطبيق على المحاكي للتأكد من عمله بشكل صحيح. تطبيق 6 في بعض الأحيان تحتاج إلى التعديل على إشعار سابق دون إصدار إشعار جديد، وذلك بإضافة بعض المعلومات له أو بتغيير محتوى الإشعار أو كلاهما. وقد تحتاج أيضًا إلى إزالة الإشعار برمجيًا دون تدخل من المستخدم وذلك عند حدوث شيء محدد أو مرور وقت محدد. أولًا للقيام بالتعديل أو بتغيير محتوى إشعار دون إصدار إشعار آخر جديد نقوم ببناء الإشعار ثم نقوم بإصداره باستخدام نفس الـ NotificationID الذي نمرره للتابع ()notify حتى يقوم بتعديل الإشعار صاحب ID ذاته. بفرض أن لدينا هذا الإشعار عند الضغط على زر Show Notification. shwbtn = (Button) findViewById(R.id.shw_notification); shwbtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //Step 1 Notification.Builder mBuilder = new Notification.Builder(MainActivity.this); //Step 2 mBuilder.setSmallIcon(R.drawable.ic_message); Bitmap img = BitmapFactory.decodeResource(MainActivity.this.getResources(), R.drawable.ic_person); mBuilder.setLargeIcon(img); mBuilder.setContentTitle("New Message"); mBuilder.setContentText("Hi, This is the message text."); mBuilder.setNumber(++totalNumber); mBuilder.setAutoCancel(true); Intent intent = new Intent(MainActivity.this,ResultActivity.class); intent.putExtra(DESC_KEY,"Hi, This is the message text."); PendingIntent pIntent = PendingIntent.getActivity(MainActivity.this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT); mBuilder.setContentIntent(pIntent); //Step 3 Notification notif = mBuilder.build(); //Step 4 NotificationManager notifyMngr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); int notificationId = 103; notifyMngr.notify(notificationId,notif); } }); ثم عند الضغط على الزر Update Notification يتم تغييرها إلى المحتوى التالي. updatebtn = (Button) findViewById(R.id.upd_notification); updatebtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //Step 1 Notification.Builder mBuilder = new Notification.Builder(MainActivity.this); //Step 2 mBuilder.setSmallIcon(R.drawable.ic_message); Bitmap img = BitmapFactory.decodeResource(MainActivity.this.getResources(), R.drawable.ic_person); mBuilder.setLargeIcon(img); mBuilder.setContentTitle("Updated Message"); mBuilder.setContentText("Hi, This is an updated Message."); mBuilder.setNumber(++totalNumber); mBuilder.setAutoCancel(true); Intent intent = new Intent(MainActivity.this,ResultActivity.class); intent.putExtra(DESC_KEY,"Hi, This is an updated Message."); PendingIntent pIntent = PendingIntent.getActivity(MainActivity.this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT); mBuilder.setContentIntent(pIntent); //Step 3 Notification notif = mBuilder.build(); //Step 4 NotificationManager notifyMngr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); int notificationId = 103; notifyMngr.notify(notificationId,notif); } }); لاحظ أننا قمنا باستخدام نفس NotificationID في خطوة إظهار الإشعار وذلك لإخبار النظام أننا نريد التعديل على إشعار متواجد بالفعل. والآن لإزالة الإشعار نضغط على الزر Cancel Notification. cnclbtn = (Button) findViewById(R.id.cncl_notification); cnclbtn.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { NotificationManager notifyMngr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); totalNumber = 0; int notificationId = 103; notifyMngr.cancel(notificationId); } }); لإزالة الإشعار نستدعي التابع ()cancel باستخدام الكائن من NotificationManager ونمرر لها الـ ID الخاص بالإشعار. لاحظ أننا قد قمنا باستخدام التابع ()setNumber عند بناء الإشعار وذلك ليُظهر عدد مرات بناء وتعديل الإشعار ذاته، ويتم بدأ العد مجددًا عند الضغط على الزر Cancel Notification. وبتغيير ملف الواجهة في activity_main.xml ليُصبح. <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:gravity="center"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Show Notification" android:id="@+id/shw_notification"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Update Notification" android:id="@+id/upd_notification"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Cancel Notification" android:id="@+id/cncl_notification"/> </LinearLayout> تستطيع أن تلاحظ الرقم المتواجد أقصى يمين الإشعار والذي يُعبر عن عدد مرات التعديل على الإشعار ذاته، ويتحكم التابع ()setNumber في القيمة التي ستظهر بناءً على قيمة المعامل الذي تم تمريره له. تطبيق 7 هناك العديد من الإشعارات التي لا يستطيع المستخدم من إزالتها ويجب عليه انتظار انتهاء حدث معين أو القيام بمهمة معينة حتى يختفي الإشعار، مثال على ذلك عند تحميلك لملف تجد إشعار لا يمكنك إزالته يُخبرك بمعلومات عن التحميل وللتخلص منه ينبغي الانتظار حتى اكتمال تحميل الملف أو إلغاء التحميل. لتفعيل هذه النوعية من الإشعارات داخل التطبيق لدينا طريقتان 1. نقوم بتغير قيمة إحدى خصائص الإشعار الذي قمنا ببنائه وتدعى flags، حيث نقوم بإضافة خاصيتين إلى الإشعار وهما: Notification.FLAG_NO_CLEAR وهي تلغي تأثير التابع ()setAutoCancel فلا يتم مسح الإشعار عند الضغط عليه. Notification.FLAG_ONGOING_EVENT وهي المسؤولة عن إخبار النظام أن هذا الإشعار لديه معلومات لا زالت لها أهمية ولا ينبغي إزالتها الآن. //Step 3 Notification notif = mBuilder.build(); notif.flags |= Notification.FLAG_NO_CLEAR | Notification.FLAG_ONGOING_EVENT; 2. استدعاء التابع ()setOngoing باستخدام كائن البناء و تمرير له القيمة true، مع إزالة سطر استدعاء التابع ()setAutoCancel حتى لا يتم إزالة الإشعار عند الضغط عليه. //Step 2 mBuilder.setSmallIcon(R.drawable.ic_message); mBuilder.setContentTitle("New Message"); mBuilder.setContentText("Hi, This is the message text."); mBuilder.setOngoing(true); ملحوظة: لا يوجد فرق بين أي من الطريقتين من حيث الوظيفة أو التأثير. ولإزالة هذا الإشعار عند الانتهاء من الحدث ينبغي استدعاء التابع ()cancel وتمرير له NotificationID كما سبق، ولا يمكن إزالته إلا بهذه الطريقة. تطبيق 8 عندما يأتي تنبيه من تطبيق ما وكانت شاشة القفل مغلقة فهناك ثلاثة اختيارات للنظام للتعامل مع هذا الإشعار. إما إظهار محتوى الإشعار على شاشة القفل، أو إظهار الإشعار مع إخفاء محتواه أو عدم إظهار الإشعار ويمكن التحكم في هذه الاختيارات برمجيًا من خلال التابع ()setVisibility باستخدام كائن البناء ويُمرر له ثابت قيمته: Notification.VISIBILITY_PUBLIC إذا أردت أن يظهر محتوى الإشعار. Notification.VISIBILITY_PRIVATE إذا أردت إظهار الإشعار فقط دون إظهار محتواه. Notification.VISIBILITY_SECRET وذلك لعدم ظهور الإشعار على شاشة القفل ويظهر حين نتجاوز قفل الشاشة أولًا. //Step 2 mBuilder.setSmallIcon(R.drawable.ic_message); mBuilder.setContentTitle("New Message"); mBuilder.setContentText("Hi, This is the message text."); mBuilder.setAutoCancel(true); mBuilder.setVisibility(Notification.VISIBILITY_PRIVATE); ملحوظة: حتى يعمل التابع ()setVisibility يجب أن يكون الحد الأدنى من نسخة النظام التي يدعمها التطبيق هي Lollipop API 21، حيث لا تدعم النسخ الأقدم هذه الميزة لذا تأكد من تغييرها عند عمل مشروع جديد. تطبيق 9 يدعم أندرويد عدة أنواع من الإشعارات بجانب النوع الأساسي الذي استخدمناه في الأمثلة السابقة. Big Text Style حيث تستطيع أن تجمع بين الأمرين، إشعار بسيط يعرض نصًا مختصرًا ويمكن للمستخدم أن يقوم بتكبيره لعرض المزيد من التفاصيل. ويكثر استخدام هذه الطريقة عند عرض إشعار برسالة بريد إلكتروني جديدة فيمكن لك تكبيرها وقراءة تفاصيل الرسالة دون فتح التطبيق. ويمكنك تطبيق ذلك في تطبيقك عن طريق. عمل إشعار وتحديد خصائصه كما سبق وذلك لتُعرض هذه المعلومات عندما يكون الإشعار صغير الحجم. عمل كائن من Notification.BigTextStyle وتحديد عنوان جديد وعرض تفاصيل أكثر ثم إضافته لخصائص الإشعار. بناء الإشعار. ولتوضيح هذه الخطوات بالشيفرة نقوم بالتالي: private void showBigTextNotification() { //Step 1 mBuilder = new Notification.Builder(this); mBuilder.setSmallIcon(R.drawable.ic_txt); mBuilder.setContentTitle(“Big Text in Normal Mode”); mBuilder.setContentText(“Example of a Big Text Notification.”); //Step 2 Notification.BigTextStyle bigText = new Notification.BigTextStyle(); bigText.bigText(“This Text will be repeated over and over.This Text will be repeated over and over.This Text will be repeated over and over.This Text will be repeated over and over.”); bigText.setBigContentTitle(“Big Text in Expansion Mode”); mBuilder.setStyle(bigText); //Step 3 Notification notfi = mBuilder.build(); mNotificationManager.notify(200,notfi); } Inbox Style يختلف هذا النوع عن النوع السابق في أنه يتيح لك عرض التفاصيل في أكثر من سطر، أما النوع السابق سيعرض كافة التفاصيل في نفس السطر دون القدرة على التحكم فيما يُعرض في كل سطر على حدا. ويُستخدم هذا النوع عند التعديل على إشعار وإضافة المزيد من التفاصيل إليه. مثل تطبيقات البريد الإلكتروني عند عرض في نفس الإشعار سطرًا عن كل رسالة قادمة. لتطبيق هذا النوع نمر بنفس الخطوات السابقة ولكن باستخدام كائن من الصنف Notification.InboxStyle. لاحظ أن لكل صنف توابعه الخاصة التي تُمكنك من إضافة الخصائص له. private void showInboxNotification() { //Step 1 mBuilder = new Notification.Builder(this); mBuilder.setSmallIcon(R.drawable.ic_inbox); mBuilder.setContentTitle(“Inbox in Normal Mode”); mBuilder.setContentText(“Example of a Inbox Notification.”); lines = new String[6]; lines[0] = “Line number 1”; lines[1] = “Line number 2”; lines[2] = “Line number 3”; lines[3] = “Line number 4”; lines[4] = “Line number 5”; lines[5] = “Line number 6”; //Step 2 Notification.InboxStyle inbox = new Notification.InboxStyle(); for(int I = 0 ; i<lines.length; i++) inbox.addLine(lines[i]); inbox.setBigContentTitle(“Inbox in Expansion Mode”); mBuilder.setStyle(inbox); //Step 3 Notification notfi = mBuilder.build(); mNotificationManager.notify(97,notfi); } Big Picture Style عندما تكون تفاصيل الإشعار هي صورة يُفضل استخدام هذا النوع. وأيضًا يختلف نوع الكائن المستخدم Notification.BigPictureStyle. private void showBigPictureNotification() { //Step 1 mBuilder = new Notification.Builder(this); mBuilder.setSmallIcon(R.drawable.ic_picture); mBuilder.setContentTitle(“Big Picture in Normal Mode”); mBuilder.setContentText(“Example of a Big Picture Notification.”); Bitmap img = BitmapFactory.decodeResource(getResources(),R.drawable.picture); //Step 2 Notification.BigPictureStyle bigPic = new Notification.BigPictureStyle(); bigPic.bigPicture(img); bigPic.setBigContentTitle(“Big Picture in Expansion Mode”); mBuilder.setStyle(bigPic); //Step 3 Notification notfi = mBuilder.build(); mNotificationManager.notify(6,notfi); } وبدمج كافة الأنواع في تطبيق واحد يعرض الإشعار عند الضغط على الزر المناسب لتُصبح الشيفرة النهائية لملف MainActivity.java هي: package apps.noby.advancednotification; import android.app.Activity; import android.app.Notification; import android.app.NotificationManager; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.view.View; import android.widget.Button; public class MainActivity extends Activity { private Button bigTextButton; private Button inboxButton; private Button bigPictureButton; private Button cancelButton; private Notification.Builder mBuilder; private NotificationManager mNotificationManager; private String[] lines; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); bigTextButton = (Button) findViewById(R.id.bg_txt); inboxButton = (Button) findViewById(R.id.inbx); bigPictureButton = (Button) findViewById(R.id.bg_pic); cancelButton = (Button) findViewById(R.id.cncl); mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); bigTextButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick (View v){ showBigTextNotification(); } } ); inboxButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { showInboxNotification(); } }); bigPictureButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { showBigPictureNotification(); } }); cancelButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { cancelNotification(); } }); } private void cancelNotification() { mNotificationManager.cancelAll(); } private void showBigTextNotification() { mBuilder = new Notification.Builder(this); mBuilder.setSmallIcon(R.drawable.ic_txt); mBuilder.setContentTitle("Big Text in Normal Mode"); mBuilder.setContentText("Example of a Big Text Notification."); Notification.BigTextStyle bigText = new Notification.BigTextStyle(); bigText.bigText("This Text will be repeated over and over.This Text will be repeated over and over.This Text will be repeated over and over.This Text will be repeated over and over."); bigText.setBigContentTitle("Big Text in Expansion Mode"); mBuilder.setStyle(bigText); Notification notfi = mBuilder.build(); mNotificationManager.notify(200,notfi); } private void showInboxNotification() { mBuilder = new Notification.Builder(this); mBuilder.setSmallIcon(R.drawable.ic_inbox); mBuilder.setContentTitle("Inbox in Normal Mode"); mBuilder.setContentText("Example of a Inbox Notification."); lines = new String[6]; lines[0] = "Line number 1"; lines[1] = "Line number 2"; lines[2] = "Line number 3"; lines[3] = "Line number 4"; lines[4] = "Line number 5"; lines[5] = "Line number 6"; Notification.InboxStyle inbox = new Notification.InboxStyle(); for(int i = 0 ; i<lines.length; i++) inbox.addLine(lines[i]); inbox.setBigContentTitle("Inbox in Expansion Mode"); mBuilder.setStyle(inbox); Notification notfi = mBuilder.build(); mNotificationManager.notify(97,notfi); } private void showBigPictureNotification() { mBuilder = new Notification.Builder(this); mBuilder.setSmallIcon(R.drawable.ic_picture); mBuilder.setContentTitle("Big Picture in Normal Mode"); mBuilder.setContentText("Example of a Big Picture Notification."); Bitmap img = BitmapFactory.decodeResource(getResources(),R.drawable.picture); Notification.BigPictureStyle bigPic = new Notification.BigPictureStyle(); bigPic.bigPicture(img); bigPic.setBigContentTitle("Big Picture in Expansion Mode"); mBuilder.setStyle(bigPic); Notification notfi = mBuilder.build(); mNotificationManager.notify(6,notfi); } } وملف واجهة المستخدم activity_main.xml: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center" android:orientation="vertical"> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Big Text Style" android:id="@+id/bg_txt"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Inbox Style" android:id="@+id/inbx"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Big Picture Style" android:id="@+id/bg_pic"/> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Cancel ALL" android:id="@+id/cncl"/> </LinearLayout> بهذا نكون قد وصلنا إلى نهاية هذا الدرس، في انتظار تجربتكم وآرائكم.1 نقطة