0

My application uses a WebView to display flash video contents.
Everything seems to go smoothly until you try to play full screen on Android ICS devices.
It works fine on devices with lower version.
On ICS devices it throws a NullPointerException. Here is my code:

    webView.getSettings().setJavaScriptEnabled(true);
            webView.getSettings().setPluginsEnabled(true);
            webView.getSettings().setLoadWithOverviewMode(true);
            webView.getSettings().setUseWideViewPort(true);
            webView.setVerticalScrollbarOverlay(true);
            webView.setWebViewClient(new WebViewClient() {
                private ProgressDialog pd;

                @Override
                public void onPageStarted(WebView view, String url,
                        Bitmap favicon) {
                    pd = new ProgressDialog(TrainingDetailActivity.this);
                    pd.setProgressStyle(ProgressDialog.STYLE_SPINNER);
                    pd.setMessage("Loading");
                    pd.show();
                    super.onPageStarted(view, url, favicon);
                }

                @Override
                public void onPageFinished(WebView view, String url) {
                    this.dismissDialog();
                    super.onPageFinished(view, url);
                }

                @Override
                public boolean shouldOverrideUrlLoading(WebView view,
                        String url) {
                    return false;
                }

                private void dismissDialog() {
                    if (pd != null) {
                        pd.dismiss();
                        pd = null;
                    }
                }
            });
            webView.loadDataWithBaseURL(baseUrl, htmlstr, "text/html", "utf-8", null);

After some digging, I found out that in ICS the android.webkit.PluginFullScreenHolder show() method gets called and throws an NullExceptionPointer. The problem lays there, not on my code. I tried some work around but none of them works.
- Work around : I added this line:

webView.setWebChromeClient(new WebChromeClient() );

With this work around the NullPointerException does not occur, but the video plays with no sound, and won't switch to Full screen mode.
I looked around stackoverflow for solutions, the closest which seems to solve my problem is this answer:
https://stackoverflow.com/a/9921073/1503155
But unfortunately the answerer didn't explain what is the variable base in his code snippet and I am still stuck.
My question is, is there a way to work around this bug. Is yes, How?
Thanks in advance. Here is the stacktrace here

Community
  • 1
  • 1
Lazy Ninja
  • 22,342
  • 9
  • 83
  • 103

2 Answers2

4

My boss gave me permission to share this with you.

I had the same issue for a long time before cobbling this together.

Create this as a class, and set the chrome client of your WebView:

WebView.setWebChromeClient(...);

To this:

public class FullscreenableChromeClient extends WebChromeClient {
    protected Activity mActivity = null;

    private View mCustomView;
    private WebChromeClient.CustomViewCallback mCustomViewCallback;
    private int mOriginalOrientation;

    private FrameLayout mContentView;
    private FrameLayout mFullscreenContainer;

    private static final FrameLayout.LayoutParams COVER_SCREEN_PARAMS = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);

    public FullscreenableChromeClient(Activity activity) {
        this.mActivity = activity;
    }

    @Override
    public void onShowCustomView(View view, int requestedOrientation, WebChromeClient.CustomViewCallback callback) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
            if (mCustomView != null) {
                callback.onCustomViewHidden();
                return;
            }

            mOriginalOrientation = mActivity.getRequestedOrientation();
            FrameLayout decor = (FrameLayout) mActivity.getWindow().getDecorView();
            mFullscreenContainer = new FullscreenHolder(mActivity);
            mFullscreenContainer.addView(view, COVER_SCREEN_PARAMS);
            decor.addView(mFullscreenContainer, COVER_SCREEN_PARAMS);
            mCustomView = view;
            setFullscreen(true);
            mCustomViewCallback = callback;
            mActivity.setRequestedOrientation(requestedOrientation);
        }

        super.onShowCustomView(view, requestedOrientation, callback);
    }

    @Override
    public void onHideCustomView() {
        if (mCustomView == null) {
            return;
        }

        setFullscreen(false);
        FrameLayout decor = (FrameLayout) mActivity.getWindow().getDecorView();
        decor.removeView(mFullscreenContainer);
        mFullscreenContainer = null;
        mCustomView = null;
        mCustomViewCallback.onCustomViewHidden();
        mActivity.setRequestedOrientation(mOriginalOrientation);
    }

    private void setFullscreen(boolean enabled) {
        Window win = mActivity.getWindow();
        WindowManager.LayoutParams winParams = win.getAttributes();
        final int bits = WindowManager.LayoutParams.FLAG_FULLSCREEN;
        if (enabled) {
            winParams.flags |= bits;
        } else {
            winParams.flags &= ~bits;
            if (mCustomView != null) {
                mCustomView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
            } else {
                mContentView.setSystemUiVisibility(View.SYSTEM_UI_FLAG_VISIBLE);
            }
        }
        win.setAttributes(winParams);
    }

    private static class FullscreenHolder extends FrameLayout {
        public FullscreenHolder(Context ctx) {
            super(ctx);
            setBackgroundColor(ctx.getResources().getColor(android.R.color.black));
        }

        @Override
        public boolean onTouchEvent(MotionEvent evt) {
            return true;
        }
    }
}
Knossos
  • 15,802
  • 10
  • 54
  • 91
  • +1 for asking your boss permission and trying to help. Unfortunately I still get the same null exception. Maybe I am doing something wrong. I set my webview like this: WebView.setWebChromeClient( new FullscreenableChromeClient(this)); Is it the correct way to use the class? Anyway I will try on my side to see what I am doing wrong. Really appreciate your help, because as I you can see I am still unable to fix it. – Lazy Ninja Sep 28 '12 at 01:27
  • Yeah, that is how you use the class. What is the stacktrace for the errors you are getting? – Knossos Sep 28 '12 at 07:11
  • I have added the stacktrace image on the original post. – Lazy Ninja Sep 28 '12 at 07:28
  • thanks for your code! but i have a doubt.. what happens when you change orientation? my webview quits. – José Silva Jun 03 '14 at 12:18
1

Thanks for upstairs' code

Host's problem I was encountered。

In Activity I resoled like that。

@Override
public void onBackPressed() {
    Log.e(TAG, "onBackPressed");

    if(mCustomView!=null){
        mFull.onHideCustomView();
    }else{
        super.onBackPressed();
    }
}
KoKo
  • 11
  • 2