안녕하세요 꾸준한 노력만이 입니다...
지금 개발중인 어플이 Vimeo의 동영상 embed code를 사용해서 웹뷰를 통해 보여주려고 합니다.
소스코드에 앞서 문제점을 먼저 말씀 드리자면
1> Layout이 titlebar - ScrollView(WebView가 child로 있음) 이런 구조인데
앱 실행시 WebView의 위에 surfaceview로 flashplayer가 실행되는 것 같습니다.
그래서 화면을 스크롤 하게되면 WebView가 ScrollView안에 있음에도 titlebar를 가리는 현상이 생깁니다.
(flashplayer를 스크롤뷰안에서 나오도록 하고 싶습니다.)
2> 두번째는 동영상이 재생된후 back버튼을 누르면 종료되지 않고 전체화면에서 원래상태로 돌아오지만
동영상은 계속 재생되고 있습니다
( back버튼을 누르면 일시정지나 정지가 되면서 원래상태로 돌아왔으면 합니다)
사진으로 보시면
<1> <2> <3> <4>
<1>이 어플을 실행했을때입니다. 초록색이 titlebar부분이고 나머지가 ScrollView로 감싸져있습니다. 사진부분이 WebView입니다.
<2>에서 처럼 스크롤시 titlebar를 가립니다.
<3>은 실행시 보여지는 화면입니다.
<4>은 back버튼을 누른후 원래 상태로 돌아왔지만 동영상은 계속 재생중입니다.
mian Activity입니다.
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method;
import android.app.Activity; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.os.Bundle; import android.view.View; import android.webkit.WebChromeClient; import android.webkit.WebSettings; import android.webkit.WebView; import android.widget.FrameLayout; import android.widget.RelativeLayout;
public class WebViewInFlash extends Activity {
private RelativeLayout header; private RelativeLayout titlebar;
private MyWebVIew mWeb; private View mCustomView; private FrameLayout mCustomViewContainer; private WebChromeClient.CustomViewCallback mCustomViewCallback; private MyWebChromeClient mWebChromeClient;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.freeboard_description);
init();
// video view remove if (inCustomView()) hideCustomView(); loadData(); mWeb.setVisibility(View.VISIBLE);
}
private void init() {
mCustomViewContainer = (FrameLayout) findViewById(R.id.fullscreen_custom_content);
mWeb = (MyWebVIew) findViewById(R.id.freeboard_desc_webview);
header = (RelativeLayout) findViewById(R.id.freeboard_desc_header);
}
private void loadData() {
mWebChromeClient = new MyWebChromeClient(); mWeb.setWebChromeClient(mWebChromeClient); mWeb.setWebViewClient(new MyWebClient()); WebSettings set = mWeb.getSettings(); set.setCacheMode(WebSettings.LOAD_NO_CACHE); set.setUserAgent(0); set.setPluginsEnabled(true);
mWeb.loadUrl("http://player.vimeo.com/video/24243147?title=0&byline=0");
}
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
callHiddenWebViewMethod("onResume");
}
@Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
callHiddenWebViewMethod("onPause");
}
@Override
public void onBackPressed() {
// TODO Auto-generated method stub
super.onBackPressed();
if (inCustomView()) {
hideCustomView();
}
finish();
}
private void callHiddenWebViewMethod(String name) {
if (mWeb != null) {
try {
Method method = WebView.class.getMethod(name);
method.invoke(mWeb);
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public boolean inCustomView() {
return (mCustomView != null);
}
public void hideCustomView() {
mWebChromeClient.onHideCustomView();
}
private class MyWebChromeClient extends WebChromeClient {
private Bitmap mDefaultVideoPoster;
private View mVideoProgressView;
@Override
public void onShowCustomView(View view, WebChromeClient.CustomViewCallback callback) {
if (mCustomView != null) {
callback.onCustomViewHidden();
return;
}
header.setVisibility(View.GONE);
titlebar.setVisibility(View.GONE);
mCustomViewContainer.addView(view); // attach mediaplayer
mCustomView = view;
mCustomViewCallback = callback;
mCustomViewContainer.setVisibility(View.VISIBLE);
}
@Override
public void onHideCustomView() {
if (mCustomView == null)
return;
mCustomView.setVisibility(View.GONE); mCustomViewContainer.removeView(mCustomView); mCustomView = null; mCustomViewContainer.setVisibility(View.GONE); mCustomViewCallback.onCustomViewHidden(); header.setVisibility(View.VISIBLE); titlebar.setVisibility(View.VISIBLE); }
public Bitmap getDefaultVideoPoster() {
if (mDefaultVideoPoster == null) {
mDefaultVideoPoster = BitmapFactory.decodeResource(getResources(), R.drawable.background);
}
return mDefaultVideoPoster;
}
@Override
public View getVideoLoadingProgressView() {
// if (mVideoProgressView == null) {
// LayoutInflater inflater =
// LayoutInflater.from(getApplicationContext());
// mVideoProgressView =
// inflater.inflate(R.layout.video_loading_progress, null);
// }
return mVideoProgressView;
}
@Override
public void onReceivedTitle(WebView view, String title) {
// ((Activity) getApplicationContext()).setTitle(title);
}
@Override
public void onProgressChanged(WebView view, int newProgress) {
// getWindow().setFeatureInt(Window.FEATURE_PROGRESS, newProgress *
// 100);
}
}
}
xml 입니다.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ffffff">
<!-- Title bar -->
<RelativeLayout
android:id="@+id/freeboard_desc_Titlebar"
android:layout_width="fill_parent"
android:layout_height="50dp"
android:layout_alignParentTop="true"
android:background="#7AAF73">
<TextView
android:id="@+id/freeboard_desc_Titlebar_text"
android:layout_centerInParent="true"
android:gravity="center"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="웹뷰 테스트"
style="@style/titlestyle" />
</RelativeLayout>
<!-- Contents Layout -->
<RelativeLayout
android:id="@+id/freeboard_desc_header"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff"
android:layout_below="@+id/freeboard_desc_Titlebar">
<ScrollView
android:id="@+id/freeboard_desc_scrollview"
android:layout_alignParentTop="true"
android:layout_above="@+id/freeboard_desc_toolbar"
android:layout_height="match_parent"
android:layout_width="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/freeboard_desc_title"
android:layout_width="fill_parent"
android:layout_marginTop="15dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="3dp"
android:gravity="left"
android:text="웹뷰 테스트입니다."
style="@style/desctitlestyle"
android:layout_height="wrap_content" />
<ImageView
android:id="@+id/freeboard_desc_dividor"
android:layout_height="1dp"
android:layout_width="fill_parent"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:background="#7AAF73"></ImageView>
<com.test.main.MyWebVIew
android:id="@+id/freeboard_desc_webview"
android:layout_height="200dp"
android:layout_width="fill_parent"
android:layout_gravity="center_horizontal"
android:layout_marginTop="10dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp" />
<TextView
android:id="@+id/freeboard_desc_description"
android:layout_marginTop="10dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_width="fill_parent"
android:text="웹뷰 테스트입니다. 웹뷰 테스트입니다. 웹뷰 테스트입니다. 웹뷰 테스트입니다. 웹뷰 테스트입니다. 웹뷰 테스트입니다. 웹뷰 테스트입니다. 웹뷰 테스트입니다. 웹뷰 테스트입니다. 웹뷰 테스트입니다. 웹뷰 테스트입니다. 웹뷰 테스트입니다."
style="@style/desctextstyle"
android:lineSpacingExtra="25dp"
android:layout_height="wrap_content" />
<ImageView
android:layout_height="1dp"
android:layout_width="fill_parent"
android:layout_marginTop="10dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:background="#7AAF73"></ImageView>
<TextView
android:id="@+id/freeboard_desc_time"
android:gravity="right"
android:layout_width="fill_parent"
android:layout_marginTop="10dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_marginBottom="20dp"
android:padding="0dp"
style="@style/desctimestyle"
android:layout_height="20dp" />
</LinearLayout>
</ScrollView>
<FrameLayout
android:id="@+id/fullscreen_custom_content"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#000000"
android:visibility="gone">
</FrameLayout>
</RelativeLayout>
</RelativeLayout>
AndroidManifest.xml입니다
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="net.tcnmedia.main"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk
android:minSdkVersion="8" />
<application
android:icon="@drawable/icon"
android:label="@string/app_name">
<activity
android:name=".WebViewInFlash"
android:label="@string/app_name"
android:theme="@android:style/Theme.NoTitleBar"
android:configChanges="orientation|keyboardHidden">
<intent-filter>
<action
android:name="android.intent.action.MAIN" />
<category
android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission
android:name="android.permission.INTERNET" />
<uses-permission
android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission
android:name="android.permission.WAKE_LOCK" />
</manifest>
살펴봐 주시고 많은 답변 부탁드려요. 읽어 주셔서 감사합니다.
댓글 달아주신 초맨님 감사합니다...
현재 아이폰과 안드로이드 두가지를 개발중인데...아이폰에서는 스크롤안에서 생성이 되더군요 ㅜㅜ
개발에 사용된 디바이스는 갤럭시S와 넥서스원 둘다 진저브레드입니다.
불가능 한것이군요...가능한한 해결할 방법을 찾고 싶어 지네요~ UI측면으로 해결할 수 있으면 좋겠지만...
스크롤을 하는것이 문제네요...
그리고 두번째 답변주신것에 대한건 제 코드에 작성이 되어 있습니다...하지만 플레이시 전체 화면으로 바뀌고 전체화면에서 일시정지를 하지 않고 back버튼을 누르면 실행된 상태로 원래 화면으로 돌아옵니다. 물론 일시정지를 하면 정지된 상태로 돌아오겠죠...
연휴동안 확인을 못하고 이제야 확인하게 됩니다...감사합니다...
1. Flash를 표시하는 surfaceView가 앱 window보다 상위에 위치하면서 발생한는 문제입니다. (Hierachyviewer 를 이용하면 보일겁니다.)
앱단에서 직접 해본것은 아니지만, webview의 child view 중 surfaceView를 찾아서 surfaceView.setZOrderOnTop(false); 를 해주시면 가능할 것으로 보입니다.
2. WebView.onPause(), WebView.onResume() 을 사용하셨다는 얘기인가요? 위의 코드에서는 안보여서요.
1. 그런 방법이 있었군요... 오늘중으로 한번 해보겠습니다...
2. callHiddenWebViewMethod("onPause"); 로 메서드를 만들어서 넣었습니다.
시작한지 얼마 안되서 이것저것 짜집기로 구현한거다 보니 코드에 대한 이해력이 부족합니다
더 공부해야겠군요 ㅜㅜ
해결되는데로 답변달겠습니다. 감사합니다~꾸벅^^
시간문제로 UI를 변경하는 방법으로 해결을 하였습니다...간단하게 WebView는 고정시키고 아래의 Text만 스크롤에 담았죠 ㅜㅜ
오늘에서야 시간이 생겨 초맨님께서 말씀하신 방법으로 해보았습니다....
mWeb.getChildAt(0)가 com.adobe.flashplayer.FlashPaintSurface@405becb0 이렇게 나오더군요...
그런데 한가지 문제는 onCreate()시에 mWeb에 url을 통해서 플레이어를 실행시키는데...로드시간차로 인해 Child가 null이 발생합니다...
그리하여 핸들러로 지연시간을 주니...Child가 잡힙니다...
SurfaceView flash = (SurfaceView) mWeb.getChildAt(0);
flash.setZOrderOnTop(false);
를 해보았지만...여전히 title위로 올라가네요 ㅜㅜ
api를 살펴보니 setZOrderOnTop(boolean)은 반드시 SurfaceView가 포함된 window가 windowManager에 붙이기 전에 실행해야된다고 되어 있네요...
좀더 살펴 봐야겠습니다...초맨님 덕분에 플레시 플레이어를 잡는데 성공하였습니다...희망이 보이네요 ㅎㅎ




1. Flash 영역이 view 상위에 위치하기 때문에 앱단에서 flash를 타 view아래에 두는 것은 불가능합니다.
(진저브래드, 허니콤 계열은 확인해보지 못했습니다.)
2. 동영상 멈춤, 재생은 WebView method 중 onPause(), onResume() 을 사용하세요.