Ran*_*tno 8 audio android webview android-assets
当用户点击我的应用程序的WebView上的标签时,我正试图从assets文件夹中播放声音.我发现我可以使用扩展WebViewClient的新类来检测链接的扩展名,如果是mp3文件,它可以通过默认的音频播放器播放.但是我想让它在没有开始新活动的情况下在活动中发挥作用.
我使用以下链接作为参考: Webview中的声音 和使用Uri创建MediaPlayer或使用资产中的文件时出错
但它没有用.
我尝试使用以下代码执行此操作:
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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
我在getAssets()上得到一个未定义的方法错误,我尝试了谷歌它,它说了一些关于传递一个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());
}
}
Run Code Online (Sandbox Code Playgroud)
编辑
所以这些代码的工作原理归功于/sf/users/34176901/,但现在出现了另一个问题,我将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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
但是我得到了一个java.io.FileNotFoundException,但路径似乎正确.我将2个mp3文件放在assets/webpages/sounds/1.mp3和assets/webpages/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>
Run Code Online (Sandbox Code Playgroud)
但我在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)
Run Code Online (Sandbox Code Playgroud)
我调用文件的方式有问题吗?谢谢你.
解决了
感谢squonk的建议,我尝试了以下代码使其工作,并且运行良好,谢谢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;
}
}
}
Run Code Online (Sandbox Code Playgroud)
和HTML测试它:
<html>
<head>
<title>Test Audio</title>
</head>
<body>
<a href="webpages/1.mp3">File Asset</a><br/>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
虽然如果我反复点击它确实会出错,但这是另一个问题:D如何关闭一个人的问题?> <
在您声明MediaPLayerin 的地方MyWebViewClient,添加以下内容...
public class MyWebViewClient extends WebViewClient{
public MediaPlayer mp;
private Context context = null; // Add this line
...
}
Run Code Online (Sandbox Code Playgroud)
然后添加一个构造函数MyWebViewClient如下......
public MyWebViewClient(Context context) {
this.context = context;
}
Run Code Online (Sandbox Code Playgroud)
然后shouldOverrideUrlLoading(...)按如下方式获取您的资产...
AssetFileDescriptor afd = context.getAssets().openFd(url);
Run Code Online (Sandbox Code Playgroud)
在您的MainActivity设置中,WebViewClient传递this(即 Activity Context)如下......
webMain.setWebViewClient(new MyWebViewClient(this));
Run Code Online (Sandbox Code Playgroud)
另外,如果 url 以“.mp3”结尾,您应该返回false-这表明您正在处理事情,并且“主机”应用程序不应启动普通 Web 浏览器的实例。shouldOverrideUrlLoading(...)WebView
编辑:要从资产目录播放音频文件,您需要以不同的方式设置数据源 - 请参阅play-audio-file-from-the-assets-directory的接受答案。
另外,您应该mp.prepare()先打电话再打电话mp.start()。