1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 | package org.apache.cordova.dialogs;
|
20 |
|
21 | import android.annotation.SuppressLint;
|
22 | import android.app.AlertDialog;
|
23 | import android.app.AlertDialog.Builder;
|
24 | import android.app.ProgressDialog;
|
25 | import android.content.DialogInterface;
|
26 | import android.content.res.Resources;
|
27 | import android.media.Ringtone;
|
28 | import android.media.RingtoneManager;
|
29 | import android.net.Uri;
|
30 | import android.widget.EditText;
|
31 | import android.widget.TextView;
|
32 |
|
33 | import org.apache.cordova.CallbackContext;
|
34 | import org.apache.cordova.CordovaInterface;
|
35 | import org.apache.cordova.CordovaPlugin;
|
36 | import org.apache.cordova.LOG;
|
37 | import org.apache.cordova.PluginResult;
|
38 | import org.json.JSONArray;
|
39 | import org.json.JSONException;
|
40 | import org.json.JSONObject;
|
41 |
|
42 |
|
43 |
|
44 |
|
45 |
|
46 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 | public class Notification extends CordovaPlugin {
|
52 |
|
53 | private static final String LOG_TAG = "Notification";
|
54 |
|
55 | private static final String ACTION_BEEP = "beep";
|
56 | private static final String ACTION_ALERT = "alert";
|
57 | private static final String ACTION_CONFIRM = "confirm";
|
58 | private static final String ACTION_PROMPT = "prompt";
|
59 | private static final String ACTION_ACTIVITY_START = "activityStart";
|
60 | private static final String ACTION_ACTIVITY_STOP = "activityStop";
|
61 | private static final String ACTION_PROGRESS_START = "progressStart";
|
62 | private static final String ACTION_PROGRESS_VALUE = "progressValue";
|
63 | private static final String ACTION_PROGRESS_STOP = "progressStop";
|
64 |
|
65 | private static final long BEEP_TIMEOUT = 5000;
|
66 | private static final long BEEP_WAIT_TINE = 100;
|
67 |
|
68 | public int confirmResult = -1;
|
69 | public ProgressDialog spinnerDialog = null;
|
70 | public ProgressDialog progressDialog = null;
|
71 |
|
72 | |
73 |
|
74 |
|
75 | public Notification() {
|
76 | }
|
77 |
|
78 | |
79 |
|
80 |
|
81 |
|
82 |
|
83 |
|
84 |
|
85 |
|
86 | public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
|
87 | |
88 |
|
89 |
|
90 |
|
91 |
|
92 |
|
93 | if (this.cordova.getActivity().isFinishing()) return true;
|
94 |
|
95 | if (action.equals(ACTION_BEEP)) {
|
96 | this.beep(args.getLong(0));
|
97 | }
|
98 | else if (action.equals(ACTION_ALERT)) {
|
99 | this.alert(args.getString(0), args.getString(1), args.getString(2), callbackContext);
|
100 | return true;
|
101 | }
|
102 | else if (action.equals(ACTION_CONFIRM)) {
|
103 | this.confirm(args.getString(0), args.getString(1), args.getJSONArray(2), callbackContext);
|
104 | return true;
|
105 | }
|
106 | else if (action.equals(ACTION_PROMPT)) {
|
107 | this.prompt(args.getString(0), args.getString(1), args.getJSONArray(2), args.getString(3), callbackContext);
|
108 | return true;
|
109 | }
|
110 | else if (action.equals(ACTION_ACTIVITY_START)) {
|
111 | this.activityStart(args.getString(0), args.getString(1));
|
112 | }
|
113 | else if (action.equals(ACTION_ACTIVITY_STOP)) {
|
114 | this.activityStop();
|
115 | }
|
116 | else if (action.equals(ACTION_PROGRESS_START)) {
|
117 | this.progressStart(args.getString(0), args.getString(1));
|
118 | }
|
119 | else if (action.equals(ACTION_PROGRESS_VALUE)) {
|
120 | this.progressValue(args.getInt(0));
|
121 | }
|
122 | else if (action.equals(ACTION_PROGRESS_STOP)) {
|
123 | this.progressStop();
|
124 | }
|
125 | else {
|
126 | return false;
|
127 | }
|
128 |
|
129 |
|
130 | callbackContext.success();
|
131 | return true;
|
132 | }
|
133 |
|
134 |
|
135 |
|
136 |
|
137 |
|
138 | |
139 |
|
140 |
|
141 |
|
142 |
|
143 | public void beep(final long count) {
|
144 | cordova.getThreadPool().execute(new Runnable() {
|
145 | public void run() {
|
146 | Uri ringtone = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
|
147 | Ringtone notification = RingtoneManager.getRingtone(cordova.getActivity().getBaseContext(), ringtone);
|
148 |
|
149 |
|
150 | if (notification != null) {
|
151 | for (long i = 0; i < count; ++i) {
|
152 | notification.play();
|
153 | long timeout = BEEP_TIMEOUT;
|
154 | while (notification.isPlaying() && (timeout > 0)) {
|
155 | timeout = timeout - BEEP_WAIT_TINE;
|
156 | try {
|
157 | Thread.sleep(BEEP_WAIT_TINE);
|
158 | } catch (InterruptedException e) {
|
159 | Thread.currentThread().interrupt();
|
160 | }
|
161 | }
|
162 | }
|
163 | }
|
164 | }
|
165 | });
|
166 | }
|
167 |
|
168 | |
169 |
|
170 |
|
171 |
|
172 |
|
173 |
|
174 |
|
175 | public synchronized void alert(final String message, final String title, final String buttonLabel, final CallbackContext callbackContext) {
|
176 | final CordovaInterface cordova = this.cordova;
|
177 |
|
178 | Runnable runnable = new Runnable() {
|
179 | public void run() {
|
180 |
|
181 | Builder dlg = createDialog(cordova);
|
182 | dlg.setMessage(message);
|
183 | dlg.setTitle(title);
|
184 | dlg.setCancelable(true);
|
185 | dlg.setPositiveButton(buttonLabel,
|
186 | new AlertDialog.OnClickListener() {
|
187 | public void onClick(DialogInterface dialog, int which) {
|
188 | dialog.dismiss();
|
189 | callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, 0));
|
190 | }
|
191 | });
|
192 | dlg.setOnCancelListener(new AlertDialog.OnCancelListener() {
|
193 | public void onCancel(DialogInterface dialog)
|
194 | {
|
195 | dialog.dismiss();
|
196 | callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, 0));
|
197 | }
|
198 | });
|
199 |
|
200 | changeTextDirection(dlg);
|
201 | };
|
202 | };
|
203 | this.cordova.getActivity().runOnUiThread(runnable);
|
204 | }
|
205 |
|
206 | |
207 |
|
208 |
|
209 |
|
210 |
|
211 |
|
212 |
|
213 |
|
214 |
|
215 |
|
216 | public synchronized void confirm(final String message, final String title, final JSONArray buttonLabels, final CallbackContext callbackContext) {
|
217 | final CordovaInterface cordova = this.cordova;
|
218 |
|
219 | Runnable runnable = new Runnable() {
|
220 | public void run() {
|
221 | Builder dlg = createDialog(cordova);
|
222 | dlg.setMessage(message);
|
223 | dlg.setTitle(title);
|
224 | dlg.setCancelable(true);
|
225 |
|
226 |
|
227 | if (buttonLabels.length() > 0) {
|
228 | try {
|
229 | dlg.setNegativeButton(buttonLabels.getString(0),
|
230 | new AlertDialog.OnClickListener() {
|
231 | public void onClick(DialogInterface dialog, int which) {
|
232 | dialog.dismiss();
|
233 | callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, 1));
|
234 | }
|
235 | });
|
236 | } catch (JSONException e) {
|
237 | LOG.d(LOG_TAG,"JSONException on first button.");
|
238 | }
|
239 | }
|
240 |
|
241 |
|
242 | if (buttonLabels.length() > 1) {
|
243 | try {
|
244 | dlg.setNeutralButton(buttonLabels.getString(1),
|
245 | new AlertDialog.OnClickListener() {
|
246 | public void onClick(DialogInterface dialog, int which) {
|
247 | dialog.dismiss();
|
248 | callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, 2));
|
249 | }
|
250 | });
|
251 | } catch (JSONException e) {
|
252 | LOG.d(LOG_TAG,"JSONException on second button.");
|
253 | }
|
254 | }
|
255 |
|
256 |
|
257 | if (buttonLabels.length() > 2) {
|
258 | try {
|
259 | dlg.setPositiveButton(buttonLabels.getString(2),
|
260 | new AlertDialog.OnClickListener() {
|
261 | public void onClick(DialogInterface dialog, int which) {
|
262 | dialog.dismiss();
|
263 | callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, 3));
|
264 | }
|
265 | });
|
266 | } catch (JSONException e) {
|
267 | LOG.d(LOG_TAG,"JSONException on third button.");
|
268 | }
|
269 | }
|
270 | dlg.setOnCancelListener(new AlertDialog.OnCancelListener() {
|
271 | public void onCancel(DialogInterface dialog)
|
272 | {
|
273 | dialog.dismiss();
|
274 | callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, 0));
|
275 | }
|
276 | });
|
277 |
|
278 | changeTextDirection(dlg);
|
279 | };
|
280 | };
|
281 | this.cordova.getActivity().runOnUiThread(runnable);
|
282 | }
|
283 |
|
284 | |
285 |
|
286 |
|
287 |
|
288 |
|
289 |
|
290 |
|
291 |
|
292 |
|
293 |
|
294 |
|
295 |
|
296 | public synchronized void prompt(final String message, final String title, final JSONArray buttonLabels, final String defaultText, final CallbackContext callbackContext) {
|
297 |
|
298 | final CordovaInterface cordova = this.cordova;
|
299 |
|
300 | Runnable runnable = new Runnable() {
|
301 | public void run() {
|
302 | final EditText promptInput = new EditText(cordova.getActivity());
|
303 |
|
304 | |
305 |
|
306 |
|
307 | Resources resources = cordova.getActivity().getResources();
|
308 | int promptInputTextColor = resources.getColor(android.R.color.primary_text_light);
|
309 | promptInput.setTextColor(promptInputTextColor);
|
310 | promptInput.setText(defaultText);
|
311 | Builder dlg = createDialog(cordova);
|
312 | dlg.setMessage(message);
|
313 | dlg.setTitle(title);
|
314 | dlg.setCancelable(true);
|
315 |
|
316 | dlg.setView(promptInput);
|
317 |
|
318 | final JSONObject result = new JSONObject();
|
319 |
|
320 |
|
321 | if (buttonLabels.length() > 0) {
|
322 | try {
|
323 | dlg.setNegativeButton(buttonLabels.getString(0),
|
324 | new AlertDialog.OnClickListener() {
|
325 | public void onClick(DialogInterface dialog, int which) {
|
326 | dialog.dismiss();
|
327 | try {
|
328 | result.put("buttonIndex",1);
|
329 | result.put("input1", promptInput.getText().toString().trim().length()==0 ? defaultText : promptInput.getText());
|
330 | } catch (JSONException e) {
|
331 | LOG.d(LOG_TAG,"JSONException on first button.", e);
|
332 | }
|
333 | callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, result));
|
334 | }
|
335 | });
|
336 | } catch (JSONException e) {
|
337 | LOG.d(LOG_TAG,"JSONException on first button.");
|
338 | }
|
339 | }
|
340 |
|
341 |
|
342 | if (buttonLabels.length() > 1) {
|
343 | try {
|
344 | dlg.setNeutralButton(buttonLabels.getString(1),
|
345 | new AlertDialog.OnClickListener() {
|
346 | public void onClick(DialogInterface dialog, int which) {
|
347 | dialog.dismiss();
|
348 | try {
|
349 | result.put("buttonIndex",2);
|
350 | result.put("input1", promptInput.getText().toString().trim().length()==0 ? defaultText : promptInput.getText());
|
351 | } catch (JSONException e) {
|
352 | LOG.d(LOG_TAG,"JSONException on second button.", e);
|
353 | }
|
354 | callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, result));
|
355 | }
|
356 | });
|
357 | } catch (JSONException e) {
|
358 | LOG.d(LOG_TAG,"JSONException on second button.");
|
359 | }
|
360 | }
|
361 |
|
362 |
|
363 | if (buttonLabels.length() > 2) {
|
364 | try {
|
365 | dlg.setPositiveButton(buttonLabels.getString(2),
|
366 | new AlertDialog.OnClickListener() {
|
367 | public void onClick(DialogInterface dialog, int which) {
|
368 | dialog.dismiss();
|
369 | try {
|
370 | result.put("buttonIndex",3);
|
371 | result.put("input1", promptInput.getText().toString().trim().length()==0 ? defaultText : promptInput.getText());
|
372 | } catch (JSONException e) {
|
373 | LOG.d(LOG_TAG,"JSONException on third button.", e);
|
374 | }
|
375 | callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, result));
|
376 | }
|
377 | });
|
378 | } catch (JSONException e) {
|
379 | LOG.d(LOG_TAG,"JSONException on third button.");
|
380 | }
|
381 | }
|
382 | dlg.setOnCancelListener(new AlertDialog.OnCancelListener() {
|
383 | public void onCancel(DialogInterface dialog){
|
384 | dialog.dismiss();
|
385 | try {
|
386 | result.put("buttonIndex",0);
|
387 | result.put("input1", promptInput.getText().toString().trim().length()==0 ? defaultText : promptInput.getText());
|
388 | } catch (JSONException e) { e.printStackTrace(); }
|
389 | callbackContext.sendPluginResult(new PluginResult(PluginResult.Status.OK, result));
|
390 | }
|
391 | });
|
392 |
|
393 | changeTextDirection(dlg);
|
394 | };
|
395 | };
|
396 | this.cordova.getActivity().runOnUiThread(runnable);
|
397 | }
|
398 |
|
399 | |
400 |
|
401 |
|
402 |
|
403 |
|
404 |
|
405 | public synchronized void activityStart(final String title, final String message) {
|
406 | if (this.spinnerDialog != null) {
|
407 | this.spinnerDialog.dismiss();
|
408 | this.spinnerDialog = null;
|
409 | }
|
410 | final Notification notification = this;
|
411 | final CordovaInterface cordova = this.cordova;
|
412 | Runnable runnable = new Runnable() {
|
413 | public void run() {
|
414 | notification.spinnerDialog = createProgressDialog(cordova);
|
415 | notification.spinnerDialog.setTitle(title);
|
416 | notification.spinnerDialog.setMessage(message);
|
417 | notification.spinnerDialog.setCancelable(true);
|
418 | notification.spinnerDialog.setIndeterminate(true);
|
419 | notification.spinnerDialog.setOnCancelListener(
|
420 | new DialogInterface.OnCancelListener() {
|
421 | public void onCancel(DialogInterface dialog) {
|
422 | notification.spinnerDialog = null;
|
423 | }
|
424 | });
|
425 | notification.spinnerDialog.show();
|
426 | }
|
427 | };
|
428 | this.cordova.getActivity().runOnUiThread(runnable);
|
429 | }
|
430 |
|
431 | |
432 |
|
433 |
|
434 | public synchronized void activityStop() {
|
435 | if (this.spinnerDialog != null) {
|
436 | this.spinnerDialog.dismiss();
|
437 | this.spinnerDialog = null;
|
438 | }
|
439 | }
|
440 |
|
441 | |
442 |
|
443 |
|
444 |
|
445 |
|
446 |
|
447 | public synchronized void progressStart(final String title, final String message) {
|
448 | if (this.progressDialog != null) {
|
449 | this.progressDialog.dismiss();
|
450 | this.progressDialog = null;
|
451 | }
|
452 | final Notification notification = this;
|
453 | final CordovaInterface cordova = this.cordova;
|
454 | Runnable runnable = new Runnable() {
|
455 | public void run() {
|
456 | notification.progressDialog = createProgressDialog(cordova);
|
457 | notification.progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
|
458 | notification.progressDialog.setTitle(title);
|
459 | notification.progressDialog.setMessage(message);
|
460 | notification.progressDialog.setCancelable(true);
|
461 | notification.progressDialog.setMax(100);
|
462 | notification.progressDialog.setProgress(0);
|
463 | notification.progressDialog.setOnCancelListener(
|
464 | new DialogInterface.OnCancelListener() {
|
465 | public void onCancel(DialogInterface dialog) {
|
466 | notification.progressDialog = null;
|
467 | }
|
468 | });
|
469 | notification.progressDialog.show();
|
470 | }
|
471 | };
|
472 | this.cordova.getActivity().runOnUiThread(runnable);
|
473 | }
|
474 |
|
475 | |
476 |
|
477 |
|
478 |
|
479 |
|
480 | public synchronized void progressValue(int value) {
|
481 | if (this.progressDialog != null) {
|
482 | this.progressDialog.setProgress(value);
|
483 | }
|
484 | }
|
485 |
|
486 | |
487 |
|
488 |
|
489 | public synchronized void progressStop() {
|
490 | if (this.progressDialog != null) {
|
491 | this.progressDialog.dismiss();
|
492 | this.progressDialog = null;
|
493 | }
|
494 | }
|
495 |
|
496 | @SuppressLint("NewApi")
|
497 | private Builder createDialog(CordovaInterface cordova) {
|
498 | int currentapiVersion = android.os.Build.VERSION.SDK_INT;
|
499 | if (currentapiVersion >= android.os.Build.VERSION_CODES.HONEYCOMB) {
|
500 | return new Builder(cordova.getActivity(), AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);
|
501 | } else {
|
502 | return new Builder(cordova.getActivity());
|
503 | }
|
504 | }
|
505 |
|
506 | @SuppressLint("InlinedApi")
|
507 | private ProgressDialog createProgressDialog(CordovaInterface cordova) {
|
508 | int currentapiVersion = android.os.Build.VERSION.SDK_INT;
|
509 | if (currentapiVersion >= android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
|
510 | return new ProgressDialog(cordova.getActivity(), AlertDialog.THEME_DEVICE_DEFAULT_LIGHT);
|
511 | } else {
|
512 | return new ProgressDialog(cordova.getActivity());
|
513 | }
|
514 | }
|
515 |
|
516 | @SuppressLint("NewApi")
|
517 | private void changeTextDirection(Builder dlg){
|
518 | int currentapiVersion = android.os.Build.VERSION.SDK_INT;
|
519 | dlg.create();
|
520 | AlertDialog dialog = dlg.show();
|
521 | if (currentapiVersion >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) {
|
522 | TextView messageview = (TextView)dialog.findViewById(android.R.id.message);
|
523 | messageview.setTextDirection(android.view.View.TEXT_DIRECTION_LOCALE);
|
524 | }
|
525 | }
|
526 | }
|