יום רביעי, דצמבר 15

Implicit Intent

ה-Implicit Intent היא הודעה הנשלחת בלי כתובת יעד. יעד ההודעה יקבע על-פי הפרמטרים המוצמדים להודעה:
  • Activity
  • Category
  • Data
שני פוסטים קודמים דנו בנושא ה-Intent:

Intents - מבוא להעברת הודעות במערכת 
Explicit Intent - העברת הודעות בין Activities -עם דוגמא. 

מומלץ לקרוא אותם קודם.

בכל אופן, ניקח את הדוגמא של ה- Explicit Intent, ובשינויים קלים נהפוך אותה ל-Implicit Intent.

תאור האפליקציה:
  • ה-Activity השולח ישלח Implicit Intent  שאליו הוצמד Action  , ויחכה לתגובה.
  • ה-Activity המקבל ירשם ב-Intent Filter כמתאים לקבלת ה-Action הנ"ל.
  • ה-Activity השולח והמקבל שייכים לאפליקציות שונות (בדוגמא ל- Exlicit השולח והמקבל היו באותה אפליקציה, אבל גם שם ניתן לשלוח הודעה בין אפליקציות).
  • מקבל ההודעה ישלח תגובה חזרה, שתודפס על המסך של יוזם ה-Intent המקורי.
  • שליחת ההודעה מופעלת עם כפתור.

כך נראית התצוגה לאחר קבלת התשובה:





נציג את הקוד. הוא כאמור מתפרס על שני פרוייקטים - משדר ומקלט -  אותם צריך לקמפל ולטעון בנפרד.

נתחיל עם משדר ההודעה.
רק שורה אחת שונתה לעומת המשדר של ה-Explicit Message.


הנה ה-class :



  1.  public class MessageCalling extends Activity {
  2.     public final static int RECEIVE_MESSAGE = 0;
  3.     /** Called when the activity is first created. */
  4.     @Override
  5.     public void onCreate(Bundle savedInstanceState) {
  6.         super.onCreate(savedInstanceState);
  7.         setContentView(R.layout.main);
  8.         Button sendMessage = (Button) findViewById(R.id.send);
  9.         Button CleanScreen = (Button) findViewById(R.id.clean);
  10.         sendMessage.setOnClickListener(new View.OnClickListener() {
  11.             public void onClick(View view) {
  12.                 TextView msg2screen = (TextView)findViewById(R.id.pong_message);
  13.                 msg2screen.setText("");
  14.                 Intent pingIntent = new Intent();
  15.                 pingIntent.setAction("com.ahs.ronen.identify");
  16.            //     pingIntent.setClass(MessageCalling.this, MessageReceiving.class);
  17.                 pingIntent.putExtra( "extra1", new String( "Message Received: Can you hear us?" ) );
  18.                 startActivityForResult(pingIntent, RECEIVE_MESSAGE);
  19.              }
  20.         });
  21.         CleanScreen.setOnClickListener(new View.OnClickListener() {
  22.             public void onClick(View view) {
  23.                 TextView msg2screen = (TextView)findViewById(R.id.pong_message);
  24.                  msg2screen.setText("");
  25.              }
  26.         });
  27.     }
  28.     protected void onActivityResult(int requestCode, int resultCode, Intent data){
  29.         switch(requestCode) {
  30.             case RECEIVE_MESSAGE:
  31.                 String     rec1    = data.getStringExtra("extra1");    
  32.                 Integer rec2    = data.getIntExtra("extra2",0);    
  33.       
  34.             if( rec1 != null ) {
  35.                 TextView msg2screen = (TextView)findViewById(R.id.pong_message);
  36.                 msg2screen.setText( rec1 + " " + rec2);
  37.             }
  38.          }
  39.     }
  40. }



יש כאן שתי מתודות:
  • onCreate 
  • onActivityResult.
רק שורה אחת מהקוד של ה-Explicit שונתה:
ב-onCreate במקום שורה 16, בה נקבע יעד ההודעה, (ראה למעלה, מסומנת כהערה), נוספה שורה15, בה מוצמד להודעה ה-Action:
ingIntent.setAction("com.ahs.ronen.identify");


לא נצלול  לפרטים, רק נזכיר מספר דגשים:
  • כדי לקבל הודעה זו, על המקלט להוסיף ל-intent filter את ה-Action הנ"ל.
  • ה-intent נשלח תוך שימוש במתודה startActivityForResult, כך שמצפים לקבל תגובה מהצד השני שישלח כשהוא יסיים פעולתו. התגובה תטופל על ידי onActivityResult.
  • כרגיל אצל אנדרואיד, מערכת ההודעה-תגובה היא אסינכרונית. הצד השולח ממשיך בפעולתו, ועם קבלת התשובה ה-callback הנ"ל יופעל.
  • ניתן היה לשלוח את ה-intent בלי לצפות לתגובה עם המתודה startActivity.
  • הסבר מפורט לקוד זה יש כמובן באותו פוסט קודם.

נעבור למקלט.
כאן נתעניין בשני קבצים:
  • ה-manifest.xml שם מוגדר ה-Intent Filter.
  • class ה-ג'אווה שלמעשה לא השתנה, למעט הוצאת הדפסות מיותרות למסך, והחלפת תוכן התשובה.

הנה המניפסט:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3.       package="com.ahs.androheb.implicitintent"
  4.       android:versionCode="1"
  5.       android:versionName="1.0">
  6.     <application android:icon="@drawable/icon" android:label="@string/app_name">
  7.         <activity android:name=".MyImplicitIntentReceive"
  8.                   android:label="@string/app_name">
  9.             <intent-filter>
  10.                 <action android:name="com.ahs.ronen.identify" />
  11.                 <category android:name="android.intent.category.DEFAULT"/>
  12.                 
  13.             </intent-filter>
  14.         </activity>
  15.     </application>
  16.     <uses-sdk android:minSdkVersion="8" />
  17. </manifest>

דגשים בנוגע לקובץ זה:
  • בשורות 10-11 מוגדר ה-intent filter המתאים.
  •  למרות שה-Category לא הוגדר (הוא Don't Care), חייבים להוסיף את ה-Default ראה שורה 11, אלא אם היה מוגדר פילטר נוסף עם Action MAIN.
  • הוצאתי את ה-intent filter עם ה-Action MAIN, כך שה-Activity הזה לא יתעורר בהפעלה, אלא רק ע"י ה-intent שלנו.

נציג את class הג'אווה. הוא כאמור זהה  לההוא של ה-Explicit למעט שינויים קוסמטיים הכוללים ביטול הדפסות ושינוי תוכן ההודעה החוזרת.

  1. public class MyImplicitIntentReceive extends Activity {
  2.        /** Called with the activity is first created. */
  3.     @Override
  4.     public void onCreate(Bundle savedInstanceState)
  5.     {
  6.        
  7.         super.onCreate(savedInstanceState);
  8.         setContentView(R.layout.main);
  9.         String extraMsg1 = getIntent().getExtras().getString("extra1");
  10.         if( ( extraMsg1 != null ) ) {
  11.         }
  12.         else
  13.         {
  14.              Log.e("Received Extra is null", "null");
  15.         }
  16.         Intent pongIntent = new Intent();
  17.         pongIntent.putExtra("extra1", "Response Implicit Intent received: Yes, we can hear yall!");
  18.         pongIntent.putExtra("extra2", new Integer(777) );
  19.         setResult(RESULT_OK,pongIntent);
  20.         finish();
  21.     }
  22. }

רק המתודה onCreate ממומשת.
בשורה 9 נשלפף שדה ה-extra מה-intent שהתקבל.
בשורה 16 יוצרים intent תשובה, ומכניסים לא שני שדות extra שיודפסו על המסך של המקבל.




2 תגובות:

  1. היי רונן, לינק להורדה לא פועל. תודה רבה על הפוסט :)

    השבמחק
  2. סידרתי את זה. אתר איחסון הקבצים עושה בעיות.

    השבמחק