SampleSliceProvider.java revision d264a86530b606566e3c8d83e334018afd65a646
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 android.app.PendingIntent; 20import android.content.ContentResolver; 21import android.content.Context; 22import android.content.Intent; 23import android.graphics.drawable.Icon; 24import android.net.Uri; 25import android.net.wifi.WifiManager; 26import android.provider.Settings; 27import android.support.annotation.NonNull; 28import android.text.format.DateUtils; 29 30import androidx.app.slice.Slice; 31import androidx.app.slice.SliceProvider; 32import androidx.app.slice.builders.GridBuilder; 33import androidx.app.slice.builders.ListBuilder; 34import androidx.app.slice.builders.MessagingSliceBuilder; 35 36/** 37 * Examples of using slice template builders. 38 */ 39public class SampleSliceProvider extends SliceProvider { 40 41 public static final String ACTION_WIFI_CHANGED = 42 "com.example.androidx.slice.action.WIFI_CHANGED"; 43 public static final String ACTION_TOAST = 44 "com.example.androidx.slice.action.TOAST"; 45 public static final String EXTRA_TOAST_MESSAGE = "com.example.androidx.extra.TOAST_MESSAGE"; 46 47 public static final String[] URI_PATHS = {"message", "wifi", "note", "ride", "toggle", 48 "contact", "gallery", "weather"}; 49 50 /** 51 * @return Uri with the provided path 52 */ 53 public static Uri getUri(String path, Context context) { 54 return new Uri.Builder() 55 .scheme(ContentResolver.SCHEME_CONTENT) 56 .authority(context.getPackageName()) 57 .appendPath(path) 58 .build(); 59 } 60 61 @Override 62 public boolean onCreateSliceProvider() { 63 return true; 64 } 65 66 @NonNull 67 @Override 68 public Uri onMapIntentToUri(Intent intent) { 69 return getUri("wifi", getContext()); 70 } 71 72 @Override 73 public Slice onBindSlice(Uri sliceUri) { 74 String path = sliceUri.getPath(); 75 switch (path) { 76 case "/message": 77 return createMessagingSlice(sliceUri); 78 case "/wifi": 79 return createWifiSlice(sliceUri); 80 case "/note": 81 return createNoteSlice(sliceUri); 82 case "/ride": 83 return createRideSlice(sliceUri); 84 case "/toggle": 85 return createCustomToggleSlice(sliceUri); 86 case "/contact": 87 return createContact(sliceUri); 88 case "/gallery": 89 return createGallery(sliceUri); 90 case "/weather": 91 return createWeather(sliceUri); 92 } 93 throw new IllegalArgumentException("Unknown uri " + sliceUri); 94 } 95 96 private Slice createWeather(Uri sliceUri) { 97 return new GridBuilder(sliceUri) 98 .addCell(cb -> cb 99 .addLargeImage(Icon.createWithResource(getContext(), R.drawable.weather_1)) 100 .addText("MON") 101 .addTitleText("69\u00B0")) 102 .addCell(cb -> cb 103 .addLargeImage(Icon.createWithResource(getContext(), R.drawable.weather_2)) 104 .addText("TUE") 105 .addTitleText("71\u00B0")) 106 .addCell(cb -> cb 107 .addLargeImage(Icon.createWithResource(getContext(), R.drawable.weather_3)) 108 .addText("WED") 109 .addTitleText("76\u00B0")) 110 .addCell(cb -> cb 111 .addLargeImage(Icon.createWithResource(getContext(), R.drawable.weather_4)) 112 .addText("THU") 113 .addTitleText("72\u00B0")) 114 .addCell(cb -> cb 115 .addLargeImage(Icon.createWithResource(getContext(), R.drawable.weather_1)) 116 .addText("FRI") 117 .addTitleText("68\u00B0")) 118 .build(); 119 } 120 121 private Slice createGallery(Uri sliceUri) { 122 return new GridBuilder(sliceUri) 123 .addCell(cb -> cb 124 .addLargeImage(Icon.createWithResource(getContext(), R.drawable.slices_1))) 125 .addCell(cb -> cb 126 .addLargeImage(Icon.createWithResource(getContext(), R.drawable.slices_2))) 127 .addCell(cb -> cb 128 .addLargeImage(Icon.createWithResource(getContext(), R.drawable.slices_3))) 129 .addCell(cb -> cb 130 .addLargeImage(Icon.createWithResource(getContext(), R.drawable.slices_4))) 131 .build(); 132 } 133 134 private Slice createContact(Uri sliceUri) { 135 return new ListBuilder(sliceUri) 136 .setColor(0xff3949ab) 137 .addRow(b -> b 138 .setTitle("Mady Pitza") 139 .setSubtitle("Frequently contacted contact") 140 .setIsHeader(true) 141 .addEndItem(Icon.createWithResource(getContext(), R.drawable.mady))) 142 .addGrid(b -> b 143 .addCell(cb -> cb 144 .addImage(Icon.createWithResource(getContext(), R.drawable.ic_call)) 145 .addText("Call") 146 .setContentIntent(getBroadcastIntent(ACTION_TOAST, "call"))) 147 .addCell(cb -> cb 148 .addImage(Icon.createWithResource(getContext(), R.drawable.ic_text)) 149 .addText("Text") 150 .setContentIntent(getBroadcastIntent(ACTION_TOAST, "text"))) 151 .addCell(cb ->cb 152 .addImage(Icon.createWithResource(getContext(), R.drawable.ic_video)) 153 .setContentIntent(getBroadcastIntent(ACTION_TOAST, "video")) 154 .addText("Video")) 155 .addCell(cb -> cb 156 .addImage(Icon.createWithResource(getContext(), R.drawable.ic_email)) 157 .addText("Email") 158 .setContentIntent(getBroadcastIntent(ACTION_TOAST, "email")))) 159 .build(); 160 } 161 162 private Slice createMessagingSlice(Uri sliceUri) { 163 // TODO: Remote input. 164 return new MessagingSliceBuilder(sliceUri) 165 .add(b -> b 166 .addText("yo home \uD83C\uDF55, I emailed you the info") 167 .addTimestamp(System.currentTimeMillis() - 20 * DateUtils.MINUTE_IN_MILLIS) 168 .addSource(Icon.createWithResource(getContext(), R.drawable.mady))) 169 .add(b -> b 170 .addText("just bought my tickets") 171 .addTimestamp(System.currentTimeMillis() - 10 * DateUtils.MINUTE_IN_MILLIS)) 172 .add(b -> b 173 .addText("yay! can't wait for getContext() weekend!\n" 174 + "\uD83D\uDE00") 175 .addTimestamp(System.currentTimeMillis() - 5 * DateUtils.MINUTE_IN_MILLIS) 176 .addSource(Icon.createWithResource(getContext(), R.drawable.mady))) 177 .build(); 178 179 } 180 181 private Slice createNoteSlice(Uri sliceUri) { 182 // TODO: Remote input. 183 return new ListBuilder(sliceUri) 184 .setColor(0xfff4b400) 185 .addRow(b -> b 186 .setTitle("Create new note") 187 .setSubtitle("with this note taking app") 188 .addEndItem(Icon.createWithResource(getContext(), R.drawable.ic_create), 189 getBroadcastIntent(ACTION_TOAST, "create note")) 190 .addEndItem(Icon.createWithResource(getContext(), R.drawable.ic_voice), 191 getBroadcastIntent(ACTION_TOAST, "voice note")) 192 .addEndItem(Icon.createWithResource(getContext(), R.drawable.ic_camera), 193 getIntent("android.media.action.IMAGE_CAPTURE"))) 194 .build(); 195 } 196 197 private Slice createRideSlice(Uri sliceUri) { 198 return new ListBuilder(sliceUri) 199 .setColor(0xff1b5e20) 200 .addSummaryRow(b -> b 201 .setTitle("Get ride") 202 .setSubtitle("Multiple cars 4 minutes away") 203 .addEndItem(Icon.createWithResource(getContext(), R.drawable.ic_home), 204 getBroadcastIntent(ACTION_TOAST, "home")) 205 .addEndItem(Icon.createWithResource(getContext(), R.drawable.ic_work), 206 getBroadcastIntent(ACTION_TOAST, "work"))) 207 .addRow(b -> b 208 .setContentIntent(getBroadcastIntent(ACTION_TOAST, "work")) 209 .setTitle("Work") 210 .setSubtitle("2 min") 211 .addEndItem(Icon.createWithResource(getContext(), R.drawable.ic_work))) 212 .addRow(b -> b 213 .setContentIntent(getBroadcastIntent(ACTION_TOAST, "home")) 214 .setTitle("Home") 215 .setSubtitle("2 hours 33 min via 101") 216 .addEndItem(Icon.createWithResource(getContext(), R.drawable.ic_home))) 217 .addRow(b -> b 218 .setContentIntent(getBroadcastIntent(ACTION_TOAST, "book ride")) 219 .setTitle("Book ride") 220 .addEndItem(Icon.createWithResource(getContext(), R.drawable.ic_car))) 221 .build(); 222 } 223 224 private Slice createCustomToggleSlice(Uri sliceUri) { 225 // TODO: support 2 custom toggles in the same row 226 return new ListBuilder(sliceUri) 227 .setColor(0xffff4081) 228 .addRow(b -> b 229 .setTitle("Custom toggle") 230 .setSubtitle("It can support two states") 231 .addToggle(getBroadcastIntent(ACTION_TOAST, "star toggled"), 232 true /* isChecked */, 233 Icon.createWithResource(getContext(), R.drawable.toggle_star))) 234 .build(); 235 } 236 237 private Slice createWifiSlice(Uri sliceUri) { 238 // Get wifi state 239 WifiManager wifiManager = (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE); 240 int wifiState = wifiManager.getWifiState(); 241 boolean wifiEnabled = false; 242 String state; 243 switch (wifiState) { 244 case WifiManager.WIFI_STATE_DISABLED: 245 case WifiManager.WIFI_STATE_DISABLING: 246 state = "disconnected"; 247 break; 248 case WifiManager.WIFI_STATE_ENABLED: 249 case WifiManager.WIFI_STATE_ENABLING: 250 state = wifiManager.getConnectionInfo().getSSID(); 251 wifiEnabled = true; 252 break; 253 case WifiManager.WIFI_STATE_UNKNOWN: 254 default: 255 state = ""; // just don't show anything? 256 break; 257 } 258 boolean finalWifiEnabled = wifiEnabled; 259 return new ListBuilder(sliceUri) 260 .setColor(0xff4285f4) 261 .addRow(b -> b 262 .setTitle("Wi-fi") 263 .setTitleItem(Icon.createWithResource(getContext(), R.drawable.ic_wifi)) 264 .setSubtitle(state) 265 .addToggle(getBroadcastIntent(ACTION_WIFI_CHANGED, null), finalWifiEnabled) 266 .setContentIntent(getIntent(Settings.ACTION_WIFI_SETTINGS))) 267 .build(); 268 } 269 270 private PendingIntent getIntent(String action) { 271 Intent intent = new Intent(action); 272 PendingIntent pi = PendingIntent.getActivity(getContext(), 0, intent, 0); 273 return pi; 274 } 275 276 private PendingIntent getBroadcastIntent(String action, String message) { 277 Intent intent = new Intent(action); 278 if (message != null) { 279 intent.putExtra(EXTRA_TOAST_MESSAGE, message); 280 } 281 intent.setClass(getContext(), SliceBroadcastReceiver.class); 282 return PendingIntent.getBroadcast(getContext(), 0, intent, 283 PendingIntent.FLAG_CANCEL_CURRENT); 284 } 285} 286