1 Mobile Software Development Framework: Android IPC; Mobile Push Notification 10/16/2012 Y. Richard Yang.

Slides:



Advertisements
Similar presentations
Staying in Sync with Cloud 2 Device Messaging. About Me Chris Risner Twitter: chrisrisner.
Advertisements

Programming with Android: Activities and Intents Luca Bedogni Marco Di Felice Dipartimento di Informatica – Scienza e Ingegneria Università di Bologna.
Cosc 5/4730 Android Services. What is a service? From android developer web pages: Most confusion about the Service class actually revolves around what.
Cellular Networks and Mobile Computing COMS , Spring 2014 Instructor: Li Erran Li
The Activity Class 1.  One application component type  Provides a visual interface for a single screen  Typically supports one thing a user can do,
Application Fundamentals. See: developer.android.com/guide/developing/building/index.html.
Android 101 Application Fundamentals January 29, 2010.
Security of Mobile Applications Vitaly Shmatikov CS 6431.
Cellular Networks and Mobile Computing COMS , Spring 2013 Instructor: Li Erran Li
1 Mobile Software Development Framework: Mobile-Cloud Services (Push/Track) 10/18/2012 Y. Richard Yang.
1 Android: Event Handler Blocking, Android Inter-Thread, Process Communications 10/11/2012 Y. Richard Yang.
Cellular Networks and Mobile Computing COMS , Spring 2014 Instructor: Li Erran Li
CSE 486/586, Spring 2013 CSE 486/586 Distributed Systems Content Providers & Services.
Mobile Computing Lecture#08 IntentFilters & BroadcastReceivers.
Google Cloud Messaging for Android (GCM) is a free service that helps developers send data from servers to their Android.
1 Mobile Software Development Framework: Android 2/23/2011 Y. Richard Yang.
Data Storage: Part 4 (Content Providers). Content Providers Content providers allow the sharing of data between applications. Inter-process communication.
Integrating with Android Services. Introduction  Android has numerous built-in functionality that can be called from within your applications  SMS/MMS.
Erika Chin Adrienne Porter Felt Kate Greenwood David Wagner University of California Berkeley MobiSys 2011.
DUE Hello World on the Android Platform.
CS378 - Mobile Computing Intents.
16 Services and Broadcast Receivers CSNB544 Mobile Application Development Thanks to Utexas Austin.
1 Announcements Homework #2 due Feb 7 at 1:30pm Submit the entire Eclipse project in Blackboard Please fill out the when2meets when your Project Manager.
1 Mobile Software Development Framework: Android 2/28/2011 Y. Richard Yang.
1 Mobile Software Development Framework: Mobile-Cloud Service 10/18/2012 Y. Richard Yang.
Threads and Services. Background Processes One of the key differences between Android and iPhone is the ability to run things in the background on Android.
CS378 - Mobile Computing Intents. Allow us to use applications and components that are part of Android System – start activities – start services – deliver.
COMP 365 Android Development.  Every android application has a manifest file called AndroidManifest.xml  Found in the Project folder  Contains critical.
Cosc 5/4730 Android Communications Intents, callbacks, and setters.
Linking Activities using Intents How to navigate between Android Activities 1Linking Activities using Intents.
Services A Service is an application component that can perform long-running operations in the background and does not provide a user interface. An application.
Mobile Programming Midterm Review
Applications with Multiple Activities. Most applications will have more than one activity. The main activity is started when the application is started.
FCM Workflow using GCM.
1 Mobile Software Development Framework: Android Inter- Thread, Process Communications 10/11/2012 Y. Richard Yang.
Working with Multiple Activities. Slide 2 Introduction Working with multiple activities Creating multiple views Introduction to intents Passing data to.
Intents 1 CS440. Intents  Message passing mechanism  Most common uses:  starting an Activity (open an , contact, etc.)  starting an Activity.
Services Background operating component without a visual interface Running in the background indefinitely Differently from Activity, Service in Android.
1 Mobile Software Development Framework: IOS 10/2/2012 Y. Richard Yang.
CSE 486/586, Spring 2014 CSE 486/586 Distributed Systems Android Programming Steve Ko Computer Sciences and Engineering University at Buffalo.
Lecture 2: Android Concepts
Technische Universität München Services, IPC and RPC Gökhan Yilmaz, Benedikt Brück.
Activities and Intents Chapter 3 1. Objectives Explore an activity’s lifecycle Learn about saving and restoring an activity Understand intents and how.
Intents and Broadcast Receivers Dr. David Janzen Except as otherwise noted, the content of this presentation is licensed under the Creative Commons Attribution.
Mobile Software Development for Android - I397 IT COLLEGE, ANDRES KÄVER, WEB:
David Sutton SMS TELEPHONY IN ANDROID. OUTLINE  This week’s exercise, an SMS Pub Quiz  Simulating telephony on an emulator  Broadcast Intents and broadcast.
The Ingredients of Android Applications. A simple application in a process In a classical programming environment, the OS would load the program code.
Working with Multiple Activities. Slide 2 Introduction Working with multiple activities Putting together the AndroidManifest.xml file Creating multiple.
CS371m - Mobile Computing Intents 1. Allow us to use applications and components that are already part of Android System – start activities – start services.
Android Application -Architecture.
Intents and Broadcast Receivers
Lecture 2: Android Concepts
CS499 – Mobile Application Development
Programming with Android:
Broadcast receivers.
Linking Activities using Intents
CS434/534: Topics in Networked (Networking) Systems Mobile System: Android Component Composition/ Inter-process Communication (IPC) Yang (Richard) Yang.
Notifications and Services
Mobile Software Development for Android - I397
Mobile Software Development Framework: Android
Android Programming Lecture 9
Developing Android Services
Mobile Software Development Framework: Android
Android Network Layer; Location Management
Activities and Intents
Activities and Intents
Android Developer Fundamentals V2 Lesson 5
It is used to Start an Activity Start a Service Deliver a Broadcast
Lecture 2: Android Concepts
Mobile Programming Broadcast Receivers.
Presentation transcript:

1 Mobile Software Development Framework: Android IPC; Mobile Push Notification 10/16/2012 Y. Richard Yang

2 Outline r Admin r Android Inter-process communications r Mobile push notification

3 Admin. r Schedule for the rest of semester

Recap: Event Handler Execution 4 r Event handler (EH) executed by the main/UI thread’s Looper r Slow EH blocks event processing r Guidelines m Notify user m Incremental update m Short/non- blocking handler, real processing offloaded to other thread UI events system events message Looper UI (main) thread

Recap: Background/UI Contention 5 public class LoadingScreen extends Activity implements Runnable public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.loading); // start a new thread to load Thread thread = new Thread(this); thread.start(); } public void run(){ longRunningTask(); setContentView(R.layout.main); } … } Conflict with UI thread

Recap: Android Handler 6 Background thread sends msg through handler to UI thread, who processes the msg

Recap: Fixing LoadingScreen 7 public class LoadingScreen extends Activity implements Runnable { private Handler mHandler = new Handler(); // UI public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.loading); // start a new thread to load Thread thread = new Thread(this); thread.start(); } public void run(){ longTask(); mHandler.post(mSetFinalViewTask); } private Runnable mSetFinalViewTask = new Runnable() { public void run() { setContentView(R.layout.main); } }; } Conflict with UI thread

8 Recap: Inter-Process Communications (IPC) r Objective: reuse existing data and services among Android components

9 Recap: Inter-Process Communications (IPC) Component Activity Component Service Component Broadcast Receiver startActivity() startActivityForResult() startService() bindService() broadcastIntent()

Recap: Intent Data Structure r Primary pieces of info in an Intent m Action: The general action to be performed ACTION_VIEW, ACTION_DIAL, ACTION_EDIT, … Your own definition of strings m Data: a URI tel:123 content://contacts/people/1 hotel://name/Omni_New_Haven r Other attributes m Category m Type (MIME type) m Component (class name) m Extras (key-value store) 10 scheme host path

Explicit Intent 11 Yelp Map App class: MapActivity To: MapActivity.class Only the specified activity receives this message

Declare Activity in Manifest 12 r Make sure AndroidManifest.xml announces activities that can be started <application > <activity android:name=".IntentController” android:label="IntentController" > <activity android:name=".TipCal" android:label="TipCal" > Shown in Launcher Announce class See IntentController

Intent Resolution: Explicit Intent 13 public class IntentController extends Activity { /** Called when the activity is first created. public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.intentcontroller); // launch tip cal button Button tipBtn = (Button) findViewById(R.id.tipButton); tipBtn.setOnClickListener(new View.OnClickListener() public void onClick(View v) { Intent tipIntent = new Intent(IntentController.this, TipCal.class); startActivity(tipIntent); } }); class name Context start activity

StartActivity for Result: Caller 14 private void startGame() { Intent launchGame = new Intent(this, CoolGameA.class); // passing information to launched activity launchGame.putExtra("userName", userName); launchGame.putExtra("userScore", userScore); startActivityForResult(launchGame, PLAY_GAME); }

StartActivity for Result: Called 15 public class CoolGameA extends Activity { private TextView tv2; int previousScore, score; String user; public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.game); tv2 = (TextView) findViewById(R.id.game_text); //Get the intent that started this activity to fetch passed info Intent i = getIntent(); //returns [] if not initialized by calling activity user = i.getStringExtra("userName"); //returns -1 if not initialized by calling activity previousScore = i.getIntExtra("userScore", -1); tv2.setText(user + ":" + previousScore); doSessionWithInput(user, previousScore);

StartActivity for Result: Callee 16 //change values for an example of return score = previousScore - 41; //setup button listener Button startButton = (Button) findViewById(R.id.end_game); startButton.setOnClickListener(new View.OnClickListener() { public void onClick(View view) { //return information to calling activity Intent i = getIntent(); i.putExtra("returnScore", score); i.putExtra("returnName", user); setResult(RESULT_OK, i); finish(); } }); }

StartActivity for Result: Caller 17 private void startGame() { Intent launchGame = new Intent(this, CoolGameA.class); // passing information to launched activity launchGame.putExtra("userName", userName); launchGame.putExtra("userScore", userScore); startActivityForResult(launchGame, PLAY_GAME); protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == PLAY_GAME && resultCode == RESULT_OK) { userName = data.getExtras().getString(”returnName"); userScore = data.getExtras().getInt(“returnScore"); // show it has changed tv.setText(userName + ":" + userScore); } super.onActivityResult(requestCode, resultCode, data); }

Explicit Intent: Start Service 18 public class PlayMusicService extends Service { public void onCreate() { super.onCreate(); } public int onStartCommand(Intent intent, int flags, int startId) { play_music(); return 1; } private void play_music() { while (true) { play_music_note(currentIndex); currentIndex++; } } // end of play_music

Discussion r Problem of explicit intent 19

20 Outline r Admin r Android Inter-process communications m Intent data structure m Explicit intent m Implicit intent

Intent Resolution: Implicit Intent r Intent does not specify exact class to run m Info in the Intent used by the system to determine the best component, at run time, to handle the intent 21

Implicit Intents 22 Yelp Browser A Handles Action: VIEW Implicit Intent Action: VIEW

Implicit Intents 23 Yelp Browser B Browser A Handles Action: VIEW Implicit Intent Action: VIEW

Intent Filter r Problem: how to know what an Activity/Service can handle? r Solution: Activities/Services/Receivers declare what they can/want to receive in Intent filter 24 action category data

Intent Filter: Example r AndroidManifest.xml file for com.android.browser 25 String action = "android.intent.action.VIEW"; Uri data = Uri.parse(" Intent myIntent = new Intent(action, data); startActivity(myIntent);

Implicit Start Activity 26 public class IntentController extends Activity { /** Called when the activity is first created. public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.intentcontroller); // launch dial button Button dialBtn = (Button) findViewById(R.id.dialButton); dialBtn.setOnClickListener(new View.OnClickListener() public void onClick(View v) { String action = "android.intent.action.DIAL"; String phno = "tel: "; Uri data = Uri.parse(phno); Intent dialIntent = new Intent(action, data); startActivity(tipIntent); } }); data action See IntentController

A Design Template: Provider 27

A Design Template: Provider public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Intent intent = getIntent(); // why am I called String action = intent.getAction(); Uri data = intent.getdata(); String hotelName = data.getPath(); // do the booking setResult(RESULT_OK); finish(); }

A Design Template: Invoker 29 String action = “com.hotelapp.ACTION_BOOK"; String hotel = “hotel://name/“ + selectedHotel; Uri data = Uri.parse(hotel); Intent bookingIntent = new Intent(action, data); startActivityForResults(bookingIntent, requestCode);

30 Outline r Admin r Android Inter-process communications m Intent data structure m Explicit intent m Implicit intent m Content provider as target of intent

Content Provider r Enable uniformed API for sharing data across applications m E.g., Address book, photo gallery r Each provider can expose its data as a simple table on a database model m Query, delete, update, and insert rows 31

Content Provider and Intent r Each content provider exposes a public URI that uniquely identifies its data set: m android.provider.Contacts.Phones.CONTENT_URI android.provider.Contacts.Photos.CONTENT_URI android.provider.CallLog.Calls.CONTENT_URI android.provider.Calendar.CONTENT_URI r A content consumer declares access requirement m 32

Content Consumer private void pickContact() { // Create an intent to "pick" a contact, as defined by the content provider URI Intent intent = new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI); startActivityForResult(intent, PICK_CONTACT_REQUEST); protected void onActivityResult(int requestCode, int resultCode, Intent data) { // If the request went well (OK) and the request was PICK_CONTACT_REQUEST if (resultCode == Activity.RESULT_OK && requestCode == PICK_CONTACT_REQUEST) { // Perform a query to the contact's content provider for the contact's name Cursor cursor = getContentResolver().query(data.getData(), new String[] {Contacts.DISPLAY_NAME}, null, null, null); if (cursor.moveToFirst()) { // True if the cursor is not empty int columnIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME); String name = cursor.getString(columnIndex); // Do something with the selected contact's name... } } } 33

34 Outline r Admin r Android Inter-process communications m Intent data structure m Explicit intent m Implicit intent m Content provider as target of intent m Broadcast intent

Broadcast Intents r Multiple components may be interested in an event/update m e.g., system event such as an incoming phone call, battery level low, network cell changes m receives notification by declaring a broadcast receiver 35

Intent and Broadcast: Sender String action = "edu.yale.cs434.RUN"; Intent cs434BroadcastIntent = new Intent(action); cs434BroadcastIntent.putExtra("message", "Wake up."); sendBroadcast(cs434BroadcastIntent); 36 Example: IntentController

Intent and Broadcast: Receiver 37

Intent, Broadcast, Receiver, Notification public class CS434BroadcastReceiver extends BroadcastReceiver { public static final String CUSTOM_INTENT = "edu.yale.cs434.RUN"; // Display an alert that we've received a public void onReceive(Context context, Intent intent) { if (intent.getAction().equals(CUSTOM_INTENT)) { String message = (String)intent.getExtras().get("message"); CharSequence text = "Got intent " + CUSTOM_INTENT + " with " + message; int duration = Toast.LENGTH_SHORT; Toast mToast = Toast.makeText(context, text, duration); mToast.show(); } // end of if } // end of onReceive } 38

Intent, Broadcast, Receiver, Notification public class MyPhoneReceiver extends BroadcastReceiver public void onReceive(Context context, Intent intent) { Bundle extras = intent.getExtras(); if (extras != null) { String state = extras.getString(TelephonyManager.EXTRA_STATE); if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) { String phoneNumber = extras.getString(TelephonyManager.EXTRA_INCOMING_NUMBER); Toast.makeText(context, "Incoming number: "+phoneNumber, Toast.LENGTH_LONG).show(); } // end of if } // end of onReceive } 39

Discussion: Downside of Implicit Intent 40

Real Example App: iMDb 41

Example App 42 Showtime Search Results UI IMDb App Handles Actions: willUpdateShowtimes, showtimesNoLocationError Implicit Intent Action: willUpdateShowtimes

43 Vulnerability: Eavedropping Showtime Search Malicious Receiver IMDb App Handles Action: willUpdateShowtimes, showtimesNoLocationError Implicit Intent Action: willUpdateShowtimes Eavesdropping App Sending Implicit Intents makes communication public

44 Vulnerability: Spoofing Malicious Component Results UI IMDb App Handles Action: willUpdateShowtimes, showtimesNoLocationError Action: showtimesNoLocationError Malicious Injection App Receiving Implicit Intents makes the component public

45 Vulnerability: Man-in-the-Middle Showtime Search Results UI IMDb App Handles Action: willUpdateShowtimes, showtimesNoLocation Error Malicious Receiver Handles Action: willUpdateShowtimes, showtimesNoLocationError Man-in-the-Middle App Action: willUpdateShowtimes Action: showtimesNoLocation Error

46 Vulnerability: Spoofing

47 Vulnerability: Permission re-Delegation r Permission re-delegation occurs when an application without a permission gains additional privileges through another application

48 Permission System API Malware Deputy toggleWifi() Permission System toggleWifi()

49 Permission Redelegation Malware API Deputy Malware toggleWifi() pressButton(0) Permission System

Permission Redelegation: Reality Check 50 r Analyzed manifests of 5 system applications r Built attacks using 5 of the 16 system apps r Found 15 attacks in the 5 applications

More Examples of Attack r DeskClock: m Start an internal service m Tell it to infinitely vibrate with a WAKE_LOCK on r Phone: m Trigger the “phone call answered” message receiver m Phone call will be silenced, vibrate cancelled r More details see schedule page links 51

More Info on IPC r Intent is a high level abstraction r For more details on implementation of Intent, see a set of slides on binder 52 Binder AIDL Intent More abstract

Progress So Far r Issue (responsiveness): slow UI is a sin m Solution: event listener gives tasks to background thread(s) m Issue: Background threads may need to update UI m Solution: Handler/AsyncTask so that one thread can delegate tasks to to another thread r Issue (composability): reusability is highly desired m Solution: Intent 53

Problem: Accessing Data in Cloud r A typical setting is that a device accesses data in the cloud r Challenge: How do you keep data on a device fresh? 54

Solution 1: Polling r Simple to implement r Device periodically asks server for new data/update r Appropriate for content that changes constantly m Stock Quotes, News Headlines  Problems? 55

Impact of Polling on Battery r Baseline: ~5-8 mA r Network: ~ mA m Tx more expensive than Rx r Assume radio stays on for 10 sec. m Energy per poll: ~0.50 mAh m 5 min frequency: ~144 mAh / day r Droid 2 total battery: 1400 mAh 56 Source: Android development team at Google

Solution 2: Push Notification r Design issue: Who to push to client device? m Option 1: each app does it individually m Option 2: a shared push service 57

Push Service r A single persistent connection from device to Cloud provider r Multiple application providers push to a cloud provider r Cloud provider pushes to a device using the persistent connection r Two examples m Apple Push Notification Service (APNS) m Google Cloud Messaging (GCM) 58

Design Issues of a Push Service r How to do authorization? m Do not want to allow arbitrary app to push to a device r What to push? m Option 1: Just push signal (data available) and then app fetches from app server or push data m Option 2: push real data 59

Apple Push Notification Service 60 r iOS device maintains a persistent TCP connection to a Apple Push Notification Server(APNS) A push notification from a provider to a client application Multi-providers to multiple devices

Apple Push Notification: Device Token 61 r Device token is analogous to a phone number m Contains information that enables APNs to locate the device m Client app needs to provide the token to its provider m Device token should be requested and passed to providers every time your application launches

Apple Push Notification Data r Each push notification carries a payload m 256 bytes maximum m Best effort delivery r App provider provides a JSON dictionary object, which contains another dictionary identified by the key aps r aps specifies the following actions An alert message to display to the user A number to badge the application icon with A sound to play 62

APNS Example: Client (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 2. { 3. // Let the device know we want to receive push notifications 4. [[UIApplication sharedApplication] registerForRemoteNotificationTypes: 5. (UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)]; return YES; 8. } 9. - (void)application:(UIApplication*)application didReceiveRemoteNotification:(NSDictionary*)userInfo 10. {//userInfo contains the notification 11. notification: userInfo); 12. } (void)application:(UIApplication*)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData*)deviceToken 14. { 15. token is: deviceToken); 16. }

APNS Example: Server $devicetoken ='f05571e4be60a4e11524d76e f430522fb470c46fc6810fffb07af7’; 2. // Put your private key's passphrase here: 3. $passphrase = 'PushChat'; 4. // Put your alert message here: 5. $message = ’CS434: my first push notification!'; 1. $ctx = stream_context_create(); 2. Stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem'); 3. stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase); 4. // Open a connection to the APNS server 5. $fp = stream_socket_client( 6. 'ssl://gateway.sandbox.push.apple.com:2195', $err, 7. $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx); 8. if (!$fp) 9. exit("Failed to connect: $err $errstr". PHP_EOL); 10. echo 'Connected to APNS'. PHP_EOL;

APNS Example: Server (cont’) // Create the payload body 17. $body['aps'] = array( 18. 'alert' => $message, 19. 'sound' => 'default' 20. ); 21. // Encode the payload as JSON 22. $payload = json_encode($body); 23. // Build the binary notification 24. $msg = chr(0). pack('n', 32). pack('H*', $deviceToken). pack('n', strlen($payload)). $payload; 25. // Send it to the server 26. $result = fwrite($fp, $msg, strlen($msg)); 27. if (!$result) 28. echo 'Message not delivered'. PHP_EOL; 29. else 30. echo 'Message successfully delivered'. PHP_EOL; 31. // Close the connection to the server 32. fclose($fp);

Google Cloud Messaging r Very similar to APNS 66 GCM Servers See for detailed steps

GCM Flow r Enabling cloud to device messaging m App (on device) registers with Google, gets registration ID m App sends registration ID to its App Server r Per message m App Server sends (authenticated) message to Google m Google sends message to device, which sends to registered app r Disabling cloud to device messaging m App can unregister ID, e.g., when user no longer wants push 67

GCM Flow r Enabling cloud to device messaging m App (on device) registers with Google, gets registration ID 68 public class MyActivity extends Activity { public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); GCMRegistrar.checkDevice(this); GCMRegistrar.checkManifest(this); final String regId = GCMRegistrar.getRegistrationId(this); if (regId.equals("")) { GCMRegistrar.register(this, SENDER_ID); } else { Log.v(TAG, "Already registered"); } … } google/gcm/gs.html

GCM Flow r Enabling cloud to device messaging m App (on device) registers with Google, gets registration ID m App sends registration ID to its App Server r Per message m App Server sends (authenticated) message to Google m Google sends message to device r Disabling cloud to device messaging m App can unregister ID, e.g., when user no longer wants push 69

Android Code: Registration to C2DM // Use the Intent API to get a registration ID // Registration ID is compartmentalized per app/device Intent regIntent = new Intent(“com.google.android.c2dm.intent.REGISTER”); // Identify your app regIntent.putExtra(“app”, PendingIntent.getBroadcast(this, 0, new Intent(), 0); // Identify role account server will use to send regIntent.putExtra(“sender”, OfSender); // Start the registration process startService(regIntent); 70

Receiving Registration ID 71 // Registration ID received via an Intent public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (“…REGISTRATION”.equals(action)) { handleRegistration(context, intent); } private void handleRegistration(Context context, Intent intent){ String id = intent.getExtra(“registration_id”); if ((intent.getExtra(“error”) != null) { // Registration failed. Try again later, with backoff. } else if (id != null) { // Send the registration ID to the app’s server. // Be sure to do this in a separate thread. }

Receiving Registration ID r App receives the ID as an Intent m com.google.android.c2dm.intent.REGISTRATION r App should send this ID to its server r Service may issue new registration ID at any time r App will receive REGISTRATION Intent broadcast r App must update server with new ID 72