Preliminary fix for permissions, fixed a new crash, formatted some code
This commit is contained in:
parent
159053841a
commit
99e4773e45
@ -11,14 +11,12 @@ import android.animation.ValueAnimator.AnimatorUpdateListener;
|
||||
import android.app.Activity;
|
||||
import android.content.ClipData;
|
||||
import android.content.ClipboardManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.database.sqlite.SQLiteException;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.BitmapFactory;
|
||||
import android.graphics.Color;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.graphics.drawable.ColorDrawable;
|
||||
@ -45,7 +43,6 @@ import android.support.v7.graphics.drawable.DrawerArrowDrawable;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.MotionEvent;
|
||||
@ -77,7 +74,6 @@ import android.widget.EditText;
|
||||
import android.widget.FrameLayout;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.LinearLayout;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.TextView.OnEditorActionListener;
|
||||
@ -88,8 +84,6 @@ import com.squareup.otto.Subscribe;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
@ -109,7 +103,6 @@ import acr.browser.lightning.dialog.LightningDialogBuilder;
|
||||
import acr.browser.lightning.fragment.BookmarksFragment;
|
||||
import acr.browser.lightning.fragment.TabsFragment;
|
||||
import acr.browser.lightning.object.SearchAdapter;
|
||||
import acr.browser.lightning.preference.PreferenceManager;
|
||||
import acr.browser.lightning.receiver.NetworkReceiver;
|
||||
import acr.browser.lightning.utils.PermissionsManager;
|
||||
import acr.browser.lightning.utils.ProxyUtils;
|
||||
@ -822,7 +815,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
||||
* displays the WebView contained in the LightningView Also handles the
|
||||
* removal of previous views
|
||||
*
|
||||
* @param position the poition of the tab to display
|
||||
* @param position the poition of the tab to display
|
||||
*/
|
||||
private synchronized void showTab(final int position) {
|
||||
final LightningView currentView = tabsManager.getCurrentTab();
|
||||
@ -1733,7 +1726,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
||||
mToolbarLayout.setTranslationY(0);
|
||||
if (view != null) {
|
||||
view.setTranslationY(height);
|
||||
}
|
||||
}
|
||||
}
|
||||
final LightningView currentTab = tabsManager.getCurrentTab();
|
||||
if (currentTab == null)
|
||||
@ -1755,9 +1748,9 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
||||
show.setInterpolator(new DecelerateInterpolator());
|
||||
if (view != null) {
|
||||
view.startAnimation(show);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1848,6 +1841,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
||||
}
|
||||
|
||||
// TODO Check if all the calls are relative to TabsFragement
|
||||
|
||||
/**
|
||||
* A utility method that creates a FrameLayout button with the given ID and
|
||||
* sets the image of the button to the given image ID. The OnClick and OnLongClick
|
||||
@ -1880,7 +1874,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
||||
boolean isConnected = isConnected(context);
|
||||
Log.d(Constants.TAG, "Network Connected: " + String.valueOf(isConnected));
|
||||
tabsManager.notifyConnectioneStatus(isConnected);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
@ -1894,7 +1888,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
||||
*/
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
PermissionsManager.getInstance().notifyPermissionsChange(permissions);
|
||||
PermissionsManager.getInstance().notifyPermissionsChange(permissions, grantResults);
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
}
|
||||
|
||||
@ -2037,7 +2031,7 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
||||
*/
|
||||
@Subscribe
|
||||
public void showCloseDialog(final TabEvents.ShowCloseDialog event) {
|
||||
BrowserActivity.this.showCloseDialog(event.position);
|
||||
BrowserActivity.this.showCloseDialog(event.position);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2098,13 +2092,13 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements
|
||||
*/
|
||||
@Subscribe
|
||||
public void newTabLongPress(final TabEvents.NewTabLongPress event) {
|
||||
String url = mPreferences.getSavedUrl();
|
||||
if (url != null) {
|
||||
BrowserActivity.this.newTab(url, true);
|
||||
String url = mPreferences.getSavedUrl();
|
||||
if (url != null) {
|
||||
BrowserActivity.this.newTab(url, true);
|
||||
|
||||
Utils.showSnackbar(BrowserActivity.this, R.string.deleted_tab);
|
||||
}
|
||||
mPreferences.setSavedUrl(null);
|
||||
Utils.showSnackbar(BrowserActivity.this, R.string.deleted_tab);
|
||||
}
|
||||
mPreferences.setSavedUrl(null);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
|
@ -61,7 +61,7 @@ public class SettingsActivity extends ThemableSettingsActivity {
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
PermissionsManager.getInstance().notifyPermissionsChange(permissions);
|
||||
PermissionsManager.getInstance().notifyPermissionsChange(permissions, grantResults);
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
package acr.browser.lightning.activity;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.webkit.WebView;
|
||||
@ -11,7 +10,6 @@ import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import acr.browser.lightning.controller.BrowserController;
|
||||
import acr.browser.lightning.preference.PreferenceManager;
|
||||
import acr.browser.lightning.utils.Utils;
|
||||
import acr.browser.lightning.view.LightningView;
|
||||
@ -57,7 +55,7 @@ public class TabsManager {
|
||||
* Return a clone of the current tabs list. The list will not be updated, the user has to fetch
|
||||
* a new copy when notified.
|
||||
*
|
||||
* @return a copy of the current tabs list
|
||||
* @return a copy of the current tabs list
|
||||
*/
|
||||
public List<LightningView> getTabsList() {
|
||||
return new ArrayList<>(mWebViewList);
|
||||
@ -67,8 +65,8 @@ public class TabsManager {
|
||||
* Return the tab at the given position in tabs list, or null if position is not in tabs list
|
||||
* range.
|
||||
*
|
||||
* @param position the index in tabs list
|
||||
* @return the corespondent {@link LightningView}, or null if the index is invalid
|
||||
* @param position the index in tabs list
|
||||
* @return the corespondent {@link LightningView}, or null if the index is invalid
|
||||
*/
|
||||
@Nullable
|
||||
public LightningView getTabAtPosition(final int position) {
|
||||
@ -83,7 +81,7 @@ public class TabsManager {
|
||||
* Try to low memory pressure
|
||||
*/
|
||||
public void freeMemory() {
|
||||
for (LightningView tab: mWebViewList) {
|
||||
for (LightningView tab : mWebViewList) {
|
||||
tab.freeMemory();
|
||||
}
|
||||
}
|
||||
@ -92,7 +90,7 @@ public class TabsManager {
|
||||
* Shutdown the manager
|
||||
*/
|
||||
public synchronized void shutdown() {
|
||||
for (LightningView tab: mWebViewList) {
|
||||
for (LightningView tab : mWebViewList) {
|
||||
tab.onDestroy();
|
||||
}
|
||||
mWebViewList.clear();
|
||||
@ -104,7 +102,7 @@ public class TabsManager {
|
||||
* @param context
|
||||
*/
|
||||
public synchronized void resume(final Context context) {
|
||||
for (LightningView tab: mWebViewList) {
|
||||
for (LightningView tab : mWebViewList) {
|
||||
tab.initializePreferences(null, context);
|
||||
}
|
||||
}
|
||||
@ -115,15 +113,16 @@ public class TabsManager {
|
||||
* @param isConnected
|
||||
*/
|
||||
public synchronized void notifyConnectioneStatus(final boolean isConnected) {
|
||||
for (LightningView tab: mWebViewList) {
|
||||
for (LightningView tab : mWebViewList) {
|
||||
final WebView webView = tab.getWebView();
|
||||
if (webView != null) {
|
||||
webView.setNetworkAvailable(isConnected);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The number of currently opened tabs
|
||||
* @return The number of currently opened tabs
|
||||
*/
|
||||
public int size() {
|
||||
return mWebViewList.size();
|
||||
@ -149,8 +148,8 @@ public class TabsManager {
|
||||
/**
|
||||
* Remove a tab and return its reference or null if the position is not in tabs range
|
||||
*
|
||||
* @param position The position of the tab to remove
|
||||
* @return The removed tab reference or null
|
||||
* @param position The position of the tab to remove
|
||||
* @return The removed tab reference or null
|
||||
*/
|
||||
@Nullable
|
||||
public synchronized LightningView deleteTab(final int position) {
|
||||
@ -163,22 +162,23 @@ public class TabsManager {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the position of the given tab
|
||||
* @param tab
|
||||
* @return
|
||||
* Return the position of the given tab.
|
||||
*
|
||||
* @param tab the tab to look for
|
||||
* @return the position of the tab or -1 if the tab is not in the list
|
||||
*/
|
||||
public int positionOf(final LightningView tab) {
|
||||
return mWebViewList.indexOf(tab);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return A string representation of the currently opened tabs
|
||||
* @return A string representation of the currently opened tabs
|
||||
*/
|
||||
public String tabsString() {
|
||||
final StringBuilder builder = new StringBuilder();
|
||||
for (LightningView tab: mWebViewList) {
|
||||
for (LightningView tab : mWebViewList) {
|
||||
final String url = tab.getUrl();
|
||||
if (url != null && !url.isEmpty()) {
|
||||
if (!url.isEmpty()) {
|
||||
builder.append(url).append("|$|SEPARATOR|$|");
|
||||
}
|
||||
}
|
||||
@ -187,6 +187,7 @@ public class TabsManager {
|
||||
|
||||
/**
|
||||
* Return the {@link WebView} associated to the current tab, or null if there is no current tab
|
||||
*
|
||||
* @return a {@link WebView} or null
|
||||
*/
|
||||
@Nullable
|
||||
@ -196,8 +197,10 @@ public class TabsManager {
|
||||
|
||||
/**
|
||||
* TODO We should remove also this, but probably not
|
||||
*
|
||||
* @return
|
||||
*/
|
||||
@Nullable
|
||||
public LightningView getCurrentTab() {
|
||||
return mCurrentTab;
|
||||
}
|
||||
@ -207,7 +210,7 @@ public class TabsManager {
|
||||
* call {@link TabsManager#getCurrentTab()} return the same reference returned by this method if
|
||||
* position is valid.
|
||||
*
|
||||
* @return the selected tab or null if position is out of tabs range
|
||||
* @return the selected tab or null if position is out of tabs range
|
||||
*/
|
||||
@Nullable
|
||||
public LightningView switchToTab(final int position) {
|
||||
|
@ -6,6 +6,8 @@ package acr.browser.lightning.download;
|
||||
import android.app.DownloadManager;
|
||||
import android.content.Context;
|
||||
import android.os.Environment;
|
||||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.webkit.MimeTypeMap;
|
||||
import android.webkit.URLUtil;
|
||||
|
||||
@ -53,7 +55,7 @@ class FetchUrlMimeType extends Thread {
|
||||
public void run() {
|
||||
// User agent is likely to be null, though the AndroidHttpClient
|
||||
// seems ok with that.
|
||||
final Bus evenBus = BrowserApp.getAppComponent().getBus();
|
||||
final Bus eventBus = BrowserApp.getAppComponent().getBus();
|
||||
String mimeType = null;
|
||||
String contentDisposition = null;
|
||||
HttpURLConnection connection = null;
|
||||
@ -108,6 +110,13 @@ class FetchUrlMimeType extends Thread {
|
||||
DownloadManager manager = (DownloadManager) mContext
|
||||
.getSystemService(Context.DOWNLOAD_SERVICE);
|
||||
manager.enqueue(mRequest);
|
||||
evenBus.post(new BrowserEvents.ShowSnackBarMessage(mContext.getString(R.string.download_pending) + ' ' + filename));
|
||||
Handler handler = new Handler(Looper.getMainLooper());
|
||||
final String file = filename;
|
||||
handler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
eventBus.post(new BrowserEvents.ShowSnackBarMessage(mContext.getString(R.string.download_pending) + ' ' + file));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,8 @@
|
||||
*/
|
||||
package acr.browser.lightning.download;
|
||||
|
||||
import android.content.Context;
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.content.DialogInterface;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.util.Log;
|
||||
@ -16,40 +17,51 @@ import acr.browser.lightning.utils.PermissionsManager;
|
||||
|
||||
public class LightningDownloadListener implements DownloadListener {
|
||||
|
||||
private final Context mContext;
|
||||
private final Activity mActivity;
|
||||
|
||||
public LightningDownloadListener(Context context) {
|
||||
mContext = context;
|
||||
public LightningDownloadListener(Activity context) {
|
||||
mActivity = context;
|
||||
}
|
||||
|
||||
//TODO implement permissions for downloading
|
||||
@Override
|
||||
public void onDownloadStart(final String url, final String userAgent,
|
||||
final String contentDisposition, final String mimetype, long contentLength) {
|
||||
String fileName = URLUtil.guessFileName(url, contentDisposition, mimetype);
|
||||
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
|
||||
final String contentDisposition, final String mimetype, long contentLength) {
|
||||
PermissionsManager.getInstance().requestPermissionsIfNecessary(mActivity, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE}, new PermissionsManager.PermissionResult() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
switch (which) {
|
||||
case DialogInterface.BUTTON_POSITIVE:
|
||||
DownloadHandler.onDownloadStart(mContext, url, userAgent,
|
||||
contentDisposition, mimetype);
|
||||
break;
|
||||
public void onGranted() {
|
||||
String fileName = URLUtil.guessFileName(url, contentDisposition, mimetype);
|
||||
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
switch (which) {
|
||||
case DialogInterface.BUTTON_POSITIVE:
|
||||
DownloadHandler.onDownloadStart(mActivity, url, userAgent,
|
||||
contentDisposition, mimetype);
|
||||
break;
|
||||
|
||||
case DialogInterface.BUTTON_NEGATIVE:
|
||||
break;
|
||||
}
|
||||
case DialogInterface.BUTTON_NEGATIVE:
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(mActivity); // dialog
|
||||
builder.setTitle(fileName)
|
||||
.setMessage(mActivity.getResources().getString(R.string.dialog_download))
|
||||
.setPositiveButton(mActivity.getResources().getString(R.string.action_download),
|
||||
dialogClickListener)
|
||||
.setNegativeButton(mActivity.getResources().getString(R.string.action_cancel),
|
||||
dialogClickListener).show();
|
||||
Log.i(Constants.TAG, "Downloading" + fileName);
|
||||
}
|
||||
};
|
||||
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(mContext); // dialog
|
||||
builder.setTitle(fileName)
|
||||
.setMessage(mContext.getResources().getString(R.string.dialog_download))
|
||||
.setPositiveButton(mContext.getResources().getString(R.string.action_download),
|
||||
dialogClickListener)
|
||||
.setNegativeButton(mContext.getResources().getString(R.string.action_cancel),
|
||||
dialogClickListener).show();
|
||||
Log.i(Constants.TAG, "Downloading" + fileName);
|
||||
@Override
|
||||
public void onDenied(String permission) {
|
||||
//TODO show message
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -88,7 +88,7 @@ public class BookmarkSettingsFragment extends PreferenceFragment implements Pref
|
||||
|
||||
PermissionsManager permissionsManager = PermissionsManager.getInstance();
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
|
||||
permissionsManager.requestPermissionsIfNecessary(getActivity(), REQUIRED_PERMISSIONS);
|
||||
permissionsManager.requestPermissionsIfNecessary(getActivity(), REQUIRED_PERMISSIONS, null);
|
||||
}
|
||||
}
|
||||
|
||||
@ -124,15 +124,40 @@ public class BookmarkSettingsFragment extends PreferenceFragment implements Pref
|
||||
public boolean onPreferenceClick(Preference preference) {
|
||||
switch (preference.getKey()) {
|
||||
case SETTINGS_EXPORT:
|
||||
if (PermissionsManager.checkPermissions(getActivity(), REQUIRED_PERMISSIONS)) {
|
||||
mBookmarkManager.exportBookmarks(getActivity());
|
||||
}
|
||||
// if (PermissionsManager.checkPermissions(getActivity(), REQUIRED_PERMISSIONS)) {
|
||||
// mBookmarkManager.exportBookmarks(getActivity());
|
||||
// }
|
||||
PermissionsManager.getInstance().requestPermissionsIfNecessary(getActivity(), REQUIRED_PERMISSIONS,
|
||||
new PermissionsManager.PermissionResult() {
|
||||
@Override
|
||||
public void onGranted() {
|
||||
mBookmarkManager.exportBookmarks(getActivity());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDenied(String permission) {
|
||||
//TODO Show message
|
||||
}
|
||||
});
|
||||
return true;
|
||||
case SETTINGS_IMPORT:
|
||||
if (PermissionsManager.checkPermissions(getActivity(), REQUIRED_PERMISSIONS)) {
|
||||
loadFileList(null);
|
||||
createDialog();
|
||||
}
|
||||
// if (PermissionsManager.checkPermissions(getActivity(), REQUIRED_PERMISSIONS)) {
|
||||
// loadFileList(null);
|
||||
// createDialog();
|
||||
// }
|
||||
PermissionsManager.getInstance().requestPermissionsIfNecessary(getActivity(), REQUIRED_PERMISSIONS,
|
||||
new PermissionsManager.PermissionResult() {
|
||||
@Override
|
||||
public void onGranted() {
|
||||
loadFileList(null);
|
||||
createDialog();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDenied(String permission) {
|
||||
//TODO Show message
|
||||
}
|
||||
});
|
||||
return true;
|
||||
case SETTINGS_IMPORT_BROWSER:
|
||||
new ImportBookmarksTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||
|
@ -4,8 +4,11 @@ import android.app.Activity;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
@ -13,10 +16,11 @@ import java.util.Set;
|
||||
/**
|
||||
* Copyright 8/22/2015 Anthony Restaino
|
||||
*/
|
||||
public class PermissionsManager {
|
||||
public final class PermissionsManager {
|
||||
|
||||
private static PermissionsManager mInstance;
|
||||
private final Set<String> mPendingRequests = new HashSet<>();
|
||||
private final List<PermissionResult> mPendingActions = new ArrayList<>();
|
||||
|
||||
public static PermissionsManager getInstance() {
|
||||
if (mInstance == null) {
|
||||
@ -25,34 +29,47 @@ public class PermissionsManager {
|
||||
return mInstance;
|
||||
}
|
||||
|
||||
public void requestPermissionsIfNecessary(Activity activity, @NonNull String[] permissions) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M || activity == null) {
|
||||
private void addPendingAction(@NonNull String[] permissions, @Nullable PermissionResult result) {
|
||||
if (result == null) {
|
||||
return;
|
||||
}
|
||||
result.addPermissions(permissions);
|
||||
mPendingActions.add(result);
|
||||
}
|
||||
|
||||
public void requestPermissionsIfNecessary(@Nullable Activity activity, @NonNull String[] permissions, @Nullable PermissionResult result) {
|
||||
if (activity == null) {
|
||||
return;
|
||||
}
|
||||
addPendingAction(permissions, result);
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
||||
for (String perm : permissions) {
|
||||
if (result != null) {
|
||||
result.onResult(perm, PackageManager.PERMISSION_GRANTED);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
List<String> permList = new ArrayList<>();
|
||||
for (String perm : permissions) {
|
||||
if (activity.checkSelfPermission(perm) != PackageManager.PERMISSION_GRANTED
|
||||
&& !mPendingRequests.contains(perm)) {
|
||||
permList.add(perm);
|
||||
if (ActivityCompat.checkSelfPermission(activity, perm) != PackageManager.PERMISSION_GRANTED) {
|
||||
if (!mPendingRequests.contains(perm)) {
|
||||
permList.add(perm);
|
||||
}
|
||||
} else {
|
||||
if (result != null) {
|
||||
result.onResult(perm, PackageManager.PERMISSION_GRANTED);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!permList.isEmpty()) {
|
||||
String[] permsToRequest = permList.toArray(new String[permList.size()]);
|
||||
mPendingRequests.addAll(permList);
|
||||
activity.requestPermissions(permsToRequest, 1);
|
||||
ActivityCompat.requestPermissions(activity, permsToRequest, 1);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static boolean checkPermission(Activity activity, @NonNull String permission) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
||||
return true;
|
||||
} else if (activity == null) {
|
||||
return false;
|
||||
}
|
||||
return activity.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED;
|
||||
}
|
||||
|
||||
public static boolean checkPermissions(Activity activity, @NonNull String[] permissions) {
|
||||
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
|
||||
return true;
|
||||
@ -66,9 +83,40 @@ public class PermissionsManager {
|
||||
return permissionsNecessary;
|
||||
}
|
||||
|
||||
public void notifyPermissionsChange(String[] permissions) {
|
||||
for (String perm : permissions) {
|
||||
mPendingRequests.remove(perm);
|
||||
public void notifyPermissionsChange(@NonNull String[] permissions, @NonNull int[] results) {
|
||||
int size = permissions.length;
|
||||
if (results.length < size) {
|
||||
size = results.length;
|
||||
}
|
||||
for (int n = 0; n < size; n++) {
|
||||
for (PermissionResult result : mPendingActions) {
|
||||
result.onResult(permissions[n], results[n]);
|
||||
mPendingRequests.remove(permissions[n]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static abstract class PermissionResult {
|
||||
|
||||
private Set<String> mPermissions = new HashSet<>();
|
||||
|
||||
public abstract void onGranted();
|
||||
|
||||
public abstract void onDenied(String permission);
|
||||
|
||||
public void onResult(String permission, int result) {
|
||||
if (result == PackageManager.PERMISSION_GRANTED) {
|
||||
mPermissions.remove(permission);
|
||||
if (mPermissions.isEmpty()) {
|
||||
onGranted();
|
||||
}
|
||||
} else {
|
||||
onDenied(permission);
|
||||
}
|
||||
}
|
||||
|
||||
public void addPermissions(@NonNull String[] perms) {
|
||||
Collections.addAll(mPermissions, perms);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,6 +3,7 @@
|
||||
*/
|
||||
package acr.browser.lightning.utils;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
@ -44,10 +45,22 @@ public final class Utils {
|
||||
|
||||
public static void downloadFile(final Activity activity, final String url,
|
||||
final String userAgent, final String contentDisposition) {
|
||||
String fileName = URLUtil.guessFileName(url, null, null);
|
||||
DownloadHandler.onDownloadStart(activity, url, userAgent, contentDisposition, null
|
||||
);
|
||||
Log.i(Constants.TAG, "Downloading" + fileName);
|
||||
PermissionsManager.getInstance().requestPermissionsIfNecessary(activity, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,
|
||||
Manifest.permission.WRITE_EXTERNAL_STORAGE}, new PermissionsManager.PermissionResult() {
|
||||
@Override
|
||||
public void onGranted() {
|
||||
String fileName = URLUtil.guessFileName(url, null, null);
|
||||
DownloadHandler.onDownloadStart(activity, url, userAgent, contentDisposition, null
|
||||
);
|
||||
Log.i(Constants.TAG, "Downloading" + fileName);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDenied(String permission) {
|
||||
// TODO Show Message
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
public static Intent newEmailIntent(String address, String subject,
|
||||
|
@ -61,12 +61,14 @@ class LightningChromeClient extends WebChromeClient {
|
||||
if (icon == null)
|
||||
return;
|
||||
mLightningView.mTitle.setFavicon(icon);
|
||||
eventBus.post(new BrowserEvents.TabsChanged()); ;
|
||||
eventBus.post(new BrowserEvents.TabsChanged());
|
||||
;
|
||||
cacheFavicon(view.getUrl(), icon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Naive caching of the favicon according to the domain name of the URL
|
||||
*
|
||||
* @param icon the icon to cache
|
||||
*/
|
||||
private void cacheFavicon(final String url, final Bitmap icon) {
|
||||
@ -112,35 +114,43 @@ class LightningChromeClient extends WebChromeClient {
|
||||
@Override
|
||||
public void onGeolocationPermissionsShowPrompt(final String origin,
|
||||
final GeolocationPermissions.Callback callback) {
|
||||
PermissionsManager.getInstance().requestPermissionsIfNecessary(mActivity, PERMISSIONS);
|
||||
final boolean remember = true;
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
|
||||
builder.setTitle(mActivity.getString(R.string.location));
|
||||
String org;
|
||||
if (origin.length() > 50) {
|
||||
org = origin.subSequence(0, 50) + "...";
|
||||
} else {
|
||||
org = origin;
|
||||
}
|
||||
builder.setMessage(org + mActivity.getString(R.string.message_location))
|
||||
.setCancelable(true)
|
||||
.setPositiveButton(mActivity.getString(R.string.action_allow),
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
callback.invoke(origin, true, remember);
|
||||
}
|
||||
})
|
||||
.setNegativeButton(mActivity.getString(R.string.action_dont_allow),
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
callback.invoke(origin, false, remember);
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
alert.show();
|
||||
PermissionsManager.getInstance().requestPermissionsIfNecessary(mActivity, PERMISSIONS, new PermissionsManager.PermissionResult() {
|
||||
@Override
|
||||
public void onGranted() {
|
||||
final boolean remember = true;
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(mActivity);
|
||||
builder.setTitle(mActivity.getString(R.string.location));
|
||||
String org;
|
||||
if (origin.length() > 50) {
|
||||
org = origin.subSequence(0, 50) + "...";
|
||||
} else {
|
||||
org = origin;
|
||||
}
|
||||
builder.setMessage(org + mActivity.getString(R.string.message_location))
|
||||
.setCancelable(true)
|
||||
.setPositiveButton(mActivity.getString(R.string.action_allow),
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
callback.invoke(origin, true, remember);
|
||||
}
|
||||
})
|
||||
.setNegativeButton(mActivity.getString(R.string.action_dont_allow),
|
||||
new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int id) {
|
||||
callback.invoke(origin, false, remember);
|
||||
}
|
||||
});
|
||||
AlertDialog alert = builder.create();
|
||||
alert.show();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDenied(String permission) {
|
||||
//TODO show message and/or turn off setting
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -39,6 +39,7 @@ import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@ -198,9 +199,6 @@ public class LightningView {
|
||||
|
||||
if (!mIsIncognitoTab) {
|
||||
settings.setGeolocationEnabled(mPreferences.getLocationEnabled());
|
||||
if (mPreferences.getLocationEnabled() && !PermissionsManager.checkPermissions(mActivity, PERMISSIONS)) {
|
||||
mPermissionsManager.requestPermissionsIfNecessary(mActivity, PERMISSIONS);
|
||||
}
|
||||
} else {
|
||||
settings.setGeolocationEnabled(false);
|
||||
}
|
||||
@ -527,6 +525,7 @@ public class LightningView {
|
||||
|
||||
/**
|
||||
* Naive caching of the favicon according to the domain name of the URL
|
||||
*
|
||||
* @param icon the icon to cache
|
||||
*/
|
||||
private void cacheFavicon(final Bitmap icon) {
|
||||
@ -591,6 +590,7 @@ public class LightningView {
|
||||
public boolean getInvertePage() {
|
||||
return mInvertPage;
|
||||
}
|
||||
|
||||
/**
|
||||
* handles a long click on the page, parameter String url
|
||||
* is the url that should have been obtained from the WebView touch node
|
||||
@ -741,7 +741,7 @@ public class LightningView {
|
||||
msg.setTarget(webViewHandler);
|
||||
mWebView.requestFocusNodeHref(msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user