Android App Is Prompting for Permissions Again

Overview

By default, an Android app starts with cipher permissions granted to information technology. When the app needs to utilize whatever of the protected features of the device (sending network requests, accessing the camera, sending an SMS, etc) it must obtain the appropriate permission from the user to do then.

Before Marshmallow, permissions were handled at install-fourth dimension and specified in the AndroidManifest.xml inside the project. Full list of permissions can exist found here. After Marshmallow, permissions must at present be requested at runtime earlier beingness used. There are a number of libraries available to make runtime permissions easier. If you to get started quickly, check out our guide on managing runtime permissions with PermissionsDispatcher.

Permissions before Marshmallow

Permissions were much simpler earlier Marshmallow (API 23). All permissions were handled at install-time. When a user went to install an app from the Google Play Shop, the user was presented a list of permissions that the app required (some people referred to this as a "wall of permissions". The user could either take all the permissions and continue to install the app or decide not to install the app. It was an all or zilch approach. At that place was no mode to grant merely sure permissions to the app and no way for the user to revoke certain permissions after the app was installed.

Example of pre-Marshmallow permissions requested by the Dropbox app:

Imgur

For an app developer, permissions were very simple. To request one of the many permissions, just specify information technology in the AndroidManifest.xml:

For example, an application that needs to read the user's contacts would add together the following to it'due south AndroidManifest.xml:

<manifest            xmlns            :            android=              "http://schemas.android.com/apk/res/android"                        packet=              "com.android.app.myapp"                        >          <uses-permission            android            :            proper name=              "android.permission.READ_CONTACTS"                        />     ... </manifest>

That'due south all there was to information technology. The user had no way of changing permissions, even after installing the app. This made it easy for developers to deal with permissions, simply wasn't the best user experience.

Permission Updates in Marshmallow

Marshmallow brought big changes to the permissions model. It introduced the concept of runtime permissions. These are permissions that are requested while the app is running (instead of before the app is installed). These permission can then exist allowed or denied by the user. For approved permissions, these can besides be revoked at a subsequently fourth dimension.

This means in that location are a couple more things to consider when working with permissions for a Marshmallow app. Keep in mind that your targetSdkVersion must exist >= 23 and your emulator / device must be running Marshmallow to meet the new permissions model. If this isn't the example, see the backwards compatibility section to understand how permissions will behave on your configuration.

Normal Permissions

When y'all need to add together a new permission, first check this page to meet if the permission is considered a PROTECTION_NORMAL permission. In Marshmallow, Google has designated certain permissions to exist "condom" and called these "Normal Permissions". These are things like ACCESS_NETWORK_STATE, INTERNET, etc. which can't do much impairment. Normal permissions are automatically granted at install time and never prompt the user asking for permission.

Of import: 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 together isn't listed under the normal permissions, yous'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 volition prove a dialog to the user, like to the following one:

Imgur

The first pace 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>

Next, you'll need to initiate the permission request and handle the result. The following lawmaking shows how to do this in the context of an Activity, but this is also possible from within a Fragment.

                          //              MainActivity.coffee            public            form            MainActivity            extends            AppCompatActivity            {            @Override            protected            void            onCreate(Bundle            savedInstanceState) {            super            .onCreate(savedInstanceState);         setContentView(R            .layout.activity_main);                          //              In an actual app, you'd want to request a permission when the user performs an action                          //              that requires that permission.            getPermissionToReadUserContacts();     }                          //              Identifier for the permission asking            individual            static            last            int            READ_CONTACTS_PERMISSIONS_REQUEST            =            1;                          //              Called when the user is performing an action which requires the app to read the                          //              user'southward contacts            public            void            getPermissionToReadUserContacts() {                          //              1) Use the support library version ContextCompat.checkSelfPermission(...) to avoid                          //              checking the build version since Context.checkSelfPermission(...) is only available                          //              in Marshmallow                          //              ii) Always check for permission (even if permission has already been granted)                          //              since the user can revoke permissions at any time through Settings            if            (ContextCompat            .checkSelfPermission(this,            Manifest            .            permission.READ_CONTACTS)            !=            PackageManager                          .PERMISSION_GRANTED) {                          //              The permission is Not already granted.                          //              Check if the user has been asked almost this permission already and denied                          //              it. If so, we want to give more explanation about why the permission is needed.            if            (shouldShowRequestPermissionRationale(            Manifest            .            permission.READ_CONTACTS)) {                          //              Testify our own UI to explicate to the user why we need to read the contacts                          //              before actually requesting the permission and showing the default UI            }                          //              Fire off an async asking to really get the permission                          //              This will show the standard permission asking dialog UI            requestPermissions(new            String[]{Manifest            .            permission.READ_CONTACTS},            READ_CONTACTS_PERMISSIONS_REQUEST);         }     }                          //              Callback with the request from calling requestPermissions(...)            @Override            public            void            onRequestPermissionsResult(int            requestCode,            @NonNull            Cord            permissions[],            @NonNull            int[]            grantResults) {                          //              Make sure it's our original READ_CONTACTS request            if            (requestCode            ==            READ_CONTACTS_PERMISSIONS_REQUEST) {            if            (grantResults.length            ==            one            &&            grantResults[0]            ==            PackageManager                          .PERMISSION_GRANTED) {            Toast            .makeText(this,                          "Read Contacts permission granted"            ,            Toast                          .LENGTH_SHORT).show();             }            else            {                          //              showRationale = false if user clicks Never Ask Again, otherwise true            boolean            showRationale            =            shouldShowRequestPermissionRationale(            this,            Manifest            .            permission.READ_CONTACTS);            if            (showRationale) {                          //              do something hither to handle degraded way            }            else            {            Toast            .makeText(this,                          "Read Contacts permission denied"            ,            Toast                          .LENGTH_SHORT).bear witness();                 }             }         }            else            {            super            .onRequestPermissionsResult(requestCode, permissions, grantResults);         }     } }

Permission Groups

Permission Groups avoids spamming the user with a lot of permission requests while allowing the app developer to but request the minimal amount of permissions needed at any point in time.

Related permissions are grouped into i 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 nearly the college 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 yous'll be working with the individual permissions and non the permission groups, merely pay close attention to what the API expects as both permissions and permission groups are Strings.

Backwards Compatibility

There are 2 primary scenarios to think about when it comes to backwards compatibility:

  1. Your app is targeting an API less than Marshmallow (TargetSdkVersion < 23), only the emulator / device is Marshmallow:
  • Your app will keep to use the erstwhile permissions model.
  • All permissions listed in the AndroidManifest will be asked for at install time.
  • Users will be able to revoke permissions after the app is installed. Information technology'due south of import to examination this scenario since the results of certain deportment without the appropriate permission can be unexpected.
  1. The emulator / device is running something older than Marshmallow, but you app targets Marshmallow (TargetSdkVersion >= 23):
  • Your app will continue to employ the old permissions model.
  • All permissions listed in the AndroidManifest will be asked for at install fourth dimension.

How to Ask For Permissions

Google recommends in this video that there are four patterns to consider when thinking nigh permissions:

Each pattern dictates a different fashion of requesting permissions. For instance, when requesting for critical but unclear permissions, use a warm welcome screen to help understand a permission is requested. For critical permissions, such as a camera app that needs camera permission, ask up-front for it. Secondary features can be requested later in context, such equally a geotagging app when asking for a location permission. For permissions that are secondary and unclear, yous should include a rationale explanation if you really demand them.

Storage permissions

Rethink nigh whether you need read/write storage permissions (i.e. android.permission.WRITE_EXTERNAL_STORAGE or android.permission.READ_EXTERNAL_STORAGE), which give yous all files on the SD card. Instead, you should use methods on Context to access package-specific directories on external storage. Your app always take access to read/write to these directories,so at that place is no need to permissions to asking it:

                          //              Application-specific call that doesn't require external storage permissions                          //              Can be Surroundings.DIRECTORY_PICTURES, Surroundings.DIRECTORY_PODCASTS, Environment.DIRECTORY_RINGTONES,                                      //              Environs.DIRECTORY_NOTIFICATIONS, Environment.DIRECTORY_PICTURES, or Environment.MOVIES            File            dir            =            MyActivity            .            this            .getExternalFilesDir(Surround                          .DIRECTORY_PICTURES);

Managing Permissions using ADB

Permissions can also exist managed on the command-line using adb with the post-obit commands.

Prove all Android permissions:

$ adb crush pm list permissions -d -thousand

Dumping app permission state:

            $adb            crush dumpsys package com.PackageName.enterprise

Granting and revoking runtime permissions:

            $adb            trounce pm grant com.PackageName.enterprise some.permission.NAME            $adb            shell pm revoke com.PackageName.enterprise android.permission.READ_CONTACTS

Installing an app with all permissions granted:

            $adb            install -thou myAPP.apk

References

  • http://developer.android.com/guide/topics/security/permissions.html
  • http://developer.android.com/preview/features/runtime-permissions.html
  • https://github.com/googlesamples/android-RuntimePermissions

garrisonlacquess.blogspot.com

Source: https://github.com/codepath/android_guides/wiki/Understanding-App-Permissions

0 Response to "Android App Is Prompting for Permissions Again"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel