Nội dung
1. 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.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é.
Ả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à Grab đã 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 (hơi khó tìm một chút), 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,…. Còn hình ngoài cùng bên phải chính là thông tin của ứng dụng Grab 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.
2. 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 AndroidManifest.xml trong thư mục manifests của app. 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).
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.vncoder.menu_demo">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
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>
3. 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. Sau dòng khai báo này thì các thẻ khác bên trong thẻ manifest này mới có thể sử dụng được từ khóa android.– 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.
4. Thẻ uses-permission
Như bạn thấy ở hình chụp màn hình 2 ứng dụng Facebook và Grab ở trên kia, những quyền mà hệ thống hiển thị ra đó đề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, một số quyền còn yêu cầu ứng dụng phải hiển thị popup xin phép người dùng khi lần đầu tiên họ sử dụng đến chức năng có liên quan đến quyền này trong ứng dụng. Chẳng hạn khi lần đầu tiên 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 TourNote sẽ phải 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.
5. Thẻ permission
Thẻ permission là thẻ giup hạn chế giới hạn truy cập vào một phần của mã hoặc vào dữ liệu trên thiết bị. Giới hạn này được áp đặt nhằm bảo vệ dữ liệu và mã trọng yếu, có thể bị lạm dụng để bóp méo hoặc làm hỏng trải nghiệm người dùng.
Mỗi quyền được nhận biết bằng một nhãn duy nhất. Thông thường, nhãn cho biết hành động bị hạn chế. Ví dụ, sau đây là một số quyền được định nghĩa bởi Android:
android.permission.CALL_EMERGENCY_NUMBERS
android.permission.READ_OWNER_DATA
android.permission.SET_WALLPAPER
android.permission.DEVICE_POWER
Một tính năng có thể được bảo vệ bởi nhiều nhất một quyền.
Nếu một ứng dụng cần truy cập vào một tính năng được bảo vệ bởi một quyền, nó phải khai báo rằng nó yêu cầu quyền đó cùng với một phần tử <uses-permission> trong bản kê khai. Lúc đó, khi ứng dụng được cài đặt trên thiết bị, trình cài đặt sẽ xác định xem có cấp quyền được yêu cầu hay không bằng cách kiểm tra các thẩm quyền đã ký chứng chỉ của ứng dụng và trong một số trường hợp, bằng cách hỏi người dùng. Nếu quyền được cấp, ứng dụng có thể sử dụng các tính năng được bảo vệ. Nếu không, việc thử truy cập những tính năng đó sẽ thất bại mà không có bất kỳ thông báo nào cho người dùng.
6. 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 chưa kiểm chứng tính hiệu quả của chế độ backup này, nghe nói hệ thống sẽ giới hạn dữ liệu backup của ứng dụng với mỗi người dùng là 25MB, kèm theo việc giới hạn các loại dữ liệu có thể backup. Dù sao thì tính năng này cũng rất tốt nên 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 set 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ác bạn tự tìm hiểu thêm ,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.