以下のコードは、URLページを正常にロードし、ダウンロードリンクをクリックしたときに曲を検索した後、クラッシュします。ダウンロードマネージャーで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
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"/>
----- EDIT -----
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にインターネットアクセス許可を与えるのと同じように、ストレージに保存するアクセス許可を与えることを非常に重要にします。
<uses-permission Android:name="Android.permission.WRITE_EXTERNAL_STORAGE" />