|
|
@ -3,10 +3,8 @@ |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
package acr.browser.lightning.download; |
|
|
|
package acr.browser.lightning.download; |
|
|
|
|
|
|
|
|
|
|
|
import android.app.Activity; |
|
|
|
|
|
|
|
import android.app.DownloadManager; |
|
|
|
import android.app.DownloadManager; |
|
|
|
import android.content.ActivityNotFoundException; |
|
|
|
import android.content.ActivityNotFoundException; |
|
|
|
import android.content.ComponentName; |
|
|
|
|
|
|
|
import android.content.Context; |
|
|
|
import android.content.Context; |
|
|
|
import android.content.Intent; |
|
|
|
import android.content.Intent; |
|
|
|
import android.content.pm.PackageManager; |
|
|
|
import android.content.pm.PackageManager; |
|
|
@ -19,14 +17,17 @@ import android.util.Log; |
|
|
|
import android.webkit.CookieManager; |
|
|
|
import android.webkit.CookieManager; |
|
|
|
import android.webkit.URLUtil; |
|
|
|
import android.webkit.URLUtil; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import com.squareup.otto.Bus; |
|
|
|
|
|
|
|
|
|
|
|
import java.io.File; |
|
|
|
import java.io.File; |
|
|
|
import java.io.IOException; |
|
|
|
import java.io.IOException; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
import acr.browser.lightning.BuildConfig; |
|
|
|
import acr.browser.lightning.R; |
|
|
|
import acr.browser.lightning.R; |
|
|
|
|
|
|
|
import acr.browser.lightning.activity.MainActivity; |
|
|
|
import acr.browser.lightning.app.BrowserApp; |
|
|
|
import acr.browser.lightning.app.BrowserApp; |
|
|
|
|
|
|
|
import acr.browser.lightning.bus.BrowserEvents; |
|
|
|
import acr.browser.lightning.constant.Constants; |
|
|
|
import acr.browser.lightning.constant.Constants; |
|
|
|
import acr.browser.lightning.preference.PreferenceManager; |
|
|
|
|
|
|
|
import acr.browser.lightning.utils.Utils; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
/** |
|
|
|
* Handle download requests |
|
|
|
* Handle download requests |
|
|
@ -45,13 +46,13 @@ public class DownloadHandler { |
|
|
|
* Notify the host application a download should be done, or that the data |
|
|
|
* Notify the host application a download should be done, or that the data |
|
|
|
* should be streamed if a streaming viewer is available. |
|
|
|
* should be streamed if a streaming viewer is available. |
|
|
|
* |
|
|
|
* |
|
|
|
* @param activity Activity requesting the download. |
|
|
|
* @param context The context in which the download was requested. |
|
|
|
* @param url The full url to the content that should be downloaded |
|
|
|
* @param url The full url to the content that should be downloaded |
|
|
|
* @param userAgent User agent of the downloading application. |
|
|
|
* @param userAgent User agent of the downloading application. |
|
|
|
* @param contentDisposition Content-disposition http header, if present. |
|
|
|
* @param contentDisposition Content-disposition http header, if present. |
|
|
|
* @param mimetype The mimetype of the content reported by the server |
|
|
|
* @param mimetype The mimetype of the content reported by the server |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
public static void onDownloadStart(Activity activity, String url, String userAgent, |
|
|
|
public static void onDownloadStart(Context context, String url, String userAgent, |
|
|
|
String contentDisposition, String mimetype) { |
|
|
|
String contentDisposition, String mimetype) { |
|
|
|
// if we're dealing wih A/V content that's not explicitly marked
|
|
|
|
// if we're dealing wih A/V content that's not explicitly marked
|
|
|
|
// for download, check if it's streamable.
|
|
|
|
// for download, check if it's streamable.
|
|
|
@ -62,18 +63,17 @@ public class DownloadHandler { |
|
|
|
Intent intent = new Intent(Intent.ACTION_VIEW); |
|
|
|
Intent intent = new Intent(Intent.ACTION_VIEW); |
|
|
|
intent.setDataAndType(Uri.parse(url), mimetype); |
|
|
|
intent.setDataAndType(Uri.parse(url), mimetype); |
|
|
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); |
|
|
|
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); |
|
|
|
ResolveInfo info = activity.getPackageManager().resolveActivity(intent, |
|
|
|
ResolveInfo info = context.getPackageManager().resolveActivity(intent, |
|
|
|
PackageManager.MATCH_DEFAULT_ONLY); |
|
|
|
PackageManager.MATCH_DEFAULT_ONLY); |
|
|
|
if (info != null) { |
|
|
|
if (info != null) { |
|
|
|
ComponentName myName = activity.getComponentName(); |
|
|
|
|
|
|
|
// If we resolved to ourselves, we don't want to attempt to
|
|
|
|
// If we resolved to ourselves, we don't want to attempt to
|
|
|
|
// load the url only to try and download it again.
|
|
|
|
// load the url only to try and download it again.
|
|
|
|
if (!myName.getPackageName().equals(info.activityInfo.packageName) |
|
|
|
if (BuildConfig.APPLICATION_ID.equals(info.activityInfo.packageName) |
|
|
|
|| !myName.getClassName().equals(info.activityInfo.name)) { |
|
|
|
|| MainActivity.class.getName().equals(info.activityInfo.name)) { |
|
|
|
// someone (other than us) knows how to handle this mime
|
|
|
|
// someone (other than us) knows how to handle this mime
|
|
|
|
// type with this scheme, don't download.
|
|
|
|
// type with this scheme, don't download.
|
|
|
|
try { |
|
|
|
try { |
|
|
|
activity.startActivity(intent); |
|
|
|
context.startActivity(intent); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} catch (ActivityNotFoundException ex) { |
|
|
|
} catch (ActivityNotFoundException ex) { |
|
|
|
// Best behavior is to fall back to a download in this
|
|
|
|
// Best behavior is to fall back to a download in this
|
|
|
@ -82,8 +82,7 @@ public class DownloadHandler { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
onDownloadStartNoStream(activity, url, userAgent, contentDisposition, mimetype |
|
|
|
onDownloadStartNoStream(context, url, userAgent, contentDisposition, mimetype); |
|
|
|
); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// This is to work around the fact that java.net.URI throws Exceptions
|
|
|
|
// This is to work around the fact that java.net.URI throws Exceptions
|
|
|
@ -120,17 +119,17 @@ public class DownloadHandler { |
|
|
|
* Notify the host application a download should be done, even if there is a |
|
|
|
* Notify the host application a download should be done, even if there is a |
|
|
|
* streaming viewer available for thise type. |
|
|
|
* streaming viewer available for thise type. |
|
|
|
* |
|
|
|
* |
|
|
|
* @param activity Activity requesting the download. |
|
|
|
* @param context The context in which the download is requested. |
|
|
|
* @param url The full url to the content that should be downloaded |
|
|
|
* @param url The full url to the content that should be downloaded |
|
|
|
* @param userAgent User agent of the downloading application. |
|
|
|
* @param userAgent User agent of the downloading application. |
|
|
|
* @param contentDisposition Content-disposition http header, if present. |
|
|
|
* @param contentDisposition Content-disposition http header, if present. |
|
|
|
* @param mimetype The mimetype of the content reported by the server |
|
|
|
* @param mimetype The mimetype of the content reported by the server |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
/* package */ |
|
|
|
/* package */ |
|
|
|
private static void onDownloadStartNoStream(final Activity activity, String url, String userAgent, |
|
|
|
private static void onDownloadStartNoStream(final Context context, String url, String userAgent, |
|
|
|
String contentDisposition, String mimetype) { |
|
|
|
String contentDisposition, String mimetype) { |
|
|
|
|
|
|
|
final Bus eventBus = BrowserApp.getAppComponent().getBus(); |
|
|
|
String filename = URLUtil.guessFileName(url, contentDisposition, mimetype); |
|
|
|
final String filename = URLUtil.guessFileName(url, contentDisposition, mimetype); |
|
|
|
|
|
|
|
|
|
|
|
// Check to see if we have an SDCard
|
|
|
|
// Check to see if we have an SDCard
|
|
|
|
String status = Environment.getExternalStorageState(); |
|
|
|
String status = Environment.getExternalStorageState(); |
|
|
@ -140,14 +139,14 @@ public class DownloadHandler { |
|
|
|
|
|
|
|
|
|
|
|
// Check to see if the SDCard is busy, same as the music app
|
|
|
|
// Check to see if the SDCard is busy, same as the music app
|
|
|
|
if (status.equals(Environment.MEDIA_SHARED)) { |
|
|
|
if (status.equals(Environment.MEDIA_SHARED)) { |
|
|
|
msg = activity.getString(R.string.download_sdcard_busy_dlg_msg); |
|
|
|
msg = context.getString(R.string.download_sdcard_busy_dlg_msg); |
|
|
|
title = R.string.download_sdcard_busy_dlg_title; |
|
|
|
title = R.string.download_sdcard_busy_dlg_title; |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
msg = activity.getString(R.string.download_no_sdcard_dlg_msg, filename); |
|
|
|
msg = context.getString(R.string.download_no_sdcard_dlg_msg, filename); |
|
|
|
title = R.string.download_no_sdcard_dlg_title; |
|
|
|
title = R.string.download_no_sdcard_dlg_title; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
new AlertDialog.Builder(activity).setTitle(title) |
|
|
|
new AlertDialog.Builder(context).setTitle(title) |
|
|
|
.setIcon(android.R.drawable.ic_dialog_alert).setMessage(msg) |
|
|
|
.setIcon(android.R.drawable.ic_dialog_alert).setMessage(msg) |
|
|
|
.setPositiveButton(R.string.action_ok, null).show(); |
|
|
|
.setPositiveButton(R.string.action_ok, null).show(); |
|
|
|
return; |
|
|
|
return; |
|
|
@ -163,7 +162,7 @@ public class DownloadHandler { |
|
|
|
// This only happens for very bad urls, we want to catch the
|
|
|
|
// This only happens for very bad urls, we want to catch the
|
|
|
|
// exception here
|
|
|
|
// exception here
|
|
|
|
Log.e(TAG, "Exception while trying to parse url '" + url + '\'', e); |
|
|
|
Log.e(TAG, "Exception while trying to parse url '" + url + '\'', e); |
|
|
|
Utils.showSnackbar(activity, R.string.problem_download); |
|
|
|
eventBus.post(new BrowserEvents.ShowSnackBarMessage(R.string.problem_download)); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
@ -173,7 +172,7 @@ public class DownloadHandler { |
|
|
|
try { |
|
|
|
try { |
|
|
|
request = new DownloadManager.Request(uri); |
|
|
|
request = new DownloadManager.Request(uri); |
|
|
|
} catch (IllegalArgumentException e) { |
|
|
|
} catch (IllegalArgumentException e) { |
|
|
|
Utils.showSnackbar(activity, R.string.cannot_download); |
|
|
|
eventBus.post(new BrowserEvents.ShowSnackBarMessage(R.string.cannot_download)); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
request.setMimeType(mimetype); |
|
|
|
request.setMimeType(mimetype); |
|
|
@ -195,12 +194,12 @@ public class DownloadHandler { |
|
|
|
File dir = new File(downloadFolder.getPath()); |
|
|
|
File dir = new File(downloadFolder.getPath()); |
|
|
|
if (!dir.isDirectory() && !dir.mkdirs()) { |
|
|
|
if (!dir.isDirectory() && !dir.mkdirs()) { |
|
|
|
// Cannot make the directory
|
|
|
|
// Cannot make the directory
|
|
|
|
Utils.showSnackbar(activity, R.string.problem_location_download); |
|
|
|
eventBus.post(new BrowserEvents.ShowSnackBarMessage(R.string.problem_location_download)); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if (!isWriteAccessAvailable(downloadFolder)) { |
|
|
|
if (!isWriteAccessAvailable(downloadFolder)) { |
|
|
|
Utils.showSnackbar(activity, R.string.problem_location_download); |
|
|
|
eventBus.post(new BrowserEvents.ShowSnackBarMessage(R.string.problem_location_download)); |
|
|
|
return; |
|
|
|
return; |
|
|
|
} |
|
|
|
} |
|
|
|
request.setDestinationUri(Uri.parse(Constants.FILE + location + filename)); |
|
|
|
request.setDestinationUri(Uri.parse(Constants.FILE + location + filename)); |
|
|
@ -220,9 +219,9 @@ public class DownloadHandler { |
|
|
|
} |
|
|
|
} |
|
|
|
// We must have long pressed on a link or image to download it. We
|
|
|
|
// 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
|
|
|
|
// are not sure of the mimetype in this case, so do a head request
|
|
|
|
new FetchUrlMimeType(activity, request, addressString, cookies, userAgent).start(); |
|
|
|
new FetchUrlMimeType(context, request, addressString, cookies, userAgent).start(); |
|
|
|
} else { |
|
|
|
} else { |
|
|
|
final DownloadManager manager = (DownloadManager) activity |
|
|
|
final DownloadManager manager = (DownloadManager) context |
|
|
|
.getSystemService(Context.DOWNLOAD_SERVICE); |
|
|
|
.getSystemService(Context.DOWNLOAD_SERVICE); |
|
|
|
new Thread() { |
|
|
|
new Thread() { |
|
|
|
@Override |
|
|
|
@Override |
|
|
@ -232,15 +231,16 @@ public class DownloadHandler { |
|
|
|
} catch (IllegalArgumentException e) { |
|
|
|
} catch (IllegalArgumentException e) { |
|
|
|
// Probably got a bad URL or something
|
|
|
|
// Probably got a bad URL or something
|
|
|
|
e.printStackTrace(); |
|
|
|
e.printStackTrace(); |
|
|
|
Utils.showSnackbar(activity, R.string.cannot_download); |
|
|
|
eventBus.post(new BrowserEvents.ShowSnackBarMessage(R.string.cannot_download)); |
|
|
|
} catch (SecurityException e) { |
|
|
|
} catch (SecurityException e) { |
|
|
|
// TODO write a download utility that downloads files rather than rely on the system
|
|
|
|
// TODO write a download utility that downloads files rather than rely on the system
|
|
|
|
// because the system can only handle Environment.getExternal... as a path
|
|
|
|
// because the system can only handle Environment.getExternal... as a path
|
|
|
|
Utils.showSnackbar(activity, R.string.problem_location_download); |
|
|
|
eventBus.post(new BrowserEvents.ShowSnackBarMessage(R.string.problem_location_download)); |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
}.start(); |
|
|
|
}.start(); |
|
|
|
Utils.showSnackbar(activity, activity.getString(R.string.download_pending) + ' ' + filename); |
|
|
|
eventBus.post(new BrowserEvents.ShowSnackBarMessage( |
|
|
|
|
|
|
|
context.getString(R.string.download_pending) + ' ' + filename)); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|