Android Bài 12: Khai Báo Manifest

Posted by

Được chỉnh sửa ngày 26/1/2017.

Chào mừng các bạn quay trở lại với bài học Android thứ 12 trong chương trình học Android của Yellow Code Books.

Lễ Noel có vui không các bạn? Mình thì chả đi chơi gì hết, bận kinh luôn, nhưng cũng tranh thủ ngày lễ soạn bài học Android 12 này, đến tận hôm nay mới xuất xưởng em nó. Nếu bạn nào còn dư âm không khí ngày lễ thì đọc hết bài hôm nay để lấy lại tinh thần nào. 😉

Nếu nghỉ lâu các bạn quên bài thì mình nhắc lại một chút, như bài hôm trước mình có nói, GradleManifest luôn được nói chung với nhau dù cho chúng chẳng có bà con gì với nhau hết. Chúng chỉ tranh nhau vai trò cấu hình cho project của bạn. Tất nhiên chúng cũng có những vai trò tách biệt nhau như chỉ có ở file này mà không có ở file kia. Nhưng mình không muốn bạn phải đau đầu vì những thứ giống nhau và khác nhau đó. Mình đã nói hết những gì nên làm với Gradle ở bài trước, và những gì nên làm với Manifest ở bài này, không hề có những thông tin trùng lắp khiến bạn bối rối đâu. Tuy nhiên nếu bạn muốn tìm hiểu xem Gradle và Manifest giao thoa ở những chức năng nào thì vẫn có thể dễ dàng tìm thấy thông tin này ở nhiều tài liệu khác nhé.

Khái Niệm Manifest

Khác với Gradle xuất hiện khá muộn khi mà Android Studio ra đời, giúp hỗ trợ bạn quản lý project dễ dàng hơn trước kia. Thì Manifest lại xuất hiện với vai trò là một nền tảng của Android ngay từ ban đầu. Nếu bạn còn nhớ ở Bài 5 mình có nhắc đến Manifest như là một thành phần cơ bản nhất và không thể thiếu trong một ứng dụng Android, thì bạn sẽ thấy Manifest gắn bó với Android như thế nào.

Bạn cứ nhớ là Manifest dùng để định nghĩa những thứ bên trong ứng dụng của bạn. Tại sao phải định nghĩa những thứ này? Vì đây chính là một nơi giúp tóm tắt toàn bộ thông tin về ứng dụng, từ việc ứng dụng sẽ sử dụng internet, sẽ đọc thẻ nhớ ngoài, sẽ dùng GPS, đến việc ứng dụng có bao nhiêu màn hình, có các service nào, broadcast receiver nào, vân vân và mây mây… Dựa trên những định nghĩa này của bạn mà hệ thống sẽ cho phép ứng dụng của bạn được sử dụng các chức năng đặc biệt của hệ thống, đồng thời cảnh báo với user một số thông tin quan trọng trong ứng dụng của bạn trước khi họ quyết định cài đặt và sử dụng ứng dụng, hoặc khi họ vào Settings và xem lại các thông tin đó, hay khi ứng dụng đang chạy thì hệ thống vẫn có căn cứ vào các định nghĩa này mà hỏi quyền từ người dùng. Chà phức tạp nhĩ, tạm thời bỏ qua đi bạn. Để nhẹ đầu hơn thì bạn có thể nhìn vào một số ví dụ của các ứng dụng nổi tiếng bên dưới để xem những cảnh báo của hệ thống như thế nào nhé.

group

Ảnh trên là tất cả các thông tin mà Manifest của 2 app nổi tiếng là Facebook và Evernote đã khai báo. 2 hình đầu tiên bên trái là khi user nhấn chọn cài đặt, khi đó Google Play sẽ dựa vào khai báo đó mà hiển thị thông tin ra cho các bạn xem, những thông tin này chính là những “quyền” mà bạn cho phép các ứng dụng này được phép dùng trên máy của bạn hay không, như sử dụng camera, gửi tin nhắn SMS, xem lịch của ban, đọc danh bạ của bạn,…. Mình biết nhiều bạn bỏ qua thông tin quyền này lắm, cứ nhấn Accept ngay và luôn thôi. Còn hình ngoài cùng bên phải chính là thông tin của ứng dụng Facebook sau khi bạn đã cài đặt và vào Settings của hệ thống để xem lại.

Chúng ta sẽ biết nhiều hơn về Manifest ở các mục bên dưới. Và cũng như Gradle, bạn sẽ có cơ hội được đụng đến Manifest khá nhiều, đến nỗi bạn thân quen với 2 file này lúc nào không hay.

Làm Quen Với File Manifest

May mắn cho chúng ta là Manifest chỉ có duy nhất một file, ý mình là không có sự phân cấp giữa Manifest cho project và Manifest cho module như với Gradle. Nhưng Manifest vẫn được dùng riêng cho từng module, và vì ở giai đoạn này chúng ta chỉ làm quen với việc một project chỉ có một module, do đó hiện tại chúng ta xem như chỉ duy nhất một Manifest trong project TourNote mà thôi.

Bạn có thể tìm thấy file Manifest trong thư mục src/main/ của module. File này có tên đầy đủ là AndroidManifest.xml. Như hình sau (hình trái hay phải tùy vào cách view của cửa sổ này là Android hay Project).

group

Nếu đã tìm thấy file Manifest này rồi thì bạn hãy click đúp vào để mở nó lên.

Điều đầu tiên bạn nhận ra khi nhìn thấy cấu trúc của Manifest là gì? Vâng mình hiểu ý bạn, nhìn nó như đám rừng… Đùa thôi, bạn cũng nhận thấy là Manifest sử dụng cấu trúc XML giống như cấu trúc của layout mà bạn học ở các bài trước vậy. Điều này làm cho Manifest khác với Gradle vốn sử dụng một kiểu setting riêng dạng khối, phải mất một khoảng thời gian bạn mới quen với việc cấu hình Gradle. Còn với Manifest mình chắc chắn bạn sẽ cảm thấy thân thiện hơn với cấu trúc XML của nó.

Và mình liệt kê lại dưới đây nội dung Manifest của TourNote, nó được tạo mặc định khi bạn tạo mới một project.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.yellowcode.tournote">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Thực ra mà nói thì file Manifest trên đây của TourNote chả nhằm nhò gì cả, nó còn thiếu nhiều lắm. Nhưng bạn đừng vội thêm vào, mình sẽ từ từ hướng dẫn bạn thêm vào các khai báo cho Manifest ở các bước thực hành ở bài này và các bài tiếp theo. Còn bây giờ mình xin phép được liệt kê đầy đủ hơn các khai báo thường dùng của Manifest để bạn làm quen trước. Bạn hãy xem liệt kê dưới đây.

<?xml version="1.0" encoding="utf-8"?>

<manifest>

    <uses-permission />
    <permission />
    <permission-tree />
    <permission-group />
    <supports-screens />  

    <application>

        <activity>
            <intent-filter>
                <action />
                <category />
                <data />
            </intent-filter>
            <meta-data />
        </activity>

        <service>
            <intent-filter> . . . </intent-filter>
            <meta-data/>
        </service>

        <receiver>
            <intent-filter> . . . </intent-filter>
            <meta-data />
        </receiver>

        <provider>
            <grant-uri-permission />
            <meta-data />
            <path-permission />
        </provider>

    </application>

</manifest>

Bùm! Bạn đã thấy sợ chưa. Đó mới chỉ là cái “sườn” của Manifest thôi đấy, tức là dựa trên đó chúng ta phải thêm vào, thêm vào nhiều nữa.

Nào đừng nản nhé, cái gì cũng có nguyên tắc của nó, và khi hiểu rõ nguyên tắc chúng ta sẽ thấy dễ dàng hơn đấy. Mình sẽ nói qua một số thẻ có trong liệt kê trên đây cho các bạn làm quen trước.

Thẻ manifest

Bao bọc file Manifest này chính là thẻ có tên manifest, thẻ này là thẻ gốc cho các thẻ con bên trong nó.

Thẻ này ngày xưa chứa vài thông tin cấu hình cho ứng dụng, nhưng do sự ra đời của Gradle nên một vài thông bị trùng lắp giữa 2 file, các thông tin trùng lắp này dù vẫn còn nhưng không được dùng đến ở Manifest nữa. Do đó chúng ta sẽ không nói đến các thông tin bị trùng lắp kia nữa, mà chỉ nói qua thông tin được dùng đến ở thẻ này của chỉ riêng Manifest mà thôi.

xmlns:android. Đây đơn giản là dòng khai báo namspace android mà thôi. Khái niệm namspace ở Manifest tương tự như khái niệm namspace khi lập trình giao diện với XML mà mình có nhắc đến ở phần thực hành của Bài 7.
package: chính là package name của project. Mặc định package này sẽ là giá trị giống như thuộc tính applicationId trong file build.gradle ở cấp độ module mà bạn đã làm quen ở bài trước.

Hầu như chúng ta sẽ chẳng cần đụng đến thẻ này, bạn chỉ cần biết thôi và để nó như mặc định.

Thẻ uses-permission

Như bạn thấy ở hình chụp màn hình trước khi người dùng chấp nhận cài đặt 2 ứng dụng Facebook và Evernote ở trên kia, những quyền mà hệ thống hiển thị ra đó đang chờ bạn chấp nhận trước khi chúng được cài đặt. Tất cả các quyền đó đều được lấy ra từ các thẻ uses-permission này.

Lưu ý là với ứng dụng hỗ trợ Android 6.0 hoặc mới hơn, thì các quyền này không được hỏi khi cài đặt ứng dụng như hình trên đâu nha, nó sẽ được hỏi ngay khi người dùng lần đầu sử dụng đến chức năng cần xin quyền trong ứng dụng của bạn. Chẳng hạn khi người dùng nhấn vào nút chụp hình trên TourNote để lưu lại một ghi chú về món ăn, lập tức hệ thống sẽ hỏi người dùng quyền được sử dụng camera, nếu user cho phép thì TourNote sẽ chạy như bình thường, nếu user không cho phép thì TourNote mãi không sử dụng được camera của hệ thống và sẽ không chụp ảnh được. Một ảnh minh họa cho việc hỏi quyền trong khi sử dụng app, mà mình lấy từ trang developer.android.com về, ứng dụng này đang hỏi quyền truy cập vào danh bạ của user.

request_permission_dialog_2x

Còn đây là cách mà một ứng dụng xin quyền dựa vào thẻ uses-permission từ file Manifest, mình đã “chôm” được khai báo này từ một ứng dụng hoàn chỉnh trên Google Play.

screen-shot-2016-12-26-at-13-18-54

Xin quyền thì có rất nhiều chuyện để nói. Có thể mình sẽ có một bài viết riêng về nó. Hoặc nếu bạn có thắc mắc gì ở bước này thì cứ để lại bình luận ở cuối bài học nhé, mình sẵn lòng giải đáp cho các bạn.

Thẻ permission

Thẻ này mình xin được nói sơ thôi vì tuy trông giống với uses-permission ở trên đây nhưng permission có công dụng hoàn toàn khác. Thẻ permission này có thể dùng để định nghĩa ra các quyền cho riêng ứng dụng của bạn. Vì chúng khá ít xài nên các thẻ permission, permission-tree, permission-group sẽ được mình nói đến cụ thể sau nhé.

Một ví dụ cho thẻ permission mà mình chôm được của một app.

screen-shot-2016-12-26-at-15-55-33

Thẻ supports-screens

Thẻ này cũng kha khá quan trọng, nó được dùng để định nghĩa các thể loại màn hình mà ứng dụng của bạn hỗ trợ. Thông thường thì các ứng dụng hay loại bỏ việc hỗ trợ màn hình nhỏ, là các thiết bị có màn hình dưới 3 inch. Chúng ta sẽ sử dụng thẻ này ở bài thực hành phía dưới.

Và đây là một ví dụ cho thẻ này, tất nhiên cũng là do mình chôm luôn.

screen-shot-2016-12-26-at-16-06-49

Thẻ application

Thẻ này quan trọng lắm đây, thẻ này chứa một số thuộc tính liên quan đến cấu hình của ứng dụng (đúng như tên gọi của nó), mà mình sẽ liệt kê như bên dưới đây.

<application android:allowBackup=["true" | "false"]
             android:icon="drawable resource"
             android:label="string resource"
             android:supportsRtl=["true" | "false"]
             android:theme="resource or theme" >
    . . .
</application>

Chúng ta sẽ nói sơ vài thuộc tính đã được liệt kê.

android:allowBackup – Cho phép ứng dụng của bạn nằm trong chương trình tự động backup của hệ thống Android hay không. Thực sự mình cũng không rõ lắm chế độ tự động backup này, mình sẽ tìm hiểu về nó và quay lại với các bạn ở bài viết riêng. Còn hôm nay bạn cứ để giá trị của thuộc tính này là true như mặc định nhé.
android:icon – Thuộc tính này là nơi bạn thiết lập icon cho ứng dụng. Icon này sẽ xuất hiện trên màn hình chính của thiết bị. Hiện tại thì icon này đang được để mặc định là file ic_launcher.png để trong thư mục res/mipmap/. Cách sử dụng icon cho ứng dụng cũng giống như cách bạn hiển thị một ảnh lên ImageView ở bài trước vậy. Chúng ta sẽ thực hành thay đổi icon cho TourNote ở bài học sau nhé.
android:label – Thuộc tính này trỏ đến một giá trị string trong resource, hoàn toàn tương tự như cách bạn khai báo text cho TextView ở bài trước vậy. String này chính là tên ứng dụng của chúng ta, hiện tại đang là “TourNote”. Chúng ta cũng sẽ thực hành thay đổi tên cho TourNote ở bài học sau.
android:supportsRtl – Nếu bạn còn nhớ, từ RTL viết tắt của right-to-left, thuộc tính này cho phép ứng dụng của bạn có hỗ trợ cho các hệ ngôn ngữ viết từ phải-sang-trái hay không. Việc hỗ trợ các ngôn ngữ RTL đã được mình nhắc đến cụ thể ở Bài 10 rồi nhé.
android:theme – Thuộc tính này khá hay, nó giúp chúng ta định nghĩa “giao diện chủ đề” cho ứng dụng. Và vì nó hay quá nên mình sẽ không nói ở đây, mình dành hẳn một bài để nói về chủ đề này để cho các bạn hiểu rõ nhất về nó.

Tất nhiên thẻ application còn nhiều thuộc tính lắm, bạn có thể vào link này để xem thông tin đầy đủ về nó. Mình chỉ nói qua những thuộc tính dùng nhiều nhất, còn lại thì khi nào phát sinh thuộc tính mới mình sẽ nói thêm với các bạn.

Ngoài ra thì trong thẻ application này có các thẻ con quan trọng nữa, chúng ta lại tiếp tục nói đến các thẻ con của application ở bên dưới đây.

Thẻ activity

Thẻ này giúp bạn khai báo các Activity có trong ứng dụng. Activity là gì? Chúng được xem như các màn hình trong ứng dụng của chúng ta. Hiện tại khi mở ứng dụng TourNote lên, bạn sẽ thấy có một màn hình duy nhất mà chúng ta hì hụi xây dựng giao diện cho nó mấy hôm nay, chính vì vậy mà khi nhìn vào file Manifest hiện tại bạn chỉ thấy một thẻ activity mà thôi. Tất nhiên về sau chúng ta sẽ xây dựng nhiều màn hình khác, và khi đó thẻ activity sẽ nhiều lên, vì mỗi thẻ activity như vậy giúp khai báo cho một màn hình duy nhất. Chúng ta dành “giấy mực” cho thẻ này khi học về Activity sau nhé.

Thẻ service

Tương tự như thẻ activity trên đây. Mỗi thẻ service dùng để định nghĩa cho một loại Service. Service là gì á? Bạn có thể xem lại một tí ở Bài 5, nhưng chúng ta sẽ nói cụ thể về Service ở bài học sau.

Thẻ receiver

Cũng như hai thẻ activityservice trên đây. Mỗi thẻ receiver dùng để định nghĩa cho một loại Broadcast Receiver. Broadcast Receiver cũng được nhắc đến ở Bài 5, và sẽ được nói cụ thể sau.

Thẻ provider

Cũng như các thẻ activity, service, và receiver trên đây. Mỗi thẻ provider dùng để định nghĩa cho một loại Content Provider. Content Provider cũng được nhắc đến ở Bài 5và sẽ được nói cụ thể sau.

Thực Hành Thay Đổi Manifest Cho Ứng Dụng TourNote

Bài học đã khá dài rồi, do đó phần thực hành này chúng ta làm nhanh gọn lẹ thôi. Những bổ sung cho Manifest của TourNote sẽ được nói đến ở các bài thực hành sau bạn nhé.

Như đã nói ở trên, chúng ta sẽ thiết lập cho Manifest của TourNote sao cho ứng dụng của chúng ta không hỗ trợ màn hình nhỏ. Và cũng từ kiến thức trên đây, chúng ta biết nên thêm vào Manifest thẻ supports-screens, thẻ này là thẻ con của manifest. Vậy chúng ta hãy mở file AndroidManifest.xml của TourNote lên và thêm vào các dòng như sau.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.yellowcode.tournote">

    <supports-screens
        android:smallScreens="false"
        android:normalScreens="true"
        android:largeScreens="true"
        android:xlargeScreens="true"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Download Source Code Mẫu

Bạn có thể download source code mẫu của bài này ở đây.

Chúng ta vừa kết thúc bài học về Manifest, như vậy đến bài học hôm nay, các bạn đã biết những khái niệm và cách thức xây dựng một ứng dụng Android ở mức cơ bản nhất. Từ bài sau chúng ta sẽ ở một bước tiến cao hơn trong lĩnh vực lập trình ứng dụng Android này, và các bạn sẽ còn được làm quen rất rất nhiều điều thú vị hơn nữa.

Cảm ơn bạn đã đọc các bài viết của Yellow Code Books. Bạn hãy đánh giá 5 sao nếu thấy thích bài viết, hãy comment bên dưới nếu có thắc mắc, hãy để lại địa chỉ email của bạn để nhận được thông báo mới nhất khi có bài viết mới, và nhớ chia sẻ các bài viết của Yellow Code Books đến nhiều người khác nữa nhé.

Bài Kế Tiếp

Chúng ta sẽ lần lượt làm quen với cách sử dụng từng loại resource cao cấp. Chẳng hạn như menu, animation, theme,…

Advertisements
Rating: 4.8/5. From 16 votes.
Please wait...

6 comments

    1. Hehe, cũng do bận một số công việc cuối năm, mỗi ngày viết được một ít, quay qua quay lại đã hơn một tuần trôi qua, mới cho xuất xưởng em này được. Chắc phải tập trung viết bù lại quá… kkk

    1. Cảm ơn bạn Lê Đắc Luyện nhé, chia sẻ kiến thức cũng là một thú vui, mình sẽ tiếp tục duy trì với mật độ và chất lượng tốt nhất. Chúc bạn và mọi người luôn mạnh khỏe trong năm mới.

Gửi phản hồi