Bài 33: Permission trong Android - Lập trình Android cơ bản

Đăng bởi: Admin | Lượt xem: 6498 | Chuyên mục: Android


1. Giới thiệu

Hệ điều hành Android bảo vệ chính nó và thông tin riêng của người dùng bằng cách chạy các ứng dụng Android trên một môi trường ảo riêng (thuật ngữ gọi là Sandbox), môi trường ảo này có tài nguyên riêng, không đụng chạm gì tới tài nguyên của hệ điều hành, nếu ứng dụng muốn sử dụng tài nguyên bên ngoài Sandbox thì ứng dụng phải xin permission – quyền sử dụng. Tùy thuộc vào loại tài nguyên mà ứng dụng muốn truy cập, hệ điều hành sẽ cấp quyền sử dụng tự động hoặc sẽ phải hỏi ý kiến của người dùng thì mới được sử dụng.
Permission là một trong những thứ cực kì quan trọng với Android vì nó quyết định đến tính năng cũng như sự an toàn của chúng ta. Tuy nhiên, không phải ai cũng hiểu hết về Permission và ý nghĩa của nó nên các app có thể lợi dụng để khai thác thông tin cá nhân hay thậm chí là trừ tiền cước điện thoại của bạn. Ngoài ra, cũng có trường hợp bản thân chúng ta cũng có thể trở nên quá thận trọng trước các Permission mà bỏ qua những ứng dụng hay và chính đáng. Lúc trước mình từng có bài nói về Permission nhưng đã cũ lắm rồi, nay cập nhật bài lại theo các hệ điều hành Android mới để anh em dễ theo dõi, dễ hiểu và dễ làm hơn.  
Nói một cách ngắn gọn súc tích nhất, permissions là những khả năng mà Android cung cấp, cho phép và kiểm soát ứng dụng của bạn. Chẳng hạn, Android cung cấp khả năng truy cập internet cho các ứng dụng do nó quản lí, và ứng dụng của bạn muốn truy cập internet, thì phải “xin xỏ” nó.
1.1 Lịch sử phát triển
Sau vụ scandal Cambridge Analytica mà Facebook là bên chịu nhiều chỉ trích nhất. Đến lúc này thì vấn đề quyền riêng tư và dữ liệu người dùng trở lên nóng hơn bao giờ hết. Bài viết này sẽ hướng dẫn các bạn để có thể yêu cầu cấp quyền cho ứng dụng (permission trong Android) với trải nghiệm tốt nhất  và được người dùng tin tưởng.
Có rất nhiều người dùng đã cẩn thận gỡ bỏ hết các quyền trong ứng dụng đã cấp trước đó. Thậm chí là xóa luôn các ứng dụng mà họ không sử dụng đến.
Tuy nhiên, các nhà phát triển vẫn có cách khác để có được thông tin cá nhân của khách hàng. Như truy xuất được thông tin về vị trí, tin nhắn, danh bạ, liên hệ… truy cập vào các tệp tin, trạng thái WIFI, trạng thái điện thoại và rất nhiều thông tin khác.
Các vụ rò rỉ thông tin ngày càng tràn ngập trên các mặt báo. Người dùng do đó trở nên thận trọng hơn bao giờ hết. Nếu ứng dụng của bạn mà cần cấp quyền(runtime permisson) sẽ trở lên khó khăn hơn, người dùng sẽ thường nghi ngờ ứng dụng của bạn.
Tuy nhiên, nếu ứng dụng mà không được cấp quyền thì sẽ không thể hoạt động bình thường được.
Vậy phải làm sao để thuyết phục người dùng đây?
Thực tế, thì cho tới đời Android 5.1 Lollipop được ấn định mức API là 22, thì việc xin xỏ permissions chỉ mang tính “cho có để đó” đối với lập trình viên. Vì thứ nhất, bạn chỉ cần khai báo tất tần tật các permissions trong Manifest là được. Và thứ hai là Android system sẽ “nhắm mắt đưa chân”, cấp phép tất cả các permissions đó khi người dùng chấp nhận cài đặt ứng dụng mà chả thèm đếm xỉa tới tâm lí của chủ thiết bị: “Oke, ông/bà chấp nhận thì chấp nhận cả rổ, còn không thì khỏi cài luôn. Thích cái nào đây?”. Điều này dẫn tới những trường hợp mã độc tung hoành khắp thiết bị, đặc biệt là trên những thiết bị mà chủ của chúng thích root để gian lận trong các games, hoặc hay cài đặt ứng dụng từ những nguồn chưa xác định dù là ứng dụng đó đang miễn phí trên Google Play nhưng vẫn thích cài từ bên ngoài, hoặc tệ hơn nữa là những ứng dụng tràn lan trên Google Play thích truy cập vào những thông tin mà chức năng chính của chúng chả cần thiết phải đọc qua, chẳng hạn như ứng dụng đèn pin nhưng truy cập vào đủ thứ thông tin như vị trí của bạn, danh bạ của bạn, cuộc gọi của bạn, v.v…
Nhưng với phiên bản Android Lollipop 6.0, khi bạn cài đặt một ứng dụng bất kỳ, bạn sẽ phải đồng ý với những “điều kiện” để cài đặt được ứng dụng. Sau đó người dùng có thể cấp thêm quyền cho ứng dụng đó như sử dụng microphone, camera, GPS, thực hiện cuộc gọi, gửi tin nhắn,… Tuy nhiên vấn đề này thường ít được quan tâm nhưng bạn cũng lên xem xét nó bởi nhiều lúc bạn cũng cần tùy chỉnh ứng dụng cho nó nhẹ hơn chạy mượt hơn và tăng tốc bộ nhớ ram của thiết bị. Chính vì vậy mà hôm nay, vncoder sẽ hướng dẫn các bạn cách cấp quyền cho ứng dụng Android, chỉnh sửa quyền qua bà viết sau đây.  

2. Các permissions trong Android, và một số Permission cần lưu ý

2.1 Các permissions trong Android

Thông thường thì ứng dụng sẽ cần dùng đến các loại dữ liệu mà bản thân nó không thể tự tạo ra được, hay các hành động có thể làm ảnh hưởng đến hành vi của smartphone hoặc các ứng dụng khác. Chẳng hạn như quyền truy cập Internet, quyền sử dụng Camera, quyền tắt/bật Wifi…
Các quyền lại được chia làm nhiều cấp độ, trong đó 2 cấp độ cao nhất là bình thường (normal) và nguy hiểm (dangerous). Quyền bình thường là các quyền sử dụng tài nguyên mà ít có rủi ro đối với sự riêng tư của người dùng, loại quyền này sẽ được hệ điều hành tự động cấp. Dưới đây là danh sách các quyền bình thường có trong phiên bản API 23:
  1. ACCESS_LOCATION_EXTRA_COMMANDS
  2. ACCESS_NETWORK_STATE
  3. ACCESS_NOTIFICATION_POLICY
  4. ACCESS_WIFI_STATE
  5. BLUETOOTH
  6. BLUETOOTH_ADMIN
  7. BROADCAST_STICKY
  8. CHANGE_NETWORK_STATE
  9. CHANGE_WIFI_MULTICAST_STATE
  10. CHANGE_WIFI_STATE
  11. DISABLE_KEYGUARD
  12. EXPAND_STATUS_BAR
  13. GET_PACKAGE_SIZE
  14. INSTALL_SHORTCUT
  15. INTERNET
  16. KILL_BACKGROUND_PROCESSES
  17. MODIFY_AUDIO_SETTINGS
  18. NFC
  19. READ_SYNC_SETTINGS
  20. READ_SYNC_STATS
  21. RECEIVE_BOOT_COMPLETED
  22. REORDER_TASKS
  23. REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
  24. REQUEST_INSTALL_PACKAGES
  25. SET_ALARM
  26. SET_TIME_ZONE
  27. SET_WALLPAPER
  28. SET_WALLPAPER_HINTS
  29. TRANSMIT_IR
  30. UNINSTALL_SHORTCUT
  31. USE_FINGERPRINT
  32. VIBRATE
  33. WAKE_LOCK
  34. WRITE_SYNC_SETTINGS
  Quyền nguy hiểm là quyền sử dụng các loại tài nguyên có liên quan đến sự riêng tư của người dùng hoặc có thể ảnh hưởng đến hệ điều hành và các ứng dụng khác. Loại quyền này cần được sự cho phép của người dùng. Dưới đây là danh sách các quyền nguy hiểm có trong phiên bản API 23:  
  1. READ_CALENDAR
  2. WRITE_CALENDAR
  3. CAMERA
  4. READ_CONTACTS
  5. WRITE_CONTACTS
  6. GET_ACCOUNTS
  7. ACCESS_FINE_LOCATION
  8. ACCESS_COARSE_LOCATION
  9. RECORD_AUDIO
  10. READ_PHONE_STATE
  11. CALL_PHONE
  12. READ_CALL_LOG
  13. WRITE_CALL_LOG
  14. ADD_VOICEMAIL
  15. USE_SIP
  16. PROCESS_OUTGOING_CALLS
  17. BODY_SENSORS
  18. SEND_SMS
  19. RECEIVE_SMS
  20. READ_SMS
  21. RECEIVE_WAP_PUSH
  22. RECEIVE_MMS
  23. READ_EXTERNAL_STORAGE
  24. WRITE_EXTERNAL_STORAGE
Ứng dụng chỉ cần xin quyền để nó có thể sử dụng trực tiếp tài nguyên, nếu trong quá trình chạy mà ứng dụng có sử dụng dữ liệu lấy từ một ứng dụng khác thì chỉ có ứng dụng khác mới cần xin quyền.
Khai báo trong file AndroidManifest.xml
Để khai báo quyền thì chúng ta sử dụng thẻ <user-permissions> trong thẻ <manifest>. Ví dụ:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.phocode">
    <uses-permission android:name="android.permission.SEND_SMS"/>
    <application ...>
        ...
    </application>
</manifest>
Ở đây chúng ta xin quyền được gửi tin SMS. Đây là loại quyền nguy hiểm.

2.2 một số Permission cần lưu ý

Location (vị trí)
Vị trí được chia làm 2 loại FINE LOCATION (vị trí chính xác) và COARSE LOCATION (vị trí tương đối).
Ví dụ như app Facebook tự động nhận diện vị trí của bạn khi đăng status, hoặc app có quảng cáo sẽ hiện quảng cáo tiếng Việt khi bạn ở Việt Nam.
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
Phone Status
Đây là Permission để kiểm soát các cuộc gọi. Ví dụ một app chứa mã độc nào đó thực hiện các cuộc gọi ngầm thì chẳng mấy chốc mà hết sạch tiền trong tài khoản.
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Read and modify contacts
Đây là Permission cho phép kiểm soát danh bạ và các thông tin liên lạc, cũng như trên, hãy cẩn thận với những app yêu cầu quyền truy cập này một cách vô lý (như app nghe nhạc thì cần gì phải đến số điện thoại, nhỉ?).
<uses-permission android:name="android.permission.READ_CONTACTS" />

<uses-permission android:name="android.permission.WRITE_CONTACTS" />
SMS
Cũng như trên, nhưng lần này là liên quan đến tin nhắn và các hành động liên quan như gửi / nhận tin.
<uses-permission android:name="android.permission.WRITE_SMS" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
Account
Android có cơ chế quản lý tài khoản tích hợp. Vào mục tùy chọn và các bạn có thể thấy nhiều tài khoản của bạn được quản lý ở đây. Ví dụ trên máy mình có những tài khoản này:
<uses-permission android:name="android.permission.AUTHENTICATE_ACCOUNTS" />
<uses-permission android:name="android.permission.MANAGE_ACCOUNTS" />
Runtime Permission
Kể từ Android phiên bản 6.0, Google đã thay đổi cách thức yêu cầu Permission trên ứng dụng Android.
Nếu như từ các phiên bản 5 trở về trước, Permission của ứng dụng được gọi ra khi bạn cài app, và bạn chỉ cần đồng ý 1 lần duy nhất:
Thì ở phiên bản 6.0, từng Permission sẽ được hỏi khi bạn truy cập đến phần chức năng của ứng dụng yêu cầu Permission đó:
Và để minh họa cho chức năng này, chúng ta sẽ xem ngay ví dụ mà Google đã soạn sẵn như sau:
Bước 1: Chạy Android Studio, đợi nó load vào màn hình này:
Chọn import an Android code sample, hoặc nếu đã có project mở từ trước thì vào File > Close Project. Sau đó vào lại như trên.
Bước 2: Tìm với từ khóa “runtime” và chọn như hình, nhấn Next:
Bước 3: Bạn có thể đặt lại tên cho Project, rồi nhấn Finish, sau đó chạy thử luôn code:
Nhấn Finish, và chúng ta có ngay một Project để chạy thử và… phẫu thuật code. Và sớm thì muộn thì bạn cũng sẽ phát hiện ra rằng…
Runtime Permission 
Tất cả những gì chúng ta quan tâm đều nằm trong hàm requestContactsPermissions()
private void requestContactsPermissions() {
    // Bắt đầu hỏi quyền truy cập danh bạ.
    if (ActivityCompat.shouldShowRequestPermissionRationale(this,
            Manifest.permission.READ_CONTACTS)
            || ActivityCompat.shouldShowRequestPermissionRationale(this,
            Manifest.permission.WRITE_CONTACTS)) {
        
        // Hiển thị thông báo yêu cầu cấp quyền.
        Snackbar.make(mLayout, R.string.permission_contacts_rationale,
                Snackbar.LENGTH_INDEFINITE)
                .setAction(R.string.ok, new View.OnClickListener() {
                    @Override
                    public void onClick(View view) {
                        ActivityCompat
                                .requestPermissions(MainActivity.this, PERMISSIONS_CONTACT,
                                        REQUEST_CONTACTS);
                    }
                })
                .show();
    } else {
        // Quyền truy cập chưa được cấp, hỏi trực tiêp người dùng.
        ActivityCompat.requestPermissions(this, PERMISSIONS_CONTACT, REQUEST_CONTACTS);
    }
}
Ở đây chúng ta có thể sử dụng cả 2 lớp ActivityCompat và ContextCompat. Hai lớp này đều có các phương thức để request quyền.
Và chúng ta có được:

3. Tổng kết

Bài viết là sự tổng hợp kiến thức của nhiều trang mạng khác nhau được chúng mình biên tập lại nên còn nhiều thiếu sót. Hi vọng bài viết cung cấp những kiến thức thiết yếu về Permission trong Android và cách sử dụng chúng.
Cảm ơn bạn đã đọc các bài viết của vncoder.
Tài liệu tham khảo : 
Bài tiếp theo: Đóng gói ứng dụng Android >>
vncoder logo

Theo dõi VnCoder trên Facebook, để cập nhật những bài viết, tin tức và khoá học mới nhất!