Friday, 13 May 2016

Android M Runtime Permission Multiple Dialog Example



Android M has brought a new interesting feature, i.e. Runtime Permission. Unlike previous version, android devices now requires it's users to allow or deny to access few of their device information.

Android defined some permission s "Dangerous" and some permissions as "Normal". Both are required in your application's manifest but only dangerous requires a runtime request. Normal permissions are accepted at install time and can not be revoked later, An example of a normal permission is android.permission.Internet.  

Dangerous permission are grouped into categories that makes it easier for the user to understand what they are allowing the application to do. If the user accepts one permission in a group they accpet the entire group. the opposite is true as well, if the user denies one permission in a group, the entire group is denied.

for example, if an application if using FINE_LOCATION and COARSE_LOCTION permisions of the same group LOCATION. Then if user granted permission for one , the app will automatically grant permission for the second.

The below table show the dangerous permission and the group they belongs to:










Let's begin our example:

1. Suppose, in an application you are using Camera and Location permission, then declare permissions in AndroidManifest.xml:

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

2. Now, we will be asking for these two permissions one by one. First for location, second for camera.
In our screen there will be two button to check if permissions are already granted and another to request permissions:



public class MainActivity extends AppCompatActivity implements View.OnClickListener {

    private static final int PERMISSION_REQUEST_CODE = 200;
    private View view;


    @Override    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        Button check_permission = (Button) findViewById(R.id.check_permission);
        Button request_permission = (Button) findViewById(R.id.request_permission);
        check_permission.setOnClickListener(this);
        request_permission.setOnClickListener(this);
    }

    @Override    public void onClick(View v) {
        view = v;
        int id = v.getId();
        switch (id) {
            case R.id.check_permission:
                if (checkPermission()) {
                    Snackbar.make(view, "Permission already granted.", Snackbar.LENGTH_LONG).                    show();
                } else {
                    Snackbar.make(view, "Please request permission.", Snackbar.LENGTH_LONG).
                    show();
                }
                break;
            case R.id.request_permission:
                if (!checkPermission()) {
                    requestPermission();
                } else {
                    Snackbar.make(view, "Permission already granted.", Snackbar.LENGTH_LONG).                    show();
                }
                break;
        }
    }

    private boolean checkPermission() {
        int result = ContextCompat.checkSelfPermission(getApplicationContext(), 
                       ACCESS_FINE_LOCATION);
        int result1 = ContextCompat.checkSelfPermission(getApplicationContext(), CAMERA);
        return result == PackageManager.PERMISSION_GRANTED && result1 == 
                         PackageManager.PERMISSION_GRANTED;
    }

    private void requestPermission() {
        ActivityCompat.requestPermissions(this, new String[]{ACCESS_FINE_LOCATION, CAMERA}, 
                               PERMISSION_REQUEST_CODE);
    }

    @Override    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grant    Results) {
        switch (requestCode) {
            case PERMISSION_REQUEST_CODE:
                if (grantResults.length > 0) {

                    boolean locationAccepted = grantResults[0] == PackageManager.PERMISSION_G                    RANTED;
                    boolean cameraAccepted = grantResults[1] == PackageManager.PERMISSION_GRA                    NTED;

                    if (locationAccepted && cameraAccepted)
                        Snackbar.make(view, "Permission Granted, Now you can access location                         data and camera.", Snackbar.LENGTH_LONG).show();
                    else {

                        Snackbar.make(view, "Permission Denied, You cannot access location da                        ta and camera.", Snackbar.LENGTH_LONG).show();

                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                            if (shouldShowRequestPermissionRationale(ACCESS_FINE_LOCATION)) {
                                showMessageOKCancel("You need to allow access to both the per                                missions",
                                        new DialogInterface.OnClickListener() {
                                            @Override                                            public void onClick(DialogInterface dialog, int w                                                        hich) {
                                                if (Build.VERSION.SDK_INT >= Build.VERSION_CO                                                DES.M) {
                                                    requestPermissions(new String[]{ACCESS_FI                                                    NE_LOCATION, CAMERA},
                                                            PERMISSION_REQUEST_CODE);
                                                }
                                            }
                                        });
                                return;
                            }
                        }

                    }
                }


                break;
        }
    }


    private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListen    er) {
        new AlertDialog.Builder(MainActivity.this)
                .setMessage(message)
                .setPositiveButton("OK", okListener)
                .setNegativeButton("Cancel", null)
                .create()
                .show();
    }

}




3. Layout is like this: activity_main.xml


<?xml version="1.0" encoding="utf-8"?>

<android.support.design.widget.CoordinatorLayout 
xmlns:android="http://schemas.android.com/apk/res/android"    
xmlns:app="http://schemas.android.com/apk/res-auto"    
xmlns:tools="http://schemas.android.com/tools"    
android:layout_width="match_parent"    
android:layout_height="match_parent"   
android:fitsSystemWindows="true"    
tools:context="com.journaldev.runtimepermissions.MainActivity">

    <android.support.design.widget.AppBarLayout        
          android:layout_width="match_parent"       
          android:layout_height="wrap_content"        
          android:theme="@style/AppTheme.AppBarOverlay">

        <android.support.v7.widget.Toolbar            
              android:id="@+id/toolbar"            
              android:layout_width="match_parent"           
              android:layout_height="?attr/actionBarSize"           
              android:background="?attr/colorPrimary"            
              app:popupTheme="@style/AppTheme.PopupOverlay" />

    </android.support.design.widget.AppBarLayout>

    <include layout="@layout/content_main" />


</android.support.design.widget.CoordinatorLayout>


4. content_main.xml:

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout 
xmlns:android="http://schemas.android.com/apk/res/android"    
xmlns:app="http://schemas.android.com/apk/res-auto"   
xmlns:tools="http://schemas.android.com/tools"    
android:layout_width="match_parent"    
android:layout_height="match_parent"    
android:paddingBottom="@dimen/activity_vertical_margin"    
android:paddingLeft="@dimen/activity_horizontal_margin"    
android:paddingRight="@dimen/activity_horizontal_margin"    
android:paddingTop="@dimen/activity_vertical_margin"    
app:layout_behavior="@string/appbar_scrolling_view_behavior"    
tools:context="com.journaldev.runtimepermissions.MainActivity"    
tools:showIn="@layout/activity_main">
    <Button        
          android:id="@+id/check_permission"        
          android:layout_width="match_parent"        
          android:layout_centerInParent="true"        
          android:layout_height="wrap_content"        
          android:text="Check Permission"/>
    <Button         
          android:id="@+id/request_permission"        
          android:layout_below="@+id/check_permission"        
          android:layout_width="match_parent"        
          android:layout_height="wrap_content"        
          android:text="Request Permission"/>
</RelativeLayout>


5. And finally, this is my app gradle file:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23    
    buildToolsVersion "23.0.0"

    defaultConfig {
        applicationId "com.journaldev.runtimepermissions"        
        minSdkVersion 15        
        targetSdkVersion 23        
        versionCode 1        
        versionName "1.0"    
    }
    buildTypes {
        release {
            minifyEnabled false            
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'       }
   }
}

dependencies {
    compile fileTree(
            dir: 'libs', include: ['*.jar'])
            testCompile 'junit:junit:4.12'    
            compile 'com.android.support:appcompat-v7:23.1.1'    
            compile 'com.android.support:design:23.1.1'
    }

6. Screenshots of the app are here:
















No comments:

Post a Comment