안드로이드 웹뷰에서 동영상 전체화면 및 가로모드
현재 일하는 회사는 에이전시 회사인데 네이티브는 서브고 웹개발이 메인이다.
그래서 업무의 7할이 웹패키징 업무이다.
이번에 진행하던 프로젝트에서 웹뷰에서 영상을 보여주는 앱이 있었다.
영상은 <video>태그로 되어있었다.
안드로이드 웹뷰에서는 기본값으로 웹뷰에서의 영상은 전체화면이 비활성화가 되어있다.
처리과정을 적어본다.
class BaseWebChromeClient( //0
private val context: Context,
val activity: Activity? = null
) : WebChromeClient() {
private val TAG = this::class.java.simpleName
private var uploadMessageArray: ValueCallback<Array<Uri>>? = null
private var captureResultArray: Array<Uri>? = null
private lateinit var mCustomView: View
private lateinit var mCustomViewCallback: WebChromeClient.CustomViewCallback
private var mOriginalOrientation = -1;
private lateinit var mFullscreenContainer: FrameLayout
companion object {
val COVER_SCREEN_PARAMS = FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT
)
}
override fun onCreateWindow(
view: WebView?,
isDialog: Boolean,
isUserGesture: Boolean,
resultMsg: Message?
): Boolean {
Log.d(TAG, "onCreateWindow")
super.onCreateWindow(view, isDialog, isUserGesture, resultMsg)
}
//1
override fun onShowCustomView(view: View?, callback: CustomViewCallback?) {
Log.d(TAG, "onShowCustomView")
activity?.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR //2
mOriginalOrientation = activity?.requestedOrientation!! //3
Log.d(TAG, "mOriginalOrientation: $mOriginalOrientation")
val decor = activity.window.decorView as FrameLayout //4
mFullscreenContainer = FullscreenHolder(activity) //5
mFullscreenContainer.addView(view, COVER_SCREEN_PARAMS)
decor.addView(mFullscreenContainer, COVER_SCREEN_PARAMS) //6
if (view != null) {
mCustomView = view //7
}
setFullscreen(true) //8
if (callback != null) {
mCustomViewCallback = callback //9
}
super.onShowCustomView(view, callback)
}
//deprecated
override fun onShowCustomView(
view: View?,
requestedOrientation: Int,
callback: CustomViewCallback?
) {
super.onShowCustomView(view, requestedOrientation, callback)
}
override fun onHideCustomView() { //10
super.onHideCustomView()
Log.d(TAG, "onHideCustomView")
setFullscreen(false) //11
val decor = activity?.window?.decorView as FrameLayout
decor.removeView(mFullscreenContainer) //12
mCustomViewCallback.onCustomViewHidden() //13
activity.requestedOrientation = SCREEN_ORIENTATION_PORTRAIT //14
}
private fun setFullscreen(enabled: Boolean) {
val win = activity?.window
val winParams = win?.attributes
val bits = WindowManager.LayoutParams.FLAG_FULLSCREEN
if (enabled) { //8
winParams?.flags = winParams?.flags?.or(bits)
} else { //11
winParams?.flags = winParams?.flags?.and(bits.inv())
mCustomView.systemUiVisibility = View.SYSTEM_UI_FLAG_VISIBLE
}
win?.attributes = winParams
}
inner class FullscreenHolder(context: Context) : FrameLayout(context) { //5
init {
setBackgroundColor(ContextCompat.getColor(context, android.R.color.black))
}
override fun onTouchEvent(event: MotionEvent?): Boolean {
return true
}
}
}
0 => WebChromeClient를 상속하는 BaseWebChromeClient 클래스를 만든다.
생성자에 매개변수로 Context와 Activity를 넘겨준다.
1 => onShowCustomView를 override 해준다.
전체화면 버튼을 클릭하면 이 함수가 호출된다.
onShowCustomView가 호출되면 비디오 동영상 컨텐츠는 더이상 웹뷰에서 재생되지 않는다.
이때, WindowManager.LayoutParams.FLAG_FULLSCREEN으로 구성된 Window를 만들어서 비디오 동영상을 렌더링해줄거다.
2 => 전체화면시 가로, 세로 전환 자유롭게 가능하도록
3 => 현재 화면의 방향을 출력(그냥)
4 => 현재 액티비티의 Window창을 가져와서 FrameLayout으로 변환한다.
5 => FrameLayout을 상속하는 FullscreenHolder이다.
배경색은 까맣게 해준다.
6 => Window창에 FullscreenHolder를 addView 해준다.
7 => 여기서 view는 비디오 동영상 컨텐츠를 말한다.
전역변수로 저장해둔다.
8 => activity의 Window를 전체화면으로 만든다.
9 => 여기서 callback은 전체화면을 취소하는 함수를 말한다.
전역변수로 저장해둔다.
10 => 전체화면을 빠져나오면 onHideCustomView가 호출된다.
여기서 동영상 전체화면시 만들어준 Window를 제거하고 기존 영상을 웹뷰에서 보여주게 하면된다.
11 => 비디오 영상 전체화면을 빠져나오고 기존 영상을 웹뷰에서 나오게 한다.
12 => 전체화면을 위해 만들었던 Window를 제거한다.
13 => onShowCustomView에서 저장한 전체화면을 빠져나오는 callback을 호출한다.
14 => 동영상 전체화면을 끝냈으니 기존 앱은 세로모드 고정시킨다,
✋ 한 가지 더!
웹뷰에서는 가로모드 <-> 세로모드 전환 시 액티비티가 새로고침 된다.
이를 막기위해서 manifest.xml에서 아래 속성을 <activity>태그안에 추가해준다.
android:configChanges="keyboardHidden|orientation|screenSize"
이제 이 BaseWebChromeClient를 내가 사용하는 웹뷰에 추가해주면 된다.
currentWebView?.webChromeClient = BaseWebChromeClient(context, activity = mActivity)
끝!!~
댓글 없음:
댓글 쓰기