WebView y HTML5 <video>


122

Estoy armando una aplicación de cheapo que, entre otras cosas, "enmarca" algunos de nuestros sitios web ... Bastante simple con el WebViewClient. hasta que llegue al video.

El video está hecho como HTML5 elementos, y estos funcionan bien en Chrome, iPhones, y ahora que solucionamos los problemas de codificación, funciona muy bien Androiden el navegador nativo.

Ahora el problema: WebViewno le gusta. En absoluto. Puedo hacer clic en la imagen del póster y no pasa nada.

En Google, encontré esto que está cerca, pero parece estar basado en un 'enlace' (como en un href ...) en lugar de un elemento de video. (onDownloadListener no parece ser invocado en elementos de video ...)

También veo referencias a la anulación de onShowCustomView, pero parece que no se llama a los elementos de video ... ni debería OververUrlLoading ...

Prefiero no entrar en "extraer xml del servidor, volver a formatearlo en la aplicación" ... manteniendo el diseño de la historia en el servidor, puedo controlar el contenido un poco mejor sin obligar a las personas a seguir actualizando una aplicación. Entonces, si puedo convencer a WebView para que maneje etiquetas como el navegador nativo, sería lo mejor.

Claramente me falta algo obvio ... pero no tengo idea de qué.



En esta misma línea, estoy buscando un reproductor HTML5 para mi sitio web. ¿Qué debo usar?
Wolfpack'08


1
Nada funcionó, así que miré VideoEnabledWebViewaquí stackoverflow.com/questions/15768837/…
EpicPandaForce

Respuestas:


92

Respondo este tema en caso de que alguien lo lea y esté interesado en el resultado. Es posible ver un elemento de video (etiqueta video html5) dentro de un WebView, pero debo decir que tuve que lidiar con él durante unos días. Estos son los pasos que tuve que seguir hasta ahora:

-Buscar un video codificado correctamente

-Al iniciar el WebView, configure el JavaScript, los complementos del WebViewClient y el WebChromeClient.

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

- Maneje el onShowCustomView en el objeto WebChromeClient.

@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();
        }
    }
}

- Maneje los eventos onCompletion y onError para el video, para volver a la vista web.

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();
}

Pero ahora debería decir que todavía hay un problema importante. Puedo jugarlo solo una vez. La segunda vez que hago clic en el despachador de video (ya sea el póster o algún botón de reproducción), no hace nada.

También me gustaría que el video se reproduzca dentro del marco de WebView, en lugar de abrir la ventana del reproductor de medios, pero esto es para mí un problema secundario.

Espero que ayude a alguien, y también agradecería cualquier comentario o sugerencia.

Saludos, terrícolas.


No ejecuto ningún resultado, mi pantalla es negra. Quiero saber si esto necesita thead. mi código es demasiado largo para posy aquí. ¿Puede darme alguna forma de contacto o abrir otro tema?
pengwang

¿Estás completamente seguro de que no es un problema de codificación? Prueba con la URL que publiqué. Obviamente tiene que funcionar con el navegador nativo
mdelolmo

46
¿Qué es "a"? ¿Cómo sería esa actividad?
Collin Price

1
@Collin Price a es una instancia de la Actividad que aloja la vista web. @desgraci, puedo proporcionarlo, pero no hay mucho más que eso. Haga que una clase se extienda WebChromeClienty anule los métodos correspondientes que necesita. Si insiste, puedo subir el resto de la clase más tarde cuando llegue a casa.
mdelolmo

66
No funciona en ICS ya que getFocusedChild () no es un VideoView, sino un HTML5VFullScreen $ SurfaceVideoView. ¿Alguna idea sobre cómo hacer en ICS? (ver stackoverflow.com/questions/13540654/…
Pascal

61

Después de una larga investigación, conseguí que esto funcionara. Ver el siguiente código:

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>

Esperando el resto de las cosas que puedes entender.


77
Esta debería ser la respuesta aceptada. Surendra y Malenkiy los dos salvaron mi cordura. Funcionó muy bien para mí.
George Baker

Estoy de acuerdo con George Así es exactamente cómo funciona el navegador nativo de Android con VideoView. Parece que este es el mismo código que aquí code.google.com/p/html5webview . Funciona muy bien para todas las versiones de Android (probé en Android 2.2 y superior). Solo una cosa que quería notar, debe tener en cuenta que si cambia el SDK objetivo en algo por encima de 13, entonces su actividad se recreará al cambiar de orientación. Para evitar esto, agregue screenSize a android: configChanges (pero en este caso necesitará usar min sdk <13) o usar el SDK de destino anterior (entonces puede mantener android: configChanges)
Yuriy Ashaev

2
Esto me está dando una pantalla en blanco en blanco en Nexus 7 (Android 4.1). ¿Algúna idea de cómo arreglar esto?
Sahil

El botón de retroceso no detiene el video y el audio sigue siendo audible, ¿alguna idea de cómo solucionar esto?
CONvid19

Esto es lo que estaba buscando exactamente igual que el flujo del navegador nativo. Gracias, Ton Surendra y Malenkiy.
Abhilash

33

La respuesta de mdelolmo fue increíblemente útil, pero como él dijo, el video solo se reproduce una vez y luego no puede abrirlo nuevamente.

Investigué un poco esto y esto es lo que encontré, en caso de que algún viajero cansado de WebView como yo tropiece con esta publicación en el futuro.

En primer lugar, miré la documentación de VideoView y MediaPlayer y tuve una mejor idea de cómo funcionan. Los recomiendo encarecidamente.

Luego, miré el código fuente para ver cómo lo hace el navegador de Android . Haz una página para buscar y ver cómo se manejan onShowCustomView(). Mantienen una referencia a CustomViewCallbacky a la vista personalizada.

Con todo eso, y con la respuesta de mdelolmo en mente, cuando haya terminado con el video, todo lo que necesita hacer son dos cosas. Primero, en el VideoViewque guardó una referencia, la llamada stopPlayback()liberará el MediaPlayerpara ser utilizado más adelante en otro lugar. Puede verlo en el código fuente de VideoView . En segundo lugar, en el CustomViewCallbackque guardó una referencia para llamar CustomViewCallback.onCustomViewHidden().

Después de hacer esas dos cosas, puede hacer clic en el mismo video o en cualquier otro video y se abrirá como antes. No es necesario reiniciar todo el WebView.

Espero que ayude.


En realidad, también lo resolví un poco, pero no me acordé de publicar la solución (lástima de mí). Al igual que usted, tuve que echar un vistazo al código del navegador de Android y, bueno, no hay mucho que agregar, usé el oyente onCompletion para detener el reproductor y tuve que configurar la visibilidad un par de veces, pero compraría su solución. ¡Saludos!
mdelolmo

1
Google Code Search ha sido retirado, creo que esta versión de BrowserActivity.java (de Froyo) corresponde aproximadamente a la descrita aquí: github.com/android/platform_packages_apps_browser/blob/…
michiakig

El código vinculado de @ spacemanki no contiene ninguna mención de VideoView en todo el repositorio. Supongo que BrowserActivity lo hace de manera diferente ahora. Incluso volví al lanzamiento de Eclair. No puedo encontrar ningún uso.
mxcl

El problema que tengo con todo esto es que estoy recuperando de frame.getFocusedChild (); es un HTml5VideoView en lugar de un ViewView y, por lo tanto, nada de esto funciona para mí y no puede cambiar a pantalla completa :( Estoy en Android 4.1.2.
Gonan

1
Lo que finalmente lo hizo por mí fue agregar: @Override public void onStop () {super.onStop (); mWebView.destroy (); } para la actividad ... webview.destroy () fue crucial
MacD

8

En realidad, parece suficiente simplemente adjuntar un WebChromeClient de stock a la vista del cliente, ala

mWebView.setWebChromeClient(new WebChromeClient());

¡y necesita tener activada la aceleración de hardware!

Al menos, si no necesita reproducir un video a pantalla completa, no es necesario extraer el VideoView del WebView e insertarlo en la vista de la Actividad. Se reproducirá en el rectángulo asignado del elemento de video.

¿Alguna idea de cómo interceptar el botón expandir video?


puede interceptarlo usando WebChromeClient y anulando enShowCustomView
Frank

Por favor, especifique qué versión de Android. Esto funciona de manera diferente para diferentes versiones.
Ethan_AI

7

Sé que este hilo tiene varios meses, pero encontré una solución para reproducir el video dentro de WebView sin hacerlo a pantalla completa (pero aún en el reproductor multimedia ...). Hasta ahora, no encontré ninguna pista sobre esto en Internet, así que tal vez esto también sea interesante para otros. Todavía estoy luchando por algunos problemas (es decir, colocar el reproductor multimedia en la sección correcta de la pantalla, no sé por qué lo estoy haciendo mal, pero creo que es un problema relativamente pequeño ...).

En el ChromeClient personalizado, especifique LayoutParams:

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

Mi método onShowCustomView se ve así:

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();
         }
     }
 }

Entonces, espero poder ayudar ... También tuve que jugar con la codificación de video y vi diferentes tipos de uso de WebView con video html5; al final, mi código de trabajo era una mezcla salvaje de diferentes partes de código que encontré en Internet y algunas cosas que tuve que resolver por mí mismo. Realmente fue un dolor en el a *.


En ICS, getFocusedChild () no devuelve un VideoView. ¿Alguna idea sobre cómo hacer que esto funcione en ICS?
Pascal

4

Este enfoque funciona muy bien hasta 2.3 Y al agregar hardwareaccelerated = true incluso funciona desde 3.0 a ICS. Un problema que estoy enfrentando actualmente es el segundo lanzamiento de la aplicación del reproductor de medios que se bloquea porque no he detenido la reproducción y lanzado el reproductor de medios. Como el objeto VideoSurfaceView, que obtenemos en la función onShowCustomView desde el sistema operativo 3.0, es específico del navegador y no un objeto VideoView como hasta el sistema operativo 2.3 ¿Cómo puedo acceder a él y detener la reproducción y liberar recursos?


3

AM es similar a lo que hace BrowerActivity . para FrameLayout.LayoutParams LayoutParameters = new FrameLayout.LayoutParams (768, 512);

Creo que podemos usar

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

en lugar.

Otro problema que encontré es si el video se está reproduciendo, y el usuario hace clic en el botón Atrás, la próxima vez, vas a esta actividad (SingleTop one) y no puedes reproducir el video. para arreglar esto, llamé al

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

en el método onBackPressed de la actividad.


2

Sé que esta es una pregunta muy antigua, pero ¿ha probado el hardwareAccelerated="true"indicador de manifiesto para su aplicación o actividad?

Con este conjunto, parece funcionar sin ninguna modificación de WebChromeClient (que esperaría de un elemento DOM).


2
hardwareAcceleratedcomienza desde Android 3.0
vbence

2

Utilicé html5webview para resolver este problema. Descargue y póngalo en su proyecto, luego puede codificar así.

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);
}

Para hacer que el video sea giratorio, coloque el código android: configChanges = "orientación" en su Actividad, por ejemplo (Androidmanifest.xml)

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

y anular el método onConfigurationChanged.

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

2

Esta pregunta tiene años, pero tal vez mi respuesta ayude a personas como yo que tienen que admitir la versión anterior de Android. Probé muchos enfoques diferentes que funcionaron en algunas versiones de Android, pero no en todas. La mejor solución que encontré es usar Crosswalk Webview, que está optimizado para admitir funciones HTML5 y funciona en Android 4.1 y versiones posteriores. Es tan simple de usar como el Android WebView predeterminado. Solo tienes que incluir la biblioteca. Aquí puede encontrar un tutorial simple sobre cómo usarlo: https://diego.org/2015/01/07/embedding-crosswalk-in-android-studio/


Nota: Crosswalk ya no se mantiene .
slhck

1

Bueno, aparentemente esto no es posible sin usar un JNI para registrar un complemento para obtener el evento de video. (Personalmente, estoy evitando los JNI ya que realmente no quiero lidiar con un desastre cuando salgan las tabletas Android basadas en Atom en los próximos meses, perdiendo la portabilidad de Java).

La única alternativa real parece ser crear una nueva página web solo para WebView y hacer videos de la vieja escuela con un enlace A HREF como se cita en la URL de Codelark anterior.

Icky


1

En uso de panal hardwareaccelerated=truey pluginstate.on_demandparece funcionar


1

Tuve un problema similar. Tenía archivos y videos HTML en la carpeta de activos de mi aplicación.

Por lo tanto, los videos se ubicaron dentro del APK. Debido a que el APK es realmente un archivo ZIP, WebView no pudo leer los archivos de video.

Copiar todos los archivos HTML y de video en la tarjeta SD funcionó para mí.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.