zoukankan      html  css  js  c++  java
  • WebView中实现文件下载功能

     

    WebView控制调用相应的WEB页面进行展示。当碰到页面有下载链接的时候,点击上去是一点反应都没有的。原来是因为WebView默认没有开启文件下载的功能,如果要实现文件下载的功能,需要设置WebView的DownloadListener,通过实现自己的DownloadListener来实现文件的下载。具体操作如下: 

    1、设置WebView的DownloadListener: 
        webView.setDownloadListener(new MyWebViewDownLoadListener()); 

    2、实现MyWebViewDownLoadListener这个类,具体可以如下这样:  

     

    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);              

            }   

        }  


     

    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进行一系列设置。 

    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;   

        }  


     

    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;  

        }  



    第二步,起线程开始下载文件。 

     

    //内部类   

    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);   

            }    

        }   

    [java]view plain copy

    //内部类  

    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);  

            }   

        }   


    第三步,实现一些工具方法。 

    Java代码 复制代码收藏代码

    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;   

        }   

     

     

  • 相关阅读:
    理解Express express.static 和 __direname 及 __firename的含义
    HTTP请求中 request payload 和 formData 区别?
    POST提交数据之---Content-Type的理解;
    前端域名访问页面中的一些配置项
    使用Nginx来解决跨域的问题
    vue-resource get/post请求如何携带cookie的问题
    socket实现聊天功能(二)
    go语言之进阶篇通过结构体生成json
    go语言之进阶篇JSON处理
    go语言之进阶篇正则表达式
  • 原文地址:https://www.cnblogs.com/dubo-/p/5582595.html
Copyright © 2011-2022 走看看