MENU
コンテンツ再構築中

Android: WebView での YouTube 再生について(フルスクリーン対応)

Android の WebView は仕様をよく理解していないと、ネイティブ実装よりも大変なケースに遭遇します(しました)。

WebView から Web ページが表示されて一息ついていたら、YouTube が見れないという問題が発生しましたので、その解決方法をメモしておきます。

老婆心ながら、くれぐれもアプリのユーザーエージェントを、あまりにもユニークなものに書き換えたりしないでください。
ユーザーエージェントが大きく変わると、今回の方法でどう頑張っても YouTube は再生できません。これで人生の貴重な3日間を棒に振りました。。。

それではどうぞ。

INDEX

目次

  • AndroidManifest の設定
  • MainActivity -> WebView の設定
  • MainActivity -> WebChromeClient 拡張クラス
  • MainActivity の全コード
  • レイアウトファイル

AndroidManifest の設定

application の android:hardwareAccelerated を true にします。

AndroidManifest.xml

[code]

[/code]

MainActivity -> WebView の設定

WebView の設定を以下のようにし、WebChromeClient の拡張クラス(後述)をセットします。

MainActivity.java -> protected void onCreate

[code]
myWebView = (WebView) findViewById(R.id.webView);

WebSettings settings = myWebView.getSettings();
settings.setJavaScriptEnabled(true);
settings.setAppCacheEnabled(true);

myWebView.setWebChromeClient(new CustomWebChromeClient());
[/code]

MainActivity -> WebChromeClient 拡張クラス

WebChromeClient の拡張クラスが必要な理由は YouTube のフルスクリーン表示に対応するためです。

フルスクリーン表示になったとき、 WebVeiw を非表示にしカスタムビューと背景(黒)を表示、フルスクリーンが解除された時に WebVeiw を表示し、カスタムビューと背景(黒)を非表示にする、といった処理を書く必要があります。

WebChromeClient の拡張クラスでオーバーライドするメソッドは次の2つです。

  • public void onShowCustomView
  • public void onHideCustomView

WebChromeClient の拡張クラス CustomWebChromeClient は以下のようになります。

MainActivity.java

[code]
class CustomWebChromeClient extends WebChromeClient {

@Override
public void onShowCustomView(View view, CustomViewCallback callback) {

if (videoCustomView != null) {
callback.onCustomViewHidden();
return;
}

final FrameLayout frame = ((FrameLayout) view);

final View v1 = frame.getChildAt(0);
view.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT, Gravity.CENTER));
v1.setOnKeyListener(new View.OnKeyListener() {

@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
onHideCustomView();
return true;
}
return false;
}
});

videoCustomView = view;
customViewContainer.setVisibility(View.VISIBLE);
customViewContainer.setBackgroundColor(Color.BLACK);
customViewContainer.bringToFront();
myWebView.setVisibility(View.GONE);

customViewContainer.addView(videoCustomView);
}

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

customViewContainer.removeView(videoCustomView);
videoCustomView = null;
customViewContainer.setVisibility(View.INVISIBLE);
myWebView.setVisibility(View.VISIBLE);

}
}
[/code]

MainActivity の全コード

完成した MainActivity は以下となります。

MainActivity.java

[code]
public class MainActivity extends Activity {

private WebView myWebView;
private View containerView;
private FrameLayout customViewContainer;
private View videoCustomView;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);
myWebView = (WebView)findViewById(R.id.myWebView);
customViewContainer = (FrameLayout) findViewById(R.id.customView_frame);

WebSettings settings = myWebView.getSettings();
settings.setJavaScriptEnabled(true);
settings.setAppCacheEnabled(true);

myWebView.setWebChromeClient(new CustomWebChromeClient());

myWebView.loadUrl(“”);
}

class CustomWebChromeClient extends WebChromeClient {

@Override
public void onShowCustomView(View view, CustomViewCallback callback) {

if (videoCustomView != null) {
callback.onCustomViewHidden();
return;
}

final FrameLayout frame = ((FrameLayout) view);

final View v1 = frame.getChildAt(0);
view.setLayoutParams(new FrameLayout.LayoutParams(FrameLayout.LayoutParams.MATCH_PARENT,
FrameLayout.LayoutParams.MATCH_PARENT, Gravity.CENTER));
v1.setOnKeyListener(new View.OnKeyListener() {

@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK && event.getAction() == KeyEvent.ACTION_DOWN) {
onHideCustomView();
return true;
}
return false;
}
});

videoCustomView = view;
customViewContainer.setVisibility(View.VISIBLE);
customViewContainer.setBackgroundColor(Color.BLACK);
customViewContainer.bringToFront();
myWebView.setVisibility(View.GONE);

customViewContainer.addView(videoCustomView);
}

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

customViewContainer.removeView(videoCustomView);
videoCustomView = null;
customViewContainer.setVisibility(View.INVISIBLE);
myWebView.setVisibility(View.VISIBLE);

}
}
}
[/code]

レイアウトファイル

おまけに layout ファイルも載せておきます。

activity_main.xml

[code]


[/code]

まとめ

Android も YouTube も同じ Google なのに、なぜここまでやらなければ WebView から YouTube が再生できないんでしょうか。

今回のソースコードは Android 4.0 以降をターゲットに YouTube の再生に特化したソースコードですが、ここに WebViewClient、ジェスチャー、Android OS の後方互換を考慮した場合、相当カオスなソースコードになります。

Android の WebView の取り扱いにはくれぐれもご注意を。

この記事がみなさんのお役に立ちましたら、下記「Share it」よりブックマークやSNSで共有していただければ幸いです。

Please share it!
  • URLをコピーしました!
  • URLをコピーしました!
INDEX