Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iframe videos won't go fullscreen mode in Android web view

I'm currently working on an Android application based on a website. The iOS application already exists, and I have to respect some codes for uniformity.

Everything is almost done, but I just discovered an interesting issue : when using the webview (I don't have any control on the page displayed) for a page with an iframe video (Youtube, Dailymotion), it won't go full screen, even though I'm pressing the button of the player.

I already tried pretty much everything found here, but it only refers to apps where I know what pages you need to display.

Here's the code for the webActivity part of the app :

public class WebActivity extends Activity {
    String targetURL = "";
    String title = "";
    WebView wv;

    @Override
    public void onResume() { super.onResume(); CookieSyncManager.getInstance().startSync(); }
    @Override
    public void onPause() { super.onPause();  CookieSyncManager.getInstance().stopSync(); }

    /** Called when the activity is first created. */
    @SuppressLint("SetJavaScriptEnabled")
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        getWindow().requestFeature(Window.FEATURE_PROGRESS);
        //getWindow().requestFeature(Window.FEATURE_NO_TITLE);
        CookieSyncManager.createInstance(getApplicationContext());
        CookieSyncManager.getInstance().startSync();
        CookieManager.getInstance().setAcceptCookie(true);
        /**
         * TODO: WebView Cookie management.
         * Right now, a cookie is hardcoded here into the WebView instead of getting it from the API called by HttpClient when retrieving the JSON.
         * Need to make things cleaner.
         */
        CookieManager.getInstance().setCookie("http://www.blabla.fr/mobile/","gbapi=1; Domain=.www.blabla.fr"); 
        /**
         * Get parameters
         */
        Bundle b = getIntent().getExtras();
        if(b != null)
        {
            targetURL = b.getString("url");
            title = b.getString("title");
        }

        setTitle(title);
        setContentView(R.layout.activity_webview);

        wv = (WebView) findViewById(R.id.webview);

        WebSettings wvSettings = wv.getSettings();

        // WebView options
        wvSettings.setDefaultTextEncodingName("utf-8");
        wvSettings.setJavaScriptEnabled(true);
        wvSettings.setPluginState(PluginState.ON);
        wvSettings.setJavaScriptCanOpenWindowsAutomatically(true);
        wvSettings.setBuiltInZoomControls(true);
        final Activity activity = this;
        wv.setWebChromeClient(new WebChromeClient() {
            public void onProgressChanged(WebView view, int progress) {
                activity.setProgress(progress * 100);
            }
        });

        wv.setWebViewClient(new WebViewClient() {
            public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
                Toast.makeText(activity, "Oh snap! " + description, Toast.LENGTH_SHORT).show();
            }
        });

        wv.loadUrl(targetURL);
    }
}

Thanks for any help.

like image 692
user1769473 Avatar asked Oct 23 '12 20:10

user1769473


People also ask

How do I make Android videos full screen?

Tap the video you'd like to watch. At the bottom of the video player, tap full screen .

Can iframe go fullscreen?

You can add allowfullscreen attribute to the iframe so that you can click fullscreen button in the HTML5 player toolbar to go fullscreen.


1 Answers

You will need to create a custom WebChromeClient that handles both versions of onShowCustomView (a new version of this callback was introduced in API level 14) as well as onHideCustomView. Essentially what will happen is that when you attempt to play videos fullscreen, you will be given a view that is some variation of VideoView. You need to attach this to a fullscreen FrameLayout and stick it at the root of your layout hierarchy to overlay the entire screen. Once they're done you need to remove it again.

Here is a version I am using to play videos

private class DerpChromeClient extends WebChromeClient implements MediaPlayer.OnCompletionListener, MediaPlayer.OnErrorListener {
    //@Override
    public void onShowCustomView(View view, int requestedOrientation, CustomViewCallback callback) {
        log.warn("onShowCustomView");
        showCustomView(view, callback);
    }

    private View mVideoProgressView;

    @Override
    public void onHideCustomView() {
        super.onHideCustomView();

        activity.removeFullscreenView();
        webView.setVisibility(View.VISIBLE);

        try {
            mCustomViewCallback.onCustomViewHidden();
        } catch (NullPointerException npe) {
            // occasionally Android likes to freak out and throw an unhandled NPE if it can't play the video
            // therefore we are not going to do anything but eat this exception so it fails gracefully
        }

        mCustomView = null;
        mVideoView = null;
    }

    @Override
    public void onShowCustomView(View view, CustomViewCallback callback) {
        super.onShowCustomView(view, callback);
        log.warn("onShowCustomView");
        showCustomView(view, callback);
    }

    private void showCustomView(View view, CustomViewCallback callback) {
        if (mCustomView != null) {
            callback.onCustomViewHidden();
            return;
        }

        mCustomView = view;
        mCustomViewCallback = callback;
        webView.setVisibility(View.GONE);

        if (view instanceof FrameLayout) {
            if (((FrameLayout)view).getFocusedChild() instanceof VideoView) {
                mVideoView = (VideoView)((FrameLayout)view).getFocusedChild();
            }
        }

        view.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT, FrameLayout.LayoutParams.MATCH_PARENT));
        view.setBackgroundColor(Color.BLACK);
        activity.displayFullscreenView(view);
    }

    @Override
    public boolean onConsoleMessage(ConsoleMessage cm) {
        log.warn("Console Message: " + cm.message() + " on line " + cm.lineNumber() + " of " + cm.sourceId());
        return super.onConsoleMessage(cm);
    }

    @Override
    public void onProgressChanged(WebView view, int newProgress) {
        super.onProgressChanged(view, newProgress);

        if (newProgress < 100) {
            if (loadingProgress.getVisibility() == ProgressBar.GONE) {
                loadingProgress.setVisibility(ProgressBar.VISIBLE);
            }
            loadingProgress.setProgress(newProgress);
        } else if (newProgress >= 100) {
            loadingProgress.setVisibility(ProgressBar.GONE);
        }
    }

    @Override
    public View getVideoLoadingProgressView() {
        if (mVideoProgressView == null) {
            LayoutInflater inflater = LayoutInflater.from(KnowledgeBaseFragment.this.getActivity().getApplicationContext());
            mVideoProgressView = inflater.inflate(R.layout.video_loading_progress, null);
        }

        return mVideoProgressView; 
    }

    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        // TODO Auto-generated method stub
        return false;
    }

    @Override
    public void onCompletion(MediaPlayer mp) {
        this.onHideCustomView();
    }
}

Note that I am doing this within a fragment, so to make it truly fullscreen I had to tightly couple it with the activity so it could attach the FrameLayout at the root of the entire view hierarchy, not just the fragment's.

Here are those functions:

@Override
public void displayFullscreenView(View customView) {
    parentLayout.addView(customView);
    this.customView = customView;
}

@Override
public void removeFullscreenView() {
    if (customView != null) {
        customView.setVisibility(View.GONE);
        parentLayout.removeView(customView);
    }

    customView = null;
}

Here's another question like yours: WebView and HTML5 <video>

like image 144
MattC Avatar answered Oct 10 '22 18:10

MattC