Vista web de Android cargando la página html5 de la tarjeta SD con videos mp4 en varios API

esta es mi primera pregunta en los foros.

Estoy construyendo una aplicación que implementa una sencilla vista web que carga una página html5 desde la tarjeta SD.

La aplicación es una presentación hecha de 5 secciones, y cada sección contiene un texto superpuesto encima de un video HD de 2 segundos de duración que se reproduce en bucle, básicamente actuando como una página con un fondo de video. La aplicación se ejecuta en pantalla completa con letterboxing automático / pillarboxing dependiendo de la resolución de vídeo y orientación.

En Chrome (Windows 7) y Nodo-Webkit la aplicación funciona maravillosamente, con un aspecto bueno y estable. En Android 4.0.3 (Galaxy Tab 10.1) funciona bastante bien – la aplicación también parece buena y estable, aunque parece imposible precargar los videos: estoy inyectando los mp4 en la página html usando javascript CreateElement ("video ") y establecer el atributo de precarga en true). En Android 4.1.1 (Medion Lifetab) los videos no se están cargando y la aplicación muestra un cuadro gris con un icono de vídeo. ¿Alguien sabe por qué?

También el evento "canplaythrough" parece que nunca se dispara en las tabletas (otro error supongo), por lo tanto estoy obligado a usar el evento "loadstart", que no es lo mismo pero lo suficientemente bueno.

Aquí está la fuente (un visor webview simple que carga un html5 desde el almacenamiento externo)

——————————– activity_main.xml ————— —————–

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:id="@+id/mainLayout" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="top" android:orientation="horizontal" android:background="@null" tools:context=".MainActivity" > <WebView android:id="@+id/webView" android:layout_width="fill_parent" android:layout_height="fill_parent" android:focusable="true" android:scrollbars="none" /> </RelativeLayout> 

——————————– AndroidManifest.xml ————— —————–

 <?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.rr.pe2013" android:versionCode="1" android:versionName="1.0" > <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="17" /> <application android:hardwareAccelerated="true" android:keepScreenOn="true" android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.rr.pe2013.MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest> 

——————————– MainActivity.java ————— —————–

 package com.rr.pe2013; import android.os.Bundle; import android.os.Environment; import android.app.Activity; import android.annotation.SuppressLint; import android.graphics.Color; import android.view.GestureDetector; import android.view.KeyEvent; import android.view.Window; import android.view.WindowManager; import android.webkit.ConsoleMessage; import android.webkit.WebResourceResponse; import android.webkit.WebView; import android.webkit.WebSettings; import android.webkit.WebChromeClient; import android.webkit.WebViewClient; import android.widget.Toast; public class MainActivity extends Activity { WebView webView; GestureDetector gestureDetector; @SuppressWarnings("deprecation") @SuppressLint("SetJavaScriptEnabled") @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // data folder located on the sd card String webAppFolder = Environment.getExternalStorageDirectory().getPath() + "/rr/pe2013"; // remove title bar as we already have it in the web app this.requestWindowFeature(Window.FEATURE_NO_TITLE); getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); // Point to the content view defined in XML setContentView(R.layout.activity_main); // configure the webview setup in the xml layout webView = (WebView) findViewById(R.id.webView); // webView.clearView(); webView.setFocusable(true); webView.requestFocus(); webView.setBackgroundColor(Color.BLACK); webView.setInitialScale(1); // web view settings WebSettings webSettings = webView.getSettings(); // enable javascript, plugins, dom storage, file access webSettings.setJavaScriptEnabled(true); webSettings.setJavaScriptCanOpenWindowsAutomatically(true); webSettings.setPluginState(WebSettings.PluginState.ON); webSettings.setDomStorageEnabled(true); webSettings.setSaveFormData(false); webSettings.setSavePassword(false); webSettings.setAllowFileAccess(true); if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) { webSettings.setAllowContentAccess(true); } if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) { webSettings.setAllowFileAccessFromFileURLs(true); webSettings.setAllowUniversalAccessFromFileURLs(true); } // more settings webSettings.setLoadsImagesAutomatically(true); webSettings.setSupportMultipleWindows(false); webSettings.setUseWideViewPort(true); webSettings.setLoadWithOverviewMode(false); webSettings.setSupportZoom(false); if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) { webSettings.setMediaPlaybackRequiresUserGesture(false); } if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.HONEYCOMB) { webSettings.setBuiltInZoomControls(false); webSettings.setDisplayZoomControls(false); } // webchrome client webView.setWebChromeClient(new WebChromeClient() { // handle javascript alerts @Override public boolean onJsAlert(WebView view, String url, String message, final android.webkit.JsResult result) { showToast(message); result.confirm(); return true; }; // log console messages @Override public void onConsoleMessage(String message, int lineNumber, String sourceID) { // showToast(sourceID + " [" + lineNumber + "]:\n" + message); } public boolean onConsoleMessage(ConsoleMessage cm) { showToast(cm.sourceId() + " [" + cm.lineNumber() + "]:\n" + cm.message()); return true; } }); // webview client webView.setWebViewClient(new WebViewClient() { public void onPageFinished(WebView webView, String url) { } @Override public void onReceivedError(WebView webview, int errorCode, String description, String failingUrl) { // showToast("onReceivedError: " + description); } }); // load the URL String url = "file:///" + webAppFolder + "/index.html"; // from sd card webView.loadUrl(url); } @Override protected void onPause(){ super.onPause(); webView.onPause(); } @Override protected void onResume(){ super.onResume(); webView.onResume(); } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { // Check if the key event was the Back button and if there's history if ((keyCode == KeyEvent.KEYCODE_BACK) && webView.canGoBack()) { webView.goBack(); return true; } // If it wasn't the Back key or there's no web page history, bubble up to the default // system behavior (probably exit the activity) return super.onKeyDown(keyCode, event); } // display an on-screen temporary message public void showToast(String toast, int duration) { Toast.makeText(getApplicationContext(), toast, duration).show(); } public void showToast(String toast) { showToast(toast, Toast.LENGTH_LONG); } } 

FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.