问题
this is my first question on the forums.
I'm building an app which implements a simple webview that loads an html5 page from the SD card.
The app is a presentation made of 5 sections, and each section is contains some text overlayed on top of an HD video about 2 seconds long that plays in loop, basically acting like a page with a video background. The app runs fullscreen with automatic letterboxing / pillarboxing depending on the video resolution and orientation.
On Chrome (Windows 7) and Node-Webkit the app works beautifully, looking good and stable. On Android 4.0.3 (Galaxy Tab 10.1) it works well enough - the app looks also good and stable, even though it seems not possible to preload the videos: I'm injecting the mp4s inside the html page using javascript CreateElement("video") and setting preload attribute to true). On Android 4.1.1 (Medion Lifetab) the videos just aren't loading, and the app displayes a gray box with a video icon. Anyone knows why?
Also the "canplaythrough" event seem to never fire on tablets (another bug I guess), therefore I'm forced to use the "loadstart" event, which is not the same but good enough.
Here's the source (a simple webview viewer that loads an html5 from the external storage)
-------------------------------- 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);
}
}
来源:https://stackoverflow.com/questions/17316127/android-webview-loading-html5-page-from-sd-card-with-mp4-videos-on-various-api