Tổng quan về tệp kê khai ứng dụng

Mỗi dự án ứng dụng phải có một tệp AndroidManifest.xml (có tên chính xác như vậy) ở gốc của nhóm tài nguyên dự án. Tệp kê khai mô tả thông tin thiết yếu về ứng dụng của bạn cho các công cụ xây dựng của Android, hệ điều hành Android và Google Play.

Tệp kê khai bắt buộc phải khai báo những nội dung sau:

  • Các thành phần của ứng dụng, bao gồm tất cả các hoạt động, dịch vụ, broadcast receiver và nhà cung cấp nội dung. Mỗi thành phần phải xác định các thuộc tính cơ bản, chẳng hạn như tên lớp Kotlin hoặc Java của thành phần đó. Tệp kê khai cũng có thể khai báo các tính năng, chẳng hạn như cấu hình thiết bị mà nó có thể xử lý, cũng như các bộ lọc ý định mô tả cách khởi động thành phần. Tìm hiểu thêm về thành phần ứng dụng trong phần sau.
  • Các quyền mà ứng dụng cần có để truy cập các phần được bảo vệ của hệ thống hoặc ứng dụng khác. Tệp kê khai cũng khai báo mọi quyền mà các ứng dụng khác phải có nếu muốn truy cập vào nội dung của ứng dụng này. Tìm hiểu thêm về quyền trong phần sau.
  • Các tính năng phần cứng và phần mềm mà ứng dụng yêu cầu. Điều này quyết định thiết bị nào có thể cài đặt ứng dụng từ Google Play. Tìm hiểu thêm về khả năng tương thích với thiết bị trong phần sau.

Nếu bạn sử dụng Android Studio để xây dựng ứng dụng, thì tệp kê khai sẽ được tạo cho bạn và hầu hết thành phần thiết yếu của tệp kê khai đều sẽ được thêm vào khi bạn xây dựng ứng dụng, nhất là khi sử dụng mẫu mã.

Đặc điểm của tệp

Các phần sau đây mô tả cách mà một số đặc điểm quan trọng nhất của ứng dụng được phản ánh trong tệp kê khai.

Thành phần ứng dụng

Trong tệp kê khai, hãy khai báo phần tử XML tương ứng với mỗi thành phần ứng dụng mà bạn tạo trong ứng dụng:

Nếu bạn tạo lớp con cho bất kỳ thành phần nào trong số các thành phần này mà không khai báo trong tệp kê khai, thì hệ thống sẽ không thể khởi động thành phần đó.

Chỉ định tên lớp con bằng thuộc tính name, sử dụng ký hiệu gói hoàn chỉnh. Ví dụ: Bạn khai báo một lớp con Activity như sau:

<manifest ... >
    <application ... >
        <activity android:name="com.example.myapp.MainActivity" ... >
        </activity>
    </application>
</manifest>

Tuy nhiên, nếu ký tự đầu tiên trong giá trị name là dấu chấm, thì không gian tên của ứng dụng (từ thuộc tính namespace của tệp build.gradle cấp mô-đun) sẽ được thêm vào trước tên. Ví dụ: nếu không gian tên là "com.example.myapp", thì tên hoạt động sau sẽ được phân giải thành com.example.myapp.MainActivity:

<manifest ... >
    <application ... >
        <activity android:name=".MainActivity" ... >
            ...
        </activity>
    </application>
</manifest>

Để biết thêm thông tin về cách đặt tên gói hoặc không gian tên, hãy xem phần Đặt không gian tên.

Nếu bạn có các thành phần ứng dụng nằm trong các gói con, chẳng hạn như trong com.example.myapp.purchases, thì giá trị name phải thêm tên gói con bị thiếu, chẳng hạn như ".purchases.PayActivity" hoặc hãy sử dụng tên gói đủ điều kiện.

Bộ lọc ý định

Các hoạt động trong ứng dụng, dịch vụ và broadcast receiver được ý định kích hoạt. Ý định là một thông báo được xác định bằng một đối tượng Intent mô tả một hành động cần thực hiện, bao gồm dữ liệu cần thực hiện, danh mục của thành phần sẽ thực hiện hành động và các hướng dẫn khác.

Khi một ứng dụng gửi ý định đến hệ thống, hệ thống sẽ xác định một thành phần ứng dụng có thể xử lý ý định đó dựa trên nội dung khai báo của bộ lọc ý định trong tệp kê khai của mỗi ứng dụng. Hệ thống sẽ khởi chạy một thực thể của thành phần phù hợp và truyền đối tượng Intent đến thành phần đó. Nếu có nhiều ứng dụng có thể xử lý ý định này, thì người dùng có thể chọn ứng dụng sẽ dùng.

Một thành phần ứng dụng có thể có số lượng bộ lọc ý định bất kỳ (xác định bởi phần tử <intent-filter>), mỗi bộ lọc ý định mô tả một tính năng của thành phần đó.

Để biết thêm thông tin, hãy xem tài liệu về Ý định và bộ lọc ý định.

Biểu tượng và nhãn

Một số phần tử trong tệp kê khai có thuộc tính icon để trình bày một biểu tượng nhỏ và thuộc tính label để trình bày một nhãn văn bản với người dùng, cho thành phần ứng dụng tương ứng.

Trong mọi trường hợp, biểu tượng và nhãn được đặt trong phần tử mẹ sẽ trở thành giá trị iconlabel mặc định cho tất cả các phần tử con. Ví dụ: biểu tượng và nhãn được đặt trong phần tử <application> sẽ là biểu tượng và nhãn mặc định cho mỗi thành phần của ứng dụng, chẳng hạn như tất cả các hoạt động.

Biểu tượng và nhãn được đặt trong <intent-filter> của một thành phần sẽ hiển thị với người dùng mỗi khi thành phần đó được biểu thị dưới dạng một tuỳ chọn để thực hiện ý định. Theo mặc định, biểu tượng này được kế thừa từ bất kỳ biểu tượng nào được khai báo cho phần tử mẹ (phần tử <activity> hoặc <application>).

Bạn nên thay đổi biểu tượng cho bộ lọc ý định nếu bộ lọc đó cung cấp một hành động duy nhất mà bạn muốn chỉ định rõ hơn trong hộp thoại bộ chọn. Để biết thêm thông tin, hãy xem phần Cho phép ứng dụng khác bắt đầu hoạt động của bạn.

Quyền

Các ứng dụng Android phải gửi yêu cầu mới có quyền truy cập vào dữ liệu nhạy cảm của người dùng, chẳng hạn như danh bạ và SMS hoặc một số tính năng hệ thống, chẳng hạn như quyền truy cập Internet và camera. Mỗi quyền được xác định bằng một nhãn duy nhất. Ví dụ: một ứng dụng cần gửi tin nhắn SMS phải có dòng sau trong tệp kê khai:

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

Kể từ Android 6.0 (API cấp 23), người dùng có thể phê duyệt hoặc từ chối một số quyền cho ứng dụng trong thời gian chạy. Tuy nhiên, dù ứng dụng của bạn hỗ trợ phiên bản Android nào, thì bạn cũng phải khai báo mọi yêu cầu cấp quyền có phần tử <uses-permission> trong tệp kê khai. Nếu được cấp quyền, ứng dụng có thể sử dụng các tính năng được bảo vệ. Nếu không, ứng dụng sẽ không thể sử dụng các tính năng đó.

Ứng dụng cũng có thể bảo vệ các thành phần của chính ứng dụng đó bằng quyền. Ứng dụng có thể dùng mọi quyền được Android xác định, như liệt kê trong android.Manifest.permission hoặc quyền được khai báo trong một ứng dụng khác. Ứng dụng cũng có thể tự xác định các quyền riêng. Một quyền mới được khai báo bằng phần tử <permission>.

Để biết thêm thông tin, hãy xem bài viết Quyền trên Android.

Khả năng tương thích với thiết bị

Trong tệp kê khai, bạn cũng sẽ cho biết ứng dụng của mình yêu cầu những loại tính năng nào cho phần cứng hoặc phần mềm, và theo đó ứng dụng tương thích với những loại thiết bị nào. Cửa hàng Google Play không cho phép người dùng cài đặt ứng dụng trên các thiết bị không có tính năng hoặc phiên bản hệ thống mà ứng dụng yêu cầu.

Có một số thẻ tệp kê khai xác định những thiết bị tương thích với ứng dụng của bạn. Sau đây là một số thẻ phổ biến nhất.

<uses-feature>

Phần tử <uses-feature> cho phép bạn khai báo các tính năng phần cứng và phần mềm mà ứng dụng của bạn cần. Ví dụ: nếu ứng dụng không thể thực hiện chức năng cơ bản trên một thiết bị không có cảm biến la bàn, thì bạn có thể khai báo cảm biến la bàn theo yêu cầu bằng thẻ tệp kê khai sau:

<manifest ... >
    <uses-feature android:name="android.hardware.sensor.compass"
                  android:required="true" />
    ...
</manifest>

Lưu ý: Nếu muốn cung cấp ứng dụng cho Chromebook, bạn cần cân nhắc một số giới hạn quan trọng về tính năng phần cứng và phần mềm. Để biết thêm thông tin, hãy xem phần Khả năng tương thích của tệp kê khai ứng dụng cho Chromebook.

<uses-sdk>

Mỗi phiên bản nền tảng kế tiếp thường bổ sung các API mới không có trong phiên bản trước đó. Để cho biết phiên bản tối thiểu tương thích với ứng dụng, tệp kê khai phải bao gồm thẻ <uses-sdk> và thuộc tính minSdkVersion của nó.

Tuy nhiên, hãy lưu ý rằng các thuộc tính trong phần tử <uses-sdk> sẽ bị các thuộc tính tương ứng trong tệp build.gradle ghi đè. Vì vậy, nếu bạn sử dụng Android Studio, hãy chỉ định các giá trị minSdkVersiontargetSdkVersion tại đó:

Groovy

android {
    defaultConfig {
        applicationId 'com.example.myapp'

        // Defines the minimum API level required to run the app.
        minSdkVersion 21

        // Specifies the API level used to test the app.
        targetSdkVersion 33
        ...
    }
}

Kotlin

android {
    defaultConfig {
        applicationId = "com.example.myapp"

        // Defines the minimum API level required to run the app.
        minSdkVersion(21)

        // Specifies the API level used to test the app.
        targetSdkVersion(33)
        ...
    }
}

Để biết thêm thông tin về tệp build.gradle, hãy tìm hiểu cách định cấu hình bản dựng.

Để tìm hiểu thêm về cách khai báo tính năng hỗ trợ của ứng dụng cho các thiết bị, hãy xem phần Tổng quan về khả năng tương thích với thiết bị.

Quy ước của tệp

Phần này mô tả các quy ước và quy tắc thường áp dụng cho tất cả các phần tử và thuộc tính trong tệp kê khai.

Phần tử
Chỉ yêu cầu có các phần tử <manifest><application>. Các phần tử này chỉ được xuất hiện một lần. Hầu hết các phần tử khác có thể không xuất hiện hoặc xuất hiện nhiều lần. Tuy nhiên, một số phần tử phải xuất hiện thì tệp kê khai mới hữu ích.

Tất cả các giá trị được đặt thông qua các thuộc tính, không phải dưới dạng dữ liệu ký tự trong một phần tử.

Các phần tử ở cùng cấp thường không được sắp xếp theo thứ tự. Ví dụ: các phần tử <activity>, <provider><service> có thể được đặt theo thứ tự bất kỳ. Có hai trường hợp ngoại lệ chính đối với quy tắc này:

  • Một phần tử <activity-alias> mà là biệt hiệu của <activity> sẽ phải tuân thủ.
  • Phần tử <application> phải là phần tử cuối cùng trong phần tử <manifest>.
Thuộc tính
Về mặt kỹ thuật, tất cả thuộc tính là không bắt buộc. Tuy nhiên, nhiều thuộc tính phải được chỉ định để một phần tử có thể hoàn thành được mục đích. Đối với các thuộc tính thực sự không bắt buộc, tài liệu tham khảo cho biết các giá trị mặc định.

Ngoại trừ một số thuộc tính của phần tử <manifest> gốc, tất cả tên thuộc tính đều bắt đầu bằng tiền tố android:, chẳng hạn như android:alwaysRetainTaskState. Vì tiền tố là chung, nên tài liệu thường bỏ qua tiền tố khi tham chiếu đến các thuộc tính theo tên.

Nhiều giá trị
Nếu có thể chỉ định nhiều giá trị, thì phần tử hầu như luôn được lặp lại, thay vì nhiều giá trị được liệt kê trong một phần tử. Ví dụ: bộ lọc ý định có thể liệt kê một số hành động:
<intent-filter ... >
    <action android:name="android.intent.action.EDIT" />
    <action android:name="android.intent.action.INSERT" />
    <action android:name="android.intent.action.DELETE" />
    ...
</intent-filter>
Giá trị tài nguyên
Một số thuộc tính có các giá trị mà người dùng thấy được, chẳng hạn như tiêu đề của một hoạt động hoặc biểu tượng ứng dụng. Giá trị của các thuộc tính này có thể khác nhau tuỳ theo ngôn ngữ của người dùng hoặc các cấu hình thiết bị khác (chẳng hạn như để cung cấp một kích thước biểu tượng khác dựa trên mật độ pixel của thiết bị), vì vậy, bạn nên thiết lập giá trị từ một tài nguyên hoặc giao diện thay vì mã hoá cứng vào tệp kê khai. Sau đó, giá trị thực tế có thể thay đổi dựa trên tài nguyên thay thế mà bạn cung cấp cho nhiều cấu hình thiết bị.

Tài nguyên được biểu thị dưới dạng giá trị có định dạng sau:

"@[package:]type/name"

Bạn có thể bỏ qua tên package nếu tài nguyên được cung cấp bởi ứng dụng (kể cả khi đó là tài nguyên được cung cấp bởi phần phụ thuộc của thư viện, vì tài nguyên thư viện được tích hợp vào tài nguyên của bạn). Chỉ có một tên gói khác hợp lệ là android, khi bạn muốn sử dụng một tài nguyên trong khung Android.

type là một loại tài nguyên, chẳng hạn như string hoặc drawable, còn name là tên xác định tài nguyên cụ thể. Dưới đây là ví dụ:

<activity android:icon="@drawable/smallPic" ... >

Để biết thêm thông tin về cách thêm tài nguyên vào dự án của bạn, hãy đọc bài viết Tổng quan về tài nguyên ứng dụng.

Để áp dụng một giá trị được xác định trong một giao diện, ký tự đầu tiên phải là ? thay vì @:

"?[package:]type/name"

Các giá trị chuỗi
Nếu giá trị thuộc tính là một chuỗi, hãy sử dụng hai dấu gạch chéo ngược (\\) cho các ký tự thoát, chẳng hạn như \\n cho một dòng mới hoặc \\uxxxx cho một ký tự Unicode.

Tài liệu tham khảo về phần tử của tệp kê khai

Bảng sau đây cung cấp các đường liên kết đến tài liệu tham khảo cho tất cả các phần tử hợp lệ trong tệp AndroidManifest.xml.

<action> Thêm một hành động vào bộ lọc ý định.
<activity> Khai báo một thành phần hoạt động.
<activity-alias> Khai báo một biệt hiệu cho một hoạt động.
<application> Khai báo ứng dụng.
<category> Thêm tên danh mục vào bộ lọc ý định.
<compatible-screens> Chỉ định từng cấu hình màn hình tương thích với ứng dụng.
<data> Thêm thông số kỹ thuật dữ liệu vào bộ lọc ý định.
<grant-uri-permission> Chỉ định các nhóm nhỏ dữ liệu ứng dụng mà nhà cung cấp nội dung gốc có quyền truy cập.
<instrumentation> Khai báo một lớp Instrumentation cho phép bạn giám sát hoạt động tương tác của một ứng dụng với hệ thống.
<intent-filter> Nêu các loại ý định mà một hoạt động, dịch vụ hoặc broadcast receiver có thể phản hồi.
<manifest> Phần tử gốc của tệp AndroidManifest.xml.
<meta-data> Cặp tên–giá trị cho một mục gồm dữ liệu bổ sung, tuỳ ý có thể được cung cấp cho thành phần mẹ.
<path-permission> Xác định đường dẫn và các quyền cần thiết cho một tập hợp con dữ liệu cụ thể của một nhà cung cấp nội dung.
<permission> Khai báo quyền bảo mật mà có thể dùng để hạn chế truy cập vào các thành phần hay tính năng cụ thể của ứng dụng này hoặc các ứng dụng khác.
<permission-group> Khai báo tên cho một nhóm các quyền liên quan theo logic.
<permission-tree> Khai báo tên cơ sở cho cây quyền.
<provider> Khai báo thành phần nhà cung cấp nội dung (content provider).
<queries> Khai báo nhóm các ứng dụng khác mà ứng dụng của bạn định truy cập. Hãy tìm hiểu thêm về tính năng lọc chế độ xem gói trong hướng dẫn.
<receiver> Khai báo thành phần broadcast receiver.
<service> Khai báo thành phần dịch vụ.
<supports-gl-texture> Khai báo một định dạng nén kết cấu GL mà ứng dụng hỗ trợ.
<supports-screens> Khai báo kích thước màn hình mà ứng dụng của bạn hỗ trợ và bật chế độ tương thích màn hình cho các màn hình lớn hơn nội dung mà ứng dụng hỗ trợ.
<uses-configuration> Cho biết các tính năng nhập cụ thể mà ứng dụng yêu cầu.
<uses-feature> Khai báo tính năng phần cứng hoặc phần mềm mà ứng dụng sử dụng.
<uses-library> Chỉ định một thư viện chia sẻ mà phải được liên kết với ứng dụng.
<uses-native-library> Chỉ định một thư viện chia sẻ gốc do nhà cung cấp đưa ra và phải được liên kết với ứng dụng.
<uses-permission> Chỉ định một quyền hệ thống mà người dùng phải cấp để ứng dụng hoạt động chính xác.
<uses-permission-sdk-23> Xác định rằng một ứng dụng muốn có một quyền cụ thể, nhưng chỉ khi ứng dụng đó được cài đặt trên một thiết bị chạy Android 6.0 (API cấp 23) trở lên.
<uses-sdk> Cho phép bạn thể hiện khả năng tương thích của ứng dụng với một hoặc nhiều phiên bản nền tảng Android, thông qua số nguyên cấp độ API.

Giới hạn

Các thẻ sau đây có giới hạn về số lần xuất hiện trong tệp kê khai:

Tên thẻ Giới hạn
<package> 1000
<meta-data> 1000
<uses-library> 1000

Các thuộc tính sau có giới hạn về độ dài tối đa:

Thuộc tính Giới hạn
name 1024
versionName 1024
host 255
mimeType 255

Tệp kê khai mẫu

XML dưới đây là một AndroidManifest.xml mẫu đơn giản khai báo 2 hoạt động cho ứng dụng.

<?xml version="1.0" encoding="utf-8"?>
<manifest
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:versionCode="1"
    android:versionName="1.0">

    <!-- Beware that these values are overridden by the build.gradle file -->
    <uses-sdk android:minSdkVersion="15" android:targetSdkVersion="26" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <!-- This name is resolved to com.example.myapp.MainActivity
             based on the namespace property in the build.gradle file -->
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity
            android:name=".DisplayMessageActivity"
            android:parentActivityName=".MainActivity" />
    </application>
</manifest>