1eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn/*
2eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn * Copyright (C) 2009 The Android Open Source Project
3eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn *
4eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn * Licensed under the Apache License, Version 2.0 (the "License");
5eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn * you may not use this file except in compliance with the License.
6eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn * You may obtain a copy of the License at
7eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn *
8eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn *      http://www.apache.org/licenses/LICENSE-2.0
9eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn *
10eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn * Unless required by applicable law or agreed to in writing, software
11eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn * distributed under the License is distributed on an "AS IS" BASIS,
12eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn * See the License for the specific language governing permissions and
14eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn * limitations under the License.
15eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn */
16eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn
17eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackbornpackage com.example.android.apis.app;
18eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn
19579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackbornimport android.app.Activity;
20eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackbornimport android.app.Notification;
21eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackbornimport android.app.NotificationManager;
22eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackbornimport android.app.PendingIntent;
23eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackbornimport android.app.Service;
24eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackbornimport android.content.Intent;
25579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackbornimport android.os.Bundle;
26eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackbornimport android.os.IBinder;
27eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackbornimport android.util.Log;
28579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackbornimport android.view.View;
29579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackbornimport android.view.View.OnClickListener;
30579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackbornimport android.widget.Button;
31eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn
32eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackbornimport java.lang.reflect.InvocationTargetException;
33eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackbornimport java.lang.reflect.Method;
34eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn
35eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn// Need the following import to get access to the app resources, since this
36eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn// class is in a sub-package.
37eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackbornimport com.example.android.apis.R;
38eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn
39eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn/**
40eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn * This is an example of implementing an application service that can
41eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn * run in the "foreground".  It shows how to code this to work well by using
42eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn * the improved Android 2.0 APIs when available and otherwise falling back
43eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn * to the original APIs.  Yes: you can take this exact code, compile it
44eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn * against the Android 2.0 SDK, and it will against everything down to
45eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn * Android 1.0.
46eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn */
47eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackbornpublic class ForegroundService extends Service {
48eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn    static final String ACTION_FOREGROUND = "com.example.android.apis.FOREGROUND";
49eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn    static final String ACTION_BACKGROUND = "com.example.android.apis.BACKGROUND";
50eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn
51579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn // BEGIN_INCLUDE(foreground_compatibility)
528ab4ac232b11ee3eb1130790fdee480a0563bf6eDianne Hackborn    private static final Class<?>[] mSetForegroundSignature = new Class[] {
538ab4ac232b11ee3eb1130790fdee480a0563bf6eDianne Hackborn        boolean.class};
5497d0e8ddb788190be7e68931a50729a4f9ea3993Christian Mehlmauer    private static final Class<?>[] mStartForegroundSignature = new Class[] {
55eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn        int.class, Notification.class};
5697d0e8ddb788190be7e68931a50729a4f9ea3993Christian Mehlmauer    private static final Class<?>[] mStopForegroundSignature = new Class[] {
57eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn        boolean.class};
58eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn
59eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn    private NotificationManager mNM;
608ab4ac232b11ee3eb1130790fdee480a0563bf6eDianne Hackborn    private Method mSetForeground;
61eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn    private Method mStartForeground;
62eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn    private Method mStopForeground;
638ab4ac232b11ee3eb1130790fdee480a0563bf6eDianne Hackborn    private Object[] mSetForegroundArgs = new Object[1];
64eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn    private Object[] mStartForegroundArgs = new Object[2];
65eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn    private Object[] mStopForegroundArgs = new Object[1];
66eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn
678ab4ac232b11ee3eb1130790fdee480a0563bf6eDianne Hackborn    void invokeMethod(Method method, Object[] args) {
688ab4ac232b11ee3eb1130790fdee480a0563bf6eDianne Hackborn        try {
69c8c211a085a97ead0e31011bfcaf56a62b9dcf7bKenny Root            method.invoke(this, args);
708ab4ac232b11ee3eb1130790fdee480a0563bf6eDianne Hackborn        } catch (InvocationTargetException e) {
718ab4ac232b11ee3eb1130790fdee480a0563bf6eDianne Hackborn            // Should not happen.
728ab4ac232b11ee3eb1130790fdee480a0563bf6eDianne Hackborn            Log.w("ApiDemos", "Unable to invoke method", e);
738ab4ac232b11ee3eb1130790fdee480a0563bf6eDianne Hackborn        } catch (IllegalAccessException e) {
748ab4ac232b11ee3eb1130790fdee480a0563bf6eDianne Hackborn            // Should not happen.
758ab4ac232b11ee3eb1130790fdee480a0563bf6eDianne Hackborn            Log.w("ApiDemos", "Unable to invoke method", e);
768ab4ac232b11ee3eb1130790fdee480a0563bf6eDianne Hackborn        }
778ab4ac232b11ee3eb1130790fdee480a0563bf6eDianne Hackborn    }
788ab4ac232b11ee3eb1130790fdee480a0563bf6eDianne Hackborn
79eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn    /**
80eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn     * This is a wrapper around the new startForeground method, using the older
81eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn     * APIs if it is not available.
82eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn     */
83eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn    void startForegroundCompat(int id, Notification notification) {
84eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn        // If we have the new startForeground API, then use it.
85eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn        if (mStartForeground != null) {
86eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn            mStartForegroundArgs[0] = Integer.valueOf(id);
87eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn            mStartForegroundArgs[1] = notification;
888ab4ac232b11ee3eb1130790fdee480a0563bf6eDianne Hackborn            invokeMethod(mStartForeground, mStartForegroundArgs);
89eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn            return;
90eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn        }
91eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn
92eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn        // Fall back on the old API.
938ab4ac232b11ee3eb1130790fdee480a0563bf6eDianne Hackborn        mSetForegroundArgs[0] = Boolean.TRUE;
948ab4ac232b11ee3eb1130790fdee480a0563bf6eDianne Hackborn        invokeMethod(mSetForeground, mSetForegroundArgs);
95eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn        mNM.notify(id, notification);
96eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn    }
97eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn
98eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn    /**
99eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn     * This is a wrapper around the new stopForeground method, using the older
100eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn     * APIs if it is not available.
101eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn     */
102eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn    void stopForegroundCompat(int id) {
103eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn        // If we have the new stopForeground API, then use it.
104eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn        if (mStopForeground != null) {
105eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn            mStopForegroundArgs[0] = Boolean.TRUE;
106c8c211a085a97ead0e31011bfcaf56a62b9dcf7bKenny Root            invokeMethod(mStopForeground, mStopForegroundArgs);
107eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn            return;
108eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn        }
109eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn
110eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn        // Fall back on the old API.  Note to cancel BEFORE changing the
111eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn        // foreground state, since we could be killed at that point.
112eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn        mNM.cancel(id);
1138ab4ac232b11ee3eb1130790fdee480a0563bf6eDianne Hackborn        mSetForegroundArgs[0] = Boolean.FALSE;
1148ab4ac232b11ee3eb1130790fdee480a0563bf6eDianne Hackborn        invokeMethod(mSetForeground, mSetForegroundArgs);
115eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn    }
116eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn
117eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn    @Override
118579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn    public void onCreate() {
119579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn        mNM = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
120579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn        try {
121579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn            mStartForeground = getClass().getMethod("startForeground",
122579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn                    mStartForegroundSignature);
123579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn            mStopForeground = getClass().getMethod("stopForeground",
124579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn                    mStopForegroundSignature);
125c8c211a085a97ead0e31011bfcaf56a62b9dcf7bKenny Root            return;
126579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn        } catch (NoSuchMethodException e) {
127579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn            // Running on an older platform.
128579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn            mStartForeground = mStopForeground = null;
1298ab4ac232b11ee3eb1130790fdee480a0563bf6eDianne Hackborn        }
1308ab4ac232b11ee3eb1130790fdee480a0563bf6eDianne Hackborn        try {
1318ab4ac232b11ee3eb1130790fdee480a0563bf6eDianne Hackborn            mSetForeground = getClass().getMethod("setForeground",
1328ab4ac232b11ee3eb1130790fdee480a0563bf6eDianne Hackborn                    mSetForegroundSignature);
1338ab4ac232b11ee3eb1130790fdee480a0563bf6eDianne Hackborn        } catch (NoSuchMethodException e) {
1348ab4ac232b11ee3eb1130790fdee480a0563bf6eDianne Hackborn            throw new IllegalStateException(
1358ab4ac232b11ee3eb1130790fdee480a0563bf6eDianne Hackborn                    "OS doesn't have Service.startForeground OR Service.setForeground!");
136579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn        }
137579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn    }
138579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn
139579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn    @Override
140eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn    public void onDestroy() {
141eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn        // Make sure our notification is gone.
142eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn        stopForegroundCompat(R.string.foreground_service_started);
143eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn    }
144579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn// END_INCLUDE(foreground_compatibility)
145579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn
146579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn// BEGIN_INCLUDE(start_compatibility)
147579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn    // This is the old onStart method that will be called on the pre-2.0
148579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn    // platform.  On 2.0 or later we override onStartCommand() so this
149579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn    // method will not be called.
150579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn    @Override
151579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn    public void onStart(Intent intent, int startId) {
152579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn        handleCommand(intent);
153579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn    }
154579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn
155579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn    @Override
156579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn    public int onStartCommand(Intent intent, int flags, int startId) {
157579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn        handleCommand(intent);
158579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn        // We want this service to continue running until it is explicitly
159579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn        // stopped, so return sticky.
160579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn        return START_STICKY;
161579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn    }
162579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn// END_INCLUDE(start_compatibility)
163579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn
164579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn    void handleCommand(Intent intent) {
165579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn        if (ACTION_FOREGROUND.equals(intent.getAction())) {
166579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn            // In this sample, we'll use the same text for the ticker and the expanded notification
167579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn            CharSequence text = getText(R.string.foreground_service_started);
168579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn
169579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn            // Set the icon, scrolling text and timestamp
170579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn            Notification notification = new Notification(R.drawable.stat_sample, text,
171579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn                    System.currentTimeMillis());
172579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn
173579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn            // The PendingIntent to launch our activity if the user selects this notification
174579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn            PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
175579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn                    new Intent(this, Controller.class), 0);
176eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn
177579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn            // Set the info for the views that show in the notification panel.
178579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn            notification.setLatestEventInfo(this, getText(R.string.local_service_label),
179579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn                           text, contentIntent);
180579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn
181579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn            startForegroundCompat(R.string.foreground_service_started, notification);
182579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn
183579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn        } else if (ACTION_BACKGROUND.equals(intent.getAction())) {
184579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn            stopForegroundCompat(R.string.foreground_service_started);
185579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn        }
186579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn    }
187579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn
188eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn    @Override
189eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn    public IBinder onBind(Intent intent) {
190eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn        return null;
191eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn    }
192579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn
193579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn    // ----------------------------------------------------------------------
194579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn
195579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn    /**
196579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn     * <p>Example of explicitly starting and stopping the {@link ForegroundService}.
197579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn     *
198579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn     * <p>Note that this is implemented as an inner class only keep the sample
199579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn     * all together; typically this code would appear in some separate class.
200579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn     */
201579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn    public static class Controller extends Activity {
202579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn        @Override
203579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn        protected void onCreate(Bundle savedInstanceState) {
204579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn            super.onCreate(savedInstanceState);
205579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn
206579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn            setContentView(R.layout.foreground_service_controller);
207579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn
208579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn            // Watch for button clicks.
209579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn            Button button = (Button)findViewById(R.id.start_foreground);
210579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn            button.setOnClickListener(mForegroundListener);
211579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn            button = (Button)findViewById(R.id.start_background);
212579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn            button.setOnClickListener(mBackgroundListener);
213579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn            button = (Button)findViewById(R.id.stop);
214579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn            button.setOnClickListener(mStopListener);
215579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn        }
216579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn
217579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn        private OnClickListener mForegroundListener = new OnClickListener() {
218579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn            public void onClick(View v) {
219579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn                Intent intent = new Intent(ForegroundService.ACTION_FOREGROUND);
220579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn                intent.setClass(Controller.this, ForegroundService.class);
221579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn                startService(intent);
222579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn            }
223579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn        };
224579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn
225579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn        private OnClickListener mBackgroundListener = new OnClickListener() {
226579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn            public void onClick(View v) {
227579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn                Intent intent = new Intent(ForegroundService.ACTION_BACKGROUND);
228579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn                intent.setClass(Controller.this, ForegroundService.class);
229579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn                startService(intent);
230579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn            }
231579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn        };
232579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn
233579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn        private OnClickListener mStopListener = new OnClickListener() {
234579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn            public void onClick(View v) {
235579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn                stopService(new Intent(Controller.this,
236579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn                        ForegroundService.class));
237579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn            }
238579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn        };
239579c7f19ac379294822b976b73fe4037f40eba82Dianne Hackborn    }
240eb3547b3d0678ad16a602d342cf81dc64e03d9b7Dianne Hackborn}
241