2012-06-10 121 views
8

我试图在用户单击应用程序的WebView上的标签时从assets文件夹播放声音。我发现我可以使用一个扩展WebViewClient的新类来检测链接的扩展,如果它是一个mp3文件,它可以通过默认的音频播放器播放它。但我希望它能在活动中发挥作用,而无需开展新的活动。Android:使用WebView播放资产声音

我用下面的链接作为参考: Sound in Webview 和​​

但没有奏效。

我试着用下面的代码可以这样做:

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它,它说,有关通过上下文获得一个未定义的方法错误。我对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,但路径似乎正确。我已经把2个mp3文件的资产/网页/声音/ 1.MP3和资产/网页/ 1.MP3和使用下面的HTML代码来测试它:

<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以湿眶客的建议,我尝试下面的代码,使其工作和它的工作好,谢谢湿眶客!

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来测试它:

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

虽然我做了,如果我重复单击它得到一个错误,但这是另外一个问题:d 怎样一个接近一个人的问题吗? >。 <

回答

3

如果你宣布你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通过传递this(这是活动Context)按以下步骤设置WebViewClient ...

webMain.setWebViewClient(new MyWebViewClient(this)); 

此外,您应该返回falseshouldOverrideUrlLoading(...)如果t他的网址以'.mp3'结尾 - 这表明你的WebView正在处理的东西,'主机'应用程序不应该启动股票网页浏览器的实例。

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

此外,您应致电mp.start()致电mp.prepare()

+0

哇,感谢它至少现在运行,你先生是传奇..等待它.. dary! 但是,当我点击链接1和3时,它得到一个java.oi.FileNotFoundException,它看起来像链接上的路径是错误的>。<而链接2它只是打开网页不可用页面。 有没有办法在资产文件中播放声音,或者应该放在原始文件或SD卡中? –

+0

@RanggaWiratno:在我的回答结尾处查看编辑。 – Squonk

+0

是的,其实我也试过以下。我已经在afd上添加了参数,并且在阅读了http://droidapp.co.uk/?p=272之后在mp.start()之前添加了mp.prepare()和afd.close(),但是奇怪的是是,即使路径是正确的,我仍然得到java.io.FileNotFoundException。我试图搞乱HTML但仍然无法正确对待File Asset
Same Folder。我已经把2个文件进行测试,在资产>网页> 1.mp3和资产>网页>声音> 1.mp3 –