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