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
19import com.example.android.apis.R;
20
21import android.app.Activity;
22import android.app.Notification;
23import android.app.NotificationManager;
24import android.app.PendingIntent;
25import android.content.ComponentName;
26import android.content.Intent;
27import android.os.Bundle;
28import android.view.View;
29import android.widget.Button;
30import android.widget.RemoteViews;
31
32/**
33 * Demonstrates adding notifications to the status bar
34 */
35public class StatusBarNotifications extends Activity {
36
37    private NotificationManager mNotificationManager;
38
39    // Use our layout id for a unique identifier
40    private static int MOOD_NOTIFICATIONS = R.layout.status_bar_notifications;
41
42    @Override
43    protected void onCreate(Bundle savedInstanceState) {
44        super.onCreate(savedInstanceState);
45
46        setContentView(R.layout.status_bar_notifications);
47
48        Button button;
49
50        // Get the notification manager serivce.
51        mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
52
53        button = (Button) findViewById(R.id.happy);
54        button.setOnClickListener(new Button.OnClickListener() {
55            public void onClick(View v) {
56                setMood(R.drawable.stat_happy, R.string.status_bar_notifications_happy_message,
57                        false);
58            }
59        });
60
61        button = (Button) findViewById(R.id.neutral);
62        button.setOnClickListener(new Button.OnClickListener() {
63            public void onClick(View v) {
64                setMood(R.drawable.stat_neutral, R.string.status_bar_notifications_ok_message,
65                        false);
66            }
67        });
68
69        button = (Button) findViewById(R.id.sad);
70        button.setOnClickListener(new Button.OnClickListener() {
71            public void onClick(View v) {
72                setMood(R.drawable.stat_sad, R.string.status_bar_notifications_sad_message, false);
73            }
74        });
75
76        button = (Button) findViewById(R.id.happyMarquee);
77        button.setOnClickListener(new Button.OnClickListener() {
78            public void onClick(View v) {
79                setMood(R.drawable.stat_happy, R.string.status_bar_notifications_happy_message,
80                        true);
81            }
82        });
83
84        button = (Button) findViewById(R.id.neutralMarquee);
85        button.setOnClickListener(new Button.OnClickListener() {
86            public void onClick(View v) {
87                setMood(R.drawable.stat_neutral, R.string.status_bar_notifications_ok_message, true);
88            }
89        });
90
91        button = (Button) findViewById(R.id.sadMarquee);
92        button.setOnClickListener(new Button.OnClickListener() {
93            public void onClick(View v) {
94                setMood(R.drawable.stat_sad, R.string.status_bar_notifications_sad_message, true);
95            }
96        });
97
98        button = (Button) findViewById(R.id.happyViews);
99        button.setOnClickListener(new Button.OnClickListener() {
100            public void onClick(View v) {
101                setMoodView(R.drawable.stat_happy, R.string.status_bar_notifications_happy_message);
102            }
103        });
104
105        button = (Button) findViewById(R.id.neutralViews);
106        button.setOnClickListener(new Button.OnClickListener() {
107            public void onClick(View v) {
108                setMoodView(R.drawable.stat_neutral, R.string.status_bar_notifications_ok_message);
109            }
110        });
111
112        button = (Button) findViewById(R.id.sadViews);
113        button.setOnClickListener(new Button.OnClickListener() {
114            public void onClick(View v) {
115                setMoodView(R.drawable.stat_sad, R.string.status_bar_notifications_sad_message);
116            }
117        });
118
119        button = (Button) findViewById(R.id.defaultSound);
120        button.setOnClickListener(new Button.OnClickListener() {
121            public void onClick(View v) {
122                setDefault(Notification.DEFAULT_SOUND);
123            }
124        });
125
126        button = (Button) findViewById(R.id.defaultVibrate);
127        button.setOnClickListener(new Button.OnClickListener() {
128            public void onClick(View v) {
129                setDefault(Notification.DEFAULT_VIBRATE);
130            }
131        });
132
133        button = (Button) findViewById(R.id.defaultAll);
134        button.setOnClickListener(new Button.OnClickListener() {
135            public void onClick(View v) {
136                setDefault(Notification.DEFAULT_ALL);
137            }
138        });
139
140        button = (Button) findViewById(R.id.clear);
141        button.setOnClickListener(new Button.OnClickListener() {
142            public void onClick(View v) {
143                mNotificationManager.cancel(R.layout.status_bar_notifications);
144            }
145        });
146    }
147
148    private PendingIntent makeMoodIntent(int moodId) {
149        // The PendingIntent to launch our activity if the user selects this
150        // notification.  Note the use of FLAG_UPDATE_CURRENT so that if there
151        // is already an active matching pending intent, we will update its
152        // extras (and other Intents in the array) to be the ones passed in here.
153        PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
154                new Intent(this, NotificationDisplay.class).putExtra("moodimg", moodId),
155                PendingIntent.FLAG_UPDATE_CURRENT);
156        return contentIntent;
157    }
158
159//BEGIN_INCLUDE(intent_array)
160    private PendingIntent makeDefaultIntent() {
161        // A typical convention for notifications is to launch the user deeply
162        // into an application representing the data in the notification; to
163        // accomplish this, we can build an array of intents to insert the back
164        // stack stack history above the item being displayed.
165        Intent[] intents = new Intent[4];
166
167        // First: root activity of ApiDemos.
168        // This is a convenient way to make the proper Intent to launch and
169        // reset an application's task.
170        intents[0] = Intent.makeRestartActivityTask(new ComponentName(this,
171                com.example.android.apis.ApiDemos.class));
172
173        // "App"
174        intents[1] = new Intent(this, com.example.android.apis.ApiDemos.class);
175        intents[1].putExtra("com.example.android.apis.Path", "App");
176        // "App/Notification"
177        intents[2] = new Intent(this, com.example.android.apis.ApiDemos.class);
178        intents[2].putExtra("com.example.android.apis.Path", "App/Notification");
179
180        // Now the activity to display to the user.
181        intents[3] = new Intent(this, StatusBarNotifications.class);
182
183        // The PendingIntent to launch our activity if the user selects this
184        // notification.  Note the use of FLAG_UPDATE_CURRENT so that if there
185        // is already an active matching pending intent, we will update its
186        // extras (and other Intents in the array) to be the ones passed in here.
187        PendingIntent contentIntent = PendingIntent.getActivities(this, 0,
188                intents, PendingIntent.FLAG_UPDATE_CURRENT);
189        return contentIntent;
190    }
191//END_INCLUDE(intent_array)
192
193    private void setMood(int moodId, int textId, boolean showTicker) {
194        // In this sample, we'll use the same text for the ticker and the expanded notification
195        CharSequence text = getText(textId);
196
197        // choose the ticker text
198        String tickerText = showTicker ? getString(textId) : null;
199
200        // Set the icon, scrolling text and timestamp
201        Notification notification = new Notification(moodId, tickerText,
202                System.currentTimeMillis());
203
204        // Set the info for the views that show in the notification panel.
205        notification.setLatestEventInfo(this, getText(R.string.status_bar_notifications_mood_title),
206                       text, makeMoodIntent(moodId));
207
208        // Send the notification.
209        // We use a layout id because it is a unique number.  We use it later to cancel.
210        mNotificationManager.notify(MOOD_NOTIFICATIONS, notification);
211    }
212
213    private void setMoodView(int moodId, int textId) {
214        // Instead of the normal constructor, we're going to use the one with no args and fill
215        // in all of the data ourselves.  The normal one uses the default layout for notifications.
216        // You probably want that in most cases, but if you want to do something custom, you
217        // can set the contentView field to your own RemoteViews object.
218        Notification notif = new Notification();
219
220        // This is who should be launched if the user selects our notification.
221        notif.contentIntent = makeMoodIntent(moodId);
222
223        // In this sample, we'll use the same text for the ticker and the expanded notification
224        CharSequence text = getText(textId);
225        notif.tickerText = text;
226
227        // the icon for the status bar
228        notif.icon = moodId;
229
230        // our custom view
231        RemoteViews contentView = new RemoteViews(getPackageName(), R.layout.status_bar_balloon);
232        contentView.setTextViewText(R.id.text, text);
233        contentView.setImageViewResource(R.id.icon, moodId);
234        notif.contentView = contentView;
235
236        // we use a string id because is a unique number.  we use it later to cancel the
237        // notification
238        mNotificationManager.notify(MOOD_NOTIFICATIONS, notif);
239    }
240
241    private void setDefault(int defaults) {
242
243        // This method sets the defaults on the notification before posting it.
244
245        // This is who should be launched if the user selects our notification.
246        PendingIntent contentIntent = makeDefaultIntent();
247
248        // In this sample, we'll use the same text for the ticker and the expanded notification
249        CharSequence text = getText(R.string.status_bar_notifications_happy_message);
250
251        final Notification notification = new Notification(
252                R.drawable.stat_happy,       // the icon for the status bar
253                text,                        // the text to display in the ticker
254                System.currentTimeMillis()); // the timestamp for the notification
255
256        notification.setLatestEventInfo(
257                this,                        // the context to use
258                getText(R.string.status_bar_notifications_mood_title),
259                                             // the title for the notification
260                text,                        // the details to display in the notification
261                contentIntent);              // the contentIntent (see above)
262
263        notification.defaults = defaults;
264
265        mNotificationManager.notify(
266                MOOD_NOTIFICATIONS, // we use a string id because it is a unique
267                                    // number.  we use it later to cancel the notification
268                notification);
269    }
270}
271