inject DownloadHandler
+ don't save downloads in incognito
This commit is contained in:
parent
334dbb3780
commit
e850d26abb
@ -14,6 +14,7 @@ import acr.browser.lightning.constant.HistoryPage;
|
||||
import acr.browser.lightning.constant.StartPage;
|
||||
import acr.browser.lightning.database.history.HistoryDatabase;
|
||||
import acr.browser.lightning.dialog.LightningDialogBuilder;
|
||||
import acr.browser.lightning.download.DownloadHandler;
|
||||
import acr.browser.lightning.download.LightningDownloadListener;
|
||||
import acr.browser.lightning.fragment.BookmarkSettingsFragment;
|
||||
import acr.browser.lightning.fragment.BookmarksFragment;
|
||||
@ -80,6 +81,8 @@ public interface AppComponent {
|
||||
|
||||
void inject(LightningChromeClient chromeClient);
|
||||
|
||||
void inject(DownloadHandler downloadHandler);
|
||||
|
||||
HistoryDatabase historyDatabase();
|
||||
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ import acr.browser.lightning.database.downloads.DownloadsDatabase;
|
||||
import acr.browser.lightning.database.downloads.DownloadsModel;
|
||||
import acr.browser.lightning.database.history.HistoryDatabase;
|
||||
import acr.browser.lightning.database.history.HistoryModel;
|
||||
import acr.browser.lightning.download.DownloadHandler;
|
||||
import dagger.Module;
|
||||
import dagger.Provides;
|
||||
|
||||
@ -56,6 +57,13 @@ public class AppModule {
|
||||
return new HistoryDatabase(mApp);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Provides
|
||||
@Singleton
|
||||
public DownloadHandler provideDownloadHandler() {
|
||||
return new DownloadHandler();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Provides
|
||||
@Singleton
|
||||
|
@ -8,9 +8,7 @@ import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.webkit.URLUtil;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.AutoCompleteTextView;
|
||||
import android.widget.EditText;
|
||||
@ -31,13 +29,12 @@ import acr.browser.lightning.constant.Constants;
|
||||
import acr.browser.lightning.controller.UIController;
|
||||
import acr.browser.lightning.database.HistoryItem;
|
||||
import acr.browser.lightning.database.bookmark.BookmarkModel;
|
||||
import acr.browser.lightning.database.downloads.DownloadItem;
|
||||
import acr.browser.lightning.database.downloads.DownloadsModel;
|
||||
import acr.browser.lightning.database.history.HistoryModel;
|
||||
import acr.browser.lightning.download.DownloadHandler;
|
||||
import acr.browser.lightning.preference.PreferenceManager;
|
||||
import acr.browser.lightning.utils.IntentUtils;
|
||||
import acr.browser.lightning.utils.Preconditions;
|
||||
import acr.browser.lightning.utils.Utils;
|
||||
|
||||
/**
|
||||
* TODO Rename this class it doesn't build dialogs only for bookmarks
|
||||
@ -57,6 +54,7 @@ public class LightningDialogBuilder {
|
||||
@Inject DownloadsModel mDownloadsModel;
|
||||
@Inject HistoryModel mHistoryModel;
|
||||
@Inject PreferenceManager mPreferenceManager;
|
||||
@Inject DownloadHandler mDownloadHandler;
|
||||
|
||||
@Inject
|
||||
public LightningDialogBuilder() {
|
||||
@ -385,16 +383,7 @@ public class LightningDialogBuilder {
|
||||
new BrowserDialog.Item(R.string.dialog_download_image) {
|
||||
@Override
|
||||
public void onClick() {
|
||||
Utils.downloadFile(activity, mPreferenceManager, url, userAgent, "attachment");
|
||||
|
||||
mDownloadsModel.addDownloadIfNotExists(new DownloadItem(url, URLUtil.guessFileName(url, null, null), ""))
|
||||
.subscribe(new SingleOnSubscribe<Boolean>() {
|
||||
@Override
|
||||
public void onItem(@Nullable Boolean item) {
|
||||
if (item != null && !item)
|
||||
Log.i(TAG, "error saving download to database");
|
||||
}
|
||||
});
|
||||
mDownloadHandler.onDownloadStart(activity, mPreferenceManager, url, userAgent, "attachment", null, "");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -23,16 +23,26 @@ import android.webkit.CookieManager;
|
||||
import android.webkit.MimeTypeMap;
|
||||
import android.webkit.URLUtil;
|
||||
|
||||
import com.anthonycr.bonsai.SingleOnSubscribe;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import acr.browser.lightning.BuildConfig;
|
||||
import acr.browser.lightning.R;
|
||||
import acr.browser.lightning.activity.BrowserActivity;
|
||||
import acr.browser.lightning.activity.MainActivity;
|
||||
import acr.browser.lightning.app.BrowserApp;
|
||||
import acr.browser.lightning.constant.Constants;
|
||||
import acr.browser.lightning.database.downloads.DownloadItem;
|
||||
import acr.browser.lightning.database.downloads.DownloadsModel;
|
||||
import acr.browser.lightning.dialog.BrowserDialog;
|
||||
import acr.browser.lightning.preference.PreferenceManager;
|
||||
import acr.browser.lightning.utils.FileUtils;
|
||||
import acr.browser.lightning.utils.Utils;
|
||||
import acr.browser.lightning.view.LightningView;
|
||||
|
||||
/**
|
||||
* Handle download requests
|
||||
@ -43,9 +53,11 @@ public class DownloadHandler {
|
||||
|
||||
private static final String COOKIE_REQUEST_HEADER = "Cookie";
|
||||
|
||||
public static final String DEFAULT_DOWNLOAD_PATH =
|
||||
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)
|
||||
.getPath();
|
||||
@Inject DownloadsModel downloadsModel;
|
||||
|
||||
public DownloadHandler() {
|
||||
BrowserApp.getAppComponent().inject(this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Notify the host application a download should be done, or that the data
|
||||
@ -56,9 +68,10 @@ public class DownloadHandler {
|
||||
* @param userAgent User agent of the downloading application.
|
||||
* @param contentDisposition Content-disposition http header, if present.
|
||||
* @param mimetype The mimetype of the content reported by the server
|
||||
* @param contentSize The size of the content
|
||||
*/
|
||||
public static void onDownloadStart(@NonNull Activity context, @NonNull PreferenceManager manager, String url, String userAgent,
|
||||
@Nullable String contentDisposition, String mimetype) {
|
||||
public void onDownloadStart(@NonNull Activity context, @NonNull PreferenceManager manager, String url, String userAgent,
|
||||
@Nullable String contentDisposition, String mimetype, String contentSize) {
|
||||
|
||||
Log.d(TAG, "DOWNLOAD: Trying to download from URL: " + url);
|
||||
Log.d(TAG, "DOWNLOAD: Content disposition: " + contentDisposition);
|
||||
@ -68,7 +81,7 @@ public class DownloadHandler {
|
||||
// if we're dealing wih A/V content that's not explicitly marked
|
||||
// for download, check if it's streamable.
|
||||
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
|
||||
// that matches.
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
@ -80,12 +93,12 @@ public class DownloadHandler {
|
||||
intent.setSelector(null);
|
||||
}
|
||||
ResolveInfo info = context.getPackageManager().resolveActivity(intent,
|
||||
PackageManager.MATCH_DEFAULT_ONLY);
|
||||
PackageManager.MATCH_DEFAULT_ONLY);
|
||||
if (info != null) {
|
||||
// If we resolved to ourselves, we don't want to attempt to
|
||||
// load the url only to try and download it again.
|
||||
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
|
||||
// type with this scheme, don't download.
|
||||
try {
|
||||
@ -98,7 +111,7 @@ public class DownloadHandler {
|
||||
}
|
||||
}
|
||||
}
|
||||
onDownloadStartNoStream(context, manager, url, userAgent, contentDisposition, mimetype);
|
||||
onDownloadStartNoStream(context, manager, url, userAgent, contentDisposition, mimetype, contentSize);
|
||||
}
|
||||
|
||||
// This is to work around the fact that java.net.URI throws Exceptions
|
||||
@ -141,11 +154,12 @@ public class DownloadHandler {
|
||||
* @param userAgent User agent of the downloading application.
|
||||
* @param contentDisposition Content-disposition http header, if present.
|
||||
* @param mimetype The mimetype of the content reported by the server
|
||||
* @param contentSize The size of the content
|
||||
*/
|
||||
/* package */
|
||||
private static void onDownloadStartNoStream(@NonNull final Activity context, @NonNull PreferenceManager preferences,
|
||||
String url, String userAgent,
|
||||
String contentDisposition, @Nullable String mimetype) {
|
||||
private void onDownloadStartNoStream(@NonNull final Activity context, @NonNull PreferenceManager preferences,
|
||||
String url, String userAgent,
|
||||
String contentDisposition, @Nullable String mimetype, String contentSize) {
|
||||
final String filename = URLUtil.guessFileName(url, contentDisposition, mimetype);
|
||||
|
||||
// Check to see if we have an SDCard
|
||||
@ -164,8 +178,8 @@ public class DownloadHandler {
|
||||
}
|
||||
|
||||
Dialog dialog = new AlertDialog.Builder(context).setTitle(title)
|
||||
.setIcon(android.R.drawable.ic_dialog_alert).setMessage(msg)
|
||||
.setPositiveButton(R.string.action_ok, null).show();
|
||||
.setIcon(android.R.drawable.ic_dialog_alert).setMessage(msg)
|
||||
.setPositiveButton(R.string.action_ok, null).show();
|
||||
BrowserDialog.setDialogSize(context, dialog);
|
||||
return;
|
||||
}
|
||||
@ -198,16 +212,8 @@ public class DownloadHandler {
|
||||
// or, should it be set to one of several Environment.DIRECTORY* dirs
|
||||
// depending on mimetype?
|
||||
String location = preferences.getDownloadDirectory();
|
||||
Uri downloadFolder;
|
||||
location = addNecessarySlashes(location);
|
||||
downloadFolder = Uri.parse(location);
|
||||
|
||||
File dir = new File(downloadFolder.getPath());
|
||||
if (!dir.isDirectory() && !dir.mkdirs()) {
|
||||
// Cannot make the directory
|
||||
Utils.showSnackbar(context, R.string.problem_location_download);
|
||||
return;
|
||||
}
|
||||
location = FileUtils.addNecessarySlashes(location);
|
||||
Uri downloadFolder = Uri.parse(location);
|
||||
|
||||
if (!isWriteAccessAvailable(downloadFolder)) {
|
||||
Utils.showSnackbar(context, R.string.problem_location_download);
|
||||
@ -240,7 +246,7 @@ public class DownloadHandler {
|
||||
} else {
|
||||
Log.d(TAG, "Valid mimetype, attempting to download");
|
||||
final DownloadManager manager = (DownloadManager) context
|
||||
.getSystemService(Context.DOWNLOAD_SERVICE);
|
||||
.getSystemService(Context.DOWNLOAD_SERVICE);
|
||||
try {
|
||||
manager.enqueue(request);
|
||||
} catch (IllegalArgumentException e) {
|
||||
@ -254,80 +260,30 @@ public class DownloadHandler {
|
||||
}
|
||||
Utils.showSnackbar(context, context.getString(R.string.download_pending) + ' ' + filename);
|
||||
}
|
||||
}
|
||||
|
||||
private static final String sFileName = "test";
|
||||
private static final String sFileExtension = ".txt";
|
||||
// save download in database
|
||||
BrowserActivity browserActivity = (BrowserActivity) context;
|
||||
LightningView view = browserActivity.getTabModel().getCurrentTab();
|
||||
|
||||
/**
|
||||
* Determine whether there is write access in the given directory. Returns false if a
|
||||
* file cannot be created in the directory or if the directory does not exist.
|
||||
*
|
||||
* @param directory the directory to check for write access
|
||||
* @return returns true if the directory can be written to or is in a directory that can
|
||||
* be written to. false if there is no write access.
|
||||
*/
|
||||
public static boolean isWriteAccessAvailable(@Nullable String directory) {
|
||||
if (directory == null || directory.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
String dir = addNecessarySlashes(directory);
|
||||
dir = getFirstRealParentDirectory(dir);
|
||||
File file = new File(dir + sFileName + sFileExtension);
|
||||
for (int n = 0; n < 100; n++) {
|
||||
if (!file.exists()) {
|
||||
try {
|
||||
if (file.createNewFile()) {
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
file.delete();
|
||||
}
|
||||
return true;
|
||||
} catch (IOException ignored) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
file = new File(dir + sFileName + '-' + n + sFileExtension);
|
||||
}
|
||||
}
|
||||
return file.canWrite();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first parent directory of a directory that exists. This is useful
|
||||
* for subdirectories that do not exist but their parents do.
|
||||
*
|
||||
* @param directory the directory to find the first existent parent
|
||||
* @return the first existent parent
|
||||
*/
|
||||
@Nullable
|
||||
private static String getFirstRealParentDirectory(@Nullable String directory) {
|
||||
while (true) {
|
||||
if (directory == null || directory.isEmpty()) {
|
||||
return "/";
|
||||
}
|
||||
directory = addNecessarySlashes(directory);
|
||||
File file = new File(directory);
|
||||
if (!file.isDirectory()) {
|
||||
int indexSlash = directory.lastIndexOf('/');
|
||||
if (indexSlash > 0) {
|
||||
String parent = directory.substring(0, indexSlash);
|
||||
int previousIndex = parent.lastIndexOf('/');
|
||||
if (previousIndex > 0) {
|
||||
directory = parent.substring(0, previousIndex);
|
||||
} else {
|
||||
return "/";
|
||||
}
|
||||
} else {
|
||||
return "/";
|
||||
}
|
||||
} else {
|
||||
return directory;
|
||||
}
|
||||
if (view != null && !view.isIncognito()) {
|
||||
downloadsModel.addDownloadIfNotExists(new DownloadItem(url, filename, contentSize))
|
||||
.subscribe(new SingleOnSubscribe<Boolean>() {
|
||||
@Override
|
||||
public void onItem(@Nullable Boolean item) {
|
||||
if (item != null && !item)
|
||||
Log.i(TAG, "error saving download to database");
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isWriteAccessAvailable(@NonNull Uri fileUri) {
|
||||
File file = new File(fileUri.getPath());
|
||||
|
||||
if (!file.isDirectory() && !file.mkdirs()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
if (file.createNewFile()) {
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
@ -338,19 +294,4 @@ public class DownloadHandler {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String addNecessarySlashes(@Nullable String originalPath) {
|
||||
if (originalPath == null || originalPath.length() == 0) {
|
||||
return "/";
|
||||
}
|
||||
if (originalPath.charAt(originalPath.length() - 1) != '/') {
|
||||
originalPath = originalPath + '/';
|
||||
}
|
||||
if (originalPath.charAt(0) != '/') {
|
||||
originalPath = '/' + originalPath;
|
||||
}
|
||||
return originalPath;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -7,7 +7,6 @@ import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.text.format.Formatter;
|
||||
import android.util.Log;
|
||||
@ -16,12 +15,10 @@ import android.webkit.URLUtil;
|
||||
|
||||
import acr.browser.lightning.R;
|
||||
import acr.browser.lightning.app.BrowserApp;
|
||||
import acr.browser.lightning.database.downloads.DownloadItem;
|
||||
import acr.browser.lightning.database.downloads.DownloadsModel;
|
||||
import acr.browser.lightning.dialog.BrowserDialog;
|
||||
import acr.browser.lightning.preference.PreferenceManager;
|
||||
|
||||
import com.anthonycr.bonsai.SingleOnSubscribe;
|
||||
import com.anthonycr.grant.PermissionsManager;
|
||||
import com.anthonycr.grant.PermissionsResultAction;
|
||||
|
||||
@ -34,7 +31,7 @@ public class LightningDownloadListener implements DownloadListener {
|
||||
private final Activity mActivity;
|
||||
|
||||
@Inject PreferenceManager mPreferenceManager;
|
||||
|
||||
@Inject DownloadHandler mDownloadHandler;
|
||||
@Inject DownloadsModel downloadsModel;
|
||||
|
||||
public LightningDownloadListener(Activity context) {
|
||||
@ -64,17 +61,7 @@ public class LightningDownloadListener implements DownloadListener {
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
switch (which) {
|
||||
case DialogInterface.BUTTON_POSITIVE:
|
||||
DownloadHandler.onDownloadStart(mActivity, mPreferenceManager, url, userAgent,
|
||||
contentDisposition, mimetype);
|
||||
|
||||
downloadsModel.addDownloadIfNotExists(new DownloadItem(url, fileName, downloadSize))
|
||||
.subscribe(new SingleOnSubscribe<Boolean>() {
|
||||
@Override
|
||||
public void onItem(@Nullable Boolean item) {
|
||||
if (item != null && !item)
|
||||
Log.i(TAG, "error saving download to database");
|
||||
}
|
||||
});
|
||||
mDownloadHandler.onDownloadStart(mActivity, mPreferenceManager, url, userAgent, "attachment", null, "");
|
||||
break;
|
||||
case DialogInterface.BUTTON_NEGATIVE:
|
||||
break;
|
||||
|
@ -25,7 +25,7 @@ import acr.browser.lightning.BuildConfig;
|
||||
import acr.browser.lightning.R;
|
||||
import acr.browser.lightning.constant.Constants;
|
||||
import acr.browser.lightning.dialog.BrowserDialog;
|
||||
import acr.browser.lightning.download.DownloadHandler;
|
||||
import acr.browser.lightning.utils.FileUtils;
|
||||
import acr.browser.lightning.utils.ProxyUtils;
|
||||
import acr.browser.lightning.utils.ThemeUtils;
|
||||
import acr.browser.lightning.utils.Utils;
|
||||
@ -459,8 +459,8 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
switch (which) {
|
||||
case 0:
|
||||
mPreferenceManager.setDownloadDirectory(DownloadHandler.DEFAULT_DOWNLOAD_PATH);
|
||||
downloadloc.setSummary(DownloadHandler.DEFAULT_DOWNLOAD_PATH);
|
||||
mPreferenceManager.setDownloadDirectory(FileUtils.DEFAULT_DOWNLOAD_PATH);
|
||||
downloadloc.setSummary(FileUtils.DEFAULT_DOWNLOAD_PATH);
|
||||
break;
|
||||
case 1:
|
||||
downPicker();
|
||||
@ -539,7 +539,7 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
String text = getDownload.getText().toString();
|
||||
text = DownloadHandler.addNecessarySlashes(text);
|
||||
text = FileUtils.addNecessarySlashes(text);
|
||||
mPreferenceManager.setDownloadDirectory(text);
|
||||
downloadloc.setSummary(text);
|
||||
}
|
||||
@ -667,7 +667,7 @@ public class GeneralSettingsFragment extends LightningPreferenceFragment impleme
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(@NonNull Editable s) {
|
||||
if (!DownloadHandler.isWriteAccessAvailable(s.toString())) {
|
||||
if (!FileUtils.isWriteAccessAvailable(s.toString())) {
|
||||
this.getDownload.setTextColor(this.errorColor);
|
||||
} else {
|
||||
this.getDownload.setTextColor(this.regularColor);
|
||||
|
@ -9,7 +9,7 @@ import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import acr.browser.lightning.constant.Constants;
|
||||
import acr.browser.lightning.download.DownloadHandler;
|
||||
import acr.browser.lightning.utils.FileUtils;
|
||||
|
||||
@Singleton
|
||||
public class PreferenceManager {
|
||||
@ -150,7 +150,7 @@ public class PreferenceManager {
|
||||
|
||||
@NonNull
|
||||
public String getDownloadDirectory() {
|
||||
return mPrefs.getString(Name.DOWNLOAD_DIRECTORY, DownloadHandler.DEFAULT_DOWNLOAD_PATH);
|
||||
return mPrefs.getString(Name.DOWNLOAD_DIRECTORY, FileUtils.DEFAULT_DOWNLOAD_PATH);
|
||||
}
|
||||
|
||||
public int getFlashSupport() {
|
||||
|
@ -28,6 +28,9 @@ public class FileUtils {
|
||||
|
||||
private static final String TAG = "FileUtils";
|
||||
|
||||
public static final String DEFAULT_DOWNLOAD_PATH =
|
||||
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath();
|
||||
|
||||
/**
|
||||
* Writes a bundle to persistent storage in the files directory
|
||||
* using the specified file name. This method is a blocking
|
||||
@ -160,4 +163,87 @@ public class FileUtils {
|
||||
return megaBytes * 1024 * 1024;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine whether there is write access in the given directory. Returns false if a
|
||||
* file cannot be created in the directory or if the directory does not exist.
|
||||
*
|
||||
* @param directory the directory to check for write access
|
||||
* @return returns true if the directory can be written to or is in a directory that can
|
||||
* be written to. false if there is no write access.
|
||||
*/
|
||||
public static boolean isWriteAccessAvailable(@Nullable String directory) {
|
||||
if (directory == null || directory.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final String sFileName = "test";
|
||||
final String sFileExtension = ".txt";
|
||||
String dir = addNecessarySlashes(directory);
|
||||
dir = getFirstRealParentDirectory(dir);
|
||||
File file = new File(dir + sFileName + sFileExtension);
|
||||
for (int n = 0; n < 100; n++) {
|
||||
if (!file.exists()) {
|
||||
try {
|
||||
if (file.createNewFile()) {
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
file.delete();
|
||||
}
|
||||
return true;
|
||||
} catch (IOException ignored) {
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
file = new File(dir + sFileName + '-' + n + sFileExtension);
|
||||
}
|
||||
}
|
||||
return file.canWrite();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the first parent directory of a directory that exists. This is useful
|
||||
* for subdirectories that do not exist but their parents do.
|
||||
*
|
||||
* @param directory the directory to find the first existent parent
|
||||
* @return the first existent parent
|
||||
*/
|
||||
@Nullable
|
||||
private static String getFirstRealParentDirectory(@Nullable String directory) {
|
||||
while (true) {
|
||||
if (directory == null || directory.isEmpty()) {
|
||||
return "/";
|
||||
}
|
||||
directory = addNecessarySlashes(directory);
|
||||
File file = new File(directory);
|
||||
if (!file.isDirectory()) {
|
||||
int indexSlash = directory.lastIndexOf('/');
|
||||
if (indexSlash > 0) {
|
||||
String parent = directory.substring(0, indexSlash);
|
||||
int previousIndex = parent.lastIndexOf('/');
|
||||
if (previousIndex > 0) {
|
||||
directory = parent.substring(0, previousIndex);
|
||||
} else {
|
||||
return "/";
|
||||
}
|
||||
} else {
|
||||
return "/";
|
||||
}
|
||||
} else {
|
||||
return directory;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public static String addNecessarySlashes(@Nullable String originalPath) {
|
||||
if (originalPath == null || originalPath.length() == 0) {
|
||||
return "/";
|
||||
}
|
||||
if (originalPath.charAt(originalPath.length() - 1) != '/') {
|
||||
originalPath = originalPath + '/';
|
||||
}
|
||||
if (originalPath.charAt(0) != '/') {
|
||||
originalPath = '/' + originalPath;
|
||||
}
|
||||
return originalPath;
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,6 @@
|
||||
*/
|
||||
package acr.browser.lightning.utils;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
@ -33,12 +32,8 @@ import android.text.TextUtils;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.webkit.URLUtil;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.anthonycr.grant.PermissionsManager;
|
||||
import com.anthonycr.grant.PermissionsResultAction;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
@ -52,8 +47,6 @@ import acr.browser.lightning.activity.MainActivity;
|
||||
import acr.browser.lightning.constant.Constants;
|
||||
import acr.browser.lightning.database.HistoryItem;
|
||||
import acr.browser.lightning.dialog.BrowserDialog;
|
||||
import acr.browser.lightning.download.DownloadHandler;
|
||||
import acr.browser.lightning.preference.PreferenceManager;
|
||||
|
||||
public final class Utils {
|
||||
|
||||
@ -63,35 +56,6 @@ public final class Utils {
|
||||
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Downloads a file from the specified URL. Handles permissions
|
||||
* requests, and creates all the necessary dialogs that must be
|
||||
* showed to the user.
|
||||
*
|
||||
* @param activity activity needed to created dialogs.
|
||||
* @param url url to download from.
|
||||
* @param userAgent the user agent of the browser.
|
||||
* @param contentDisposition the content description of the file.
|
||||
*/
|
||||
public static void downloadFile(@NonNull final Activity activity, @NonNull final PreferenceManager manager, final String url,
|
||||
final String userAgent, final String contentDisposition) {
|
||||
PermissionsManager.getInstance().requestPermissionsIfNecessaryForResult(activity, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE}, new PermissionsResultAction() {
|
||||
@Override
|
||||
public void onGranted() {
|
||||
String fileName = URLUtil.guessFileName(url, null, null);
|
||||
DownloadHandler.onDownloadStart(activity, manager, url, userAgent, contentDisposition, null);
|
||||
Log.i(TAG, "Downloading: " + fileName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDenied(String permission) {
|
||||
// TODO Show Message
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new intent that can launch the email
|
||||
* app with a subject, address, body, and cc. It
|
||||
|
Loading…
Reference in New Issue
Block a user