Update browseable samples for lmp-docs
Synced to commit df5e5013422b81b4fd05c0ac9fd964b13624847a. Includes new samples for Android Auto. Change-Id: I3fec46e2a6b3f196682a92f1afd91eb682dc2dc1
This commit is contained in:
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (C) 2014 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.support.wearable.notifications;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
|
||||
/**
|
||||
* Base class for notification actions presets.
|
||||
*/
|
||||
public abstract class ActionsPreset extends NamedPreset {
|
||||
public ActionsPreset(int nameResId) {
|
||||
super(nameResId);
|
||||
}
|
||||
|
||||
/** Apply the priority to a notification builder */
|
||||
public abstract void apply(Context context, NotificationCompat.Builder builder,
|
||||
NotificationCompat.WearableExtender wearableOptions);
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
/*
|
||||
* Copyright (C) 2014 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.support.wearable.notifications;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
import android.support.v4.app.RemoteInput;
|
||||
|
||||
/**
|
||||
* Collection of notification actions presets.
|
||||
*/
|
||||
public class ActionsPresets {
|
||||
public static final ActionsPreset NO_ACTIONS_PRESET = new NoActionsPreset();
|
||||
public static final ActionsPreset SINGLE_ACTION_PRESET = new SingleActionPreset();
|
||||
|
||||
public static final ActionsPreset[] PRESETS = new ActionsPreset[] {
|
||||
NO_ACTIONS_PRESET,
|
||||
SINGLE_ACTION_PRESET,
|
||||
new ReplyActionPreset(),
|
||||
new ReplyWithChoicesActionPreset(),
|
||||
new DifferentActionsOnPhoneAndWearable(),
|
||||
new LongTitleActionPreset()
|
||||
};
|
||||
|
||||
private static class NoActionsPreset extends ActionsPreset {
|
||||
public NoActionsPreset() {
|
||||
super(R.string.no_actions);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(Context context, NotificationCompat.Builder builder,
|
||||
NotificationCompat.WearableExtender wearableOptions) {
|
||||
}
|
||||
}
|
||||
|
||||
private static class SingleActionPreset extends ActionsPreset {
|
||||
public SingleActionPreset() {
|
||||
super(R.string.single_action);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(Context context, NotificationCompat.Builder builder,
|
||||
NotificationCompat.WearableExtender wearableOptions) {
|
||||
builder.addAction(R.drawable.ic_full_action,
|
||||
context.getString(R.string.example_action),
|
||||
NotificationUtil.getExamplePendingIntent(context,
|
||||
R.string.example_action_clicked))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
private static class LongTitleActionPreset extends ActionsPreset {
|
||||
public LongTitleActionPreset() {
|
||||
super(R.string.long_title_action);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(Context context, NotificationCompat.Builder builder,
|
||||
NotificationCompat.WearableExtender wearableOptions) {
|
||||
builder.addAction(R.drawable.ic_full_action,
|
||||
context.getString(R.string.example_action_long_title),
|
||||
NotificationUtil.getExamplePendingIntent(context,
|
||||
R.string.example_action_clicked))
|
||||
.build();
|
||||
}
|
||||
}
|
||||
|
||||
private static class ReplyActionPreset extends ActionsPreset {
|
||||
public ReplyActionPreset() {
|
||||
super(R.string.reply_action);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(Context context, NotificationCompat.Builder builder,
|
||||
NotificationCompat.WearableExtender wearableOptions) {
|
||||
RemoteInput remoteInput = new RemoteInput.Builder(NotificationUtil.EXTRA_REPLY)
|
||||
.setLabel(context.getString(R.string.example_reply_label))
|
||||
.build();
|
||||
NotificationCompat.Action action = new NotificationCompat.Action.Builder(
|
||||
R.drawable.ic_full_reply,
|
||||
context.getString(R.string.example_reply_action),
|
||||
NotificationUtil.getExamplePendingIntent(context,
|
||||
R.string.example_reply_action_clicked))
|
||||
.addRemoteInput(remoteInput)
|
||||
.build();
|
||||
builder.addAction(action);
|
||||
}
|
||||
}
|
||||
|
||||
private static class ReplyWithChoicesActionPreset extends ActionsPreset {
|
||||
public ReplyWithChoicesActionPreset() {
|
||||
super(R.string.reply_action_with_choices);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(Context context, NotificationCompat.Builder builder,
|
||||
NotificationCompat.WearableExtender wearableOptions) {
|
||||
RemoteInput remoteInput = new RemoteInput.Builder(NotificationUtil.EXTRA_REPLY)
|
||||
.setLabel(context.getString(R.string.example_reply_answer_label))
|
||||
.setChoices(new String[] { context.getString(R.string.yes),
|
||||
context.getString(R.string.no), context.getString(R.string.maybe) })
|
||||
.build();
|
||||
NotificationCompat.Action action = new NotificationCompat.Action.Builder(
|
||||
R.drawable.ic_full_reply,
|
||||
context.getString(R.string.example_reply_action),
|
||||
NotificationUtil.getExamplePendingIntent(context,
|
||||
R.string.example_reply_action_clicked))
|
||||
.addRemoteInput(remoteInput)
|
||||
.build();
|
||||
wearableOptions.addAction(action);
|
||||
}
|
||||
}
|
||||
|
||||
private static class DifferentActionsOnPhoneAndWearable extends ActionsPreset {
|
||||
public DifferentActionsOnPhoneAndWearable() {
|
||||
super(R.string.different_actions_on_phone_and_wearable);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(Context context, NotificationCompat.Builder builder,
|
||||
NotificationCompat.WearableExtender wearableOptions) {
|
||||
NotificationCompat.Action phoneAction = new NotificationCompat.Action.Builder(
|
||||
R.drawable.ic_full_action,
|
||||
context.getString(R.string.phone_action),
|
||||
NotificationUtil.getExamplePendingIntent(context,
|
||||
R.string.phone_action_clicked))
|
||||
.build();
|
||||
builder.addAction(phoneAction);
|
||||
|
||||
RemoteInput remoteInput = new RemoteInput.Builder(NotificationUtil.EXTRA_REPLY)
|
||||
.setLabel(context.getString(R.string.example_reply_label))
|
||||
.build();
|
||||
|
||||
NotificationCompat.Action wearableAction = new NotificationCompat.Action.Builder(
|
||||
R.drawable.ic_full_reply,
|
||||
context.getString(R.string.wearable_action),
|
||||
NotificationUtil.getExamplePendingIntent(context,
|
||||
R.string.wearable_action_clicked))
|
||||
.addRemoteInput(remoteInput)
|
||||
.build();
|
||||
wearableOptions.addAction(wearableAction);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (C) 2014 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.support.wearable.notifications;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.res.Resources;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Manages the background image pickers.
|
||||
*/
|
||||
public class BackgroundPickers {
|
||||
|
||||
public interface OnBackgroundPickersChangedListener {
|
||||
public void onBackgroundPickersChanged(BackgroundPickers pickers);
|
||||
}
|
||||
|
||||
private final ViewGroup mContainer;
|
||||
private final OnPickedListener mOnPickedListener;
|
||||
private final List<ViewGroup> mPickers;
|
||||
private final OnBackgroundPickersChangedListener listener;
|
||||
|
||||
public BackgroundPickers(ViewGroup container, OnBackgroundPickersChangedListener listener) {
|
||||
this.mContainer = container;
|
||||
this.mOnPickedListener = new OnPickedListener();
|
||||
this.mPickers = new ArrayList<ViewGroup>();
|
||||
this.listener = listener;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the pickers as necessary.
|
||||
*/
|
||||
public void generatePickers(int count) {
|
||||
// Clear existing containers.
|
||||
clear();
|
||||
|
||||
// Fill in new pickers.
|
||||
LayoutInflater inflater = LayoutInflater.from(mContainer.getContext());
|
||||
Resources res = mContainer.getResources();
|
||||
for (int i = 0; i < count; i++) {
|
||||
View picker = inflater.inflate(R.layout.background_picker, mContainer, false);
|
||||
TextView label = (TextView) picker.findViewById(R.id.bg_picker_label);
|
||||
label.setText(String.format(res.getString(R.string.bg_picker_label), i+1));
|
||||
ViewGroup pickerBox = (ViewGroup) picker.findViewById(R.id.bg_picker_container);
|
||||
mPickers.add(pickerBox);
|
||||
for (int j = 0; j < pickerBox.getChildCount(); j++) {
|
||||
ImageView img = (ImageView) pickerBox.getChildAt(j);
|
||||
img.setOnClickListener(mOnPickedListener);
|
||||
}
|
||||
mContainer.addView(picker);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the background resource for the picker at the given index.
|
||||
* @param position Index of the background picker.
|
||||
* @return Id of the background image resource. null if no image is picked.
|
||||
*/
|
||||
public Integer getRes(int position) {
|
||||
String tag = (String) mPickers.get(position).getTag();
|
||||
if (tag == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Context context = mContainer.getContext();
|
||||
return context.getResources().getIdentifier(tag, "drawable", context.getPackageName());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the all the background resources for the pickers managed by this object. Returns null
|
||||
* if no pickers exist.
|
||||
*/
|
||||
public Integer[] getRes() {
|
||||
if (mPickers.size() == 0) {
|
||||
return null;
|
||||
}
|
||||
|
||||
Integer[] res = new Integer[mPickers.size()];
|
||||
for (int i = 0; i < mPickers.size(); i++) {
|
||||
res[i] = getRes(i);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears the pickers.
|
||||
*/
|
||||
public void clear() {
|
||||
mContainer.removeAllViews();
|
||||
mPickers.clear();
|
||||
}
|
||||
|
||||
public int getCount() {
|
||||
return mPickers.size();
|
||||
}
|
||||
|
||||
private class OnPickedListener implements View.OnClickListener {
|
||||
|
||||
@Override
|
||||
public void onClick(View view) {
|
||||
ImageView pickedView = (ImageView) view;
|
||||
ViewGroup pickerBox = (ViewGroup) view.getParent();
|
||||
|
||||
// Clear old selection.
|
||||
for (int i = 0; i < pickerBox.getChildCount(); i++) {
|
||||
ImageView childView = (ImageView) pickerBox.getChildAt(i);
|
||||
childView.setBackgroundResource(R.drawable.unselected_background);
|
||||
}
|
||||
|
||||
// Set new selection.
|
||||
pickedView.setBackgroundResource(R.drawable.selected_background);
|
||||
pickerBox.setTag(pickedView.getTag());
|
||||
|
||||
if (listener != null) {
|
||||
listener.onBackgroundPickersChanged(BackgroundPickers.this);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,352 @@
|
||||
/*
|
||||
* Copyright (C) 2014 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.support.wearable.notifications;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.Notification;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.support.v4.app.NotificationManagerCompat;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Main activity which posts a notification when resumed, and allows customization
|
||||
* of that notification via controls.
|
||||
*/
|
||||
public class MainActivity extends Activity implements Handler.Callback {
|
||||
private static final int MSG_POST_NOTIFICATIONS = 0;
|
||||
private static final long POST_NOTIFICATIONS_DELAY_MS = 200;
|
||||
|
||||
private Handler mHandler;
|
||||
private Spinner mPresetSpinner;
|
||||
private EditText mTitleEditText;
|
||||
private EditText mTextEditText;
|
||||
private TextWatcher mTextChangedListener;
|
||||
private Spinner mPrioritySpinner;
|
||||
private Spinner mActionsSpinner;
|
||||
private CheckBox mIncludeLargeIconCheckbox;
|
||||
private CheckBox mLocalOnlyCheckbox;
|
||||
private CheckBox mIncludeContentIntentCheckbox;
|
||||
private CheckBox mVibrateCheckbox;
|
||||
private BackgroundPickers mBackgroundPickers;
|
||||
private int postedNotificationCount = 0;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.main);
|
||||
|
||||
mHandler = new Handler(this);
|
||||
mTextChangedListener = new UpdateNotificationsOnTextChangeListener();
|
||||
|
||||
initPresetSpinner();
|
||||
initTitleEditText();
|
||||
initTextEditText();
|
||||
initPrioritySpinner();
|
||||
initActionsSpinner();
|
||||
initIncludeLargeIconCheckbox();
|
||||
initLocalOnlyCheckbox();
|
||||
initIncludeContentIntentCheckbox();
|
||||
initVibrateCheckbox();
|
||||
initBackgroundPickers();
|
||||
|
||||
NotificationPreset preset = NotificationPresets.PRESETS[
|
||||
mPresetSpinner.getSelectedItemPosition()];
|
||||
updateTextEditors(preset);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
updateNotifications(false /* cancelExisting */);
|
||||
}
|
||||
|
||||
private void initPresetSpinner() {
|
||||
mPresetSpinner = (Spinner) findViewById(R.id.preset_spinner);
|
||||
mPresetSpinner.setAdapter(new NamedPresetSpinnerArrayAdapter(this,
|
||||
NotificationPresets.PRESETS));
|
||||
mPresetSpinner.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mPresetSpinner.setOnItemSelectedListener(new PresetSpinnerListener());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void initTitleEditText() {
|
||||
mTitleEditText = (EditText) findViewById(R.id.title_editor);
|
||||
}
|
||||
|
||||
private void initTextEditText() {
|
||||
mTextEditText = (EditText) findViewById(R.id.text_editor);
|
||||
}
|
||||
|
||||
private void initPrioritySpinner() {
|
||||
mPrioritySpinner = (Spinner) findViewById(R.id.priority_spinner);
|
||||
mPrioritySpinner.setAdapter(new NamedPresetSpinnerArrayAdapter(this,
|
||||
PriorityPresets.PRESETS));
|
||||
mPrioritySpinner.setSelection(Arrays.asList(PriorityPresets.PRESETS)
|
||||
.indexOf(PriorityPresets.DEFAULT));
|
||||
mPrioritySpinner.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mPrioritySpinner.setOnItemSelectedListener(
|
||||
new UpdateNotificationsOnItemSelectedListener(true /* cancelExisting */));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void initActionsSpinner() {
|
||||
mActionsSpinner = (Spinner) findViewById(R.id.actions_spinner);
|
||||
mActionsSpinner.setAdapter(new NamedPresetSpinnerArrayAdapter(this,
|
||||
ActionsPresets.PRESETS));
|
||||
mActionsSpinner.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mActionsSpinner.setOnItemSelectedListener(
|
||||
new UpdateNotificationsOnItemSelectedListener(false /* cancelExisting */));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void initIncludeLargeIconCheckbox() {
|
||||
mIncludeLargeIconCheckbox = (CheckBox) findViewById(R.id.include_large_icon_checkbox);
|
||||
mIncludeLargeIconCheckbox.setOnCheckedChangeListener(
|
||||
new UpdateNotificationsOnCheckedChangeListener(false /* cancelExisting */));
|
||||
}
|
||||
|
||||
private void initLocalOnlyCheckbox() {
|
||||
mLocalOnlyCheckbox = (CheckBox) findViewById(R.id.local_only_checkbox);
|
||||
mLocalOnlyCheckbox.setOnCheckedChangeListener(
|
||||
new UpdateNotificationsOnCheckedChangeListener(false /* cancelExisting */));
|
||||
}
|
||||
|
||||
private void initIncludeContentIntentCheckbox() {
|
||||
mIncludeContentIntentCheckbox = (CheckBox) findViewById(
|
||||
R.id.include_content_intent_checkbox);
|
||||
mIncludeContentIntentCheckbox.setOnCheckedChangeListener(
|
||||
new UpdateNotificationsOnCheckedChangeListener(false /* cancelExisting */));
|
||||
}
|
||||
|
||||
private void initVibrateCheckbox() {
|
||||
mVibrateCheckbox = (CheckBox) findViewById(R.id.vibrate_checkbox);
|
||||
mVibrateCheckbox.setOnCheckedChangeListener(
|
||||
new UpdateNotificationsOnCheckedChangeListener(false /* cancelExisting */));
|
||||
}
|
||||
|
||||
private void initBackgroundPickers() {
|
||||
mBackgroundPickers = new BackgroundPickers(
|
||||
(ViewGroup) findViewById(R.id.background_pickers),
|
||||
new BackgroundPickerListener());
|
||||
}
|
||||
|
||||
private void updateTextEditors(NotificationPreset preset) {
|
||||
if (preset == NotificationPresets.BASIC) {
|
||||
findViewById(R.id.title_edit_field).setVisibility(View.VISIBLE);
|
||||
mTitleEditText.setText(getString(preset.titleResId));
|
||||
mTitleEditText.addTextChangedListener(mTextChangedListener);
|
||||
findViewById(R.id.text_edit_field).setVisibility(View.VISIBLE);
|
||||
mTextEditText.setText(getString(preset.textResId));
|
||||
mTextEditText.addTextChangedListener(mTextChangedListener);
|
||||
} else {
|
||||
findViewById(R.id.title_edit_field).setVisibility(View.GONE);
|
||||
mTitleEditText.removeTextChangedListener(mTextChangedListener);
|
||||
findViewById(R.id.text_edit_field).setVisibility(View.GONE);
|
||||
mTextEditText.removeTextChangedListener(mTextChangedListener);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Begin to re-post the sample notification(s).
|
||||
*/
|
||||
private void updateNotifications(boolean cancelExisting) {
|
||||
// Disable messages to skip notification deleted messages during cancel.
|
||||
sendBroadcast(new Intent(NotificationIntentReceiver.ACTION_DISABLE_MESSAGES)
|
||||
.setClass(this, NotificationIntentReceiver.class));
|
||||
|
||||
if (cancelExisting) {
|
||||
// Cancel all existing notifications to trigger fresh-posting behavior: For example,
|
||||
// switching from HIGH to LOW priority does not cause a reordering in Notification Shade.
|
||||
NotificationManagerCompat.from(this).cancelAll();
|
||||
postedNotificationCount = 0;
|
||||
|
||||
// Post the updated notifications on a delay to avoid a cancel+post race condition
|
||||
// with notification manager.
|
||||
mHandler.removeMessages(MSG_POST_NOTIFICATIONS);
|
||||
mHandler.sendEmptyMessageDelayed(MSG_POST_NOTIFICATIONS, POST_NOTIFICATIONS_DELAY_MS);
|
||||
} else {
|
||||
postNotifications();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Post the sample notification(s) using current options.
|
||||
*/
|
||||
private void postNotifications() {
|
||||
sendBroadcast(new Intent(NotificationIntentReceiver.ACTION_ENABLE_MESSAGES)
|
||||
.setClass(this, NotificationIntentReceiver.class));
|
||||
|
||||
NotificationPreset preset = NotificationPresets.PRESETS[
|
||||
mPresetSpinner.getSelectedItemPosition()];
|
||||
CharSequence titlePreset = mTitleEditText.getText();
|
||||
CharSequence textPreset = mTextEditText.getText();
|
||||
PriorityPreset priorityPreset = PriorityPresets.PRESETS[
|
||||
mPrioritySpinner.getSelectedItemPosition()];
|
||||
ActionsPreset actionsPreset = ActionsPresets.PRESETS[
|
||||
mActionsSpinner.getSelectedItemPosition()];
|
||||
if (preset.actionsRequired() && actionsPreset == ActionsPresets.NO_ACTIONS_PRESET) {
|
||||
// If actions are required, but the no-actions preset was selected, change presets.
|
||||
actionsPreset = ActionsPresets.SINGLE_ACTION_PRESET;
|
||||
mActionsSpinner.setSelection(Arrays.asList(ActionsPresets.PRESETS).indexOf(
|
||||
actionsPreset), true);
|
||||
}
|
||||
NotificationPreset.BuildOptions options = new NotificationPreset.BuildOptions(
|
||||
titlePreset,
|
||||
textPreset,
|
||||
priorityPreset,
|
||||
actionsPreset,
|
||||
mIncludeLargeIconCheckbox.isChecked(),
|
||||
mLocalOnlyCheckbox.isChecked(),
|
||||
mIncludeContentIntentCheckbox.isChecked(),
|
||||
mVibrateCheckbox.isChecked(),
|
||||
mBackgroundPickers.getRes());
|
||||
Notification[] notifications = preset.buildNotifications(this, options);
|
||||
|
||||
// Post new notifications
|
||||
for (int i = 0; i < notifications.length; i++) {
|
||||
NotificationManagerCompat.from(this).notify(i, notifications[i]);
|
||||
}
|
||||
// Cancel any that are beyond the current count.
|
||||
for (int i = notifications.length; i < postedNotificationCount; i++) {
|
||||
NotificationManagerCompat.from(this).cancel(i);
|
||||
}
|
||||
postedNotificationCount = notifications.length;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean handleMessage(Message message) {
|
||||
switch (message.what) {
|
||||
case MSG_POST_NOTIFICATIONS:
|
||||
postNotifications();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private class PresetSpinnerListener implements AdapterView.OnItemSelectedListener {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
NotificationPreset preset = NotificationPresets.PRESETS[position];
|
||||
mBackgroundPickers.generatePickers(preset.countBackgroundPickersRequired());
|
||||
updateTextEditors(preset);
|
||||
updateNotifications(false /* cancelExisting */);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> adapterView) {
|
||||
}
|
||||
}
|
||||
|
||||
private class UpdateNotificationsOnTextChangeListener implements TextWatcher {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
}
|
||||
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
updateNotifications(false /* cancelExisting */);
|
||||
}
|
||||
}
|
||||
|
||||
private class UpdateNotificationsOnItemSelectedListener
|
||||
implements AdapterView.OnItemSelectedListener {
|
||||
private final boolean mCancelExisting;
|
||||
|
||||
public UpdateNotificationsOnItemSelectedListener(boolean cancelExisting) {
|
||||
mCancelExisting = cancelExisting;
|
||||
}
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
updateNotifications(mCancelExisting);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> adapterView) {
|
||||
}
|
||||
}
|
||||
|
||||
private class UpdateNotificationsOnCheckedChangeListener
|
||||
implements CompoundButton.OnCheckedChangeListener {
|
||||
private final boolean mCancelExisting;
|
||||
|
||||
public UpdateNotificationsOnCheckedChangeListener(boolean cancelExisting) {
|
||||
mCancelExisting = cancelExisting;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
|
||||
updateNotifications(mCancelExisting);
|
||||
}
|
||||
}
|
||||
|
||||
private class BackgroundPickerListener
|
||||
implements BackgroundPickers.OnBackgroundPickersChangedListener {
|
||||
@Override
|
||||
public void onBackgroundPickersChanged(BackgroundPickers pickers) {
|
||||
updateNotifications(false /* cancelExisting */);
|
||||
}
|
||||
}
|
||||
|
||||
private class NamedPresetSpinnerArrayAdapter extends ArrayAdapter<NamedPreset> {
|
||||
public NamedPresetSpinnerArrayAdapter(Context context, NamedPreset[] presets) {
|
||||
super(context, R.layout.simple_spinner_item, presets);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getDropDownView(int position, View convertView, ViewGroup parent) {
|
||||
TextView view = (TextView) super.getDropDownView(position, convertView, parent);
|
||||
view.setText(getString(getItem(position).nameResId));
|
||||
return view;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent) {
|
||||
TextView view = (TextView) getLayoutInflater().inflate(
|
||||
android.R.layout.simple_spinner_item, parent, false);
|
||||
view.setText(getString(getItem(position).nameResId));
|
||||
return view;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* Copyright (C) 2014 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.support.wearable.notifications;
|
||||
|
||||
/**
|
||||
* Base class for presets that have a simple name to display.
|
||||
*/
|
||||
public abstract class NamedPreset {
|
||||
public final int nameResId;
|
||||
|
||||
public NamedPreset(int nameResId) {
|
||||
this.nameResId = nameResId;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright (C) 2014 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.support.wearable.notifications;
|
||||
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.RemoteInput;
|
||||
import android.widget.Toast;
|
||||
|
||||
/**
|
||||
* Broadcast receiver to post toast messages in response to notification intents firing.
|
||||
*/
|
||||
public class NotificationIntentReceiver extends BroadcastReceiver {
|
||||
public static final String ACTION_EXAMPLE =
|
||||
"com.example.android.support.wearable.notifications.ACTION_EXAMPLE";
|
||||
public static final String ACTION_ENABLE_MESSAGES =
|
||||
"com.example.android.support.wearable.notifications.ACTION_ENABLE_MESSAGES";
|
||||
public static final String ACTION_DISABLE_MESSAGES =
|
||||
"com.example.android.support.wearable.notifications.ACTION_DISABLE_MESSAGES";
|
||||
|
||||
private boolean mEnableMessages = true;
|
||||
|
||||
@Override
|
||||
public void onReceive(Context context, Intent intent) {
|
||||
if (intent.getAction().equals(ACTION_EXAMPLE)) {
|
||||
if (mEnableMessages) {
|
||||
String message = intent.getStringExtra(NotificationUtil.EXTRA_MESSAGE);
|
||||
Bundle remoteInputResults = RemoteInput.getResultsFromIntent(intent);
|
||||
CharSequence replyMessage = null;
|
||||
if (remoteInputResults != null) {
|
||||
replyMessage = remoteInputResults.getCharSequence(NotificationUtil.EXTRA_REPLY);
|
||||
}
|
||||
if (replyMessage != null) {
|
||||
message = message + ": \"" + replyMessage + "\"";
|
||||
}
|
||||
Toast.makeText(context, message, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
} else if (intent.getAction().equals(ACTION_ENABLE_MESSAGES)) {
|
||||
mEnableMessages = true;
|
||||
} else if (intent.getAction().equals(ACTION_DISABLE_MESSAGES)) {
|
||||
mEnableMessages = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (C) 2014 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.support.wearable.notifications;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.content.Context;
|
||||
|
||||
/**
|
||||
* Base class for notification preset generators.
|
||||
*/
|
||||
public abstract class NotificationPreset extends NamedPreset {
|
||||
public final int titleResId;
|
||||
public final int textResId;
|
||||
|
||||
public NotificationPreset(int nameResId, int titleResId, int textResId) {
|
||||
super(nameResId);
|
||||
this.titleResId = titleResId;
|
||||
this.textResId = textResId;
|
||||
}
|
||||
|
||||
public static class BuildOptions {
|
||||
public final CharSequence titlePreset;
|
||||
public final CharSequence textPreset;
|
||||
public final PriorityPreset priorityPreset;
|
||||
public final ActionsPreset actionsPreset;
|
||||
public final boolean includeLargeIcon;
|
||||
public final boolean isLocalOnly;
|
||||
public final boolean hasContentIntent;
|
||||
public final boolean vibrate;
|
||||
public final Integer[] backgroundIds;
|
||||
|
||||
public BuildOptions(CharSequence titlePreset, CharSequence textPreset,
|
||||
PriorityPreset priorityPreset, ActionsPreset actionsPreset,
|
||||
boolean includeLargeIcon, boolean isLocalOnly, boolean hasContentIntent,
|
||||
boolean vibrate, Integer[] backgroundIds) {
|
||||
this.titlePreset = titlePreset;
|
||||
this.textPreset = textPreset;
|
||||
this.priorityPreset = priorityPreset;
|
||||
this.actionsPreset = actionsPreset;
|
||||
this.includeLargeIcon = includeLargeIcon;
|
||||
this.isLocalOnly = isLocalOnly;
|
||||
this.hasContentIntent = hasContentIntent;
|
||||
this.vibrate = vibrate;
|
||||
this.backgroundIds = backgroundIds;
|
||||
}
|
||||
}
|
||||
|
||||
/** Build a notification with this preset and the provided options */
|
||||
public abstract Notification[] buildNotifications(Context context, BuildOptions options);
|
||||
|
||||
/** Whether actions are required to use this preset. */
|
||||
public boolean actionsRequired() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Number of background pickers required */
|
||||
public int countBackgroundPickersRequired() {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,479 @@
|
||||
/*
|
||||
* Copyright (C) 2014 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.support.wearable.notifications;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.content.Context;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.Typeface;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
import android.text.SpannableStringBuilder;
|
||||
import android.text.style.ForegroundColorSpan;
|
||||
import android.text.style.RelativeSizeSpan;
|
||||
import android.text.style.StrikethroughSpan;
|
||||
import android.text.style.StyleSpan;
|
||||
import android.text.style.SubscriptSpan;
|
||||
import android.text.style.SuperscriptSpan;
|
||||
import android.text.style.TypefaceSpan;
|
||||
import android.text.style.UnderlineSpan;
|
||||
import android.view.Gravity;
|
||||
|
||||
/**
|
||||
* Collection of notification builder presets.
|
||||
*/
|
||||
public class NotificationPresets {
|
||||
private static final String EXAMPLE_GROUP_KEY = "example";
|
||||
|
||||
public static final NotificationPreset BASIC = new BasicNotificationPreset();
|
||||
public static final NotificationPreset STYLIZED_TEXT = new StylizedTextNotificationPreset();
|
||||
public static final NotificationPreset INBOX = new InboxNotificationPreset();
|
||||
public static final NotificationPreset BIG_PICTURE = new BigPictureNotificationPreset();
|
||||
public static final NotificationPreset BIG_TEXT = new BigTextNotificationPreset();
|
||||
public static final NotificationPreset BOTTOM_ALIGNED = new BottomAlignedNotificationPreset();
|
||||
public static final NotificationPreset GRAVITY = new GravityNotificationPreset();
|
||||
public static final NotificationPreset CONTENT_ACTION = new ContentActionNotificationPreset();
|
||||
public static final NotificationPreset CONTENT_ICON = new ContentIconNotificationPreset();
|
||||
public static final NotificationPreset MULTIPLE_PAGE = new MultiplePageNotificationPreset();
|
||||
public static final NotificationPreset BUNDLE = new NotificationBundlePreset();
|
||||
|
||||
public static final NotificationPreset[] PRESETS = new NotificationPreset[] {
|
||||
BASIC,
|
||||
STYLIZED_TEXT,
|
||||
INBOX,
|
||||
BIG_PICTURE,
|
||||
BIG_TEXT,
|
||||
BOTTOM_ALIGNED,
|
||||
GRAVITY,
|
||||
CONTENT_ACTION,
|
||||
CONTENT_ICON,
|
||||
MULTIPLE_PAGE,
|
||||
BUNDLE
|
||||
};
|
||||
|
||||
private static NotificationCompat.Builder applyBasicOptions(Context context,
|
||||
NotificationCompat.Builder builder, NotificationCompat.WearableExtender wearableOptions,
|
||||
NotificationPreset.BuildOptions options) {
|
||||
builder.setContentTitle(options.titlePreset)
|
||||
.setContentText(options.textPreset)
|
||||
.setSmallIcon(R.mipmap.ic_launcher)
|
||||
.setDeleteIntent(NotificationUtil.getExamplePendingIntent(
|
||||
context, R.string.example_notification_deleted));
|
||||
options.actionsPreset.apply(context, builder, wearableOptions);
|
||||
options.priorityPreset.apply(builder, wearableOptions);
|
||||
if (options.includeLargeIcon) {
|
||||
builder.setLargeIcon(BitmapFactory.decodeResource(
|
||||
context.getResources(), R.drawable.example_large_icon));
|
||||
}
|
||||
if (options.isLocalOnly) {
|
||||
builder.setLocalOnly(true);
|
||||
}
|
||||
if (options.hasContentIntent) {
|
||||
builder.setContentIntent(NotificationUtil.getExamplePendingIntent(context,
|
||||
R.string.content_intent_clicked));
|
||||
}
|
||||
if (options.vibrate) {
|
||||
builder.setVibrate(new long[] {0, 100, 50, 100} );
|
||||
}
|
||||
return builder;
|
||||
}
|
||||
|
||||
private static class BasicNotificationPreset extends NotificationPreset {
|
||||
public BasicNotificationPreset() {
|
||||
super(R.string.basic_example, R.string.example_content_title,
|
||||
R.string.example_content_text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Notification[] buildNotifications(Context context, BuildOptions options) {
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
|
||||
NotificationCompat.WearableExtender wearableOptions =
|
||||
new NotificationCompat.WearableExtender();
|
||||
applyBasicOptions(context, builder, wearableOptions, options);
|
||||
builder.extend(wearableOptions);
|
||||
return new Notification[] { builder.build() };
|
||||
}
|
||||
}
|
||||
|
||||
private static class StylizedTextNotificationPreset extends NotificationPreset {
|
||||
public StylizedTextNotificationPreset() {
|
||||
super(R.string.stylized_text_example, R.string.example_content_title,
|
||||
R.string.example_content_text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Notification[] buildNotifications(Context context, BuildOptions options) {
|
||||
NotificationCompat.BigTextStyle style = new NotificationCompat.BigTextStyle();
|
||||
|
||||
SpannableStringBuilder title = new SpannableStringBuilder();
|
||||
appendStyled(title, "Stylized", new StyleSpan(Typeface.BOLD_ITALIC));
|
||||
title.append(" title");
|
||||
SpannableStringBuilder text = new SpannableStringBuilder("Stylized text: ");
|
||||
appendStyled(text, "C", new ForegroundColorSpan(Color.RED));
|
||||
appendStyled(text, "O", new ForegroundColorSpan(Color.GREEN));
|
||||
appendStyled(text, "L", new ForegroundColorSpan(Color.BLUE));
|
||||
appendStyled(text, "O", new ForegroundColorSpan(Color.YELLOW));
|
||||
appendStyled(text, "R", new ForegroundColorSpan(Color.MAGENTA));
|
||||
appendStyled(text, "S", new ForegroundColorSpan(Color.CYAN));
|
||||
text.append("; ");
|
||||
appendStyled(text, "1.25x size", new RelativeSizeSpan(1.25f));
|
||||
text.append("; ");
|
||||
appendStyled(text, "0.75x size", new RelativeSizeSpan(0.75f));
|
||||
text.append("; ");
|
||||
appendStyled(text, "underline", new UnderlineSpan());
|
||||
text.append("; ");
|
||||
appendStyled(text, "strikethrough", new StrikethroughSpan());
|
||||
text.append("; ");
|
||||
appendStyled(text, "bold", new StyleSpan(Typeface.BOLD));
|
||||
text.append("; ");
|
||||
appendStyled(text, "italic", new StyleSpan(Typeface.ITALIC));
|
||||
text.append("; ");
|
||||
appendStyled(text, "sans-serif-thin", new TypefaceSpan("sans-serif-thin"));
|
||||
text.append("; ");
|
||||
appendStyled(text, "monospace", new TypefaceSpan("monospace"));
|
||||
text.append("; ");
|
||||
appendStyled(text, "sub", new SubscriptSpan());
|
||||
text.append("script");
|
||||
appendStyled(text, "super", new SuperscriptSpan());
|
||||
|
||||
style.setBigContentTitle(title);
|
||||
style.bigText(text);
|
||||
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
|
||||
.setStyle(style);
|
||||
NotificationCompat.WearableExtender wearableOptions =
|
||||
new NotificationCompat.WearableExtender();
|
||||
applyBasicOptions(context, builder, wearableOptions, options);
|
||||
builder.extend(wearableOptions);
|
||||
return new Notification[] { builder.build() };
|
||||
}
|
||||
|
||||
private void appendStyled(SpannableStringBuilder builder, String str, Object... spans) {
|
||||
builder.append(str);
|
||||
for (Object span : spans) {
|
||||
builder.setSpan(span, builder.length() - str.length(), builder.length(), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class InboxNotificationPreset extends NotificationPreset {
|
||||
public InboxNotificationPreset() {
|
||||
super(R.string.inbox_example, R.string.example_content_title,
|
||||
R.string.example_content_text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Notification[] buildNotifications(Context context, BuildOptions options) {
|
||||
NotificationCompat.InboxStyle style = new NotificationCompat.InboxStyle();
|
||||
style.addLine(context.getString(R.string.inbox_style_example_line1));
|
||||
style.addLine(context.getString(R.string.inbox_style_example_line2));
|
||||
style.addLine(context.getString(R.string.inbox_style_example_line3));
|
||||
style.setBigContentTitle(context.getString(R.string.inbox_style_example_title));
|
||||
style.setSummaryText(context.getString(R.string.inbox_style_example_summary_text));
|
||||
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
|
||||
.setStyle(style);
|
||||
NotificationCompat.WearableExtender wearableOptions =
|
||||
new NotificationCompat.WearableExtender();
|
||||
applyBasicOptions(context, builder, wearableOptions, options);
|
||||
builder.extend(wearableOptions);
|
||||
return new Notification[] { builder.build() };
|
||||
}
|
||||
}
|
||||
|
||||
private static class BigPictureNotificationPreset extends NotificationPreset {
|
||||
public BigPictureNotificationPreset() {
|
||||
super(R.string.big_picture_example, R.string.example_content_title,
|
||||
R.string.example_content_text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Notification[] buildNotifications(Context context, BuildOptions options) {
|
||||
NotificationCompat.BigPictureStyle style = new NotificationCompat.BigPictureStyle();
|
||||
style.bigPicture(BitmapFactory.decodeResource(context.getResources(),
|
||||
R.drawable.example_big_picture));
|
||||
style.setBigContentTitle(context.getString(R.string.big_picture_style_example_title));
|
||||
style.setSummaryText(context.getString(
|
||||
R.string.big_picture_style_example_summary_text));
|
||||
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
|
||||
.setStyle(style);
|
||||
NotificationCompat.WearableExtender wearableOptions =
|
||||
new NotificationCompat.WearableExtender();
|
||||
applyBasicOptions(context, builder, wearableOptions, options);
|
||||
builder.extend(wearableOptions);
|
||||
return new Notification[] { builder.build() };
|
||||
}
|
||||
}
|
||||
|
||||
private static class BigTextNotificationPreset extends NotificationPreset {
|
||||
public BigTextNotificationPreset() {
|
||||
super(R.string.big_text_example, R.string.example_content_title,
|
||||
R.string.example_content_text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Notification[] buildNotifications(Context context, BuildOptions options) {
|
||||
NotificationCompat.BigTextStyle style = new NotificationCompat.BigTextStyle();
|
||||
style.bigText(context.getString(R.string.big_text_example_big_text));
|
||||
style.setBigContentTitle(context.getString(R.string.big_text_example_title));
|
||||
style.setSummaryText(context.getString(R.string.big_text_example_summary_text));
|
||||
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
|
||||
.setStyle(style);
|
||||
NotificationCompat.WearableExtender wearableOptions =
|
||||
new NotificationCompat.WearableExtender();
|
||||
applyBasicOptions(context, builder, wearableOptions, options);
|
||||
builder.extend(wearableOptions);
|
||||
return new Notification[] { builder.build() };
|
||||
}
|
||||
}
|
||||
|
||||
private static class BottomAlignedNotificationPreset extends NotificationPreset {
|
||||
public BottomAlignedNotificationPreset() {
|
||||
super(R.string.bottom_aligned_example, R.string.example_content_title,
|
||||
R.string.example_content_text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Notification[] buildNotifications(Context context, BuildOptions options) {
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
|
||||
NotificationCompat.WearableExtender wearableOptions =
|
||||
new NotificationCompat.WearableExtender();
|
||||
applyBasicOptions(context, builder, wearableOptions, options);
|
||||
|
||||
NotificationCompat.Builder secondPageBuilder = new NotificationCompat.Builder(context);
|
||||
secondPageBuilder.setContentTitle(
|
||||
context.getString(R.string.second_page_content_title));
|
||||
secondPageBuilder.setContentText(context.getString(R.string.big_text_example_big_text));
|
||||
secondPageBuilder.extend(new NotificationCompat.WearableExtender()
|
||||
.setStartScrollBottom(true));
|
||||
|
||||
wearableOptions.addPage(secondPageBuilder.build());
|
||||
builder.extend(wearableOptions);
|
||||
return new Notification[] { builder.build() };
|
||||
}
|
||||
}
|
||||
|
||||
private static class GravityNotificationPreset extends NotificationPreset {
|
||||
public GravityNotificationPreset() {
|
||||
super(R.string.gravity_example, R.string.example_content_title,
|
||||
R.string.example_content_text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Notification[] buildNotifications(Context context, BuildOptions options) {
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
|
||||
NotificationCompat.WearableExtender wearableOptions =
|
||||
new NotificationCompat.WearableExtender();
|
||||
applyBasicOptions(context, builder, wearableOptions, options);
|
||||
|
||||
NotificationCompat.Builder secondPageBuilder = new NotificationCompat.Builder(context)
|
||||
.setContentTitle(options.titlePreset)
|
||||
.setContentText(options.textPreset)
|
||||
.extend(new NotificationCompat.WearableExtender()
|
||||
.setGravity(Gravity.CENTER_VERTICAL));
|
||||
wearableOptions.addPage(secondPageBuilder.build());
|
||||
|
||||
NotificationCompat.Builder thirdPageBuilder = new NotificationCompat.Builder(context)
|
||||
.setContentTitle(options.titlePreset)
|
||||
.setContentText(options.textPreset)
|
||||
.extend(new NotificationCompat.WearableExtender()
|
||||
.setGravity(Gravity.TOP));
|
||||
wearableOptions.addPage(thirdPageBuilder.build());
|
||||
|
||||
wearableOptions.setGravity(Gravity.BOTTOM);
|
||||
builder.extend(wearableOptions);
|
||||
return new Notification[] { builder.build() };
|
||||
}
|
||||
}
|
||||
|
||||
private static class ContentActionNotificationPreset extends NotificationPreset {
|
||||
public ContentActionNotificationPreset() {
|
||||
super(R.string.content_action_example, R.string.example_content_title,
|
||||
R.string.example_content_text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Notification[] buildNotifications(Context context, BuildOptions options) {
|
||||
Notification secondPage = new NotificationCompat.Builder(context)
|
||||
.setContentTitle(context.getString(R.string.second_page_content_title))
|
||||
.setContentText(context.getString(R.string.second_page_content_text))
|
||||
.extend(new NotificationCompat.WearableExtender()
|
||||
.setContentAction(1))
|
||||
.build();
|
||||
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
|
||||
NotificationCompat.Action action = new NotificationCompat.Action.Builder(
|
||||
R.drawable.ic_result_open, null, NotificationUtil.getExamplePendingIntent(
|
||||
context, R.string.example_content_action_clicked)).build();
|
||||
NotificationCompat.Action action2 = new NotificationCompat.Action.Builder(
|
||||
R.drawable.ic_result_open, null, NotificationUtil.getExamplePendingIntent(
|
||||
context, R.string.example_content_action2_clicked)).build();
|
||||
NotificationCompat.WearableExtender wearableOptions =
|
||||
new NotificationCompat.WearableExtender()
|
||||
.addAction(action)
|
||||
.addAction(action2)
|
||||
.addPage(secondPage)
|
||||
.setContentAction(0)
|
||||
.setHintHideIcon(true);
|
||||
applyBasicOptions(context, builder, wearableOptions, options);
|
||||
builder.extend(wearableOptions);
|
||||
return new Notification[] { builder.build() };
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean actionsRequired() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
private static class ContentIconNotificationPreset extends NotificationPreset {
|
||||
public ContentIconNotificationPreset() {
|
||||
super(R.string.content_icon_example, R.string.example_content_title,
|
||||
R.string.example_content_text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Notification[] buildNotifications(Context context, BuildOptions options) {
|
||||
Notification secondPage = new NotificationCompat.Builder(context)
|
||||
.setContentTitle(context.getString(R.string.second_page_content_title))
|
||||
.setContentText(context.getString(R.string.second_page_content_text))
|
||||
.extend(new NotificationCompat.WearableExtender()
|
||||
.setContentIcon(R.drawable.content_icon_small)
|
||||
.setContentIconGravity(Gravity.START))
|
||||
.build();
|
||||
|
||||
Notification thirdPage = new NotificationCompat.Builder(context)
|
||||
.setContentTitle(context.getString(R.string.third_page_content_title))
|
||||
.setContentText(context.getString(R.string.third_page_content_text))
|
||||
.extend(new NotificationCompat.WearableExtender()
|
||||
.setContentIcon(R.drawable.content_icon_large))
|
||||
.build();
|
||||
|
||||
Notification fourthPage = new NotificationCompat.Builder(context)
|
||||
.setContentTitle(context.getString(R.string.fourth_page_content_title))
|
||||
.setContentText(context.getString(R.string.fourth_page_content_text))
|
||||
.extend(new NotificationCompat.WearableExtender()
|
||||
.setContentIcon(R.drawable.content_icon_large)
|
||||
.setContentIconGravity(Gravity.START))
|
||||
.build();
|
||||
|
||||
NotificationCompat.Builder builder = new NotificationCompat.Builder(context);
|
||||
NotificationCompat.WearableExtender wearableOptions =
|
||||
new NotificationCompat.WearableExtender()
|
||||
.setHintHideIcon(true)
|
||||
.setContentIcon(R.drawable.content_icon_small)
|
||||
.addPage(secondPage)
|
||||
.addPage(thirdPage)
|
||||
.addPage(fourthPage);
|
||||
applyBasicOptions(context, builder, wearableOptions, options);
|
||||
builder.extend(wearableOptions);
|
||||
return new Notification[] { builder.build() };
|
||||
}
|
||||
}
|
||||
|
||||
private static class MultiplePageNotificationPreset extends NotificationPreset {
|
||||
public MultiplePageNotificationPreset() {
|
||||
super(R.string.multiple_page_example, R.string.example_content_title,
|
||||
R.string.example_content_text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Notification[] buildNotifications(Context context, BuildOptions options) {
|
||||
NotificationCompat.Builder secondPageBuilder = new NotificationCompat.Builder(context)
|
||||
.setContentTitle(context.getString(R.string.second_page_content_title))
|
||||
.setContentText(context.getString(R.string.second_page_content_text));
|
||||
|
||||
NotificationCompat.Builder firstPageBuilder = new NotificationCompat.Builder(context);
|
||||
NotificationCompat.WearableExtender firstPageWearableOptions =
|
||||
new NotificationCompat.WearableExtender();
|
||||
applyBasicOptions(context, firstPageBuilder, firstPageWearableOptions, options);
|
||||
|
||||
Integer firstBackground = options.backgroundIds == null
|
||||
? null : options.backgroundIds[0];
|
||||
if (firstBackground != null) {
|
||||
NotificationCompat.BigPictureStyle style =
|
||||
new NotificationCompat.BigPictureStyle();
|
||||
style.bigPicture(BitmapFactory.decodeResource(context.getResources(),
|
||||
firstBackground));
|
||||
firstPageBuilder.setStyle(style);
|
||||
}
|
||||
|
||||
Integer secondBackground = options.backgroundIds == null
|
||||
? null : options.backgroundIds[1];
|
||||
if (secondBackground != null) {
|
||||
NotificationCompat.BigPictureStyle style = new NotificationCompat.BigPictureStyle();
|
||||
style.bigPicture(BitmapFactory.decodeResource(context.getResources(),
|
||||
secondBackground));
|
||||
secondPageBuilder.setStyle(style);
|
||||
}
|
||||
|
||||
firstPageBuilder.extend(
|
||||
firstPageWearableOptions.addPage(secondPageBuilder.build()));
|
||||
|
||||
return new Notification[]{ firstPageBuilder.build() };
|
||||
}
|
||||
|
||||
@Override
|
||||
public int countBackgroundPickersRequired() {
|
||||
return 2; // This sample does 2 pages notifications.
|
||||
}
|
||||
}
|
||||
|
||||
private static class NotificationBundlePreset extends NotificationPreset {
|
||||
public NotificationBundlePreset() {
|
||||
super(R.string.bundle_example, R.string.example_content_title,
|
||||
R.string.example_content_text);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Notification[] buildNotifications(Context context, BuildOptions options) {
|
||||
NotificationCompat.Builder childBuilder1 = new NotificationCompat.Builder(context)
|
||||
.setContentTitle(context.getString(R.string.first_child_content_title))
|
||||
.setContentText(context.getString(R.string.first_child_content_text))
|
||||
.setSmallIcon(R.mipmap.ic_launcher)
|
||||
.setLocalOnly(options.isLocalOnly)
|
||||
.setGroup(EXAMPLE_GROUP_KEY)
|
||||
.setSortKey("0");
|
||||
|
||||
NotificationCompat.Builder childBuilder2 = new NotificationCompat.Builder(context)
|
||||
.setContentTitle(context.getString(R.string.second_child_content_title))
|
||||
.setContentText(context.getString(R.string.second_child_content_text))
|
||||
.setSmallIcon(R.mipmap.ic_launcher)
|
||||
.addAction(R.mipmap.ic_launcher,
|
||||
context.getString(R.string.second_child_action),
|
||||
NotificationUtil.getExamplePendingIntent(
|
||||
context, R.string.second_child_action_clicked))
|
||||
.setLocalOnly(options.isLocalOnly)
|
||||
.setGroup(EXAMPLE_GROUP_KEY)
|
||||
.setSortKey("1");
|
||||
|
||||
NotificationCompat.Builder summaryBuilder = new NotificationCompat.Builder(context)
|
||||
.setGroup(EXAMPLE_GROUP_KEY)
|
||||
.setGroupSummary(true);
|
||||
|
||||
NotificationCompat.WearableExtender summaryWearableOptions =
|
||||
new NotificationCompat.WearableExtender();
|
||||
applyBasicOptions(context, summaryBuilder, summaryWearableOptions, options);
|
||||
summaryBuilder.extend(summaryWearableOptions);
|
||||
|
||||
return new Notification[] { summaryBuilder.build(), childBuilder1.build(),
|
||||
childBuilder2.build() };
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2014 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.support.wearable.notifications;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
|
||||
public class NotificationUtil {
|
||||
public static final String EXTRA_MESSAGE =
|
||||
"com.example.android.support.wearable.notifications.MESSAGE";
|
||||
public static final String EXTRA_REPLY =
|
||||
"com.example.android.support.wearable.notifications.REPLY";
|
||||
|
||||
public static PendingIntent getExamplePendingIntent(Context context, int messageResId) {
|
||||
Intent intent = new Intent(NotificationIntentReceiver.ACTION_EXAMPLE)
|
||||
.setClass(context, NotificationIntentReceiver.class);
|
||||
intent.putExtra(EXTRA_MESSAGE, context.getString(messageResId));
|
||||
return PendingIntent.getBroadcast(context, messageResId /* requestCode */, intent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* Copyright (C) 2014 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.support.wearable.notifications;
|
||||
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
|
||||
/**
|
||||
* Base class for notification priority presets.
|
||||
*/
|
||||
public abstract class PriorityPreset extends NamedPreset {
|
||||
public PriorityPreset(int nameResId) {
|
||||
super(nameResId);
|
||||
}
|
||||
|
||||
/** Apply the priority to a notification builder */
|
||||
public abstract void apply(NotificationCompat.Builder builder,
|
||||
NotificationCompat.WearableExtender wearableOptions);
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2014 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.support.wearable.notifications;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
|
||||
/**
|
||||
* Collection of notification priority presets.
|
||||
*/
|
||||
public class PriorityPresets {
|
||||
public static final PriorityPreset DEFAULT = new SimplePriorityPreset(
|
||||
R.string.default_priority, Notification.PRIORITY_DEFAULT);
|
||||
|
||||
public static final PriorityPreset[] PRESETS = new PriorityPreset[] {
|
||||
new SimplePriorityPreset(R.string.min_priority, Notification.PRIORITY_MIN),
|
||||
new SimplePriorityPreset(R.string.low_priority, Notification.PRIORITY_LOW),
|
||||
DEFAULT,
|
||||
new SimplePriorityPreset(R.string.high_priority, Notification.PRIORITY_HIGH),
|
||||
new SimplePriorityPreset(R.string.max_priority, Notification.PRIORITY_MAX)
|
||||
};
|
||||
|
||||
/**
|
||||
* Simple notification priority preset that sets a priority using
|
||||
* {@link android.support.v4.app.NotificationCompat.Builder#setPriority}
|
||||
*/
|
||||
private static class SimplePriorityPreset extends PriorityPreset {
|
||||
private final int mPriority;
|
||||
|
||||
public SimplePriorityPreset(int nameResId, int priority) {
|
||||
super(nameResId);
|
||||
mPriority = priority;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void apply(NotificationCompat.Builder builder,
|
||||
NotificationCompat.WearableExtender wearableOptions) {
|
||||
builder.setPriority(mPriority);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user