diff --git a/studio/integration/src/main/java/nl/sogeti/android/gpstracker/integration/PermissionRequester.java b/studio/integration/src/main/java/nl/sogeti/android/gpstracker/integration/PermissionRequester.java index 58b5a9c..ab3df1d 100644 --- a/studio/integration/src/main/java/nl/sogeti/android/gpstracker/integration/PermissionRequester.java +++ b/studio/integration/src/main/java/nl/sogeti/android/gpstracker/integration/PermissionRequester.java @@ -29,6 +29,7 @@ package nl.sogeti.android.gpstracker.integration; import android.app.Activity; +import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.pm.PackageManager; @@ -36,99 +37,157 @@ import android.os.Build; import android.support.annotation.NonNull; import android.support.v4.app.ActivityCompat; +import android.support.v4.app.Fragment; import android.support.v4.content.ContextCompat; import android.support.v7.app.AlertDialog; +import java.util.LinkedList; +import java.util.List; + import static nl.sogeti.android.gpstracker.integration.ServiceConstants.permission.TRACKING_CONTROL; import static nl.sogeti.android.gpstracker.integration.ServiceConstants.permission.TRACKING_HISTORY; /** * Asks for Open GPS tracker permissions */ -public class PermissionRequester implements DialogInterface.OnClickListener { +public class PermissionRequester { - private static final int REQUEST_TRACKING_CONTROL = 10000001; + private static final int REQUEST_TRACKING_CONTROL = 10001; private static final String INSTALL_URI = "https://play.google.com/store/apps/details?id=nl.sogeti.android.gpstracker"; + private static final PermissionRequestingState shared = new PermissionRequestingState(); + + static class PermissionRequestingState { + private List runnables = new LinkedList<>(); + private AlertDialog permissionDialog; + private AlertDialog installDialog; + + private boolean isShowingDialog() { + return permissionDialog != null || installDialog != null; + } + } + + public void checkPermissions(final Activity activity, Runnable runnable) { + Runnable request = new Runnable() { + @Override + public void run() { + executePermissionsRequest(activity); + } + }; + checkPermissions(activity, shouldExplainAny(activity), request); + } + + public void checkPermissions(final Fragment fragment, Runnable runnable) { + shared.runnables.add(runnable); + Runnable request = new Runnable() { + @Override + public void run() { + executePermissionsRequest(fragment); + } + }; + checkPermissions(fragment.getContext(), shouldExplainAny(fragment.getActivity()), request); + } - private static boolean isShowingDialog = false; - private AlertDialog permissionDialog; - private AlertDialog installDialog; - private Activity activity; - private Runnable runnable; - - public void checkPermissions(final Activity _activity, Runnable _runnable) { - this.activity = _activity; - this.runnable = _runnable; - - if (new ServiceManager().isPackageInstalled(activity)) { - if (isMissing(TRACKING_CONTROL) || isMissing(TRACKING_HISTORY)) { - if (shouldExplain(TRACKING_CONTROL) || shouldExplain(TRACKING_HISTORY)) { - if (!isShowingDialog) { - isShowingDialog = true; - permissionDialog = new AlertDialog.Builder(activity) + public void checkPermissions(final Context context, final boolean shouldExplain, final Runnable request) { + DialogInterface.OnClickListener install = new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + installOpenGpsTracker(context); + } + }; + DialogInterface.OnClickListener cancel = new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + cancel(); + } + }; + DialogInterface.OnClickListener startRequest = new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + request.run(); + } + }; + + if (new ServiceManager().isPackageInstalled(context)) { + if (isMissing(context, TRACKING_CONTROL) || isMissing(context, TRACKING_HISTORY)) { + if (shouldExplain) { + if (!shared.isShowingDialog()) { + shared.permissionDialog = new AlertDialog.Builder(context) .setMessage(R.string.permission_explain_need_control) - .setNegativeButton(android.R.string.cancel, this) - .setPositiveButton(android.R.string.ok, this) + .setNegativeButton(android.R.string.cancel, cancel) + .setPositiveButton(android.R.string.ok, startRequest) .show(); } } else { - executePermissionsRequest(); + request.run(); } } else { - runnable.run(); + permissionGranted(); } - } else if (!isShowingDialog) { - isShowingDialog = true; - installDialog = new AlertDialog.Builder(activity) + } else if (!shared.isShowingDialog()) { + shared.installDialog = new AlertDialog.Builder(context) .setTitle(R.string.permission_missing_title) .setMessage(R.string.permission_missing_message) - .setNegativeButton(android.R.string.cancel, this) - .setPositiveButton(R.string.permission_button_install, new DialogInterface.OnClickListener() { - @Override - public void onClick(DialogInterface dialog, int which) { - isShowingDialog = false; - Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(INSTALL_URI)); - activity.startActivity(intent); - } - }) + .setNegativeButton(android.R.string.cancel, cancel) + .setPositiveButton(R.string.permission_button_install, install) .show(); } } + private void executePermissionsRequest(Activity activity) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + activity.requestPermissions(new String[]{TRACKING_CONTROL, TRACKING_HISTORY}, REQUEST_TRACKING_CONTROL); + } + } + + private void executePermissionsRequest(Fragment fragment) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + fragment.requestPermissions(new String[]{TRACKING_CONTROL, TRACKING_HISTORY}, REQUEST_TRACKING_CONTROL); + } + } + + private void installOpenGpsTracker(Context context) { + shared.installDialog = null; + Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(INSTALL_URI)); + context.startActivity(intent); + } + + private void permissionGranted() { + for (Runnable runnable : shared.runnables) { + runnable.run(); + } + shared.runnables.clear(); + } + + private void cancel() { + shared.installDialog = null; + shared.permissionDialog = null; + } + /** * Remove dialogs and context references */ public void stop() { - if (installDialog != null) { - installDialog.dismiss(); - installDialog = null; + if (shared.installDialog != null) { + shared.installDialog.dismiss(); + shared.installDialog = null; } - if (permissionDialog != null) { - permissionDialog.dismiss(); - permissionDialog = null; + if (shared.permissionDialog != null) { + shared.permissionDialog.dismiss(); + shared.permissionDialog = null; } - runnable = null; - activity = null; + shared.runnables.clear(); } - @Override - public void onClick(DialogInterface dialog, int which) { - isShowingDialog = false; - executePermissionsRequest(); + private boolean shouldExplainAny(Activity activity) { + return shouldExplain(activity, TRACKING_CONTROL) || shouldExplain(activity, TRACKING_HISTORY); } - private boolean shouldExplain(String permission) { + private boolean shouldExplain(Activity activity, String permission) { return ActivityCompat.shouldShowRequestPermissionRationale(activity, permission); } - private boolean isMissing(String permission) { - return ContextCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED; - } - - private void executePermissionsRequest() { - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { - activity.requestPermissions(new String[]{TRACKING_CONTROL, TRACKING_HISTORY}, REQUEST_TRACKING_CONTROL); - } + private boolean isMissing(Context context, String permission) { + return ContextCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED; } public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { @@ -136,7 +195,7 @@ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permis for (int i = 0; i < permissions.length; i++) { if (TRACKING_CONTROL.equals(permissions[i]) && grantResults[i] == PackageManager.PERMISSION_GRANTED) { - runnable.run(); + permissionGranted(); } } }