mirror of
https://github.com/apache/cordova-android.git
synced 2025-05-18 01:57:23 +08:00
Extract alert, confirm, prompt Dialog logic into a helper for use by other engines
This commit is contained in:
parent
de4d7cd10d
commit
8106981bb6
@ -18,31 +18,24 @@
|
|||||||
*/
|
*/
|
||||||
package org.apache.cordova;
|
package org.apache.cordova;
|
||||||
|
|
||||||
import org.apache.cordova.CordovaInterface;
|
|
||||||
import org.apache.cordova.LOG;
|
|
||||||
|
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.content.ActivityNotFoundException;
|
import android.content.ActivityNotFoundException;
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.util.Log;
|
import android.util.Log;
|
||||||
import android.view.Gravity;
|
import android.view.Gravity;
|
||||||
import android.view.KeyEvent;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup.LayoutParams;
|
import android.view.ViewGroup.LayoutParams;
|
||||||
import android.webkit.ConsoleMessage;
|
import android.webkit.ConsoleMessage;
|
||||||
|
import android.webkit.GeolocationPermissions.Callback;
|
||||||
import android.webkit.JsPromptResult;
|
import android.webkit.JsPromptResult;
|
||||||
import android.webkit.JsResult;
|
import android.webkit.JsResult;
|
||||||
import android.webkit.ValueCallback;
|
import android.webkit.ValueCallback;
|
||||||
import android.webkit.WebChromeClient;
|
import android.webkit.WebChromeClient;
|
||||||
import android.webkit.WebStorage;
|
import android.webkit.WebStorage;
|
||||||
import android.webkit.WebView;
|
import android.webkit.WebView;
|
||||||
import android.webkit.GeolocationPermissions.Callback;
|
|
||||||
import android.widget.EditText;
|
|
||||||
import android.widget.LinearLayout;
|
import android.widget.LinearLayout;
|
||||||
import android.widget.ProgressBar;
|
import android.widget.ProgressBar;
|
||||||
import android.widget.RelativeLayout;
|
import android.widget.RelativeLayout;
|
||||||
@ -52,11 +45,6 @@ import android.widget.RelativeLayout;
|
|||||||
* The kind of callbacks that happen here are on the chrome outside the document,
|
* The kind of callbacks that happen here are on the chrome outside the document,
|
||||||
* such as onCreateWindow(), onConsoleMessage(), onProgressChanged(), etc. Related
|
* such as onCreateWindow(), onConsoleMessage(), onProgressChanged(), etc. Related
|
||||||
* to but different than CordovaWebViewClient.
|
* to but different than CordovaWebViewClient.
|
||||||
*
|
|
||||||
* @see <a href="http://developer.android.com/reference/android/webkit/WebChromeClient.html">WebChromeClient</a>
|
|
||||||
* @see <a href="http://developer.android.com/guide/webapps/webview.html">WebView guide</a>
|
|
||||||
* @see CordovaWebViewClient
|
|
||||||
* @see CordovaWebView
|
|
||||||
*/
|
*/
|
||||||
public class AndroidChromeClient extends WebChromeClient {
|
public class AndroidChromeClient extends WebChromeClient {
|
||||||
|
|
||||||
@ -69,104 +57,46 @@ public class AndroidChromeClient extends WebChromeClient {
|
|||||||
// the video progress view
|
// the video progress view
|
||||||
private View mVideoProgressView;
|
private View mVideoProgressView;
|
||||||
|
|
||||||
//Keep track of last AlertDialog showed
|
private CordovaDialogsHelper dialogsHelper;
|
||||||
private AlertDialog lastHandledDialog;
|
|
||||||
|
|
||||||
public AndroidChromeClient(CordovaInterface ctx, AndroidWebView app) {
|
public AndroidChromeClient(CordovaInterface ctx, AndroidWebView webView) {
|
||||||
this.cordova = ctx;
|
this.cordova = ctx;
|
||||||
this.appView = app;
|
this.appView = webView;
|
||||||
|
dialogsHelper = new CordovaDialogsHelper(webView.getContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tell the client to display a javascript alert dialog.
|
* Tell the client to display a javascript alert dialog.
|
||||||
*
|
|
||||||
* @param view
|
|
||||||
* @param url
|
|
||||||
* @param message
|
|
||||||
* @param result
|
|
||||||
* @see Other implementation in the Dialogs plugin.
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
|
public boolean onJsAlert(WebView view, String url, String message, final JsResult result) {
|
||||||
AlertDialog.Builder dlg = new AlertDialog.Builder(this.cordova.getActivity());
|
dialogsHelper.showAlert(message, new CordovaDialogsHelper.Result() {
|
||||||
dlg.setMessage(message);
|
@Override public void gotResult(boolean success, String value) {
|
||||||
dlg.setTitle("Alert");
|
if (success) {
|
||||||
//Don't let alerts break the back button
|
|
||||||
dlg.setCancelable(true);
|
|
||||||
dlg.setPositiveButton(android.R.string.ok,
|
|
||||||
new AlertDialog.OnClickListener() {
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
result.confirm();
|
result.confirm();
|
||||||
}
|
} else {
|
||||||
});
|
|
||||||
dlg.setOnCancelListener(
|
|
||||||
new DialogInterface.OnCancelListener() {
|
|
||||||
public void onCancel(DialogInterface dialog) {
|
|
||||||
result.cancel();
|
result.cancel();
|
||||||
}
|
}
|
||||||
});
|
|
||||||
dlg.setOnKeyListener(new DialogInterface.OnKeyListener() {
|
|
||||||
//DO NOTHING
|
|
||||||
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
|
|
||||||
if (keyCode == KeyEvent.KEYCODE_BACK)
|
|
||||||
{
|
|
||||||
result.confirm();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
lastHandledDialog = dlg.show();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Tell the client to display a confirm dialog to the user.
|
* Tell the client to display a confirm dialog to the user.
|
||||||
*
|
|
||||||
* @param view
|
|
||||||
* @param url
|
|
||||||
* @param message
|
|
||||||
* @param result
|
|
||||||
* @see Other implementation in the Dialogs plugin.
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {
|
public boolean onJsConfirm(WebView view, String url, String message, final JsResult result) {
|
||||||
AlertDialog.Builder dlg = new AlertDialog.Builder(this.cordova.getActivity());
|
dialogsHelper.showConfirm(message, new CordovaDialogsHelper.Result() {
|
||||||
dlg.setMessage(message);
|
@Override
|
||||||
dlg.setTitle("Confirm");
|
public void gotResult(boolean success, String value) {
|
||||||
dlg.setCancelable(true);
|
if (success) {
|
||||||
dlg.setPositiveButton(android.R.string.ok,
|
|
||||||
new DialogInterface.OnClickListener() {
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
result.confirm();
|
result.confirm();
|
||||||
}
|
} else {
|
||||||
});
|
|
||||||
dlg.setNegativeButton(android.R.string.cancel,
|
|
||||||
new DialogInterface.OnClickListener() {
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
result.cancel();
|
result.cancel();
|
||||||
}
|
}
|
||||||
});
|
|
||||||
dlg.setOnCancelListener(
|
|
||||||
new DialogInterface.OnCancelListener() {
|
|
||||||
public void onCancel(DialogInterface dialog) {
|
|
||||||
result.cancel();
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
dlg.setOnKeyListener(new DialogInterface.OnKeyListener() {
|
|
||||||
//DO NOTHING
|
|
||||||
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
|
|
||||||
if (keyCode == KeyEvent.KEYCODE_BACK)
|
|
||||||
{
|
|
||||||
result.cancel();
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
lastHandledDialog = dlg.show();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,40 +107,24 @@ public class AndroidChromeClient extends WebChromeClient {
|
|||||||
*
|
*
|
||||||
* Since we are hacking prompts for our own purposes, we should not be using them for
|
* Since we are hacking prompts for our own purposes, we should not be using them for
|
||||||
* this purpose, perhaps we should hack console.log to do this instead!
|
* this purpose, perhaps we should hack console.log to do this instead!
|
||||||
*
|
|
||||||
* @see Other implementation in the Dialogs plugin.
|
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public boolean onJsPrompt(WebView view, String origin, String message, String defaultValue, JsPromptResult result) {
|
public boolean onJsPrompt(WebView view, String origin, String message, String defaultValue, final JsPromptResult result) {
|
||||||
// Unlike the @JavascriptInterface bridge, this method is always called on the UI thread.
|
// Unlike the @JavascriptInterface bridge, this method is always called on the UI thread.
|
||||||
String handledRet = appView.bridge.promptOnJsPrompt(origin, message, defaultValue);
|
String handledRet = appView.bridge.promptOnJsPrompt(origin, message, defaultValue);
|
||||||
if (handledRet != null) {
|
if (handledRet != null) {
|
||||||
result.confirm(handledRet);
|
result.confirm(handledRet);
|
||||||
} else {
|
} else {
|
||||||
// Returning false would also show a dialog, but the default one shows the origin (ugly).
|
dialogsHelper.showPrompt(message, defaultValue, new CordovaDialogsHelper.Result() {
|
||||||
final JsPromptResult res = result;
|
@Override
|
||||||
AlertDialog.Builder dlg = new AlertDialog.Builder(this.cordova.getActivity());
|
public void gotResult(boolean success, String value) {
|
||||||
dlg.setMessage(message);
|
if (success) {
|
||||||
final EditText input = new EditText(this.cordova.getActivity());
|
result.confirm(value);
|
||||||
if (defaultValue != null) {
|
} else {
|
||||||
input.setText(defaultValue);
|
result.cancel();
|
||||||
}
|
}
|
||||||
dlg.setView(input);
|
|
||||||
dlg.setCancelable(false);
|
|
||||||
dlg.setPositiveButton(android.R.string.ok,
|
|
||||||
new DialogInterface.OnClickListener() {
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
String usertext = input.getText().toString();
|
|
||||||
res.confirm(usertext);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
dlg.setNegativeButton(android.R.string.cancel,
|
|
||||||
new DialogInterface.OnClickListener() {
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
res.cancel();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
lastHandledDialog = dlg.show();
|
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -348,9 +262,7 @@ public class AndroidChromeClient extends WebChromeClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void destroyLastDialog(){
|
public void destroyLastDialog(){
|
||||||
if(lastHandledDialog != null){
|
dialogsHelper.destroyLastDialog();
|
||||||
lastHandledDialog.cancel();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
152
framework/src/org/apache/cordova/CordovaDialogsHelper.java
Normal file
152
framework/src/org/apache/cordova/CordovaDialogsHelper.java
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
/*
|
||||||
|
Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
or more contributor license agreements. See the NOTICE file
|
||||||
|
distributed with this work for additional information
|
||||||
|
regarding copyright ownership. The ASF licenses this file
|
||||||
|
to you under the Apache License, Version 2.0 (the
|
||||||
|
"License"); you may not use this file except in compliance
|
||||||
|
with the License. You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing,
|
||||||
|
software distributed under the License is distributed on an
|
||||||
|
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
KIND, either express or implied. See the License for the
|
||||||
|
specific language governing permissions and limitations
|
||||||
|
under the License.
|
||||||
|
*/
|
||||||
|
package org.apache.cordova;
|
||||||
|
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.view.KeyEvent;
|
||||||
|
import android.widget.EditText;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Helper class for WebViews to implement prompt(), alert(), confirm() dialogs.
|
||||||
|
*/
|
||||||
|
public class CordovaDialogsHelper {
|
||||||
|
private final Context context;
|
||||||
|
private AlertDialog lastHandledDialog;
|
||||||
|
|
||||||
|
public CordovaDialogsHelper(Context context) {
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void showAlert(String message, final Result result) {
|
||||||
|
AlertDialog.Builder dlg = new AlertDialog.Builder(context);
|
||||||
|
dlg.setMessage(message);
|
||||||
|
dlg.setTitle("Alert");
|
||||||
|
//Don't let alerts break the back button
|
||||||
|
dlg.setCancelable(true);
|
||||||
|
dlg.setPositiveButton(android.R.string.ok,
|
||||||
|
new AlertDialog.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
result.gotResult(true, null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
dlg.setOnCancelListener(
|
||||||
|
new DialogInterface.OnCancelListener() {
|
||||||
|
public void onCancel(DialogInterface dialog) {
|
||||||
|
result.gotResult(false, null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
dlg.setOnKeyListener(new DialogInterface.OnKeyListener() {
|
||||||
|
//DO NOTHING
|
||||||
|
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
|
||||||
|
if (keyCode == KeyEvent.KEYCODE_BACK)
|
||||||
|
{
|
||||||
|
result.gotResult(true, null);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
lastHandledDialog = dlg.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void showConfirm(String message, final Result result) {
|
||||||
|
AlertDialog.Builder dlg = new AlertDialog.Builder(context);
|
||||||
|
dlg.setMessage(message);
|
||||||
|
dlg.setTitle("Confirm");
|
||||||
|
dlg.setCancelable(true);
|
||||||
|
dlg.setPositiveButton(android.R.string.ok,
|
||||||
|
new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
result.gotResult(true, null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
dlg.setNegativeButton(android.R.string.cancel,
|
||||||
|
new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
result.gotResult(false, null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
dlg.setOnCancelListener(
|
||||||
|
new DialogInterface.OnCancelListener() {
|
||||||
|
public void onCancel(DialogInterface dialog) {
|
||||||
|
result.gotResult(false, null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
dlg.setOnKeyListener(new DialogInterface.OnKeyListener() {
|
||||||
|
//DO NOTHING
|
||||||
|
public boolean onKey(DialogInterface dialog, int keyCode, KeyEvent event) {
|
||||||
|
if (keyCode == KeyEvent.KEYCODE_BACK)
|
||||||
|
{
|
||||||
|
result.gotResult(false, null);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
lastHandledDialog = dlg.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tell the client to display a prompt dialog to the user.
|
||||||
|
* If the client returns true, WebView will assume that the client will
|
||||||
|
* handle the prompt dialog and call the appropriate JsPromptResult method.
|
||||||
|
*
|
||||||
|
* Since we are hacking prompts for our own purposes, we should not be using them for
|
||||||
|
* this purpose, perhaps we should hack console.log to do this instead!
|
||||||
|
*/
|
||||||
|
public void showPrompt(String message, String defaultValue, final Result result) {
|
||||||
|
// Returning false would also show a dialog, but the default one shows the origin (ugly).
|
||||||
|
AlertDialog.Builder dlg = new AlertDialog.Builder(context);
|
||||||
|
dlg.setMessage(message);
|
||||||
|
final EditText input = new EditText(context);
|
||||||
|
if (defaultValue != null) {
|
||||||
|
input.setText(defaultValue);
|
||||||
|
}
|
||||||
|
dlg.setView(input);
|
||||||
|
dlg.setCancelable(false);
|
||||||
|
dlg.setPositiveButton(android.R.string.ok,
|
||||||
|
new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
String userText = input.getText().toString();
|
||||||
|
result.gotResult(true, userText);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
dlg.setNegativeButton(android.R.string.cancel,
|
||||||
|
new DialogInterface.OnClickListener() {
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
result.gotResult(false, null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
lastHandledDialog = dlg.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void destroyLastDialog(){
|
||||||
|
if (lastHandledDialog != null){
|
||||||
|
lastHandledDialog.cancel();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface Result {
|
||||||
|
public void gotResult(boolean success, String value);
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user