AndroidManifest.xml เป็นไฟล์กำหนดค่าที่จำเป็นของทุกแอปพลิเคชัน Android ซึ่งอธิบายส่วนประกอบ สิทธิ์อนุญาต และเมทาดาทาของแอป ระบบ Android จะอ่านไฟล์นี้เมื่อติดตั้งและเรียกใช้แต่ละแอปพลิเคชัน ตามข้อมูลจาก Android Developers, 2025 หากไม่มีแมนิเฟสต์ที่ถูกต้อง แอปพลิเคชันจะไม่ถูกติดตั้งบนอุปกรณ์ AndroidManifest.xml จะลงทะเบียน Activity, Service, BroadcastReceiver และ ContentProvider ให้กับระบบปฏิบัติการ
ใจความสำคัญ
AndroidManifest.xml คือไฟล์กำหนดค่ารากในรูปแบบ XML ที่ทุกโปรเจกต์ Android ต้องมีในไดเรกทอรี app/src/main ระบบ Android จะวิเคราะห์ไฟล์นี้ก่อนเรียกใช้โค้ดใด ๆ ของแอปพลิเคชัน — ในขั้นตอนการแยกวิเคราะห์ APK ขณะติดตั้ง หากแมนิเฟสต์มีข้อผิดพลาดทางไวยากรณ์หรือขาดการประกาศที่จำเป็น การติดตั้งจะถูกยกเลิกพร้อมข้อความแสดงข้อผิดพลาด
ไฟล์นี้ประกอบด้วย การประกาศ ที่สมบูรณ์ของแอปพลิเคชัน: รายการส่วนประกอบทั้งหมด (Activity, Service, BroadcastReceiver, ContentProvider) สิทธิ์อนุญาตที่ร้องขอ เวอร์ชัน SDK ขั้นต่ำ ข้อกำหนดด้านฮาร์ดแวร์ และการกำหนดค่าธีมและสไตล์ ทุกส่วนประกอบที่ระบบหรือแอปพลิเคชันอื่นสามารถเรียกใช้ได้ จะต้องประกาศอย่างชัดเจนในแมนิเฟสต์ นี่คือข้อกำหนดด้านความปลอดภัย: หากไม่มีการประกาศอย่างชัดเจน ส่วนประกอบจะไม่สามารถถูกเรียกใช้งานได้
หากไม่มีแมนิเฟสต์ที่กำหนดค่าอย่างถูกต้อง แอปพลิเคชันจะไม่สามารถติดตั้งผ่าน Google Play หรือการติดตั้งข้างเคียง ระบบจะตรวจสอบแมนิเฟสต์ในขั้นตอนการแยกวิเคราะห์ APK และปฏิเสธการติดตั้งหากมีข้อผิดพลาด Google Play ยังสแกนแมนิเฟสต์เพื่อหาการกำหนดค่าที่ไม่ปลอดภัย: หาก exported=true บนส่วนประกอบที่ไม่มี intent-filter จะมีการเตือน และหากไม่มีสิทธิ์อนุญาตที่จำเป็นสำหรับ targetSdk 34+ การเผยแพร่จะถูกบล็อก ดังนั้นการทำความเข้าใจโครงสร้างแมนิเฟสต์จึงเป็นทักษะที่จำเป็นสำหรับนักพัฒนา Android
ทุกส่วนประกอบของแอปพลิเคชัน Android ต้อง ลงทะเบียน อย่างชัดเจนในแมนิเฟสต์ นี่คือข้อกำหนดบังคับของแพลตฟอร์มสำหรับส่วนประกอบทั้งสี่ประเภท หากไม่ลงทะเบียน ส่วนประกอบจะไม่สามารถถูกสร้างขึ้นโดยระบบได้ และการพยายามเรียกใช้จะทำให้เกิดข้อยกเว้น ActivityNotFoundException หรือข้อยกเว้นที่คล้ายกัน ส่วนประกอบจะถูกลงทะเบียนภายในแท็ก application โดยลำดับไม่มีผลต่อการทำงาน
แท็ก activity ลงทะเบียนหน้าจอของแอปพลิเคชัน แอตทริบิวต์ exported กำหนดว่าแอปพลิเคชันอื่นสามารถเรียกใช้ Activity นี้ได้หรือไม่ ตั้งแต่ Android 12 เป็นต้นไป การไม่มี exported ทั้งที่มี intent-filter จะทำให้เกิดข้อผิดพลาดในการคอมไพล์ — นี่คือข้อกำหนดด้านความปลอดภัย จุดเริ่มต้นถูกกำหนดผ่าน intent-filter ที่มี action MAIN และ category LAUNCHER แต่ละ Activity ต้องมี android:name ที่ไม่ซ้ำกัน ซึ่งสอดคล้องกับชื่อคลาสแบบเต็มหรือแบบสัมพัทธ์
<activity
android:name=".MainActivity"
android:exported="true"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
แท็ก service กำหนดบริการพื้นหลัง ตั้งแต่ Android 8 เป็นต้นไป บริการพื้นหลังมีข้อจำกัดที่เข้มงวด: foreground service ต้องการการแจ้งเตือนที่จำเป็นพร้อมไอคอนที่ผู้ใช้มองเห็นได้ และ bound service จะทำงานเมื่อมีไคลเอนต์ที่เชื่อมต่ออยู่เท่านั้น บริการที่ทำงานในพื้นหลังโดยไม่มีการแจ้งเตือนจะถูกระบบยุติโดยอัตโนมัติภายในไม่กี่นาทีหลังจากแอปพลิเคชันเข้าสู่โหมดพื้นหลัง สำหรับงานที่ใช้เวลานาน ให้ใช้ WorkManager แทน Service
<service
android:name=".SyncService"
android:exported="false"
android:foregroundServiceType="dataSync" />
แท็ก receiver ประกาศตัวรับสัญญาณของข้อความกระจายเสียงของระบบหรือแบบกำหนดเอง ตั้งแต่ Android 8 เป็นต้นไป บรอดแคสต์โดยนัยส่วนใหญ่จะไม่ถูกส่งไปยังตัวรับสัญญาณที่ประกาศแบบคงที่ในแมนิเฟสต์อีกต่อไป แนะนำให้ลงทะเบียนตัวรับสัญญาณแบบไดนามิกผ่าน Context.registerReceiver ในโค้ดแทน ข้อยกเว้นคือบรอดแคสต์ของระบบบางรายการ เช่น BOOT_COMPLETED ซึ่งยังคงต้องการการลงทะเบียนแบบคงที่ในแมนิเฟสต์
<receiver
android:name=".ConnectivityReceiver"
android:exported="true">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
สิทธิ์อนุญาตอันตรายแต่ละรายการใน Android ต้องมีการ ประกาศ ในแมนิเฟสต์ผ่านแท็ก uses-permission ตั้งแต่ Android 6 เป็นต้นไป สิทธิ์อนุญาตอันตรายจะถูกขอระหว่างการทำงานผ่านไดอะล็อกกับผู้ใช้ แต่การประกาศในแมนิเฟสต์ยังคงเป็นข้อบังคับ หากไม่มี การเรียกเมธอด requestPermissions จะทำให้เกิดข้อยกเว้น SecurityException สิทธิ์อนุญาตระดับปกติ เช่น INTERNET และ ACCESS_NETWORK_STATE จะได้รับโดยอัตโนมัติเมื่อติดตั้ง
| สิทธิ์อนุญาต | วัตถุประสงค์ |
|---|---|
| CAMERA | เข้าถึงกล้องของอุปกรณ์สำหรับถ่ายภาพและวิดีโอ |
| ACCESS_FINE_LOCATION | ตำแหน่งที่แน่นอนผ่าน GPS และเครือข่าย |
| RECORD_AUDIO | บันทึกเสียงจากไมโครโฟนของอุปกรณ์ |
| READ_CONTACTS | อ่านรายชื่อจากสมุดโทรศัพท์ |
| POST_NOTIFICATIONS | ส่งการแจ้งเตือนบน Android 13+ |
แท็ก uses-permission-sdk-23 ระบุสิทธิ์อนุญาตที่จำเป็นเฉพาะบน Android 6.0+ เท่านั้น ซึ่งช่วยให้คงความเข้ากันได้กับเวอร์ชันเก่าโดยไม่ต้องขอสิทธิ์อนุญาตที่ไม่มีอยู่จริง ตัวอย่างเช่น POST_NOTIFICATIONS ใช้งานได้เฉพาะบน Android 13+ ดังนั้นจึงควรระบุผ่าน uses-permission-sdk-33 เพื่อหลีกเลี่ยงข้อผิดพลาดสิทธิ์อนุญาตที่ไม่รู้จักบนอุปกรณ์รุ่นเก่า แอตทริบิวต์ maxSdkVersion ใน uses-permission ช่วยให้เพิกถอนสิทธิ์อนุญาตที่ไม่จำเป็นโดยอัตโนมัติเมื่ออัปเดตแอปพลิเคชันบน Android เวอร์ชันใหม่
สิทธิ์อนุญาตระดับ ปกติ (INTERNET, ACCESS_NETWORK_STATE) จะได้รับโดยอัตโนมัติเมื่อติดตั้งและไม่ต้องขอขณะรันไทม์ สิทธิ์เหล่านี้ก็ประกาศผ่าน uses-permission เช่นกัน แต่ไม่แสดงต่อผู้ใช้ในไดอะล็อก สำหรับการควบคุมการเข้าถึงส่วนประกอบของแอปพลิเคชันจากแอปอื่น จะใช้กลไก permission-protected components: สามารถระบุสิทธิ์อนุญาตแบบกำหนดเองที่ระดับ Activity หรือ Service ซึ่งระบบจะตรวจสอบเมื่อมีการเรียกใช้ส่วนประกอบจากภายนอก ซึ่งให้ระดับความปลอดภัยเพิ่มเติมสำหรับการสื่อสารระหว่างกระบวนการ
แท็ก intent-filter ในแมนิเฟสต์ประกาศว่าอินเทนต์โดยนัยใดที่ส่วนประกอบสามารถจัดการได้ นี่คือกลไกที่ Android ใช้เชื่อมโยงการทำงานของระบบหรือแบบกำหนดเองกับแอปพลิเคชัน Intent filter ประกอบด้วยสามองค์ประกอบ: action (การกระทำ), category (หมวดหมู่) และ data (ข้อมูล) ทั้งสามสามารถรวมกันเพื่ออธิบายอย่างแม่นยำว่าอินเทนต์ใดที่ส่วนประกอบควรได้รับ ระบบจะเลือกส่วนประกอบที่เหมาะสมโดยพิจารณาจากตัวกรองที่เฉพาะเจาะจงที่สุด
<activity android:name=".DeepLinkActivity">
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="https"
android:host="itsectr.com"
android:pathPrefix="/app" />
</intent-filter>
</activity>
แอตทริบิวต์ autoVerify เปิดใช้งานการตรวจสอบ Android App Links: ระบบจะติดต่อเซิร์ฟเวอร์เพื่อยืนยันความเป็นเจ้าของโดเมน หากไม่มีการตรวจสอบ ดีพลิงก์จะทำงานผ่านไดอะล็อกตัวเลือกมาตรฐาน ซึ่งผู้ใช้เลือกแอปพลิเคชันที่จะเปิดลิงก์ หลังจากการตรวจสอบสำเร็จ ลิงก์จะเปิดในแอปพลิเคชันโดยตรงโดยไม่ต้องแสดงไดอะล็อก Google Search Console ยังใช้ autoVerify ในการจัดทำดัชนีดีพลิงก์และแสดงในผลการค้นหา
ตัวกรองที่มี action.VIEW และหมวดหมู่ DEFAULT และ BROWSABLE จัดการลิงก์จากเบราว์เซอร์ อีเมล และแอปพลิเคชันอื่น นี่คือกลไกหลักในการimplementดีพลิงก์ใน Android สำหรับการรองรับสคีมา URL แบบกำหนดเอง เช่น myapp:// เพียงระบุ scheme โดยไม่ต้องมี host อย่างไรก็ตาม Google แนะนำให้ใช้ HTTPS ดีพลิงก์แทนสคีมาแบบกำหนดเอง เนื่องจากปลอดภัยกว่าและไม่ต้องการสิทธิ์อนุญาตเพิ่มเติม สคีมาแบบกำหนดเองสามารถถูกดักจับโดยแอปพลิเคชันใด ๆ ที่ลงทะเบียนสคีมาเดียวกัน
แท็กราก manifest มีแอตทริบิวต์ของแพ็กเกจ เวอร์ชัน และ SDK แท็ก application เก็บการตั้งค่าระดับโลก: ธีม ไอคอน ป้ายชื่อ และแฟล็กการดีบัก แอตทริบิวต์ของ manifest กำหนดการกำหนดเวอร์ชันในระดับแพ็กเกจ ในขณะที่แอตทริบิวต์ของ application กำหนดลักษณะและพฤติกรรมโดยรวมของแอปพลิเคชัน ค่าสามารถเป็นข้อมูลอ้างอิงทรัพยากรผ่าน @-ซินแท็กซ์หรือสตริงลิเทอรัล
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.itsectr.myapp"
<uses-sdk
android:minSdkVersion="24"
android:targetSdkVersion="34" />
<application
android:label="MyApp"
android:icon="@mipmap/ic_launcher"
android:theme="@style/Theme.MyApp"
android:supportsRtl="true"
android:allowBackup="true">
<!-- ส่วนประกอบของแอปพลิเคชัน -->
</application>
</manifest>
แท็ก meta-data ภายใน application ช่วยให้เก็บคู่คีย์-ค่าได้ตามต้องการ สะดวกสำหรับการกำหนดค่าไลบรารีของบริษัทอื่น: คีย์ API, ที่อยู่เอนด์พอยต์ และแฟล็กฟังก์ชันการทำงาน ข้อมูลจาก meta-data สามารถเข้าถึงได้ผ่าน PackageManager.getApplicationInfo().metaData ในรันไทม์ ตัวอย่างเช่น Firebase และ Google Maps ใช้ meta-data เพื่อส่งคีย์การเข้าถึงโดยไม่ต้องฮาร์ดโค้ดในซอร์สโค้ด คีย์จะถูกกำหนดในแมนิเฟสต์และสามารถแตกต่างกันไปตามรสชาติของการคอมไพล์
แอตทริบิวต์ android:extractNativeLibs ควบคุมการแตกไฟล์ไลบรารีเนทีฟจาก APK สำหรับแอปพลิเคชันที่มี targetSdk 34+ ต้องระบุแอตทริบิวต์นี้อย่างชัดเจน มิฉะนั้นการคอมไพล์อาจล้มเหลวด้วยข้อผิดพลาด INSTALL_FAILED_INVALID_APK หาก extractNativeLibs=false ไลบรารีเนทีฟจะยังคงอยู่ภายใน APK โดยไม่ถูกแตกไฟล์ ซึ่งลดขนาดของแอปพลิเคชันที่ติดตั้ง แต่เพิ่มเวลาในการโหลดไลบรารี สำหรับแอปพลิเคชันสมัยใหม่ส่วนใหญ่ แนะนำให้ใช้ extractNativeLibs=false เพื่อลดพื้นที่ดิสก์ที่ใช้บนอุปกรณ์ผู้ใช้
แอตทริบิวต์ android:networkSecurityConfig ช่วยให้กำหนดไฟล์กำหนดค่าความปลอดภัยเครือข่ายได้ สำคัญโดยเฉพาะสำหรับแอปพลิเคชันที่มี targetSdk 28+ ซึ่งทราฟฟิก HTTP ถูกบล็อกโดยค่าเริ่มต้น ไฟล์กำหนดค่าจะกำหนดใบรับรองที่เชื่อถือได้ โดเมนสำหรับการเชื่อมต่อ HTTP และกฎการปักหมุดใบรับรอง ซึ่งแทนที่แอตทริบิวต์ android:usesCleartextTraffic ที่เลิกใช้แล้ว และให้กลไกที่ยืดหยุ่นมากขึ้นสำหรับการจัดการความปลอดภัยการเชื่อมต่อในระดับ OS
แอตทริบิวต์ android:largeHeap ขนาดฮีปที่เพิ่มขึ้นสำหรับแอปพลิเคชัน โดยค่าเริ่มต้น Android จะจัดสรรหน่วยความจำจำกัดให้แต่ละแอปพลิเคชัน ขึ้นอยู่กับอุปกรณ์และเวอร์ชัน OS หากแอปพลิเคชันทำงานกับภาพขนาดใหญ่ วิดีโอ หรือชุดข้อมูลขนาดใหญ่ largeHeap สามารถป้องกัน OutOfMemoryError ได้ อย่างไรก็ตาม การใช้แอตทริบิวต์นี้ในทางที่ผิดเป็นอันตราย: แอปพลิเคชันที่ใช้หน่วยความจำมากจะถูกระบบยุติเร็วขึ้นเมื่อทรัพยากรไม่เพียงพอ ใช้ largeHeap หลังจากการทำโปรไฟล์และยืนยันความจำเป็นเท่านั้น
คำถามที่พบบ่อย
ตั้งแต่ Android 12 เป็นต้นไป การไม่มีแอตทริบิวต์ exported ทั้งที่มี intent-filter จะทำให้เกิดข้อผิดพลาดในการคอมไพล์ ระบบต้องการการระบุการมองเห็นของแต่ละส่วนประกอบที่มี intent-filter อย่างชัดเจน — นี่คือมาตรการความปลอดภัยเพื่อป้องกันการเปิดส่วนประกอบโดยไม่ตั้งใจจากแอปพลิเคชันอื่น สำหรับ Activity ที่ไม่มี intent-filter exported มีค่าเริ่มต้นเป็น false
ได้ แต่ในตัวเรียกใช้งานจะแสดงไอคอนแอปพลิเคชันหลายไอคอน แต่ละ Activity ที่มี MAIN/LAUNCHER จะกลายเป็นจุดเริ่มต้นที่แยกต่างหาก ใช้สำหรับสร้างทางลัดไปยังส่วนต่าง ๆ ของแอปพลิเคชัน เช่น การไปที่การตั้งค่าหรือสร้างรายการใหม่โดยตรง แต่ละไอคอนจะเปิด Activity ที่เกี่ยวข้องโดยตรง
Android ผสานแมนิเฟสต์จากไลบรารีกับ แมนิเฟสต์ หลักของแอปพลิเคชัน เมื่อแอตทริบิวต์ขัดแย้งกัน ให้ใช้ tools:replace หรือ tools:node="merge" เพื่อแก้ไข กลไกนี้เป็นอัตโนมัติ: เมื่อเพิ่มไลบรารีผ่าน Gradle แมนิเฟสต์ของมันจะถูกผสานกับแมนิเฟสต์หลัก หากต้องการยกเลิกหรือแทนที่แอตทริบิวต์จากไลบรารี ให้ใช้ tools:node="remove" หรือ tools:replace="attributeName"
สาเหตุทั่วไป: ไม่ได้ประกาศสิทธิ์อนุญาตในแมนิเฟสต์ผ่าน uses-permission, ใช้สิทธิ์อนุญาตระดับปกติ (ไม่ต้องขอขณะรันไทม์), ผู้ใช้เลือก “ไม่ถามอีก” และสิทธิ์อนุญาตถูกปฏิเสธถาวร, หรือ targetSdkVersion ต่ำกว่า 23 ซึ่งสิทธิ์อนุญาตจะถูกขอเมื่อติดตั้ง สำหรับการวินิจฉัย ให้ตรวจสอบแมนิเฟสต์และล็อกผ่าน adb logcat
แอตทริบิวต์ android:debuggable เปิดใช้งานการดีบักแอปพลิเคชันผ่าน ADB สำหรับบิลด์ที่เผยแพร่ใน Google Play จะต้องเป็น false หาก debuggable=true ในบิลด์ที่เผยแพร่ ผู้ไม่ประสงค์ดีสามารถเชื่อมต่อกับแอปพลิเคชันผ่าน ADB อ่านข้อมูล และรันโค้ดตามอำเภอใจ Google Play จะบล็อกการเผยแพร่บิลด์ที่มี debuggable=true โดยอัตโนมัติ
สรุป
เราจะพัฒนาแอปพลิเคชันบนมือถือแบบครบวงจร
IT Sectr สร้างแอปพลิเคชัน iOS และ Android สำหรับสตาร์ทอัพและธุรกิจตั้งแต่ปี 2017 เราจะให้คำแนะนำและเสนอวิธีแก้ปัญหาที่ดีที่สุดแก่คุณ
อ่านเพิ่มเติม