android runtime permission illustration

Tutorial Memahami Teknologi Runtime Permission Pada Marshmallow

Tutorial Memahami Teknologi Runtime Permission Pada Marshmallow – Beberapa hari yang lalu Google telah mengumumkan platform Android terbaru mereka tersedia untuk perangkat Nexus dan Andoid One. Sekarang kita akan mencicipi “Marshmalow” yang katanya manis apalagi dilumuri coklat cair “yummi mantab”. Banyak pembaharuan yang dilakukan Google untuk meningkatkan performance Android terutama “Runtime Permission”. Runtime Permisson merupakan proses yang digunakan untuk melakukan pengecekan ataupun proses pembukaan hak akses secara langsung. Developer Android dengan versi sebelumnya melakukan check permission secara hard code dan juga untuk pembukaan hak akses tersebut. Jadi kebanyakan untuk membuka hak akses secara langsung menggunakan hard code syarat Smartphone tersebut sudah di root, pekerjaan tersebut sangat fatal dan beresiko, kenapa? pertama pengguna smartphone tidak semuanya paham dengan rooting, kedua security yang dimiliki smartphone tersebut sudah rentan untuk di curi datanya. Mari kita lanjutkan bagaimana cara membuka hak akses secara runtime, berikut alur flowchart meminta akses untuk write calendar :

2

Perbedaan pembukaan Permission android 6.0 dan android 5.1

Permission Android 6.0

ActivityCompat.requestPermissions(context, new String[]{Manifest.permission.CAMERA}, PERMISSION_REQUEST_CAMERA);

Permission Android 5.1

startActivityForResult(new Intent(android.provider.Settings.ACTION_SETTINGS), 0);

Tutorial berikut merupakan contoh untuk mengakses runtime permission pada kamera dan kalender:

1. Mendeklarasikan permisson pada manifest.xml

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

Pendeklarasian tersebut untuk mendeklarasikan permisson apa aja yang akan digunakan pada aplikasi.

2. Menurunkan class ActivityCompat.OnRequestPermissionsResultCallback 

public class MainActivity extends AppCompatActivity
        implements ActivityCompat.OnRequestPermissionsResultCallback {

Class ActivityCompat.OnRequestPermissionsResultCallback merupakan class Callback(balikan) dari aksi yang akan kita lakukan, maka akan secara default class tersebut membuat method

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
        int[] grantResults) {

3. Check permisson yang akan kita buka.

private void showCameraPreview() {
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
            == PackageManager.PERMISSION_GRANTED) {
        // Permission is already available, start camera preview
        Snackbar.make(mLayout,
                "Camera permission is available. Starting preview.",
                Snackbar.LENGTH_SHORT).show();
        startCamera();
    } else {
        new PermissonRuntime(MainActivity.this,mLayout).requestCameraPermission();
    }
}
private void checkCalendar(){
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_CALENDAR)
            == PackageManager.PERMISSION_GRANTED) {
        // Permission is already available, start camera preview
        Snackbar.make(mLayout,
                "Calendar permission is available. Starting preview.",
                Snackbar.LENGTH_SHORT).show();
    } else {
       new PermissonRuntime(MainActivity.this,mLayout).requestPermissionCalendar();
    }
}

4. Setelah kita cek disana ada kondisi yang kita buat, dibawah ini merupakan cara membuka permission yang kita inginkan

public void requestCameraPermission() {
    // Permission has not been granted and must be requested.
    if (ActivityCompat.shouldShowRequestPermissionRationale(context,
            Manifest.permission.CAMERA)) {
        // Provide an additional rationale to the user if the permission was not granted
        // and the user would benefit from additional context for the use of the permission.
        // Display a SnackBar with a button to request the missing permission.
        Snackbar.make(mLayout, "Camera access is required to display the camera preview.",
                Snackbar.LENGTH_INDEFINITE).setAction("OK", new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // Request the permission
                ActivityCompat.requestPermissions(context,
                        new String[]{Manifest.permission.CAMERA},
                        PERMISSION_REQUEST_CAMERA);
            }
        }).show();

    } else {
        Snackbar.make(mLayout,
                "Permission is not available. Requesting camera permission.",
                Snackbar.LENGTH_SHORT).show();
        // Request the permission. The result will be received in onRequestPermissionResult().
        ActivityCompat.requestPermissions(context, new String[]{Manifest.permission.CAMERA},
                PERMISSION_REQUEST_CAMERA);
    }
}
public void requestPermissionCalendar(){
    if (ActivityCompat.shouldShowRequestPermissionRationale(context,
            Manifest.permission.CAMERA)) {
        // Provide an additional rationale to the user if the permission was not granted
        // and the user would benefit from additional context for the use of the permission.
        // Display a SnackBar with a button to request the missing permission.
        Snackbar.make(mLayout, "Calendar access is required ",
                Snackbar.LENGTH_INDEFINITE).setAction("OK", new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                // Request the permission
                ActivityCompat.requestPermissions(context,
                        new String[]{Manifest.permission.WRITE_CALENDAR},
                        PERMISSION_REQUEST_CALENDAR);
            }
        }).show();

    } else {
        Snackbar.make(mLayout,
                "Permission is not available. Requesting calendar permission.",
                Snackbar.LENGTH_SHORT).show();
        // Request the permission. The result will be received in onRequestPermissionResult().
        ActivityCompat.requestPermissions(context, new String[]{Manifest.permission.WRITE_CALENDAR},
                PERMISSION_REQUEST_CAMERA);
    }
}

Full Source Code :

Manifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.sample.runtimepermission" >
    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.WRITE_CALENDAR"/>
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <activity
            android:name=".camera.CameraPreviewActivity"
            android:exported="false"/>
    </application>

</manifest>

MainActivity.java

/*
* Copyright 2015 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.sample.runtimepermission;


import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;

import com.sample.runtimepermission.camera.CameraPreviewActivity;
import com.sample.runtimepermission.manage.PermissonRuntime;

/**
 * Launcher Activity that demonstrates the use of runtime permissions for Android M.
 * This Activity requests permissions to access the camera
 * ({@link Manifest.permission#CAMERA})
 * when the 'Show Camera Preview' button is clicked to start  {@link CameraPreviewActivity} once
 * the permission has been granted.
 * <p>
 * First, the status of the Camera permission is checked using {@link
 * ActivityCompat#checkSelfPermission(Context, String)}
 * If it has not been granted ({@link PackageManager#PERMISSION_GRANTED}), it is requested by
 * calling
 * {@link ActivityCompat#requestPermissions(Activity, String[], int)}. The result of the request is
 * returned to the
 * {@link ActivityCompat.OnRequestPermissionsResultCallback}, which starts
 * {@link
 * CameraPreviewActivity} if the permission has been granted.
 * <p>
 * Note that there is no need to check the API level, the support library
 * already takes care of this. Similar helper methods for permissions are also available in
 * ({@link ActivityCompat},
 * {@link android.support.v4.content.ContextCompat} and {@link android.support.v4.app.Fragment}).
 */
public class MainActivity extends AppCompatActivity
        implements ActivityCompat.OnRequestPermissionsResultCallback {

    private static final int PERMISSION_REQUEST_CAMERA = 0;
    private static final int PERMISSION_REQUEST_CALENDAR = 1;

    private View mLayout;

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

        // Register a listener for the 'Show Camera Preview' button.
        Button camera = (Button) findViewById(R.id.camera);
        Button calendar = (Button) findViewById(R.id.calendar);

        camera.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                showCameraPreview();
            }
        });
        calendar.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                checkCalendar();
            }
        });
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions,
            int[] grantResults) {
        // BEGIN_INCLUDE(onRequestPermissionsResult)
        if (requestCode == PERMISSION_REQUEST_CAMERA) {
            // Request for camera permission.
            if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Permission has been granted. Start camera preview Activity.
                Snackbar.make(mLayout, "Camera permission was granted. Starting preview.",
                        Snackbar.LENGTH_SHORT)
                        .show();
                startCamera();
            } else {
                // Permission request was denied.
                Snackbar.make(mLayout, "Camera permission request was denied.",
                        Snackbar.LENGTH_SHORT)
                        .show();
            }
        }

        if (requestCode == PERMISSION_REQUEST_CALENDAR) {
            // Request for camera permission.
            if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                // Permission has been granted. Start camera preview Activity.
                Snackbar.make(mLayout, "Calendar permission was granted.",
                        Snackbar.LENGTH_SHORT)
                        .show();
            } else {
                // Permission request was denied.
                Snackbar.make(mLayout, "Calendar permission request was denied.",
                        Snackbar.LENGTH_SHORT)
                        .show();
            }
        }
        // END_INCLUDE(onRequestPermissionsResult)
    }

    private void showCameraPreview() {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
                == PackageManager.PERMISSION_GRANTED) {
            // Permission is already available, start camera preview
            Snackbar.make(mLayout,
                    "Camera permission is available. Starting preview.",
                    Snackbar.LENGTH_SHORT).show();
            startCamera();
        } else {
            new PermissonRuntime(MainActivity.this,mLayout).requestCameraPermission();
        }
    }

    private void checkCalendar(){
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_CALENDAR)
                == PackageManager.PERMISSION_GRANTED) {
            // Permission is already available, start camera preview
            Snackbar.make(mLayout,
                    "Calendar permission is available. Starting preview.",
                    Snackbar.LENGTH_SHORT).show();
        } else {
           new PermissonRuntime(MainActivity.this,mLayout).requestPermissionCalendar();
        }
    }

    /**
     * Requests the {@link Manifest.permission#CAMERA} permission.
     * If an additional rationale should be displayed, the user has to launch the request from
     * a SnackBar that includes additional information.
     */

    private void startCamera() {
        Intent intent = new Intent(this, CameraPreviewActivity.class);
        startActivity(intent);
    }

}

PermissionRuntime.java

package com.sample.runtimepermission.manage;

import android.Manifest;
import android.app.Activity;
import android.content.Context;
import android.support.design.widget.Snackbar;
import android.support.v4.app.ActivityCompat;
import android.view.View;

import com.sample.runtimepermission.R;

/**
 * Created by Jarod on 2015-10-10.
 */
public class PermissonRuntime {
    Activity context;
    private View mLayout;
    private static final int PERMISSION_REQUEST_CAMERA = 0;
    private static final int PERMISSION_REQUEST_CALENDAR = 1;

    public PermissonRuntime(Activity context,View mLayout){
        this.context = context;
        this.mLayout = mLayout;
    }
    public void requestCameraPermission() {
        // Permission has not been granted and must be requested.
        if (ActivityCompat.shouldShowRequestPermissionRationale(context,
                Manifest.permission.CAMERA)) {
            // Provide an additional rationale to the user if the permission was not granted
            // and the user would benefit from additional context for the use of the permission.
            // Display a SnackBar with a button to request the missing permission.
            Snackbar.make(mLayout, "Camera access is required to display the camera preview.",
                    Snackbar.LENGTH_INDEFINITE).setAction("OK", new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    // Request the permission
                    ActivityCompat.requestPermissions(context,
                            new String[]{Manifest.permission.CAMERA},
                            PERMISSION_REQUEST_CAMERA);
                }
            }).show();

        } else {
            Snackbar.make(mLayout,
                    "Permission is not available. Requesting camera permission.",
                    Snackbar.LENGTH_SHORT).show();
            // Request the permission. The result will be received in onRequestPermissionResult().
            ActivityCompat.requestPermissions(context, new String[]{Manifest.permission.CAMERA},
                    PERMISSION_REQUEST_CAMERA);
        }
    }

    public void requestPermissionCalendar(){
        if (ActivityCompat.shouldShowRequestPermissionRationale(context,
                Manifest.permission.CAMERA)) {
            // Provide an additional rationale to the user if the permission was not granted
            // and the user would benefit from additional context for the use of the permission.
            // Display a SnackBar with a button to request the missing permission.
            Snackbar.make(mLayout, "Calendar access is required ",
                    Snackbar.LENGTH_INDEFINITE).setAction("OK", new View.OnClickListener() {
                @Override
                public void onClick(View view) {
                    // Request the permission
                    ActivityCompat.requestPermissions(context,
                            new String[]{Manifest.permission.WRITE_CALENDAR},
                            PERMISSION_REQUEST_CALENDAR);
                }
            }).show();

        } else {
            Snackbar.make(mLayout,
                    "Permission is not available. Requesting calendar permission.",
                    Snackbar.LENGTH_SHORT).show();
            // Request the permission. The result will be received in onRequestPermissionResult().
            ActivityCompat.requestPermissions(context, new String[]{Manifest.permission.WRITE_CALENDAR},
                    PERMISSION_REQUEST_CAMERA);
        }
    }
}

Screenshot

runtime permisson

Catatan : 

Jika ingin mencoba permisson yang lain seperti Write SDCard, GPS, Internet dan sebagainya, tinggal mengganti pada manifest dan menyesuaikan java class yang diinginkan. list permisson dapat lihat disini

Get Source Code Ongitlab icon

Referensi :

Google Github

Android Developer

Leave a Reply

Your email address will not be published. Required fields are marked *