1

我正在使用以下课程在子浏览器中打开链接,但无法在 Android 上跟踪设备后退按钮事件。我正在使用 showWebPage 方法,因为还有关闭按钮,但我想跟踪设备后退按钮事件。

公共类 ChildBrowser 扩展插件 {

protected static final String LOG_TAG = "ChildBrowser";
private static int CLOSE_EVENT = 0;
private static int LOCATION_CHANGED_EVENT = 1;

private String browserCallbackId = null;

private Dialog dialog;
private WebView webview;
private EditText edittext; 
private boolean showLocationBar = true;

/**
 * Executes the request and returns PluginResult.
 *
 * @param action        The action to execute.
 * @param args          JSONArry of arguments for the plugin.
 * @param callbackId    The callback id used when calling back into JavaScript.
 * @return              A PluginResult object with a status and message.
 */
public PluginResult execute(String action, JSONArray args, String callbackId) {
    PluginResult.Status status = PluginResult.Status.OK;
    String result = "";

    try {
        if (action.equals("showWebPage")) {
            this.browserCallbackId = callbackId;

            // If the ChildBrowser is already open then throw an error
            if (dialog != null && dialog.isShowing()) {
                return new PluginResult(PluginResult.Status.ERROR, "ChildBrowser is already open");
            }

            result = this.showWebPage(args.getString(0), args.optJSONObject(1));

            if (result.length() > 0) {
                status = PluginResult.Status.ERROR;
                return new PluginResult(status, result);
            } else {
                PluginResult pluginResult = new PluginResult(status, result);
                pluginResult.setKeepCallback(true);
                return pluginResult;
            }
        }
        else if (action.equals("close")) {
            closeDialog();

            JSONObject obj = new JSONObject();
            obj.put("type", CLOSE_EVENT);

            PluginResult pluginResult = new PluginResult(status, obj);
            pluginResult.setKeepCallback(false);
            return pluginResult;
        }
        else if (action.equals("openExternal")) {
            result = this.openExternal(args.getString(0), args.optBoolean(1));
            if (result.length() > 0) {
                status = PluginResult.Status.ERROR;
            }
        }
        else {
            status = PluginResult.Status.INVALID_ACTION;
        }
        return new PluginResult(status, result);
    } catch (JSONException e) {
        return new PluginResult(PluginResult.Status.JSON_EXCEPTION);
    }
}

/**
 * Display a new browser with the specified URL.
 *
 * @param url           The url to load.
 * @param usePhoneGap   Load url in PhoneGap webview
 * @return              "" if ok, or error message.
 */
public String openExternal(String url, boolean usePhoneGap) {
    try {
        Intent intent = null;
        if (usePhoneGap) {
            intent = new Intent().setClass(this.ctx.getContext(), org.apache.cordova.DroidGap.class);
            intent.setData(Uri.parse(url)); // This line will be removed in future.
            intent.putExtra("url", url);

            // Timeout parameter: 60 sec max - May be less if http device timeout is less.
            intent.putExtra("loadUrlTimeoutValue", 60000);

            // These parameters can be configured if you want to show the loading dialog
            intent.putExtra("loadingDialog", "Wait,Loading web page...");   // show loading dialog
            intent.putExtra("hideLoadingDialogOnPageLoad", true);           // hide it once page has completely loaded
        }
        else {
            intent = new Intent(Intent.ACTION_VIEW);
            intent.setData(Uri.parse(url));
        }
        this.ctx.startActivity(intent);
        return "";
    } catch (android.content.ActivityNotFoundException e) {
        Log.d(LOG_TAG, "ChildBrowser: Error loading url "+url+":"+ e.toString());
        return e.toString();
    }
}

/**
 * Closes the dialog
 */
private void closeDialog() {
    if (dialog != null) {
        dialog.dismiss();
    }
}

/**
 * Checks to see if it is possible to go back one page in history, then does so.
 */
private void goBack() {
    if (this.webview.canGoBack()) {
        this.webview.goBack();
    }
}

/**
 * Checks to see if it is possible to go forward one page in history, then does so.
 */
private void goForward() {
    if (this.webview.canGoForward()) {
        this.webview.goForward();
    }
}

/**
 * Navigate to the new page
 * 
 * @param url to load
 */
private void navigate(String url) {        
    InputMethodManager imm = (InputMethodManager)this.ctx.getSystemService(Context.INPUT_METHOD_SERVICE);
    imm.hideSoftInputFromWindow(edittext.getWindowToken(), 0);

    if (!url.startsWith("http") && !url.startsWith("file:")) {
        this.webview.loadUrl("http://" + url);
    } else {
        this.webview.loadUrl(url);
    }
    this.webview.requestFocus();
}


/**
 * Should we show the location bar?
 * 
 * @return boolean
 */
private boolean getShowLocationBar() {
    return this.showLocationBar;
}

/**
 * Display a new browser with the specified URL.
 *
 * @param url           The url to load.
 * @param jsonObject 
 */
public String showWebPage(final String url, JSONObject options) {
    // Determine if we should hide the location bar.
    if (options != null) {
        showLocationBar = options.optBoolean("showLocationBar", true);
    }

    // Create dialog in new thread 
    Runnable runnable = new Runnable() {
        /**
         * Convert our DIP units to Pixels
         * 
         * @return int
         */
        private int dpToPixels(int dipValue) {
            int value = (int) TypedValue.applyDimension( TypedValue.COMPLEX_UNIT_DIP,
                                                        (float) dipValue,
                                                        ctx.getContext().getResources().getDisplayMetrics()
            );

            return value;
        }

        public void run() {
            // Let's create the main dialog
            dialog = new Dialog(ctx.getContext(), android.R.style.Theme_NoTitleBar);
            dialog.getWindow().getAttributes().windowAnimations = android.R.style.Animation_Dialog;
            dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
            dialog.setCancelable(true);
            dialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
                    public void onDismiss(DialogInterface dialog) {
                        try {
                            JSONObject obj = new JSONObject();
                            obj.put("type", CLOSE_EVENT);

                            sendUpdate(obj, false);
                        } catch (JSONException e) {
                            Log.d(LOG_TAG, "Should never happen");
                        }
                    }
            });

            // Main container layout
            LinearLayout main = new LinearLayout(ctx.getContext());
            main.setOrientation(LinearLayout.VERTICAL);

            // Toolbar layout
            RelativeLayout toolbar = new RelativeLayout(ctx.getContext());
            toolbar.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, this.dpToPixels(44)));
            toolbar.setPadding(this.dpToPixels(2), this.dpToPixels(2), this.dpToPixels(2), this.dpToPixels(2));
            toolbar.setHorizontalGravity(Gravity.LEFT);
            toolbar.setVerticalGravity(Gravity.TOP);

            // Action Button Container layout
            RelativeLayout actionButtonContainer = new RelativeLayout(ctx.getContext());
            actionButtonContainer.setLayoutParams(new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
            actionButtonContainer.setHorizontalGravity(Gravity.LEFT);
            actionButtonContainer.setVerticalGravity(Gravity.CENTER_VERTICAL);
            actionButtonContainer.setId(1);

            // Back button
            ImageButton back = new ImageButton(ctx.getContext());
            RelativeLayout.LayoutParams backLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT);
            backLayoutParams.addRule(RelativeLayout.ALIGN_LEFT);
            back.setLayoutParams(backLayoutParams);
            back.setContentDescription("Back Button");
            back.setId(2);
            try {
                back.setImageBitmap(loadDrawable("www/childbrowser/icon_arrow_left.png"));
            } catch (IOException e) {
                Log.e(LOG_TAG, e.getMessage(), e);
            }
            back.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                    goBack();
                }
            });

            // Forward button
            ImageButton forward = new ImageButton(ctx.getContext());
            RelativeLayout.LayoutParams forwardLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT);
            forwardLayoutParams.addRule(RelativeLayout.RIGHT_OF, 2);
            forward.setLayoutParams(forwardLayoutParams);
            forward.setContentDescription("Forward Button");
            forward.setId(3);
            try {
                forward.setImageBitmap(loadDrawable("www/childbrowser/icon_arrow_right.png"));
            } catch (IOException e) {
                Log.e(LOG_TAG, e.getMessage(), e);
            }
            forward.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                    goForward();
                }
            });

            // Edit Text Box
            edittext = new EditText(ctx.getContext());
            RelativeLayout.LayoutParams textLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT);
            textLayoutParams.addRule(RelativeLayout.RIGHT_OF, 1);
            textLayoutParams.addRule(RelativeLayout.LEFT_OF, 5);
            edittext.setLayoutParams(textLayoutParams);
            edittext.setId(4);
            edittext.setSingleLine(true);
            edittext.setText(url);
            edittext.setInputType(InputType.TYPE_TEXT_VARIATION_URI);
            edittext.setImeOptions(EditorInfo.IME_ACTION_GO);
            edittext.setInputType(InputType.TYPE_NULL); // Will not except input... Makes the text NON-EDITABLE
            edittext.setOnKeyListener(new View.OnKeyListener() {
                public boolean onKey(View v, int keyCode, KeyEvent event) {
                    // If the event is a key-down event on the "enter" button
                    if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) {
                      navigate(edittext.getText().toString());
                      return true;
                    }
                    return false;
                }
            });

            // Close button
            ImageButton close = new ImageButton(ctx.getContext());
            RelativeLayout.LayoutParams closeLayoutParams = new RelativeLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT);
            closeLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
            close.setLayoutParams(closeLayoutParams);
            forward.setContentDescription("Close Button");
            close.setId(5);
            try {
                close.setImageBitmap(loadDrawable("www/childbrowser/icon_close.png"));
            } catch (IOException e) {
                Log.e(LOG_TAG, e.getMessage(), e);
            }   
            close.setOnClickListener(new View.OnClickListener() {
                public void onClick(View v) {
                    closeDialog();
                }
            });

            // WebView
            webview = new WebView(ctx.getContext());
            webview.setLayoutParams(new LinearLayout.LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
            webview.setWebChromeClient(new WebChromeClient());
            WebViewClient client = new ChildBrowserClient(edittext);
            webview.setWebViewClient(client);
            WebSettings settings = webview.getSettings();
            settings.setJavaScriptEnabled(true);
            settings.setJavaScriptCanOpenWindowsAutomatically(true);
            settings.setBuiltInZoomControls(true);
            settings.setPluginsEnabled(true);
            settings.setDomStorageEnabled(true);
            webview.loadUrl(url);
            webview.setId(6);
            webview.getSettings().setLoadWithOverviewMode(true);
            webview.getSettings().setUseWideViewPort(true);
            webview.requestFocus();
            webview.requestFocusFromTouch();   

            // Add the back and forward buttons to our action button container layout
            actionButtonContainer.addView(back);
            actionButtonContainer.addView(forward);

            // Add the views to our toolbar
            toolbar.addView(actionButtonContainer);
            toolbar.addView(edittext);
            toolbar.addView(close);

            // Don't add the toolbar if its been disabled
            if (getShowLocationBar()) {
                // Add our toolbar to our main view/layout
                main.addView(toolbar);
            }

            // Add our webview to our main view/layout
            main.addView(webview);

            WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
            lp.copyFrom(dialog.getWindow().getAttributes());
            lp.width = WindowManager.LayoutParams.FILL_PARENT;
            lp.height = WindowManager.LayoutParams.FILL_PARENT;

            dialog.setContentView(main);
            dialog.show();
            dialog.getWindow().setAttributes(lp);
        }

      private Bitmap loadDrawable(String filename) throws java.io.IOException {
          InputStream input = ctx.getAssets().open(filename);    
          return BitmapFactory.decodeStream(input);
      }
    };
    this.ctx.runOnUiThread(runnable);
    return "";
}

/**
 * Create a new plugin result and send it back to JavaScript
 * 
 * @param obj a JSONObject contain event payload information
 */
private void sendUpdate(JSONObject obj, boolean keepCallback) {
    if (this.browserCallbackId != null) {
        PluginResult result = new PluginResult(PluginResult.Status.OK, obj);
        result.setKeepCallback(keepCallback);
        this.success(result, this.browserCallbackId);
    }
}

/**
 * The webview client receives notifications about appView
 */
public class ChildBrowserClient extends WebViewClient {
    EditText edittext;

    /**
     * Constructor.
     * 
     * @param mContext
     * @param edittext 
     */
    public ChildBrowserClient(EditText mEditText) {
        this.edittext = mEditText;
    }       

    /**
     * Notify the host application that a page has started loading.
     * 
     * @param view          The webview initiating the callback.
     * @param url           The url of the page.
     */
    @Override
    public void onPageStarted(WebView view, String url,  Bitmap favicon) {
        super.onPageStarted(view, url, favicon);            
        String newloc;
        if (url.startsWith("http:") || url.startsWith("https:") || url.startsWith("file:")) {
            newloc = url;
        } else {
            newloc = "http://" + url;
        }

        if (!newloc.equals(edittext.getText().toString())) {           
            edittext.setText(newloc);
        }

        try {
            JSONObject obj = new JSONObject();
            obj.put("type", LOCATION_CHANGED_EVENT);
            obj.put("location", url);

            sendUpdate(obj, true);
        } catch (JSONException e) {
            Log.d("ChildBrowser", "This should never happen");
        }
    }
}

}

4

0 回答 0