Runtime permissions

The number of different types of devices that your app will target depends on the feature requirements (which needs permissions) and the markets at which you are targeting (by explicitly selecting specific countries or by offering your app in specific languages).

If, for example, your app requires both a front and a back camera, you will be targeting a smaller number of devices, as would be the case if you just require a back camera.

Usually when installing an app, the user is asked to accept (or decline) all the required permissions, as it has been defined in the AndroidManifest file of an app.

With the introduction of Android 6 (Marshmallow), the way a user is asked for particular permissions has changed. Only if a certain type of permission is required, the user will be prompted so that he can allow or deny that permission.

With that, there is an opportunity for the app to explain why this permission is needed. After this, the whole thing makes much more sense to the user. These so-called runtime permissions require a somewhat different development approach.

For this recipe, we will modify the previous app that sends SMSs. Now we need to ask the user's permission once he hits the button in order to send an SMS.

Getting ready

To test runtime permissions, you need to have a device running on Android 6.0 or higher or you need to have a virtual device running on Android Marshmallow or higher.

Also, make sure that you have downloaded the Android 6.x SDK (API Level 23 or above).

How to do it...

So, how do these runtime permissions look and how do we handle them? This can be checked with the help of the following steps:

  1. Open the project from the previous recipe.
  2. Open the AndroidManifest file and add the permission (according to the new model) to send SMS messages:
    <uses-permission-sdk- 
     android:name="android.permission.SEND_SMS"/>
  3. Open the build.gradle file in the app folder and set the value for compileSdkVersion to the latest available version. Also, change the values for each minSdkVersion and targetSdkVersion to 23 or above.
  4. Modify the onClick method:
    @Override
    public void onClick(View v) {
        String phoneNumber = ((EditText) findViewById( 
         R.id.main_edit_phone_number)).getText().toString();
        String message = getString(R.string.yeah);
        if (Constants.isTestSMS) {
          Toast.makeText(this, String.format(
           "TEST Send %s to %s", message, phoneNumber), 
           Toast.LENGTH_SHORT).show();
        } 
        else {
          if (checkSelfPermission(Manifest.permission.SEND_SMS)   
           != PackageManager.PERMISSION_GRANTED) {
                requestPermissions(new String[]{  
                  Manifest.permission.SEND_SMS},
                     REQUEST_PERMISSION_SEND_SMS);
            }
        }
    }
  5. Add a constant value so that later we will know to which permission request the permission result is referring to:
    private final int REQUEST_PERMISSION_SEND_SMS = 1;
  6. Implement the sendSms method. We will use the SmsManager method to send the Y-E-A-H text to the phone number that the user has entered. Once the message has been sent, a toast will be displayed:
    private void sendSms(){
        String phoneNumber = ((EditText) findViewById( 
         R.id.main_edit_phone_number)).getText().toString();
        String message = getString(R.string.yeah);
        SmsManager sms = SmsManager.getDefault();
        sms.sendTextMessage(phoneNumber, null, 
         getString(R.string.yeah), null, null);
        Toast.makeText(this, String.format("Send %s to %s", getString(R.string.yeah), phoneNumber), Toast.LENGTH_SHORT).show();
    }
  7. Finally, implement the onRequestPermissionsResult method. If the granted permission is the permission for an SMS, then call the sendSms method. If the permission is denied, a toast will be displayed and the send button and the edit text to enter the phone number will be disabled:
    @Override
    public void onRequestPermissionsResult(int requestCode,  String permissions[], int[] grantResults) {
        switch (requestCode) {
            case REQUEST_PERMISSION_SEND_SMS: {
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    sendSms();
                }
                else {                
                  findViewById(
                   R.id.main_edit_phone_number).setEnabled(false); 
                  findViewById(  
                   R.id.main_button_send).setEnabled(false);
                    Toast.makeText(this, 
                     getString(R.string.no_sms_permission), Toast.LENGTH_SHORT).show();
                }
                return;
            }
        }
    }
  8. Run your app. Use a device running on Android 6.0 or higher or create a virtual device that runs on the API level 23 or above.
  9. Now the permission to send the SMS will not be asked upfront (that is, if the user installs the application). Instead, a dialog asking for permission pops up as soon as you hit the Send button.
  10. If you agree with the request permission, the SMS message will be sent. If you deny the requested permission, the edit box and the button will be disabled and a toast will be displayed to provide feedback:
    How to do it...

This recipe has demonstrated the basic idea of runtime permissions.

There's more...

To see how and when to ask for permission, or how and when to provide feedback about particular features that are not available, you can check the Google guidelines at https://www.google.com/design/spec/patterns/permissions.html.

Note

Android Studio tip

You can easily extract code from a method that has become too large. Just mark the code that you want to move and use the shortcut Cmd + Alt + M (for Windows: Ctrl + Alt + M).

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset