Skip to content

Most visited

Recently visited

navigation
WearNotifications / Wearable / src / com.example.android.wearable.wear.wearnotifications /

StandaloneMainActivity.java

1
/*
2
 * Copyright (C) 2016 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
package com.example.android.wearable.wear.wearnotifications;
17
 
18
import android.app.Notification;
19
import android.app.PendingIntent;
20
import android.content.Intent;
21
import android.graphics.BitmapFactory;
22
import android.os.Build;
23
import android.os.Bundle;
24
import android.support.design.widget.Snackbar;
25
import android.support.v4.app.NotificationCompat.BigPictureStyle;
26
import android.support.v4.app.NotificationCompat.BigTextStyle;
27
import android.support.v4.app.NotificationCompat.InboxStyle;
28
import android.support.v4.app.NotificationCompat.MessagingStyle;
29
import android.support.v4.app.NotificationManagerCompat;
30
import android.support.v4.app.RemoteInput;
31
import android.support.v7.app.NotificationCompat;
32
import android.support.wearable.activity.WearableActivity;
33
import android.support.wearable.view.WearableRecyclerView;
34
import android.util.Log;
35
import android.view.View;
36
import android.widget.FrameLayout;
37
 
38
import com.example.android.wearable.wear.wearnotifications.handlers.BigPictureSocialIntentService;
39
import com.example.android.wearable.wear.wearnotifications.handlers.BigPictureSocialMainActivity;
40
import com.example.android.wearable.wear.wearnotifications.handlers.BigTextIntentService;
41
import com.example.android.wearable.wear.wearnotifications.handlers.BigTextMainActivity;
42
import com.example.android.wearable.wear.wearnotifications.handlers.InboxMainActivity;
43
import com.example.android.wearable.wear.wearnotifications.handlers.MessagingIntentService;
44
import com.example.android.wearable.wear.wearnotifications.handlers.MessagingMainActivity;
45
import com.example.android.wearable.wear.wearnotifications.mock.MockDatabase;
46
 
47
/**
48
 * Demonstrates best practice for {@link NotificationCompat} Notifications created by local
49
 * standalone Android Wear apps. All {@link NotificationCompat} examples use
50
 * {@link NotificationCompat.Style}.
51
 */
52
public class StandaloneMainActivity extends WearableActivity {
53
 
54
    private static final String TAG = "StandaloneMainActivity";
55
 
56
    public static final int NOTIFICATION_ID = 888;
57
 
58
    /*
59
     * Used to represent each major {@link NotificationCompat.Style} in the
60
     * {@link WearableRecyclerView}. These constants are also used in a switch statement when one
61
     * of the items is selected to create the appropriate {@link Notification}.
62
     */
63
    private static final String BIG_TEXT_STYLE = "BIG_TEXT_STYLE";
64
    private static final String BIG_PICTURE_STYLE = "BIG_PICTURE_STYLE";
65
    private static final String INBOX_STYLE = "INBOX_STYLE";
66
    private static final String MESSAGING_STYLE = "MESSAGING_STYLE";
67
 
68
    /*
69
    Collection of major {@link NotificationCompat.Style} to create {@link CustomRecyclerAdapter}
70
    for {@link WearableRecyclerView}.
71
    */
72
    private static final String[] NOTIFICATION_STYLES =
73
            {BIG_TEXT_STYLE, BIG_PICTURE_STYLE, INBOX_STYLE, MESSAGING_STYLE};
74
 
75
    private NotificationManagerCompat mNotificationManagerCompat;
76
 
77
    // Needed for {@link SnackBar} to alert users when {@link Notification} are disabled for app.
78
    private FrameLayout mMainFrameLayout;
79
    private WearableRecyclerView mWearableRecyclerView;
80
    private CustomRecyclerAdapter mCustomRecyclerAdapter;
81
 
82
    @Override
83
    protected void onCreate(Bundle savedInstanceState) {
84
        super.onCreate(savedInstanceState);
85
        Log.d(TAG, "onCreate()");
86
 
87
        setContentView(R.layout.activity_main);
88
        setAmbientEnabled();
89
 
90
        mNotificationManagerCompat = NotificationManagerCompat.from(getApplicationContext());
91
 
92
        mMainFrameLayout = (FrameLayout) findViewById(R.id.mainFrameLayout);
93
        mWearableRecyclerView = (WearableRecyclerView) findViewById(R.id.recycler_view);
94
 
95
        // Aligns the first and last items on the list vertically centered on the screen.
96
        mWearableRecyclerView.setCenterEdgeItems(true);
97
 
98
        // Customizes scrolling (zoom) and offsets of WearableRecyclerView's items
99
        ScalingOffsettingHelper scalingOffsettingHelper = new ScalingOffsettingHelper();
100
        mWearableRecyclerView.setOffsettingHelper(scalingOffsettingHelper);
101
 
102
        // Improves performance because we know changes in content do not change the layout size of
103
        // the RecyclerView.
104
        mWearableRecyclerView.setHasFixedSize(true);
105
 
106
        // Specifies an adapter (see also next example).
107
        mCustomRecyclerAdapter = new CustomRecyclerAdapter(
108
                NOTIFICATION_STYLES,
109
                // Controller passes selected data from the Adapter out to this Activity to trigger
110
                // updates in the UI/Notifications.
111
                new Controller(this));
112
 
113
        mWearableRecyclerView.setAdapter(mCustomRecyclerAdapter);
114
    }
115
 
116
    // Called by WearableRecyclerView when an item is selected (check onCreate() for initialization)
117
    public void itemSelected(String data) {
118
 
119
        Log.d(TAG, "itemSelected()");
120
 
121
        boolean areNotificationsEnabled = mNotificationManagerCompat.areNotificationsEnabled();
122
 
123
        // If notifications are disabled, allow user to enable.
124
        if (!areNotificationsEnabled) {
125
            // Because the user took an action to create a notification, we create a prompt to let
126
            // the user re-enable notifications for this application again.
127
            Snackbar snackbar = Snackbar
128
                    .make(
129
                            mMainFrameLayout,
130
                            "", // Not enough space for both text and action text
131
                            Snackbar.LENGTH_LONG)
132
                    .setAction("Enable Notifications", new View.OnClickListener() {
133
                        @Override
134
                        public void onClick(View view) {
135
                            // Links to this app's notification settings
136
                            openNotificationSettingsForApp();
137
                        }
138
                    });
139
            snackbar.show();
140
            return;
141
        }
142
 
143
        String notificationStyle = data;
144
 
145
        switch (notificationStyle) {
146
            case BIG_TEXT_STYLE:
147
                generateBigTextStyleNotification();
148
                break;
149
 
150
            case BIG_PICTURE_STYLE:
151
                generateBigPictureStyleNotification();
152
                break;
153
 
154
            case INBOX_STYLE:
155
                generateInboxStyleNotification();
156
                break;
157
 
158
            case MESSAGING_STYLE:
159
                generateMessagingStyleNotification();
160
                break;
161
 
162
            default:
163
                // continue below
164
        }
165
    }
166
 
167
    /*
168
     * Generates a BIG_TEXT_STYLE Notification that supports both Wear 1.+ and Wear 2.0.
169
     *
170
     * IMPORTANT NOTE:
171
     * This method includes extra code to replicate Notification Styles behavior from Wear 1.+ and
172
     * phones on Wear 2.0, i.e., the notification expands on click. To see the specific code in the
173
     * method, search for "REPLICATE_NOTIFICATION_STYLE_CODE".
174
     *
175
     * Notification Styles behave slightly different on Wear 2.0 when they are launched by a
176
     * native/local Wear app, i.e., they will NOT expand when the user taps them but will instead
177
     * take the user directly into the local app for the richest experience. In contrast, a bridged
178
     * Notification launched from the phone will expand with the style details (whether there is a
179
     * local app or not).
180
     *
181
     * If you want to see the new behavior, please review the generateBigPictureStyleNotification()
182
     * and generateMessagingStyleNotification() methods.
183
     */
184
    private void generateBigTextStyleNotification() {
185
 
186
        Log.d(TAG, "generateBigTextStyleNotification()");
187
 
188
        // Main steps for building a BIG_TEXT_STYLE notification:
189
        //      0. Get your data
190
        //      1. Build the BIG_TEXT_STYLE
191
        //      2. Set up main Intent for notification
192
        //      3. Create additional Actions for the Notification
193
        //      4. Build and issue the notification
194
 
195
        // 0. Get your data (everything unique per Notification)
196
        MockDatabase.BigTextStyleReminderAppData bigTextStyleReminderAppData =
197
                MockDatabase.getBigTextStyleData();
198
 
199
        // 1. Build the BIG_TEXT_STYLE
200
        BigTextStyle bigTextStyle = new NotificationCompat.BigTextStyle()
201
                // Overrides ContentText in the big form of the template
202
                .bigText(bigTextStyleReminderAppData.getBigText())
203
                // Overrides ContentTitle in the big form of the template
204
                .setBigContentTitle(bigTextStyleReminderAppData.getBigContentTitle())
205
                // Summary line after the detail section in the big form of the template
206
                // Note: To improve readability, don't overload the user with info. If Summary Text
207
                // doesn't add critical information, you should skip it.
208
                .setSummaryText(bigTextStyleReminderAppData.getSummaryText());
209
 
210
 
211
        // 2. Set up main Intent for notification
212
        Intent mainIntent = new Intent(this, BigTextMainActivity.class);
213
 
214
        PendingIntent mainPendingIntent =
215
                PendingIntent.getActivity(
216
                        this,
217
                        0,
218
                        mainIntent,
219
                        PendingIntent.FLAG_UPDATE_CURRENT
220
                );
221
 
222
 
223
        // 3. Create additional Actions (Intents) for the Notification
224
 
225
        // In our case, we create two additional actions: a Snooze action and a Dismiss action.
226
 
227
        // Snooze Action
228
        Intent snoozeIntent = new Intent(this, BigTextIntentService.class);
229
        snoozeIntent.setAction(BigTextIntentService.ACTION_SNOOZE);
230
 
231
        PendingIntent snoozePendingIntent = PendingIntent.getService(this, 0, snoozeIntent, 0);
232
        NotificationCompat.Action snoozeAction =
233
                new NotificationCompat.Action.Builder(
234
                        R.drawable.ic_alarm_white_48dp,
235
                        "Snooze",
236
                        snoozePendingIntent)
237
                        .build();
238
 
239
        // Dismiss Action
240
        Intent dismissIntent = new Intent(this, BigTextIntentService.class);
241
        dismissIntent.setAction(BigTextIntentService.ACTION_DISMISS);
242
 
243
        PendingIntent dismissPendingIntent = PendingIntent.getService(this, 0, dismissIntent, 0);
244
        NotificationCompat.Action dismissAction =
245
                new NotificationCompat.Action.Builder(
246
                        R.drawable.ic_cancel_white_48dp,
247
                        "Dismiss",
248
                        dismissPendingIntent)
249
                        .build();
250
 
251
 
252
        // 4. Build and issue the notification
253
 
254
        // Because we want this to be a new notification (not updating a previous notification), we
255
        // create a new Builder. Later, we use the same global builder to get back the notification
256
        // we built here for the snooze action, that is, canceling the notification and relaunching
257
        // it several seconds later.
258
 
259
        NotificationCompat.Builder notificationCompatBuilder =
260
                new NotificationCompat.Builder(getApplicationContext());
261
 
262
        GlobalNotificationBuilder.setNotificationCompatBuilderInstance(notificationCompatBuilder);
263
 
264
        notificationCompatBuilder
265
                // BIG_TEXT_STYLE sets title and content
266
                .setStyle(bigTextStyle)
267
                .setContentTitle(bigTextStyleReminderAppData.getContentTitle())
268
                .setContentText(bigTextStyleReminderAppData.getContentText())
269
                .setSmallIcon(R.drawable.ic_launcher)
270
                .setLargeIcon(BitmapFactory.decodeResource(
271
                        getResources(),
272
                        R.drawable.ic_alarm_white_48dp))
273
                // Set primary color (important for Wear 2.0 Notifications)
274
                .setColor(getResources().getColor(R.color.colorPrimary))
275
 
276
                .setCategory(Notification.CATEGORY_REMINDER)
277
                .setPriority(Notification.PRIORITY_HIGH)
278
 
279
                // Shows content on the lock-screen
280
                .setVisibility(Notification.VISIBILITY_PUBLIC)
281
 
282
                // Adds additional actions specified above
283
                .addAction(snoozeAction)
284
                .addAction(dismissAction);
285
 
286
        /* REPLICATE_NOTIFICATION_STYLE_CODE:
287
         * You can replicate Notification Style functionality on Wear 2.0 (24+) by not setting the
288
         *