Browse Source

Fixed bugs in downloading preventing some files from being properly opened

master
Anthony Restaino 8 years ago
parent
commit
6319503973
  1. 42
      app/src/main/java/acr/browser/lightning/download/DownloadHandler.java
  2. 2
      app/src/main/java/acr/browser/lightning/download/FetchUrlMimeType.java
  3. 64
      app/src/main/java/acr/browser/lightning/download/LightningDownloadListener.java
  4. 32
      app/src/main/java/acr/browser/lightning/utils/Utils.java

42
app/src/main/java/acr/browser/lightning/download/DownloadHandler.java

@ -19,6 +19,7 @@ import android.support.v7.app.AlertDialog;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import android.webkit.CookieManager; import android.webkit.CookieManager;
import android.webkit.MimeTypeMap;
import android.webkit.URLUtil; import android.webkit.URLUtil;
import com.squareup.otto.Bus; import com.squareup.otto.Bus;
@ -44,9 +45,17 @@ public class DownloadHandler {
private static final String COOKIE_REQUEST_HEADER = "Cookie"; private static final String COOKIE_REQUEST_HEADER = "Cookie";
public static final String DEFAULT_DOWNLOAD_PATH = public static final String DEFAULT_DOWNLOAD_PATH =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
.getPath(); .getPath();
@Nullable
public static String guessFileExtension(@NonNull String filename) {
int lastIndex = filename.lastIndexOf('.') + 1;
if (lastIndex > 0 && filename.length() > lastIndex) {
return filename.substring(lastIndex, filename.length());
}
return null;
}
/** /**
* 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
@ -60,10 +69,16 @@ public class DownloadHandler {
*/ */
public static void onDownloadStart(@NonNull Context context, @NonNull PreferenceManager manager, String url, String userAgent, public static void onDownloadStart(@NonNull Context context, @NonNull PreferenceManager manager, String url, String userAgent,
@Nullable String contentDisposition, String mimetype) { @Nullable String contentDisposition, String mimetype) {
Log.d(TAG, "DOWNLOAD: Trying to download from URL: " + url);
Log.d(TAG, "DOWNLOAD: Content disposition: " + contentDisposition);
Log.d(TAG, "DOWNLOAD: Mimetype: " + mimetype);
Log.d(TAG, "DOWNLOAD: User agent: " + userAgent);
// 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.
if (contentDisposition == null if (contentDisposition == null
|| !contentDisposition.regionMatches(true, 0, "attachment", 0, 10)) { || !contentDisposition.regionMatches(true, 0, "attachment", 0, 10)) {
// query the package manager to see if there's a registered handler // query the package manager to see if there's a registered handler
// that matches. // that matches.
Intent intent = new Intent(Intent.ACTION_VIEW); Intent intent = new Intent(Intent.ACTION_VIEW);
@ -75,12 +90,12 @@ public class DownloadHandler {
intent.setSelector(null); intent.setSelector(null);
} }
ResolveInfo info = context.getPackageManager().resolveActivity(intent, ResolveInfo info = context.getPackageManager().resolveActivity(intent,
PackageManager.MATCH_DEFAULT_ONLY); PackageManager.MATCH_DEFAULT_ONLY);
if (info != null) { if (info != null) {
// 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 (BuildConfig.APPLICATION_ID.equals(info.activityInfo.packageName) if (BuildConfig.APPLICATION_ID.equals(info.activityInfo.packageName)
|| MainActivity.class.getName().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 {
@ -160,8 +175,8 @@ public class DownloadHandler {
} }
Dialog dialog = new AlertDialog.Builder(context).setTitle(title) Dialog dialog = 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();
BrowserDialog.setDialogSize(context, dialog); BrowserDialog.setDialogSize(context, dialog);
return; return;
} }
@ -189,11 +204,10 @@ public class DownloadHandler {
eventBus.post(new BrowserEvents.ShowSnackBarMessage(R.string.cannot_download)); eventBus.post(new BrowserEvents.ShowSnackBarMessage(R.string.cannot_download));
return; return;
} }
request.setMimeType(mimetype);
// set downloaded file destination to /sdcard/Download. // set downloaded file destination to /sdcard/Download.
// or, should it be set to one of several Environment.DIRECTORY* dirs // or, should it be set to one of several Environment.DIRECTORY* dirs
// depending on mimetype? // depending on mimetype?
String location = preferences.getDownloadDirectory(); String location = preferences.getDownloadDirectory();
Uri downloadFolder; Uri downloadFolder;
location = addNecessarySlashes(location); location = addNecessarySlashes(location);
@ -210,6 +224,9 @@ public class DownloadHandler {
eventBus.post(new BrowserEvents.ShowSnackBarMessage(R.string.problem_location_download)); eventBus.post(new BrowserEvents.ShowSnackBarMessage(R.string.problem_location_download));
return; return;
} }
String newMimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(guessFileExtension(filename));
Log.d(TAG, "New mimetype: " + newMimeType);
request.setMimeType(newMimeType);
request.setDestinationUri(Uri.parse(Constants.FILE + location + filename)); request.setDestinationUri(Uri.parse(Constants.FILE + location + filename));
// let this downloaded file be scanned by MediaScanner - so that it can // let this downloaded file be scanned by MediaScanner - so that it can
// show up in Gallery app, for example. // show up in Gallery app, for example.
@ -221,6 +238,8 @@ public class DownloadHandler {
String cookies = CookieManager.getInstance().getCookie(url); String cookies = CookieManager.getInstance().getCookie(url);
request.addRequestHeader(COOKIE_REQUEST_HEADER, cookies); request.addRequestHeader(COOKIE_REQUEST_HEADER, cookies);
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
//noinspection VariableNotUsedInsideIf
if (mimetype == null) { if (mimetype == null) {
Log.d(TAG, "Mimetype is null"); Log.d(TAG, "Mimetype is null");
if (TextUtils.isEmpty(addressString)) { if (TextUtils.isEmpty(addressString)) {
@ -232,7 +251,7 @@ public class DownloadHandler {
} else { } else {
Log.d(TAG, "Valid mimetype, attempting to download"); Log.d(TAG, "Valid mimetype, attempting to download");
final DownloadManager manager = (DownloadManager) context final DownloadManager manager = (DownloadManager) context
.getSystemService(Context.DOWNLOAD_SERVICE); .getSystemService(Context.DOWNLOAD_SERVICE);
try { try {
manager.enqueue(request); manager.enqueue(request);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException e) {
@ -245,9 +264,8 @@ public class DownloadHandler {
eventBus.post(new BrowserEvents.ShowSnackBarMessage(R.string.problem_location_download)); eventBus.post(new BrowserEvents.ShowSnackBarMessage(R.string.problem_location_download));
} }
eventBus.post(new BrowserEvents.ShowSnackBarMessage( eventBus.post(new BrowserEvents.ShowSnackBarMessage(
context.getString(R.string.download_pending) + ' ' + filename)); context.getString(R.string.download_pending) + ' ' + filename));
} }
} }
private static final String sFileName = "test"; private static final String sFileName = "test";

2
app/src/main/java/acr/browser/lightning/download/FetchUrlMimeType.java

@ -95,7 +95,7 @@ class FetchUrlMimeType extends Thread {
if (mimeType.equalsIgnoreCase("text/plain") if (mimeType.equalsIgnoreCase("text/plain")
|| mimeType.equalsIgnoreCase("application/octet-stream")) { || mimeType.equalsIgnoreCase("application/octet-stream")) {
String newMimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension( String newMimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
MimeTypeMap.getFileExtensionFromUrl(mUri)); DownloadHandler.guessFileExtension(mUri));
if (newMimeType != null) { if (newMimeType != null) {
mRequest.setMimeType(newMimeType); mRequest.setMimeType(newMimeType);
} }

64
app/src/main/java/acr/browser/lightning/download/LightningDownloadListener.java

@ -38,40 +38,40 @@ public class LightningDownloadListener implements DownloadListener {
public void onDownloadStart(final String url, final String userAgent, public void onDownloadStart(final String url, final String userAgent,
final String contentDisposition, final String mimetype, long contentLength) { final String contentDisposition, final String mimetype, long contentLength) {
PermissionsManager.getInstance().requestPermissionsIfNecessaryForResult(mActivity, PermissionsManager.getInstance().requestPermissionsIfNecessaryForResult(mActivity,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE},
new PermissionsResultAction() { new PermissionsResultAction() {
@Override @Override
public void onGranted() { public void onGranted() {
String fileName = URLUtil.guessFileName(url, contentDisposition, mimetype); String fileName = URLUtil.guessFileName(url, contentDisposition, mimetype);
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() { DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int which) { public void onClick(DialogInterface dialog, int which) {
switch (which) { switch (which) {
case DialogInterface.BUTTON_POSITIVE: case DialogInterface.BUTTON_POSITIVE:
DownloadHandler.onDownloadStart(mActivity, mPreferenceManager, url, userAgent, DownloadHandler.onDownloadStart(mActivity, mPreferenceManager, url, userAgent,
contentDisposition, mimetype); contentDisposition, mimetype);
break; break;
case DialogInterface.BUTTON_NEGATIVE: case DialogInterface.BUTTON_NEGATIVE:
break; break;
}
} }
}; }
};
AlertDialog.Builder builder = new AlertDialog.Builder(mActivity); // dialog AlertDialog.Builder builder = new AlertDialog.Builder(mActivity); // dialog
Dialog dialog = builder.setTitle(fileName) Dialog dialog = builder.setTitle(fileName)
.setMessage(mActivity.getResources().getString(R.string.dialog_download)) .setMessage(mActivity.getResources().getString(R.string.dialog_download))
.setPositiveButton(mActivity.getResources().getString(R.string.action_download), .setPositiveButton(mActivity.getResources().getString(R.string.action_download),
dialogClickListener) dialogClickListener)
.setNegativeButton(mActivity.getResources().getString(R.string.action_cancel), .setNegativeButton(mActivity.getResources().getString(R.string.action_cancel),
dialogClickListener).show(); dialogClickListener).show();
BrowserDialog.setDialogSize(mActivity, dialog); BrowserDialog.setDialogSize(mActivity, dialog);
Log.i(Constants.TAG, "Downloading" + fileName); Log.i(Constants.TAG, "Downloading: " + fileName);
} }
@Override @Override
public void onDenied(String permission) { public void onDenied(String permission) {
//TODO show message //TODO show message
} }
}); });
} }
} }

32
app/src/main/java/acr/browser/lightning/utils/Utils.java

@ -74,12 +74,12 @@ public final class Utils {
public static void downloadFile(final Activity activity, final PreferenceManager manager, final String url, public static void downloadFile(final Activity activity, final PreferenceManager manager, final String url,
final String userAgent, final String contentDisposition) { final String userAgent, final String contentDisposition) {
PermissionsManager.getInstance().requestPermissionsIfNecessaryForResult(activity, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, PermissionsManager.getInstance().requestPermissionsIfNecessaryForResult(activity, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE}, new PermissionsResultAction() { Manifest.permission.WRITE_EXTERNAL_STORAGE}, new PermissionsResultAction() {
@Override @Override
public void onGranted() { public void onGranted() {
String fileName = URLUtil.guessFileName(url, null, null); String fileName = URLUtil.guessFileName(url, null, null);
DownloadHandler.onDownloadStart(activity, manager, url, userAgent, contentDisposition, null); DownloadHandler.onDownloadStart(activity, manager, url, userAgent, contentDisposition, null);
Log.i(Constants.TAG, "Downloading" + fileName); Log.i(Constants.TAG, "Downloading: " + fileName);
} }
@Override @Override
@ -124,13 +124,13 @@ public final class Utils {
AlertDialog.Builder builder = new AlertDialog.Builder(activity); AlertDialog.Builder builder = new AlertDialog.Builder(activity);
builder.setTitle(title); builder.setTitle(title);
builder.setMessage(message) builder.setMessage(message)
.setCancelable(true) .setCancelable(true)
.setPositiveButton(activity.getResources().getString(R.string.action_ok), .setPositiveButton(activity.getResources().getString(R.string.action_ok),
new DialogInterface.OnClickListener() { new DialogInterface.OnClickListener() {
@Override @Override
public void onClick(DialogInterface dialog, int id) { public void onClick(DialogInterface dialog, int id) {
} }
}); });
AlertDialog alert = builder.create(); AlertDialog alert = builder.create();
alert.show(); alert.show();
BrowserDialog.setDialogSize(activity, alert); BrowserDialog.setDialogSize(activity, alert);
@ -253,7 +253,7 @@ public final class Utils {
int padding = Utils.dpToPx(4); int padding = Utils.dpToPx(4);
Bitmap paddedBitmap = Bitmap.createBitmap(bitmap.getWidth() + padding, bitmap.getHeight() Bitmap paddedBitmap = Bitmap.createBitmap(bitmap.getWidth() + padding, bitmap.getHeight()
+ padding, Bitmap.Config.ARGB_8888); + padding, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(paddedBitmap); Canvas canvas = new Canvas(paddedBitmap);
canvas.drawARGB(0x00, 0x00, 0x00, 0x00); // this represents white color canvas.drawARGB(0x00, 0x00, 0x00, 0x00); // this represents white color
@ -297,10 +297,10 @@ public final class Utils {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + '_'; String imageFileName = "JPEG_" + timeStamp + '_';
File storageDir = Environment File storageDir = Environment
.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
return File.createTempFile(imageFileName, /* prefix */ return File.createTempFile(imageFileName, /* prefix */
".jpg", /* suffix */ ".jpg", /* suffix */
storageDir /* directory */ storageDir /* directory */
); );
} }
@ -374,9 +374,9 @@ public final class Utils {
paint.setDither(true); paint.setDither(true);
if (withShader) { if (withShader) {
paint.setShader(new LinearGradient(0, 0.9f * canvas.getHeight(), paint.setShader(new LinearGradient(0, 0.9f * canvas.getHeight(),
0, canvas.getHeight(), 0, canvas.getHeight(),
color, mixTwoColors(Color.BLACK, color, 0.5f), color, mixTwoColors(Color.BLACK, color, 0.5f),
Shader.TileMode.CLAMP)); Shader.TileMode.CLAMP));
} else { } else {
paint.setShader(null); paint.setShader(null);
} }

Loading…
Cancel
Save