1 /* 2 * Copyright (C) 2019 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 17 package com.android.car.ui.paintbooth.dialogs; 18 19 import android.Manifest; 20 import android.app.Activity; 21 import android.app.AlertDialog; 22 import android.content.pm.PackageManager; 23 import android.os.Bundle; 24 import android.util.Pair; 25 import android.view.LayoutInflater; 26 import android.view.View; 27 import android.view.ViewGroup; 28 import android.widget.Button; 29 import android.widget.Toast; 30 31 import androidx.annotation.NonNull; 32 import androidx.recyclerview.widget.RecyclerView; 33 34 import com.android.car.ui.AlertDialogBuilder; 35 import com.android.car.ui.FocusArea; 36 import com.android.car.ui.baselayout.Insets; 37 import com.android.car.ui.baselayout.InsetsChangedListener; 38 import com.android.car.ui.core.CarUi; 39 import com.android.car.ui.paintbooth.R; 40 import com.android.car.ui.recyclerview.CarUiContentListItem; 41 import com.android.car.ui.recyclerview.CarUiListItemAdapter; 42 import com.android.car.ui.recyclerview.CarUiRadioButtonListItem; 43 import com.android.car.ui.recyclerview.CarUiRadioButtonListItemAdapter; 44 import com.android.car.ui.recyclerview.CarUiRecyclerView; 45 import com.android.car.ui.toolbar.NavButtonMode; 46 import com.android.car.ui.toolbar.ToolbarController; 47 48 import java.util.ArrayList; 49 import java.util.List; 50 51 /** 52 * Activity that shows different dialogs from the device default theme. 53 */ 54 public class DialogsActivity extends Activity implements InsetsChangedListener { 55 56 private final List<Pair<Integer, View.OnClickListener>> mButtons = new ArrayList<>(); 57 58 @Override onCreate(Bundle savedInstanceState)59 protected void onCreate(Bundle savedInstanceState) { 60 super.onCreate(savedInstanceState); 61 setContentView(R.layout.car_ui_recycler_view_activity); 62 ToolbarController toolbar = CarUi.requireToolbar(this); 63 toolbar.setTitle(getTitle()); 64 toolbar.setNavButtonMode(NavButtonMode.BACK); 65 66 mButtons.add(Pair.create(R.string.dialog_show_dialog, 67 v -> showDialog())); 68 mButtons.add(Pair.create(R.string.dialog_show_dialog_icon, 69 v -> showDialogWithIcon())); 70 mButtons.add(Pair.create(R.string.dialog_show_dialog_edit, 71 v -> showDialogWithTextBox())); 72 mButtons.add(Pair.create(R.string.dialog_show_dialog_only_positive, 73 v -> showDialogWithOnlyPositiveButton())); 74 mButtons.add(Pair.create(R.string.dialog_show_dialog_no_button, 75 v -> showDialogWithNoButtonProvided())); 76 mButtons.add(Pair.create(R.string.dialog_show_dialog_checkbox, 77 v -> showDialogWithCheckbox())); 78 mButtons.add(Pair.create(R.string.dialog_show_dialog_no_title, 79 v -> showDialogWithoutTitle())); 80 mButtons.add(Pair.create(R.string.dialog_show_toast, 81 v -> showToast())); 82 mButtons.add(Pair.create(R.string.dialog_show_subtitle, 83 v -> showDialogWithSubtitle())); 84 mButtons.add(Pair.create(R.string.dialog_show_subtitle_and_icon, 85 v -> showDialogWithSubtitleAndIcon())); 86 mButtons.add(Pair.create(R.string.dialog_show_long_subtitle_and_icon, 87 v -> showDialogWithLongSubtitleAndIcon())); 88 mButtons.add(Pair.create(R.string.dialog_show_single_choice, 89 v -> showDialogWithSingleChoiceItems())); 90 mButtons.add(Pair.create(R.string.dialog_show_list_items_without_default_button, 91 v -> showDialogWithListItemsWithoutDefaultButton())); 92 mButtons.add(Pair.create(R.string.dialog_show_permission_dialog, 93 v -> showPermissionDialog())); 94 mButtons.add(Pair.create(R.string.dialog_show_multi_permission_dialog, 95 v -> showMultiPermissionDialog())); 96 mButtons.add(Pair.create(R.string.dialog_show_foreground_permission_dialog, 97 v -> showForegroundPermissionDialog())); 98 mButtons.add(Pair.create(R.string.dialog_show_background_permission_dialog, 99 v -> showBackgroundPermissionDialog())); 100 101 CarUiRecyclerView recyclerView = requireViewById(R.id.list); 102 recyclerView.setAdapter(mAdapter); 103 } 104 showDialog()105 private void showDialog() { 106 new AlertDialogBuilder(this) 107 .setTitle(getString(R.string.standard_alert_dialog)) 108 .setMessage(getString(R.string.my_message)) 109 .setNeutralButton(getString(R.string.neutral), (dialogInterface, which) -> { 110 }) 111 .setPositiveButton(getString(R.string.ok), (dialogInterface, which) -> { 112 }) 113 .setNegativeButton(getString(R.string.cancel), (dialogInterface, which) -> { 114 }) 115 .show(); 116 } 117 showDialogWithIcon()118 private void showDialogWithIcon() { 119 new AlertDialogBuilder(this) 120 .setTitle(getString(R.string.alert_dialog_with_icon)) 121 .setMessage(getString(R.string.my_message)) 122 .setIcon(R.drawable.ic_tracklist) 123 .show(); 124 } 125 showDialogWithNoButtonProvided()126 private void showDialogWithNoButtonProvided() { 127 new AlertDialogBuilder(this) 128 .setTitle(getString(R.string.standard_alert_dialog)) 129 .show(); 130 } 131 showDialogWithCheckbox()132 private void showDialogWithCheckbox() { 133 new AlertDialogBuilder(this) 134 .setTitle(R.string.custom_dialog_box) 135 .setMultiChoiceItems( 136 new CharSequence[]{"I am a checkbox"}, 137 new boolean[]{false}, 138 (dialog, which, isChecked) -> { 139 }) 140 .setPositiveButton(getString(R.string.ok), (dialogInterface, which) -> { 141 }) 142 .setNegativeButton(getString(R.string.cancel), (dialogInterface, which) -> { 143 }) 144 .show(); 145 } 146 showDialogWithTextBox()147 private void showDialogWithTextBox() { 148 new AlertDialogBuilder(this) 149 .setTitle(R.string.standard_alert_dialog) 150 .setEditBox(getString(R.string.edit_me_please), null, null) 151 .setAutoDescUpdateForWidescreen(true) 152 .setEditTextTitleAndDescForWideScreen("title", "desc from app") 153 .setPositiveButton("OK", (dialogInterface, i) -> { 154 }) 155 .show(); 156 } 157 showDialogWithOnlyPositiveButton()158 private void showDialogWithOnlyPositiveButton() { 159 new AlertDialogBuilder(this) 160 .setTitle(R.string.standard_alert_dialog) 161 .setMessage(getString(R.string.my_message)) 162 .setPositiveButton(getString(R.string.ok), (dialogInterface, i) -> { 163 }) 164 .show(); 165 } 166 showDialogWithoutTitle()167 private void showDialogWithoutTitle() { 168 new AlertDialogBuilder(this) 169 .setMessage(R.string.no_title_message) 170 .setPositiveButton(getString(R.string.ok), (dialogInterface, i) -> { 171 }) 172 .setNegativeButton(getString(R.string.cancel), (dialogInterface, which) -> { 173 }) 174 .show(); 175 } 176 showToast()177 private void showToast() { 178 Toast.makeText(this, "Toast message looks like this", Toast.LENGTH_LONG).show(); 179 } 180 showDialogWithSubtitle()181 private void showDialogWithSubtitle() { 182 new AlertDialogBuilder(this) 183 .setTitle(R.string.my_title) 184 .setSubtitle(R.string.my_subtitle) 185 .setMessage(getString(R.string.my_message)) 186 .show(); 187 } 188 showDialogWithSingleChoiceItems()189 private void showDialogWithSingleChoiceItems() { 190 ArrayList<CarUiRadioButtonListItem> data = new ArrayList<>(); 191 192 CarUiRadioButtonListItem item = new CarUiRadioButtonListItem(); 193 item.setTitle(getString(R.string.first_item)); 194 data.add(item); 195 196 item = new CarUiRadioButtonListItem(); 197 item.setTitle(getString(R.string.second_item)); 198 data.add(item); 199 200 item = new CarUiRadioButtonListItem(); 201 item.setTitle(getString(R.string.third_item)); 202 data.add(item); 203 204 new AlertDialogBuilder(this) 205 .setTitle(R.string.select_one_option) 206 .setSubtitle(R.string.select_one_option_at_a_time) 207 .setSingleChoiceItems(new CarUiRadioButtonListItemAdapter(data), null) 208 .show(); 209 } 210 showDialogWithListItemsWithoutDefaultButton()211 private void showDialogWithListItemsWithoutDefaultButton() { 212 ArrayList<CarUiContentListItem> data = new ArrayList<>(); 213 AlertDialog[] dialog = new AlertDialog[1]; 214 215 CarUiContentListItem item = new CarUiContentListItem(CarUiContentListItem.Action.NONE); 216 item.setTitle("First item"); 217 item.setOnItemClickedListener(i -> dialog[0].dismiss()); 218 data.add(item); 219 220 221 item = new CarUiContentListItem(CarUiContentListItem.Action.NONE); 222 item.setTitle("Second item"); 223 item.setOnItemClickedListener(i -> dialog[0].dismiss()); 224 data.add(item); 225 226 item = new CarUiContentListItem(CarUiContentListItem.Action.NONE); 227 item.setTitle("Third item"); 228 item.setOnItemClickedListener(i -> dialog[0].dismiss()); 229 data.add(item); 230 231 dialog[0] = new AlertDialogBuilder(this) 232 .setTitle("Select one option.") 233 .setSubtitle("Ony one option may be selected at a time") 234 .setAdapter(new CarUiListItemAdapter(data)) 235 .setAllowDismissButton(false) 236 .show(); 237 } 238 showDialogWithSubtitleAndIcon()239 private void showDialogWithSubtitleAndIcon() { 240 new AlertDialogBuilder(this) 241 .setTitle(R.string.my_title) 242 .setSubtitle(R.string.my_subtitle) 243 .setMessage(getString(R.string.my_message)) 244 .setIcon(R.drawable.ic_tracklist) 245 .show(); 246 } 247 showDialogWithLongSubtitleAndIcon()248 private void showDialogWithLongSubtitleAndIcon() { 249 new AlertDialogBuilder(this) 250 .setTitle(getString(R.string.long_title)) 251 .setSubtitle(R.string.long_subtitle) 252 .setMessage(getString(R.string.my_message)) 253 .setIcon(R.drawable.ic_tracklist) 254 .show(); 255 } 256 showPermissionDialog()257 private void showPermissionDialog() { 258 if (checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) { 259 Toast.makeText(this, "Permission already granted. Remove CAMERA permission from " 260 + "Settings > All apps > PaintBooth", Toast.LENGTH_SHORT).show(); 261 return; 262 } 263 requestPermissions(new String[]{Manifest.permission.CAMERA}, 1); 264 } 265 showMultiPermissionDialog()266 private void showMultiPermissionDialog() { 267 if (checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED 268 && checkSelfPermission(Manifest.permission.SEND_SMS) 269 == PackageManager.PERMISSION_GRANTED 270 && checkSelfPermission(Manifest.permission.READ_CONTACTS) 271 == PackageManager.PERMISSION_GRANTED) { 272 Toast.makeText(this, "Permissions are already granted. Remove CAMERA, SEND_SMS or " 273 + "READ_CONTACTS permission from Settings > All apps > PaintBooth", 274 Toast.LENGTH_SHORT).show(); 275 return; 276 } 277 requestPermissions(new String[]{Manifest.permission.CAMERA, 278 Manifest.permission.READ_CONTACTS, Manifest.permission.SEND_SMS}, 1); 279 } 280 showForegroundPermissionDialog()281 private void showForegroundPermissionDialog() { 282 requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1); 283 } 284 showBackgroundPermissionDialog()285 private void showBackgroundPermissionDialog() { 286 requestPermissions(new String[]{Manifest.permission.ACCESS_BACKGROUND_LOCATION}, 1); 287 } 288 289 @Override onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults)290 public void onRequestPermissionsResult(int requestCode, String[] permissions, 291 int[] grantResults) { 292 StringBuilder sb = new StringBuilder(); 293 sb.append("Permission "); 294 for (int i = 0; i < permissions.length; i++) { 295 sb.append(permissions[i]); 296 sb.append("="); 297 sb.append(grantResults[i] == PackageManager.PERMISSION_GRANTED ? "granted" : "denied"); 298 sb.append("\n"); 299 } 300 Toast.makeText(this, sb.toString(), Toast.LENGTH_SHORT).show(); 301 } 302 303 private static class ViewHolder extends RecyclerView.ViewHolder { 304 305 private final Button mButton; 306 ViewHolder(View itemView)307 ViewHolder(View itemView) { 308 super(itemView); 309 mButton = itemView.requireViewById(R.id.button); 310 } 311 bind(Integer title, View.OnClickListener listener)312 public void bind(Integer title, View.OnClickListener listener) { 313 mButton.setText(title); 314 mButton.setOnClickListener(listener); 315 } 316 } 317 318 private final RecyclerView.Adapter<ViewHolder> mAdapter = 319 new RecyclerView.Adapter<ViewHolder>() { 320 @Override 321 public int getItemCount() { 322 return mButtons.size(); 323 } 324 325 @Override 326 public ViewHolder onCreateViewHolder(ViewGroup parent, int position) { 327 View item = 328 LayoutInflater.from(parent.getContext()).inflate(R.layout.list_item, 329 parent, false); 330 return new ViewHolder(item); 331 } 332 333 @Override 334 public void onBindViewHolder(@NonNull ViewHolder holder, int position) { 335 Pair<Integer, View.OnClickListener> pair = mButtons.get(position); 336 holder.bind(pair.first, pair.second); 337 } 338 }; 339 340 @Override onCarUiInsetsChanged(@onNull Insets insets)341 public void onCarUiInsetsChanged(@NonNull Insets insets) { 342 FocusArea focusArea = requireViewById(R.id.focus_area); 343 focusArea.setBoundsOffset(0, insets.getTop(), 0, insets.getBottom()); 344 focusArea.setHighlightPadding(0, insets.getTop(), 0, insets.getBottom()); 345 requireViewById(R.id.list) 346 .setPadding(0, insets.getTop(), 0, insets.getBottom()); 347 requireViewById(android.R.id.content) 348 .setPadding(insets.getLeft(), 0, insets.getRight(), 0); 349 } 350 } 351