สิทธิ์ขณะรันไทม์

ใน Android 6.0 ขึ้นไป รูปแบบสิทธิ์ของแอป Android ได้รับการออกแบบมาเพื่อให้ผู้ใช้เข้าใจสิทธิ์ต่างๆ ได้ง่ายขึ้น ใช้ประโยชน์ได้มากขึ้น และปลอดภัยยิ่งขึ้น โมเดลนี้ย้ายแอป Android ที่ต้องขอสิทธิ์ที่เป็นอันตราย (ดูสิทธิ์ที่ได้รับผลกระทบ) จากรูปแบบสิทธิ์ขณะติดตั้งไปยังรูปแบบสิทธิ์รันไทม์

  • สิทธิ์ ณ เวลาที่ติดตั้ง

    (Android 5.1 และต่ำกว่า) ผู้ใช้ให้สิทธิ์ที่เป็นอันตรายแก่แอปเมื่อติดตั้งหรืออัปเดตแอป ผู้ผลิตและผู้ให้บริการอุปกรณ์สามารถติดตั้งแอปล่วงหน้าพร้อมสิทธิ์ที่มอบไว้ล่วงหน้าได้โดยไม่ต้องแจ้งให้ผู้ใช้ทราบ

  • สิทธิ์รันไทม์

    (Android 6.0 ถึง 9) ผู้ใช้ให้สิทธิ์ที่เป็นอันตรายแก่แอปเมื่อแอปทำงานอยู่ เวลาที่ขอสิทธิ์ (เช่น เมื่อแอปเปิดขึ้นหรือเมื่อผู้ใช้เข้าถึงฟีเจอร์ที่เฉพาะเจาะจง) จะขึ้นอยู่กับแอป แต่ผู้ใช้จะให้สิทธิ์/ปฏิเสธการเข้าถึงกลุ่มสิทธิ์ที่เฉพาะเจาะจงแก่แอป OEM/ผู้ให้บริการสามารถติดตั้งแอปล่วงหน้าได้ แต่จะให้สิทธิ์ล่วงหน้าไม่ได้ เว้นแต่ว่าจะทำตามกระบวนการยกเว้น (ดูการสร้างข้อยกเว้น)

    (Android 10) ผู้ใช้จะเห็นความโปร่งใสมากขึ้นและสามารถควบคุมได้ว่าแอปใดมีสิทธิ์รันไทม์การจดจำกิจกรรม (AR) กล่องโต้ตอบสิทธิ์รันไทม์จะแจ้งให้ผู้ใช้อนุญาตเสมอ อนุญาตขณะใช้งาน หรือปฏิเสธสิทธิ์ เมื่ออัปเกรดระบบปฏิบัติการเป็น Android 10 ระบบจะเก็บสิทธิ์ที่มอบให้กับแอปไว้ แต่ผู้ใช้สามารถไปที่การตั้งค่าและเปลี่ยนแปลงสิทธิ์เหล่านั้นได้

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

สิทธิ์ที่ได้รับผลกระทบ

Android 6.0 ขึ้นไปต้องใช้สิทธิ์ที่เป็นอันตรายเพื่อใช้โมเดลสิทธิ์รันไทม์ สิทธิ์ที่เป็นอันตรายคือสิทธิ์ที่มีความเสี่ยงสูงกว่า (เช่น READ_CALENDAR) ซึ่งให้สิทธิ์แอปที่ขอเข้าถึงข้อมูลส่วนตัวของผู้ใช้หรือควบคุมอุปกรณ์ ซึ่งอาจส่งผลเสียต่อผู้ใช้ หากต้องการดูรายการสิทธิ์ที่เป็นอันตราย ให้เรียกใช้คำสั่งต่อไปนี้

adb shell pm list permissions -g -d

Android 6.0 ขึ้นไปจะไม่เปลี่ยนแปลงลักษณะการทํางานของสิทธิ์แบบปกติ สิทธิ์เหล่านี้ทั้งหมดไม่ใช่สิทธิ์ที่เป็นอันตราย ซึ่งรวมถึงสิทธิ์ปกติ สิทธิ์ระดับระบบ และสิทธิ์ลายเซ็น สิทธิ์ปกติคือสิทธิ์ที่มีความเสี่ยงต่ำ (เช่น SET_WALLPAPER) ที่ให้สิทธิ์แอปที่ขอเข้าถึงฟีเจอร์ระดับแอปแบบแยกส่วนโดยมีความเสี่ยงน้อยที่สุดต่อแอปอื่นๆ ระบบ หรือผู้ใช้ ระบบจะมอบสิทธิ์ปกติให้กับแอปที่ขอโดยอัตโนมัติเมื่อติดตั้ง และไม่แสดงข้อความแจ้งให้ผู้ใช้อนุมัติ เช่นเดียวกับใน Android 5.1 และรุ่นที่ต่ำกว่า ดูรายละเอียดเกี่ยวกับสิทธิ์ได้ที่เอกสารประกอบของ<permission> element

การจำกัดแบบเข้มงวดและแบบไม่เข้มงวดใน Android 10

นอกเหนือจากการเป็นอันตรายแล้ว สิทธิ์ยังอาจถูกจํากัดอย่างเข้มงวดหรือจํากัดอย่างอ่อนก็ได้ ไม่ว่าในกรณีใด สิทธิ์ที่จํากัดจะต้องอยู่ในรายการที่อนุญาตด้วย ข้อจำกัดที่เข้มงวดซึ่งไม่อยู่ในรายการที่อนุญาตจะทำงานแตกต่างจากข้อจำกัดที่ผ่อนปรนซึ่งไม่อยู่ในรายการที่อนุญาต ดังนี้

  • (ข้อจำกัดที่เปลี่ยนแปลงไม่ได้) แอปไม่ได้รับสิทธิ์ที่ไม่ได้อยู่ในรายการที่อนุญาต
  • (การจํากัดแบบไม่เข้มงวด) แอปที่ไม่มีรายการที่อนุญาตจะทํางานตามสิทธิ์ที่เฉพาะเจาะจงที่ขอ ลักษณะการทำงานจะอธิบายไว้ในเอกสารประกอบสาธารณะสำหรับสิทธิ์ที่ขอ

เมื่อติดตั้งแอป เครื่องมือติดตั้ง (เช่น Google Play Store) อาจเลือกที่จะไม่เพิ่มสิทธิ์ที่จํากัดไว้ลงในรายการที่อนุญาตสําหรับแอป สิทธิ์จะจํากัดโดยแพลตฟอร์มและจะอนุญาตได้ก็ต่อเมื่อแอปมีคุณสมบัติตรงตามเกณฑ์พิเศษตามนโยบายแพลตฟอร์มเท่านั้น ตัวอย่างประเภทสิทธิ์ที่จํากัดอย่างเข้มงวด ได้แก่ สิทธิ์เข้าถึง SMS และประวัติการโทร

รายการที่อนุญาตจะเกิดขึ้นระหว่างการติดตั้งและในกรณีต่อไปนี้

  • มีการติดตั้งแอปไว้แล้วระหว่างการอัปเกรด Android 9 เป็น 10
  • มีการให้สิทธิ์ล่วงหน้าหรือมีการติดตั้งแอปไว้ล่วงหน้า
  • ต้องมีสิทธิ์สำหรับบทบาทที่กําหนดไว้แล้วเพื่อเพิ่มสิทธิ์ในรายการที่อนุญาต
  • โปรแกรมติดตั้ง (เช่น Google Play Store) ทำเครื่องหมายสิทธิ์เป็นรายการที่อนุญาต

ผู้ใช้ไม่สามารถเพิ่มสิทธิ์ในรายการที่อนุญาตด้วยตนเอง

ข้อกำหนด

รูปแบบสิทธิ์รันไทม์มีผลกับแอปทั้งหมด ซึ่งรวมถึงแอปที่ติดตั้งไว้ล่วงหน้าและแอปที่ส่งไปยังอุปกรณ์ในกระบวนการตั้งค่า ข้อกำหนดของซอฟต์แวร์แอปมีดังนี้

  • รูปแบบสิทธิ์รันไทม์ต้องสอดคล้องกันในทุกอุปกรณ์ที่ใช้ Android 6.0 ขึ้นไป ซึ่งมีการบังคับใช้โดยการทดสอบชุดเครื่องมือทดสอบความเข้ากันได้ของ Android (CTS)
  • แอปต้องแจ้งให้ผู้ใช้ให้สิทธิ์แอปขณะรันไทม์ โปรดดูรายละเอียดที่หัวข้ออัปเดตแอป เราอาจให้ข้อยกเว้นแบบจำกัดแก่แอปเริ่มต้นและตัวแฮนเดิลที่ให้ฟังก์ชันการทำงานพื้นฐานของอุปกรณ์ซึ่งเป็นพื้นฐานของการทำงานตามปกติของอุปกรณ์ (เช่น แอปโทรศัพท์เริ่มต้นของอุปกรณ์สำหรับจัดการ ACTION_CALL อาจเข้าถึงสิทธิ์ของโทรศัพท์ได้) โปรดดูรายละเอียดที่หัวข้อการสร้างข้อยกเว้น
  • แอปที่โหลดไว้ล่วงหน้าซึ่งมีสิทธิ์ที่เป็นอันตรายต้องกำหนดเป้าหมายเป็น API ระดับ 23 และคงรูปแบบสิทธิ์รันไทม์ไว้ กล่าวคือ ขั้นตอน UI ระหว่างการติดตั้งแอปต้องไม่แตกต่างจากการใช้งาน PermissionController ของ AOSP, ผู้ใช้สามารถเพิกถอนสิทธิ์ที่เป็นอันตรายของแอปที่ติดตั้งไว้ล่วงหน้า และอื่นๆ
  • แอป Headless ต้องใช้กิจกรรมเพื่อขอสิทธิ์หรือแชร์ UID กับแอปอื่นที่มีสิทธิ์ที่จำเป็น โปรดดูรายละเอียดที่แอป Headless

การย้ายข้อมูลสิทธิ์

สิทธิ์ที่มอบให้กับแอปใน Android 5.x จะยังคงมีผลอยู่หลังจากอัปเดตเป็น Android 6.0 ขึ้นไป แต่ผู้ใช้สามารถเพิกถอนสิทธิ์เหล่านั้นได้ทุกเมื่อ

ในการอัปเดต Android 9 เป็น 10 สิทธิ์ที่จํากัดอย่างเข้มงวดทั้งหมดจะอยู่ในรายการที่อนุญาต โปรดดูรายละเอียดเกี่ยวกับการใช้สิทธิ์แยกสำหรับเบื้องหน้า/เบื้องหลังที่หัวข้อการเปลี่ยนแปลงด้านความเป็นส่วนตัวของ Android 10 โดยเริ่มจากขอตำแหน่งในเบื้องหลัง

การรวมระบบ

เมื่อผสานรวมรูปแบบสิทธิ์รันไทม์ของแอปสำหรับ Android 6.0 ขึ้นไป คุณต้องอัปเดตแอปที่ติดตั้งไว้ล่วงหน้าให้ทำงานร่วมกับรูปแบบใหม่ได้ นอกจากนี้ คุณยังกำหนดข้อยกเว้นสำหรับแอปที่เป็นตัวแฮนเดิล/ผู้ให้บริการเริ่มต้นสำหรับฟังก์ชันหลัก กำหนดสิทธิ์ที่กำหนดเอง และปรับแต่งธีมที่ใช้ในแอป PermissionController ได้ด้วย

อัปเดตแอป

แอปในอิมเมจระบบและแอปที่ติดตั้งไว้ล่วงหน้าจะไม่ได้รับสิทธิ์ล่วงหน้าโดยอัตโนมัติ เราขอแนะนำให้คุณทำงานร่วมกับนักพัฒนาแอปที่ติดตั้งไว้ล่วงหน้า (OEM, ผู้ให้บริการเครือข่าย และบุคคลที่สาม) เพื่อทำการแก้ไขแอปที่จำเป็นโดยใช้หลักเกณฑ์สำหรับนักพัฒนาแอป กล่าวโดยละเอียดคือ คุณต้องตรวจสอบว่าแอปที่ติดตั้งไว้ล่วงหน้าได้รับการแก้ไขเพื่อหลีกเลี่ยงข้อขัดข้องและปัญหาอื่นๆ เมื่อผู้ใช้เพิกถอนสิทธิ์

แอปที่โหลดไว้ล่วงหน้า

ใน Android 9 และต่ำกว่า แอปที่โหลดไว้ล่วงหน้าซึ่งใช้สิทธิ์ที่เป็นอันตรายต้องกำหนดเป้าหมายเป็น API ระดับ 23 ขึ้นไป และคงรูปแบบสิทธิ์ AOSP ของ Android 6.0 ขึ้นไปไว้ ตัวอย่างเช่น ขั้นตอน UI ขณะติดตั้งแอปต้องไม่แตกต่างจากการใช้งาน PermissionController ใน AOSP ผู้ใช้ยังเพิกถอนสิทธิ์ที่เป็นอันตรายของแอปที่ติดตั้งไว้ล่วงหน้าได้ด้วย

ใน Android 6.0 ถึง 9 ระบบจะมอบสิทธิ์บางอย่างระหว่างขั้นตอนการติดตั้ง อย่างไรก็ตาม ตั้งแต่เวอร์ชัน 10 เป็นต้นไป ขั้นตอนการติดตั้ง (ดำเนินการโดยแอป Package Installer) จะเป็นฟังก์ชันแยกต่างหากจากการให้สิทธิ์ (ในแอป Permission Controller)

แอปแบบ Headless

เฉพาะกิจกรรมเท่านั้นที่ขอสิทธิ์ได้ บริการจะขอสิทธิ์โดยตรงไม่ได้

  • ใน Android 5.1 และเวอร์ชันก่อนหน้า แอปแบบ Headless จะขอสิทธิ์ได้เมื่อติดตั้ง หรือหากติดตั้งไว้ล่วงหน้าโดยไม่ได้ใช้กิจกรรม
  • ใน Android 6.0 ขึ้นไป แอปแบบ Headless ต้องใช้วิธีใดวิธีหนึ่งต่อไปนี้เพื่อขอสิทธิ์
    • เพิ่มกิจกรรมเพื่อขอสิทธิ์ (วิธีนี้เป็นวิธีที่แนะนำ)
    • แชร์ UID กับแอปอื่นที่มีสิทธิ์ที่จำเป็น ใช้วิธีนี้เมื่อคุณต้องการให้แพลตฟอร์มจัดการ APK หลายรายการเป็นแอปเดียวเท่านั้น

โดยมีเป้าหมายเพื่อไม่ให้ผู้ใช้สับสนกับคำขอสิทธิ์ที่ปรากฏขึ้นนอกบริบท

ปรับแต่ง UI ของ PackageInstaller

หากต้องการ คุณสามารถปรับแต่งธีม UI สิทธิ์ได้โดยอัปเดตธีมเริ่มต้นของอุปกรณ์ (Theme.DeviceDefault.Settings และ Theme.DeviceDefault.Light.Dialog.NoActionBar) ที่ PackageInstaller ใช้ อย่างไรก็ตาม เนื่องจากความสอดคล้องเป็นสิ่งสำคัญอย่างยิ่งสำหรับนักพัฒนาแอป คุณจึงปรับแต่งตําแหน่ง ตำแหน่ง และกฎของเวลาที่ UI สิทธิ์จะปรากฏไม่ได้

หากต้องการรวมสตริงสำหรับภาษาอื่นๆ ให้ส่งสตริงไปยัง AOSP

สร้างข้อยกเว้น

คุณสามารถให้สิทธิ์แก่แอปที่เป็นตัวแฮนเดิลหรือผู้ให้บริการเริ่มต้นสำหรับฟังก์ชันหลักของระบบปฏิบัติการล่วงหน้าได้โดยใช้คลาส DefaultPermissionGrantPolicy.java ใน PackageManager ตัวอย่าง

ACTION_CALL (Dialer) Default
Phone, Contacts, SMS, Microphone
SMS_DELIVER_ACTION (SMS/MMS) Default
Phone, Contacts, SMS

กำหนดสิทธิ์ที่กำหนดเอง

คุณสามารถกำหนดสิทธิ์และกลุ่มที่กำหนดเองเป็นปกติหรืออันตราย และเพิ่มสิทธิ์เฉพาะ OEM/ผู้ให้บริการลงในกลุ่มสิทธิ์ที่มีอยู่ได้ เช่นเดียวกับใน Android 5.x และรุ่นก่อนหน้า

ใน Android 6.0 ขึ้นไป หากคุณเพิ่มสิทธิ์ที่เป็นอันตรายใหม่ สิทธิ์ดังกล่าวต้องได้รับการจัดการในลักษณะเดียวกับสิทธิ์ที่เป็นอันตรายอื่นๆ (ขอระหว่างรันไทม์ของแอปและผู้ใช้เพิกถอนได้) ดังนี้

  • คุณสามารถเพิ่มสิทธิ์ใหม่ลงในกลุ่มปัจจุบันได้ แต่จะแก้ไขการแมปสิทธิ์ที่เป็นอันตรายและกลุ่มสิทธิ์ที่เป็นอันตรายของ AOSP ไม่ได้ (กล่าวคือ คุณไม่สามารถนำสิทธิ์ออกจากกลุ่มหนึ่งแล้วมอบหมายให้กับอีกกลุ่มหนึ่ง)
  • คุณสามารถเพิ่มกลุ่มสิทธิ์ใหม่ในแอปที่ติดตั้งในอุปกรณ์ได้ แต่เพิ่มกลุ่มสิทธิ์ใหม่ในไฟล์ Manifest ของแพลตฟอร์มไม่ได้

ทดสอบสิทธิ์

Android มีการทดสอบชุดเครื่องมือทดสอบความเข้ากันได้ (CTS) ที่ยืนยันว่ามีการแมปสิทธิ์แต่ละรายการไปยังกลุ่มที่ถูกต้อง การผ่านการทดสอบเหล่านี้เป็นข้อกำหนดสำหรับความเข้ากันได้กับ CTS ของ Android 6.0 ขึ้นไป

เพิกถอนสิทธิ์

ใน Android 13 ขึ้นไป คุณสามารถเพิกถอนสิทธิ์รันไทม์ที่ตนเองให้ไว้ได้โดยใช้ Context.revokeSelfPermissionsOnKill() การเพิกถอนจะดำเนินการแบบไม่พร้อมกันและจะทริกเกอร์เมื่อดำเนินการได้อย่างปลอดภัยโดยไม่รบกวนผู้ใช้ เมื่อมีการเรียกให้เพิกถอน ระบบจะหยุดกระบวนการทั้งหมดที่ทำงานอยู่ใน UID ที่เรียกให้หยุด

โปรดทราบว่าการเพิกถอนสิทธิ์รายการเดียวอาจไม่แสดงใน UI การตั้งค่า ซึ่งจะจัดการสิทธิ์ตามกลุ่ม โดยปกติแล้ว กลุ่มสิทธิ์จะแสดงเป็น "มีสิทธิ์" ตราบใดที่มีการให้สิทธิ์อย่างน้อย 1 รายการในกลุ่มนั้น หากการทำให้ผู้ใช้ยืนยันการเพิกถอนในการตั้งค่าได้เป็นเรื่องสำคัญสำหรับคุณ โปรดเพิกถอนสิทธิ์ทั้งหมดในกลุ่มสิทธิ์ หากต้องการดูว่าสิทธิ์ใดเป็นของกลุ่มหนึ่งๆ ให้ใช้ PackageManager.getGroupOfPlatformPermission และ PackageManager.getPlatformPermissionsForGroup

เมื่อระบบเพิกถอนสิทธิ์ที่ขอ ระบบจะเพิกถอนสิทธิ์ที่เกี่ยวข้องในเบื้องหลังด้วย หากยังไม่มีการอนุญาตให้สิทธิ์ที่เกี่ยวข้องในเบื้องหน้า

การเพิกถอนจะไม่ทริกเกอร์ตราบใดที่กระบวนการยังคงทำงานอยู่เบื้องหน้า แต่สามารถทริกเกอร์ได้ทันทีโดยปิดกระบวนการทั้งหมดที่ทำงานอยู่ใน uid ปัจจุบันด้วยตนเอง เช่น ใช้ System.exit() อย่างไรก็ตาม เราขอแนะนำให้ระบบเป็นผู้ตัดสินใจว่าควรทริกเกอร์เมื่อใด

หลังจากเพิกถอนสิทธิ์แล้ว คุณจะขอสิทธิ์อีกครั้งได้ และระบบจะแจ้งให้ผู้ใช้ให้สิทธิ์หรือปฏิเสธคำขอ คุณจะขอสิทธิ์ที่ผู้ใช้ปฏิเสธไปแล้วก่อนหน้านี้ไม่ได้ แม้ว่าเราขอแนะนำให้เพิกถอนสิทธิ์ที่คุณมีอยู่ในตอนนี้แต่ไม่จำเป็นต้องใช้แล้ว แต่คุณควรระมัดระวังที่จะไม่แจ้งให้ผู้ใช้ทราบเกี่ยวกับการเพิกถอนจนกว่าสิทธิ์ดังกล่าวจะมีผล