Touchgui/plugins/org.apache.cordova.dialogs/src/android/Notification.java

Thu, 04 Jun 2015 14:50:33 +0200

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 04 Jun 2015 14:50:33 +0200
changeset 0
e8ccd40d0ef6
permissions
-rw-r--r--

Genesis of lecture sources for Droidcon Berlin 2015 in Postbahnhof.

michael@0 1 /*
michael@0 2 Licensed to the Apache Software Foundation (ASF) under one
michael@0 3 or more contributor license agreements. See the NOTICE file
michael@0 4 distributed with this work for additional information
michael@0 5 regarding copyright ownership. The ASF licenses this file
michael@0 6 to you under the Apache License, Version 2.0 (the
michael@0 7 "License"); you may not use this file except in compliance
michael@0 8 with the License. You may obtain a copy of the License at
michael@0 9
michael@0 10 http://www.apache.org/licenses/LICENSE-2.0
michael@0 11
michael@0 12 Unless required by applicable law or agreed to in writing,
michael@0 13 software distributed under the License is distributed on an
michael@0 14 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
michael@0 15 KIND, either express or implied. See the License for the
michael@0 16 specific language governing permissions and limitations
michael@0 17 under the License.
michael@0 18 */
michael@0 19 package org.apache.cordova.dialogs;
michael@0 20
michael@0 21 import org.apache.cordova.CallbackContext;
michael@0 22 import org.apache.cordova.CordovaInterface;
michael@0 23 import org.apache.cordova.CordovaPlugin;
michael@0 24 import org.apache.cordova.PluginResult;
michael@0 25 import org.json.JSONArray;
michael@0 26 import org.json.JSONException;
michael@0 27 import org.json.JSONObject;
michael@0 28
michael@0 29 import android.annotation.SuppressLint;
michael@0 30 import android.app.AlertDialog;
michael@0 31 import android.app.AlertDialog.Builder;
michael@0 32 import android.app.ProgressDialog;
michael@0 33 import android.content.DialogInterface;
michael@0 34 import android.media.Ringtone;
michael@0 35 import android.media.RingtoneManager;
michael@0 36 import android.net.Uri;
michael@0 37 import android.widget.EditText;
michael@0 38 import android.widget.TextView;
michael@0 39
michael@0 40
michael@0 41 /**
michael@0 42 * This class provides access to notifications on the device.
michael@0 43 *
michael@0 44 * Be aware that this implementation gets called on
michael@0 45 * navigator.notification.{alert|confirm|prompt}, and that there is a separate
michael@0 46 * implementation in org.apache.cordova.CordovaChromeClient that gets
michael@0 47 * called on a simple window.{alert|confirm|prompt}.
michael@0 48 */
michael@0 49 public class Notification extends CordovaPlugin {
michael@0 50
michael@0 51 public int confirmResult = -1;
michael@0 52 public ProgressDialog spinnerDialog = null;
michael@0 53 public ProgressDialog progressDialog = null;
michael@0 54
michael@0 55 /**
michael@0 56 * Constructor.
michael@0 57 */
michael@0 58 public Notification() {
michael@0 59 }
michael@0 60
michael@0 61 /**
michael@0 62 * Executes the request and returns PluginResult.
michael@0 63 *
michael@0 64 * @param action The action to execute.
michael@0 65 * @param args JSONArray of arguments for the plugin.
michael@0 66 * @param callbackContext The callback context used when calling back into JavaScript.
michael@0 67 * @return True when the action was valid, false otherwise.
michael@0 68 */
michael@0 69 public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
michael@0 70 /*
michael@0 71 * Don't run any of these if the current activity is finishing
michael@0 72 * in order to avoid android.view.WindowManager$BadTokenException
michael@0 73 * crashing the app. Just return true here since false should only
michael@0 74 * be returned in the event of an invalid action.
michael@0 75 */
michael@0 76 if(this.cordova.getActivity().isFinishing()) return true;
michael@0 77
michael@0 78 if (action.equals("beep")) {
michael@0 79 this.beep(args.getLong(0));
michael@0 80 }
michael@0 81 else if (action.equals("alert")) {
michael@0 82 this.alert(args.getString(0), args.getString(1), args.getString(2), callbackContext);
michael@0 83 return true;
michael@0 84 }
michael@0 85 else if (action.equals("confirm")) {
michael@0 86 this.confirm(args.getString(0), args.getString(1), args.getJSONArray(2), callbackContext);
michael@0 87 return true;
michael@0 88 }
michael@0 89 else if (action.equals("prompt")) {
michael@0 90 this.prompt(args.getString(0), args.getString(1), args.getJSONArray(2), args.getString(3), callbackContext);
michael@0 91 return true;
michael@0 92 }
michael@0 93 else if (action.equals("activityStart")) {
michael@0 94 this.activityStart(args.getString(0), args.getString(1));
michael@0 95 }
michael@0 96 else if (action.equals("activityStop")) {
michael@0 97 this.activityStop();
michael@0 98 }
michael@0 99 else if (action.equals("progressStart")) {
michael@0 100 this.progressStart(args.getString(0), args.getString(1));
michael@0 101 }
michael@0 102 else if (action.equals("progressValue")) {
michael@0 103 this.progressValue(args.getInt(0));
michael@0 104 }
michael@0 105 else if (action.equals("progressStop")) {
michael@0 106 this.progressStop();
michael@0 107 }
michael@0 108 else {
michael@0 109 return false;
michael@0 110 }
michael@0 111
michael@0 112 // Only alert and confirm are async.
michael@0 113 callbackContext.success();
michael@0 114 return true;
michael@0 115 }
michael@0 116
michael@0 117 //--------------------------------------------------------------------------
michael@0 118 // LOCAL METHODS
michael@0 119 //--------------------------------------------------------------------------
michael@0 120
michael@0 121 /**
michael@0 122 * Beep plays the default notification ringtone.
michael@0 123 *
michael@0 124 * @param count Number of times to play notification
michael@0 125 */
michael@0 126 public void beep(final long count) {
michael@0 127 cordova.getThreadPool().execute(new Runnable() {
michael@0 128 public void run() {
michael@0 129 Uri ringtone = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
michael@0 130 Ringtone notification = RingtoneManager.getRingtone(cordova.getActivity().getBaseContext(), ringtone);
michael@0 131
michael@0 132 // If phone is not set to silent mode
michael@0 133 if (notification != null) {
michael@0 134 for (long i = 0; i < count; ++i) {
michael@0 135 notification.play();
michael@0 136 long timeout = 5000;
michael@0 137 while (notification.isPlaying() && (timeout > 0)) {
michael@0 138 timeout = timeout - 100;
michael@0 139 try {
michael@0 140 Thread.sleep(100);
michael@0 141 } catch (InterruptedException e) {
michael@0 142 }
michael@0 143 }
michael@0 144 }
michael@0 145 }
michael@0 146 }
michael@0 147 });
michael@0 148 }
michael@0 149
michael@0 150 /**
michael@0 151 * Builds and shows a native Android alert with given Strings
michael@0 152 * @param message The message the alert should display
michael@0 153 * @param title The title of the alert
michael@0 154 * @param buttonLabel The label of the button
michael@0 155 * @param callbackContext The callback context
michael@0 156 */
michael@0 157 public synchronized void alert(final String message, final String title, final String buttonLabel, final CallbackContext callbackContext) {
michael@0 158 final CordovaInterface cordova = this.cordova;
michael@0 159
michael@0 160 Runnable runnable = new Runnable() {
michael@0 161 public void run() {
michael@0 162
michael@0 163 AlertDialog.Builder dlg = createDialog(cordova); // new AlertDialog.Builder(cordova.getActivity(), AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);
michael@0 164 dlg.setMessage(message);
michael@0 165 dlg.setTitle(title);
michael@0 166 dlg.setCancelable(true);
michael@0 167 dlg.setPositiveButton(buttonLabel,
michael@0 168 new AlertDialog.OnClickListener() {
michael@0 169 public void onClick(DialogInterface dialog, int which) {
michael@0 170 dialog.dismiss();
michael@0 171 callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, 0));
michael@0 172 }
michael@0 173 });
michael@0 174 dlg.setOnCancelListener(new AlertDialog.OnCancelListener() {
michael@0 175 public void onCancel(DialogInterface dialog)
michael@0 176 {
michael@0 177 dialog.dismiss();
michael@0 178 callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, 0));
michael@0 179 }
michael@0 180 });
michael@0 181
michael@0 182 changeTextDirection(dlg);
michael@0 183 };
michael@0 184 };
michael@0 185 this.cordova.getActivity().runOnUiThread(runnable);
michael@0 186 }
michael@0 187
michael@0 188 /**
michael@0 189 * Builds and shows a native Android confirm dialog with given title, message, buttons.
michael@0 190 * This dialog only shows up to 3 buttons. Any labels after that will be ignored.
michael@0 191 * The index of the button pressed will be returned to the JavaScript callback identified by callbackId.
michael@0 192 *
michael@0 193 * @param message The message the dialog should display
michael@0 194 * @param title The title of the dialog
michael@0 195 * @param buttonLabels A comma separated list of button labels (Up to 3 buttons)
michael@0 196 * @param callbackContext The callback context.
michael@0 197 */
michael@0 198 public synchronized void confirm(final String message, final String title, final JSONArray buttonLabels, final CallbackContext callbackContext) {
michael@0 199 final CordovaInterface cordova = this.cordova;
michael@0 200
michael@0 201 Runnable runnable = new Runnable() {
michael@0 202 public void run() {
michael@0 203 AlertDialog.Builder dlg = createDialog(cordova); // new AlertDialog.Builder(cordova.getActivity(), AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);
michael@0 204 dlg.setMessage(message);
michael@0 205 dlg.setTitle(title);
michael@0 206 dlg.setCancelable(true);
michael@0 207
michael@0 208 // First button
michael@0 209 if (buttonLabels.length() > 0) {
michael@0 210 try {
michael@0 211 dlg.setNegativeButton(buttonLabels.getString(0),
michael@0 212 new AlertDialog.OnClickListener() {
michael@0 213 public void onClick(DialogInterface dialog, int which) {
michael@0 214 dialog.dismiss();
michael@0 215 callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, 1));
michael@0 216 }
michael@0 217 });
michael@0 218 } catch (JSONException e) { }
michael@0 219 }
michael@0 220
michael@0 221 // Second button
michael@0 222 if (buttonLabels.length() > 1) {
michael@0 223 try {
michael@0 224 dlg.setNeutralButton(buttonLabels.getString(1),
michael@0 225 new AlertDialog.OnClickListener() {
michael@0 226 public void onClick(DialogInterface dialog, int which) {
michael@0 227 dialog.dismiss();
michael@0 228 callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, 2));
michael@0 229 }
michael@0 230 });
michael@0 231 } catch (JSONException e) { }
michael@0 232 }
michael@0 233
michael@0 234 // Third button
michael@0 235 if (buttonLabels.length() > 2) {
michael@0 236 try {
michael@0 237 dlg.setPositiveButton(buttonLabels.getString(2),
michael@0 238 new AlertDialog.OnClickListener() {
michael@0 239 public void onClick(DialogInterface dialog, int which) {
michael@0 240 dialog.dismiss();
michael@0 241 callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, 3));
michael@0 242 }
michael@0 243 });
michael@0 244 } catch (JSONException e) { }
michael@0 245 }
michael@0 246 dlg.setOnCancelListener(new AlertDialog.OnCancelListener() {
michael@0 247 public void onCancel(DialogInterface dialog)
michael@0 248 {
michael@0 249 dialog.dismiss();
michael@0 250 callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, 0));
michael@0 251 }
michael@0 252 });
michael@0 253
michael@0 254 changeTextDirection(dlg);
michael@0 255 };
michael@0 256 };
michael@0 257 this.cordova.getActivity().runOnUiThread(runnable);
michael@0 258 }
michael@0 259
michael@0 260 /**
michael@0 261 * Builds and shows a native Android prompt dialog with given title, message, buttons.
michael@0 262 * This dialog only shows up to 3 buttons. Any labels after that will be ignored.
michael@0 263 * The following results are returned to the JavaScript callback identified by callbackId:
michael@0 264 * buttonIndex Index number of the button selected
michael@0 265 * input1 The text entered in the prompt dialog box
michael@0 266 *
michael@0 267 * @param message The message the dialog should display
michael@0 268 * @param title The title of the dialog
michael@0 269 * @param buttonLabels A comma separated list of button labels (Up to 3 buttons)
michael@0 270 * @param callbackContext The callback context.
michael@0 271 */
michael@0 272 public synchronized void prompt(final String message, final String title, final JSONArray buttonLabels, final String defaultText, final CallbackContext callbackContext) {
michael@0 273
michael@0 274 final CordovaInterface cordova = this.cordova;
michael@0 275
michael@0 276 Runnable runnable = new Runnable() {
michael@0 277 public void run() {
michael@0 278 final EditText promptInput = new EditText(cordova.getActivity());
michael@0 279 promptInput.setHint(defaultText);
michael@0 280 AlertDialog.Builder dlg = createDialog(cordova); // new AlertDialog.Builder(cordova.getActivity(), AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);
michael@0 281 dlg.setMessage(message);
michael@0 282 dlg.setTitle(title);
michael@0 283 dlg.setCancelable(true);
michael@0 284
michael@0 285 dlg.setView(promptInput);
michael@0 286
michael@0 287 final JSONObject result = new JSONObject();
michael@0 288
michael@0 289 // First button
michael@0 290 if (buttonLabels.length() > 0) {
michael@0 291 try {
michael@0 292 dlg.setNegativeButton(buttonLabels.getString(0),
michael@0 293 new AlertDialog.OnClickListener() {
michael@0 294 public void onClick(DialogInterface dialog, int which) {
michael@0 295 dialog.dismiss();
michael@0 296 try {
michael@0 297 result.put("buttonIndex",1);
michael@0 298 result.put("input1", promptInput.getText().toString().trim().length()==0 ? defaultText : promptInput.getText());
michael@0 299 } catch (JSONException e) { e.printStackTrace(); }
michael@0 300 callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, result));
michael@0 301 }
michael@0 302 });
michael@0 303 } catch (JSONException e) { }
michael@0 304 }
michael@0 305
michael@0 306 // Second button
michael@0 307 if (buttonLabels.length() > 1) {
michael@0 308 try {
michael@0 309 dlg.setNeutralButton(buttonLabels.getString(1),
michael@0 310 new AlertDialog.OnClickListener() {
michael@0 311 public void onClick(DialogInterface dialog, int which) {
michael@0 312 dialog.dismiss();
michael@0 313 try {
michael@0 314 result.put("buttonIndex",2);
michael@0 315 result.put("input1", promptInput.getText().toString().trim().length()==0 ? defaultText : promptInput.getText());
michael@0 316 } catch (JSONException e) { e.printStackTrace(); }
michael@0 317 callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, result));
michael@0 318 }
michael@0 319 });
michael@0 320 } catch (JSONException e) { }
michael@0 321 }
michael@0 322
michael@0 323 // Third button
michael@0 324 if (buttonLabels.length() > 2) {
michael@0 325 try {
michael@0 326 dlg.setPositiveButton(buttonLabels.getString(2),
michael@0 327 new AlertDialog.OnClickListener() {
michael@0 328 public void onClick(DialogInterface dialog, int which) {
michael@0 329 dialog.dismiss();
michael@0 330 try {
michael@0 331 result.put("buttonIndex",3);
michael@0 332 result.put("input1", promptInput.getText().toString().trim().length()==0 ? defaultText : promptInput.getText());
michael@0 333 } catch (JSONException e) { e.printStackTrace(); }
michael@0 334 callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, result));
michael@0 335 }
michael@0 336 });
michael@0 337 } catch (JSONException e) { }
michael@0 338 }
michael@0 339 dlg.setOnCancelListener(new AlertDialog.OnCancelListener() {
michael@0 340 public void onCancel(DialogInterface dialog){
michael@0 341 dialog.dismiss();
michael@0 342 try {
michael@0 343 result.put("buttonIndex",0);
michael@0 344 result.put("input1", promptInput.getText().toString().trim().length()==0 ? defaultText : promptInput.getText());
michael@0 345 } catch (JSONException e) { e.printStackTrace(); }
michael@0 346 callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, result));
michael@0 347 }
michael@0 348 });
michael@0 349
michael@0 350 changeTextDirection(dlg);
michael@0 351 };
michael@0 352 };
michael@0 353 this.cordova.getActivity().runOnUiThread(runnable);
michael@0 354 }
michael@0 355
michael@0 356 /**
michael@0 357 * Show the spinner.
michael@0 358 *
michael@0 359 * @param title Title of the dialog
michael@0 360 * @param message The message of the dialog
michael@0 361 */
michael@0 362 public synchronized void activityStart(final String title, final String message) {
michael@0 363 if (this.spinnerDialog != null) {
michael@0 364 this.spinnerDialog.dismiss();
michael@0 365 this.spinnerDialog = null;
michael@0 366 }
michael@0 367 final Notification notification = this;
michael@0 368 final CordovaInterface cordova = this.cordova;
michael@0 369 Runnable runnable = new Runnable() {
michael@0 370 public void run() {
michael@0 371 notification.spinnerDialog = createProgressDialog(cordova); // new ProgressDialog(cordova.getActivity(), AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);
michael@0 372 notification.spinnerDialog.setTitle(title);
michael@0 373 notification.spinnerDialog.setMessage(message);
michael@0 374 notification.spinnerDialog.setCancelable(true);
michael@0 375 notification.spinnerDialog.setIndeterminate(true);
michael@0 376 notification.spinnerDialog.setOnCancelListener(
michael@0 377 new DialogInterface.OnCancelListener() {
michael@0 378 public void onCancel(DialogInterface dialog) {
michael@0 379 notification.spinnerDialog = null;
michael@0 380 }
michael@0 381 });
michael@0 382 notification.spinnerDialog.show();
michael@0 383 }
michael@0 384 };
michael@0 385 this.cordova.getActivity().runOnUiThread(runnable);
michael@0 386 }
michael@0 387
michael@0 388 /**
michael@0 389 * Stop spinner.
michael@0 390 */
michael@0 391 public synchronized void activityStop() {
michael@0 392 if (this.spinnerDialog != null) {
michael@0 393 this.spinnerDialog.dismiss();
michael@0 394 this.spinnerDialog = null;
michael@0 395 }
michael@0 396 }
michael@0 397
michael@0 398 /**
michael@0 399 * Show the progress dialog.
michael@0 400 *
michael@0 401 * @param title Title of the dialog
michael@0 402 * @param message The message of the dialog
michael@0 403 */
michael@0 404 public synchronized void progressStart(final String title, final String message) {
michael@0 405 if (this.progressDialog != null) {
michael@0 406 this.progressDialog.dismiss();
michael@0 407 this.progressDialog = null;
michael@0 408 }
michael@0 409 final Notification notification = this;
michael@0 410 final CordovaInterface cordova = this.cordova;
michael@0 411 Runnable runnable = new Runnable() {
michael@0 412 public void run() {
michael@0 413 notification.progressDialog = createProgressDialog(cordova); // new ProgressDialog(cordova.getActivity(), AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);
michael@0 414 notification.progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
michael@0 415 notification.progressDialog.setTitle(title);
michael@0 416 notification.progressDialog.setMessage(message);
michael@0 417 notification.progressDialog.setCancelable(true);
michael@0 418 notification.progressDialog.setMax(100);
michael@0 419 notification.progressDialog.setProgress(0);
michael@0 420 notification.progressDialog.setOnCancelListener(
michael@0 421 new DialogInterface.OnCancelListener() {
michael@0 422 public void onCancel(DialogInterface dialog) {
michael@0 423 notification.progressDialog = null;
michael@0 424 }
michael@0 425 });
michael@0 426 notification.progressDialog.show();
michael@0 427 }
michael@0 428 };
michael@0 429 this.cordova.getActivity().runOnUiThread(runnable);
michael@0 430 }
michael@0 431
michael@0 432 /**
michael@0 433 * Set value of progress bar.
michael@0 434 *
michael@0 435 * @param value 0-100
michael@0 436 */
michael@0 437 public synchronized void progressValue(int value) {
michael@0 438 if (this.progressDialog != null) {
michael@0 439 this.progressDialog.setProgress(value);
michael@0 440 }
michael@0 441 }
michael@0 442
michael@0 443 /**
michael@0 444 * Stop progress dialog.
michael@0 445 */
michael@0 446 public synchronized void progressStop() {
michael@0 447 if (this.progressDialog != null) {
michael@0 448 this.progressDialog.dismiss();
michael@0 449 this.progressDialog = null;
michael@0 450 }
michael@0 451 }
michael@0 452
michael@0 453 @SuppressLint("NewApi")
michael@0 454 private AlertDialog.Builder createDialog(CordovaInterface cordova) {
michael@0 455 int currentapiVersion = android.os.Build.VERSION.SDK_INT;
michael@0 456 if (currentapiVersion >= android.os.Build.VERSION_CODES.HONEYCOMB) {
michael@0 457 return new AlertDialog.Builder(cordova.getActivity(), AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);
michael@0 458 } else {
michael@0 459 return new AlertDialog.Builder(cordova.getActivity());
michael@0 460 }
michael@0 461 }
michael@0 462
michael@0 463 @SuppressLint("InlinedApi")
michael@0 464 private ProgressDialog createProgressDialog(CordovaInterface cordova) {
michael@0 465 int currentapiVersion = android.os.Build.VERSION.SDK_INT;
michael@0 466 if (currentapiVersion >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
michael@0 467 return new ProgressDialog(cordova.getActivity(), AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);
michael@0 468 } else {
michael@0 469 return new ProgressDialog(cordova.getActivity());
michael@0 470 }
michael@0 471 }
michael@0 472
michael@0 473 @SuppressLint("NewApi")
michael@0 474 private void changeTextDirection(Builder dlg){
michael@0 475 int currentapiVersion = android.os.Build.VERSION.SDK_INT;
michael@0 476 dlg.create();
michael@0 477 AlertDialog dialog = dlg.show();
michael@0 478 if (currentapiVersion >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
michael@0 479 TextView messageview = (TextView)dialog.findViewById(android.R.id.message);
michael@0 480 messageview.setTextDirection(android.view.View.TEXT_DIRECTION_LOCALE);
michael@0 481 }
michael@0 482 }
michael@0 483 }

mercurial