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
17package 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.
21import com.example.android.apis.R;
22
23import android.app.Notification;
24import android.app.NotificationManager;
25import android.app.PendingIntent;
26import android.app.Service;
27import android.content.Intent;
28import android.os.Binder;
29import android.os.ConditionVariable;
30import android.os.IBinder;
31import android.os.Parcel;
32import android.os.RemoteException;
33
34/**
35 * This is an example of service that will update its status bar balloon
36 * every 5 seconds for a minute.
37 *
38 */
39public class NotifyingService extends Service {
40
41    // Use a layout id for a unique identifier
42    private static int MOOD_NOTIFICATIONS = R.layout.status_bar_notifications;
43
44    // variable which controls the notification thread
45    private ConditionVariable mCondition;
46
47    @Override
48    public void onCreate() {
49        mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
50
51        // Start up the thread running the service.  Note that we create a
52        // separate thread because the service normally runs in the process's
53        // main thread, which we don't want to block.
54        Thread notifyingThread = new Thread(null, mTask, "NotifyingService");
55        mCondition = new ConditionVariable(false);
56        notifyingThread.start();
57    }
58
59    @Override
60    public void onDestroy() {
61        // Cancel the persistent notification.
62        mNM.cancel(MOOD_NOTIFICATIONS);
63        // Stop the thread from generating further notifications
64        mCondition.open();
65    }
66
67    private Runnable mTask = new Runnable() {
68        public void run() {
69            for (int i = 0; i < 4; ++i) {
70                showNotification(R.drawable.stat_happy,
71                        R.string.status_bar_notifications_happy_message);
72                if (mCondition.block(5 * 1000))
73                    break;
74                showNotification(R.drawable.stat_neutral,
75                        R.string.status_bar_notifications_ok_message);
76                if (mCondition.block(5 * 1000))
77                    break;
78                showNotification(R.drawable.stat_sad,
79                        R.string.status_bar_notifications_sad_message);
80                if (mCondition.block(5 * 1000))
81                    break;
82            }
83            // Done with our work...  stop the service!
84            NotifyingService.this.stopSelf();
85        }
86    };
87
88    @Override
89    public IBinder onBind(Intent intent) {
90        return mBinder;
91    }
92
93    private void showNotification(int moodId, int textId) {
94        // In this sample, we'll use the same text for the ticker and the expanded notification
95        CharSequence text = getText(textId);
96
97        // Set the icon, scrolling text and timestamp.
98        // Note that in this example, we pass null for tickerText.  We update the icon enough that
99        // it is distracting to show the ticker text every time it changes.  We strongly suggest
100        // that you do this as well.  (Think of of the "New hardware found" or "Network connection
101        // changed" messages that always pop up)
102        Notification notification = new Notification(moodId, null, System.currentTimeMillis());
103
104        // The PendingIntent to launch our activity if the user selects this notification
105        PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
106                new Intent(this, NotifyingController.class), 0);
107
108        // Set the info for the views that show in the notification panel.
109        notification.setLatestEventInfo(this, getText(R.string.status_bar_notifications_mood_title),
110                       text, contentIntent);
111
112        // Send the notification.
113        // We use a layout id because it is a unique number.  We use it later to cancel.
114        mNM.notify(MOOD_NOTIFICATIONS, notification);
115    }
116
117    // This is the object that receives interactions from clients.  See
118    // RemoteService for a more complete example.
119    private final IBinder mBinder = new Binder() {
120        @Override
121        protected boolean onTransact(int code, Parcel data, Parcel reply,
122                int flags) throws RemoteException {
123            return super.onTransact(code, data, reply, flags);
124        }
125    };
126
127    private NotificationManager mNM;
128}
129