android - sistemas - Problema al cargar video flv en webview
sistema de recomendacion tesis (4)
Aquí hay un consejo rápido para ti. Sé que los emuladores no admiten flash, muchos de los teléfonos Android no son compatibles con flash tampoco. Entonces, cuando realice las pruebas, asegúrese de hacerlo en un teléfono que admita flash.
Quiero cargar video .flv en webview.
He tomado ayuda de este enlace , pero el problema es que no puedo ver el video en el emulador.
Este es mi código:
package com.FlvTester;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebView;
import android.widget.FrameLayout;
public class FlvTester extends Activity {
WebView webView;
String htmlPre = "<!DOCTYPE html><html lang=/"en/"><head><meta charset=/"utf-8/"></head><body style=''margin:0; pading:0; background-color: black;''>";
String htmlCode =
" <embed style=''width:100%; height:100%'' src=''http://www.platipus.nl/flvplayer/download/1.0/FLVPlayer.swf?fullscreen=true&video=@VIDEO@'' " +
" autoplay=''true'' " +
" quality=''high'' bgcolor=''#000000'' " +
" name=''VideoPlayer'' align=''middle''" + // width=''640'' height=''480''
" allowScriptAccess=''*'' allowFullScreen=''true''" +
" type=''application/x-shockwave-flash'' " +
" pluginspage=''http://www.macromedia.com/go/getflashplayer'' />" +
"";
String htmlPost = "</body></html>";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
webView = (WebView)findViewById(R.id.webview);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setAllowFileAccess(true);
webView.getSettings().setPluginsEnabled(true);
htmlCode = htmlCode.replaceAll("@VIDEO@", "file:///android_asset/expression_sad.flv");
webView.loadDataWithBaseURL("file:///android_asset/expression_sad.flv", htmlPre+htmlCode+htmlPost, "text/html", "UTF-8", null);
}
@Override
protected void onPause(){
super.onPause();
callHiddenWebViewMethod("onPause");
webView.pauseTimers();
if(isFinishing()){
webView.loadUrl("about:blank");
setContentView(new FrameLayout(this));
}
}
@Override
protected void onResume(){
super.onResume();
callHiddenWebViewMethod("onResume");
webView.resumeTimers();
}
private void callHiddenWebViewMethod(String name){
// credits: http://stackoverflow.com/questions/3431351/how-do-i-pause-flash- content-in-an-android-webview-when-my-activity-isnt-visible
if( webView != null ){
try {
Method method = WebView.class.getMethod(name);
method.invoke(webView);
} catch (NoSuchMethodException e) {
//Lo.g("No such method: " + name + e);
} catch (IllegalAccessException e) {
//Lo.g("Illegal Access: " + name + e);
} catch (InvocationTargetException e) {
//Lo.g("Invocation Target Exception: " + name + e);
}
}
}
}
Recibí este error en el registro de cat
07-06 12:00:48.567: WARN/dalvikvm(381): threadid=1: thread exiting with uncaught exception (group=0x4001d800)
07-06 12:00:48.597: ERROR/AndroidRuntime(381): FATAL EXCEPTION: main
07-06 12:00:48.597: ERROR/AndroidRuntime(381): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.FlvTester/com.FlvTester.FlvTester}: java.lang.ClassCastException: android.widget.VideoView
07-06 12:00:48.597: ERROR/AndroidRuntime(381): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2663)
07-06 12:00:48.597: ERROR/AndroidRuntime(381): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2679)
07-06 12:00:48.597: ERROR/AndroidRuntime(381): at android.app.ActivityThread.access$2300(ActivityThread.java:125)
07-06 12:00:48.597: ERROR/AndroidRuntime(381): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2033)
07-06 12:00:48.597: ERROR/AndroidRuntime(381): at android.os.Handler.dispatchMessage(Handler.java:99)
07-06 12:00:48.597: ERROR/AndroidRuntime(381): at android.os.Looper.loop(Looper.java:123)
07-06 12:00:48.597: ERROR/AndroidRuntime(381): at android.app.ActivityThread.main(ActivityThread.java:4627)
07-06 12:00:48.597: ERROR/AndroidRuntime(381): at java.lang.reflect.Method.invokeNative(Native Method)
07-06 12:00:48.597: ERROR/AndroidRuntime(381): at java.lang.reflect.Method.invoke(Method.java:521)
07-06 12:00:48.597: ERROR/AndroidRuntime(381): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:868)
07-06 12:00:48.597: ERROR/AndroidRuntime(381): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
07-06 12:00:48.597: ERROR/AndroidRuntime(381): at dalvik.system.NativeStart.main(Native Method)
07-06 12:00:48.597: ERROR/AndroidRuntime(381): Caused by: java.lang.ClassCastException: android.widget.VideoView
07-06 12:00:48.597: ERROR/AndroidRuntime(381): at com.FlvTester.FlvTester.onCreate(FlvTester.java:31)
07-06 12:00:48.597: ERROR/AndroidRuntime(381): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
07-06 12:00:48.597: ERROR/AndroidRuntime(381): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2627)
07-06 12:00:48.597: ERROR/AndroidRuntime(381): ... 11 more
Main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout android:layout_width="fill_parent" android:layout_height="fill_parent" xmlns:android="http://schemas.android.com/apk/res/android">
<WebView android:layout_width="match_parent" android:id="@+id/webview" android:layout_height="match_parent"></WebView>
</LinearLayout>
Actualizar
Esto se trabajó para mí para archivos sdcard locales
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.FrameLayout;
public class MainActivity extends Activity {
private static final String TAG = "FLVplayer";
private static WebView webView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String file = "/sdcard/FLVplayer/20051210-w50s.flv";
String htmlPre = "<!DOCTYPE html><html lang=/"en/"><head><meta charset=/"utf-8/"></head><body style=''margin:0; pading:0; background-color: black;''>";
String htmlCode = " <embed style=''width:100%; height:100%'' src=''/sdcard/FLVplayer/FLVPlayer.swf?fullscreen=true&video="
+ file
+ "&autoplay=true'' "
+ " autoplay=''true'' "
+ " quality=''high'' bgcolor=''#000000'' "
+ " name=''VideoPlayer'' align=''middle''"
+ // width=''640'' height=''480''
" allowScriptAccess=''*'' allowFullScreen=''true''"
+ " type=''application/x-shockwave-flash'' "
+ " pluginspage=''http://www.macromedia.com/go/getflashplayer'' />"
+ "";
String htmlPost = "</body></html>";
setContentView(R.layout.activity_main);
webView = (WebView) findViewById(R.id.webview);
// WebView webview = new WebView(this);
// setContentView(webview);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setAllowFileAccess(true);
webView.getSettings().setPluginState(WebSettings.PluginState.ON);
if (!Environment.getExternalStorageState().equals(
Environment.MEDIA_MOUNTED)) {
Log.d(TAG, "No SDCARD");
} else {
// load the content into the webview
// webView.loadUrl(htmlPre+htmlCode+htmlPost);
webView.loadDataWithBaseURL("file:///android_asset/FLVPlayer.swf",
htmlPre + htmlCode + htmlPost, "text/html", "UTF-8", null);
// sit back, watch FLV and eat popcorn
}
}
}
Me encontré con este problema antes. El problema es la codificación de URL en load (). Debes codificar el? y = a la URL Codificado equivalente% 3F y% 3D respectivamente.
No indicas claramente cuál es tu versión de Android, sin embargo, puedo confirmar que el complemento de flash se carga y el reproductor de películas se intilaiza con el gráfico de forma swirly. Puedo activarlo en el modo de pantalla completa. También puedo reproducir videos en línea pero no desde la carpeta de activos de la aplicación, sin embargo, tengo una solución alternativa.
Los siguientes permissinos son obligatorios en su manifest.xml:
<uses-permission android:name="android.permission.INTERNET"></uses-permission> <!-- where required -->
<uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>
Curiosamente, descubrí que solo podía ejecutar el reproductor SWF desde la carpeta de activos cuando el html estaba cargado estáticamente, es decir, cuando creé un archivo html y lo cargué directamente desde la carpeta de activos usando loadUrl (). Parece que hay algo que bloquea el acceso al directorio de la aplicación cuando se cargan datos html utilizando el método loadDataBaseUrl.
Para que el video se reproduzca con éxito desde el dispositivo local, un archivo html estático y el video deben ubicarse conjuntamente en la tarjeta SD. Mi única conclusión es que la carpeta de activos está fuera de los límites del complemento integrado por razones de seguridad.
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
Log.d(TAG, "No SDCARD");
} else {
webView.loadUrl("file://"+Environment.getExternalStorageDirectory()+"/FLVplayer/index.html");
}
Y aquí está el archivo html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
</head>
<body style="margin:0; pading:0; background-color: black;">
<embed
style="width:100%; height:100%"
src="./FLVPlayer.swf?fullscreen=true&video=./expression_sad.flv"
autoplay="true"
quality="high"
bgcolor="#000000"
name="VideoPlayer"
align="middle"
allowScriptAccess="*"
allowFullScreen="true"
type="application/x-shockwave-flash"
pluginspage="http://www.macromedia.com/go/getflashplayer">
</embed>
</body>
</html>
Esta es una solución que funciona al 100%, pero tendría que escribir su archivo html en la tarjeta SD antes de llamar a loadUrl para reemplazar dinamicamente el nombre del archivo de video. Además, debe copiar el video de su carpeta de activos en la misma ruta en la tarjeta SD (como puede ver en mi exaple, creé una carpeta llamada FLVplayer).
Prueba realizada en Samsung Galaxy Tab con Froyo (2.2)
ACTUALIZAR
Incluyo una actividad completa que ha sido probada y funcionando. Esto espera que una copia del reproductor Flash, el archivo FLV y el archivo index.html se coloquen en una carpeta llamada "FLVplayer" en la raíz de su tarjeta sdcard, que puede copiar utilizando el explorador de archivos. Puede editar las diversas funciones de utilidad para modificar el comportamiento para copiar los archivos de su carpeta assetes
package com.FLVplayer;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import android.app.Activity;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.webkit.WebView;
import android.widget.FrameLayout;
public class FLVplayerActivity extends Activity {
private static final String TAG="FLVplayer";
private static WebView webView;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
webView = (WebView)findViewById(R.id.webview);
//WebView webview = new WebView(this);
//setContentView(webview);
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setAllowFileAccess(true);
webView.getSettings().setPluginsEnabled(true);
if (!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
Log.d(TAG, "No SDCARD");
} else {
//prepare the directory
File flvDirectory = new File(Environment.getExternalStorageDirectory(),"FLVplayer");
if(!flvDirectory.exists())
try {
flvDirectory.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
//specify the html file name to use
File flvHtml = new File(flvDirectory,"index.html");
//copy what you need
copySwfAsset(flvDirectory, "FLVPlayer.swf");
copyFlvAsset(flvDirectory, "20051210-w50s.flv");
//render the html
createVideoHtml(flvHtml, "20051210-w50s.flv");
//load the content into the webview
webView.loadUrl(Uri.fromFile(flvHtml).toString());
//sit back, watch FLV and eat popcorn
}
}
private void createVideoHtml(File htmlFile, String htmlFileName)
{
//TODO render your own html file to sdcard
}
private void copySwfAsset(File flvDirectory, String flashFileName)
{
//TODO copy your own SWF video player file from assets
}
private void copyFlvAsset(File flvDirectory, String videoFileName)
{
//TODO copy your oown FLV file from asset folder
}
@Override
protected void onPause(){
super.onPause();
callHiddenWebViewMethod("onPause");
webView.pauseTimers();
if(isFinishing()){
webView.loadUrl("about:blank");
setContentView(new FrameLayout(this));
}
}
@Override
protected void onResume(){
super.onResume();
callHiddenWebViewMethod("onResume");
webView.resumeTimers();
}
private void callHiddenWebViewMethod(String name){
// credits: http://.com/questions/3431351/how-do-i-pause-flash- content-in-an-android-webview-when-my-activity-isnt-visible
if( webView != null ){
try {
Method method = WebView.class.getMethod(name);
method.invoke(webView);
} catch (NoSuchMethodException e) {
//Lo.g("No such method: " + name + e);
} catch (IllegalAccessException e) {
//Lo.g("Illegal Access: " + name + e);
} catch (InvocationTargetException e) {
//Lo.g("Invocation Target Exception: " + name + e);
}
}
}
}
ADENDUM
Creo que puede haber una forma de eludir los problemas de seguridad interceptando la URL de los diversos archivos y devolviendo los datos directamente desde la carpeta de activos usando WebViewClient.shouldInterceptRequest (), pero eso requiere API 11, por lo que no es adecuado como solución genérica.