一、設置WebView的DownloadListener:
webView.setDownloadListener(new MyWebViewDownLoadListener());
html
二、實現MyWebViewDownLoadListener這個類,具體能夠以下這樣:java
private class MyWebViewDownLoadListener implements DownloadListener{ @Override public void onDownloadStart (String url, String userAgent, String contentDisposition, String mimetype, long contentLength) { Log.i("tag", "url="+url); Log.i("tag", "userAgent="+userAgent); Log.i("tag", "contentDisposition="+contentDisposition); Log.i("tag", "mimetype="+mimetype); Log.i("tag", "contentLength="+contentLength); Uri uri = Uri.parse(url); Intent intent = new Intent(Intent.ACTION_VIEW, uri); startActivity(intent); } }
這只是調用系統中已經內置的瀏覽器進行下載,尚未WebView自己進行的文件下載,不過,這也基本上知足咱們的應用場景了。
我在項目中的運用
項目要求這樣:
1,須要使用WebView加載一個網頁;
2,網頁中有文件下載的連接,點擊後須要下載文件到SDcard;
3,而後自動打開文件;
下面是具體解決辦法
第一步,對WebView進行一系列設置。android
WebView webview=(WebView)layout.findViewById(R.id.webview); webview.getSettings().setJavaScriptEnabled(true); webview.setWebChromeClient(new MyWebChromeClient()); webview.requestFocus(); //webview.loadUrl("file:///android_asset/risktest.html"); webview.loadUrl(jcrs_sub.get(position).addr); // 設置web視圖客戶端 webview.setWebViewClient(new MyWebViewClient()); webview.setDownloadListener(new MyWebViewDownLoadListener()); //內部類 public class MyWebViewClient extends WebViewClient { // 若是頁面中連接,若是但願點擊連接繼續在當前browser中響應, // 而不是新開Android的系統browser中響應該連接,必須覆蓋 webview的WebViewClient對象。 public boolean shouldOverviewUrlLoading(WebView view, String url) { L.i("shouldOverviewUrlLoading"); view.loadUrl(url); return true; } public void onPageStarted(WebView view, String url, Bitmap favicon) { L.i("onPageStarted"); showProgress(); } public void onPageFinished(WebView view, String url) { L.i("onPageFinished"); closeProgress(); } public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { L.i("onReceivedError"); closeProgress(); } } // 若是不作任何處理,瀏覽網頁,點擊系統「Back」鍵,整個Browser會調用finish()而結束自身, // 若是但願瀏覽的網 頁回退而不是推出瀏覽器,須要在當前Activity中處理並消費掉該Back事件。 public boolean onKeyDown(int keyCode, KeyEvent event) { // if((keyCode==KeyEvent.KEYCODE_BACK)&&webview.canGoBack()){ // webview.goBack(); // return true; // } return false; }
第二步,起線程開始下載文件。web
//內部類 private class MyWebViewDownLoadListener implements DownloadListener { @Override public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype,long contentLength) { if(!Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ Toast t=Toast.makeText(mContext, "須要SD卡。", Toast.LENGTH_LONG); t.setGravity(Gravity.CENTER, 0, 0); t.show(); return; } DownloaderTask task=new DownloaderTask(); task.execute(url); } } //內部類 private class DownloaderTask extends AsyncTask<String, Void, String> { public DownloaderTask() { } @Override protected String doInBackground(String... params) { // TODO Auto-generated method stub String url=params[0]; // Log.i("tag", "url="+url); String fileName=url.substring(url.lastIndexOf("/")+1); fileName=URLDecoder.decode(fileName); Log.i("tag", "fileName="+fileName); File directory=Environment.getExternalStorageDirectory(); File file=new File(directory,fileName); if(file.exists()){ Log.i("tag", "The file has already exists."); return fileName; } try { HttpClient client = new DefaultHttpClient(); //client.getParams().setIntParameter("http.socket.timeout",3000);//設置超時 HttpGet get = new HttpGet(url); HttpResponse response = client.execute(get); if(HttpStatus.SC_OK==response.getStatusLine().getStatusCode()){ HttpEntity entity = response.getEntity(); InputStream input = entity.getContent(); writeToSDCard(fileName,input); input.close(); // entity.consumeContent(); return fileName; }else{ return null; } } catch (Exception e) { e.printStackTrace(); return null; } } @Override protected void onCancelled() { // TODO Auto-generated method stub super.onCancelled(); } @Override protected void onPostExecute(String result) { // TODO Auto-generated method stub super.onPostExecute(result); closeProgressDialog(); if(result==null){ Toast t=Toast.makeText(mContext, "鏈接錯誤!請稍後再試!", Toast.LENGTH_LONG); t.setGravity(Gravity.CENTER, 0, 0); t.show(); return; } Toast t=Toast.makeText(mContext, "已保存到SD卡。", Toast.LENGTH_LONG); t.setGravity(Gravity.CENTER, 0, 0); t.show(); File directory=Environment.getExternalStorageDirectory(); File file=new File(directory,result); Log.i("tag", "Path="+file.getAbsolutePath()); Intent intent = getFileIntent(file); startActivity(intent); } @Override protected void onPreExecute() { // TODO Auto-generated method stub super.onPreExecute(); showProgressDialog(); } @Override protected void onProgressUpdate(Void... values) { // TODO Auto-generated method stub super.onProgressUpdate(values); } }
第三步,實現一些工具方法。 瀏覽器
<span style="font-family:Helvetica, Tahoma, Arial, sans-serif;">private ProgressDialog mDialog; private void showProgressDialog(){ if(mDialog==null){ mDialog = new ProgressDialog(mContext); mDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);//設置風格爲圓形進度條 mDialog.setMessage("正在加載 ,請等待..."); mDialog.setIndeterminate(false);//設置進度條是否爲不明確 mDialog.setCancelable(true);//設置進度條是否能夠按退回鍵取消 mDialog.setCanceledOnTouchOutside(false); mDialog.setOnDismissListener(new OnDismissListener() { @Override public void onDismiss(DialogInterface dialog) { // TODO Auto-generated method stub mDialog=null; } }); mDialog.show(); } } private void closeProgressDialog(){ if(mDialog!=null){ mDialog.dismiss(); mDialog=null; } } public Intent getFileIntent(File file){ // Uri uri = Uri.parse("http://m.ql18.com.cn/hpf10/1.pdf"); Uri uri = Uri.fromFile(file); String type = getMIMEType(file); Log.i("tag", "type="+type); Intent intent = new Intent("android.intent.action.VIEW"); intent.addCategory("android.intent.category.DEFAULT"); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); intent.setDataAndType(uri, type); return intent; } public void writeToSDCard(String fileName,InputStream input){ if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ File directory=Environment.getExternalStorageDirectory(); File file=new File(directory,fileName); // if(file.exists()){ // Log.i("tag", "The file has already exists."); // return; // } try { FileOutputStream fos = new FileOutputStream(file); byte[] b = new byte[2048]; int j = 0; while ((j = input.read(b)) != -1) { fos.write(b, 0, j); } fos.flush(); fos.close(); } catch (FileNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } }else{ Log.i("tag", "NO SDCard."); } } private String getMIMEType(File f){ String type=""; String fName=f.getName(); /* 取得擴展名 */ String end=fName.substring(fName.lastIndexOf(".")+1,fName.length()).toLowerCase(); /* 依擴展名的類型決定MimeType */ if(end.equals("pdf")){ type = "application/pdf";// } else if(end.equals("m4a")||end.equals("mp3")||end.equals("mid")|| end.equals("xmf")||end.equals("ogg")||end.equals("wav")){ type = "audio/*"; } else if(end.equals("3gp")||end.equals("mp4")){ type = "video/*"; } else if(end.equals("jpg")||end.equals("gif")||end.equals("png")|| end.equals("jpeg")||end.equals("bmp")){ type = "image/*"; } else if(end.equals("apk")){ /* android.permission.INSTALL_PACKAGES */ type = "application/vnd.android.package-archive"; } // else if(end.equals("pptx")||end.equals("ppt")){ // type = "application/vnd.ms-powerpoint"; // }else if(end.equals("docx")||end.equals("doc")){ // type = "application/vnd.ms-word"; // }else if(end.equals("xlsx")||end.equals("xls")){ // type = "application/vnd.ms-excel"; // } else{ // /*若是沒法直接打開,就跳出軟件列表給用戶選擇 */ type="*/*"; } return type; } </span>