SampleSliceProvider.java revision 5ca9e16f4e8038f57d144024dff74c946a41c463
1/*
2 * Copyright 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.example.androidx.slice.demos;
18
19import static android.text.Spanned.SPAN_EXCLUSIVE_EXCLUSIVE;
20
21import android.app.PendingIntent;
22import android.content.ContentResolver;
23import android.content.Context;
24import android.content.Intent;
25import android.graphics.drawable.Icon;
26import android.net.Uri;
27import android.net.wifi.WifiManager;
28import android.os.Handler;
29import android.provider.Settings;
30import android.support.annotation.NonNull;
31import android.text.SpannableString;
32import android.text.format.DateUtils;
33import android.text.style.ForegroundColorSpan;
34
35import java.util.Calendar;
36
37import androidx.app.slice.Slice;
38import androidx.app.slice.SliceProvider;
39import androidx.app.slice.builders.GridBuilder;
40import androidx.app.slice.builders.ListBuilder;
41import androidx.app.slice.builders.MessagingSliceBuilder;
42import androidx.app.slice.builders.SliceAction;
43
44/**
45 * Examples of using slice template builders.
46 */
47public class SampleSliceProvider extends SliceProvider {
48
49    public static final String ACTION_WIFI_CHANGED =
50            "com.example.androidx.slice.action.WIFI_CHANGED";
51    public static final String ACTION_TOAST =
52            "com.example.androidx.slice.action.TOAST";
53    public static final String EXTRA_TOAST_MESSAGE = "com.example.androidx.extra.TOAST_MESSAGE";
54    public static final String ACTION_TOAST_RANGE_VALUE =
55            "com.example.androidx.slice.action.TOAST_RANGE_VALUE";
56
57    public static final int LOADING_DELAY_MS = 4000;
58
59    public static final String[] URI_PATHS = {"message", "wifi", "note", "ride", "toggle",
60            "toggle2", "contact", "gallery", "weather", "reservation", "loadlist", "loadlist2",
61            "loadgrid", "loadgrid2", "inputrange", "range", "contact2"};
62
63    /**
64     * @return Uri with the provided path
65     */
66    public static Uri getUri(String path, Context context) {
67        return new Uri.Builder()
68                .scheme(ContentResolver.SCHEME_CONTENT)
69                .authority(context.getPackageName())
70                .appendPath(path)
71                .build();
72    }
73
74    @Override
75    public boolean onCreateSliceProvider() {
76        return true;
77    }
78
79    @NonNull
80    @Override
81    public Uri onMapIntentToUri(Intent intent) {
82        return getUri("wifi", getContext());
83    }
84
85    @Override
86    public Slice onBindSlice(Uri sliceUri) {
87        String path = sliceUri.getPath();
88        switch (path) {
89            // TODO: add list / grid slices with 'see more' options
90            case "/message":
91                return createMessagingSlice(sliceUri);
92            case "/wifi":
93                return createWifiSlice(sliceUri);
94            case "/note":
95                return createNoteSlice(sliceUri);
96            case "/ride":
97                return createRideSlice(sliceUri);
98            case "/toggle":
99                return createCustomToggleSlice(sliceUri);
100            case "/toggle2":
101                return createTwoCustomToggleSlices(sliceUri);
102            case "/contact":
103                return createContact(sliceUri);
104            case "/contact2":
105                return createContact2(sliceUri);
106            case "/gallery":
107                return createGallery(sliceUri);
108            case "/weather":
109                return createWeather(sliceUri);
110            case "/reservation":
111                return createReservationSlice(sliceUri);
112            case "/loadlist":
113                return createLoadingSlice(sliceUri, false /* loadAll */, true /* isList */);
114            case "/loadlist2":
115                return createLoadingSlice(sliceUri, true /* loadAll */, true /* isList */);
116            case "/loadgrid":
117                return createLoadingSlice(sliceUri, false /* loadAll */, false /* isList */);
118            case "/loadgrid2":
119                return createLoadingSlice(sliceUri, true /* loadAll */, false /* isList */);
120            case "/inputrange":
121                return createStarRatingInputRange(sliceUri);
122            case "/range":
123                return createDownloadProgressRange(sliceUri);
124        }
125        throw new IllegalArgumentException("Unknown uri " + sliceUri);
126    }
127
128    private Slice createWeather(Uri sliceUri) {
129        SliceAction primaryAction = new SliceAction(getBroadcastIntent(ACTION_TOAST,
130                "open weather app"), Icon.createWithResource(getContext(), R.drawable.weather_1),
131                "Weather is happening!");
132        return new ListBuilder(getContext(), sliceUri).addGrid(gb -> gb
133                .setPrimaryAction(primaryAction)
134                .addCell(cb -> cb
135                        .addImage(Icon.createWithResource(getContext(), R.drawable.weather_1),
136                                GridBuilder.SMALL_IMAGE)
137                        .addText("MON")
138                        .addTitleText("69\u00B0"))
139                .addCell(cb -> cb
140                        .addImage(Icon.createWithResource(getContext(), R.drawable.weather_2),
141                                GridBuilder.SMALL_IMAGE)
142                        .addText("TUE")
143                        .addTitleText("71\u00B0"))
144                .addCell(cb -> cb
145                        .addImage(Icon.createWithResource(getContext(), R.drawable.weather_3),
146                                GridBuilder.SMALL_IMAGE)
147                        .addText("WED")
148                        .addTitleText("76\u00B0"))
149                .addCell(cb -> cb
150                        .addImage(Icon.createWithResource(getContext(), R.drawable.weather_4),
151                                GridBuilder.SMALL_IMAGE)
152                        .addText("THU")
153                        .addTitleText("72\u00B0"))
154                .addCell(cb -> cb
155                        .addImage(Icon.createWithResource(getContext(), R.drawable.weather_1),
156                                GridBuilder.SMALL_IMAGE)
157                        .addText("FRI")
158                        .addTitleText("68\u00B0")))
159                .build();
160    }
161
162    private Slice createGallery(Uri sliceUri) {
163        return new ListBuilder(getContext(), sliceUri)
164                .setColor(0xff4285F4)
165                .addRow(b -> b
166                    .setTitle("Family trip to Hawaii")
167                    .setSubtitle("Sep 30, 2017 - Oct 2, 2017"))
168                .addAction(new SliceAction(
169                        getBroadcastIntent(ACTION_TOAST, "cast photo album"),
170                        Icon.createWithResource(getContext(), R.drawable.ic_cast),
171                        "Cast photo album"))
172                .addAction(new SliceAction(
173                        getBroadcastIntent(ACTION_TOAST, "share photo album"),
174                        Icon.createWithResource(getContext(), R.drawable.ic_share),
175                        "Share photo album"))
176                .addGrid(b -> b
177                    .addCell(cb -> cb
178                        .addImage(Icon.createWithResource(getContext(), R.drawable.slices_1),
179                            GridBuilder.LARGE_IMAGE))
180                    .addCell(cb -> cb
181                        .addImage(Icon.createWithResource(getContext(), R.drawable.slices_2),
182                                GridBuilder.LARGE_IMAGE))
183                    .addCell(cb -> cb
184                        .addImage(Icon.createWithResource(getContext(), R.drawable.slices_3),
185                                GridBuilder.LARGE_IMAGE))
186                    .addCell(cb -> cb
187                        .addImage(Icon.createWithResource(getContext(), R.drawable.slices_4),
188                                GridBuilder.LARGE_IMAGE))
189                    .addCell(cb -> cb
190                        .addImage(Icon.createWithResource(getContext(), R.drawable.slices_2),
191                                GridBuilder.LARGE_IMAGE))
192                    .addCell(cb -> cb
193                        .addImage(Icon.createWithResource(getContext(), R.drawable.slices_3),
194                                GridBuilder.LARGE_IMAGE))
195                    .addCell(cb -> cb
196                        .addImage(Icon.createWithResource(getContext(), R.drawable.slices_4),
197                                GridBuilder.LARGE_IMAGE)))
198                .build();
199    }
200
201
202    private Slice createContact2(Uri sliceUri) {
203        ListBuilder b = new ListBuilder(getContext(), sliceUri);
204        ListBuilder.RowBuilder rb = new ListBuilder.RowBuilder(b);
205        GridBuilder gb = new GridBuilder(b);
206        return b.setColor(0xff3949ab)
207                .addRow(rb
208                        .setTitle("Mady Pitza")
209                        .setSubtitle("Frequently contacted contact")
210                        .addEndItem(Icon.createWithResource(getContext(), R.drawable.mady)))
211                .addGrid(gb
212                        .addCell(new GridBuilder.CellBuilder(gb)
213                                .addImage(Icon.createWithResource(getContext(), R.drawable.ic_call),
214                                        GridBuilder.ICON_IMAGE)
215                                .addText("Call")
216                                .setContentIntent(getBroadcastIntent(ACTION_TOAST, "call")))
217                        .addCell(new GridBuilder.CellBuilder(gb)
218                                .addImage(Icon.createWithResource(getContext(), R.drawable.ic_text),
219                                        GridBuilder.ICON_IMAGE)
220                                .addText("Text")
221                                .setContentIntent(getBroadcastIntent(ACTION_TOAST, "text")))
222                        .addCell(new GridBuilder.CellBuilder(gb)
223                                .addImage(Icon.createWithResource(getContext(),
224                                        R.drawable.ic_video), GridBuilder.ICON_IMAGE)
225                                .setContentIntent(getBroadcastIntent(ACTION_TOAST, "video"))
226                                .addText("Video"))
227                        .addCell(new GridBuilder.CellBuilder(gb)
228                                .addImage(Icon.createWithResource(getContext(),
229                                        R.drawable.ic_email), GridBuilder.ICON_IMAGE)
230                                .addText("Email")
231                                .setContentIntent(getBroadcastIntent(ACTION_TOAST, "email"))))
232                .build();
233    }
234
235    private Slice createContact(Uri sliceUri) {
236        final long lastCalled = System.currentTimeMillis() - 20 * DateUtils.MINUTE_IN_MILLIS;
237        CharSequence lastCalledString = DateUtils.getRelativeTimeSpanString(lastCalled,
238                Calendar.getInstance().getTimeInMillis(),
239                DateUtils.MINUTE_IN_MILLIS, DateUtils.FORMAT_ABBREV_RELATIVE);
240        SliceAction primaryAction = new SliceAction(getBroadcastIntent(ACTION_TOAST,
241                "See contact info"), Icon.createWithResource(getContext(),
242                R.drawable.mady), "Mady");
243        return new ListBuilder(getContext(), sliceUri)
244                .setColor(0xff3949ab)
245                .setHeader(b -> b
246                        .setTitle("Mady Pitza")
247                        .setSummarySubtitle("Called " + lastCalledString)
248                        .setPrimaryAction(primaryAction))
249                .addRow(b -> b
250                        .setTitleItem(Icon.createWithResource(getContext(), R.drawable.ic_call))
251                        .setTitle("314-259-2653")
252                        .setSubtitle("Call lasted 1 hr 17 min")
253                        .addEndItem(lastCalled))
254                .addRow(b -> b
255                        .setTitleItem(Icon.createWithResource(getContext(), R.drawable.ic_text))
256                        .setTitle("You: Coooooool see you then")
257                        .addEndItem(System.currentTimeMillis() - 40 * DateUtils.MINUTE_IN_MILLIS))
258                .addAction(new SliceAction(getBroadcastIntent(ACTION_TOAST, "call"),
259                        Icon.createWithResource(getContext(), R.drawable.ic_call), "Call mady"))
260                .addAction(new SliceAction(getBroadcastIntent(ACTION_TOAST, "text"),
261                        Icon.createWithResource(getContext(), R.drawable.ic_text), "Text mady"))
262                .addAction(new SliceAction(getBroadcastIntent(ACTION_TOAST, "video"),
263                        Icon.createWithResource(getContext(), R.drawable.ic_video),
264                        "Video call mady"))
265                .addAction(new SliceAction(getBroadcastIntent(ACTION_TOAST, "email"),
266                        Icon.createWithResource(getContext(), R.drawable.ic_email), "Email mady"))
267                .build();
268    }
269
270    private Slice createMessagingSlice(Uri sliceUri) {
271        // TODO: Remote input.
272        return new MessagingSliceBuilder(getContext(), sliceUri)
273                .add(b -> b
274                        .addText("yo home \uD83C\uDF55, I emailed you the info")
275                        .addTimestamp(System.currentTimeMillis() - 20 * DateUtils.MINUTE_IN_MILLIS)
276                        .addSource(Icon.createWithResource(getContext(), R.drawable.mady)))
277                .add(b -> b
278                        .addText("just bought my tickets")
279                        .addTimestamp(System.currentTimeMillis() - 10 * DateUtils.MINUTE_IN_MILLIS))
280                .add(b -> b
281                        .addText("yay! can't wait for getContext() weekend!\n"
282                                + "\uD83D\uDE00")
283                        .addTimestamp(System.currentTimeMillis() - 5 * DateUtils.MINUTE_IN_MILLIS)
284                        .addSource(Icon.createWithResource(getContext(), R.drawable.mady)))
285                .build();
286
287    }
288
289    private Slice createNoteSlice(Uri sliceUri) {
290        // TODO: Remote input.
291        return new ListBuilder(getContext(), sliceUri)
292                .setColor(0xfff4b400)
293                .addRow(b -> b.setTitle("Create new note"))
294                .addAction(new SliceAction(getBroadcastIntent(ACTION_TOAST, "create note"),
295                        Icon.createWithResource(getContext(), R.drawable.ic_create),
296                        "Create note"))
297                .addAction(new SliceAction(getBroadcastIntent(ACTION_TOAST, "voice note"),
298                        Icon.createWithResource(getContext(), R.drawable.ic_voice),
299                        "Voice note"))
300                .addAction(new SliceAction(getIntent("android.media.action.IMAGE_CAPTURE"),
301                        Icon.createWithResource(getContext(), R.drawable.ic_camera),
302                        "Photo note"))
303                .build();
304    }
305
306    private Slice createReservationSlice(Uri sliceUri) {
307        return new ListBuilder(getContext(), sliceUri)
308                .setColor(0xffFF5252)
309                .setHeader(b -> b
310                    .setTitle("Upcoming trip to Seattle")
311                    .setSubtitle("Feb 1 - 19 | 2 guests"))
312                .addAction(new SliceAction(
313                        getBroadcastIntent(ACTION_TOAST, "show location on map"),
314                        Icon.createWithResource(getContext(), R.drawable.ic_location),
315                        "Show reservation location"))
316                .addAction(new SliceAction(getBroadcastIntent(ACTION_TOAST, "contact host"),
317                        Icon.createWithResource(getContext(), R.drawable.ic_text),
318                        "Contact host"))
319                .addGrid(b -> b
320                    .addCell(cb -> cb
321                        .addImage(Icon.createWithResource(getContext(), R.drawable.reservation),
322                            GridBuilder.LARGE_IMAGE)))
323                .addGrid(b -> b
324                    .addCell(cb -> cb
325                        .addTitleText("Check In")
326                        .addText("12:00 PM, Feb 1"))
327                    .addCell(cb -> cb
328                        .addTitleText("Check Out")
329                        .addText("11:00 AM, Feb 19")))
330                .build();
331    }
332
333    private Slice createRideSlice(Uri sliceUri) {
334        final ForegroundColorSpan colorSpan = new ForegroundColorSpan(0xff0F9D58);
335        SpannableString headerSubtitle = new SpannableString("Ride in 4 min");
336        headerSubtitle.setSpan(colorSpan, 8, headerSubtitle.length(), SPAN_EXCLUSIVE_EXCLUSIVE);
337        SpannableString homeSubtitle = new SpannableString("12 miles | 12 min | $9.00");
338        homeSubtitle.setSpan(colorSpan, 20, homeSubtitle.length(), SPAN_EXCLUSIVE_EXCLUSIVE);
339        SpannableString workSubtitle = new SpannableString("44 miles | 1 hour 45 min | $31.41");
340        workSubtitle.setSpan(colorSpan, 27, workSubtitle.length(), SPAN_EXCLUSIVE_EXCLUSIVE);
341
342        SliceAction primaryAction = new SliceAction(getBroadcastIntent(ACTION_TOAST, "get ride"),
343                Icon.createWithResource(getContext(), R.drawable.ic_car), "Get Ride");
344        return new ListBuilder(getContext(), sliceUri)
345                .setColor(0xff0F9D58)
346                .setHeader(b -> b
347                    .setTitle("Get ride")
348                    .setSubtitle(headerSubtitle)
349                    .setSummarySubtitle("Ride to work in 12 min | Ride home in 1 hour 45 min")
350                    .setPrimaryAction(primaryAction))
351                .addRow(b -> b
352                    .setTitle("Work")
353                    .setSubtitle(workSubtitle)
354                    .addEndItem(new SliceAction(getBroadcastIntent(ACTION_TOAST, "work"),
355                            Icon.createWithResource(getContext(), R.drawable.ic_work),
356                            "Get ride to work")))
357                .addRow(b -> b
358                    .setTitle("Home")
359                    .setSubtitle(homeSubtitle)
360                    .addEndItem(new SliceAction(getBroadcastIntent(ACTION_TOAST, "home"),
361                            Icon.createWithResource(getContext(), R.drawable.ic_home),
362                            "Get ride home")))
363                .build();
364    }
365
366    private Slice createCustomToggleSlice(Uri sliceUri) {
367        return new ListBuilder(getContext(), sliceUri)
368                .setColor(0xffff4081)
369                .addRow(b -> b
370                    .setTitle("Custom toggle")
371                    .setSubtitle("It can support two states")
372                    .setPrimaryAction(new SliceAction(getBroadcastIntent(ACTION_TOAST,
373                            "star toggled"),
374                            Icon.createWithResource(getContext(), R.drawable.toggle_star),
375                            "Toggle star", true /* isChecked */)))
376                .build();
377    }
378
379    private Slice createTwoCustomToggleSlices(Uri sliceUri) {
380        return new ListBuilder(getContext(), sliceUri)
381                .setColor(0xffff4081)
382                .addRow(b -> b
383                        .setTitle("2 toggles")
384                        .setSubtitle("each supports two states")
385                        .addEndItem(new SliceAction(
386                                getBroadcastIntent(ACTION_TOAST, "first star toggled"),
387                                Icon.createWithResource(getContext(), R.drawable.toggle_star),
388                                "Toggle star", true /* isChecked */))
389                        .addEndItem(new SliceAction(
390                                getBroadcastIntent(ACTION_TOAST, "second star toggled"),
391                                Icon.createWithResource(getContext(), R.drawable.toggle_star),
392                                "Toggle star", false /* isChecked */)))
393                .build();
394    }
395
396    private Slice createWifiSlice(Uri sliceUri) {
397        // Get wifi state
398        WifiManager wifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
399        int wifiState = wifiManager.getWifiState();
400        boolean wifiEnabled = false;
401        String state;
402        switch (wifiState) {
403            case WifiManager.WIFI_STATE_DISABLED:
404            case WifiManager.WIFI_STATE_DISABLING:
405                state = "disconnected";
406                break;
407            case WifiManager.WIFI_STATE_ENABLED:
408            case WifiManager.WIFI_STATE_ENABLING:
409                state = wifiManager.getConnectionInfo().getSSID();
410                wifiEnabled = true;
411                break;
412            case WifiManager.WIFI_STATE_UNKNOWN:
413            default:
414                state = ""; // just don't show anything?
415                break;
416        }
417        boolean finalWifiEnabled = wifiEnabled;
418        SliceAction primaryAction = new SliceAction(getIntent(Settings.ACTION_WIFI_SETTINGS),
419                Icon.createWithResource(getContext(), R.drawable.ic_wifi), "Wi-fi Settings");
420        return new ListBuilder(getContext(), sliceUri)
421                .setColor(0xff4285f4)
422                .addRow(b -> b
423                    .setTitle("Wi-fi")
424                    .setSubtitle(state)
425                    .addEndItem(new SliceAction(getBroadcastIntent(ACTION_WIFI_CHANGED, null),
426                            "Toggle wifi", finalWifiEnabled))
427                    .setPrimaryAction(primaryAction))
428                .build();
429    }
430
431    private Slice createStarRatingInputRange(Uri sliceUri) {
432        return new ListBuilder(getContext(), sliceUri)
433                .setColor(0xffff4081)
434                .addInputRange(c -> c
435                        .setTitle("Star rating")
436                        .setThumb(Icon.createWithResource(getContext(), R.drawable.ic_star_on))
437                        .setAction(getBroadcastIntent(ACTION_TOAST_RANGE_VALUE, null))
438                        .setMax(5)
439                        .setValue(3))
440                .build();
441    }
442
443    private Slice createDownloadProgressRange(Uri sliceUri) {
444        return new ListBuilder(getContext(), sliceUri)
445                .setColor(0xffff4081)
446                .addRange(c -> c
447                        .setTitle("Download progress")
448                        .setMax(100)
449                        .setValue(75))
450                .build();
451    }
452
453    private Handler mHandler = new Handler();
454    private Runnable mLoader;
455    private boolean mLoaded = false;
456
457    private Slice createLoadingSlice(Uri sliceUri, boolean loadAll, boolean isList) {
458        if (!mLoaded || mLoader != null) {
459            // Need to load content or we're still loading so just return partial
460            if (!mLoaded) {
461                mLoader = () -> {
462                    // Note that we've loaded things
463                    mLoader = null;
464                    mLoaded = true;
465                    // Notify to update the slice
466                    getContext().getContentResolver().notifyChange(sliceUri, null);
467                };
468                mHandler.postDelayed(mLoader, LOADING_DELAY_MS);
469            }
470            if (loadAll) {
471                return new ListBuilder(getContext(), sliceUri).build();
472            }
473            return createPartialSlice(sliceUri, true, isList);
474        } else {
475            mLoaded = false;
476            return createPartialSlice(sliceUri, false, isList);
477        }
478    }
479
480    private Slice createPartialSlice(Uri sliceUri, boolean isPartial, boolean isList) {
481        Icon icon = Icon.createWithResource(getContext(), R.drawable.ic_star_on);
482        PendingIntent intent = getBroadcastIntent(ACTION_TOAST, "star tapped");
483        PendingIntent intent2 = getBroadcastIntent(ACTION_TOAST, "toggle tapped");
484        if (isPartial) {
485            if (isList) {
486                return new ListBuilder(getContext(), sliceUri)
487                        .addRow(b -> createRow(b, "Slice that has content to load",
488                                "Temporary subtitle", icon, intent, true))
489                        .addRow(b -> createRow(b, null, null, null, intent, true))
490                        .addRow(b -> b
491                                .setTitle("My title")
492                                .addEndItem(new SliceAction(intent2, "Some action",
493                                        false /* isChecked */),
494                                        true /* isLoading */))
495                        .build();
496            } else {
497                return new ListBuilder(getContext(), sliceUri).addGrid(gb -> gb
498                        .addCell(b -> createCell(b, null, null, null, true))
499                        .addCell(b -> createCell(b, "Two stars", null, icon, true))
500                        .addCell(b -> createCell(b, null, null, null, true)))
501                        .build();
502            }
503        } else {
504            if (isList) {
505                return new ListBuilder(getContext(), sliceUri)
506                        .addRow(b -> createRow(b, "Slice that has content to load",
507                                "Subtitle loaded", icon, intent, false))
508                        .addRow(b -> createRow(b, "Loaded row", "Loaded subtitle",
509                                icon, intent, false))
510                        .addRow(b -> b
511                                .setTitle("My title")
512                                .addEndItem(new SliceAction(intent2, "Some action",
513                                                false /* isChecked */)))
514                        .build();
515            } else {
516                return new ListBuilder(getContext(), sliceUri).addGrid(gb -> gb
517                        .addCell(b -> createCell(b, "One star", "meh", icon, false))
518                        .addCell(b -> createCell(b, "Two stars", "good", icon, false))
519                        .addCell(b -> createCell(b, "Three stars", "best", icon, false)))
520                        .build();
521            }
522        }
523    }
524
525    private ListBuilder.RowBuilder createRow(ListBuilder.RowBuilder rb, String title,
526            String subtitle, Icon icon, PendingIntent content, boolean isLoading) {
527        SliceAction primaryAction = new SliceAction(content, icon, title);
528        return rb.setTitle(title, isLoading)
529          .setSubtitle(subtitle, isLoading)
530          .addEndItem(icon, isLoading)
531          .setPrimaryAction(primaryAction);
532    }
533
534    private GridBuilder.CellBuilder createCell(GridBuilder.CellBuilder cb, String text1,
535            String text2, Icon icon, boolean isLoading) {
536        return cb.addText(text1, isLoading).addText(text2, isLoading).addImage(icon,
537                GridBuilder.SMALL_IMAGE, isLoading);
538    }
539
540    private PendingIntent getIntent(String action) {
541        Intent intent = new Intent(action);
542        PendingIntent pi = PendingIntent.getActivity(getContext(), 0, intent, 0);
543        return pi;
544    }
545
546    private PendingIntent getBroadcastIntent(String action, String message) {
547        Intent intent = new Intent(action);
548        intent.setClass(getContext(), SliceBroadcastReceiver.class);
549        // Ensure a new PendingIntent is created for each message.
550        int requestCode = 0;
551        if (message != null) {
552            intent.putExtra(EXTRA_TOAST_MESSAGE, message);
553            requestCode = message.hashCode();
554        }
555        return PendingIntent.getBroadcast(getContext(), requestCode, intent,
556                PendingIntent.FLAG_UPDATE_CURRENT);
557    }
558}
559