Android: Reproducción de un sonido de recursos utilizando WebView

Estoy intentando reproducir un sonido de la carpeta de activos cuando un usuario hace clic en una etiqueta en el WebView de mi aplicación. Encontré que puedo utilizar una nueva clase que extiende WebViewClient para detectar la extensión de un acoplamiento y si es un archivo mp3 él puede jugarlo vía el jugador por defecto del audio. Pero quiero que juegue dentro de la actividad sin iniciar una nueva actividad.

Utilicé los siguientes enlaces como referencias: Sonido en Webview y Error al crear MediaPlayer con Uri o archivo en activos

Pero no funcionó.

He intentado usar 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; } } } 

Tengo un error de método indefinido en el getAssets (), he intentado Googleing y dice algo acerca de pasar un contexto. Soy muy nuevo en Android y la programación orientada a objetos, así que me pregunto si esta es la manera correcta de hacerlo y si hay una explicación sencilla sobre lo que es un contexto. Gracias.

Abajo están 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í que los códigos funcionan gracias a https://stackoverflow.com/users/488241/squonk pero ahora ocurre otro problema, actualizé MyWebViewClient en lo 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, la ruta parece correcta sin embargo. He puesto 2 archivos mp3 en los activos / páginas web / sonidos / 1.mp3 y activos / páginas web / 1.mp3 y utiliza 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 obtengo 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 algo mal con la forma en que llamé al archivo? Gracias antes.

Resuelto

Thx a las sugerencias squonk, he intentado los siguientes códigos para 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 obtuve un error si repetidamente haga clic en él, pero eso es otra pregunta: D ¿Cómo se cierra una pregunta? >. <

One Solution collect form web for “Android: Reproducción de un sonido de recursos utilizando WebView”

Cuando declare su MediaPLayer en MyWebViewClient , agregue lo siguiente …

 public class MyWebViewClient extends WebViewClient{ public MediaPlayer mp; private Context context = null; // Add this line ... } 

A continuación, agregue un constructor a MyWebViewClient como sigue …

 public MyWebViewClient(Context context) { this.context = context; } 

Entonces en shouldOverrideUrlLoading(...) obtenga sus activos como sigue …

 AssetFileDescriptor afd = context.getAssets().openFd(url); 

En su MainActivity configure el WebViewClient pasando this (que es el Context la actividad) de la siguiente manera …

 webMain.setWebViewClient(new MyWebViewClient(this)); 

También debe devolver false de shouldOverrideUrlLoading(...) si la url termina con '.mp3' – esto muestra que su WebView está manejando cosas y la aplicación 'host' no debe iniciar una instancia del navegador web de stock.

EDITAR: Para reproducir archivos de audio desde el directorio de activos, debe configurar el origen de datos de forma diferente; vea el directorio aceptado para reproducir archivo de audio del directorio de activos .

También debe llamar mp.prepare() antes de llamar a mp.start() .

  • Recuperar User-Agent mediante programación
  • Android Webview: No se puede llamar a determinedVisibility () - nunca vio una conexión para el pid
  • Simular la vista Web de Android en Firefox de la PC?
  • Android webView: Es posible configurar el teclado numérico primero por defecto cuando se usa input type = text
  • Mi aplicación Android de HTML está perdiendo valores almacenados en localStorage cuando se cierra. ¿Alguien más ve este problema?
  • Android: "onBackPressed" sólo se llama desde la primera página de Cordova 3 webview, no se puede anular desde páginas interiores
  • Monkeyrunner no toca la vista web
  • Youtube Video en WebView no se carga
  • Cargando el caché cuando está sin conexión en la vista Web de Android
  • ¿Por qué el atributo minHeight no funciona en WebView Android?
  • Fling Gesture y Webview en Android
  • FlipAndroid es un fan de Google para Android, Todo sobre Android Phones, Android Wear, Android Dev y Aplicaciones para Android Aplicaciones.