1 /* 2 * Copyright (C) 2007 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.example.android.apis.app; 18 19 // Need the following import to get access to the app resources, since this 20 // class is in a sub-package. 21 import com.example.android.apis.R; 22 23 import android.app.Notification; 24 import android.app.NotificationManager; 25 import android.app.PendingIntent; 26 import android.app.Service; 27 import android.content.Intent; 28 import android.os.Binder; 29 import android.os.ConditionVariable; 30 import android.os.IBinder; 31 import android.os.Parcel; 32 import android.os.RemoteException; 33 import android.widget.RemoteViews; 34 35 /** 36 * This is an example of service that will update its status bar balloon 37 * every 5 seconds for a minute. 38 * 39 */ 40 public class NotifyingService extends Service { 41 42 // Use a layout id for a unique identifier 43 private static int MOOD_NOTIFICATIONS = R.layout.status_bar_notifications; 44 45 // variable which controls the notification thread 46 private ConditionVariable mCondition; 47 48 @Override 49 public void onCreate() { 50 mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); 51 52 // Start up the thread running the service. Note that we create a 53 // separate thread because the service normally runs in the process's 54 // main thread, which we don't want to block. 55 Thread notifyingThread = new Thread(null, mTask, "NotifyingService"); 56 mCondition = new ConditionVariable(false); 57 notifyingThread.start(); 58 } 59 60 @Override 61 public void onDestroy() { 62 // Cancel the persistent notification. 63 mNM.cancel(MOOD_NOTIFICATIONS); 64 // Stop the thread from generating further notifications 65 mCondition.open(); 66 } 67 68 private Runnable mTask = new Runnable() { 69 public void run() { 70 for (int i = 0; i < 4; ++i) { 71 showNotification(R.drawable.stat_happy, 72 R.string.status_bar_notifications_happy_message); 73 if (mCondition.block(5 * 1000)) 74 break; 75 showNotification(R.drawable.stat_neutral, 76 R.string.status_bar_notifications_ok_message); 77 if (mCondition.block(5 * 1000)) 78 break; 79 showNotification(R.drawable.stat_sad, 80 R.string.status_bar_notifications_sad_message); 81 if (mCondition.block(5 * 1000)) 82 break; 83 } 84 // Done with our work... stop the service! 85 NotifyingService.this.stopSelf(); 86 } 87 }; 88 89 @Override 90 public IBinder onBind(Intent intent) { 91 return mBinder; 92 } 93 94 private void showNotification(int moodId, int textId) { 95 // In this sample, we'll use the same text for the ticker and the expanded notification 96 CharSequence text = getText(textId); 97 98 // Set the icon, scrolling text and timestamp. 99 // Note that in this example, we pass null for tickerText. We update the icon enough that 100 // it is distracting to show the ticker text every time it changes. We strongly suggest 101 // that you do this as well. (Think of of the "New hardware found" or "Network connection 102 // changed" messages that always pop up) 103 Notification notification = new Notification(moodId, null, System.currentTimeMillis()); 104 105 // The PendingIntent to launch our activity if the user selects this notification 106 PendingIntent contentIntent = PendingIntent.getActivity(this, 0, 107 new Intent(this, NotifyingController.class), 0); 108 109 // Set the info for the views that show in the notification panel. 110 notification.setLatestEventInfo(this, getText(R.string.status_bar_notifications_mood_title), 111 text, contentIntent); 112 113 // Send the notification. 114 // We use a layout id because it is a unique number. We use it later to cancel. 115 mNM.notify(MOOD_NOTIFICATIONS, notification); 116 } 117 118 // This is the object that receives interactions from clients. See 119 // RemoteService for a more complete example. 120 private final IBinder mBinder = new Binder() { 121 @Override 122 protected boolean onTransact(int code, Parcel data, Parcel reply, 123 int flags) throws RemoteException { 124 return super.onTransact(code, data, reply, flags); 125 } 126 }; 127 128 private NotificationManager mNM; 129 } 130