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.

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

mercurial