如何从webview Android下载文件?

我下面的代码加载的网页罚款和search后,当我点击下载链接崩溃的歌曲。 关于如何让下载pipe理器使用webview,没有太多的教程。 我究竟做错了什么?

import java.io.File; import android.app.Activity; import android.app.DownloadManager; import android.content.Context; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.webkit.WebView; import android.webkit.WebViewClient; public class List1 extends Activity { WebView ourBrow; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // Use a custom layout file setContentView(R.layout.list1); final DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE); final File destinationDir = new File (Environment.getExternalStorageDirectory(), getPackageName()); if (!destinationDir.exists()) { destinationDir.mkdir(); // Don't forget to make the directory if it's not there } ourBrow = (WebView) findViewById(R.id.wvBrowser); ourBrow.getSettings().setJavaScriptEnabled(true); ourBrow.setInitialScale(50); ourBrow.getSettings().setUseWideViewPort(true); ourBrow.setVerticalScrollBarEnabled(false); ourBrow.setHorizontalScrollBarEnabled(false); ourBrow.loadUrl("http://www.degjo.com"); ourBrow.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading (WebView view, String url) { boolean shouldOverride = false; // We only want to handle requests for mp3 files, everything else the webview // can handle normally if (url.endsWith(".mp3")) { shouldOverride = true; Uri source = Uri.parse(url); // Make a new request pointing to the mp3 url DownloadManager.Request request = new DownloadManager.Request(source); // Use the same file name for the destination File destinationFile = new File (destinationDir, source.getLastPathSegment()); request.setDestinationUri(Uri.fromFile(destinationFile)); // Add it to the manager manager.enqueue(request); } return shouldOverride; } }); } } 

logcat的

 02-18 19:45:44.891: E/AndroidRuntime(357): at android.content.ContentProviderProxy.insert(ContentProviderNative.java:408) 02-18 19:45:44.891: E/AndroidRuntime(357): at android.content.ContentResolver.insert(ContentResolver.java:604) 02-18 19:45:44.891: E/AndroidRuntime(357): at android.app.DownloadManager.enqueue(DownloadManager.java:750) 02-18 19:45:44.891: E/AndroidRuntime(357): at com.example.androidbuttonsactivities.List1$1.shouldOverrideUrlLoading(List1.java:78) 02-18 19:45:44.891: E/AndroidRuntime(357): at android.webkit.CallbackProxy.uiOverrideUrlLoading(CallbackProxy.java:216) 02-18 19:45:44.891: E/AndroidRuntime(357): at android.webkit.CallbackProxy.handleMessage(CallbackProxy.java:323) 02-18 19:45:44.891: E/AndroidRuntime(357): at android.os.Handler.dispatchMessage(Handler.java:99) 02-18 19:45:44.891: E/AndroidRuntime(357): at android.os.Looper.loop(Looper.java:123) 02-18 19:45:44.891: E/AndroidRuntime(357): at android.app.ActivityThread.main(ActivityThread.java:3683) 02-18 19:45:44.891: E/AndroidRuntime(357): at java.lang.reflect.Method.invokeNative(Native Method) 02-18 19:45:44.891: E/AndroidRuntime(357): at java.lang.reflect.Method.invoke(Method.java:507) 02-18 19:45:44.891: E/AndroidRuntime(357): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839) 02-18 19:45:44.891: E/AndroidRuntime(357): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597) 02-18 19:45:44.891: E/AndroidRuntime(357): at dalvik.system.NativeStart.main(Native Method) 02-18 19:45:48.401: I/Process(357): Sending signal. PID: 357 SIG: 9 

Solutions Collecting From Web of "如何从webview Android下载文件?"

这可能是取决于Android版本的问题,下面的代码将在2.3 +版本上成功工作,检查了这一点,

 ourBrow.setWebViewClient(new WebViewClient() { @Override public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) { Log.d("WEB_VIEW_TEST", "error code:" + errorCode + " - " + description); } @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { // handle different requests for different type of files // this example handles downloads requests for .apk and .mp3 files // everything else the webview can handle normally if (url.endsWith(".apk")) { Uri source = Uri.parse(url); // Make a new request pointing to the .apk url DownloadManager.Request request = new DownloadManager.Request(source); // appears the same in Notification bar while downloading request.setDescription("Description for the DownloadManager Bar"); request.setTitle("YourApp.apk"); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) { request.allowScanningByMediaScanner(); request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); } // save the file in the "Downloads" folder of SDCARD request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "SmartPigs.apk"); // get download service and enqueue file DownloadManager manager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE); manager.enqueue(request); } else if(url.endsWith(".mp3")) { // if the link points to an .mp3 resource do something else } // if there is a link to anything else than .apk or .mp3 load the URL in the webview else view.loadUrl(url); return true; } }); 

您是否在清单文件中添加了DownloadManager权限?

 <uses-permission android:name="android.permission.ACCESS_DOWNLOAD_MANAGER"/> 

– – -编辑 – – –

我正在复制一些代码片段,以供您从Android股票浏览器开始下载任务时参考:

 import android.net.WebAddress; // java.net.URI is a lot stricter than KURL so we have to encode some // extra characters. Fix for b 2538060 and b 1634719 WebAddress webAddress; try { webAddress = new WebAddress(url); webAddress.setPath(encodePath(webAddress.getPath())); } catch (Exception e) { // This only happens for very bad urls, we want to chatch the // exception here Log.e(LOGTAG, "Exception trying to parse url:" + url); return; } String addressString = webAddress.toString(); Uri uri = Uri.parse(addressString); final DownloadManager.Request request; try { request = new DownloadManager.Request(uri); } catch (IllegalArgumentException e) { Toast.makeText(activity, R.string.cannot_download, Toast.LENGTH_SHORT).show(); return; } request.setMimeType(mimetype); // set downloaded file destination to /sdcard/Download. // or, should it be set to one of several Environment.DIRECTORY* dirs depending on mimetype? request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename); // let this downloaded file be scanned by MediaScanner - so that it can // show up in Gallery app, for example. request.allowScanningByMediaScanner(); request.setDescription(webAddress.getHost()); // XXX: Have to use the old url since the cookies were stored using the // old percent-encoded url. String cookies = CookieManager.getInstance().getCookie(url, privateBrowsing); request.addRequestHeader("cookie", cookies); request.addRequestHeader("User-Agent", userAgent); request.addRequestHeader("Referer", referer); request.setNotificationVisibility( DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); if (mimetype == null) { if (TextUtils.isEmpty(addressString)) { return; } // We must have long pressed on a link or image to download it. We // are not sure of the mimetype in this case, so do a head request new FetchUrlMimeType(activity, request, addressString, cookies, userAgent).start(); } else { final DownloadManager manager = (DownloadManager) activity.getSystemService(Context.DOWNLOAD_SERVICE); new Thread("Browser download") { public void run() { manager.enqueue(request); } }.start(); } Toast.makeText(activity, R.string.download_pending, Toast.LENGTH_SHORT) .show(); 

试试这个

 mWebView.setDownloadListener(new DownloadListener() { @Override public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) { DownloadManager.Request request = new DownloadManager.Request( Uri.parse(url)); request.allowScanningByMediaScanner(); request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); //Notify client once download is completed! request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "Name of your downloadble file goes here, example: Mathematics II "); DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE); dm.enqueue(request); Toast.makeText(getApplicationContext(), "Downloading File", //To notify the Client that the file is being downloaded Toast.LENGTH_LONG).show(); } }); 

另外,不要忘记将下面的代码添加到manifest.xml文件中,这非常重要,它会授予它保存到存储的权限,就像为weview提供Internet权限一样。

 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />