Estoy tratando de reproducir un sonido desde la carpeta de activos cuando un usuario hace clic en una etiqueta en el WebView de mi aplicación. Descubrí que puedo usar una nueva clase que extienda WebViewClient para detectar la extensión de un enlace y, si es un archivo mp3, puede reproducirlo a través del reproductor de audio predeterminado. Pero quiero que juegue dentro de la actividad sin comenzar una nueva actividad.Android: Reproducción de un sonido activo con WebView
que utilizan los siguientes enlaces como referencias: Sound in Webview y Error creating MediaPlayer with Uri or file in assets
Pero no funcionó.
He intentado utilizar los siguientes códigos para hacerlo:
package com.rangga.test.webview.sound;
import android.content.Intent;
import android.content.res.AssetFileDescriptor;
import android.media.MediaPlayer;
import android.net.Uri;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class MyWebViewClient extends WebViewClient{
public MediaPlayer mp;
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url){
if(url.endsWith(".mp3")){
mp = new MediaPlayer();
AssetFileDescriptor afd = getAssets().openFd(url);
mp.setDataSource(afd.getFileDescriptor());
mp.start();
return true;
}else{
return true;
}
}
}
Me aparece un error método definido en las getAssets(), he intentado googleing y dice algo acerca de pasar de un contexto. Soy muy nuevo en Android y en la programación orientada a objetos, por lo que me pregunto si esta es la forma correcta de hacerlo y si hay una explicación simple sobre qué es un contexto. Gracias.
continuación son mis códigos completos:
MainActivity.class
package com.rangga.test.webview.sound;
import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebView;
public class MainActivity extends Activity {
WebView webMain;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
webMain = (WebView) findViewById(R.id.webMain);
webMain.loadUrl("file:///android_asset/webpages/test.html");
webMain.setWebViewClient(new MyWebViewClient());
}
}
EDITAR
Así los códigos funciona gracias a https://stackoverflow.com/users/488241/squonk pero ahora se produce otro problema, he actualizado el MyWebViewClient en el siguiente:
package com.rangga.test.webview.sound;
import java.io.IOException;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.media.MediaPlayer;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class MyWebViewClient extends WebViewClient{
public MediaPlayer mp;
private Context context = null;
public MyWebViewClient(Context c){
this.context = c;
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url){
if(url.endsWith(".mp3")){
mp = new MediaPlayer();
try {
AssetFileDescriptor afd = context.getAssets().openFd(url);
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
afd.close();
mp.prepare();
mp.start();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return true;
}else{
return true;
}
}
}
Pero obtengo una java.io.FileNotFoundException, aunque la ruta parece correcta. He puesto 2 archivos mp3 en activos/páginas web/sonidos/1.mp3 y activos/páginas web/1.mp3 y utilizado los siguientes códigos html para probarlo:
<html>
<head>
<title>Test Audio</title>
</head>
<body>
<a href="file:///android_asset/webpages/sounds/1.mp3">File Asset</a><br/>
<a href="1.mp3">Same Folder</a>
</body>
</html>
Pero me sale el siguiente error en LogCat :
06-11 06:20:37.955: W/System.err(377): java.io.FileNotFoundException: file:///android_asset/webpages/1.mp3
06-11 06:20:37.966: W/System.err(377): at android.content.res.AssetManager.openAssetFd(Native Method)
06-11 06:20:37.974: W/System.err(377): at android.content.res.AssetManager.openFd(AssetManager.java:314)
06-11 06:20:37.974: W/System.err(377): at com.rangga.test.webview.sound.MyWebViewClient.shouldOverrideUrlLoading(MyWebViewClient.java:30)
06-11 06:20:37.985: W/System.err(377): at android.webkit.CallbackProxy.uiOverrideUrlLoading(CallbackProxy.java:193)
06-11 06:20:38.000: W/System.err(377): at android.webkit.CallbackProxy.handleMessage(CallbackProxy.java:304)
06-11 06:20:38.005: W/System.err(377): at android.os.Handler.dispatchMessage(Handler.java:99)
06-11 06:20:38.005: W/System.err(377): at android.os.Looper.loop(Looper.java:123)
06-11 06:20:38.014: W/System.err(377): at android.app.ActivityThread.main(ActivityThread.java:4363)
06-11 06:20:38.014: W/System.err(377): at java.lang.reflect.Method.invokeNative(Native Method)
06-11 06:20:38.024: W/System.err(377): at java.lang.reflect.Method.invoke(Method.java:521)
06-11 06:20:38.024: W/System.err(377): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
06-11 06:20:38.024: W/System.err(377): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
06-11 06:20:38.054: W/System.err(377): at dalvik.system.NativeStart.main(Native Method)
¿Hay algún problema con la forma en que llamé al archivo? Gracias antes.
RESUELTO
Thx a las sugerencias de Squonk, probé los siguientes códigos para hacer que funcione y funcionó bien, gracias Squonk!
package com.rangga.test.webview.sound;
import java.io.IOException;
import android.content.Context;
import android.content.res.AssetFileDescriptor;
import android.media.MediaPlayer;
import android.util.Log;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class MyWebViewClient extends WebViewClient{
public MediaPlayer mp;
private Context context = null;
public MyWebViewClient(Context c){
this.context = c;
mp = new MediaPlayer();
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url){
if(url.endsWith(".mp3")){
url = url.replace("file:///android_asset/webpages/", "");
Log.i("MyWebViewClient", url);
try {
AssetFileDescriptor afd = context.getAssets().openFd(url);
mp = new MediaPlayer();
mp.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
afd.close();
mp.prepare();
mp.start();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return true;
}else{
return true;
}
}
}
Y el html para probarlo:
<html>
<head>
<title>Test Audio</title>
</head>
<body>
<a href="webpages/1.mp3">File Asset</a><br/>
</body>
</html>
Aunque me hizo llegar un error si repetidamente clic en él, pero esa es otra pregunta: ¿Cómo D pregunta uno cerca de uno? >. <
Guau, gracias, al menos, corre ahora, señor, eres una leyenda ... espera ... ¡dary! Pero cuando hago clic en el enlace 1 y 3 obtiene una java.oi.FileNotFoundException, parece que la ruta en el enlace es incorrecta>.
@RanggaWiratno: Vea el EDIT al final de mi respuesta. – Squonk
Sí, realmente probé lo siguiente también. He agregado los parámetros en el archivo afd y agregado mp.prepare() y afd.close() antes del mp.start() después de leer este http://droidapp.co.uk/?p=272 pero lo extraño es, todavía obtengo la excepción java.io.FileNotFoundException aunque la ruta es correcta. Intenté jugar con el html pero todavía no puedo hacerlo bien File Asset
y Same Folder. He puesto 2 archivos para probarlo, en activos> páginas web> 1.mp3 y activos> páginas web> sonidos> 1.mp3 –