0

我在 childbrowser.java 中收到错误“ctx 无法解析”。我按照视频链接http://www.youtube.com/watch?v=84jmuXS8GJI的说明使用 Phonegap 在我的 Android 应用程序中获取子浏览器,但仍然出现此错误。任何人请解决这个问题。


/*This is my childBrowser.java code*/

package com.phonegap.plugins.childBrowser;

import java.io.IOException;

public class ChildBrowser extends Plugin`  
    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");
            }
        }
    }
}

这些是我在 ChildBrowser.java 页面中遇到的错误:

Description Resource    Path    Location    Type
ctx cannot be resolved  ChildBrowser.java   /childBrowser/src/com/phonegap/plugins/childBrowser line 228    Java Problem
ctx cannot be resolved  ChildBrowser.java   /childBrowser/src/com/phonegap/plugins/childBrowser line 236    Java Problem
ctx cannot be resolved  ChildBrowser.java   /childBrowser/src/com/phonegap/plugins/childBrowser line 254    Java Problem
...
4

1 回答 1

2

你看错地方了......要获取 childbrowser 的更新和工作副本,请在此处查看https://github.com/phonegap/phonegap-plugins/tree/65be38cf02466748a3b3e93c2d18cb2c198feb28/Android/ChildBrowser

更新:-

请参阅此http://simonmacdonald.blogspot.fi/2012/07/phonegap-android-plugins-sometimes-we.html

你需要修改一些这样的东西

  1. ctx.getContext() 替换为 cordova.getContext()

  2. ctx.startActivity() 替换为 cordova.getActivity().startActivity()

  3. ctx.getSystemService() 替换为 cordova.getActivity().getSystemService()

  4. ctx.getAssets() 替换为 cordova.getActivity().getAssets()

  5. ctx.runOnUiThread() 替换为 cordova.getActivity().runOnUiThread()

  6. ctx.getApplicationContext() 替换为 cordova.getActivity().getApplicationContext()

  7. ctx.getPackageManager() 替换为 cordova.getActivity().getPackageManager()

  8. ctx.getSharedPreferences() 替换为 cordova.getActivity().getSharedPreferences()

  9. ctx.unregisterActivity() 替换为 cordova.getActivity().unregisterActivity()

  10. ctx.getResources() 替换为 cordova.getActivity().getResources()

  11. import com.phonegap.api.* 替换为 import org.apache.cordova.api.*

于 2012-07-27T05:52:47.293 回答