2010-09-28 16 views
115

Estoy juntando una aplicación cheapo que, entre otras cosas, "enmarca" algunos de nuestros sitios web ... Bastante simple con el WebViewClient. hasta que golpeé el video.WebView y HTML5 <video>

El video se hace como elementos HTML5, y estos funcionan bien en Dandy en Chrome, iPhones, y ahora que hemos solucionado los problemas de codificación funciona muy bien en Android en el navegador nativo.

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

Google, encontré this que está cerca, pero parece estar basado en un 'enlace' (como en un href ...) en lugar de un elemento de video. (OnDownloadListener no parece quedar invocado en los elementos de vídeo ...)

También veo referencias a anulando onShowCustomView, pero que parece no ser llamado en los elementos de vídeo ... ni tampoco shouldOverrideUrlLoading ..

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

Me falta algo obvio ... pero no tengo ni idea de qué.

+0

Por favor, consulte: http://code.google.com/p/android/issues/detail?id=22254 – BoD

+0

En este mismo sentido, estoy buscando un reproductor HTML5 para mi sitio web. ¿Qué debería usar? –

+1

Mi respuesta aquí: http://stackoverflow.com/a/16179544/423171 – cprcrack

Respuesta

92

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

-Buscar un video codificado adecuadamente

-Cuando la inicialización de la vista Web, establezca el código JavaScript, Plug-ins y la WebViewClient la 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); 

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

-Mango la onCompletion y los eventos ONERROR para el video, con el fin de 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 debo 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 de Media Player, 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.

+0

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

+0

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

+0

gracias, mdelolmo! eso hizo que mi onShowCustomView funcione ... tendrá que jugar con eso. Tenga en cuenta que al emulador (al menos en Linux) no le gusta mucho la reproducción de videos, incluso las cosas que un android real jugará bien. Y la codificación es un poco dolorosa ... tomó un tiempo para configurar las cosas aquí para que los droides se transmitieran. –

0

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

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

Icky.

32

La respuesta de mdelolmo fue increíblemente útil, pero como dijo, el video solo se reproduce una vez y luego no se puede volver a abrir.

Analicé esto un poco y esto es lo que encontré, en caso de que cualquier 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 obtuve una mejor idea de cómo funcionan. Recomiendo esos.

Luego, miré el source code to see how the Android Browser. Haga una búsqueda de página e ir a ver cómo se manejan onShowCustomView(). Mantienen una referencia al CustomViewCallback y 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 es dos cosas. En primer lugar, en el VideoView al que guardó una referencia, llame al stopPlayback() que lanzará el MediaPlayer para usarlo posteriormente en otro lugar. Puede verlo en el código fuente VideoView. Segundo, en el CustomViewCallback guardó una referencia para llamar al CustomViewCallback.onCustomViewHidden().

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

Espero que ayude.

+0

En realidad, también lo resolví un poco, simplemente no recordé publicar la solución (lástima de mí). Al igual que usted, tuve que echarle un vistazo al código del navegador de Android, y bueno, no mucho para agregar, utilicé el oyente onCompletion para detener el reproductor y tuve que establecer la visibilidad un par de veces, pero me gustaría comprar 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 que se describe aquí: https://github.com/android/platform_packages_apps_browser/blob/froyo-release/src/com/ android/browser/BrowserActivity.java – spacemanaki

+0

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

6

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 en algunos asuntos (es decir, colocando el reproductor multimedia en la sección derecha de la pantalla, no sé por qué lo estoy haciendo mal pero creo que es un problema relativamente pequeño ...).

En el ChromeClient personalizada especificar 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(); 
     } 
    } 
} 

Por lo tanto, espero poder ayudar ... yo también tenía que jugar un poco con el vídeo -En la codificación 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 mi cuenta. Realmente fue un dolor en el a *.

+0

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

2

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

Con este conjunto, parece que funciona sin ninguna modificación WebChromeClient (que yo esperaría de un DOM-Element.)

+2

'hardwareAccelerated' se inicia desde Android 3.0 – vbence

+0

nice hermano, gracias –

3

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

creo que podemos utilizar

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

lugar.

Otro problema que encontré es que si el video se está reproduciendo, y el usuario hace clic en el botón Atrás, la próxima vez va a esta actividad (solo a la cima) y no puede 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.

1

El uso de nido de abeja hardwareaccelerated=true y pluginstate.on_demand parece funcionar

8

En realidad, parece suficiente para simplemente adjuntar una WebChromeClient acciones a la vista de cliente, ala

mWebView.setWebChromeClient(new WebChromeClient()); 

y es necesario tener la aceleración de hardware activada !

Al menos, si no necesita reproducir un video a pantalla completa, no hay necesidad de sacar el VideoView del WebView y colocarlo en la vista de la actividad. Jugará en el rect adjudicado del elemento de video.

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

+1

No funcionó para mí. – mxcl

+0

Funcionó aquí, gracias! –

+0

puede interceptarlo usando WebChromeClient y redefiniendo onShowCustomView – Frank

4

Este enfoque funciona bien muy hasta 2,3 Y añadiendo hardwareaccelerated = true incluso funciona desde 3,0 a ICS Un problema que estoy enfrentando actualmente está sobre el segundo lanzamiento de aplicación del reproductor de medios de comunicación ponen estrellado porque no he dejado de reproducción y lanzó el reproductor multimedia. Como el objeto VideoSurfaceView, que obtenemos en la función ShowView personalizado desde el SO 3.0, son específicos del navegador y no un objeto VideoView como en, hasta 2.3 OS ¿Cómo puedo acceder a él, detener Playback y liberar recursos?

2

He usado html5webview para resolver este problema. Descárguelo y póngalo en su proyecto, entonces 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 giratorio de vídeo, poner android: configChanges = código de "orientación" en su actividad por ejemplo (AndroidManifest.xml)

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

y reemplazar el método onConfigurationChanged.

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

Después de una larga investigación, hice que esto funcionara. Véase 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 cosas que puedas entender.

+7

Esta debería ser la respuesta aceptada. Surendra y Malenkiy ambos salvaron mi cordura. Funcionó muy bien para mí –

+0

Estoy de acuerdo con George. Así es exactamente como funciona el navegador nativo de Android con VideoView. Parece que es el mismo código que aquí http://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 es que debes tener en cuenta que si cambias el SDK objetivo por algo superior a 13, la actividad de tu 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 use el viejo SDK de destino (entonces puede mantener android: configChanges) –

+2

Esto me da una pantalla blanca en blanco en nexus 7 (Android 4.1). ¿Algúna idea de cómo arreglar esto? – Sahil

1

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

Por lo tanto, los videos se ubicaron dentro del APK. Como 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í.

2

Esta pregunta tiene muchos años, pero tal vez mi respuesta ayude a las personas como yo que tienen que soportar la versión anterior de Android. Probé muchos enfoques diferentes que funcionaban en algunas versiones de Android, pero no en todas. La mejor solución que encontré es usar el Crosswalk Webview que está optimizado para el soporte de 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 sencillo tutorial sobre cómo usarlo: https://diego.org/2015/01/07/embedding-crosswalk-in-android-studio/