gpt4 book ai didi

Android:使用 WebView 播放 Assets 声音

转载 作者:塔克拉玛干 更新时间:2023-11-02 18:58:45 29 4
gpt4 key购买 nike

当用户单击我应用程序的 WebView 上的标签时,我尝试播放 Assets 文件夹中的声音。我发现我可以使用一个扩展 WebViewClient 的新类来检测链接的扩展,如果它是一个 mp3 文件,它可以通过默认的音频播放器播放它。但我希望它在 Activity 中播放而不开始新的 Activity。

我使用以下链接作为引用: Sound in WebviewError creating MediaPlayer with Uri or file in assets

但是没有用。

我尝试使用以下代码来做到这一点:

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() 上收到一个未定义的方法错误,我尝试用谷歌搜索它,它说了一些关于传递上下文的内容。我是 Android 和面向对象编程的新手,所以我想知道这是否是正确的方法,以及是否有关于上下文是什么的简单解释。谢谢。

下面是我的完整代码:

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 文件放在 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>

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

我调用文件的方式有问题吗?先谢谢了。

已解决

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

以及用于测试它的 html:

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

虽然我反复点击它确实会出错,但那是另一个问题:D如何结束一个人的问题? >.<

最佳答案

MyWebViewClient 中声明 MediaPLayer 的地方,添加以下内容...

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(即 Activity Context)来设置 WebViewClient,如下所示。 ..

webMain.setWebViewClient(new MyWebViewClient(this));

此外,如果 url 以“.mp3”结尾,您应该从 shouldOverrideUrlLoading(...) 返回 false - 这显示您的 WebView正在处理事情,“主机”应用程序不应启动标准 Web 浏览器的实例。

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

此外,您还应该在调用 mp.start() 之前调用 mp.prepare()

关于Android:使用 WebView 播放 Assets 声音,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10966245/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com