วิธีจัดการ Permission Android M

สำหรับใน Android M ( version 6.0 ) นั้นได้มีการเปลี่ยนแปลงครั้งใหญ่เกี่ยวกับระบบ Permission เมื่อมีการเรียกใช้ฟังชันก์บางอย่างจำเป็นต้องขอสิทธิ์จากผู้ใช้งานก่อน แต่สำหรับ Android ต่ำกว่า version 6 จะขอเพียงครั้งเดียวตอนติดตั้งแอปพลิเคชัน ภาพดูตัวอย่างด้านล่างเป็นการเปรียบเทียบระหว่าง Android M และเวอร์ชันที่ต่ำกว่า

android m permission

จากภาพด้านซ้ายมือคือ Android ตั้งแต่เวอร์ชันต่ำกว่า 6.0 จะมีการขอสิทธิ์การใช้งานเพียงครั้งเดียว แต่สำหรับภาพด้านขวา Android 6.0+ จะมีการขอสิทธิ์ในการใช้งานสำหรับบางฟังชันก์หลังจากติดตั้งแอปพลิเคชันแล้ว โดยฟังชันก์ที่ต้องขอ Permission หลังติดตั้งมีดังนี้

permission android m

ด้านซ้ายจะเป็นชื่อ Permission Group ที่ต้องขอสิทธิ์จากผู้ใช้งาน ตัวอย่างเช่นภาพด้านบน มีการขอ Permission SMS หากผู้ใช้งานตกลง ตัวแอปพลิเคชันจะสามารถใช้สิทธ์ได้ทั้งหมด 5 อย่างคือ SEND_SMS, RECEIVE_SMS, READ_SMS, RECEIVE_WAP_PUSH, RECEIVE_MMS หากเพื่อนๆลองสังเกตดีๆแล้วจะพบว่าไม่มี Permission Internet อยู่ด้วยซึ่งเป็นสิ่งที่แอปพลิเคชันส่วนใหญ่ต้องขออย่างแน่นอน เนื่องจาก Android M มีการขอสิทธิ์การใช้งานพื้นฐานตอนติดตั้งนั่นเอง ทำให้สามารถเรียกใช้งานได้เลย

รายละเอียดเพิ่มเติมได้ที่ http://developer.android.com/guide/topics/security/permissions.html

แล้วทำไมนักพัฒนาต้องรู้เรื่อง Permission บน Android M ด้วย ?
  • เนื่องจาก Alert Dialog ที่เห็นจากภาพด้านบนไม่ใช่สิ่งที่ Google ทำไว้ให้แต่นักพัฒนาต้องเป็นคนจัดการเอง ถ้าหากไม่ได้จัดการไว้ก็จะทำให้แอป Crash นั่นเอง
เริ่มจัดการ Permission บน Android M อย่างไรดีล่ะ ?

โดยปกติแล้วเราสามารถใช้วิธีที่ Google สอนได้จาก http://developer.android.com/training/permissions/requesting.html แต่การเลือกใช้วิธีดังกล่าวทำให้โค้ดยาวและใช้งานยาก วันนี้เราจึงมาแนะนำเครื่องมือตัวใหม่ที่ช่วยจัดการ Permission บน Android M โดยเฉพาะ รู้จักกับ Dexter Library

 

เริ่มต้นติดตั้งก่อนเลย
dependencies{
    compile 'com.karumi:dexter:2.2.2'
}

 

วิธีใช้งาน

การใช้งาน Dexter ต้องทำการ Initialize ก่อนถึงใช้งาน Library ได้ วิธีการการคือ สร้าง Application Class ขึ้นมาก่อน

public MyApplication extends Application {
    @Override 
    public void onCreate() {
        super.onCreate();
        Dexter.initialize(context);
    }
}

 

หลังจากกำหนดค่าแล้วเราต้องไป config ใน android manifest ดังนี้

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="app.meter.com.meter">

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

    <application
        ...
        android:name=".Application">      
        ...

    </application>
</manifest>

 

สังเกตว่าใน tag <application> ต้องมีการกำหนด android:name=”” เพื่อให้รู้ว่าหลังจากเปิดแอปแล้วจะเข้าไปยัง Class ใดก่อน หากไม่มีการกำหนดระบบจะเข้าไปยัง Default Class หลังจากรัน Appication Class เรียบร้อยแล้ว โปรแกรมก็จะเข้าสู้ Activity Class นั่นเอง ทำให้ dexter ได้ initialize ค่าก่อนเพื่อเตรียมพร้อมใช้งาน ก่อนที่จะเข้าสู้ Activity Class

การขอใช้  Permission
Dexter.checkPermission(new PermissionListener() {
    @Override 
    public void onPermissionGranted(PermissionGrantedResponse response) {/* ... */}
    
    @Override 
    public void onPermissionDenied(PermissionDeniedResponse response) {/* ... */}
    
    @Override 
    public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) {/* ... */}
}, Manifest.permission.CAMERA);

 

สำหรับ Callback onPermissionGranted จะถูกเรียกเมื่อผู้ใช้งานอนุญาติ

สำหรับ Callback onPermissionDenied จะถูกเรียกเมื่อผู้ใช้งานไม่อนุญาติให้ใช้สิทธิ์

สำหรับ Callback onPermissionRationaleShouldBeShown สำหรับฟังชันนี้จะมี parameter token ซึ่งเราต้องนำไปจัดการต่อครับ 

 

หากเราปฏิเสธสิทธิ์ใช้งาน ครั้งต่อไปที่เปิดแอปเราจะไม่เห็น Alert Dialog เพื่อขอสิทธิ์อีก ให้เราใช้คำสั่งนี้

token.continuePermissionRequest();

 

หากเราปฏิเสธสิทธิ์ใช้งาน แต่ในครั้งต่อไปที่เราเปิดแอปพลิเคขันแล้วต้องการขอสิทธิ์การใช้งานอีกให้ใช้คำสั่งนี้

token.cancelPermissionRequest();

 

ตัวอย่างการใช้งาน

Dexter.checkPermission(new PermissionListener() {
    @Override
    public void onPermissionGranted(PermissionGrantedResponse response) {/* ... */}

    @Override
    public void onPermissionDenied(PermissionDeniedResponse response) {/* ... */}

    @Override
    public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) {
        // request permission when call method again
        token.continuePermissionRequest();
        
        // ask permission once time
        token.cancelPermissionRequest();
    }
}, Manifest.permission.CAMERA);

 

การขอ Multiple Permisstions
Dexter.checkPermissions(new MultiplePermissionsListener() {
    @Override
    public void onPermissionsChecked(MultiplePermissionsReport report) {
        List<PermissionGrantedResponse> permissionGrantedResponses = report.getGrantedPermissionResponses();
        List<PermissionDeniedResponse> permissionDeniedResponses = report.getDeniedPermissionResponses();
        
        for(PermissionGrantedResponse grantedResponse : permissionGrantedResponses)
        {
            grantedResponse.getPermissionName();
        }
        
        report.areAllPermissionsGranted();
    }

    @Override
    public void onPermissionRationaleShouldBeShown(List<PermissionRequest> permissions, PermissionToken token) {
        token.continuePermissionRequest();
    }
}, Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION);

 

สำหรับ public void onPermissionsChecked(MultiplePermissionsReport report) ไว้สำหรับตรวจสอบ Permission ที่ได้รับและไม่ได้รับสิทธิ์จากผู้ใช้งาน ผ่าน parameter report โดยมีคำสั่งดังนี้

report.getGrantedPermissionResponses() เราจะได้ Permission ทั้งหมดที่มีสิทธิ์ใช้งาน

report.getDeniedPermissionResponses() เราจะได้ Permission ทั้งหมดที่โดนปฏิเสธการให้สิทธิ์ใช้งาน

report.areAllPermissionsGranted() ได้ค่าเป็น true หากได้รับสิทธิ์การใช้งานทั้งหมด และคืนค่าเป็น false หากมีการปฏิเสธการให้สิทธิ์

 

Support Orientation Screen

สำหรับแอปพลิเคชันที่รองรับการหมุนจอนั้นต้องทำการกำหนดค่าเพิ่มเติมเพื่อให้ Dexter ใช้งานได้ตามปกติ หากเราไม่เพิ่มจะทำให้แอป Crash !

ให้เราเพิ่มคำสั่ง 1 บรรทัดแล้วส่ง PermissionListener ที่เราสร้างไว้เข้าไป ดังนี้

@Override 
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.sample_activity);
    Dexter.continuePendingRequestsIfPossible(permissionsListener);
}

เพียงเท่านี้เราก็สามารถจัดการ Permission Android M ได้อย่างง่ายดาย

เพื่อนๆสามารถอ่านรายละเอียดเพิ่มเติมได้ที่ https://github.com/Karumi/Dexter

 

สรุป

บทความนี้ต้องการให้นักพัฒนาเริ่มจัดการระบบ Permission บน Android M เนื่องจากเริ่มมีผู้ใช้งานมากขึ้นๆ สังเกตได้จาก Smart Phone หลายๆเจ้าออกมือถือรุ่นใหม่ๆเป็น Android M ทั้งสิ้น หากเพื่อนๆคนไหนมีวิธีอื่นก็สามารถแชร์มาได้ครับ 😀