본문 바로가기

Android

Android : webview에서 HTML video 전체화면 재생

Android : webview에서 HTML video 전체화면 재생 

안드로이드에서 webview로 해당 url에 접속할 때 기본적으로 setWebChromeClient()setWebViewClient()를 설정해주는데,

보통과 같이 진행하면 HTML video 태그 혹은 유튜브 비디오에 전체화면 버튼 자체가 보이질 않는다. 


전체화면 버튼을 컨트롤바에 보이게 하려면 webChromeClient 클래스의 onShowCustomView() 메소드와 onHideCustomeView()를 오버라이드 해줘야 하는데, 오버라이드만 해도 전체화면 버튼이 생긴다. 

그러나 오버라이드하고 별다른 코드를 추가하지 않으면 전체화면시 흰 화면만 나오거나 오디오만 나오는 문제가 발생한다. 

구현

다음과 같이 webChromeClient 클래스를 상속받는 FullscreenableChromeClient 클래스를 생성한다.


FullscreenableChromeClient.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
import android.app.Activity;
import android.content.Context;
import android.os.Build;
import android.support.v4.content.ContextCompat;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.view.WindowManager;
import android.webkit.WebChromeClient;
import android.widget.FrameLayout;
 
public class FullscreenableChromeClient extends WebChromeClient {
    private Activity mActivity = null;
 
    private View mCustomView;
    private WebChromeClient.CustomViewCallback mCustomViewCallback;
    private int mOriginalOrientation;
    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, 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, callback);
    }
 
    @SuppressWarnings("deprecation")
    @Override
    public void onShowCustomView(View view, int requestedOrientation, WebChromeClient.CustomViewCallback callback) {
        this.onShowCustomView(view, 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);
            }
        }
        win.setAttributes(winParams);
    }
 
    private static class FullscreenHolder extends FrameLayout {
        public FullscreenHolder(Context ctx) {
            super(ctx);
            setBackgroundColor(ContextCompat.getColor(ctx, android.R.color.black));
        }
        @Override
        public boolean onTouchEvent(MotionEvent evt) {
            return true;
        }
    }
}
cs


webView를 사용하는 곳에서, setWebChromeClient() 의 파라미터로 new webChromeClient() 대신 

방금 만들어놓은 클래스를 활용한다.

1
webView.setWebChromeClient(new FullscreenableChromeClient(MainActivity.this));
cs


이렇게 설정하면 풀스크린 버튼이 생기고, 실제로 작동하지만 세로모드에서 전체화면을 실행한 뒤 가로모드로 회전시키면 동영상이 종료되어 버리고 액티비티가 새로고침된다.

가로모드 풀스크린으로 동영상을 보고 싶다면 가로모드로 동영상을 재생한 뒤 전체화면을 실행시켜야 하는 불편함이 발생한다.

마찬가지로 가로모드에서 세로모드로 회전해도 액티비티가 새로고침되는 현상이 발생한다.


그 이유는 안드로이드에서 rotate 가 발생하면 onPause() -> onSave...() -> onStop() -> onCreate() -> ... 순으로 액티비티 생명주기가 발생되어버리기 때문이다. 


이 현상을 막기 위해 AndroidManifest.xml 로 이동해 해당 액티비티 name 밑에 다음과 같이 추가해준다.

1
android:configChanges="keyboardHidden|orientation|screenSize"
cs


동영상 재생도 잘 되고, 가로모드<->세로모드 모두 전체화면이 잘 작동하며

일반적인 세로모드에서 동영상을 회전시키면 자동으로 풀스크린 모드로 진입하며 동영상이 끊김없이 이어진다.