From b68ad65abc66e8667a74a540cfa629ae068005b1 Mon Sep 17 00:00:00 2001 From: Anthony Restaino Date: Sun, 23 Aug 2015 12:13:06 -0400 Subject: [PATCH] Added permission handling and support for API 23 --- app/build.gradle | 2 +- app/src/main/AndroidManifest.xml | 2 - .../lightning/activity/BrowserActivity.java | 7 ++ .../lightning/activity/SettingsActivity.java | 8 ++ .../fragment/BookmarkSettingsFragment.java | 29 +++++-- .../lightning/utils/PermissionsManager.java | 75 +++++++++++++++++++ .../browser/lightning/view/LightningView.java | 23 ++++-- 7 files changed, 128 insertions(+), 18 deletions(-) create mode 100644 app/src/main/java/acr/browser/lightning/utils/PermissionsManager.java diff --git a/app/build.gradle b/app/build.gradle index 880dc2c..3f0af54 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -5,7 +5,7 @@ android { buildToolsVersion "23.0.0" defaultConfig { minSdkVersion 14 - targetSdkVersion 22 + targetSdkVersion 23 versionName "4.1.1a" } sourceSets { diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 027305e..1cc2031 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -4,8 +4,6 @@ package="acr.browser.lightning" > - - diff --git a/app/src/main/java/acr/browser/lightning/activity/BrowserActivity.java b/app/src/main/java/acr/browser/lightning/activity/BrowserActivity.java index f0483a0..1df20f2 100644 --- a/app/src/main/java/acr/browser/lightning/activity/BrowserActivity.java +++ b/app/src/main/java/acr/browser/lightning/activity/BrowserActivity.java @@ -118,6 +118,7 @@ import acr.browser.lightning.object.DrawerArrowDrawable; 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; import acr.browser.lightning.utils.ThemeUtils; import acr.browser.lightning.utils.UrlUtils; @@ -2868,4 +2869,10 @@ public abstract class BrowserActivity extends ThemableBrowserActivity implements } } }; + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + PermissionsManager.getInstance().notifyPermissionsChange(permissions); + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + } } diff --git a/app/src/main/java/acr/browser/lightning/activity/SettingsActivity.java b/app/src/main/java/acr/browser/lightning/activity/SettingsActivity.java index 8c8fa36..d97c0da 100644 --- a/app/src/main/java/acr/browser/lightning/activity/SettingsActivity.java +++ b/app/src/main/java/acr/browser/lightning/activity/SettingsActivity.java @@ -4,6 +4,7 @@ package acr.browser.lightning.activity; import android.os.Bundle; +import android.support.annotation.NonNull; import android.support.v7.widget.Toolbar; import android.view.MenuItem; import android.view.View; @@ -14,6 +15,7 @@ import java.util.ArrayList; import java.util.List; import acr.browser.lightning.R; +import acr.browser.lightning.utils.PermissionsManager; public class SettingsActivity extends ThemableSettingsActivity { @@ -56,4 +58,10 @@ public class SettingsActivity extends ThemableSettingsActivity { finish(); return true; } + + @Override + public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { + PermissionsManager.getInstance().notifyPermissionsChange(permissions); + super.onRequestPermissionsResult(requestCode, permissions, grantResults); + } } diff --git a/app/src/main/java/acr/browser/lightning/fragment/BookmarkSettingsFragment.java b/app/src/main/java/acr/browser/lightning/fragment/BookmarkSettingsFragment.java index 56e43a1..73d209e 100644 --- a/app/src/main/java/acr/browser/lightning/fragment/BookmarkSettingsFragment.java +++ b/app/src/main/java/acr/browser/lightning/fragment/BookmarkSettingsFragment.java @@ -3,8 +3,10 @@ */ package acr.browser.lightning.fragment; +import android.Manifest; import android.app.Activity; import android.content.DialogInterface; +import android.os.Build; import android.os.Bundle; import android.os.Environment; import android.preference.Preference; @@ -17,7 +19,7 @@ import java.util.Comparator; import acr.browser.lightning.R; import acr.browser.lightning.database.BookmarkManager; -import acr.browser.lightning.preference.PreferenceManager; +import acr.browser.lightning.utils.PermissionsManager; public class BookmarkSettingsFragment extends PreferenceFragment implements Preference.OnPreferenceClickListener { @@ -28,6 +30,11 @@ public class BookmarkSettingsFragment extends PreferenceFragment implements Pref private BookmarkManager mBookmarkManager; private File[] mFileList; private String[] mFileNameList; + private PermissionsManager mPermissionsManager; + private static String[] REQUIRED_PERMISSIONS = new String[]{ + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE + }; private static final File mPath = new File(Environment.getExternalStorageDirectory().toString()); @Override @@ -41,11 +48,14 @@ public class BookmarkSettingsFragment extends PreferenceFragment implements Pref mBookmarkManager = BookmarkManager.getInstance(mActivity.getApplicationContext()); initPrefs(); + + mPermissionsManager = PermissionsManager.getInstance(); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) { + mPermissionsManager.requestPermissionsIfNecessary(getActivity(), REQUIRED_PERMISSIONS); + } } private void initPrefs() { - // mPreferences storage - PreferenceManager mPreferences = PreferenceManager.getInstance(); Preference exportpref = findPreference(SETTINGS_EXPORT); Preference importpref = findPreference(SETTINGS_IMPORT); @@ -58,11 +68,15 @@ public class BookmarkSettingsFragment extends PreferenceFragment implements Pref public boolean onPreferenceClick(Preference preference) { switch (preference.getKey()) { case SETTINGS_EXPORT: - mBookmarkManager.exportBookmarks(getActivity()); + if (PermissionsManager.checkPermissions(getActivity(), REQUIRED_PERMISSIONS)) { + mBookmarkManager.exportBookmarks(getActivity()); + } return true; case SETTINGS_IMPORT: - loadFileList(null); - createDialog(); + if (PermissionsManager.checkPermissions(getActivity(), REQUIRED_PERMISSIONS)) { + loadFileList(null); + createDialog(); + } return true; default: return false; @@ -87,12 +101,11 @@ public class BookmarkSettingsFragment extends PreferenceFragment implements Pref mFileList = new File[0]; } - Arrays.sort(mFileList, new SortName()); - if (mFileList == null) { mFileNameList = new String[0]; mFileList = new File[0]; } else { + Arrays.sort(mFileList, new SortName()); mFileNameList = new String[mFileList.length]; } for (int n = 0; n < mFileList.length; n++) { diff --git a/app/src/main/java/acr/browser/lightning/utils/PermissionsManager.java b/app/src/main/java/acr/browser/lightning/utils/PermissionsManager.java new file mode 100644 index 0000000..fdebd53 --- /dev/null +++ b/app/src/main/java/acr/browser/lightning/utils/PermissionsManager.java @@ -0,0 +1,75 @@ +package acr.browser.lightning.utils; + +import android.app.Activity; +import android.content.pm.PackageManager; +import android.os.Build; +import android.support.annotation.NonNull; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Copyright 8/22/2015 Anthony Restaino + */ +public class PermissionsManager { + + private static PermissionsManager mInstance; + private Set mPendingRequests = new HashSet<>(); + + public static PermissionsManager getInstance() { + if (mInstance == null) { + mInstance = new PermissionsManager(); + } + return mInstance; + } + + public void requestPermissionsIfNecessary(Activity activity, @NonNull String[] permissions) { + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M || activity == null) { + return; + } + List permList = new ArrayList<>(); + for (String perm : permissions) { + if (activity.checkSelfPermission(perm) != PackageManager.PERMISSION_GRANTED + && !mPendingRequests.contains(perm)) { + permList.add(perm); + } + } + if (!permList.isEmpty()) { + String[] permsToRequest = permList.toArray(new String[permList.size()]); + mPendingRequests.addAll(permList); + activity.requestPermissions(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; + } else if (activity == null) { + return false; + } + boolean permissionsNecessary = true; + for (String perm : permissions) { + permissionsNecessary &= activity.checkSelfPermission(perm) == PackageManager.PERMISSION_GRANTED; + } + return permissionsNecessary; + } + + public void notifyPermissionsChange(String[] permissions) { + for (String perm : permissions) { + mPendingRequests.remove(perm); + } + } + +} diff --git a/app/src/main/java/acr/browser/lightning/view/LightningView.java b/app/src/main/java/acr/browser/lightning/view/LightningView.java index 07e4a7b..74eb04a 100644 --- a/app/src/main/java/acr/browser/lightning/view/LightningView.java +++ b/app/src/main/java/acr/browser/lightning/view/LightningView.java @@ -4,6 +4,7 @@ package acr.browser.lightning.view; +import android.Manifest; import android.annotation.SuppressLint; import android.app.Activity; import android.content.ActivityNotFoundException; @@ -62,6 +63,7 @@ import acr.browser.lightning.download.LightningDownloadListener; import acr.browser.lightning.preference.PreferenceManager; import acr.browser.lightning.utils.AdBlock; import acr.browser.lightning.utils.IntentUtils; +import acr.browser.lightning.utils.PermissionsManager; import acr.browser.lightning.utils.ThemeUtils; import acr.browser.lightning.utils.Utils; @@ -93,6 +95,8 @@ public class LightningView { 0, 0, -1.0f, 0, 255, // blue 0, 0, 0, 1.0f, 0 // alpha }; + private PermissionsManager mPermissionsManager; + private static final String[] PERMISSIONS = new String[]{Manifest.permission.ACCESS_FINE_LOCATION}; public LightningView(Activity activity, String url, boolean darkTheme, boolean isIncognito) { @@ -101,6 +105,7 @@ public class LightningView { mIsIncognitoTab = isIncognito; mTitle = new Title(activity, darkTheme); mAdBlock = AdBlock.getInstance(activity.getApplicationContext()); + mPermissionsManager = PermissionsManager.getInstance(); mWebpageBitmap = mTitle.mDefaultIcon; @@ -288,10 +293,13 @@ public class LightningView { if (!mIsIncognitoTab) { settings.setGeolocationEnabled(mPreferences.getLocationEnabled()); + if (mPreferences.getLocationEnabled() && !PermissionsManager.checkPermissions(mActivity, PERMISSIONS)) { + mPermissionsManager.requestPermissionsIfNecessary(mActivity, PERMISSIONS); + } } else { settings.setGeolocationEnabled(false); } - if (API < 19) { + if (API < Build.VERSION_CODES.KITKAT) { switch (mPreferences.getFlashSupport()) { case 0: settings.setPluginState(PluginState.OFF); @@ -709,10 +717,10 @@ public class LightningView { public class LightningWebClient extends WebViewClient { - final Context mActivity; + final Activity mActivity; - LightningWebClient(Context context) { - mActivity = context; + LightningWebClient(Activity activity) { + mActivity = activity; } @Override @@ -932,10 +940,10 @@ public class LightningView { public class LightningChromeClient extends WebChromeClient { - final Context mActivity; + final Activity mActivity; - LightningChromeClient(Context context) { - mActivity = context; + LightningChromeClient(Activity activity) { + mActivity = activity; } @Override @@ -969,6 +977,7 @@ public class LightningView { @Override public void onGeolocationPermissionsShowPrompt(final String origin, final GeolocationPermissions.Callback callback) { + mPermissionsManager.requestPermissionsIfNecessary(mActivity, PERMISSIONS); final boolean remember = true; AlertDialog.Builder builder = new AlertDialog.Builder(mActivity); builder.setTitle(mActivity.getString(R.string.location));