am 0b6b4f2d: Merge "Fix notification sample to follow current UI guidelines." into ics-mr1

* commit '0b6b4f2d195f8224e19b66e5c266a7fd798f321d':
  Fix notification sample to follow current UI guidelines.
This commit is contained in:
Dianne Hackborn
2012-01-11 10:54:42 -08:00
committed by Android Git Automerger
10 changed files with 315 additions and 57 deletions

View File

@@ -615,24 +615,27 @@
</intent-filter>
</activity>
<!-- BEGIN_INCLUDE(no_task_affinity) -->
<activity android:name=".app.IncomingMessage"
android:label="App/Notification/IncomingMessage"
android:taskAffinity="">
android:label="App/Notification/IncomingMessage">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.SAMPLE_CODE" />
</intent-filter>
</activity>
<!-- END_INCLUDE(no_task_affinity) -->
<activity android:name=".app.IncomingMessageView" android:label="App/Notification/IncomingMessageView">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.EMBED" />
</intent-filter>
<activity android:name=".app.IncomingMessageView"
android:label="App/Notification/IncomingMessageView">
</activity>
<!-- BEGIN_INCLUDE(interstitial_affinity) -->
<activity android:name=".app.IncomingMessageInterstitial"
android:label="You have messages"
android:theme="@style/ThemeHoloDialog"
android:launchMode="singleInstance"
android:excludeFromRecents="true">
</activity>
<!-- END_INCLUDE(interstitial_affinity) -->
<!-- This is used to display a notification selected by the user
from StatusBarNotifications. Note the configuration here so
that the activity layers on top of whatever the user is doing,

View File

@@ -17,12 +17,34 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
android:layout_height="match_parent"
android:padding="8dp">
<Button
android:id="@+id/notify"
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/incoming_message_notify_text" />
android:layout_gravity="center"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Display a notification that will switch to the app in a new activity stack." />
<Button
android:id="@+id/notify_app"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Show App Notification" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingTop="16dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="Display a notification that will go to a dedicated interstitial activity." />
<Button
android:id="@+id/notify_interstitial"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Show Interstitial Notification" />
</LinearLayout>

View File

@@ -0,0 +1,37 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2012 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="8dp">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:paddingBottom="4dp"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="This would be where you would see a summary of the information related to the notification. Instead, we'll just give you a button." />
<Button
android:id="@+id/notify_app"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Switch To App" />
</LinearLayout>

View File

@@ -23,6 +23,15 @@
android:paddingTop="4dip"
>
<TextView
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingBottom="12dip"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/incoming_message_view_message_text"
/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="match_parent"
@@ -35,23 +44,35 @@
android:src="@drawable/sample_thumb_2"
/>
<TextView
android:id="@+id/message"
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:paddingLeft="6dip"
android:text="@string/incoming_message_view_message_text"
/>
>
<TextView
android:id="@+id/from"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
/>
<TextView
android:id="@+id/message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceMedium"
/>
</LinearLayout>
</LinearLayout>
<TextView
android:id="@+id/message"
android:layout_gravity="center_vertical"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingTop="12dip"
android:textAppearance="?android:attr/textAppearanceMedium"
android:text="@string/imcoming_message_view_message2_text"
/>

View File

@@ -19,6 +19,10 @@
<style name="ThemeHolo" parent="android:Theme.Holo">
</style>
<!-- For API level 11 or later, the Holo theme is available and we prefer that. -->
<style name="ThemeHoloDialog" parent="android:Theme.Holo.Dialog">
</style>
<!-- For API level 11 or later, we can use the magical DialogWhenLarge theme. -->
<style name="ThemeDialogWhenLarge" parent="android:style/Theme.Holo.DialogWhenLarge">
</style>

View File

@@ -1195,11 +1195,9 @@
<string name="google_login_username_text"></string>
<string name="incoming_message_notify_text">Show Notification</string>
<string name="incoming_message_info_message_text">this is the text of a previous message.\nkthx. meet u for dinner. cul8r</string>
<string name="incoming_message_view_message_text">this is the text of a previous message.\nkthx. meet u for dinner. cul8r</string>
<string name="incoming_message_view_message_text">This is the text of the posted notification.</string>
<string name="imcoming_message_view_message2_text">Did you notice that the status bar icon disappeared?</string>
<string name="imcoming_message_ticker_text">New text message: <xliff:g id="text">%0$s</xliff:g></string>

View File

@@ -30,6 +30,13 @@
<style name="ThemeHolo" parent="android:Theme">
</style>
<!-- This is a theme that will adjust itself depending on the API version.
The default definition is the safe one, using a theme that has always
been defined. Look at values-11/styles.xml for a variation that is
selected when the holographic theme is available. -->
<style name="ThemeHoloDialog" parent="android:Theme.Dialog">
</style>
<!-- Base application theme is the default theme. -->
<style name="Theme" parent="android:Theme">
</style>

View File

@@ -16,22 +16,24 @@
package com.example.android.apis.app;
import java.util.Random;
import com.example.android.apis.R;
import android.app.Activity;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
/**
* UI for posting an example notification.
*/
public class IncomingMessage extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
@@ -39,36 +41,82 @@ public class IncomingMessage extends Activity {
setContentView(R.layout.incoming_message);
Button button = (Button) findViewById(R.id.notify);
Button button = (Button) findViewById(R.id.notify_app);
button.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
showNotification();
showAppNotification();
}
});
button = (Button) findViewById(R.id.notify_interstitial);
button.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
showInterstitialNotification();
}
});
}
private View inflateView(int resource) {
LayoutInflater vi = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
return vi.inflate(resource, null);
//BEGIN_INCLUDE(app_notification)
//BEGIN_INCLUDE(intent_array)
/**
* This method creates an array of Intent objects representing the
* activity stack for the incoming message details state that the
* application should be in when launching it from a notification.
*/
static Intent[] makeMessageIntentStack(Context context, CharSequence from,
CharSequence msg) {
// A typical convention for notifications is to launch the user deeply
// into an application representing the data in the notification; to
// accomplish this, we can build an array of intents to insert the back
// stack stack history above the item being displayed.
Intent[] intents = new Intent[4];
// First: root activity of ApiDemos.
// This is a convenient way to make the proper Intent to launch and
// reset an application's task.
intents[0] = Intent.makeRestartActivityTask(new ComponentName(context,
com.example.android.apis.ApiDemos.class));
// "App"
intents[1] = new Intent(context, com.example.android.apis.ApiDemos.class);
intents[1].putExtra("com.example.android.apis.Path", "App");
// "App/Notification"
intents[2] = new Intent(context, com.example.android.apis.ApiDemos.class);
intents[2].putExtra("com.example.android.apis.Path", "App/Notification");
// Now the activity to display to the user. Also fill in the data it
// should display.
intents[3] = new Intent(context, IncomingMessageView.class);
intents[3].putExtra(IncomingMessageView.KEY_FROM, from);
intents[3].putExtra(IncomingMessageView.KEY_MESSAGE, msg);
return intents;
}
//END_INCLUDE(intent_array)
/**
* The notification is the icon and associated expanded entry in the
* status bar.
*/
protected void showNotification() {
void showAppNotification() {
// look up the notification manager service
NotificationManager nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
// The details of our fake message
CharSequence from = "Joe";
CharSequence message = "kthx. meet u for dinner. cul8r";
CharSequence message;
switch ((new Random().nextInt()) % 3) {
case 0: message = "r u hungry? i am starved"; break;
case 1: message = "im nearby u"; break;
default: message = "kthx. meet u for dinner. cul8r"; break;
}
// The PendingIntent to launch our activity if the user selects this notification
//BEGIN_INCLUDE(pending_intent)
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, IncomingMessageView.class), 0);
//END_INCLUDE(pending_intent)
// The PendingIntent to launch our activity if the user selects this
// notification. Note the use of FLAG_CANCEL_CURRENT so that, if there
// is already an active matching pending intent, cancel it and replace
// it with the new array of Intents.
PendingIntent contentIntent = PendingIntent.getActivities(this, 0,
makeMessageIntentStack(this, from, message), PendingIntent.FLAG_CANCEL_CURRENT);
// The ticker text, this uses a formatted string so our message could be localized
String tickerText = getString(R.string.imcoming_message_ticker_text, message);
@@ -80,20 +128,10 @@ public class IncomingMessage extends Activity {
// Set the info for the views that show in the notification panel.
notif.setLatestEventInfo(this, from, message, contentIntent);
/*
// On tablets, the ticker shows the sender, the first line of the message,
// the photo of the person and the app icon. For our sample, we just show
// the same icon twice. If there is no sender, just pass an array of 1 Bitmap.
notif.tickerTitle = from;
notif.tickerSubtitle = message;
notif.tickerIcons = new Bitmap[2];
notif.tickerIcons[0] = getIconBitmap();;
notif.tickerIcons[1] = getIconBitmap();;
*/
// after a 0ms delay, vibrate for 250ms, pause for 100 ms and
// then vibrate for 500ms.
notif.vibrate = new long[] { 0, 250, 100, 500};
// We'll have this notification do the default sound, vibration, and led.
// Note that if you want any of these behaviors, you should always have
// a preference for the user to turn them off.
notif.defaults = Notification.DEFAULT_ALL;
// Note that we use R.layout.incoming_message_panel as the ID for
// the notification. It could be any integer you want, but we use
@@ -102,10 +140,58 @@ public class IncomingMessage extends Activity {
// application.
nm.notify(R.string.imcoming_message_ticker_text, notif);
}
//END_INCLUDE(app_notification)
private Bitmap getIconBitmap() {
BitmapFactory f = new BitmapFactory();
return f.decodeResource(getResources(), R.drawable.app_sample_code);
//BEGIN_INCLUDE(interstitial_notification)
/**
* The notification is the icon and associated expanded entry in the
* status bar.
*/
void showInterstitialNotification() {
// look up the notification manager service
NotificationManager nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
// The details of our fake message
CharSequence from = "Dianne";
CharSequence message;
switch ((new Random().nextInt()) % 3) {
case 0: message = "i am ready for some dinner"; break;
case 1: message = "how about thai down the block?"; break;
default: message = "meet u soon. dont b late!"; break;
}
// The PendingIntent to launch our activity if the user selects this
// notification. Note the use of FLAG_CANCEL_CURRENT so that, if there
// is already an active matching pending intent, cancel it and replace
// it with the new Intent.
Intent intent = new Intent(this, IncomingMessageInterstitial.class);
intent.putExtra(IncomingMessageView.KEY_FROM, from);
intent.putExtra(IncomingMessageView.KEY_MESSAGE, message);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
intent, PendingIntent.FLAG_CANCEL_CURRENT);
// The ticker text, this uses a formatted string so our message could be localized
String tickerText = getString(R.string.imcoming_message_ticker_text, message);
// construct the Notification object.
Notification notif = new Notification(R.drawable.stat_sample, tickerText,
System.currentTimeMillis());
// Set the info for the views that show in the notification panel.
notif.setLatestEventInfo(this, from, message, contentIntent);
// We'll have this notification do the default sound, vibration, and led.
// Note that if you want any of these behaviors, you should always have
// a preference for the user to turn them off.
notif.defaults = Notification.DEFAULT_ALL;
// Note that we use R.layout.incoming_message_panel as the ID for
// the notification. It could be any integer you want, but we use
// the convention of using a resource id for a string related to
// the notification. It will always be a unique number within your
// application.
nm.notify(R.string.imcoming_message_ticker_text, notif);
}
//END_INCLUDE(interstitial_notification)
}

View File

@@ -0,0 +1,64 @@
/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.example.android.apis.app;
import com.example.android.apis.R;
import android.app.Activity;
import android.app.NotificationManager;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
/**
* This is an activity that provides an interstitial UI for the notification
* that is posted by {@link IncomingMessage}. It allows the user to switch
* to the app in its appropriate state if they want.
*/
public class IncomingMessageInterstitial extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.incoming_message_interstitial);
Button button = (Button) findViewById(R.id.notify_app);
button.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
switchToApp();
}
});
}
//BEGIN_INCLUDE(app_launch)
/**
* Perform a switch to the app. A new activity stack is started, replacing
* whatever is currently running, and this activity is finished.
*/
void switchToApp() {
// We will launch the app showing what the user picked. In this simple
// example, it is just what the notification gave us.
CharSequence from = getIntent().getCharSequenceExtra(IncomingMessageView.KEY_FROM);
CharSequence msg = getIntent().getCharSequenceExtra(IncomingMessageView.KEY_MESSAGE);
// Build the new activity stack, launch it, and finish this UI.
Intent[] stack = IncomingMessage.makeMessageIntentStack(this, from, msg);
startActivities(stack);
finish();
}
//END_INCLUDE(app_launch)
}

View File

@@ -21,6 +21,7 @@ import com.example.android.apis.R;
import android.app.Activity;
import android.app.NotificationManager;
import android.os.Bundle;
import android.widget.TextView;
/**
* This activity is run as the click activity for {@link IncomingMessage}.
@@ -28,11 +29,26 @@ import android.os.Bundle;
* has been "read."
*/
public class IncomingMessageView extends Activity {
/**
* Extra that can be supplied to Intent: who the message is from.
*/
static final public String KEY_FROM = "from";
/**
* Extra that can be supplied to Intent: the message that was sent.
*/
static final public String KEY_MESSAGE = "message";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.incoming_message_view);
// Fill in the message content.
((TextView)findViewById(R.id.from)).setText(
getIntent().getCharSequenceExtra(KEY_FROM));
((TextView)findViewById(R.id.message)).setText(
getIntent().getCharSequenceExtra(KEY_MESSAGE));
// look up the notification manager service
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);