Android:使用WebView播放资产声音

我尝试从用户点击应用程序的WebView上的标记时从资源文件夹播放声音。 我发现我可以使用一个扩展WebViewClient的新类来检测链接的扩展,如果它是一个mp3文件,它可以通过默认的audio播放器播放它。 但是我希望它能在活动中发挥作用,而不必开始新的活动。

我使用了以下链接作为参考: Webview中的声音和使用Uri或资产中的文件创buildMediaPlayer时出错

但它没有工作。

我试着用下面的代码来做到这一点:

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; } } } 

我在getAssets()上得到了一个未定义的方法错误,我试着Googleing它,并且说了一些关于传递Context的东西。 我对Android和面向对象编程非常陌生,所以我想知道这是否是正确的方法,以及对Context是什么的简单解释。 谢谢。

以下是我的完整代码:

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()); } } 

编辑

所以代码的作品感谢https://stackoverflow.com/users/488241/squonk,但现在又出现了一个问题,我更新了MyWebViewClient到以下内容:

 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; } } } 

但是我得到了一个java.io.FileNotFoundException,path似乎正确。 我已经把资产/网页/声音/ 1.mp3和资产/网页/ 1.mp3 2个MP3文件,并使用下面的HTML代码来testing它:

 <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> 

但是我在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) 

我调用文件的方式有问题吗? 谢谢之前。

解决了

thx squonk的build议,我试着下面的代码,使其工作,它运作良好,谢谢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; } } } 

和HTML来testing它:

 <html> <head> <title>Test Audio</title> </head> <body> <a href="webpages/1.mp3">File Asset</a><br/> </body> </html> 

尽pipe如果我反复点击它,我确实得到了一个错误,但这是另一个问题:D如何closures一个人的问题? > <

Solutions Collecting From Web of "Android:使用WebView播放资产声音"

MediaPLayer中声明MediaPLayerMyWebViewClient ,添加以下内容…

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

然后添加一个构造函数MyWebViewClient ,如下所示…

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

然后在shouldOverrideUrlLoading(...)获取您的资产,如下所示…

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

在你的MainActivity设置WebViewClient通过传递this (这是活动Context ),如下所示…

 webMain.setWebViewClient(new MyWebViewClient(this)); 

如果URL以'.mp3'结尾,你也应该从shouldOverrideUrlLoading(...)返回false – 这表明你的WebView正在处理事物,“主机”应用程序不应该启动股票Web浏览器的一个实例。

编辑:要播放资产目录中的audio文件,您需要以不同的方式设置数据源 – 请参阅Play-audio-file-from-the-assets-directory的接受答案。

你也应该在调用mp.prepare()之前调用mp.start()