Android WebView realizes file download function

  • 2021-09-11 21:15:17
  • OfStack

The WebView control invokes the corresponding WEB page for presentation. When there is a download link on the page, there is no response at all when clicking on it. It turns out that WebView does not open the function of file download by default. If you want to realize the function of file download, you need to set DownloadListener of WebView and realize the file download by implementing your own DownloadListener. The specific operation is as follows:

1. Set DownloadListener of WebView:


 webView.setDownloadListener(new MyWebViewDownLoadListener());

2. Implement the MyWebViewDownLoadListener class as follows:


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

This is just calling the browser built in the system to download, and there is no file download for WebView itself. However, this basically meets our application scenarios.

My application in the project

The project requires this:
1. Need to load a web page using WebView;
2. There is a link to download files in the webpage. After clicking, you need to download files to SDcard;;
3. Then automatically open the file;

Here are the specific solutions
Step 1, set up WebView in series 1.


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); 
    //  Settings web View client  
    webview.setWebViewClient(new MyWebViewClient()); 
    webview.setDownloadListener(new MyWebViewDownLoadListener()); 
 
// Inner class  
public class MyWebViewClient extends WebViewClient { 
  //  If there is a link in the page, if you want to click the link to continue in the current browser In the response,  
  //  Instead of opening new ones Android System of browser In response to the link, you must override the  webview Adj. WebViewClient Object.  
  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(); 
  } 
 } 
 
//  If you don't do anything, browse the web page and click the system " Back "Key, the whole Browser Will call finish() And end yourself,  
 //  If the web you want to browse   Page rollback instead of pushing out the browser, which needs to be implemented in the current Activity Processes and consumes the Back Events.  
 public boolean onKeyDown(int keyCode, KeyEvent event) { 
  // if((keyCode==KeyEvent.KEYCODE_BACK)&&webview.canGoBack()){ 
  // webview.goBack(); 
  // return true; 
  // } 
  return false; 
} 

Step 2, start the thread to start downloading files.


// Inner class  
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, " Need SD Card. ", Toast.LENGTH_LONG); 
    t.setGravity(Gravity.CENTER, 0, 0); 
    t.show(); 
    return; 
   } 
   DownloaderTask task=new DownloaderTask(); 
   task.execute(url); 
  } 
 
 } 
 // Inner class  
 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);// Set timeout  
    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, " Connection error! Please try again later! ", Toast.LENGTH_LONG); 
    t.setGravity(Gravity.CENTER, 0, 0); 
    t.show(); 
    return; 
   } 
    
   Toast t=Toast.makeText(mContext, " Saved to SD Card. ", 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); 
  } 
 
} 

Step 3, implement some tool methods.


private ProgressDialog mDialog; 
 private void showProgressDialog(){ 
  if(mDialog==null){ 
   mDialog = new ProgressDialog(mContext); 
   mDialog.setProgressStyle(ProgressDialog.STYLE_SPINNER);// Set the style to round progress bar  
   mDialog.setMessage(" Loading   Please wait ..."); 
   mDialog.setIndeterminate(false);// Setting the progress bar to be ambiguous  
   mDialog.setCancelable(true);// Set whether the progress bar can be cancelled by pressing the Back button  
   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(); 
  /*  Get Extensions  */ 
  String end=fName.substring(fName.lastIndexOf(".")+1,fName.length()).toLowerCase(); 
  
  /*  Depending on the type of extension 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{ 
//  /* If it can't be opened directly, it will jump out of the software list and give the user a choice  */ 
  type="*/*"; 
  } 
  return type; 
} 

Related articles: