Normal Permission คือหมวดหมู่ของสิทธิ์ใน Android ที่ระบบให้โดยอัตโนมัติโดยไม่ต้องขออนุญาตจากผู้ใช้ ตาม Android Developer Documentation, 2024 สิทธิ์ปกติ มี ProtectionLevel normal และไม่ต้องใช้ไดอะล็อกขณะรันไทม์ แตกต่างจากสิทธิ์อันตราย สิทธิ์เหล่านี้ครอบคลุมการเข้าถึงอินเทอร์เน็ต สถานะเครือข่าย และการสั่น โดยไม่สร้างความเสี่ยงต่อข้อมูลที่ละเอียดอ่อนของผู้ใช้
ประเด็นสำคัญ
Normal Permission คือประเภทของสิทธิ์ระบบใน Android ที่มี ProtectionLevel normal ซึ่งให้กับแอปพลิเคชันโดยอัตโนมัติเมื่อติดตั้ง นักพัฒนาไม่จำเป็นต้องเขียนโค้ดเพื่อขอสิทธิ์ — เพียงประกาศสิทธิ์ใน AndroidManifest.xml ผู้ใช้ไม่เห็นไดอะล็อกใดๆ และไม่สามารถเพิกถอนสิทธิ์ปกติแยกต่างหากได้ ทำได้เพียงลบแอปพลิเคชันทั้งหมดทิ้ง
ระบบ Android จัดประเภทสิทธิ์ปกติว่ามีความเสี่ยงต่ำ — ไม่ให้เข้าถึงข้อมูลส่วนบุคคล กล้อง หรือไมโครโฟน ตัวอย่างทั่วไป: การเข้าถึงอินเทอร์เน็ต การควบคุมการสั่น การอ่านสถานะ Wi-Fi ตาม Android Security Model (2024) ประมาณ 40 เปอร์เซ็นต์ของสิทธิ์ระบบทั้งหมดอยู่ในหมวดหมู่ปกติ
คุณสมบัติที่สำคัญ — สิทธิ์ปกติไม่สามารถเพิกถอนได้ระหว่างรันไทม์ผ่านการตั้งค่า หากผู้ใช้ต้องการปฏิเสธการเข้าถึง วิธีเดียวคือลบแอปพลิเคชัน นักพัฒนาควรพิจารณาเรื่องนี้ในสถาปัตยกรรม แต่สำหรับผู้ใช้แล้ว วิธีการนี้ช่วยให้การโต้ตอบง่ายขึ้น: ไม่มีไดอะล็อกเมื่อเริ่มใช้งานครั้งแรก
การแบ่งเป็นสิทธิ์ปกติและอันตรายปรากฏใน Android 6.0 Marshmallow (API 23) ก่อนเวอร์ชันนี้ สิทธิ์ทั้งหมดจะถูกขอเมื่อติดตั้ง — ผู้ใช้จะเห็นรายการเดียวและยอมรับหรือปฏิเสธทั้งหมด Normal Permission ยังคงรูปแบบนี้สำหรับการดำเนินการที่มีความเสี่ยงต่ำ ในขณะที่ Dangerous เปลี่ยนเป็นคำขอรันไทม์ การเปลี่ยนแปลงนี้ช่วยปรับปรุงประสบการณ์ผู้ใช้และเพิ่มความปลอดภัยในเวลาเดียวกัน
API ระบบ Android จำนวนมากต้องการการประกาศสิทธิ์ปกติอย่างชัดเจน แม้ว่าการเข้าถึงจะเป็นแบบอัตโนมัติ ตัวอย่างเช่น คลาส ConnectivityManager ต้องใช้ ACCESS_NETWORK_STATE, VibratorService ต้องใช้ VIBRATE, WifiManager ต้องใช้ ACCESS_WIFI_STATE หากไม่ประกาศ uses-permission ที่เกี่ยวข้อง การเรียก API เหล่านี้จะทำให้เกิด SecurityException
ProtectionLevel normal คือระดับการป้องกันขั้นต่ำในระบบสิทธิ์ Android สิทธิ์ในระดับนี้จะประกาศใน manifest และระบบจะตรวจสอบการประกาศเมื่อติดตั้ง โดยให้สิทธิ์เข้าใช้โดยไม่ต้องให้ผู้ใช้ดำเนินการใดๆ ไม่มีการแสดงองค์ประกอบ UI ไม่มีการเรียกคืนค่า
กลไกการตรวจสอบทำงานที่ระดับ PackageManager ระหว่างการติดตั้ง APK ระบบจะสแกนแท็ก uses-permission ทั้งหมด กำหนดระดับการป้องกันของแต่ละสิทธิ์โดยจับคู่กับคำจำกัดความของระบบในไฟล์ permissions.xml และสำหรับระดับปกติ เพียงลงทะเบียนการเข้าถึง กระบวนการใช้เวลาเป็นมิลลิวินาทีและไม่ต้องโต้ตอบกับอินเทอร์เฟซผู้ใช้
อัลกอริธึมการให้สิทธิ์ทำงานดังนี้:
ผู้ใช้ไม่สามารถเพิกถอนสิทธิ์ปกติผ่านอินเทอร์เฟซได้ ในการตั้งค่าแอปพลิเคชัน ในส่วนสิทธิ์ จะแสดงเฉพาะสิทธิ์อันตรายเท่านั้น ซึ่งแตกต่างจาก iOS ที่ทุกสิทธิ์ต้องได้รับการยืนยันแยกต่างหาก โดยไม่ขึ้นกับระดับความละเอียดอ่อนของฟังก์ชัน
Normal และ Dangerous Permission เป็นหมวดหมู่การป้องกันที่ตรงกันข้ามสองหมวดหมู่ใน Android ความแตกต่างหลักอยู่ที่วิธีการให้สิทธิ์: สิทธิ์ปกติจะให้โดยอัตโนมัติเมื่อติดตั้ง สิทธิ์อันตรายต้องการความยินยอมอย่างชัดแจ้งผ่านไดอะล็อกขณะรันไทม์ ความแตกต่างนี้สร้างไว้ในสถาปัตยกรรมความปลอดภัยของ Android ตั้งแต่เวอร์ชัน 6.0 Marshmallow
การเปรียบเทียบคุณลักษณะสำคัญ:
| คุณลักษณะ | Normal Permission | Dangerous Permission |
|---|---|---|
| ProtectionLevel | normal | dangerous |
| คำขอผู้ใช้ | ไม่จำเป็น | ไดอะล็อกรันไทม์บังคับ |
| การเพิกถอนได้ | ไม่ได้ เฉพาะลบแอป | ได้ ผ่านการตั้งค่าเมื่อใดก็ได้ |
| ตรวจสอบในโค้ด | PERMISSION_GRANTED เสมอ | checkSelfPermission บังคับ |
| ตัวอย่าง | INTERNET, VIBRATE, ACCESS_NETWORK_STATE | CAMERA, RECORD_AUDIO, ACCESS_FINE_LOCATION |
ผู้ใช้ไม่เห็นไดอะล็อกใดๆ เมื่อขอ Normal Permission หากแอปต้องการ INTERNET — จะได้รับโดยไม่มีเสียงแจ้ง สำหรับ Dangerous Permission ระบบจะแสดงไดอะล็อกแบบโมดัลที่อธิบายการเข้าถึงที่ขอ ผู้ใช้กดอนุญาตหรือปฏิเสธ และภายหลังสามารถเพิกถอนสิทธิ์ได้ตลอดเวลาผ่านการตั้งค่า นี่คือความแตกต่าง UX ที่สำคัญซึ่งกำหนดกลยุทธ์การพัฒนาอินเทอร์เฟซ
Normal ควรใช้ในทุกกรณีที่การเข้าถึงไม่เกี่ยวข้องกับข้อมูลที่ละเอียดอ่อน ACCESS_NETWORK_STATE สำหรับตรวจสอบการเชื่อมต่อ, VIBRATE สำหรับการตอบสนองแบบสัมผัส, INTERNET สำหรับคำขอ HTTP — ทั้งหมดนี้คือสิทธิ์ปกติ การใช้ระดับ dangerous ในที่ที่ normal เพียงพอเป็นแนวทางที่ไม่ดี ทำให้เกิดไดอะล็อกที่ไม่จำเป็นและลดความไว้วางใจของผู้ใช้ในแอปพลิเคชัน
Android กำหนด สิทธิ์ปกติหลายสิบรายการ แต่ละรายการสอดคล้องกับฟังก์ชันระบบเฉพาะ ทั้งหมดสามารถเข้าถึงได้ผ่านค่าคงที่ของคลาส Manifest.permission ด้านล่างคือรายการที่ใช้บ่อยที่สุดในการพัฒนาแอปพลิเคชัน
| ค่าคงที่ | การเข้าถึง | คำอธิบาย |
|---|---|---|
| INTERNET | เครือข่าย | เปิดซ็อกเก็ตเครือข่ายสำหรับคำขอ HTTP |
| ACCESS_NETWORK_STATE | เครือข่าย | รับข้อมูลเกี่ยวกับสถานะเครือข่าย |
| ACCESS_WIFI_STATE | Wi-Fi | อ่านข้อมูลเกี่ยวกับการเชื่อมต่อ Wi-Fi |
| VIBRATE | การสั่น | ควบคุมมอเตอร์สั่นของอุปกรณ์ |
| BLUETOOTH | Bluetooth | เชื่อมต่อกับอุปกรณ์ Bluetooth |
| WAKE_LOCK | พลังงาน | ป้องกันไม่ให้โปรเซสเซอร์เข้าสู่โหมดหลับ |
| SET_ALARM | ปลุก | ตั้งปลุกผ่าน AlarmManager |
| CHANGE_NETWORK_STATE | เครือข่าย | เปลี่ยนสถานะการเชื่อมต่อเครือข่าย |
สิทธิ์ปกติไม่ได้ถูกจัดกลุ่มเป็น Permission Group เพื่อวัตถุประสงค์ในการแสดงผลบน UI กลุ่มใน Android มีไว้สำหรับหน้าจอการตั้งค่าที่แสดงเฉพาะสิทธิ์อันตรายเท่านั้น อย่างไรก็ตาม สิทธิ์ปกติสามารถแบ่งตามตรรกะเป็นหมวดหมู่: เครือข่าย (INTERNET, ACCESS_NETWORK_STATE), ฮาร์ดแวร์ (VIBRATE, WAKE_LOCK), ระบบ (SET_ALARM) และสิทธิ์ Bluetooth
ค่าคงที่บางตัวจาก Manifest.permission อาจเปลี่ยนระดับการป้องกันใน Android เวอร์ชันต่างๆ ตัวอย่างเช่น BLUETOOTH_CONNECT บน Android 12+ กลายเป็นสิทธิ์อันตรายที่ต้องขอรันไทม์ แม้ว่าในเวอร์ชันเก่าจะเป็นปกติ นักพัฒนาแนะนำให้ตรวจสอบ protectionLevel ปัจจุบันสำหรับ API เป้าหมายผ่านเอกสารประกอบ
นักพัฒนาสามารถตรวจสอบโดยโปรแกรมว่าสิทธิ์เป็นปกติหรือไม่ผ่าน PackageManager เมธอด getPermissionInfo ส่งคืน PermissionInfo ซึ่งฟิลด์ protectionLevel มีแฟล็ก PermissionInfo.PROTECTION_NORMAL ซึ่งมีประโยชน์สำหรับการจัดการแบบไดนามิกและการดีบัก
fun isNormalPermission(permission: String): Boolean {
val pm = packageManager
val info = pm.getPermissionInfo(
permission,
PackageManager.GET_META_DATA
)
return info.protectionLevel ==
PermissionInfo.PROTECTION_NORMAL
}
การประกาศ Normal Permission ใน AndroidManifest.xml เป็นการดำเนินการที่ง่ายที่สุด โดยต้องใช้แท็ก uses-permission เพียงแท็กเดียว ไม่จำเป็นต้องกำหนดค่า protectionLevel เพิ่มเติม เนื่องจากระดับการป้องกันถูกกำหนดโดยคำจำกัดความของระบบ ไม่ใช่โดย manifest ของแอปพลิเคชัน นักพัฒนาเพียงระบุชื่อเต็มของค่าคงที่
<!-- AndroidManifest.xml -->
<uses-permission
android:name="android.permission.INTERNET" />
<uses-permission
android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission
android:name="android.permission.VIBRATE" />
ระบบประมวลผลการประกาศทั้งหมดเมื่อติดตั้ง หากสิทธิ์ที่ประกาศอย่างน้อยหนึ่งรายการมี protectionLevel ที่แตกต่างจาก normal จะต้องมีคำขอรันไทม์ INTERNET เป็นสิทธิ์ปกติที่ได้รับความนิยมมากที่สุด ซึ่งมีอยู่ในแอปพลิเคชัน Android ส่วนใหญ่ โดยเฉพาะแอปที่ทำคำขอ HTTP หรือโหลดเนื้อหาจากเครือข่าย
ตัวอย่างที่สมบูรณ์ของ AndroidManifest.xml ที่มีสิทธิ์ปกติและอันตรายแสดงให้เห็นความแตกต่าง: ทางไวยากรณ์ แท็ก uses-permission เหมือนกัน แต่ขณะรันไทม์ INTERNET และ VIBRATE จะได้รับโดยอัตโนมัติ ในขณะที่ CAMERA จะต้องมีไดอะล็อก
<manifest
xmlns:android="http://schemas.android.com/apk/res/android">
<!-- Normal permissions -->
<uses-permission
android:name="android.permission.INTERNET" />
<uses-permission
android:name="android.permission.VIBRATE" />
<!-- Dangerous permission -->
<uses-permission
android:name="android.permission.CAMERA" />
</manifest>
เมื่อใช้ไลบรารี — Google Play Services, Firebase, Glide — ไลบรารีเหล่านั้นอาจเพิ่ม uses-permission ของตัวเองลงใน manifest สุดท้ายผ่าน Manifest Merger บางรายการเป็นปกติ (INTERNET สำหรับ Firebase) บางรายการเป็นอันตราย (ACCESS_FINE_LOCATION สำหรับ Google Maps) นักพัฒนาควรตรวจสอบ manifest ที่รวมกันสุดท้ายใน build/outputs/logs/manifest-merger-report.txt ก่อนเผยแพร่
Normal Permission มีข้อจำกัดพื้นฐานสองประการ: ผู้ใช้ไม่สามารถเพิกถอนได้ และไม่มีอินเทอร์เฟซการจัดการ หากผู้ใช้ไม่ไว้วางใจแอปพลิเคชัน แต่สิทธิ์ปกติถูกให้ไปแล้วโดยอัตโนมัติ — ทางออกเดียวคือลบแอปพลิเคชัน สิ่งนี้สร้างความเสี่ยง เนื่องจากสิทธิ์ปกติไม่สามารถถูกบล็อกโดยวิธีการมาตรฐานของ Android
ข้อจำกัดเพิ่มเติมปรากฏบนอุปกรณ์ที่มีหลายโปรไฟล์ (Work Profile, Multiple Users) Normal Permission จะให้กับทุกโปรไฟล์พร้อมกัน — แอปพลิเคชันไม่สามารถจำกัดสิทธิ์ให้เฉพาะโปรไฟล์เดียว ในสถานการณ์องค์กร จะแก้ไขผ่าน Managed Configurations
ไม่สามารถตรวจสอบได้ว่าแอปพลิเคชันกำลังใช้ Normal Permission ในขณะนั้นหรือไม่ เมธอดของระบบ checkSelfPermission ทำงานเฉพาะกับสิทธิ์อันตรายเท่านั้น สำหรับสิทธิ์ปกติ จะส่งคืน PERMISSION_GRANTED เสมอ ซึ่งไม่สะท้อนกิจกรรมจริง ควรพิจารณาเรื่องนี้ในการตรวจสอบความปลอดภัยและการวิเคราะห์พฤติกรรมของแอปพลิเคชัน
นอกจากนี้ ควรจำไว้ว่าผู้ผลิตอุปกรณ์บางราย (Xiaomi, Huawei, Samsung) ปรับเปลี่ยนพฤติกรรมมาตรฐานของสิทธิ์ ในเฟิร์มแวร์ของพวกเขา Normal Permission อาจต้องการสิทธิ์เพิ่มเติมในเชลล์ MIUI หรือ EMUI ที่เป็นกรรมสิทธิ์ นักพัฒนาแนะนำให้ทดสอบบนอุปกรณ์จริงจากผู้ผลิตต่างๆ
คำถามที่พบบ่อย
Normal Permission จะให้โดยอัตโนมัติเมื่อติดตั้งโดยไม่มีไดอะล็อก Dangerous ต้องการคำขอรันไทม์โดยได้รับความยินยอมอย่างชัดแจ้งจากผู้ใช้และสามารถเพิกถอนผ่านการตั้งค่าได้ Normal ใช้ ProtectionLevel normal, Dangerous ใช้ protectionLevel dangerous
ไม่ สำหรับสิทธิ์ปกติ เพียงประกาศ uses-permission ใน AndroidManifest.xml ก็เพียงพอ ไม่ต้องใช้โค้ดขอสิทธิ์ — ระบบให้การเข้าถึงโดยอัตโนมัติ ซึ่งแตกต่างจากสิทธิ์อันตรายที่ต้องใช้ ActivityCompat.requestPermissions
ที่ใช้บ่อยที่สุด: INTERNET (คำขอเครือข่าย), ACCESS_NETWORK_STATE (ตรวจสอบการเชื่อมต่อ), VIBRATE (การตอบสนองแบบสัมผัส) และ WAKE_LOCK (ทำให้โปรเซสเซอร์ตื่นอยู่) แอปพลิเคชัน Android เกือบทุกตัวใช้ INTERNET อย่างน้อย
ไม่ Normal Permission ไม่สามารถเพิกถอนผ่านการตั้งค่าแอปพลิเคชันได้ วิธีเดียวที่จะหยุดการเข้าถึงคือการลบแอปพลิเคชัน นี่คือความแตกต่างสำคัญจากสิทธิ์อันตรายที่ผู้ใช้สามารถปิดใช้งานได้ตลอดเวลา
ใช้ PackageManager.getPermissionInfo โดยส่งชื่อสตริงของสิทธิ์ เมธอดส่งคืน PermissionInfo พร้อมฟิลด์ protectionLevel เปรียบเทียบกับค่าคงที่ PermissionInfo.PROTECTION_NORMAL หรือ PROTECTION_DANGEROUS เพื่อกำหนดหมวดหมู่
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม