@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
localBrowser = (WebView)findViewById(R.id.localbrowser);
localBrowser.getSettings().setJavaScriptEnabled(true);
localBrowser.setWebViewClient(new WebViewClient());
localBrowser.setWebChromeClient(new WebChromeClient());
...
Context context = localBrowser.getContext();
File filesDir = context.getFilesDir();
Log.d("FILE PATH", filesDir.getAbsolutePath());
if (filesDir.exists())
{
filesDir.setReadable(true, false);
try
{
String[] audioFiles = context.getAssets().list("audio");
if (audioFiles != null)
{
byte[] buffer;
int length;
InputStream inStream;
FileOutputStream outStream;
for (int i=0; i<audioFiles.length; i++)
{
inStream = context.getAssets().open(
"audio/" + audioFiles[i] );
outStream = context.openFileOutput(audioFiles[i],
Context.MODE_WORLD_READABLE);
buffer = new byte[8192];
while ((length=inStream.read(buffer)) > 0)
{
outStream.write(buffer, 0, length);
}
// Close the streams
inStream.close();
outStream.flush();
outStream.close();
}
}
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// Feedback
String[] fileList = context().fileList();
Log.d("FILE LIST", "--------------");
for (String fileName : fileList)
{
Log.d("- FILE", fileName);
}
...
}
对应HTML标签
<div id="centre_all" style="width:300px;height:400px;">
<audio controls="controls" autoplay="autoplay">
<source src="/data/data/com.test.audiotag/files/a-00099954.mp3" type="audio/mpeg" />
<source src="audio/a-00099954.mp3" type="audio/mpeg" />
 
</audio>
</div>
外部通用存储解决方案
使用此解决方案时,尝试使用“onDestroy()”方法清理复制到“/mnt/sdcard/temp”目录的临时文件,但在实践中,该方法似乎从未执行过(尝试了两个都被调用的“onStop()”和“onPause()”,但它们过早地删除了文件)。这里给出关于“onDestroy()”的讨论,确认它的代码可能不会执行:
http://developer.android.com/reference/android/app/Activity.html#onDestroy()
清单条目
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Java 代码
private String[] audioList;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
localBrowser = (WebView)findViewById(R.id.localbrowser);
localBrowser.getSettings().setJavaScriptEnabled(true);
localBrowser.setWebViewClient(new WebViewClient());
localBrowser.setWebChromeClient(new WebChromeClient());
...
Context context = localBrowser.getContext();
File dirRoot = new File(Environment.getExternalStorageDirectory().toString());
Log.d("ROOT DIR PATH", dirRoot.getAbsolutePath());
if (dirRoot.exists())
{
File dirTemp = new File(dirRoot.getAbsolutePath() + "/temp");
if (!dirTemp.exists())
{
if (!dirTemp.mkdir())
{
Log.e("AUDIO DIR PATH", "FAILED TO CREATE " +
dirTemp.getAbsolutePath());
}
}
else
{
Log.d("AUDIO DIR PATH", dirTemp.getAbsolutePath());
}
if (dirTemp.exists())
{
dirTemp.setReadable(true, false);
dirTemp.setWritable(true);
try
{
String[] audioFiles = context.getAssets().list("audio");
if (audioFiles != null)
{
byte[] buffer;
int length;
InputStream inStream;
FileOutputStream outStream;
audioList = new String[audioFiles.length];
for (int i=0; i<audioFiles.length; i++)
{
inStream = context.getAssets().open(
"audio/" + audioFiles[i] );
audioList[i] = dirTemp.getAbsolutePath() + "/" +
audioFiles[i];
outStream = new FileOutputStream(audioList[i]);
buffer = new byte[8192];
while ( (length=inStream.read(buffer)) > 0)
{
outStream.write(buffer, 0, length);
}
// Close the streams
inStream.close();
outStream.flush();
outStream.close();
//audioFile = new File(audioList[i]);
//audioFile.deleteOnExit();
}
}
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// Feedback
String[] fileList = dirTemp.list();
Log.d("FILE LIST", "--------------");
for (String fileName : fileList)
{
Log.d("- FILE", fileName);
}
}
...
} // onCreate()
@Override
public void onDestroy()
{
for (String audioFile : audioList)
{
File hFile = new File(audioFile);
if (hFile.delete())
{
Log.d("DELETE FILE", audioFile);
}
else
{
Log.d("DELETE FILE FAILED", audioFile);
}
}
super.onDestroy();
} // onDestroy()
相关的 HTML 标签
<div id="centre_all" style="width:300px;height:400px;">
<audio controls="controls" autoplay="autoplay">
<source src="/mnt/sdcard/temp/a-00099954.mp3" type="audio/mpeg" />
<source src="audio/a-00099954.mp3" type="audio/mpeg" />
 
</audio>
</div>
外部应用存储解决方案
我不会在此列出代码,但它基本上是上面所示解决方案的混合体。请注意,Android必须查看文件扩展名并决定将文件存储在何处;无论您指定目录"context.getExternalFilesDir(null)"还是"context.getExternalFilesDir(Environment.DIRECTORY_MUSIC)",在这两种情况下,文件都将被写入目录"/mnt/sdcard/Android/data/package_name/files/Music"。
最终评论
虽然上述方法可行,但存在缺点。首先,相同的数据被复制,因此存储空间加倍。其次,相同的MediaPlayer用于所有声音文件,因此播放一个文件会中断前一个文件,这样就无法在前景音频上播放背景音频。当我尝试使用此处描述的解决方案时,我能够同时播放多个音频文件:
我认为更好的解决方案是使用Javascript函数来启动音频,进而调用Android Java方法启动自己的MediaPlayer(我可能最终会尝试一下)。
小心,暴力方法
我假设您想要在网页内播放音频而不是直接播放。我不确定以下内容是否有帮助,但当我无法控制HTML(即从某些第三方站点加载)时,我仍然需要控制其启动行为。例如,Vimeo目前似乎忽略WebView的即时版本中的“autoplay”URI参数。因此,为了让视频在页面加载时播放,我采用了专利的“插入手臂大约到肘部”的方法。在您的情况下,隐藏标签(根据上面引用的帖子),然后模拟单击具有不在WebView完全加载之前对页面进行检测的好处。然后,您可以注入JS代码(该代码源自此处:在Android Webview中,我能否修改网页的DOM?):
mWebView.setWebViewClient(new CustomVimeoViewClient(){
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
String injection = injectPageMonitor();
if(injection != null) {
Log.d(TAG, " Injecting . . .");
view.loadUrl(injection);
}
Log.d(TAG, "Page is loaded");
}
}
使用直接的JS或者模拟点击,你可以对你的页面进行仪器化。为了仅仅定位一个小标签位置而加载jQuery似乎有些笨重,因此也许你可以使用以下方法(这是从这里无耻地借鉴来的如何在JavaScript中获取元素类?):
private String injectPageMonitor() {
return( "javascript:" +
"function eventFire(el, etype){ if (el.fireEvent) { (el.fireEvent('on' + etype)); } else { var evObj = document.createEvent('Events'); evObj.initEvent(etype, true, false); el.dispatchEvent(evObj); }}" +
"eventFire(document.querySelectorAll('.some_class_or_another')[0], 'click');";
}
既然我已经告诉你一些尴尬的事情,那么我就坦白地承认,我使用Chrome浏览器在第三方页面上寻找我想要以这种方式检测的东西。由于Android上没有开发者工具(至少目前还没有),我会调整UserAgent,具体方法可以参考这里http://www.technipages.com/google-chrome-change-user-agent-string.html。然后我会泡杯咖啡(液体,而不是Rails Gem),并且在其他人的代码中胡闹。