1. 程式人生 > >WebView實現檔案下載功能

WebView實現檔案下載功能

WebView控制呼叫相應的WEB頁面進行展示。當碰到頁面有下載連結的時候,點選上去是一點反應都沒有的。原來是因為WebView預設沒有開啟檔案下載的功能,如果要實現檔案下載的功能,需要設定WebView的DownloadListener,通過實現自己的DownloadListener來實現檔案的下載。具體操作如下: 

1、設定WebView的DownloadListener: 
    webView.setDownloadListener(new MyWebViewDownLoadListener()); 

2、實現MyWebViewDownLoadListener這個類,具體可以如下這樣:  

  1. privateclass MyWebViewDownLoadListener implements DownloadListener{  
  2.         @Override
  3.         publicvoid onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype,  
  4.                                     long contentLength) {             
  5.             Log.i("tag""url="
    +url);             
  6.             Log.i("tag""userAgent="+userAgent);  
  7.             Log.i("tag""contentDisposition="+contentDisposition);           
  8.             Log.i("tag""mimetype="+mimetype);  
  9.             Log.i("tag""contentLength="+contentLength);  
  10.             Uri uri = Uri.parse(url);  
  11.             Intent intent = new
     Intent(Intent.ACTION_VIEW, uri);  
  12.             startActivity(intent);             
  13.         }  
  14.     }  
  這只是呼叫系統中已經內建的瀏覽器進行下載,還沒有WebView本身進行的檔案下載,不過,這也基本上滿足我們的應用場景了。 

我在專案中的運用 
專案要求這樣: 
1,需要使用WebView載入一個網頁; 
2,網頁中有檔案下載的連結,點選後需要下載檔案到SDcard; 
3,然後自動開啟檔案; 
下面是具體解決辦法 
第一步,對WebView進行一系列設定。
  1. WebView webview=(WebView)layout.findViewById(R.id.webview);  
  2.                 webview.getSettings().setJavaScriptEnabled(true);  
  3.                 webview.setWebChromeClient(new MyWebChromeClient());  
  4.                 webview.requestFocus();  
  5. //              webview.loadUrl("file:///android_asset/risktest.html");
  6.                 webview.loadUrl(jcrs_sub.get(position).addr);  
  7.                 // 設定web檢視客戶端
  8.                 webview.setWebViewClient(new MyWebViewClient());  
  9.                 webview.setDownloadListener(new MyWebViewDownLoadListener());  
  10. //內部類
  11. publicclass MyWebViewClient extends WebViewClient {  
  12.         // 如果頁面中連結,如果希望點選連結繼續在當前browser中響應,
  13.         // 而不是新開Android的系統browser中響應該連結,必須覆蓋 webview的WebViewClient物件。
  14.         publicboolean shouldOverviewUrlLoading(WebView view, String url) {  
  15.             L.i("shouldOverviewUrlLoading");  
  16.             view.loadUrl(url);  
  17.             returntrue;  
  18.         }  
  19.         publicvoid onPageStarted(WebView view, String url, Bitmap favicon) {  
  20.             L.i("onPageStarted");  
  21.             showProgress();  
  22.         }  
  23.         publicvoid onPageFinished(WebView view, String url) {  
  24.             L.i("onPageFinished");  
  25.             closeProgress();  
  26.         }  
  27.         publicvoid onReceivedError(WebView view, int errorCode,  
  28.                 String description, String failingUrl) {  
  29.             L.i("onReceivedError");  
  30.             closeProgress();  
  31.         }  
  32.     }  
  33. // 如果不做任何處理,瀏覽網頁,點選系統“Back”鍵,整個Browser會呼叫finish()而結束自身,
  34.     // 如果希望瀏覽的網 頁回退而不是推出瀏覽器,需要在當前Activity中處理並消費掉該Back事件。
  35.     publicboolean onKeyDown(int keyCode, KeyEvent event) {  
  36.         // if((keyCode==KeyEvent.KEYCODE_BACK)&&webview.canGoBack()){
  37.         // webview.goBack();
  38.         // return true;
  39.         // }
  40.         returnfalse;  
  41.     }  
第二步,起執行緒開始下載檔案。
  1. //內部類
  2. privateclass MyWebViewDownLoadListener implements DownloadListener {  
  3.         @Override
  4.         publicvoid onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype,  
  5.                                     long contentLength) {  
  6.             if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){  
  7.                 Toast t=Toast.makeText(mContext, "需要SD卡。", Toast.LENGTH_LONG);  
  8.                 t.setGravity(Gravity.CENTER, 00);  
  9.                 t.show();  
  10.                 return;  
  11.             }  
  12.             DownloaderTask task=new DownloaderTask();  
  13.             task.execute(url);  
  14.         }  
  15.     }  
  16.     //內部類
  17.     privateclass DownloaderTask extends AsyncTask<String, Void, String> {   
  18.         public DownloaderTask() {   
  19.         }  
  20.         @Override
  21.         protected String doInBackground(String... params) {  
  22.             // TODO Auto-generated method stub
  23.             String url=params[0];  
  24. //          Log.i("tag", "url="+url);
  25.             String fileName=url.substring(url.lastIndexOf("/")+1);  
  26.             fileName=URLDecoder.decode(fileName);  
  27.             Log.i("tag""fileName="+fileName);  
  28.             File directory=Environment.getExternalStorageDirectory();  
  29.             File file=new File(directory,fileName);  
  30.             if(file.exists()){  
  31.                 Log.i("tag""The file has already exists.");  
  32.                 return fileName;  
  33.             }  
  34.             try {    
  35.                 HttpClient client = new DefaultHttpClient();    
  36. //                client.getParams().setIntParameter("http.socket.timeout",3000);//設定超時
  37.                 HttpGet get = new HttpGet(url);    
  38.                 HttpResponse response = client.execute(get);  
  39.                 if(HttpStatus.SC_OK==response.getStatusLine().getStatusCode()){  
  40.                     HttpEntity entity = response.getEntity();  
  41.                     InputStream input = entity.getContent();  
  42.                     writeToSDCard(fileName,input);  
  43.                     input.close();  
  44. //                  entity.consumeContent();
  45.                     return fileName;    
  46.                 }else{  
  47.                     returnnull;  
  48.                 }  
  49.             } catch (Exception e) {    
  50.                 e.printStackTrace();  
  51.                 returnnull;  
  52.             }  
  53.         }  
  54.         @Override
  55.         protectedvoid onCancelled() {  
  56.             // TODO Auto-generated method stub
  57.             super.onCancelled();  
  58.         }  
  59.         @Override
  60.         protectedvoid onPostExecute(String result) {  
  61.             // TODO Auto-generated method stub
  62.             super.onPostExecute(result);  
  63.             closeProgressDialog();  
  64.             if(result==null){  
  65.                 Toast t=Toast.makeText(mContext, "連線錯誤!請稍後再試!", Toast.LENGTH_LONG);  
  66.                 t.setGravity(Gravity.CENTER, 00);  
  67.                 t.show();  
  68.                 return;  
  69.             }  
  70.             Toast t=Toast.makeText(mContext, "已儲存到SD卡。", Toast.LENGTH_LONG);  
  71.             t.setGravity(Gravity.CENTER, 00);  
  72.             t.show();  
  73.             File directory=Environment.getExternalStorageDirectory();  
  74.             File file=new File(directory,result);  
  75.             Log.i("tag""Path="+file.getAbsolutePath());  
  76.             Intent intent = getFileIntent(file);  
  77.             startActivity(intent);  
  78.         }  
  79.         @Override
  80.         protectedvoid onPreExecute() {  
  81.             // TODO Auto-generated method stub
  82.             super.onPreExecute();  
  83.             showProgressDialog();  
  84.         }  
  85.         @Override
  86.         protectedvoid onProgressUpdate(Void... values) {  
  87.             // TODO Auto-generated method stub
  88.             super.onProgressUpdate(values);  
  89.         }   
  90.     }   
第三步,實現一些工具方法。 
  1. <span style="font-family:Helvetica, Tahoma, Arial, sans-serif;">private ProgressDialog mDialog;  
  2.     privatevoid showProgressDialog(){  
  3.         if(mDialog==null){  
  4.             mDialog = new ProgressDialog(mContext);    
  5.             mDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);//設定風格為圓形進度條  
  6.             mDialog.setMessage("正在載入 ,請等待...");    
  7.             mDialog.setIndeterminate(false);//設定進度條是否為不明確  
  8.             mDialog.setCancelable(true);//設定進度條是否可以按退回鍵取消  
  9.             mDialog.setCanceledOnTouchOutside(false);  
  10.             mDialog.setOnDismissListener(new OnDismissListener() {  
  11.                 @Override
  12.                 publicvoid onDismiss(DialogInterface dialog) {  
  13.                     // TODO Auto-generated method stub
  14.                     mDialog=null;  
  15.                 }  
  16.             });  
  17.             mDialog.show();  
  18.         }  
  19.     }  
  20.     privatevoid closeProgressDialog(){  
  21.         if(mDialog!=null){  
  22.             mDialog.dismiss();  
  23.             mDialog=null;  
  24.         }  
  25.     }  
  26.      public Intent getFileIntent(File file){  
  27. //       Uri uri = Uri.parse("http://m.ql18.com.cn/hpf10/1.pdf");
  28.         Uri uri = Uri.fromFile(file);  
  29.         String type = getMIMEType(file);  
  30.         Log.i("tag""type="+type);  
  31.         Intent intent = new Intent("android.intent.action.VIEW");  
  32.         intent.addCategory("android.intent.category.DEFAULT");  
  33.         intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);  
  34.         intent.setDataAndType(uri, type);  
  35.         return intent;  
  36.       }  
  37.     publicvoid writeToSDCard(String fileName,InputStream input){  
  38.         if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){  
  39.             File directory=Environment.getExternalStorageDirectory();  
  40.             File file=new File(directory,fileName);  
  41. //          if(file.exists()){
  42. //              Log.i("tag", "The file has already exists.");
  43. //              return;
  44. //          }
  45.             try {  
  46.                 FileOutputStream fos = new FileOutputStream(file);  
  47.                 byte[] b = newbyte[2048];  
  48.                 int j = 0;  
  49.                 while ((j = input.read(b)) != -1) {  
  50.                     fos.write(b, 0, j);  
  51.                 }  
  52.                 fos.flush();  
  53.                 fos.close();  
  54.             } catch (FileNotFoundException e) {  
  55.                 // TODO Auto-generated catch block
  56.                 e.printStackTrace();  
  57.             } catch (IOException e) {  
  58.                 // TODO Auto-generated catch block
  59.                 e.printStackTrace();  
  60.             }  
  61.         }else{  
  62.             Log.i("tag""NO SDCard.");  
  63.         }  
  64.     }  
  65.     private String getMIMEType(File f){     
  66.       String type="";    
  67.       String fName=f.getName();    
  68.       /* 取得副檔名 */
  69.       String end=fName.substring(fName.lastIndexOf(".")+1,fName.length()).toLowerCase();  
  70.       /* 依副檔名的型別決定MimeType */
  71.       if(end.equals("pdf")){  
  72.           type = "application/pdf";//
  73.       }  
  74.       elseif(end.equals("m4a")||end.equals("mp3")||end.equals("mid")||    
  75.       end.equals("xmf")||end.equals("ogg")||end.equals("wav")){    
  76.         type = "audio/*";     
  77.       }    
  78.       elseif(end.equals("3gp")||end.equals("mp4")){    
  79.         type = "video/*";    
  80.       }    
  81.       elseif(end.equals("jpg")||end.equals("gif")||end.equals("png")||    
  82.       end.equals("jpeg")||end.equals("bmp")){    
  83.         type = "image/*";    
  84.       }    
  85.       elseif(end.equals("apk")){     
  86.         /* android.permission.INSTALL_PACKAGES */     
  87.         type = "application/vnd.android.package-archive";   
  88.       }  
  89. //      else if(end.equals("pptx")||end.equals("ppt")){
  90. //        type = "application/vnd.ms-powerpoint"; 
  91. //      }else if(end.equals("docx")||end.equals("doc")){
  92. //        type = "application/vnd.ms-word";
  93. //      }else if(end.equals("xlsx")||end.equals("xls")){
  94. //        type = "application/vnd.ms-excel";
  95. //      }
  96.       else{  
  97. //        /*如果無法直接開啟,就跳出軟體列表給使用者選擇 */  
  98.         type="*/*";  
  99.       }  
  100.       return type;  
  101.     }   </span>  
  1. <span style="font-family:Helvetica, Tahoma, Arial, sans-serif;">轉自:<a href="http://gundumw100.iteye.com/blog/1338645">http://gundumw100.iteye.com/blog/1338645</a>  
  2. </span>