1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/Touchgui/plugins/org.apache.cordova.dialogs/src/android/Notification.java Thu Jun 04 14:50:33 2015 +0200 1.3 @@ -0,0 +1,483 @@ 1.4 +/* 1.5 + Licensed to the Apache Software Foundation (ASF) under one 1.6 + or more contributor license agreements. See the NOTICE file 1.7 + distributed with this work for additional information 1.8 + regarding copyright ownership. The ASF licenses this file 1.9 + to you under the Apache License, Version 2.0 (the 1.10 + "License"); you may not use this file except in compliance 1.11 + with the License. You may obtain a copy of the License at 1.12 + 1.13 + http://www.apache.org/licenses/LICENSE-2.0 1.14 + 1.15 + Unless required by applicable law or agreed to in writing, 1.16 + software distributed under the License is distributed on an 1.17 + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 1.18 + KIND, either express or implied. See the License for the 1.19 + specific language governing permissions and limitations 1.20 + under the License. 1.21 +*/ 1.22 +package org.apache.cordova.dialogs; 1.23 + 1.24 +import org.apache.cordova.CallbackContext; 1.25 +import org.apache.cordova.CordovaInterface; 1.26 +import org.apache.cordova.CordovaPlugin; 1.27 +import org.apache.cordova.PluginResult; 1.28 +import org.json.JSONArray; 1.29 +import org.json.JSONException; 1.30 +import org.json.JSONObject; 1.31 + 1.32 +import android.annotation.SuppressLint; 1.33 +import android.app.AlertDialog; 1.34 +import android.app.AlertDialog.Builder; 1.35 +import android.app.ProgressDialog; 1.36 +import android.content.DialogInterface; 1.37 +import android.media.Ringtone; 1.38 +import android.media.RingtoneManager; 1.39 +import android.net.Uri; 1.40 +import android.widget.EditText; 1.41 +import android.widget.TextView; 1.42 + 1.43 + 1.44 +/** 1.45 + * This class provides access to notifications on the device. 1.46 + * 1.47 + * Be aware that this implementation gets called on 1.48 + * navigator.notification.{alert|confirm|prompt}, and that there is a separate 1.49 + * implementation in org.apache.cordova.CordovaChromeClient that gets 1.50 + * called on a simple window.{alert|confirm|prompt}. 1.51 + */ 1.52 +public class Notification extends CordovaPlugin { 1.53 + 1.54 + public int confirmResult = -1; 1.55 + public ProgressDialog spinnerDialog = null; 1.56 + public ProgressDialog progressDialog = null; 1.57 + 1.58 + /** 1.59 + * Constructor. 1.60 + */ 1.61 + public Notification() { 1.62 + } 1.63 + 1.64 + /** 1.65 + * Executes the request and returns PluginResult. 1.66 + * 1.67 + * @param action The action to execute. 1.68 + * @param args JSONArray of arguments for the plugin. 1.69 + * @param callbackContext The callback context used when calling back into JavaScript. 1.70 + * @return True when the action was valid, false otherwise. 1.71 + */ 1.72 + public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException { 1.73 + /* 1.74 + * Don't run any of these if the current activity is finishing 1.75 + * in order to avoid android.view.WindowManager$BadTokenException 1.76 + * crashing the app. Just return true here since false should only 1.77 + * be returned in the event of an invalid action. 1.78 + */ 1.79 + if(this.cordova.getActivity().isFinishing()) return true; 1.80 + 1.81 + if (action.equals("beep")) { 1.82 + this.beep(args.getLong(0)); 1.83 + } 1.84 + else if (action.equals("alert")) { 1.85 + this.alert(args.getString(0), args.getString(1), args.getString(2), callbackContext); 1.86 + return true; 1.87 + } 1.88 + else if (action.equals("confirm")) { 1.89 + this.confirm(args.getString(0), args.getString(1), args.getJSONArray(2), callbackContext); 1.90 + return true; 1.91 + } 1.92 + else if (action.equals("prompt")) { 1.93 + this.prompt(args.getString(0), args.getString(1), args.getJSONArray(2), args.getString(3), callbackContext); 1.94 + return true; 1.95 + } 1.96 + else if (action.equals("activityStart")) { 1.97 + this.activityStart(args.getString(0), args.getString(1)); 1.98 + } 1.99 + else if (action.equals("activityStop")) { 1.100 + this.activityStop(); 1.101 + } 1.102 + else if (action.equals("progressStart")) { 1.103 + this.progressStart(args.getString(0), args.getString(1)); 1.104 + } 1.105 + else if (action.equals("progressValue")) { 1.106 + this.progressValue(args.getInt(0)); 1.107 + } 1.108 + else if (action.equals("progressStop")) { 1.109 + this.progressStop(); 1.110 + } 1.111 + else { 1.112 + return false; 1.113 + } 1.114 + 1.115 + // Only alert and confirm are async. 1.116 + callbackContext.success(); 1.117 + return true; 1.118 + } 1.119 + 1.120 + //-------------------------------------------------------------------------- 1.121 + // LOCAL METHODS 1.122 + //-------------------------------------------------------------------------- 1.123 + 1.124 + /** 1.125 + * Beep plays the default notification ringtone. 1.126 + * 1.127 + * @param count Number of times to play notification 1.128 + */ 1.129 + public void beep(final long count) { 1.130 + cordova.getThreadPool().execute(new Runnable() { 1.131 + public void run() { 1.132 + Uri ringtone = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION); 1.133 + Ringtone notification = RingtoneManager.getRingtone(cordova.getActivity().getBaseContext(), ringtone); 1.134 + 1.135 + // If phone is not set to silent mode 1.136 + if (notification != null) { 1.137 + for (long i = 0; i < count; ++i) { 1.138 + notification.play(); 1.139 + long timeout = 5000; 1.140 + while (notification.isPlaying() && (timeout > 0)) { 1.141 + timeout = timeout - 100; 1.142 + try { 1.143 + Thread.sleep(100); 1.144 + } catch (InterruptedException e) { 1.145 + } 1.146 + } 1.147 + } 1.148 + } 1.149 + } 1.150 + }); 1.151 + } 1.152 + 1.153 + /** 1.154 + * Builds and shows a native Android alert with given Strings 1.155 + * @param message The message the alert should display 1.156 + * @param title The title of the alert 1.157 + * @param buttonLabel The label of the button 1.158 + * @param callbackContext The callback context 1.159 + */ 1.160 + public synchronized void alert(final String message, final String title, final String buttonLabel, final CallbackContext callbackContext) { 1.161 + final CordovaInterface cordova = this.cordova; 1.162 + 1.163 + Runnable runnable = new Runnable() { 1.164 + public void run() { 1.165 + 1.166 + AlertDialog.Builder dlg = createDialog(cordova); // new AlertDialog.Builder(cordova.getActivity(), AlertDialog.THEME_DEVICE_DEFAULT_LIGHT); 1.167 + dlg.setMessage(message); 1.168 + dlg.setTitle(title); 1.169 + dlg.setCancelable(true); 1.170 + dlg.setPositiveButton(buttonLabel, 1.171 + new AlertDialog.OnClickListener() { 1.172 + public void onClick(DialogInterface dialog, int which) { 1.173 + dialog.dismiss(); 1.174 + callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, 0)); 1.175 + } 1.176 + }); 1.177 + dlg.setOnCancelListener(new AlertDialog.OnCancelListener() { 1.178 + public void onCancel(DialogInterface dialog) 1.179 + { 1.180 + dialog.dismiss(); 1.181 + callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, 0)); 1.182 + } 1.183 + }); 1.184 + 1.185 + changeTextDirection(dlg); 1.186 + }; 1.187 + }; 1.188 + this.cordova.getActivity().runOnUiThread(runnable); 1.189 + } 1.190 + 1.191 + /** 1.192 + * Builds and shows a native Android confirm dialog with given title, message, buttons. 1.193 + * This dialog only shows up to 3 buttons. Any labels after that will be ignored. 1.194 + * The index of the button pressed will be returned to the JavaScript callback identified by callbackId. 1.195 + * 1.196 + * @param message The message the dialog should display 1.197 + * @param title The title of the dialog 1.198 + * @param buttonLabels A comma separated list of button labels (Up to 3 buttons) 1.199 + * @param callbackContext The callback context. 1.200 + */ 1.201 + public synchronized void confirm(final String message, final String title, final JSONArray buttonLabels, final CallbackContext callbackContext) { 1.202 + final CordovaInterface cordova = this.cordova; 1.203 + 1.204 + Runnable runnable = new Runnable() { 1.205 + public void run() { 1.206 + AlertDialog.Builder dlg = createDialog(cordova); // new AlertDialog.Builder(cordova.getActivity(), AlertDialog.THEME_DEVICE_DEFAULT_LIGHT); 1.207 + dlg.setMessage(message); 1.208 + dlg.setTitle(title); 1.209 + dlg.setCancelable(true); 1.210 + 1.211 + // First button 1.212 + if (buttonLabels.length() > 0) { 1.213 + try { 1.214 + dlg.setNegativeButton(buttonLabels.getString(0), 1.215 + new AlertDialog.OnClickListener() { 1.216 + public void onClick(DialogInterface dialog, int which) { 1.217 + dialog.dismiss(); 1.218 + callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, 1)); 1.219 + } 1.220 + }); 1.221 + } catch (JSONException e) { } 1.222 + } 1.223 + 1.224 + // Second button 1.225 + if (buttonLabels.length() > 1) { 1.226 + try { 1.227 + dlg.setNeutralButton(buttonLabels.getString(1), 1.228 + new AlertDialog.OnClickListener() { 1.229 + public void onClick(DialogInterface dialog, int which) { 1.230 + dialog.dismiss(); 1.231 + callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, 2)); 1.232 + } 1.233 + }); 1.234 + } catch (JSONException e) { } 1.235 + } 1.236 + 1.237 + // Third button 1.238 + if (buttonLabels.length() > 2) { 1.239 + try { 1.240 + dlg.setPositiveButton(buttonLabels.getString(2), 1.241 + new AlertDialog.OnClickListener() { 1.242 + public void onClick(DialogInterface dialog, int which) { 1.243 + dialog.dismiss(); 1.244 + callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, 3)); 1.245 + } 1.246 + }); 1.247 + } catch (JSONException e) { } 1.248 + } 1.249 + dlg.setOnCancelListener(new AlertDialog.OnCancelListener() { 1.250 + public void onCancel(DialogInterface dialog) 1.251 + { 1.252 + dialog.dismiss(); 1.253 + callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, 0)); 1.254 + } 1.255 + }); 1.256 + 1.257 + changeTextDirection(dlg); 1.258 + }; 1.259 + }; 1.260 + this.cordova.getActivity().runOnUiThread(runnable); 1.261 + } 1.262 + 1.263 + /** 1.264 + * Builds and shows a native Android prompt dialog with given title, message, buttons. 1.265 + * This dialog only shows up to 3 buttons. Any labels after that will be ignored. 1.266 + * The following results are returned to the JavaScript callback identified by callbackId: 1.267 + * buttonIndex Index number of the button selected 1.268 + * input1 The text entered in the prompt dialog box 1.269 + * 1.270 + * @param message The message the dialog should display 1.271 + * @param title The title of the dialog 1.272 + * @param buttonLabels A comma separated list of button labels (Up to 3 buttons) 1.273 + * @param callbackContext The callback context. 1.274 + */ 1.275 + public synchronized void prompt(final String message, final String title, final JSONArray buttonLabels, final String defaultText, final CallbackContext callbackContext) { 1.276 + 1.277 + final CordovaInterface cordova = this.cordova; 1.278 + 1.279 + Runnable runnable = new Runnable() { 1.280 + public void run() { 1.281 + final EditText promptInput = new EditText(cordova.getActivity()); 1.282 + promptInput.setHint(defaultText); 1.283 + AlertDialog.Builder dlg = createDialog(cordova); // new AlertDialog.Builder(cordova.getActivity(), AlertDialog.THEME_DEVICE_DEFAULT_LIGHT); 1.284 + dlg.setMessage(message); 1.285 + dlg.setTitle(title); 1.286 + dlg.setCancelable(true); 1.287 + 1.288 + dlg.setView(promptInput); 1.289 + 1.290 + final JSONObject result = new JSONObject(); 1.291 + 1.292 + // First button 1.293 + if (buttonLabels.length() > 0) { 1.294 + try { 1.295 + dlg.setNegativeButton(buttonLabels.getString(0), 1.296 + new AlertDialog.OnClickListener() { 1.297 + public void onClick(DialogInterface dialog, int which) { 1.298 + dialog.dismiss(); 1.299 + try { 1.300 + result.put("buttonIndex",1); 1.301 + result.put("input1", promptInput.getText().toString().trim().length()==0 ? defaultText : promptInput.getText()); 1.302 + } catch (JSONException e) { e.printStackTrace(); } 1.303 + callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, result)); 1.304 + } 1.305 + }); 1.306 + } catch (JSONException e) { } 1.307 + } 1.308 + 1.309 + // Second button 1.310 + if (buttonLabels.length() > 1) { 1.311 + try { 1.312 + dlg.setNeutralButton(buttonLabels.getString(1), 1.313 + new AlertDialog.OnClickListener() { 1.314 + public void onClick(DialogInterface dialog, int which) { 1.315 + dialog.dismiss(); 1.316 + try { 1.317 + result.put("buttonIndex",2); 1.318 + result.put("input1", promptInput.getText().toString().trim().length()==0 ? defaultText : promptInput.getText()); 1.319 + } catch (JSONException e) { e.printStackTrace(); } 1.320 + callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, result)); 1.321 + } 1.322 + }); 1.323 + } catch (JSONException e) { } 1.324 + } 1.325 + 1.326 + // Third button 1.327 + if (buttonLabels.length() > 2) { 1.328 + try { 1.329 + dlg.setPositiveButton(buttonLabels.getString(2), 1.330 + new AlertDialog.OnClickListener() { 1.331 + public void onClick(DialogInterface dialog, int which) { 1.332 + dialog.dismiss(); 1.333 + try { 1.334 + result.put("buttonIndex",3); 1.335 + result.put("input1", promptInput.getText().toString().trim().length()==0 ? defaultText : promptInput.getText()); 1.336 + } catch (JSONException e) { e.printStackTrace(); } 1.337 + callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, result)); 1.338 + } 1.339 + }); 1.340 + } catch (JSONException e) { } 1.341 + } 1.342 + dlg.setOnCancelListener(new AlertDialog.OnCancelListener() { 1.343 + public void onCancel(DialogInterface dialog){ 1.344 + dialog.dismiss(); 1.345 + try { 1.346 + result.put("buttonIndex",0); 1.347 + result.put("input1", promptInput.getText().toString().trim().length()==0 ? defaultText : promptInput.getText()); 1.348 + } catch (JSONException e) { e.printStackTrace(); } 1.349 + callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, result)); 1.350 + } 1.351 + }); 1.352 + 1.353 + changeTextDirection(dlg); 1.354 + }; 1.355 + }; 1.356 + this.cordova.getActivity().runOnUiThread(runnable); 1.357 + } 1.358 + 1.359 + /** 1.360 + * Show the spinner. 1.361 + * 1.362 + * @param title Title of the dialog 1.363 + * @param message The message of the dialog 1.364 + */ 1.365 + public synchronized void activityStart(final String title, final String message) { 1.366 + if (this.spinnerDialog != null) { 1.367 + this.spinnerDialog.dismiss(); 1.368 + this.spinnerDialog = null; 1.369 + } 1.370 + final Notification notification = this; 1.371 + final CordovaInterface cordova = this.cordova; 1.372 + Runnable runnable = new Runnable() { 1.373 + public void run() { 1.374 + notification.spinnerDialog = createProgressDialog(cordova); // new ProgressDialog(cordova.getActivity(), AlertDialog.THEME_DEVICE_DEFAULT_LIGHT); 1.375 + notification.spinnerDialog.setTitle(title); 1.376 + notification.spinnerDialog.setMessage(message); 1.377 + notification.spinnerDialog.setCancelable(true); 1.378 + notification.spinnerDialog.setIndeterminate(true); 1.379 + notification.spinnerDialog.setOnCancelListener( 1.380 + new DialogInterface.OnCancelListener() { 1.381 + public void onCancel(DialogInterface dialog) { 1.382 + notification.spinnerDialog = null; 1.383 + } 1.384 + }); 1.385 + notification.spinnerDialog.show(); 1.386 + } 1.387 + }; 1.388 + this.cordova.getActivity().runOnUiThread(runnable); 1.389 + } 1.390 + 1.391 + /** 1.392 + * Stop spinner. 1.393 + */ 1.394 + public synchronized void activityStop() { 1.395 + if (this.spinnerDialog != null) { 1.396 + this.spinnerDialog.dismiss(); 1.397 + this.spinnerDialog = null; 1.398 + } 1.399 + } 1.400 + 1.401 + /** 1.402 + * Show the progress dialog. 1.403 + * 1.404 + * @param title Title of the dialog 1.405 + * @param message The message of the dialog 1.406 + */ 1.407 + public synchronized void progressStart(final String title, final String message) { 1.408 + if (this.progressDialog != null) { 1.409 + this.progressDialog.dismiss(); 1.410 + this.progressDialog = null; 1.411 + } 1.412 + final Notification notification = this; 1.413 + final CordovaInterface cordova = this.cordova; 1.414 + Runnable runnable = new Runnable() { 1.415 + public void run() { 1.416 + notification.progressDialog = createProgressDialog(cordova); // new ProgressDialog(cordova.getActivity(), AlertDialog.THEME_DEVICE_DEFAULT_LIGHT); 1.417 + notification.progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 1.418 + notification.progressDialog.setTitle(title); 1.419 + notification.progressDialog.setMessage(message); 1.420 + notification.progressDialog.setCancelable(true); 1.421 + notification.progressDialog.setMax(100); 1.422 + notification.progressDialog.setProgress(0); 1.423 + notification.progressDialog.setOnCancelListener( 1.424 + new DialogInterface.OnCancelListener() { 1.425 + public void onCancel(DialogInterface dialog) { 1.426 + notification.progressDialog = null; 1.427 + } 1.428 + }); 1.429 + notification.progressDialog.show(); 1.430 + } 1.431 + }; 1.432 + this.cordova.getActivity().runOnUiThread(runnable); 1.433 + } 1.434 + 1.435 + /** 1.436 + * Set value of progress bar. 1.437 + * 1.438 + * @param value 0-100 1.439 + */ 1.440 + public synchronized void progressValue(int value) { 1.441 + if (this.progressDialog != null) { 1.442 + this.progressDialog.setProgress(value); 1.443 + } 1.444 + } 1.445 + 1.446 + /** 1.447 + * Stop progress dialog. 1.448 + */ 1.449 + public synchronized void progressStop() { 1.450 + if (this.progressDialog != null) { 1.451 + this.progressDialog.dismiss(); 1.452 + this.progressDialog = null; 1.453 + } 1.454 + } 1.455 + 1.456 + @SuppressLint("NewApi") 1.457 + private AlertDialog.Builder createDialog(CordovaInterface cordova) { 1.458 + int currentapiVersion = android.os.Build.VERSION.SDK_INT; 1.459 + if (currentapiVersion >= android.os.Build.VERSION_CODES.HONEYCOMB) { 1.460 + return new AlertDialog.Builder(cordova.getActivity(), AlertDialog.THEME_DEVICE_DEFAULT_LIGHT); 1.461 + } else { 1.462 + return new AlertDialog.Builder(cordova.getActivity()); 1.463 + } 1.464 + } 1.465 + 1.466 + @SuppressLint("InlinedApi") 1.467 + private ProgressDialog createProgressDialog(CordovaInterface cordova) { 1.468 + int currentapiVersion = android.os.Build.VERSION.SDK_INT; 1.469 + if (currentapiVersion >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) { 1.470 + return new ProgressDialog(cordova.getActivity(), AlertDialog.THEME_DEVICE_DEFAULT_LIGHT); 1.471 + } else { 1.472 + return new ProgressDialog(cordova.getActivity()); 1.473 + } 1.474 + } 1.475 + 1.476 + @SuppressLint("NewApi") 1.477 + private void changeTextDirection(Builder dlg){ 1.478 + int currentapiVersion = android.os.Build.VERSION.SDK_INT; 1.479 + dlg.create(); 1.480 + AlertDialog dialog = dlg.show(); 1.481 + if (currentapiVersion >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) { 1.482 + TextView messageview = (TextView)dialog.findViewById(android.R.id.message); 1.483 + messageview.setTextDirection(android.view.View.TEXT_DIRECTION_LOCALE); 1.484 + } 1.485 + } 1.486 +}