public class PermissionCheckpoint
extends java.lang.Object
By default, the list of dangerous permissions is drawn from the string
array resource named by R.array#asDangerousPermissionsRequired
in
this library. By default, the array is empty; the app consuming this library
may override the resource with its own values.
The consumer of this class may, alternatively, supply a different resource ID to one of the longer constructors. This will replace the default array resource as the definitive list of required permissions.
The main activity of the app should construct an instance of this class in
its onCreate
method, using itself as the operational context, and
optionally specifying an alternative list of permissions.
protected PermissionCheckpoint m_perms = null ; @Override protected void onCreate( Bundle bndlState ) { super.onCreate(bndlState) ; this.setContentView( R.layout.whatever ) ; if( Build.VERSION.SDK_INT >= Build.VERSION_CODES.M ) m_perms = new PermissionCheckpoint(this) ; // ... }
onResume
The activity's onResume
method must include a call to this class's
performChecks()
method, which re-evaluates the app's permissions
each time it is invoked.
@Override protected void onResume() { super.onResume() ; if( m_perms != null ) m_perms.performChecks() ; }
Finally, the activity must provide a callback for the Android OS in response to a permission request.
Activity
Modern activities include their own callback method, which must be overridden in your activity.
public class MyActivity extends Activity { protected PermissionCheckpoint m_perms = null ; // init in onCreate() // etc @RequiresApi( api = Build.VERSION_CODES.M ) @Override public void onRequestPermissionsResult( int zRequestCode, @NonNull String[] asPermissions, @NonNull int[] azStatus ) { super.onRequestPermissionsResult( zRequestCode, asPermissions, azStatus ) ; if( m_perms != null ) m_perms.processRequestResults( zRequestCode, asPermissions, azStatus ) ; } }
AppCompatActivity
An activity from the compatibility library should implement the
ActivityCompat.OnRequestPermissionsResultCallback
interface.
public class MyCompatActivity extends AppCompatActivity implements ActivityCompat.OnRequestPermissionsResultCallback { protected PermissionCheckpoint m_perms = null ; // init in onCreate() // etc @RequiresApi( api = Build.VERSION_CODES.M ) @Override public void onRequestPermissionsResult( int zRequestCode, @NonNull String[] asPermissions, @NonNull int[] azStatus ) { if( m_perms != null ) m_perms.processRequestResults( zRequestCode, asPermissions, azStatus ) ; } }
@dapayne1
for doing the heavy lifting on the
research for Android 6 permissions management, and providing the original
reference implementation from which this class was adapted.Modifier and Type | Class and Description |
---|---|
protected class |
PermissionCheckpoint.WriteSettingsDialogClickListener
Defines a click listener for the dialog that prompts the user to grant
the special
WRITE_SETTINGS permission. |
Modifier and Type | Field and Description |
---|---|
protected static int |
DANGER_REQUEST_CODE
An identifier used in permission requests.
|
protected static int |
DEFAULT_DANGER_LIST_RESOURCE
The default string array resource in which dangerous permissions are
defined.
|
static java.lang.String |
LOG_TAG |
protected android.support.v7.app.AppCompatActivity |
m_actCompatContext
An
AppCompatActivity which provides the context from which
resources are resolved and additional dialogs and activities may be
launched. |
protected android.app.Activity |
m_actContext
An
Activity which provides the context from which resources
are resolved and additional dialogs and activities may be launched. |
protected boolean |
m_bDialogVisible
Indicates that any permission dialog is currently being displayed.
|
protected android.content.Context |
m_ctx
Since both
Activity and AppCompatActivity are
descendants of Context , this field allows whichever one we end up
with to represent the operational context of the instance, where we can
use Context for resource resolution, etc. |
protected java.util.HashMap<java.lang.String,java.lang.Boolean> |
m_mapGranted
Tracks the list of "dangerous" permissions that need to be granted to the
app, and the current status of each.
|
protected int |
m_resDangerList
The resource ID of the string array that defines the list of dangerous
permissions that should be requested.
|
protected java.lang.String |
m_sFlavor
Indicates the "build flavor" used to build the app, if any.
|
protected static java.lang.String |
PERMISSION_WRITE_SETTINGS |
Constructor and Description |
---|
PermissionCheckpoint(android.app.Activity act)
Initializes the instance with an
Activity as the context. |
PermissionCheckpoint(android.app.Activity act,
int resDangerList)
Initializes the instance with an
Activity as the context. |
PermissionCheckpoint(android.support.v7.app.AppCompatActivity act)
Initializes the instance with an
AppCompatActivity as the context. |
PermissionCheckpoint(android.support.v7.app.AppCompatActivity act,
int resDangerList)
Initializes the instance with an
AppCompatActivity as the context. |
Modifier and Type | Method and Description |
---|---|
static boolean |
checkPermission(android.content.Context ctx,
java.lang.String sPermission)
Static method allowing any class to check the momentary status of a
permission.
|
protected boolean |
hasGrantedAll()
Evaluates whether all required "dangerous" permissions have been granted.
|
protected PermissionCheckpoint |
init(int resDangerList)
Initializes various fields within the instance, once context has been
established.
|
protected boolean |
isContextAppCompat()
Indicates whether the instance's operational context is an
AppCompatActivity . |
protected PermissionCheckpoint |
logPermissionState()
(debug only) Dumps the current state of the permission map to the Android
logs.
|
PermissionCheckpoint |
performChecks()
This method performs all the checks necessary to determine whether the
app has all of its required permissions.
|
void |
processRequestResults(int zCode,
java.lang.String[] asDangers,
int[] azStatus)
Dialogs spawned by
ActivityCompat.requestPermissions(android.app.Activity, java.lang.String[], int) will call
back to this method when the user chooses any option. |
protected PermissionCheckpoint |
promptForOtherDangers(java.util.ArrayList<java.lang.String> asDangers)
Prompts the user to enable "dangerous" permissions.
|
protected PermissionCheckpoint |
promptForPermissions()
Prompts the user to accept all "dangerous" permission requests.
|
protected PermissionCheckpoint |
promptForWriteSettingsPermission()
Prompts the user to enable the "write settings" permission, which can be
administered only on a special Android OS dialog.
|
protected PermissionCheckpoint |
promptWithAppCompatDialog(PermissionCheckpoint.WriteSettingsDialogClickListener listener)
If our parent activity is an
AppCompatActivity , then we need to
use the corresponding AlertDialog flavor to prompt for the
permission. |
protected PermissionCheckpoint |
promptWithModernDialog(PermissionCheckpoint.WriteSettingsDialogClickListener listener)
If our parent activity is an
Activity , then we need to use the
corresponding AlertDialog flavor to prompt for the permission. |
public static final java.lang.String LOG_TAG
protected static final int DANGER_REQUEST_CODE
protected static final java.lang.String PERMISSION_WRITE_SETTINGS
protected android.support.v7.app.AppCompatActivity m_actCompatContext
AppCompatActivity
which provides the context from which
resources are resolved and additional dialogs and activities may be
launched. Only one of m_actCompatContext
and
m_actContext
should be set for any given instance.protected android.app.Activity m_actContext
Activity
which provides the context from which resources
are resolved and additional dialogs and activities may be launched.
Only one of m_actCompatContext
and m_actContext
should
be set for any given instance.protected android.content.Context m_ctx
Activity
and AppCompatActivity
are
descendants of Context
, this field allows whichever one we end up
with to represent the operational context of the instance, where we can
use Context
for resource resolution, etc.protected static final int DEFAULT_DANGER_LIST_RESOURCE
R.array#asDangerousPermissionsRequired
resource, or have their
own resource which is passed into the constructor.protected int m_resDangerList
DEFAULT_DANGER_LIST_RESOURCE
, which is
R.array#asDangerousPermissionsRequired
.protected java.util.HashMap<java.lang.String,java.lang.Boolean> m_mapGranted
protected boolean m_bDialogVisible
protected java.lang.String m_sFlavor
public PermissionCheckpoint(android.app.Activity act)
Activity
as the context.
The default string array resource,
R.array#asDangerousPermissionsRequired
, will be used to define
the list of dangerous permissions required by the app.act
- the activity which provides operational contextpublic PermissionCheckpoint(android.app.Activity act, int resDangerList)
Activity
as the context.act
- the activity which provides operational contextresDangerList
- the resource ID for the list of dangerous
permissions required by the apppublic PermissionCheckpoint(android.support.v7.app.AppCompatActivity act)
AppCompatActivity
as the context.
The default string array resource,
R.array#asDangerousPermissionsRequired
, will be used to define
the list of dangerous permissions required by the app.act
- the activity which provides operational contextpublic PermissionCheckpoint(android.support.v7.app.AppCompatActivity act, int resDangerList)
AppCompatActivity
as the context.act
- the activity which provides operational contextresDangerList
- the resource ID for the list of dangerous
permissions required by the apppublic static boolean checkPermission(android.content.Context ctx, java.lang.String sPermission)
ctx
- the context in which to perform the checksPermission
- the qualified name of the permission to checktrue
iff the permission has been granted to the appprotected PermissionCheckpoint init(int resDangerList)
resDangerList
- the resource ID for the list of dangerous
permissions required by the appprotected boolean isContextAppCompat()
AppCompatActivity
.true
if an AppCompatActivity
was used as the
initial context for the instancepublic PermissionCheckpoint performChecks()
protected boolean hasGrantedAll()
processRequestResults(int, java.lang.String[], int[])
, but for the WRITE_SETTINGS
permission, we have to explicitly re-check it, because there's no way to
listen for a state-change event from the Android OS's application
manager.true
if all permissions are granted.protected PermissionCheckpoint logPermissionState()
hasGrantedAll()
protected PermissionCheckpoint promptForPermissions()
protected PermissionCheckpoint promptForWriteSettingsPermission()
protected PermissionCheckpoint promptWithAppCompatDialog(PermissionCheckpoint.WriteSettingsDialogClickListener listener)
AppCompatActivity
, then we need to
use the corresponding AlertDialog
flavor to prompt for the
permission.listener
- the click listener for the "OK" buttonpromptForWriteSettingsPermission()
protected PermissionCheckpoint promptWithModernDialog(PermissionCheckpoint.WriteSettingsDialogClickListener listener)
Activity
, then we need to use the
corresponding AlertDialog
flavor to prompt for the permission.listener
- the click listener for the "OK" buttonpromptForWriteSettingsPermission()
protected PermissionCheckpoint promptForOtherDangers(java.util.ArrayList<java.lang.String> asDangers)
asDangers
- a list of dangerous permissionspublic void processRequestResults(int zCode, @NonNull java.lang.String[] asDangers, @NonNull int[] azStatus)
ActivityCompat.requestPermissions(android.app.Activity, java.lang.String[], int)
will call
back to this method when the user chooses any option. We will use this
callback to re-check the permission array and determine whether we need
to try again.zCode
- the request code (we are interested in
DANGER_REQUEST_CODE
)asDangers
- an array of permissions that were requestedazStatus
- an array of result indicators