Update sample code for new service semantics.
diff --git a/samples/ApiDemos/res/layout/service_start_arguments_controller.xml b/samples/ApiDemos/res/layout/service_start_arguments_controller.xml
index f10a2c3..19b7498 100644
--- a/samples/ApiDemos/res/layout/service_start_arguments_controller.xml
+++ b/samples/ApiDemos/res/layout/service_start_arguments_controller.xml
@@ -43,5 +43,15 @@
         android:text="@string/start3_service">
     </Button>
 
+    <Button android:id="@+id/startfail"
+        android:layout_width="wrap_content" android:layout_height="wrap_content" 
+        android:text="@string/startfail_service">
+    </Button>
+
+    <Button android:id="@+id/kill"
+        android:layout_width="wrap_content" android:layout_height="wrap_content" 
+        android:text="@string/kill_process">
+    </Button>
+
 </LinearLayout>
 
diff --git a/samples/ApiDemos/res/values/strings.xml b/samples/ApiDemos/res/values/strings.xml
index fa4e61c..a1f2000 100644
--- a/samples/ApiDemos/res/values/strings.xml
+++ b/samples/ApiDemos/res/values/strings.xml
@@ -117,9 +117,6 @@
     <string name="remote_service_disconnected">Disconnected from remote service</string>
     <string name="remote_call_failed">Failure calling remote service</string>
 
-    <string name="service_arguments_started">"Started with arguments: "</string>
-    <string name="service_arguments_stopped">Finished arguments,
-        stopping.</string>
     <string name="service_start_arguments_label">Sample Service Start Arguments
     </string>
 
@@ -130,10 +127,13 @@
         service can be started with arguments, and run until all arguments are
         processed.
     </string>
-    <string name="start1_service">Start with \"One\"</string>
-    <string name="start2_service">Start with \"Two\"</string>
-    <string name="start3_service">Start with \"Three\"</string>
-
+    <string name="start1_service">Start \"One\" no redeliver</string>
+    <string name="start2_service">Start \"Two\" no redeliver</string>
+    <string name="start3_service">Start \"Three\" w/redeliver</string>
+    <string name="startfail_service">Start failed delivery</string>
+    <string name="service_created">Service created.</string>
+    <string name="service_destroyed">Service destroyed.</string>
+    
     <string name="one_shot_received">The one-shot alarm has gone off</string>
     <string name="repeating_received">The repeating alarm has gone off</string>
 
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/ServiceStartArguments.java b/samples/ApiDemos/src/com/example/android/apis/app/ServiceStartArguments.java
index 5e16158..f4f9af1 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/ServiceStartArguments.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/ServiceStartArguments.java
@@ -27,6 +27,7 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
+import android.os.Process;
 import android.util.Log;
 import android.widget.Toast;
 
@@ -41,9 +42,12 @@
  * happen in the service.  This is generally how background services should
  * interact with the user, rather than doing something more disruptive such as
  * calling startActivity().
+ * 
+ * <p>For applications targeting Android 1.5 or beyond, you may want consider
+ * using the android.app.IntentService class, which takes care of all the
+ * work of creating the extra thread and dispatching commands to it.
  */
-public class ServiceStartArguments extends Service
-{
+public class ServiceStartArguments extends Service {
     private NotificationManager mNM;
     private Intent mInvokeIntent;
     private volatile Looper mServiceLooper;
@@ -58,16 +62,22 @@
         public void handleMessage(Message msg)
         {
             Bundle arguments = (Bundle)msg.obj;
-            String txt = getResources()
-                    .getString(R.string.service_arguments_started);
-            txt = txt + arguments.getString("name");
         
-            Log.i("ServiceStartArguments", "Message: " + msg + ", " + txt);
+            String txt = arguments.getString("name");
+            
+            Log.i("ServiceStartArguments", "Message: " + msg + ", "
+                    + arguments.getString("name"));
         
-            showNotification();
+            if ((msg.arg2&Service.START_FLAG_REDELIVERY) == 0) {
+                txt = "New cmd #" + msg.arg1 + ": " + txt;
+            } else {
+                txt = "Re-delivered #" + msg.arg1 + ": " + txt;
+            }
+            
+            showNotification(txt);
         
-        // Normally we would do some work here...  for our sample, we will
-        // just sleep for 10 seconds.
+            // Normally we would do some work here...  for our sample, we will
+            // just sleep for 5 seconds.
             long endTime = System.currentTimeMillis() + 5*1000;
             while (System.currentTimeMillis() < endTime) {
                 synchronized (this) {
@@ -78,6 +88,8 @@
                 }
             }
         
+            hideNotification();
+            
             Log.i("ServiceStartArguments", "Done with #" + msg.arg1);
             stopSelf(msg.arg1);
         }
@@ -88,14 +100,19 @@
     public void onCreate() {
         mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
 
+        Toast.makeText(this, R.string.service_created,
+                Toast.LENGTH_SHORT).show();
+        
         // This is who should be launched if the user selects our persistent
         // notification.
         mInvokeIntent = new Intent(this, ServiceStartArgumentsController.class);
 
         // Start up the thread running the service.  Note that we create a
         // separate thread because the service normally runs in the process's
-        // main thread, which we don't want to block.
-        HandlerThread thread = new HandlerThread("ServiceStartArguments");
+        // main thread, which we don't want to block.  We also make it
+        // background priority so CPU-intensive work will not disrupt our UI.
+        HandlerThread thread = new HandlerThread("ServiceStartArguments",
+                Process.THREAD_PRIORITY_BACKGROUND);
         thread.start();
         
         mServiceLooper = thread.getLooper();
@@ -103,25 +120,45 @@
     }
 
     @Override
-    public void onStart(Intent intent, int startId) {
+    public int onStartCommand(Intent intent, int flags, int startId) {
         Log.i("ServiceStartArguments",
                 "Starting #" + startId + ": " + intent.getExtras());
         Message msg = mServiceHandler.obtainMessage();
         msg.arg1 = startId;
+        msg.arg2 = flags;
         msg.obj = intent.getExtras();
         mServiceHandler.sendMessage(msg);
         Log.i("ServiceStartArguments", "Sending: " + msg);
+        
+        // For the start fail button, we will simulate the process dying
+        // for some reason in onStartCommand().
+        if (intent.getBooleanExtra("fail", false)) {
+            // Don't do this if we are in a retry... the system will
+            // eventually give up if we keep crashing.
+            if ((flags&START_FLAG_RETRY) == 0) {
+                // Since the process hasn't finished handling the command,
+                // it will be restarted with the command again, regardless of
+                // whether we return START_REDELIVER_INTENT.
+                Process.killProcess(Process.myPid());
+            }
+        }
+        
+        // Normally we would consistently return one kind of result...
+        // however, here we will select between these two, so you can see
+        // how they impact the behavior.  Try killing the process while it
+        // is in the middle of executing the different commands.
+        return intent.getBooleanExtra("redeliver", false)
+                ? START_REDELIVER_INTENT : START_NOT_STICKY;
     }
 
     @Override
     public void onDestroy() {
         mServiceLooper.quit();
 
-        // Cancel the persistent notification.
-        mNM.cancel(R.string.service_arguments_started);
+        hideNotification();
 
         // Tell the user we stopped.
-        Toast.makeText(ServiceStartArguments.this, R.string.service_arguments_stopped,
+        Toast.makeText(ServiceStartArguments.this, R.string.service_destroyed,
                 Toast.LENGTH_SHORT).show();
     }
 
@@ -133,10 +170,7 @@
     /**
      * Show a notification while this service is running.
      */
-    private void showNotification() {
-        // In this sample, we'll use the same text for the ticker and the expanded notification
-        CharSequence text = getText(R.string.service_arguments_started);
-
+    private void showNotification(String text) {
         // Set the icon, scrolling text and timestamp
         Notification notification = new Notification(R.drawable.stat_sample, text,
                 System.currentTimeMillis());
@@ -149,9 +183,16 @@
         notification.setLatestEventInfo(this, getText(R.string.service_start_arguments_label),
                        text, contentIntent);
 
+        // We show this for as long as our service is processing a command.
+        notification.flags |= Notification.FLAG_ONGOING_EVENT;
+        
         // Send the notification.
         // We use a string id because it is a unique number.  We use it later to cancel.
-        mNM.notify(R.string.service_arguments_started, notification);
+        mNM.notify(R.string.service_created, notification);
+    }
+    
+    private void hideNotification() {
+        mNM.cancel(R.string.service_created);
     }
 }
 
diff --git a/samples/ApiDemos/src/com/example/android/apis/app/ServiceStartArgumentsController.java b/samples/ApiDemos/src/com/example/android/apis/app/ServiceStartArgumentsController.java
index 2c53ff4..9d79e2e 100644
--- a/samples/ApiDemos/src/com/example/android/apis/app/ServiceStartArgumentsController.java
+++ b/samples/ApiDemos/src/com/example/android/apis/app/ServiceStartArgumentsController.java
@@ -21,14 +21,13 @@
 import android.app.Activity;
 import android.content.Intent;
 import android.os.Bundle;
+import android.os.Process;
 import android.view.View;
 import android.view.View.OnClickListener;
 import android.widget.Button;
 
 import com.example.android.apis.R;
 
-import java.util.HashMap;
-
 /**
  * Example of explicitly starting the {@link ServiceStartArguments}.
  */
@@ -46,26 +45,51 @@
         button.setOnClickListener(mStart2Listener);
         button = (Button)findViewById(R.id.start3);
         button.setOnClickListener(mStart3Listener);
+        button = (Button)findViewById(R.id.startfail);
+        button.setOnClickListener(mStartFailListener);
+        button = (Button)findViewById(R.id.kill);
+        button.setOnClickListener(mKillListener);
     }
 
     private OnClickListener mStart1Listener = new OnClickListener() {
         public void onClick(View v) {
             startService(new Intent(ServiceStartArgumentsController.this,
-                    ServiceStartArguments.class).putExtra("name", "One"));
+                    ServiceStartArguments.class)
+                            .putExtra("name", "One"));
         }
     };
 
     private OnClickListener mStart2Listener = new OnClickListener() {
         public void onClick(View v) {
             startService(new Intent(ServiceStartArgumentsController.this,
-                    ServiceStartArguments.class).putExtra("name", "Two"));
+                    ServiceStartArguments.class)
+                            .putExtra("name", "Two"));
         }
     };
 
     private OnClickListener mStart3Listener = new OnClickListener() {
         public void onClick(View v) {
             startService(new Intent(ServiceStartArgumentsController.this,
-                    ServiceStartArguments.class).putExtra("name", "Three"));
+                    ServiceStartArguments.class)
+                            .putExtra("name", "Three")
+                            .putExtra("redeliver", true));
+        }
+    };
+
+    private OnClickListener mStartFailListener = new OnClickListener() {
+        public void onClick(View v) {
+            startService(new Intent(ServiceStartArgumentsController.this,
+                    ServiceStartArguments.class)
+                            .putExtra("name", "Failure")
+                            .putExtra("fail", true));
+        }
+    };
+
+    private OnClickListener mKillListener = new OnClickListener() {
+        public void onClick(View v) {
+            // This is to simulate the service being killed while it is
+            // running in the background.
+            Process.killProcess(Process.myPid());
         }
     };
 }