Android:如何在WebView中加载本地的zip压缩音频文件

时间:2018-12-15 12:58:08

标签: android

我在Android上创建了一个WebView,该WebView用于加载HTML,如下所示:

<audio controls>
  <source src="zip://resource?fileName=apple.wav" type="audio/wav">
</audio>

apple.wav存储在本地zip文件中。我想要的是,当用户单击音频组件上的“播放”按钮时,WebView将尝试从zip文件加载wav音频。目前,我尝试创建的是本地WebViewClient,如下所示。

public class MyWebViewClient extends WebViewClient {
    @Override
    public WebResourceResponse shouldInterceptRequest(final WebView view, String url) {
        if (url.startsWith("zip://resource")) {
            Uri uri = Uri.parse(url);
            String fileName = uri.getQueryParameter("fileName");
            byte[] resourceContents = getResource(fileName);
            WebResourceResponse webResourceResponse = new WebResourceResponse("audio/wav",
                    "UTF-8", new ByteArrayInputStream(resourceContents));
            Map<String, String> responseHeaders = new HashMap<>();

            responseHeaders.put("Content-Type", "audio/wav");
            webResourceResponse.setResponseHeaders(responseHeaders);
            return webResourceResponse;
        } else {
            return super.shouldInterceptRequest(view, url);
        }
    }
    private byte[] getResource(String resourceName) {
        // read the audio contents from the pre-determined zip file
    }
}

然后将其分配给WebView。

WebView webView = findViewById(R.id.webview);
webView.getSettings().setJavaScriptEnabled(true);
webView.setWebViewClient(new MyWebViewClient());

但是没有用。当我单击“播放”按钮时,没有任何反应。我已经在Internet上搜索很长时间了,唯一相关的问题是this one,但是这个问题的答案并不好,涉及修改HTML并将音频文件写入sdcard。

为什么我的代码不起作用?有一种优雅的方法可以使它工作吗?

1 个答案:

答案 0 :(得分:0)

我终于使用WebInterface解决了这个问题,这不是一个优雅的解决方案,或者,音频文件在播放之前必须先写入磁盘。但这有效。

这是我使用的HTML:

<button onclick='Audio.playAudio()' />

创建一个WebInterface:

import android.media.MediaPlayer;
import android.webkit.JavascriptInterface;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

public class PlayAudioWebInterface {
    @JavascriptInterface
    public void playAudio() {
        try {
            MediaPlayer mp = new MediaPlayer();
            FileInputStream fis = getFileInputStream();
            mp.setDataSource(fis.getFD());
            fis.close();
            mp.prepare();
            mp.start();
        } catch (Exception e) {
            Logger.debug("Couldn't play audio");
        }
    }
    private FileInputStream getFileInputStream() throws IOException {
        File resourceFile = new File("/data/data/com.example/files/test.wav");
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(resourceFile));
        bos.write(extractWAVContents());
        bos.flush();
        bos.close();
        return new FileInputStream(resourceFile);
    }
    private byte[] extractWAVContents() {
        // extract wav from zip
    }
}

将其分配给WebView

webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new PlayAudioWebInterface(), "Audio");