Android webview loading html5 page from SD card with mp4 videos on various API

自闭症网瘾萝莉.ら 提交于 2019-12-23 15:08:09

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!