Thẻ gốc của AndroidManifest XML là gì

Mỗi ứng dụng Android đều có một tập tin tên AndroidManifest.xml, được lưu ở thư mục gốc (root) của ứng dụng. Tập tin manifest mô tả những thông tin cần thiết của ứng dụng cho hệ điều hành Android, những thông tin này hệ điều hành cần phải biết trước khi nó chạy bất kỳ chương trình nào. Những công việc mà tập tin manifest cần phải thực hiện

Khai báo tên của package cho ứng dụng. Tên của package là định danh duy nhất của ứng dụng

Mô tả các thành phần (component) của ứng dụng: activity, services, broadcast receivers, và content providers mà ứng dụng có. Khai báo tên các lớp mà cài đặt các thành phần này và các tác vụ mà các thành phần này có thể xử lý (ví dụ các thông điệp một Intent có thể xử lý). Những khai báo này cho phép hệ điều hành Android biết các thành phần này có thể có thể thực hiện được tác vụ gì và điều kiện để chúng có thể thực thi.

Xác định tiến trình (process) sẽ chứa những thành phần (component) nào.

Khai báo các quyền mà ứng dụng cần phải có để truy xuất các thành phần của API và giao tiếp với các ứng dụng khác.

Khai báo các quyền mà yêu cầu ứng dụng khác cần phải có để có thể giao tiếp được với các component của ứng dụng này.

Mô tả phiên bản API tối thiểu mà ứng dụng có thể chạy.

Liệt kê các thư viện mà ứng dụng cần phải kết nối.

1. Cấu trúc của tập tin Manifest

Phần dưới đây mô tả cấu trúc của tập tin manifest và các phần tử mà nó có thể chứa

1: <?xml version="1.0" encoding="utf-8"?> 2: 3: <manifest> 4: 5: <uses-permission /> 6: <permission /> 7: <permission-tree /> 8: <permission-group /> 9: <instrumentation /> 10: <uses-sdk /> 11: <uses-configuration /> 12: <uses-feature /> 13: <supports-screens /> 14: <compatible-screens /> 15: <supports-gl-texture /> 16: 17: <application> 18: 19: <activity> 20: <intent-filter> 21: <action /> 22: <category /> 23: <data /> 24: </intent-filter> 25: <meta-data /> 26: </activity> 27: 28: <activity-alias> 29: <intent-filter> . . . </intent-filter> 30: <meta-data /> 31: </activity-alias> 32: 33: <service> 34: <intent-filter> . . . </intent-filter> 35: <meta-data/> 36: </service> 37: 38: <receiver> 39: <intent-filter> . . . </intent-filter> 40: <meta-data /> 41: </receiver> 42: 43: <provider> 44: <grant-uri-permission /> 45: <meta-data /> 46: <path-permission /> 47: </provider> 48: 49: <uses-library /> 50: 51: </application> 52: 53: </manifest>

2. Các quy ước dành cho tập tin manifest

Thẻ (element):

+ Chỉ có hai thẻ <manifest><application> là bắt buộc phải có và chỉ xuất hiện một lần. Các thẻ khác có thể xuất hiện hoặc không.

+ Một thẻ chỉ chứa thẻ con, không chứa nội dung (content) là chuỗi. Các giá trị (thông tin) được thiết lập thông qua thuộc tính.

+ Các thẻ cùng cấp không cần phải theo thứ tự. Ví dụ: các thẻ <activity>, <provider><service> có thể sắp xếp theo thứ tự này hoặc <provider>, <service><activity>.

Thuộc tính (attribute):

+ Thuộc tính không bắt buộc phải tồn tại, tuy nhiên, trong một vài thẻ đặc biệt thì nó phải có để mô tả chức năng.

+ Trừ các thuộc tính của thẻ <manifest>, tên của tất cả các thuộc tính còn lại phải bắt đầu với tiền tố (prefix) andoid:, ví dụ: android:alwaysRetainTaskState.

Khai báo tên lớp:

+ Nhiều thẻ cần phải khai báo các đối tượng Java (Java objects), bao gồm các thẻ cho chính ứng dụng (thẻ <application>) và các thành phần khác: activity (<activity>), services (<service>), broadcast receivers (<receiver>), và content providers (<provider>).

+ Nếu bạn cài đặt một lớp thực hiện một trong các tác vụ cơ bản: Activity, Service, BroadcastRecevier, và ContentProvider, thông tin của lớp này sẽ được khai báo thông qua thuộc tính name. Tên lớp phải đi kèm với tên của package. Ví dụ: lớp mô tả Service được khai báo như sau:

1: <manifest . . . > 2: <application . . . > 3: <service android:name="com.code5s.SecretService" . . . > 4: . . . 5: </service> 6: . . . 7: </application> 8: </manifest>

+ Tuy nhiên, nếu lớp mô tả Service nằm trong package đã được khai báo trong thẻ manifest, chúng ta có thể viết ngắn gọn lại như sau:

1: <manifest package="com.code5s" . . . > 2: <application . . . > 3: <service android:name=".SecretService" . . . > 4: . . . 5: </service> 6: . . . 7: </application> 8: </manifest>

+ Khi thực thi component SecretService, Android sẽ tạo một thực thể của lớp này trên bộ nhớ. Nếu Android không xác định được lớp SecretService, nó sẽ tạo một đối tượng của lớp cha của SecretService.

Thuộc tính có nhiều giá trị (multiple values):

+ Nếu có nhiều giá trị cần khai báo, thẻ sẽ xuất hiện nhiều lần. Ví dụ: một intent có thể lọc nhiều tác vụ (action):

1: <intent-filter . . . > 2: <action android:name="android.intent.action.EDIT" /> 3: <action android:name="android.intent.action.INSERT" /> 4: <action android:name="android.intent.action.DELETE" /> 5: . . . 6: </intent-filter>

Tham chiếu đến giá trị trong tập tin resource khác (Resource Values):

+ Một số thuộc tính có giá trị có thể hiển thị ra cho người dùng xem, ví dụ: label và icon cho một activity. Giá trị của những thuộc tính này có thể được ngay trong phần khai báo thuộc tính, nhưng cũng có thể được mô tả trong một tập tin resource hoặc theme.

+ Cú pháp khai báo Resource Values: @[package:]type:name.

+ Trong trường hợp resource có tên package giống với tên package của ứng dụng, có thể bỏ tên package.

+ type là kiểu của resource, ví dụ: string hoặc drawable

+ name là tên của resource.

+ Ví dụ:

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

+ Tham chiếu đến giá trị trong theme cũng tương tự, chỉ thay dấu @ bằng dấu ?:

+ Cú pháp khai báo Theme Values: ?[package:]type:name.

String Values:

+ Khi giá trị của thuộc tính là một chuỗi, có thể sử dụng (\\) cho các ký tự đặc biệt. Ví dụ: \\n cho ký tự xuống hàng.

3. Các tính năng khác:

Phần dưới đây mô tả các tính năng khác của tập tin manifest

Intent Filters:

+ Các thành phần chính của ứng dụng (activities, services, và broadcast receivers) được kích hoạt thông qua intents. Một intent gồm tập hợp nhiều thông tin (đối tượng Intent) mô tả các tác vụ tương ứng, bao gồm dữ liệu cần thiết, loại component sẽ thực hiện tác vụ, và các chỉ thị thích hợp khác. Android sẽ quyết định component thích hợp cho intent, tạo ra một thực thể (instance) của component nếu cần thiết, và truyền nó tới cho intent.

+ Component phải mô tả các khả năng mà nó có thể xử lý loại intent mà nó có thể đáp ứng thông qua intent filters. Vì vậy, hệ điều hành Android phải biết trước các intent của một component trước khi nó thực thi component, intent filters được mô tả trong tập tin manifest bằng thẻ <intent-filter>. Một component có thể có nhiều filter, mô tả các tác vụ khác nhau.

+ Một intent phải biết được tên của component sẽ được kích hoạt thông qua intent.

Icon và Label:

+ Một số thẻ có thuộc tính icon và label để hiển thị 1 biểu tượng (icon) nhỏ và một nhãn văn bản (label) cho người dùng. Một vài thẻ cũng có thuộc tính description mô tả chuỗi văn bản dài hơn có thể hiển thị trên màn hình. Ví dụ: thẻ <permission> có 3 thuộc tính mà người dùng phải cung cấp thông tin để ứng dụng có thể truy cập được, icon: biểu tượng của quyền, name: tên của quyền, description: mô tả các quyền có thể thừa kế áp dụng cho người dùng.

+ Trong hầu hết các trường hợp, thuộc tính icon và label được thiết lập trong thẻ cha sẽ trở thành giá trị mặc định cho thẻ con.

Permissions (quyền):

+ Permission được dùng để giới hạn quyền truy xuất vào chương trình mà dữ liệu trên thiết bị. Những giới hạn này được áp đặt để bảo vệ dữ liệu nhạy cảm và các chương trình có thể gây lỗi hoặc cố ý dùng sai của người dùng có kinh nghiệm.

+ Mỗi quyền được xác định bởi 1 chuỗi duy nhất. Thường mỗi chuỗi xác định duy nhất 1 quyền. Dưới đây là một số quyền được mô tả bởi sẳn Android

android.permission.CALL_EMERGENCY_NUMBERS

android.permission.READ_OWNER_DATA

android.permission.SET_WALLPAPER

android.permission.DEVICE_POWER

+ Mỗi tính năng của ứng dụng có thể được bảo vệ bằng một quyền

+ Nếu ứng dụng cần truy xuất vào một tính năng được bảo vệ bằng quyền truy xuất, nó phải mô tả quyền cần để truy xuất trong tập tin manifest bằng thẻ <uses-permission>. Khi ứng dụng được cài đặt vào thiết bị, trình cài đặt sẽ kiểm tra xem có thể cấp quyền được yêu cầu bằng cách kiểm tra chứng chỉ xác thực của ứng dụng, nếu không cấp quyền được, trình cài đặt có thể yêu cầu xác nhận của người dùng. Nếu đã được ủy quyền, ứng dụng có thể truy xuất vào các tính năng được bảo vệ, nếu không được ủy quyền, khi ứng dụng sẽ không truy cập được các tính năng được bảo vệ mà không có bất kỳ thông báo nào với người dùng.

+ Ứng dụng có thể bảo vệ các component của nó (activities, services, broadcast receivers và content providers) bằng quyền. Nó có thể sử dụng bất kỳ quyền nào đã được mô tả sẳn bởi Android (được mô tả trong android.Manifest.permission) hoặc được khai báo trong ứng dụng khác. Hoặc nó cũng có thể tự mô tả quyền của mình. Một quyền mới sẽ được khai báo bằng thẻ <permission>. Ví dụ: ứng dụng có thể tự bảo vệ activity của mình bằng quyền như sau:

1: <manifest . . . > 2: <permission android:name="com.example.project.DEBIT_ACCT" . . . /> 3: <uses-permission android:name="com.example.project.DEBIT_ACCT" /> 4: . . . 5: <application . . .> 6: <activity android:name="com.example.project.FreneticActivity" 7: android:permission="com.example.project.DEBIT_ACCT" 8: . . . > 9: . . . 10: </activity> 11: </application> 12: </manifest>

+ Chú ý rằng trong ví dụ trên, quyền DEBIT_ACCT không chỉ được khai báo bằng thẻ <permission>, nó còn được sử dụng để yêu cầu quyền với thẻ <users-permission>.

+ Trong ví dụ trên, nếu thuộc tính permission dùng quyền khác, như: android.permission.CALL_EMERGENCY_NUMBERS, thì không không cần khai báo quyền này với thẻ <permission>. Chỉ cần khai khai báo quyền này trong thẻ <uses-permission>.

Library:

+ Mỗi ứng dụng sẽ cần liên kết với những thư viện có sẳn của Android, chứa các gói cơ bản cho việc biên dịch ứng dụng.

+ Tuy nhiên, nếu ứng dụng sử dụng những package nằm ngoài thư viện có sẳn của Android, bạn cần phải liên yêu cần được liên kết với chúng. Thẻ <uses-library> trong tập tin manifest sẽ thực hiện công việc này.

4. Một số tập tin AndroidManifest.xml minh họa:

Tập tin AndroidManifest.xml của ứng dụng gửi/nhận SMS

1: <?xml version="1.0" encoding="utf-8"?> 2: <manifest xmlns:android="http://schemas.android.com/apk/res/android" 3: package="com.code5s" 4: android:versionCode="1" 5: android:versionName="1.0" > 6: 7: <uses-sdk 8: android:minSdkVersion="14" 9: android:targetSdkVersion="17" /> 10: 11: <uses-permission android:name="android.permission.SEND_SMS" /> 12: <uses-permission android:name="android.permission.RECEIVE_SMS" /> 13: 14: <application 15: android:allowBackup="true" 16: android:icon="@drawable/ic_launcher" 17: android:label="@string/app_name" 18: android:theme="@style/AppTheme" > 19: <activity 20: android:name="com.code5s.MainActivity" 21: android:label="@string/app_name" > 22: <intent-filter> 23: <action android:name="android.intent.action.MAIN" /> 24: 25: <category android:name="android.intent.category.LAUNCHER" /> 26: </intent-filter> 27: </activity> 28: </application> 29: 30: </manifest>

Tập tin AndroidManifest.xml của ứng dụng WifiDemo

1: <?xml version="1.0" encoding="utf-8"?> 2: <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.android.wifidirect" 3: android:versionCode="1" android:versionName="1.0"> 4: 5: <uses-sdk android:minSdkVersion="14" /> 6: <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> 7: <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> 8: <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> 9: <uses-permission android:name="android.permission.INTERNET" /> 10: <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 11: <uses-permission android:name="android.permission.READ_PHONE_STATE" /> 12: <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 13: 14: <!-- Google Play filtering --> 15: <uses-feature android:name="android.hardware.wifi.direct" android:required="true"/> 16: 17: <application 18: android:icon="@drawable/ic_launcher" 19: android:label="@string/app_name" 20: android:theme="@android:style/Theme.Holo"> 21: <activity 22: android:name=".WiFiDirectActivity" 23: android:label="@string/app_name" android:launchMode="singleTask"> 24: <intent-filter> 25: <action 26: android:name="android.intent.action.MAIN" /> 27: <category 28: android:name="android.intent.category.LAUNCHER" /> 29: </intent-filter> 30: </activity> 31: 32: <!-- Used for transferring files after a successful connection --> 33: <service android:enabled="true" android:name=".FileTransferService" /> 34: 35: </application> 36: </manifest>

Tập tin AndroidManifest.xml của ứng dụng NotePad

1: <manifest xmlns:android="http://schemas.android.com/apk/res/android" 2: package="com.example.android.notepad" > 3: 4: <uses-sdk android:minSdkVersion="11" /> 5: 6: <application android:icon="@drawable/app_notes" 7: android:label="@string/app_name" 8: > 9: <provider android:name="NotePadProvider" 10: android:authorities="com.google.provider.NotePad" 11: android:exported="false"> 12: <grant-uri-permission android:pathPattern=".*" /> 13: </provider> 14: 15: <activity android:name="NotesList" android:label="@string/title_notes_list"> 16: <intent-filter> 17: <action android:name="android.intent.action.MAIN" /> 18: <category android:name="android.intent.category.LAUNCHER" /> 19: </intent-filter> 20: <intent-filter> 21: <action android:name="android.intent.action.VIEW" /> 22: <action android:name="android.intent.action.EDIT" /> 23: <action android:name="android.intent.action.PICK" /> 24: <category android:name="android.intent.category.DEFAULT" /> 25: <data android:mimeType="vnd.android.cursor.dir/vnd.google.note" /> 26: </intent-filter> 27: <intent-filter> 28: <action android:name="android.intent.action.GET_CONTENT" /> 29: <category android:name="android.intent.category.DEFAULT" /> 30: <data android:mimeType="vnd.android.cursor.item/vnd.google.note" /> 31: </intent-filter> 32: </activity> 33: 34: <activity android:name="NoteEditor" 35: android:theme="@android:style/Theme.Holo.Light" 36: android:screenOrientation="sensor" 37: android:configChanges="keyboardHidden|orientation" 38: > 39: <!-- This filter says that we can view or edit the data of 40: a single note --> 41: <intent-filter android:label="@string/resolve_edit"> 42: <action android:name="android.intent.action.VIEW" /> 43: <action android:name="android.intent.action.EDIT" /> 44: <action android:name="com.android.notepad.action.EDIT_NOTE" /> 45: <category android:name="android.intent.category.DEFAULT" /> 46: <data android:mimeType="vnd.android.cursor.item/vnd.google.note" /> 47: </intent-filter> 48: 49: <!-- This filter says that we can create a new note inside 50: of a directory of notes. The INSERT action creates an 51: empty note; the PASTE action initializes a new note from 52: the current contents of the clipboard. --> 53: <intent-filter> 54: <action android:name="android.intent.action.INSERT" /> 55: <action android:name="android.intent.action.PASTE" /> 56: <category android:name="android.intent.category.DEFAULT" /> 57: <data android:mimeType="vnd.android.cursor.dir/vnd.google.note" /> 58: </intent-filter> 59: 60: </activity> 61: 62: <activity android:name="TitleEditor" 63: android:label="@string/title_edit_title" 64: android:icon="@drawable/ic_menu_edit" 65: android:theme="@android:style/Theme.Holo.Dialog" 66: android:windowSoftInputMode="stateVisible"> 67: <!-- This activity implements an alternative action that can be 68: performed on notes: editing their title. It can be used as 69: a default operation if the user invokes this action, and is 70: available as an alternative action for any note data. --> 71: <intent-filter android:label="@string/resolve_title"> 72: <!-- This is the action we perform. It is a custom action we 73: define for our application, not a generic VIEW or EDIT 74: action since we are not a general note viewer/editor. --> 75: <action android:name="com.android.notepad.action.EDIT_TITLE" /> 76: <!-- DEFAULT: execute if being directly invoked. --> 77: <category android:name="android.intent.category.DEFAULT" /> 78: <!-- ALTERNATIVE: show as an alternative action when the user is 79: working with this type of data. --> 80: <category android:name="android.intent.category.ALTERNATIVE" /> 81: <!-- SELECTED_ALTERNATIVE: show as an alternative action the user 82: can perform when selecting this type of data. --> 83: <category android:name="android.intent.category.SELECTED_ALTERNATIVE" /> 84: <!-- This is the data type we operate on. --> 85: <data android:mimeType="vnd.android.cursor.item/vnd.google.note" /> 86: </intent-filter> 87: </activity> 88: 89: <activity android:name="NotesLiveFolder" android:label="@string/live_folder_name" 90: android:icon="@drawable/live_folder_notes"> 91: <intent-filter> 92: <action android:name="android.intent.action.CREATE_LIVE_FOLDER" /> 93: <category android:name="android.intent.category.DEFAULT" /> 94: </intent-filter> 95: </activity> 96: 97: </application> 98: 99: </manifest>

Nguồn: http://developer.android.com

Tags: androidlearningprogrammingtrainingtutorial