Before Marshmallow, permissions were handled at install-time and specified in the
The full list of dangerous permissions contains all permissions that require runtime management. Please note that permissions in the normal permission group.
Important: Normal Permissions must be added to the
The first step when adding a "Runtime Permission" is to add it to the
The following code shows how to do this in the context of an
//In this Permissions array you can add as many permissions you want and handle at a time.
public static String[] PERMISSIONS = {
Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS,
};
public static boolean hasPermissions(Context context, String... permissions) {
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null && permissions != null) {
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
Log.e("permission", "" + permission);
return false;
}
}
}
return true;
} }
Create a MainActivity.java:
public class MainActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (Build.VERSION.SDK_INT >= 23) {
if (!Constants.hasPermissions(this, Constants.PERMISSIONS)) {
ActivityCompat.requestPermissions(this, Constants.PERMISSIONS, 1);
}
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT >= 23) {
if (!Constants.hasPermissions(this, Constants.PERMISSIONS)) {
ActivityCompat.requestPermissions(this, Constants.PERMISSIONS, 1);
}
}
}
}
Next, when popup comes just select DENY or ALLOW.
Related permissions are grouped into one of the permission groups. When an app requests a permission that belongs to a particular permission group (i.e. READ_CONTACTS), Android asks the user about the higher level group instead (CONTACTS). This way when the app later needs the WRITE_CONTACTS permission, Android can automatically grant this itself without prompting the user.
In most of your interaction with the permission API's you'll be working with the individual permissions and not the permission groups, but pay close attention to what the API expects as both permissions and permission groups are Strings.
AndroidManifest.xml
within the project. Full list of permissions can be found here. After Marshmallow, permissions must now be requested at runtime before being used. There are a number of libraries available to make runtime permissions easier.Dangerous Permissions
First, we need to recognize the dangerous permissions that require us to request runtime permissions. This includes but is not limited to the following common permissions:
|
---|
The full list of dangerous permissions contains all permissions that require runtime management. Please note that permissions in the normal permission group.
Normal Permissions
When you need to add a new permission, first check this page to see if the permission is considered aPROTECTION_NORMAL
permission. In Marshmallow, Google has designated certain permissions
to be "safe" and called these "Normal Permissions". These are things
like ACCESS_NETWORK_STATE
, INTERNET
, etc. which can't do much harm. Normal permissions are automatically granted at install time and never prompt the user asking for permission.Important: Normal Permissions must be added to the
AndroidManifest
:<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android.app.myapp" >
<uses-permission android:name="android.permission.INTERNET" />
...
</manifest>
Runtime Permissions
If the permission you need to add isn't listed under the normal permissions, you'll need to deal with "Runtime Permissions". Runtime permissions are permissions that are requested as they are needed while the app is running. These permissions will show a dialog to the user, similar to the following one:The first step when adding a "Runtime Permission" is to add it to the
AndroidManifest
:<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.codepath.androidpermissionsdemo" >
<uses-permission android:name="android.permission.READ_CONTACTS" />
...
</manifest>
The following code shows how to do this in the context of an
Activity
, but this is also possible from within a Fragment
.First we will create a Constants.class:
public class Constants{//In this Permissions array you can add as many permissions you want and handle at a time.
public static String[] PERMISSIONS = {
Manifest.permission.READ_CONTACTS, Manifest.permission.WRITE_CONTACTS,
};
public static boolean hasPermissions(Context context, String... permissions) {
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null && permissions != null) {
for (String permission : permissions) {
if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
Log.e("permission", "" + permission);
return false;
}
}
}
return true;
} }
Working with Activity:
Create a MainActivity.java:
public class MainActivity extends Activity{
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (Build.VERSION.SDK_INT >= 23) {
if (!Constants.hasPermissions(this, Constants.PERMISSIONS)) {
ActivityCompat.requestPermissions(this, Constants.PERMISSIONS, 1);
}
}
}
}
Working with Fragment:
public class MainActivity extends Fragment{@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT >= 23) {
if (!Constants.hasPermissions(this, Constants.PERMISSIONS)) {
ActivityCompat.requestPermissions(this, Constants.PERMISSIONS, 1);
}
}
}
}
Next, when popup comes just select DENY or ALLOW.
Permission Groups
Permission Groups avoids spamming the user with a lot of permission requests while allowing the app developer to only request the minimal amount of permissions needed at any point in time.Related permissions are grouped into one of the permission groups. When an app requests a permission that belongs to a particular permission group (i.e. READ_CONTACTS), Android asks the user about the higher level group instead (CONTACTS). This way when the app later needs the WRITE_CONTACTS permission, Android can automatically grant this itself without prompting the user.
In most of your interaction with the permission API's you'll be working with the individual permissions and not the permission groups, but pay close attention to what the API expects as both permissions and permission groups are Strings.
Backwards Compatibility
There are 2 main scenarios to think about when it comes to backwards compatibility:- Your app is targeting an API less than Marshmallow (
TargetSdkVersion
<23
)- Your app will continue to use the old permissions model.
- All permissions listed in the
AndroidManifest
.xml will be asked for at install time. - Users will be able to revoke permissions after the app is installed. It's important to test this scenario since the results of certain actions without the appropriate permission can be unexpected.
- The emulator / device is running something older than Marshmallow, but you app targets Marshmallow (
TargetSdkVersion
>=23
):- Your app will continue to use the old permissions model.
- All permissions listed in the
AndroidManifest.xml
will be asked for at install time. - The Dangerous Permissions will be asked at runtime while using it.
Thanks
ReplyDelete