android音乐播放器——通过webview下载歌曲

最近在自己的音乐播放器中添加了一个下载网络歌曲的功能,虽然还没有做到边下边播放的功能,不过总算是开了一个头了,下载功搞定了,离目标也就不远了。

  android自带播放器支持“边下载边播放”的功能,当你使用系统浏览器点击一个“MP3的下载链接”时,它就会自动播放这首歌曲并保存到本地(不知道用第三方浏览器是否也如此,笔者认为应该是系统浏览器会自动识别MP3下载链接,并调用系统播放器来播放)。

  与这个过程类似,在笔者做的音乐播放器中,当用户选择“歌曲下载”时,会转到一个webview中,这里我将webview的初始url定向到"htpp://www.top100.cn"(巨鲸音乐),当点击MP3的下载链接时,就会将音乐下载到sdcard的根目录。webview所在activity的代码如下:

?
setContentView(R.layout.web);
web = (WebView)findViewById(R.id.web);
web.setWebViewClient( new DownLoadWebViewClient( this ));
WebSettings s = web.getSettings();
s.setSaveFormData( false );
s.setSavePassword( false );
s.setUseWideViewPort( true );
s.setJavaScriptEnabled( true );
s.setLightTouchEnabled( true );
web.setWebChromeClient( new WebChromeClient() {
     public void onProgressChanged(WebView view, int progress) {
            //Activity和Webview根据加载程度决定进度条的进度大小
            //当加载到100%的时候 进度条自动消失
             context.setProgress(progress * 100 );
     }
});
web.loadUrl( "http://www.top100.cn/" );
?
 

  web.setWebViewClient(new DownLoadWebViewClient(this));其中DownLoadWebViewClient就使我们下载MP3文件的关键,它继承自WebViewClient,这里我们Override它的public boolean shouldOverrideUrlLoading(WebView view, String url)方法,在方法中我们判断点击的链接时否为“下载MP3文件”,如果成立,则启动一个service来下载mp3文件,代码如下:

?
public class DownLoadWebViewClient extends WebViewClient {
     private Context context;
     public DownLoadWebViewClient(Context context){
         this .context = context;
     }
     @Override
     public boolean shouldOverrideUrlLoading(WebView view, String url) {
         Log.i( "info" , "open an url" );
         String urlStr = "" ;                                 //存放解码后的url
         //如果是utf8编码
         if (isUtf8Url(url)){
             urlStr = Utf8URLdecode(url);
         //如果不是utf8编码
         } else {
             urlStr = URLDecoder.decode(url);
         }
         //如果链接是下载top100.cn中的mp3文件
         if (url.substring(url.length()- 4 ).equals( ".mp3" )&&url.substring( 7 , 10 ).equals( "221" )){
             Log.i( "info" , "mp3 file" );
             String ss[] = urlStr.split( "/" );
             String musicName = ss[ss.length- 1 ];             //得到音乐文件的全名(包括后缀)
             Log.i( "info" , "musicfile: " + musicName);
              
             //将下载链接和文件名传递给下载模块
             Intent intent = new Intent(context,DownLoadService. class );
             intent.putExtra( "url" , url);
             intent.putExtra( "musicName" , musicName);
             context.startService(intent);
         }
         return super .shouldOverrideUrlLoading(view, url);
     }

  这里略去了url解码的相关方法。其中DownLoadService用于下载MP3文件并在,它接收DownLoadWebViewClient传递来的url和音乐文件名,代码如下:

?
public class DownLoadService extends Service implements Runnable{   //实现Runable接口
      
     private String URL_str;                     //网络歌曲的路径
     private File download_file;                 //下载的文件
     private int total_read = 0 ;                 //已经下载文件的长度(以字节为单位)
     private int readLength = 0 ;                 //一次性下载的长度(以字节为单位)
     private int music_length = 0 ;                   //音乐文件的长度(以字节为单位)
     private boolean flag = false ;                   //是否停止下载,停止下载为true
     private Thread downThread;                  //下载线程
     private String musicName;                   //下载的文件名
     @Override
     public IBinder onBind(Intent intent) {
         return null ;
     }
  
     @Override
     public void onCreate() {
         downThread = new Thread( this );          //初始化下载线程
         downThread.start();
     }
  
     @Override
     public void onStart(Intent intent, int startId) {
          URL_str = intent.getExtras().getString( "url" );     //获取下载链接的url
          musicName = intent.getExtras().getString( "musicName" ); //获取下载的文件名
     }
      
     @Override
     public void onDestroy() {
         flag = true ;                                //停止下载
     }
      
     //实现Run方法,进行歌曲的下载
     @Override
     public void run() {                                                         
         FileOutputStream fos = null ;                //文件输出流
         FileInputStream fis = null ;             //文件输出流
         InputStream is = null ;                  //网络文件输入流
         URL url = null ;
         try {
             url = new URL(URL_str);             //网络歌曲的url
             HttpURLConnection httpConnection = null ;
             httpConnection = (HttpURLConnection)
             url.openConnection();               //打开网络连接
             download_file = new File(Environment.   //在sdcard根目录建立一个与要下载的文件的名字相同的文件
                     getExternalStorageDirectory()
                     + "/" + musicName);
             fos = new FileOutputStream(download_file, true );        //初始化文件输出流
             fis = new FileInputStream(download_file);               //初始化文件输入流
             total_read = fis.available();                       //初始化“已下载部分”的长度,此处应为0
             music_length = httpConnection.getContentLength();       //要下载的文件的总长度
              
             if (is == null ) {                               //如果下载失败则打印日志,并返回
                 Log.i( "info" , "donload failed..." );
                 return ;
             }
              
             byte buf[] = new byte [ 1024 ];                       //定义下载缓冲区
             readLength = 0 ;                            //一次性下载的长度
             Log.i( "info" , "download start..." );                     
              
             //向前台发送开始下载广播
             Intent startIntent = new Intent();
             startIntent.setAction( "com.alex.downloadstart" );
             sendBroadcast(startIntent);
              
             //如果读取网络文件的数据流成功,且用户没有选择停止下载,则开始下载文件
             while (readLength != - 1  && !flag) {                    
                 if ((readLength = is.read(buf))> 0 ){
                     fos.write(buf, 0 , readLength);
                     total_read += readLength;           //已下载文件的长度增加
                 }   
                 if (total_read == music_length) {           //当已下载的长度等于网络文件的长度,则下载完成
                     flag = false ;
                     Log.i( "info" , "download complete..." );
                      
                     //向前台发送下载完成广播
                     Intent completeIntent = new Intent();
                     completeIntent.setAction( "com.alex.downloadcompleted" );
                     sendBroadcast(completeIntent);
                      
                     //关闭输入输出流
                     fos.close();
                     is.close();
                     fis.close();
                 }
                 Thread.sleep( 50 );                           //当前现在休眠50毫秒
                 Log.i( "info" , "download process : "                 //打印下载进度
                         + ((total_read+ 0.0 )/music_length* 100 + "" ).substring( 0 , 4 )+ "%" );
             }
         } catch (Exception e) {
             Intent errorIntent = new Intent();
             errorIntent.setAction( "com.alex.downloaderror" );
             sendBroadcast(errorIntent);
             e.printStackTrace();
         }
     }
  
      
  
}

  这里有个小bug,如果下载同一首歌曲多次,程序不会多次新建文件,而将数据写入与之同名的文件中。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
AndroidWebView默认没有开启文件下载的功能。如果需要实现文件下载的功能,可以通过设置WebViewDownloadListener来实现。具体操作如下: 1. 创建一个自定义的DownloadListener类,实现DownloadListener接口。 2. 在DownloadListener的onDownloadStart方法,可以获取到下载链接的url、用户代理、内容描述、MIME类型和文件长度等信息。 3. 在onDownloadStart方法,可以根据需要进行文件下载的处理,例如使用下载管理器进行下载,或者跳转到外部浏览器进行下载。 4. 将自定义的DownloadListener设置给WebView,可以使用setDownloadListener方法。 以下是一个示例代码: ```java webView.setDownloadListener(new DownloadListener() { @Override public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) { // 在这里进行文件下载的处理 // 可以使用下载管理器进行下载,或者跳转到外部浏览器进行下载 // 例如: Uri uri = Uri.parse(url); Intent intent = new Intent(Intent.ACTION_VIEW, uri); startActivity(intent); } }); ``` 通过设置DownloadListener,当用户点击WebView下载链接时,就会触发onDownloadStart方法,你可以在这个方法实现自己的文件下载逻辑。 #### 引用[.reference_title] - *1* [Android WebView使用之文件下载](https://blog.csdn.net/weixin_32578799/article/details/117540115)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Android WebView 无法下载文件的问题](https://blog.csdn.net/qq_33372370/article/details/122156492)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [AndroidWebView 文件下载](https://blog.csdn.net/leyang0910/article/details/131554032)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值