Add API demo for LocalBroadcastManager.

Change-Id: Iee1e1189c579ab287718d138916448a02a833e44
diff --git a/samples/ApiDemos/AndroidManifest.xml b/samples/ApiDemos/AndroidManifest.xml
index 1657878..36fe4c3 100644
--- a/samples/ApiDemos/AndroidManifest.xml
+++ b/samples/ApiDemos/AndroidManifest.xml
@@ -36,14 +36,7 @@
     <!-- For android.media.audiofx.Visualizer -->
     <uses-permission android:name="android.permission.RECORD_AUDIO" />
 
-    <uses-sdk android:minSdkVersion="7" android:targetSdkVersion="11" />
-
-    <!-- The smallest screen this app works on is a phone.  The app will
-         scale its UI to larger screens but doesn't make good use of them
-         so allow the compatibility mode button to be shown (mostly because
-         this is just convenient for testing). -->
-    <supports-screens android:requiresSmallestWidthDp="320"
-            android:compatibleWidthLimitDp="480" />
+    <uses-sdk android:minSdkVersion="3" android:targetSdkVersion="3" />
 
     <!-- We will request access to the camera, saying we require a camera
          of some sort but not one with autofocus capability. -->
diff --git a/samples/Support4Demos/AndroidManifest.xml b/samples/Support4Demos/AndroidManifest.xml
index 5c74954..4719268 100644
--- a/samples/Support4Demos/AndroidManifest.xml
+++ b/samples/Support4Demos/AndroidManifest.xml
@@ -208,5 +208,15 @@
         <provider android:name=".app.LoaderThrottleSupport$SimpleProvider"
                   android:authorities="com.example.android.apis.supportv4.app.LoaderThrottle" />
 
+        <activity android:name=".content.LocalServiceBroadcaster"
+                android:label="@string/local_service_broadcaster">
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+                <category android:name="com.example.android.supportv4.SUPPORT4_SAMPLE_CODE" />
+            </intent-filter>
+        </activity>
+        <service android:name=".content.LocalServiceBroadcaster$LocalService"
+                android:stopWithTask="true" />
+
     </application>
 </manifest>
diff --git a/samples/Support4Demos/res/layout/local_service_broadcaster.xml b/samples/Support4Demos/res/layout/local_service_broadcaster.xml
new file mode 100644
index 0000000..f01120d
--- /dev/null
+++ b/samples/Support4Demos/res/layout/local_service_broadcaster.xml
@@ -0,0 +1,46 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2011 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<!-- Demonstrates starting and stopping a local service.
+     See corresponding Java code com.android.sdk.app.LocalSerice.java. -->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:padding="4dip"
+    android:gravity="center_horizontal"
+    android:layout_width="match_parent" android:layout_height="match_parent">
+
+    <TextView
+        android:layout_width="match_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:paddingBottom="4dip"
+        android:text="@string/local_service_broadcaster_msg"/>
+
+    <Button android:id="@+id/start"
+        android:layout_width="wrap_content" android:layout_height="wrap_content"
+        android:text="@string/start_service">
+        <requestFocus />
+    </Button>
+
+    <Button android:id="@+id/stop"
+        android:layout_width="wrap_content" android:layout_height="wrap_content"
+        android:text="@string/stop_service">
+    </Button>
+
+    <TextView android:id="@+id/callback"
+        android:layout_width="match_parent" android:layout_height="wrap_content"
+        android:layout_weight="0"
+        android:gravity="center_horizontal" android:paddingTop="4dip"/>
+
+</LinearLayout>
diff --git a/samples/Support4Demos/res/values/strings.xml b/samples/Support4Demos/res/values/strings.xml
index fa437db..5fa5af7 100644
--- a/samples/Support4Demos/res/values/strings.xml
+++ b/samples/Support4Demos/res/values/strings.xml
@@ -93,4 +93,11 @@
 
     <string name="loader_throttle_support">Loader/Throttle</string>
 
+    <string name="local_service_broadcaster">Content/Local Service Broadcaster</string>
+
+    <string name="local_service_broadcaster_msg">Demonstrates use of LocalBroadcastManager
+        to communicate from a Service to an Activity.</string>
+    <string name="start_service">Start Service</string>
+    <string name="stop_service">Stop Service</string>
+
 </resources>
diff --git a/samples/Support4Demos/src/com/example/android/supportv4/content/LocalServiceBroadcaster.java b/samples/Support4Demos/src/com/example/android/supportv4/content/LocalServiceBroadcaster.java
new file mode 100644
index 0000000..d4dc8e1
--- /dev/null
+++ b/samples/Support4Demos/src/com/example/android/supportv4/content/LocalServiceBroadcaster.java
@@ -0,0 +1,166 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.supportv4.content;
+
+import com.example.android.supportv4.R;
+
+import android.app.Activity;
+import android.app.Service;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.support.v4.content.LocalBroadcastManager;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.TextView;
+
+/**
+ * Demonstrates the use of a LocalBroadcastManager to easily communicate
+ * data from a service to any other interested code.
+ */
+public class LocalServiceBroadcaster extends Activity {
+    static final String ACTION_STARTED = "com.example.android.supportv4.STARTED";
+    static final String ACTION_UPDATE = "com.example.android.supportv4.UPDATE";
+    static final String ACTION_STOPPED = "com.example.android.supportv4.STOPPED";
+
+    LocalBroadcastManager mLocalBroadcastManager;
+    BroadcastReceiver mReceiver;
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.local_service_broadcaster);
+
+        // This is where we print the data we get back.
+        final TextView callbackData = (TextView)findViewById(R.id.callback);
+
+        // Put in some initial text.
+        callbackData.setText("No broadcast received yet");
+
+        // We use this to send broadcasts within our local process.
+        mLocalBroadcastManager = LocalBroadcastManager.getInstance(this);
+
+        // We are going to watch for interesting local broadcasts.
+        IntentFilter filter = new IntentFilter();
+        filter.addAction(ACTION_STARTED);
+        filter.addAction(ACTION_UPDATE);
+        filter.addAction(ACTION_STOPPED);
+        mReceiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                if (intent.getAction().equals(ACTION_STARTED)) {
+                    callbackData.setText("STARTED");
+                } else if (intent.getAction().equals(ACTION_UPDATE)) {
+                    callbackData.setText("Got update: " + intent.getIntExtra("value", 0));
+                } else if (intent.getAction().equals(ACTION_STOPPED)) {
+                    callbackData.setText("STOPPED");
+                }
+            }
+        };
+        mLocalBroadcastManager.registerReceiver(mReceiver, filter);
+
+        // Watch for button clicks.
+        Button button = (Button)findViewById(R.id.start);
+        button.setOnClickListener(mStartListener);
+        button = (Button)findViewById(R.id.stop);
+        button.setOnClickListener(mStopListener);
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+        mLocalBroadcastManager.unregisterReceiver(mReceiver);
+    }
+
+    private OnClickListener mStartListener = new OnClickListener() {
+        public void onClick(View v) {
+            startService(new Intent(LocalServiceBroadcaster.this, LocalService.class));
+        }
+    };
+
+    private OnClickListener mStopListener = new OnClickListener() {
+        public void onClick(View v) {
+            stopService(new Intent(LocalServiceBroadcaster.this, LocalService.class));
+        }
+    };
+
+    public static class LocalService extends Service {
+        LocalBroadcastManager mLocalBroadcastManager;
+        int mCurUpdate;
+
+        static final int MSG_UPDATE = 1;
+
+        Handler mHandler = new Handler() {
+            @Override
+            public void handleMessage(Message msg) {
+                switch (msg.what) {
+                    case MSG_UPDATE: {
+                        mCurUpdate++;
+                        Intent intent = new Intent(ACTION_UPDATE);
+                        intent.putExtra("value", mCurUpdate);
+                        mLocalBroadcastManager.sendBroadcast(intent);
+                        Message nmsg = mHandler.obtainMessage(MSG_UPDATE);
+                        mHandler.sendMessageDelayed(nmsg, 1000);
+                    } break;
+                    default:
+                        super.handleMessage(msg);
+                }
+            }
+        };
+
+        @Override
+        public void onCreate() {
+            super.onCreate();
+            mLocalBroadcastManager = LocalBroadcastManager.getInstance(this);
+        }
+
+        @Override
+        public int onStartCommand(Intent intent, int flags, int startId) {
+            // Tell any local interested parties about the start.
+            mLocalBroadcastManager.sendBroadcast(new Intent(ACTION_STARTED));
+
+            // Prepare to do update reports.
+            mHandler.removeMessages(MSG_UPDATE);
+            Message msg = mHandler.obtainMessage(MSG_UPDATE);
+            mHandler.sendMessageDelayed(msg, 1000);
+            return Service.START_STICKY;
+        }
+
+        @Override
+        public void onDestroy() {
+            super.onDestroy();
+
+            // Tell any local interested parties about the stop.
+            mLocalBroadcastManager.sendBroadcast(new Intent(ACTION_STOPPED));
+
+            // Stop doing updates.
+            mHandler.removeMessages(MSG_UPDATE);
+        }
+
+        @Override
+        public IBinder onBind(Intent intent) {
+            return null;
+        }
+    }
+}