
IntentService.EditText. הראשון עם inputType של time ו-hint, והשני עם text-multiline בחמש שורות להודעה. מתחתיהם לחצן "save and close" ששומר ומסיים.TextView גדול שמציג את ההודעה ולחצן close שקורא ל-finish. ב-onCreate היא מקבלת את ההודעה מ-getIntent().getStringExtra("message"). היא לא יודעת מי הפעיל אותה, ולכן אותה Activity מתאימה להפעלה מ-Service, מ-Broadcast Receiver או מ-Activity אחרת.IntentService וממשת את onHandleIntent. כשהפונקציה מסתיימת ה-Service נעצר מעצמו. הבנאי רק מעביר מחרוזת ל-super, והיא משמשת כשם ה-thread לצורכי debugging.Intent שהפעיל את ה-Service קוראים hour, minute ו-message באמצעות getIntExtra ו-getStringExtra.sleepForOneSecond) בודקים בפונקציה isTimeArrived אם השעה והדקה הנוכחיות שוות לאלה שהוזנו והשנייה היא 0. כשהזמן מגיע מציגים Notification ויוצאים מהלולאה, וכך ה-Service מסתיים.Intent ל-ReminderActivity עם extra בשם message, עטוף ב-PendingIntent.getActivity עם הדגל FLAG_ONE_SHOT. ה-Notification נבנה ב-Builder עם ticker, כותרת, טקסט, אייקון קטן וגדול (BitmapFactory.decodeResource), setAutoCancel(true) ו-setContentIntent. מציגים אותו עם NotificationManagerCompat, ומזהה ה-Notification גדל ב-++ כדי שכל התראה תהיה נפרדת.MainActivity מפרקים את המחרוזת עם split לפי נקודותיים, ממירים עם Integer.parseInt ושולחים את שלושת ה-extras ל-startService. הפעלת IntentService זהה להפעלת Service רגיל.IntentService מיועד למשימות קצרות. כאן הוא ממתין זמן רב רק לצורך התרגול, וזה בסדר כי זה ה-Service היחיד באפליקציה. עם הרבה IntentService קטנים כל אחד צריך לבצע משימה מהירה.onStartCommand, קוראים ל-super.onStartCommand ואז מחזירים START_REDELIVER_INTENT. אחרת ה-Service לא יעבוד.START_STICKY, כי הוא לא מעביר מחדש את ה-Intent. אחרי הפעלה מחדש ה-Intent יהיה null וה-Service יקרוס. עם START_REDELIVER_INTENT אותו Intent נשלח שוב עם כל המידע.ReminderActivity עם ההודעה.IntentService שרץ ברקע גם כשהאפליקציה סגורה, ומחזיר את המשתמש אליה דרך Notification.הטקסט המלא של הדקות הראשונות בהרצאה «Create Intent Service» בקורס הווידאו של PracticU – כתוביות בעברית עם זמן התחלה לכל פסקה. כך תוכלו לקרוא ולחפש את הנושאים לפני שמתחילים ללמוד.
אנחנו מגיעים לדוגמה המבצעת שימוש באינטנט סרוויס. בדוגמה הזאת אנחנו הולכים לבנות אפליקציה שמהווה מעין רימיינדר כזה עבור היוזר.
יוזר יכול להכניס באפליקציה זמן על ידי הכנסה של שעה ודקה ספציפיים ואיזושהי הודעה מסוימת ויכול לסגור את האפליקציה. ברגע שמגיע הזמן הזה, כלומר השעה והדקה הספציפיים שהוא הכניס, אוטומטית אנחנו רוצים להקפיץ לו את הרימיינדר הזה ולהציג לו את ההודעה.
אנחנו נעשה את זה על ידי זה שהאינטנט סרוויס שלנו יציג נוטיפיקיישן אז היוזר יוכל לגלול למטה את הנוטיפיקיישן, ללחוץ עליה ולראות את ההודעה. כאמור כל הסיפור הזה אפילו שהוא סגר את האפליקציה לכן אנחנו צריכים איזשהו סרוויס ברקע שרץ כל הזמן ובודק האם הגיעה השעה.
אנחנו נשתמש לצורך כך באינטנט סרוויס. אז קודם כל בואו נבנה את ממשק המשתמש. אנחנו רוצים להגדיר למשתמש איזשהו Edit טקסט כך שהוא יוכל להכניס את השעה. אז יש לנו פה Edit טקסט עם Match Parent ו-App Content.
בואו נגדיר לו איזשהו ID כדי שנוכל לקבל את זה בקוד. נקרא לו Edit טקסט time. לאחר מכן נגדיר טקסט סייז קצת יותר גדול. בואו ניקח 20 SP, נגדיר לו input type time, מפני שהיוזר מכניס לנו time, שעה, ניתן לו איזשהו hint, enter reminder time,
וזה בעצם כל מה שאנחנו רוצים עבור ה-edit text הזה. בואו נשכפל את ה-edit text ל-edit text נוסף, הפעם עבור ההודעה של ה-reminder.
מה היוזר רוצה לראות, איזו הודעה היוזר רוצה לראות כאשר הזמן הזה יגיע. פעם האינפוט טייפ יהיה טקסט מולטי ליין, נגדיר לו שיש לו נניח חמש שורות אוטומטית שהוא יוכל לרשום את ההודעה, הוא כמובן יכול לרשום הודעה הרבה יותר מחמש שורות, והאינט שאנחנו רוצים לתת לו זה Enter Reminder
Message. לבסוף אנחנו רוצים לחצן שהמשתמש יוכל לראות את הטקסט Save and Close, כלומר הלחצן הזה גם מבצע סגירה של האפליקציה, כי היוזר כבר הכניס את הרימיינדר והוא יכול פשוט להיפטר מהאפליקציה.
מה אנחנו רוצים להציג לו פה? בואו ניקח טקסט All Caps False, קח טקסט סייז 20, אותו הדבר, ואנחנו רוצים רק On Click, Button Save and Close, On Click, וממשק המשתמש מוכן.
הדבר הבא שאנחנו רוצים לבנות זה אקטיביטי נוספת שתוכל להציג את ההודעה למשתמש. אז בואו ניגש לאקטיביטיז, נצרף Empty Activity ונקרא לאקטיביטי Reminder Activity.
נעצב את ה-UI של ה-Reminder Activity על ידי טקסט view שיתפוס את כל המסך, נגדיר לו ID, טקסט view message, נגדיר לו טקסט סייז 20, נגדיר לו טקסט סטייל בולד שיראו את ההודעה בצורת בולד, נגדיר לו אדינג של 30 dp ונגדיר לו טקסט קולור לבן.
למה? כי אנחנו רוצים להגדיר כמה ערכים שונים עבור הלייאוט עצמו. בואו נגדיר כאן שיש לנו backround ונאתר איזשהו צבע יחסית כזה, ואז אם יהיה לנו פה איזשהו טקסט, אז נוכל לראות אותו בצורה כזאת.
ניפטר פה מהכל, ונוסיף לחצן. הלחצן, התפקיד שלו יהיה לסגור את ה-Activity. נגדיר ללחצן Align Parent Bottom, נגדיר לו Align Parent Right, נגדיר לו Text Close, נגדיר לו Text All Caps False ו-Text Size 20, און קליק בתון קלוז און קליק נגיע לקוד ופשוט
נבצע פיניש יש לנו כרגע את הקוד של האטיביטי של הרימיינדר אבל שימו לב שהאטיביטי הזאת של הרימיינדר פשוט מציגה את ההודעה ומאפשרת למשתמש לראות אותה ולסגור אבל איך היא מקבלת את ההודעה כאן אנחנו יכולים כאשר הרימיינדר אקטיביטי מתבצעת באון קריאייט אנחנו יכולים פשוט לקבל את זה מאינטנט מסוים ולהציג.
הרי חייב להיות איזה שהוא אינטנט שמפעיל את האקטיביטי. דרך האינטנט הזה אנחנו נקבל את ההודעה. אז בואו ניקח פה private text view, נקבל את ה-text view מסג', נאתר אותו, יש לנו פה text view, find view by id, r.id, text view מסג'.
כעת אנחנו רוצים לקבל את האינטנט שהפעיל אותנו, יש לנו את הפונקציה getIntent, יש לנו StringMessage שאנחנו מוציאים מהאינטנט, getStringExtra, ואנחנו מחליטים שבשביל לקבל הודעה צריכים להעביר לנו Extra שנקרא Message, ואז אנחנו יכולים לפנות ל-TextViewMessage ו-ToSetTextMessage,
והנה יש לנו כאן Activity שכל מה שהיא אומרת זה דבר כזה, מי שמפעיל אותי שפשוט יביא לי איזשהו מסג' ואני אציג אותו. האקטיביטי הזאת לא יודעת אם סרוויס הולך להפעיל אותה או אינטנט סרוויס או ברודקאסט רסיבר או אקטיביטי אחרת, לא מעניין אותה.
היא מאוד פשוטה, פשוט יודעת להציג הודעה שהיא קיבלה בסטרינג אקסטרה. סיימנו עם ה-reminder activity, אנחנו יכולים לסגור, ובואו נחשוב מה הדבר הבא שאנחנו צריכים לבצע.
אחרי שיש לנו את ה-reminder activity, אנחנו יכולים לגשת ולבנות את הסרוויס עצמו. ובדוגמה שלנו זה הולך להיות Intent Service רק בכדי לראות איך ניתן לעבוד עם Intent Service.
אז אנחנו רוצים לגשת ולהוסיף מחלקה חדשה. נקרא למחלקה הזאת Reminder Service. אנחנו רוצים to extend, הפעם Intent Service. בואו נלחץ על Alt Enter, נממש אינתודה אחת שנקראת onHandleIntent, האינתודה הזאת מתרחשת ברגע שמפעילים את הסרוויס, ברגע שהיא מסתיימת,
אוטומטית הסרוויס שלנו מת. אז אנחנו לא צריכים להפסיק אותו בעצמנו. דבר נוסף, אנחנו צריכים שיהיה לנו איזשהו קונסטרקטור. אם אנחנו נבצע פה עוד פעם Alt-Enter אנחנו נראה Create Constructor Matching Super.
בואו ניפטר פה מכל המידע המיותר הזה, ולמעשה הקונסטרקטור הזה צריך להיות קונסטרקטור ריק שמעביר לסופר מחרוזת.
המחרוזת בדרך כלל תהיה השם של המחלקה. מה זאת המחרוזת הזאת? אמרנו ש-Intent Service שאנחנו בונים כרגע מופעל על ידי Thread נפרד. מה שאנחנו נותנים פה למעלה זה פשוט איזה שם אנחנו רוצים לתת ל-Thread הזה רק לצורכי דיבאגינג.
אז אין לנו משמעות אחרת לשם הזה, אז רק נתנו אותו כי זה מה שהמערכת דורשת מאיתנו. כל מה שאנחנו צריכים לעשות זה לבנות את onHandleIntent, זאת הפונקציה שתתבצע עבור הסרוויס שלנו, וברגע שהיא מסתיימת נגמר הסרוויס.
אוקיי, מה אנחנו רוצים לעשות? דבר ראשון, אנחנו רוצים לקבל מבחוץ את השעה, הדקה ואת ההודעה שרוצים להציג בדיוק בשעה הזאת.
אנחנו לא אמורים שתהיה לנו גישה ישירה ל-UI, לכן אנחנו יודעים שכאשר מפעילים סרוויס יש אינטנט. אנחנו מקבלים כאן את האינטנט שהפעיל את הסרוויס, ואנחנו יכולים להחליט שמי שרוצה להפעיל אותנו חייב להביא לנו את המידע הזה.
זאת אומרת שמי שמפעיל אותנו חייב להביא לנו int hour שווה intent.getIntExtra וחייבים להביא לנו hour. בואו ניתן פה איזה ערך ברת מחדל.
אוטומטית חייבים להביא לנו minute, ניקח אותו על ידי intent.getIntExtra minute וחייבים לתת לנו איזושהי הודעה. הנה המסאג' intent.getStringExtra מסאג'. מי נותן לנו את זה?
הקוד שמפעיל אותנו כסרוויס, הוא מפעיל אותנו על ידי אינטנט והוא מחויב להביא לנו את המידע הזה כי אנחנו חייבים לפעול עם המידע. הדבר הבא שאנחנו רוצים לעשות זה פשוט לבדוק כל שנייה האם השעה הזאת הגיעה.
בואו נבצע פה איזושהי לולאה, נלך לישון במשך שנייה אחת, עשינו את זה כבר בדוגמה הקודמת, זה היה sleep one second בצורה כזאת וזאת פונקציה שאנחנו יכולים לבנות פה למטה private void sleep for one second ויש לנו thread sleep 1000 מילי שניות נעטוף את זה בtry catch ויש לנו פה המתנה של שנייה בכדי לא לטחון את המעבד של המכשיר.
הדבר הבא שאנחנו רוצים לעשות זה לקרוא לפונקציה שאנחנו הולכים לבנות שנקראת isTimeArived לתת לה את ה-Hour לתת לה את ה-Minute והיא תגיד לנו האם כרגע במכשיר ובדיוק השעה הזאת אז בואו ניגש לכאן ונבנה את הפונקציה אז יש לנו פה private void isTimeArived שמקבלת intHour intMinute כל מה שהפונקציה הזאת רוצה לעשות זה לבדוק בקלנדר של המכשיר
האם השעה הזאת הגיעה אז בואו ניקח קובייקט קלנדר, קלנדר גט אינסטנס, לאחר מכן בואו ניקח את השעה הנוכחית, קלנדר נקודה גט, קלנדר אור, אוף דיי, ואותה שעה של היום, 0 עד 23. יש לנו מינט, קלנדר גט,
מינט, ויש לנו סקנד. ניגש לקלנדר וניקח ממנו קלנדר סקנד, והנה יש לנו בדיוק את השעה, דקה ושנייה נוכחיים. מה שאנחנו רוצים לעשות זה להחזיר האם השעה הנוכחית שווה לשעה שהפונקציה שלנו קיבלה וגם הדקה הנוכחית שווה לדקה שהפונקציה שלנו קיבלה וגם השנייה הנוכחית שווה לאפס.
אם זה המצב אז אנחנו יודעים שאנחנו בעצם