
addProduct מקבלת ContentValues ומחזירה את ה-ID החדש. updateProduct מקבלת ContentValues, whereClause ו-whereArgs, ומחזירה את מספר השורות שהושפעו.deleteProduct מקבלת רק where ו-args. getProductsCursor מקבלת עמודות, selection, selectionArgs ו-order by, ומחזירה קורסור באמצעות query.ContentProvider ומממשים את הפונקציות. onCreate מחזירה true, ו-getType מחזירה null כי זה מידע טבלאי ולא סוג מדיה כמו תמונה או וידאו.content://, אחריה authority (שם החבילה והמחלקה), אחריה סוג המידע products, ואם צריך גם ID של פריט. לפי ה-URI אפשר לדעת אם מבקשים את כל המוצרים או מוצר אחד. כאן, לשם פשטות, מתייחסים תמיד לכל המוצרים.getContext().getContentResolver().notifyChange כדי להודיע למאזינים על שינוי.getProductsCursor עם הפרמטרים שהתקבלו (ה-columns הם ה-projection), וקוראים ל-setNotificationUri כדי שהקורסור יתעדכן בשינויים.application מוסיפים provider עם authorities, name של המחלקה, exported="true" ו-grantUriPermissions="true".הטקסט המלא של הדקות הראשונות בהרצאה «Content Provider - חלק 1» בקורס הווידאו של PracticU – כתוביות בעברית עם זמן התחלה לכל פסקה. כך תוכלו לקרוא ולחפש את הנושאים לפני שמתחילים ללמוד.
אחרי שראינו איך אנחנו יכולים שיהיה לנו דאטאבייס והמידע שהאפליקציה שלנו צורכת ומשתמשת בו שמור בדאטאבייס, אנחנו מגיעים לנושא שבו אנחנו יכולים לחשוף את המידע הזה מעבר לאפליקציה שלנו, כך שאפליקציות אחרות שנמצאות במכשיר של המשתמש יוכלו גם כן לצרוך את המידע הזה.
הנושא הזה נקרא Content Provider ו-Content Provider זה בעצם הכלי או המחלקה שמאפשרת לנו לחשוף את המידע מדאטאבייס בדרך כלל אל מחוץ לאפליקציה. אם לדוגמה וואטסאפ מכילה קונטנט פרוביידר, זה אומר שאנחנו יכולים לבנות אפליקציות שיכולות לצרוך את ההודעות מהקונטנט פרוביידר של וואטסאפ.
אם לדוגמה קיים במכשיר קונטנט פרוביידר של רשימת הקונטקטס המשתמשים של היוזר, אז אפליקציה שאנחנו בונים או שמישהו אחר בונה יכולה לצרוך את המידע הזה ולהשתמש ברשימת הקונטקטס.
כל הנושא הזה שמאפשר לחשוף החוצה מידע מתוך האפליקציה זה ה-content provider. בדוגמה הזאת אנחנו הולכים לראות איך אנחנו יכולים לחשוף בדיוק את המידע שעשינו בפרויקט של מסדי הנתונים אל מחוץ לאפליקציה ולאחר מכן לצרוך אותו על ידי אפליקציות אחרות.
אז קודם כל יש לנו את האפליקציה עם הדייטאבייס והאפליקציה הזאת פשוט מתעסקת עם מוצרים כאשר מוצר יש לו קוד, יש לו שם ויש לו מחיר. יש לנו את המחלקה דייטאבייס שבנינו והיא מאפשרת לייצר דייטאבייס חדש ולבצע הוספה, לבצע עדכון, לבצע מחיקה, כאן וכאן אנחנו רואים, ולקבל מוצר בודד ולקבל את כל המוצרים
בצורה כזאת כאשר כל המוצרים חוזרים על ידי קורסור ואז יש לנו פה איזשהו קורסור אדפטר פה אנחנו רואים שמאפשר אוטומטית להציג את כל המידע לפי הקורסור שמתקבל ואם אנחנו מריצים את האפליקציה הזאת אנחנו יכולים לראות שיש לנו כאן סדרה של מוצרים שהכנסנו ואנחנו יכולים לבצע הוספה של מוצר בעזרת התפריט פה אנחנו יכולים לבצע עדכון אנחנו יכולים לבצע מחיקה
וצפייה בכל המוצרים. כל האפליקציה הזאת, בנינו אותה בנושא של מסדי נתונים, ומה שאנחנו רוצים לעשות עכשיו זה לחשוף את כל המידע הזה החוצה, ולאפשר לעולם החיצון לבצע בדיוק את הפעולות של ה-crood על המידע, כלומר create, read,
update, delete, על המידע של האפליקציה שלנו, וכמובן הוא רוצה לעשות את זה מאפליקציה אחרת שהיא בכלל לא קשורה לאפליקציה שלנו.
אז אם יש לנו מצב כזה שהמידע שלנו יכול להידרש על ידי אפליקציות אחרות אז ככה אנחנו הולכים לעשות את זה. אז בואו נתחיל בואו נראה מה הפעולות שאנחנו צריכים לבצע בשביל להצליח לעשות את זה.
הדבר הראשון שאנחנו צריכים זה לאפשר סדרה של פונקציות שיבצעו את אותו קרוד ואת זה אנחנו מבצעים במחלקה של הדאטאבייס שבנינו. אותה מחלקה שמאפשרת גישה לדאטאבייס היא המחלקה שבה אנחנו רוצים לגשת ולבנות את הפונקציות הדרושות.
עכשיו, חשוב לציין, יכול להיות מצב שאתם באפליקציה שלכם שרוצים לחשוף את המידע, אתם לא מעוניינים שאפליקציות אחרות יבצעו שינויים על המידע או יוסיפו מידע, יעדכנו וימחקו, אלא רק יצרכו לצורך צפייה במידע.
אם זה המצב, אז אתם לא באמת צריכים לכתוב פונקציה שמוסיפה מוצר, מעדכנת מוצר או מוחקת מוצר, אלא רק פונקציה מתאימה שמחזירה את המוצרים, נניח שהמידע שלנו זה מוצרים.
אנחנו הולכים כרגע כן לאפשר לבצע את הכל בכדי לראות איך אפשר לחשוף לגמרי את המידע כולל האפשרות להוסיף, לעדכן ולמחוק וכמובן לצפות בנתונים ובהמשך כאשר נבנה אפליקציה חיצונית אז נשתמש בה רק לצורך ההצגה של המידע ולא לצורך העדכון של המידע אבל פה אנחנו הולכים לראות איך כן אנחנו הולכים לאפשר לבצע הכל.
אוקיי אז מה שאנחנו רוצים לעשות זה להוסיף פדרה ספציפית של פונקציות עבור המידע שלנו. אם המידע שלנו מוצרים אז אנחנו רוצים לבצע את הפונקציות הבאות. פונקציה ראשונה אנחנו רוצים לבצע פונקציה שמוסיפה מוצר.
פונקציה כזאת צריכה להחזיר את הקוד החדש של המוצר, בואו נקרא לה add product ועל הפונקציה הזאת לקבל ספציפית content values שראינו עבודה איתו בעבר.
בואו נקרא לזה values ומה שאנחנו רוצים לעשות זה לבנות אובייקט מסוג sqlite database db ואנחנו רוצים לגשת ל-get writable data בצורה כזאת ואז אנחנו רוצים את ה-id של המוצר החדש וזה יהיה db.insert ובגלל שהטבלה שלנו כרגע היא product אז אנחנו מיד רוצים להכניס את המידע לטבלת
product ואנחנו רוצים כאן להכניס נאל כי אין לנו values שהם נאלים. לאחר מכן הנה כל ה-values שאנחנו רוצים להכניס שקיבלנו מבחוץ.
אפשר לבצע סגירה ולהחזיר את ה-ID. עכשיו, הפונקציות האלה שאנחנו בונים כרגע, ארבעת הפונקציות של insert, update, delete ו-select, אנחנו בונים אותן שהן כבר יותאמו ל-content provider, כאשר אם בעבר בנינו פונקציה שמקבלת מוצר ומכניסה את המידע לתוך הדאטאבייס לפי המוצר שהיא קיבלה,
אנחנו לא יכולים עכשיו להשתמש בפונקציה הזאת או לבנות פונקציה שמקבלת מוצר. למה? כי מוצר זאת מחלקה ששייכת רק לאפליקציה שלנו, המחלקה product.
אפליקציה אחרת שרוצה להשתמש במידע שלנו אין לה ספציפית את המחלקה product והיא לא תוכל לשלוח לנו אובייקט product. אז אנחנו צריכים לשמור על עבודה עם כלים קיימים במערכת וראינו באחד הסרטונים של הדאטה בייסים שיש לנו אפשרות לארגן content values שזה בעצם איזשהו קולקשן
של key value שמאפשר להגדיר אילו ערכים אנחנו רוצים להכניס לאילו עמודות וככה אנחנו יכולים לאפשר לאפליקציה אחרת לשלוח לנו את ה-content values האלה או דברים דומים שיותאמו ל-content values.
אנחנו נראה בהמשך. אז קודם כל יש לנו כאן פונקציה לצורך הוספה של מוצר. הפונקציה הבאה שאנחנו רוצים לבנות תהיה עדכון מוצר.
אז בואו נבנה אותה כאן. יש לנו public int update product, היא גם כן מקבלת content values, היא מקבלת string where clause בכדי שליוזר תהיה את האפשרות לבצע לנו שאילתת where ו-string where args.
במידה ויש לנו סימני שאלה בתוך ה-where, אז כאן יש לנו את הערכים שיותאמו במדויק לסימני השאלה. את כל העבודה עם השיטה הזאת ראינו באחד הסרטונים של גישה למסדי נתונים.
והדבר הבא שאנחנו רוצים לעשות זה לגשת, קודם כל שיהיה לנו את ה-writable database, בואו ניקח אותו, נשים אותו כאן. אנחנו רוצים לגשת ל-db.update וכבר אנחנו רואים שיש לנו פה את השם של הטבלה, products, יש לנו איזה values אנחנו רוצים להכניס ואיזה
where clause אנחנו רוצים להשתמש בו עם ה-where arguments שאנחנו רוצים. עכשיו, פונקציית ה-update מחזירה לנו אינטג'ר שמתאר את האפקטד רוז, כמה שורות הושפעו מהפעולה של האפדייט.
אנחנו רוצים עכשיו להחזיר בדיוק את האפקטד רוז, בכדי שמי שמשתמש בנו יוכל לדעת כמה שורות הושפעו מהפקודה הזאת.
והנה, יש לנו עכשיו פונקציה שמאפשרת לעדכן מוצר קיים. הפונקציה הבאה שאנחנו רוצים נקרא delete product היא תקבל רק את ה- where clause ואת ה- where args.
עוד פעם אנחנו רוצים את אותו רכיב שמאפשר ביצוע פעולות על ה-database ה-sqlite database, get writable Database ואנחנו רוצים שוב פעם לקבל את ה-affected rows, בואו ניגש ל-db לפונקציית delete.
אנחנו רוצים שהטבלה שלנו תהיה product זה המידע היחידי שאנחנו רוצים לחשוף והנה ה-Ware Clause עם ה-Ware Args, אם היוזר רוצה למחוק רק את המוצרים שיקרים יותר מ-10, רק את המוצרים שמתחילים באלף או רק את המוצרים של ספק מספר 7, אז הוא יכול לשלוח לנו Ware עם הארגומנטים של ה-Ware וכמובן שהפקודה הזאת תיישם את זה.
בואו נסגור את ה-Database ונחזיר את ה-Affected Rows, כמה שורות הושפעו מהפקודה, ולבסוף אנחנו רוצים פונקציה אחרונה שתאפשר לנו להחזיר את המידע.
ב-content provider אנחנו מחזירים קורסור. אז בואו נבנה פונקציה ונקרא לה get products cursor והפונקציה הזאת צריכה לקבל קודם כל אילו עמודות columns אנחנו רוצים להחזיר לרשימת עמודות של ה-columns לאחר מכן משהו שנקרא ה-selection האם יש לנו איזשהו חלק של where שאנחנו רוצים להגדיר בשביל לומר מה
בדיוק לבחור בואו נקרא לזה רק selection בצורה כזאת לאחר מכן אילו arguments יש ל-selection selection args לאחר מכן האם אנחנו רוצים לבצע מיון order by אלו הפרמטרים שאנחנו רוצים בואו רגע נעבור עליהם ונבין מה הם רשימת העמודות אולי אנחנו רוצים רק את ה-name ואת ה-prime סלקשן זה בעצם איזושהי מחרובת שמתארת where,
כלומר נניח where פרייס גדול מ-10 וגם פרייס קטן מ-20. Selection Arguments זה יהיה ה-10 וה-20, אם בסלקשן היה where פרייס גדול מסימן שאלה, אין פרייס קטן מסימן שאלה, אז פה יהיה את ה-10 ואת ה-20.
ואיזו עמודה אנחנו רוצים למיין לפיה, נניח תמיין לי לפי המוצר. אז כאן, אחרי שקיבלנו את כל האפשרויות האלה, אנחנו יכולים לפתוח sqlite database, שוב פעם db, אבל הפעם get readable database ומיד להחזיר db.query כמו שעשינו בעבר.
הנה טבלת הפרודקט שאנחנו רוצים לעבוד עליה, הנה ה-columns, הנה ה-selection, הנה ה-selection args והנה ה-orderby, למעשה יש לנו groupby שאין לנו פה שימוש, נגדיר פה נעלים והאורדר ביי הוא בסוף והנה ומה שאנחנו צריכים עבור מחלקת הדאטה בייס ארבעת הפונקציות שבנינו כרגע הולכות להיות בשימוש על ידי רכיב ה-content provider שבנינו פה אני
רואה רק שיש לי שגיאת הקלדה product add product בודד good אז זה השלב הראשון השלב הראשון זה לאפשר פונקציות שמבצעות כרות על הדאטאבייס, שוב אם לא היינו רוצים לאפשר הוספה אז לא היינו בונים את הפונקציה הזאת, אם כן היינו רוצים לאפשר הוספה אז כן אנחנו בונים את הפונקציה, הכוונה הוספה מאפליקציה אחרת,
כנ"ל יכול להיות שספציפית מחיקה אנחנו לא מאשרים, אז לא היינו בונים פונקציית מחיקה ואז כמובן לא היינו משתמשים ולא היינו מאפשרים לבצע מחיקה, אבל ברוב המקרים כן תהיה לנו פונקציה שמאפשרת הצגה של כל הנתונים ופונקציה כזאת תמיד תחזיר לנו קורסור יופי אז אנחנו יכולים לעבור לשלב הבא השלב הבא זה לבנות את מחלקת
ה-content provider שלנו אז בואו נעבור ונייצר מחלקה חדשה ונקרא לה products content provider המחלקה הזאת צריכה לרשת מחלקה שקיימת בתשתית של אנדרואיד שנקראת קונטנט קונטנט פרוביידר הנה היא והמחלקה הזאת זו מחלקה אבסטרקטית שאנחנו צריכים לממש אז
בואו נלחץ על אלט אנטר אימפלימנט מתודס ויש לנו את כל הפונקציות האלה שאנחנו צריכים לכתוב אז בואו נגדיר אותן כרגע הן ריקות לגמרי נעבור פונקציה פונקציה ונראה איך אנחנו יכולים לבנות את הקונטנט פרוביידר שחושף את המידע אוקיי אז מה יש לנו כאן דבר ראשון onCreate זאת
פונקציה שמיועדת להחזיר