WebViewおよびHTML5 <video>


122

私はとりわけ、いくつかのWebサイトを「フレーム化」する安価なアプリをつなぎ合わせていWebViewClientます。ビデオをヒットするまで。

ビデオはHTML5 要素として実行され、これらはChrome、iPhoneで問題なく機能Androidし、ネイティブブラウザでうまく機能するエンコードの問題を修正しました。

今、摩擦:WebViewそれは好きではありません。全然。ポスター画像をクリックしても何も起こりません。

グーグル、私はこれが近いことを発見しましたが、ビデオ要素の代わりに(href ...のような)「リンク」に基づいているようです。(onDownloadListenerはビデオ要素で呼び出されたようには見えません...)

onShowCustomViewのオーバーライドへの参照も見ますが、それはビデオ要素で呼び出されないようです... shouldOverrideUrlLoading ..も呼び出されません。

「サーバーからxmlをプルし、アプリで再フォーマットする」ことは避けたいです。サーバー上でストーリーレイアウトを維持することで、アプリを更新し続けることを人々に強いることなく、コンテンツを少し良く制御できます。したがって、ネイティブブラウザのようなタグを処理するようにWebViewを説得できれば、それが最善です。

明らかなものは明らかに見当たりませんが、何の手掛かりもありません。


参照してください:code.google.com/p/android/issues/detail?id
BoD

これらと同じように、自分のWebサイト用のHTML5プレーヤーを探しています。何を使うべきですか?
Wolfpack'08


1
私はに見えたので、何も働いていないVideoEnabledWebViewここstackoverflow.com/questions/15768837/...
EpicPandaForce

回答:


92

誰かが読んで結果に興味がある場合に備えて、このトピックに答えます。WebView内でビデオ要素(ビデオhtml5タグ)を表示することは可能ですが、数日間処理する必要があったと言わざるを得ません。これらは私がこれまでに従わなければならなかったステップです:

-適切にエンコードされたビデオを見つける

-WebViewを初期化するときに、JavaScriptを設定し、WebViewClientとWebChromeClientをプラグインします。

url = new String( "http://broken-links.com/tests/video/"); 
mWebView =(WebView)findViewById(R.id.webview);
mWebView.setWebChromeClient(chromeClient);
mWebView.setWebViewClient(wvClient);
mWebView.getSettings()。setJavaScriptEnabled(true);
mWebView.getSettings()。setPluginState(PluginState.ON);
mWebView.loadUrl(url);

-WebChromeClientオブジェクトのonShowCustomViewを処理します。

@Override
public void onShowCustomView(View view, CustomViewCallback callback) {
    super.onShowCustomView(view, callback);
    if (view instanceof FrameLayout){
        FrameLayout frame = (FrameLayout) view;
        if (frame.getFocusedChild() instanceof VideoView){
            VideoView video = (VideoView) frame.getFocusedChild();
            frame.removeView(video);
            a.setContentView(video);
            video.setOnCompletionListener(this);
            video.setOnErrorListener(this);
            video.start();
        }
    }
}

-Webビューに戻るために、ビデオのonCompletionイベントとonErrorイベントを処理します。

public void onCompletion(MediaPlayer mp) {
    Log.d(TAG, "Video completo");
    a.setContentView(R.layout.main);
    WebView wb = (WebView) a.findViewById(R.id.webview);
    a.initWebView();
}

しかし今、私はまだ重要な問題があると言う必要があります。一度しかプレイできません。2回目にビデオディスパッチャー(ポスターまたは再生ボタン)をクリックしても、何も起こりません。

Media Playerウィンドウを開くのではなく、WebViewフレーム内でビデオを再生したいのですが、これは私にとって2番目の問題です。

それが誰かのお役に立てば幸いです。また、コメントや提案にも感謝します。

Saludos、terricolas。


結果を実行しません。画面が真っ黒です。これが必要かどうか知りたい。私のコードは長すぎてここではうまくいきません。連絡方法を教えてもらえますか、または別のトピックを開いてください。
ペングァン

エンコーディングの問題ではないことを完全に確信していますか?投稿したURLでお試しください。明らかにそれはネイティブブラウザで動作する必要があります
mdelolmo

46
「a」とは何ですか?そのような活動はそうでしょうか?
コリン価格

1
@Collin Price aは、webviewをホストするアクティビティのインスタンスです。@desgraci、私はそれを提供できますが、それ以外はあまりありません。クラスを拡張WebChromeClientして、対応する必要なメソッドをオーバーライドします。もしあなたが主張すれば、後で家に帰ったときにクラスの残りをアップロードすることができます。
mdelolmo

6
getFocusedChild()はVideoViewではなく、HTML5VFullScreen $ SurfaceVideoViewであるため、ICSでは機能しません。ICSで実行する方法に関するアイデアはありますか?(stackoverflow.com/questions/13540654/…を
Pascal、

61

長い研究の後、私はこのことを機能させました。次のコードを参照してください。

Test.java

import android.app.Activity;
import android.os.Bundle;
import android.view.KeyEvent;

public class Test extends Activity {

    HTML5WebView mWebView;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        mWebView = new HTML5WebView(this);

        if (savedInstanceState != null) {
            mWebView.restoreState(savedInstanceState);
        } else {    
            mWebView.loadUrl("http://192.168.1.18/xxxxxxxxxxxxxxxx/");
        }

        setContentView(mWebView.getLayout());
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        super.onSaveInstanceState(outState);
        mWebView.saveState(outState);
    }

    @Override
    public void onStop() {
        super.onStop();
        mWebView.stopLoading();
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {

        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if (mWebView.inCustomView()) {
                mWebView.hideCustomView();
            //  mWebView.goBack();
                //mWebView.goBack();
                return true;
            }

        }
        return super.onKeyDown(keyCode, event);
    }
}

HTML%VIDEO.java

package com.ivz.idemandtest;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.AttributeSet;
import android.util.Log;
import android.view.KeyEvent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.webkit.GeolocationPermissions;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.FrameLayout;

public class HTML5WebView extends WebView {

    private Context                             mContext;
    private MyWebChromeClient                   mWebChromeClient;
    private View                                mCustomView;
    private FrameLayout                         mCustomViewContainer;
    private WebChromeClient.CustomViewCallback  mCustomViewCallback;

    private FrameLayout                         mContentView;
    private FrameLayout                         mBrowserFrameLayout;
    private FrameLayout                         mLayout;

    static final String LOGTAG = "HTML5WebView";

    private void init(Context context) {
        mContext = context;     
        Activity a = (Activity) mContext;

        mLayout = new FrameLayout(context);

        mBrowserFrameLayout = (FrameLayout) LayoutInflater.from(a).inflate(R.layout.custom_screen, null);
        mContentView = (FrameLayout) mBrowserFrameLayout.findViewById(R.id.main_content);
        mCustomViewContainer = (FrameLayout) mBrowserFrameLayout.findViewById(R.id.fullscreen_custom_content);

        mLayout.addView(mBrowserFrameLayout, COVER_SCREEN_PARAMS);

        // Configure the webview
        WebSettings s = getSettings();
        s.setBuiltInZoomControls(true);
        s.setLayoutAlgorithm(WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
        s.setUseWideViewPort(true);
        s.setLoadWithOverviewMode(true);
      //  s.setSavePassword(true);
        s.setSaveFormData(true);
        s.setJavaScriptEnabled(true);
        mWebChromeClient = new MyWebChromeClient();
        setWebChromeClient(mWebChromeClient);

        setWebViewClient(new WebViewClient());

setScrollBarStyle(View.SCROLLBARS_INSIDE_OVERLAY);

        // enable navigator.geolocation 
       // s.setGeolocationEnabled(true);
       // s.setGeolocationDatabasePath("/data/data/org.itri.html5webview/databases/");

        // enable Web Storage: localStorage, sessionStorage
        s.setDomStorageEnabled(true);

        mContentView.addView(this);
    }

    public HTML5WebView(Context context) {
        super(context);
        init(context);
    }

    public HTML5WebView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public HTML5WebView(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        init(context);
    }

    public FrameLayout getLayout() {
        return mLayout;
    }

    public boolean inCustomView() {
        return (mCustomView != null);
    }

    public void hideCustomView() {
        mWebChromeClient.onHideCustomView();
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if ((mCustomView == null) && canGoBack()){
                goBack();
                return true;
            }
        }
        return super.onKeyDown(keyCode, event);
    }

    private class MyWebChromeClient extends WebChromeClient {
        private Bitmap      mDefaultVideoPoster;
        private View        mVideoProgressView;

        @Override
        public void onShowCustomView(View view, WebChromeClient.CustomViewCallback callback)
        {
            //Log.i(LOGTAG, "here in on ShowCustomView");
            HTML5WebView.this.setVisibility(View.GONE);

            // if a view already exists then immediately terminate the new one
            if (mCustomView != null) {
                callback.onCustomViewHidden();
                return;
            }

            mCustomViewContainer.addView(view);
            mCustomView = view;
            mCustomViewCallback = callback;
            mCustomViewContainer.setVisibility(View.VISIBLE);
        }

        @Override
        public void onHideCustomView() {
            System.out.println("customview hideeeeeeeeeeeeeeeeeeeeeeeeeee");
            if (mCustomView == null)
                return;        

            // Hide the custom view.
            mCustomView.setVisibility(View.GONE);

            // Remove the custom view from its container.
            mCustomViewContainer.removeView(mCustomView);
            mCustomView = null;
            mCustomViewContainer.setVisibility(View.GONE);
            mCustomViewCallback.onCustomViewHidden();

            HTML5WebView.this.setVisibility(View.VISIBLE);
            HTML5WebView.this.goBack();
            //Log.i(LOGTAG, "set it to webVew");
        }


        @Override
        public View getVideoLoadingProgressView() {
            //Log.i(LOGTAG, "here in on getVideoLoadingPregressView");

            if (mVideoProgressView == null) {
                LayoutInflater inflater = LayoutInflater.from(mContext);
                mVideoProgressView = inflater.inflate(R.layout.video_loading_progress, null);
            }
            return mVideoProgressView; 
        }

         @Override
         public void onReceivedTitle(WebView view, String title) {
            ((Activity) mContext).setTitle(title);
         }

         @Override
         public void onProgressChanged(WebView view, int newProgress) {
             ((Activity) mContext).getWindow().setFeatureInt(Window.FEATURE_PROGRESS, newProgress*100);
         }

         @Override
         public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
             callback.invoke(origin, true, false);
         }
    }


    static final FrameLayout.LayoutParams COVER_SCREEN_PARAMS =
        new FrameLayout.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
}

custom_screen.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2009 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android">
    <FrameLayout android:id="@+id/fullscreen_custom_content"
        android:visibility="gone"
        android:background="@color/black"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
    />
    <LinearLayout android:orientation="vertical"
        android:layout_width="match_parent"
        android:layout_height="match_parent">

        <LinearLayout android:id="@+id/error_console"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
        />

        <FrameLayout android:id="@+id/main_content"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
        />
    </LinearLayout>
</FrameLayout>

video_loading_progress.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2009 The Android Open Source Project

     Licensed under the Apache License, Version 2.0 (the "License");
     you may not use this file except in compliance with the License.
     You may obtain a copy of the License at

          http://www.apache.org/licenses/LICENSE-2.0

     Unless required by applicable law or agreed to in writing, software
     distributed under the License is distributed on an "AS IS" BASIS,
     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     See the License for the specific language governing permissions and
     limitations under the License.
-->

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
         android:id="@+id/progress_indicator"
         android:orientation="vertical"
         android:layout_centerInParent="true"
         android:layout_width="wrap_content"
         android:layout_height="wrap_content">

       <ProgressBar android:id="@android:id/progress"
           style="?android:attr/progressBarStyleLarge"
           android:layout_gravity="center"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content" />

       <TextView android:paddingTop="5dip"
           android:layout_width="wrap_content"
           android:layout_height="wrap_content"
           android:layout_gravity="center"
           android:text="@string/loading_video" android:textSize="14sp"
           android:textColor="?android:attr/textColorPrimary" />
 </LinearLayout>

colors.xml

<?xml version="1.0" encoding="utf-8"?>
<!--
/* //device/apps/common/assets/res/any/http_authentication_colors.xml
**
** Copyright 2006, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License"); 
** you may not use this file except in compliance with the License. 
** You may obtain a copy of the License at 
**
**     http://www.apache.org/licenses/LICENSE-2.0 
**
** Unless required by applicable law or agreed to in writing, software 
** distributed under the License is distributed on an "AS IS" BASIS, 
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
** See the License for the specific language governing permissions and 
** limitations under the License.
*/
-->
<!-- FIXME: Change the name of this file!  It is now being used generically
    for the browser -->
<resources>
    <color name="username_text">#ffffffff</color>
    <color name="username_edit">#ff000000</color>

    <color name="password_text">#ffffffff</color>
    <color name="password_edit">#ff000000</color>

    <color name="ssl_text_label">#ffffffff</color>
    <color name="ssl_text_value">#ffffffff</color>

    <color name="white">#ffffffff</color>
    <color name="black">#ff000000</color>



    <color name="geolocation_permissions_prompt_background">#ffdddddd</color>
</resources>

Manifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.test"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-sdk android:minSdkVersion="7" />

    <application android:icon="@drawable/icon" android:label="@string/app_name">
        <activity android:name=".Test"
                  android:label="@string/app_name" android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
            android:configChanges="orientation|keyboardHidden|keyboard">
            <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>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_GPS" />
<uses-permission android:name="android.permission.ACCESS_ASSISTED_GPS" />
<uses-permission android:name="android.permission.ACCESS_LOCATION" />
</manifest>

あなたが理解できる残りのことを期待しています。


7
これは受け入れられる答えになるはずです。SurendraとMalenkiyの両方が私の正気を救った。私にとってはうまくいきました。
George Baker

私はジョージに同意します。これはまさにAndroidネイティブブラウザーがVideoViewと連携する方法です。これはここのcode.google.com/p/html5webviewと同じコードのようです。すべてのバージョンのAndroid(Android 2.2以降でテストしました)で問題なく動作します。気づいたことは1つだけですが、13を超える値でターゲットSDKを変更すると、向きを変えるとアクティビティが再作成されることに注意してください。これを回避するには、screenSizeをandroid:configChangesに追加します(ただし、この場合、最小sdk <13を使用する必要があります)または古いターゲットSDKを使用します(その後、android:configChangesを保持できます)
Yuriy Ashaev

2
これにより、Nexus 7(Android 4.1)で白い空白の画面が表示されます。これを修正する方法はありますか?
Sahil

バックボタンはビデオとオーディオがまだ聞こえるのを止めません、これを修正する方法はありますか?
CONvid19 2014

これは、ネイティブブラウザフローとまったく同じように私が探していたものです。TonSurendraとMalenkiyに感謝します。
Abhilash 2017

33

mdelolmoの回答は非常に役に立ちましたが、彼が言ったように、ビデオは1回しか再生されないため、再度開くことはできません。

私はこれを少し調べましたが、私のような疲れたWebView旅行者が将来この投稿に遭遇した場合に備えて、ここに私が見つけたものがあります。

まず、VideoViewMediaPlayerのドキュメントを見て、それらがどのように機能するかをよりよく理解しました。それらを強くお勧めします。

次に、ソースコードを見て、Androidブラウザーどのように実行するかを確認しました。ページを見つけて、彼らがどのように処理するか見てみましょうonShowCustomView()CustomViewCallbackおよびカスタムビューへの参照を保持します。

これらすべてと、mdelolmoの答えを念頭に置いて、ビデオを使い終わったら、2つのことを行うだけです。最初に、VideoView参照を保存したで、後で他の場所で使用stopPlayback()するMediaPlayerためにを解放するを呼び出します。VideoViewソースコードで確認できます。次に、でCustomViewCallbackcallへの参照を保存しましたCustomViewCallback.onCustomViewHidden()

これら2つのことを行った後、同じ動画または他の動画をクリックすると、以前と同じように開きます。WebView全体を再起動する必要はありません。

お役に立てば幸いです。


実際、私も少し解決しました。解決策を投稿することを覚えていませんでした(恥ずべき)。あなたと同じように、Androidブラウザーのコードを確認する必要がありましたが、追加する部分はそれほど多くありませんでした。代わりにonCompletionリスナーを使用してプレーヤーを停止し、可視性を数回設定する必要がありましたが、ソリューションを購入しました。よろしく!
mdelolmo、2011年

1
:Googleソースコード検索はここで説明し、私は(フローズンヨーグルト)からBrowserActivity.javaのこのバージョンは、およそ1に対応して考えて、廃止されましたgithub.com/android/platform_packages_apps_browser/blob/...
michiakig

@spacemankiのリンクされたコードには、リポジトリ全体でのVideoViewに関する記述は含まれていません。BrowserActivityは今では別の方法で行うと思います。私はエクレアのリリースに戻りました。使用法が見つかりません。
mxcl 2012年

これらすべての問題は、frame.getFocusedChild();から返されるものです。ViewViewではなくHTml5VideoViewであるため、これは私には機能せず、フルスクリーンに切り替えることができません:(私はAndroid 4.1.2を使用しています
Gonan

1
最後に私のためにそれをしたのは追加することでした:@Override public void onStop(){super.onStop(); mWebView.destroy(); }アクティビティに... webview.destroy()は非常に重要でした
MacD 2013

8

実際には、在庫のWebChromeClientをクライアントビューに接続するだけで十分です。

mWebView.setWebChromeClient(new WebChromeClient());

ハードウェアアクセラレーションをオンにする必要があります。

少なくとも、フルスクリーンビデオを再生する必要がない場合は、VideoViewをWebViewから引き出してアクティビティのビューにプッシュする必要はありません。ビデオ要素の割り当てられた四角形で再生されます。

エキスパンドビデオボタンをインターセプトする方法はありますか?


WebChromeClientを使用してそれをインターセプトし、onShowCustomViewをオーバーライドできます
Frank

Androidのバージョンを指定してください。これは、バージョンによって動作が異なります。
Ethan_AI 2014年

7

私はこのスレッドが数か月前のものであることを知っていますが、フルスクリーンで実行することなくWebView内でビデオを再生するための解決策を見つけました(まだメディアプレーヤーで...)。これまでのところ、インターネットでこれに関するヒントを見つけられなかったので、これは他の人にとっても興味深いかもしれません。私はまだいくつかの問題で苦労しています(つまり、メディアプレーヤーを画面の右側のセクションに配置します。なぜそれが間違っているのかわかりませんが、比較的小さな問題だと思います...)。

カスタムChromeClientでLayoutParamsを指定します。

// 768x512 is the size of my video
FrameLayout.LayoutParams LayoutParameters = 
                                     new FrameLayout.LayoutParams (768, 512); 

私のonShowCustomViewメソッドは次のようになります。

public void onShowCustomView(final View view, final CustomViewCallback callback) {
     // super.onShowCustomView(view, callback);
     if (view instanceof FrameLayout) {
         this.mCustomViewContainer = (FrameLayout) view;
         this.mCustomViewCallback = callback;
         this.mContentView = (WebView) this.kameha.findViewById(R.id.webview);
         if (this.mCustomViewContainer.getFocusedChild() instanceof VideoView) {
             this.mCustomVideoView = (VideoView) 
                                     this.mCustomViewContainer.getFocusedChild();
             this.mCustomViewContainer.setVisibility(View.VISIBLE);
             final int viewWidth = this.mContentView.getWidth();
             final int viewLeft = (viewWidth - 1024) / 2;
             // get the x-position for the video (I'm porting an iPad-Webapp to Xoom, 
             // so I can use those numbers... you have to find your own of course...
             this.LayoutParameters.leftMargin = viewLeft + 256; 
             this.LayoutParameters.topMargin = 128;
             // just add this view so the webview underneath will still be visible, 
             // but apply the LayoutParameters specified above
             this.kameha.addContentView(this.mCustomViewContainer, 
                                             this.LayoutParameters); 
             this.mCustomVideoView.setOnCompletionListener(this);
             this.mCustomVideoView.setOnErrorListener(this);
             // handle clicks on the screen (turning off the video) so you can still
             // navigate in your WebView without having the video lying over it
             this.mCustomVideoView.setOnFocusChangeListener(this); 
             this.mCustomVideoView.start();
         }
     }
 }

だから、私が助けてくれるといいのですが...私もビデオエンコーディングをいじって、HTML5ビデオでWebViewを使用するさまざまな種類を見ました-結局、私の作業コードは、インターネットと私が自分で理解しなければならないいくつかのこと。それは本当にa *の苦痛でした。


ICSでは、getFocusedChild()はVideoViewを返しません。これをICSで機能させる方法に関するアイデアはありますか?
Pascal

4

このアプローチは2.3まで非常にうまく機能し、hardwareaccelerated = trueを追加することで3.0からICSまで機能します。現在直面している問題の1つは、メディアプレーヤーアプリケーションの2回目の起動時に、再生を停止せずにメディアプレーヤーをリリースしていないためにクラッシュすることです。3.0OSからonShowCustomView関数で取得するVideoSurfaceViewオブジェクトはブラウザに固有であり、2.3 OSまでのようにVideoViewオブジェクトではないため、それにアクセスしてstopPlaybackを解放してリソースを解放するにはどうすればよいですか?


3

AMはBrowerActivityが行うものに似ています。FrameLayout.LayoutParamsの場合LayoutParameters = new FrameLayout.LayoutParams(768、512);

使えると思います

FrameLayout.LayoutParams LayoutParameters = new FrameLayout.LayoutParams(FrameLayout.LayoutParams.FILL_PARENT,
            FrameLayout.LayoutParams.FILL_PARENT) 

代わりに。

私が遭遇した別の問題は、ビデオが再生されていて、ユーザーが[戻る]ボタンをクリックした場合、次にこのアクティビティ(singleTop one)に移動してビデオを再生できないことです。これを修正するために、私は

try { 
    mCustomVideoView.stopPlayback();  
    mCustomViewCallback.onCustomViewHidden();
} catch(Throwable e) { //ignore }

アクティビティのonBackPressedメソッド内。


2

これは非常に古い質問であることは承知していますが、hardwareAccelerated="true"アプリケーションまたはアクティビティのマニフェストフラグを試しましたか?

このセットを使用すると、WebChromeClientを変更しなくても機能するように見えます(DOM要素からそれを期待しています)。


2
hardwareAcceleratedAndroid 3.0から開始
vbence 2012年

2

この問題を解決するためにhtml5webviewを使用しました。ダウンロードしてプロジェクトに配置すると、次のようにコーディングできます。

private HTML5WebView mWebView;
String url = "SOMEURL";
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    mWebView = new HTML5WebView(this);
    if (savedInstanceState != null) {
            mWebView.restoreState(savedInstanceState);
    } else {
            mWebView.loadUrl(url);
    }
    setContentView(mWebView.getLayout());
}
@Override
public void onSaveInstanceState(Bundle outState) {
    super.onSaveInstanceState(outState);
    mWebView.saveState(outState);
}

ビデオを回転可能にするには、たとえばandroid:configChanges = "orientation"コードをアクティビティに追加します(Androidmanifest.xml)

<activity android:name=".ui.HTML5Activity" android:configChanges="orientation"/>

そしてonConfigurationChangedメソッドをオーバーライドします。

@Override
public void onConfigurationChanged(Configuration newConfig) {
     super.onConfigurationChanged(newConfig);
}

2

この質問は何年も前のものですが、おそらく私の答えは、私のような古いAndroidバージョンをサポートする必要がある人々を助けるでしょう。いくつかのAndroidバージョンで機能するさまざまなアプローチを試しましたが、すべてではありませんでした。私が見つけた最良の解決策は、HTML5機能のサポート用に最適化され、Android 4.1以降で動作するCrosswalk Webviewを使用することです。デフォルトのAndroid WebViewと同じくらい簡単に使用できます。あなただけのライブラリを含める必要があります。ここでは、それを使用する方法に関する簡単なチュートリアルを見つけることができます:https : //diego.org/2015/01/07/embedding-crosswalk-in-android-studio/


注:Crosswalkはもうメンテナンスされていません。
slhck

1

まあ、どうやらこれは、ビデオイベントを取得するためのプラグインを登録するためにJNIを使​​用しない限り、不可能です。(個人的には、AtomベースのAndroidタブレットが今後数か月で登場し、Javaの移植性を失うとき、混乱に対処したくないので、JNIは避けています。)

唯一の本当の選択肢は、WebViewのためだけに新しいWebページを作成し、上記のCodelarkのURLで引用されているA HREFリンクを使用して昔ながらの方法でビデオを作成することです。

イッキー。


1

ハニカムの使用についてhardwareaccelerated=true、動作してpluginstate.on_demandいるようです


1

同様の問題がありました。アプリのアセットフォルダーにHTMLファイルと動画がありました。

したがって、ビデオはAPK内にありました。APKは実際にはZIPファイルであるため、WebViewはビデオファイルを読み取ることができませんでした。

すべてのHTMLファイルとビデオファイルをSDカードにコピーするのがうまくいきました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.