summaryrefslogtreecommitdiff
path: root/docs/html-intl/intl/vi
diff options
context:
space:
mode:
Diffstat (limited to 'docs/html-intl/intl/vi')
-rw-r--r--docs/html-intl/intl/vi/guide/components/activities.jd756
-rw-r--r--docs/html-intl/intl/vi/guide/components/bound-services.jd658
-rw-r--r--docs/html-intl/intl/vi/guide/components/fragments.jd812
-rw-r--r--docs/html-intl/intl/vi/guide/components/fundamentals.jd480
-rw-r--r--docs/html-intl/intl/vi/guide/components/index.jd57
-rw-r--r--docs/html-intl/intl/vi/guide/components/intents-filters.jd901
-rw-r--r--docs/html-intl/intl/vi/guide/components/loaders.jd494
-rw-r--r--docs/html-intl/intl/vi/guide/components/processes-and-threads.jd411
-rw-r--r--docs/html-intl/intl/vi/guide/components/recents.jd256
-rw-r--r--docs/html-intl/intl/vi/guide/components/services.jd813
-rw-r--r--docs/html-intl/intl/vi/guide/components/tasks-and-back-stack.jd578
-rw-r--r--docs/html-intl/intl/vi/guide/index.jd74
-rw-r--r--docs/html-intl/intl/vi/guide/topics/manifest/manifest-intro.jd517
-rw-r--r--docs/html-intl/intl/vi/guide/topics/providers/calendar-provider.jd1184
-rw-r--r--docs/html-intl/intl/vi/guide/topics/providers/contacts-provider.jd2356
-rw-r--r--docs/html-intl/intl/vi/guide/topics/providers/content-provider-basics.jd1196
-rw-r--r--docs/html-intl/intl/vi/guide/topics/providers/content-provider-creating.jd1214
-rw-r--r--docs/html-intl/intl/vi/guide/topics/providers/content-providers.jd108
-rw-r--r--docs/html-intl/intl/vi/guide/topics/providers/document-provider.jd916
-rw-r--r--docs/html-intl/intl/vi/guide/topics/resources/accessing-resources.jd337
-rw-r--r--docs/html-intl/intl/vi/guide/topics/resources/overview.jd103
-rw-r--r--docs/html-intl/intl/vi/guide/topics/resources/providing-resources.jd1094
-rw-r--r--docs/html-intl/intl/vi/guide/topics/resources/runtime-changes.jd281
-rw-r--r--docs/html-intl/intl/vi/guide/topics/ui/controls.jd90
-rw-r--r--docs/html-intl/intl/vi/guide/topics/ui/declaring-layout.jd492
-rw-r--r--docs/html-intl/intl/vi/guide/topics/ui/dialogs.jd798
-rw-r--r--docs/html-intl/intl/vi/guide/topics/ui/menus.jd1031
-rw-r--r--docs/html-intl/intl/vi/guide/topics/ui/notifiers/notifications.jd979
-rw-r--r--docs/html-intl/intl/vi/guide/topics/ui/overview.jd71
-rw-r--r--docs/html-intl/intl/vi/guide/topics/ui/settings.jd1202
-rw-r--r--docs/html-intl/intl/vi/guide/topics/ui/ui-events.jd291
-rw-r--r--docs/html-intl/intl/vi/sdk/index.jd487
-rw-r--r--docs/html-intl/intl/vi/sdk/installing/adding-packages.jd227
33 files changed, 21264 insertions, 0 deletions
diff --git a/docs/html-intl/intl/vi/guide/components/activities.jd b/docs/html-intl/intl/vi/guide/components/activities.jd
new file mode 100644
index 000000000000..83e7669a7f76
--- /dev/null
+++ b/docs/html-intl/intl/vi/guide/components/activities.jd
@@ -0,0 +1,756 @@
+page.title=Các hoạt động
+page.tags=hoạt động,ý định
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+<h2>Trong tài liệu này</h2>
+<ol>
+ <li><a href="#Creating">Tạo một Hoạt động</a>
+ <ol>
+ <li><a href="#UI">Triển khai một giao diện người dùng</a></li>
+ <li><a href="#Declaring">Khai báo hoạt động trong bản kê khai</a></li>
+ </ol>
+ </li>
+ <li><a href="#StartingAnActivity">Bắt đầu một Hoạt động</a>
+ <ol>
+ <li><a href="#StartingAnActivityForResult">Bắt đầu một hoạt động cho một kết quả</a></li>
+ </ol>
+ </li>
+ <li><a href="#ShuttingDown">Tắt một Hoạt động</a></li>
+ <li><a href="#Lifecycle">Quản lý Vòng đời của Hoạt động</a>
+ <ol>
+ <li><a href="#ImplementingLifecycleCallbacks">Triển khai gọi lại vòng đời</a></li>
+ <li><a href="#SavingActivityState">Lưu trạng thái của hoạt động</a></li>
+ <li><a href="#ConfigurationChanges">Xử lý thay đổi về cấu hình</a></li>
+ <li><a href="#CoordinatingActivities">Điều phối hoạt động</a></li>
+ </ol>
+ </li>
+</ol>
+
+<h2>Lớp khóa</h2>
+<ol>
+ <li>{@link android.app.Activity}</li>
+</ol>
+
+<h2>Xem thêm</h2>
+<ol>
+ <li><a href="{@docRoot}guide/components/tasks-and-back-stack.html">Tác vụ và Ngăn
+Xếp</a></li>
+</ol>
+
+</div>
+</div>
+
+
+
+<p>{@link android.app.Activity} là một thành phần ứng dụng cung cấp một màn hình mà với nó
+người dùng có thể tương tác để thực hiện một điều gì đó, chẳng hạn như quay số điện thoại, chụp ảnh, gửi e-mail hoặc
+xem bản đồ. Mỗi hoạt động được cho trong một cửa sổ là nơi để vẽ giao diện người dùng của nó. Cửa sổ này
+thường lấp đầy màn hình, nhưng có thể nhỏ hơn màn hình và nổi bên trên các cửa sổ
+khác.</p>
+
+<p> Ứng dụng thường bao gồm nhiều hoạt động được liên kết lỏng lẻo
+với nhau. Thường thì một hoạt động trong một ứng dụng sẽ được quy định là hoạt động "chính", nó được
+trình bày trước người dùng khi khởi chạy ứng dụng lần đầu. Sau đó, mỗi
+hoạt động có thể bắt đầu một hoạt động khác để thực hiện các hành động khác nhau. Mỗi khi một hoạt động
+mới bắt đầu, hoạt động trước đó sẽ bị dừng lại, nhưng hệ thống vẫn giữ nguyên hoạt động
+trong một ngăn xếp ("back stack"). Khi một hoạt động mới bắt đầu, nó được đẩy lên ngăn xếp và
+chiếm lấy tiêu điểm của người dùng. Ngăn xếp sẽ tuân theo cơ chế xếp chồng cơ bản "vào cuối, ra đầu",
+vì thế, khi người dùng kết thúc hoạt động hiện tại và nhấn nút <em>Quay lại</em>, nó
+sẽ được đẩy ra khỏi ngăn xếp (và bị hủy) và hoạt động trước đó sẽ tiếp tục. (Ngăn xếp được
+đề cập kỹ hơn trong tài liệu <a href="{@docRoot}guide/components/tasks-and-back-stack.html">Tác vụ
+và Ngăn Xếp</a>.)</p>
+
+<p>Khi một hoạt động bị dừng vì một hoạt động mới bắt đầu, nó được thông báo về sự thay đổi trạng thái này
+qua các phương pháp gọi lại vòng đời của hoạt động.
+Có một vài phương pháp gọi lại vòng đời mà một hoạt động có thể nhận, do một thay đổi về
+trạng thái của nó&mdash;dù hệ thống đang tạo, dừng hay tiếp tục nó, hay hủy nó&mdash;và
+mỗi lần gọi lại cho bạn cơ hội thực hiện công việc cụ thể
+phù hợp với sự thay đổi trạng thái đó. Ví dụ, khi bị dừng, hoạt động của bạn sẽ giải phóng mọi
+đối tượng lớn, chẳng hạn như các kết nối mạng hoặc cơ sở dữ liệu. Khi hoạt động tiếp tục, bạn có thể
+thu lại những tài nguyên cần thiết và tiếp tục những hành động bị gián đoạn. Những chuyển tiếp trạng thái này
+đều là một phần của vòng đời hoạt động.</p>
+
+<p>Phần còn lại của tài liệu này bàn đến những nội dung cơ bản về cách xây dựng và sử dụng một hoạt động,
+bao gồm một nội dung đề cập đầy đủ về cách vận hành của vòng đời hoạt động, để bạn có thể quản lý tốt
+sự chuyển tiếp giữa các trạng thái hoạt động khác nhau.</p>
+
+
+
+<h2 id="Creating">Tạo một Hoạt động</h2>
+
+<p>Để tạo một hoạt động, bạn phải tạo một lớp con của {@link android.app.Activity} (hoặc
+một lớp con hiện tại của nó). Trong lớp con của mình, bạn cần triển khai các phương pháp gọi lại mà hệ thống
+gọi khi hoạt động chuyển tiếp giữa các trạng thái khác nhau trong vòng đời, chẳng hạn như khi
+hoạt động đang được tạo, dừng, tiếp tục, hoặc hủy. Hai phương pháp gọi lại quan trọng nhất
+là:</p>
+
+<dl>
+ <dt>{@link android.app.Activity#onCreate onCreate()}</dt>
+ <dd>Bạn phải triển khai phương pháp này. Hệ thống gọi phương pháp này khi tạo hoạt động
+của bạn. Trong quá trình thực hiện của mình, bạn nên khởi chạy những thành phần thiết yếu cho hoạt động
+của mình.
+ Quan trọng nhất, đây là lúc bạn phải gọi {@link android.app.Activity#setContentView
+ setContentView()} để định nghĩa bố trí cho giao diện người dùng của hoạt động.</dd>
+ <dt>{@link android.app.Activity#onPause onPause()}</dt>
+ <dd>Hệ thống gọi phương pháp này là dấu hiệu đầu tiên về việc người dùng đang rời khỏi hoạt động
+của bạn (mặc dù không phải lúc nào cũng có nghĩa rằng hoạt động đang bị hủy). Trường hợp này thường là khi bạn
+định thực hiện bất kỳ thay đổi nào vẫn cần có hiệu lực ngoài phiên của người dùng hiện thời (vì
+người dùng có thể không quay lại).</dd>
+</dl>
+
+<p>Có một vài phương pháp gọi lại vòng đời khác mà bạn nên sử dụng để đem đến
+một trải nghiệm người dùng mượt mà giữa các hoạt động và xử lý những gián đoạn bất ngờ khiến hoạt động của bạn
+bị dừng và thậm chí bị hủy. Tất cả phương pháp gọi lại vòng đời được bàn sau trong phần
+nói về <a href="#Lifecycle">Quản lý Vòng đời của Hoạt động</a>.</p>
+
+
+
+<h3 id="UI">Triển khai một giao diện người dùng</h3>
+
+<p> Giao diện người dùng cho một hoạt động sẽ được cung cấp theo phân cấp dạng xem&mdash;đối tượng được suy ra
+từ lớp {@link android.view.View}. Mỗi chế độ xem kiểm soát một không gian chữ nhật riêng
+trong cửa sổ của hoạt động và có thể phản hồi trước tương tác của người dùng. Ví dụ, chế độ xem có thể là
+một nút khởi xướng một hành động khi người dùng chạm vào nó.</p>
+
+<p>Android cung cấp nhiều chế độ xem sẵn có mà bạn có thể sử dụng để thiết kế và tổ chức cho bố trí
+của mình. "Widget" là những chế độ xem cung cấp những phần tử trực quan (và tương tác) cho màn hình, chẳng hạn như
+nút, trường văn bản, hộp kiểm, hay chỉ là một hình ảnh. "Bố trí" là những chế độ xem được suy ra từ {@link
+android.view.ViewGroup} cung cấp một mô hình bố trí duy nhất cho các chế độ xem con của nó, chẳng hạn như bố trí
+tuyến tính, bố trí lưới, hoặc bố trí tương đối. Bạn cũng có thể chia thành lớp con {@link android.view.View} và các lớp
+{@link android.view.ViewGroup} (hoặc các lớp con hiện tại) để tạo widget và
+bố trí của chính mình và áp dụng chúng vào bố trí hoạt động của bạn.</p>
+
+<p>Cách phổ biến nhất để định nghĩa một bố trí bằng cách sử dụng các chế độ xem là dùng một tệp bố trí XML được lưu trong tài nguyên ứng dụng
+của bạn. Bằng cách này, bạn có thể duy trì thiết kế giao diện người dùng của mình độc lập với
+mã nguồn định nghĩa hành vi của hoạt động. Bạn có thể đặt bố trí làm UI cho hoạt động
+của mình bằng {@link android.app.Activity#setContentView(int) setContentView()}, chuyển
+ID tài nguyên cho bố trí. Tuy nhiên, bạn cũng có thể tạo {@link android.view.View} mới trong mã hoạt động
+của mình và xây dựng một cấp bậc chế độ xem bằng cách chèn các {@link
+android.view.View} mới vào một {@link android.view.ViewGroup}, sau đó sử dụng bố trí đó bằng cách chuyển root
+{@link android.view.ViewGroup} sang {@link android.app.Activity#setContentView(View)
+setContentView()}.</p>
+
+<p>Để biết thông tin về việc tạo một giao diện người dùng, hãy xem tài liệu <a href="{@docRoot}guide/topics/ui/index.html">Giao diện Người dùng</a>.</p>
+
+
+
+<h3 id="Declaring">Khai báo hoạt động trong bản kê khai</h3>
+
+<p>Bạn phải khai báo hoạt động của mình trong tệp bản kê khai để hoạt động
+có thể truy cập được vào hệ thống. Để khai báo hoạt động của mình, hãy mở tệp bản kê khai của bạn và thêm một phần tử <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a>
+làm con của phần tử <a href="{@docRoot}guide/topics/manifest/application-element.html">{@code &lt;application&gt;}</a>
+. Ví dụ:</p>
+
+<pre>
+&lt;manifest ... &gt;
+ &lt;application ... &gt;
+ &lt;activity android:name=".ExampleActivity" /&gt;
+ ...
+ &lt;/application ... &gt;
+ ...
+&lt;/manifest &gt;
+</pre>
+
+<p>Có vài thuộc tính khác mà bạn có thể nêu trong phần tử này, để định nghĩa các thuộc tính
+như nhãn cho hoạt động, biểu tượng cho hoạt động, hoặc chủ đề mô tả kiểu UI của
+hoạt động. Thuộc tính <a href="{@docRoot}guide/topics/manifest/activity-element.html#nm">{@code android:name}</a>
+là thuộc tính bắt buộc duy nhất&mdash;nó quy định tên lớp của hoạt động. Một khi
+bạn phát hành ứng dụng của mình, bạn không nên thay đổi tên này, vì nếu bạn làm vậy, bạn có thể làm hỏng
+một số tính năng, chẳng hạn như các lối tắt của ứng dụng (hãy đọc bài đăng trên blog, <a href="http://android-developers.blogspot.com/2011/06/things-that-cannot-change.html">Những Điều
+Không Thay Đổi Được</a>).</p>
+
+<p>Xem tài liệu tham khảo phần tử <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a>
+để biết thêm thông tin về việc khai báo hoạt động của bạn trong bản kê khai.</p>
+
+
+<h4>Sử dụng các bộ lọc ý định</h4>
+
+<p>Một phần tử <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code
+&lt;activity&gt;}</a> cũng có thể quy định các bộ lọc ý định khác nhau&mdash;bằng cách sử dụng phần tử <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code
+&lt;intent-filter&gt;}</a> &mdash;để khai báo cách thức mà các thành phần khác của ứng dụng có thể
+kích hoạt nó.</p>
+
+<p>Khi bạn tạo một ứng dụng mới bằng cách sử dụng các công cụ SDK của Android, hoạt động chương trình nhỏ
+được tạo cho bạn sẽ tự động bao gồm một bộ lọc ý định khai báo hoạt động
+phản hồi lại hành động "chính" và nên được đặt trong thể loại "trình khởi chạy". Bộ lọc ý định
+trông như thế này:</p>
+
+<pre>
+&lt;activity android:name=".ExampleActivity" android:icon="@drawable/app_icon"&gt;
+ &lt;intent-filter&gt;
+ &lt;action android:name="android.intent.action.MAIN" /&gt;
+ &lt;category android:name="android.intent.category.LAUNCHER" /&gt;
+ &lt;/intent-filter&gt;
+&lt;/activity&gt;
+</pre>
+
+<p>Phần tử <a href="{@docRoot}guide/topics/manifest/action-element.html">{@code
+&lt;action&gt;}</a> quy định rằng đây là điểm mục nhập "chính" đối với ứng dụng. Phần tử <a href="{@docRoot}guide/topics/manifest/category-element.html">{@code
+&lt;category&gt;}</a> quy định rằng hoạt động này nên được liệt kê trong trình khởi chạy ứng dụng của hệ thống
+(để cho phép người dùng khởi chạy hoạt động này).</p>
+
+<p>Nếu bạn có ý định cho ứng dụng của mình được độc lập và không cho phép các ứng dụng khác
+kích hoạt các hoạt động của nó, vậy bạn không cần bất kỳ bộ lọc ý định nào khác. Chỉ một hoạt động nên có
+hành động "chính" và thể loại "trình khởi chạy" như trong ví dụ trước. Những hoạt động mà
+bạn không muốn cung cấp sẵn cho các ứng dụng khác không nên có bộ lọc ý định và bạn có thể
+tự mình bắt đầu chúng bằng cách sử dụng các ý định rõ ràng (như được đề cập trong phần sau).</p>
+
+<p>Tuy nhiên, nếu bạn muốn hoạt động của mình phản hồi lại những ý định ngầm mà được chuyển giao từ
+các ứng dụng khác (và chính bạn), thì bạn phải định nghĩa các bộ lọc ý định bổ sung cho hoạt động
+của mình. Với mỗi loại ý định mà bạn muốn phản hồi, bạn phải nêu một <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code
+&lt;intent-filter&gt;}</a> bao gồm một phần tử
+<a href="{@docRoot}guide/topics/manifest/action-element.html">{@code
+&lt;action&gt;}</a> và, không bắt buộc, một phần tử <a href="{@docRoot}guide/topics/manifest/category-element.html">{@code
+&lt;category&gt;}</a> và/hoặc một phần tử <a href="{@docRoot}guide/topics/manifest/data-element.html">{@code
+&lt;data&gt;}</a>. Những phần tử này quy định loại ý định mà hoạt động của bạn có thể
+phản hồi.</p>
+
+<p>Để biết thêm thông tin về cách thức các hoạt động của bạn có thể phản hồi lại ý định, hãy xem tài liệu <a href="{@docRoot}guide/components/intents-filters.html">Ý định và Bộ lọc Ý định</a>
+.</p>
+
+
+
+<h2 id="StartingAnActivity">Bắt đầu một Hoạt động</h2>
+
+<p>Bạn có thể bắt đầu một hoạt động khác bằng cách gọi {@link android.app.Activity#startActivity
+ startActivity()}, chuyển cho nó một {@link android.content.Intent} mà mô tả hoạt động bạn
+muốn bắt đầu. Ý định này sẽ quy định hoặc hoạt động chính xác mà bạn muốn bắt đầu hoặc mô tả
+ loại hành động mà bạn muốn thực hiện (và hệ thống lựa chọn hoạt động phù hợp cho bạn,
+thậm chí
+có thể từ một ứng dụng khác). Một ý định cũng có thể mang theo lượng nhỏ dữ liệu sẽ được
+ sử dụng bởi hoạt động được bắt đầu.</p>
+
+<p>Khi đang làm việc trong ứng dụng của chính mình, bạn thường sẽ cần khởi chạy một hoạt động đã biết.
+ Bạn có thể làm vậy bằng cách tạo một ý định trong đó quy định rõ hoạt động bạn muốn bắt đầu,
+sử dụng tên lớp đó. Ví dụ, sau đây là cách một hoạt động bắt đầu một hoạt động khác có tên {@code
+SignInActivity}:</p>
+
+<pre>
+Intent intent = new Intent(this, SignInActivity.class);
+startActivity(intent);
+</pre>
+
+<p>Tuy nhiên, ứng dụng của bạn cũng có thể muốn thực hiện một số hành động, chẳng hạn như gửi một e-mail, tin nhắn
+ văn bản, hoặc cập nhật trạng thái, bằng cách sử dụng dữ liệu từ hoạt động của bạn. Trong trường hợp này, ứng dụng của bạn có thể
+ không có các hoạt động của chính nó để thực hiện những hành động đó, vì vậy, thay vào đó, bạn có thể tận dụng những hoạt động
+ được cung cấp bởi các ứng dụng khác trên thiết bị mà có thể thực hiện hành động cho bạn. Đây là lúc
+ý định thực sự có giá trị&mdash;bạn có thể tạo một ý định mô tả một hành động bạn muốn
+thực hiện và hệ thống
+ sẽ khởi chạy hoạt động phù hợp đó từ một ứng dụng khác. Nếu có
+ nhiều hoạt động mà có thể xử lý ý định, vậy người dùng có thể chọn hoạt động nào sẽ sử dụng. Ví
+ dụ, nếu bạn muốn cho phép người dùng gửi e-mail, bạn có thể tạo
+ ý định sau:</p>
+
+<pre>
+Intent intent = new Intent(Intent.ACTION_SEND);
+intent.putExtra(Intent.EXTRA_EMAIL, recipientArray);
+startActivity(intent);
+</pre>
+
+<p>{@link android.content.Intent#EXTRA_EMAIL} phụ được thêm vào ý định là một mảng xâu của
+ các địa chỉ e-mail mà e-mail sẽ được gửi tới. Khi một ứng dụng e-mail phản hồi
+ ý định này, nó đọc mảng xâu được cung cấp trong phần phụ và đặt nó vào trường "đến" của mẫu soạn thảo
+ e-mail. Trong trường hợp này, hoạt động của ứng dụng e-mail bắt đầu và khi người dùng
+ làm xong, hoạt động của bạn sẽ tiếp tục.</p>
+
+
+
+
+<h3 id="StartingAnActivityForResult">Bắt đầu một hoạt động cho một kết quả</h3>
+
+<p>Đôi khi bạn có thể muốn nhận được một kết quả từ hoạt động mà bạn bắt đầu. Trong trường hợp đó,
+hãy bắt đầu hoạt động bằng cách gọi {@link android.app.Activity#startActivityForResult
+ startActivityForResult()} (thay vì {@link android.app.Activity#startActivity
+ startActivity()}). Rồi để nhận được kết quả từ hoạt động
+sau đó, hãy triển khai phương pháp gọi lại {@link android.app.Activity#onActivityResult onActivityResult()}
+. Khi hoạt động sau đó diễn ra xong, nó trả về một kết quả trong một {@link
+android.content.Intent} cho phương pháp {@link android.app.Activity#onActivityResult onActivityResult()}
+của bạn.</p>
+
+<p>Ví dụ, bạn có thể muốn người dùng chọn một trong các liên lạc của họ, vì vậy hoạt động của bạn có thể
+làm gì đó với thông tin trong liên lạc đó. Đây là cách bạn có thể tạo một ý định như vậy và
+xử lý kết quả:</p>
+
+<pre>
+private void pickContact() {
+ // Create an intent to "pick" a contact, as defined by the content provider URI
+ Intent intent = new Intent(Intent.ACTION_PICK, Contacts.CONTENT_URI);
+ startActivityForResult(intent, PICK_CONTACT_REQUEST);
+}
+
+&#64;Override
+protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+ // If the request went well (OK) and the request was PICK_CONTACT_REQUEST
+ if (resultCode == Activity.RESULT_OK &amp;&amp; requestCode == PICK_CONTACT_REQUEST) {
+ // Perform a query to the contact's content provider for the contact's name
+ Cursor cursor = getContentResolver().query(data.getData(),
+ new String[] {Contacts.DISPLAY_NAME}, null, null, null);
+ if (cursor.moveToFirst()) { // True if the cursor is not empty
+ int columnIndex = cursor.getColumnIndex(Contacts.DISPLAY_NAME);
+ String name = cursor.getString(columnIndex);
+ // Do something with the selected contact's name...
+ }
+ }
+}
+</pre>
+
+<p>Ví dụ này thể hiện lô-gic cơ bản mà bạn sẽ sử dụng trong phương pháp {@link
+android.app.Activity#onActivityResult onActivityResult()} của mình để xử lý một
+kết quả hoạt động. Điều kiện đầu tiên kiểm tra xem yêu cầu có thành công không&mdash;nếu có thì
+{@code resultCode} sẽ là {@link android.app.Activity#RESULT_OK}&mdash;và liệu yêu cầu
+mà kiểm tra này đang phản hồi có được biết hay không&mdash;trong trường hợp này, {@code requestCode} phù hợp với
+tham số thứ hai được gửi bằng {@link android.app.Activity#startActivityForResult
+startActivityForResult()}. Từ đó, mã xử lý kết quả hoạt động bằng cách truy vấn
+dữ liệu được trả về trong {@link android.content.Intent} (tham số {@code data}).</p>
+
+<p>Điều xảy ra đó là, {@link
+android.content.ContentResolver} sẽ thực hiện một truy vấn đối với nhà cung cấp nội dung, truy vấn này trả về một
+{@link android.database.Cursor} cho phép đọc dữ liệu được truy vấn. Để biết thêm thông tin, hãy xem tài liệu
+<a href="{@docRoot}guide/topics/providers/content-providers.html">Trình cung cấp Nội dung</a>.</p>
+
+<p>Để biết thêm thông tin về việc sử dụng ý định, hãy xem tài liệu <a href="{@docRoot}guide/components/intents-filters.html">Ý định và Bộ lọc
+Ý định</a>.</p>
+
+
+<h2 id="ShuttingDown">Tắt một Hoạt động</h2>
+
+<p>Bạn có thể tắt một hoạt động bằng cách gọi phương pháp {@link android.app.Activity#finish
+finish()} của nó. Bạn cũng có thể tắt một hoạt động riêng mà trước đó bạn đã bắt đầu bằng cách gọi
+{@link android.app.Activity#finishActivity finishActivity()}.</p>
+
+<p class="note"><strong>Lưu ý:</strong> Trong hầu hết trường hợp, bạn không nên kết thúc một hoạt động một cách rõ ràng
+bằng cách sử dụng những phương pháp này. Như đề cập trong phần sau về vòng đời của hoạt động, hệ thống
+Android quản lý tuổi thọ của một hoạt động cho bạn, vì vậy bạn không cần kết thúc các hoạt động
+của chính mình. Việc gọi những phương pháp này có thể ảnh hưởng tiêu cực tới trải nghiệm người dùng
+kỳ vọng và chỉ nên được sử dụng khi bạn tuyệt đối không muốn người dùng quay lại thực thể này của
+hoạt động.</p>
+
+
+<h2 id="Lifecycle">Quản lý Vòng đời của Hoạt động</h2>
+
+<p>Việc quản lý vòng đời các hoạt động của bạn bằng cách triển khai các phương pháp gọi lại
+rất quan trọng đối với việc xây dựng một ứng dụng mạnh
+và linh hoạt. Vòng đời của một hoạt động trực tiếp bị ảnh hưởng bởi sự liên kết giữa nó với
+các hoạt động khác, tác vụ của nó và ngăn xếp (back stack).</p>
+
+<p>Về cơ bản, một hoạt động có thể tồn tại ở ba trạng thái:</p>
+
+<dl>
+ <dt><i>Tiếp tục</i></dt>
+ <dd>Hoạt động ở tiền cảnh của màn hình và có tiêu điểm của người dùng. (Trạng thái này
+đôi khi cũng được gọi là "đang chạy".)</dd>
+
+ <dt><i>Tạm dừng</i></dt>
+ <dd>Một hoạt động khác ở tiền cảnh và có tiêu điểm, nhưng hoạt động này vẫn hiển thị. Cụ thể,
+một hoạt động khác hiển thị ở trên hoạt động này và hoạt động đó trong suốt một phần hoặc không
+che toàn bộ màn hình. Trạng thái tạm dừng hoàn toàn đang hoạt động (đối tượng {@link android.app.Activity}
+được giữ lại trong bộ nhớ, nó duy trì tất cả thông tin về trạng thái và thành viên, và vẫn gắn với
+trình quản lý cửa sổ), nhưng có thể bị hệ thống tắt bỏ trong trường hợp bộ nhớ cực kỳ thấp.</dd>
+
+ <dt><i>Dừng</i></dt>
+ <dd>Hoạt động bị che khuất hoàn toàn bởi một hoạt động khác (hoạt động hiện đang
+“dưới nền"). Hoạt động dừng cũng vẫn đang hoạt động ({@link android.app.Activity}
+đối tượng được giữ lại trong bộ nhớ, nó duy trì tất cả thông tin về trạng thái và thành viên, nhưng <em>không</em>
+gắn với trình quản lý cửa sổ). Tuy nhiên, hoạt động không còn hiển thị với người dùng nữa và hệ thống
+có thể tắt bỏ hoạt động này khi cần bộ nhớ ở nơi khác.</dd>
+</dl>
+
+<p>Nếu một hoạt động bị tạm dừng hoặc dừng, hệ thống có thể bỏ nó khỏi bộ nhớ hoặc bằng cách yêu cầu nó
+kết thúc (gọi phương pháp {@link android.app.Activity#finish finish()} của nó), hoặc đơn giản là tắt bỏ tiến trình
+của hoạt động. Khi hoạt động được mở lại (sau khi bị kết thúc hoặc tắt bỏ), nó phải được tạo
+lại hoàn toàn.</p>
+
+
+
+<h3 id="ImplementingLifecycleCallbacks">Triển khai gọi lại vòng đời</h3>
+
+<p>Khi một hoạt động chuyển tiếp vào ra các trạng thái khác nhau nêu trên, nó được thông báo
+thông qua các phương pháp gọi lại. Tất cả phương pháp gọi lại đều là những móc (hook) mà bạn
+có thể khống chế để làm công việc phù hợp khi trạng thái hoạt động của bạn thay đổi. Hoạt động khung sau
+bao gồm từng phương pháp trong các phương pháp vòng đời cơ bản:</p>
+
+
+<pre>
+public class ExampleActivity extends Activity {
+ &#64;Override
+ public void {@link android.app.Activity#onCreate onCreate}(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // The activity is being created.
+ }
+ &#64;Override
+ protected void {@link android.app.Activity#onStart onStart()} {
+ super.onStart();
+ // The activity is about to become visible.
+ }
+ &#64;Override
+ protected void {@link android.app.Activity#onResume onResume()} {
+ super.onResume();
+ // The activity has become visible (it is now "resumed").
+ }
+ &#64;Override
+ protected void {@link android.app.Activity#onPause onPause()} {
+ super.onPause();
+ // Another activity is taking focus (this activity is about to be "paused").
+ }
+ &#64;Override
+ protected void {@link android.app.Activity#onStop onStop()} {
+ super.onStop();
+ // The activity is no longer visible (it is now "stopped")
+ }
+ &#64;Override
+ protected void {@link android.app.Activity#onDestroy onDestroy()} {
+ super.onDestroy();
+ // The activity is about to be destroyed.
+ }
+}
+</pre>
+
+<p class="note"><strong>Lưu ý:</strong> Việc bạn triển khai những phương pháp vòng đời này phải luôn
+gọi triển khai siêu lớp trước khi làm bất kỳ công việc nào, như minh họa trong các ví dụ bên trên.</p>
+
+<p>Cùng nhau, những phương pháp này định nghĩa toàn bộ vòng đời của một hoạt động. Bằng việc triển khai những phương pháp
+này, bạn có thể theo dõi ba vòng lặp lồng nhau trong vòng đời của hoạt động: </p>
+
+<ul>
+<li><b>Toàn bộ vòng đời</b> của một hoạt động sẽ xảy ra từ thời điểm lệnh gọi đến {@link
+android.app.Activity#onCreate onCreate()} cho tới thời điểm lệnh gọi đến {@link
+android.app.Activity#onDestroy}. Hoạt động của bạn nên thực hiện thiết lập
+trạng thái "chung" (chẳng hạn như định nghĩa bố trí) trong {@link android.app.Activity#onCreate onCreate()}, và
+giải phóng tất cả tài nguyên còn lại trong {@link android.app.Activity#onDestroy}. Ví dụ, nếu hoạt động của bạn
+có một luồng đang chạy ngầm để tải xuống dữ liệu từ mạng, nó có thể tạo
+luồng đó trong {@link android.app.Activity#onCreate onCreate()} rồi dừng luồng trong {@link
+android.app.Activity#onDestroy}.</li>
+
+<li><p><b>Vòng đời hiển thị</b> của một hoạt động xảy ra từ thời điểm lệnh gọi đến {@link
+android.app.Activity#onStart onStart()} cho tới lệnh gọi đến {@link
+android.app.Activity#onStop onStop()}. Trong thời gian này, người dùng có thể thấy hoạt động
+trên màn hình và tương tác với nó. Ví dụ, {@link android.app.Activity#onStop onStop()} được gọi
+khi một hoạt động mới bắt đầu và không còn hiển thị nữa. Giữa hai phương pháp này, bạn có thể
+duy trì các tài nguyên cần để cho người dùng thấy hoạt động. Ví dụ, bạn có thể đăng ký một
+{@link android.content.BroadcastReceiver} trong {@link
+android.app.Activity#onStart onStart()} để theo dõi các thay đổi tác động tới UI của mình, và bỏ đăng ký
+nó trong {@link android.app.Activity#onStop onStop()} khi người dùng không còn thấy thứ bạn đang
+hiển thị nữa. Hệ thống có thể gọi {@link android.app.Activity#onStart onStart()} và {@link
+android.app.Activity#onStop onStop()} nhiều lần trong suốt vòng đời của hoạt động, khi đó
+hoạt động luân chuyển giữa trạng thái hiển thị và ẩn với người dùng.</p></li>
+
+<li><p><b>Vòng đời ở tiền cảnh</b> của một hoạt động xảy ra từ thời điểm lệnh gọi đến {@link
+android.app.Activity#onResume onResume()} cho tới thời điểm lệnh gọi đến {@link android.app.Activity#onPause
+onPause()}. Trong thời gian này, hoạt động sẽ ở phía trước tất cả hoạt động khác trên màn hình và có
+tiêu điểm đầu vào của người dùng. Hoạt động có thể thường xuyên chuyển tiếp vào và ra tiền cảnh&mdash;ví
+dụ, {@link android.app.Activity#onPause onPause()} được gọi khi thiết bị vào trạng thái ngủ hoặc
+khi một hộp thoại xuất hiện. Vì trạng thái này có thể chuyển tiếp thường xuyên, mã trong hai phương pháp này nên
+tương đối nhẹ để tránh chuyển tiếp chậm khiến người dùng phải đợi.</p></li>
+</ul>
+
+<p>Hình 1 minh họa những vòng lặp này và các đường dẫn mà một hoạt động có thể diễn ra giữa các trạng thái.
+Hình chữ nhật đại diện cho các phương pháp gọi lại bạn có thể triển khai để thực hiện thao tác khi
+hoạt động chuyển tiếp giữa những trạng thái này. <p>
+
+<img src="{@docRoot}images/activity_lifecycle.png" alt="" />
+<p class="img-caption"><strong>Hình 1.</strong> Vòng đời của hoạt động.</p>
+
+<p>Những phương pháp gọi lại vòng đời này cũng được liệt kê trong bảng 1, trong đó mô tả từng phương pháp
+gọi lại một cách chi tiết hơn và xác định từng phương pháp
+trong vòng đời tổng thể của hoạt động, bao gồm việc hệ thống có thể tắt bỏ hoạt động hay không sau khi
+phương pháp gọi lại hoàn tất.</p>
+
+<p class="table-caption"><strong>Bảng 1.</strong> Tóm tắt các phương pháp gọi lại
+trong vòng đời của hoạt động.</p>
+
+<table border="2" width="85%" frame="hsides" rules="rows">
+<colgroup align="left" span="3"></colgroup>
+<colgroup align="left"></colgroup>
+<colgroup align="center"></colgroup>
+<colgroup align="center"></colgroup>
+
+<thead>
+<tr><th colspan="3">Phương pháp</th> <th>Mô tả</th> <th>Có thể tắt bỏ sau?</th> <th>Tiếp theo</th></tr>
+</thead>
+
+<tbody>
+<tr>
+ <td colspan="3" align="left"><code>{@link android.app.Activity#onCreate onCreate()}</code></td>
+ <td>Được gọi khi hoạt động mới được tạo.
+ Đây là lúc bạn nên thực hiện tất cả thiết lập cố định thông thường của mình &mdash;
+ tạo chế độ xem, kết ghép dữ liệu với danh sách, v.v. Phương pháp này được chuyển cho
+ một đối tượng Gói chứa trạng thái trước đây của hoạt động, nếu trạng thái
+ đó được thu lại (xem phần <a href="#actstate">Lưu Trạng thái Hoạt động</a>,
+ ở đoạn sau).
+ <p>Luôn được theo sau bởi {@code onStart()}.</p></td>
+ <td align="center">Không</td>
+ <td align="center">{@code onStart()}</td>
+</tr>
+
+<tr>
+ <td rowspan="5" style="border-left: none; border-right: none;">&nbsp;&nbsp;&nbsp;&nbsp;</td>
+ <td colspan="2" align="left"><code>{@link android.app.Activity#onRestart
+onRestart()}</code></td>
+ <td>Được gọi sau khi hoạt động đã được dừng, ngay trước khi hoạt động được
+ bắt đầu lại.
+ <p>Luôn được theo sau bởi {@code onStart()}</p></td>
+ <td align="center">Không</td>
+ <td align="center">{@code onStart()}</td>
+</tr>
+
+<tr>
+ <td colspan="2" align="left"><code>{@link android.app.Activity#onStart onStart()}</code></td>
+ <td>Được gọi ngay trước khi hoạt động hiển thị trước người dùng.
+ <p>Được theo sau bởi {@code onResume()} nếu hoạt động vào
+ tiền cảnh, hoặc {@code onStop()} nếu hoạt động bị ẩn.</p></td>
+ <td align="center">Không</td>
+ <td align="center">{@code onResume()} <br/>hoặc<br/> {@code onStop()}</td>
+</tr>
+
+<tr>
+ <td rowspan="2" style="border-left: none;">&nbsp;&nbsp;&nbsp;&nbsp;</td>
+ <td align="left"><code>{@link android.app.Activity#onResume onResume()}</code></td>
+ <td>Được gọi ngay trước khi hoạt động bắt đầu
+ tương tác với người dùng. Tại điểm này, hoạt động nằm ở
+ trên cùng của chồng hoạt động, trong đó mục nhập của người dùng sẽ đến hoạt động này.
+ <p>Luôn được theo sau bởi {@code onPause()}.</p></td>
+ <td align="center">Không</td>
+ <td align="center">{@code onPause()}</td>
+</tr>
+
+<tr>
+ <td align="left"><code>{@link android.app.Activity#onPause onPause()}</code></td>
+ <td>Được gọi khi hệ thống sắp bắt đầu tiếp tục một hoạt động
+ khác. Phương pháp này thường được sử dụng để thực hiện các thay đổi chưa lưu cho
+ dữ liệu liên tục, dừng các hoạt ảnh và những việc khác mà có thể tiêu tốn công suất
+ CPU, v.v. Nó sẽ thực hiện rất nhanh, vì
+ hoạt động tiếp theo sẽ không được tiếp tục tới khi nó trở lại.
+ <p>Được theo sau hoặc bởi {@code onResume()} nếu hoạt động
+ trở lại phía trước, hoặc bởi {@code onStop()} nếu nó
+ không hiển thị với người dùng.</td>
+ <td align="center"><strong style="color:#800000">Có</strong></td>
+ <td align="center">{@code onResume()} <br/>hoặc<br/> {@code onStop()}</td>
+</tr>
+
+<tr>
+ <td colspan="2" align="left"><code>{@link android.app.Activity#onStop onStop()}</code></td>
+ <td>Được gọi khi hoạt động không còn hiển thị với người dùng. Điều này
+ có thể xảy ra vì nó đang bị hủy, hoặc vì một hoạt động khác
+ (đang tồn tại hoặc mới) đã được tiếp tục và đang che khuất nó.
+ <p>Được theo sau hoặc bởi {@code onRestart()} nếu
+ hoạt động đang quay lại để tương tác với người dùng, hoặc bởi
+ {@code onDestroy()} nếu hoạt động này sẽ đi mất.</p></td>
+ <td align="center"><strong style="color:#800000">Có</strong></td>
+ <td align="center">{@code onRestart()} <br/>hoặc<br/> {@code onDestroy()}</td>
+</tr>
+
+<tr>
+ <td colspan="3" align="left"><code>{@link android.app.Activity#onDestroy
+onDestroy()}</code></td>
+ <td>Được gọi trước khi hoạt động bị hủy. Đây là lần gọi cuối cùng
+ mà hoạt động sẽ nhận được. Nên gọi nó hoặc vì
+ hoạt động đang kết thúc (ai đó đã gọi <code>{@link android.app.Activity#finish
+ finish()}</code> trên nó), hoặc vì hệ thống đang tạm thời hủy thực thể này của
+ hoạt động để tiết kiệm bộ nhớ trống. Bạn có thể phân biệt
+ những những kịch bản này bằng phương pháp <code>{@link
+ android.app.Activity#isFinishing isFinishing()}</code>.</td>
+ <td align="center"><strong style="color:#800000">Có</strong></td>
+ <td align="center"><em>không có gì</em></td>
+</tr>
+</tbody>
+</table>
+
+<p>Cột ghi "Có thể tắt bỏ sau?" cho biết liệu hệ thống có thể
+tắt bỏ tiến trình đang lưu trữ hoạt động vào bất cứ lúc nào <em>sau khi phương pháp trả về</em>, mà không
+thực hiện một dòng mã khác của hoạt động hay không. Ba phương pháp được ghi là "có": ({@link
+android.app.Activity#onPause
+onPause()}, {@link android.app.Activity#onStop onStop()}, và {@link android.app.Activity#onDestroy
+onDestroy()}). Vì {@link android.app.Activity#onPause onPause()} là phương pháp đầu tiên
+trong ba phương pháp, sau khi hoạt động được tạo, {@link android.app.Activity#onPause onPause()} là
+phương pháp cuối cùng được bảo đảm sẽ được gọi trước khi tiến trình <em>có thể</em> bị tắt bỏ&mdash;nếu
+hệ thống phải khôi phục bộ nhớ trong một tình huống khẩn cấp, khi đó {@link
+android.app.Activity#onStop onStop()} và {@link android.app.Activity#onDestroy onDestroy()} có thể
+không được gọi. Vì thế, bạn nên sử dụng {@link android.app.Activity#onPause onPause()} để ghi
+dữ liệu cố định quan trọng (chẳng hạn như những chỉnh sửa của người dùng) vào thiết bị lưu trữ. Tuy nhiên, bạn nên chọn lọc
+thông tin nào phải được giữ lại trong {@link android.app.Activity#onPause onPause()}, vì bất kỳ
+thủ tục chặn nào trong phương pháp này cũng chặn chuyển tiếp sang hoạt động kế tiếp và làm chậm trải nghiệm
+của người dùng.</p>
+
+<p> Những phương pháp được ghi "Không" trong cột <b>Có thể tắt bỏ</b> sẽ bảo vệ tiến trình đang lưu trữ
+hoạt động khỏi bị tắt bỏ từ thời điểm chúng được gọi. Vì thế, một hoạt động có thể tắt bỏ được
+từ thời điểm {@link android.app.Activity#onPause onPause()} trở về tới thời điểm
+{@link android.app.Activity#onResume onResume()} sẽ được gọi. Nó sẽ không thể lại tắt bỏ được tới khi
+{@link android.app.Activity#onPause onPause()} lại được gọi và trả về. </p>
+
+<p class="note"><strong>Lưu ý:</strong> Một hoạt động mà không thể "tắt bỏ được" về mặt kỹ thuật bởi
+định nghĩa này trong bảng 1 vẫn có thể bị hệ thống tắt bỏ&mdash;nhưng điều đó chỉ xảy ra trong
+những hoàn cảnh cực đoan khi không còn giải pháp nào khác. Thời điểm một hoạt động có thể bị tắt bỏ được
+đề cập kỹ hơn trong tài liệu <a href="{@docRoot}guide/components/processes-and-threads.html">Tiến trình và
+Luồng</a>.</p>
+
+
+<h3 id="SavingActivityState">Lưu trạng thái của hoạt động</h3>
+
+<p>Phần giới thiệu về <a href="#Lifecycle">Quản lý Vòng đời của Hoạt động</a> có đề cập sơ qua
+rằng
+khi một hoạt động bị tạm dừng hoặc dừng, trạng thái của hoạt động đó sẽ được giữ lại. Điều này đúng vì
+đối tượng {@link android.app.Activity} vẫn được giữ trong bộ nhớ khi nó bị tạm dừng hoặc
+dừng&mdash;tất cả thông tin về các thành viên và trạng thái hiện tại của nó vẫn hoạt động. Vì thế, bất kỳ thay đổi nào
+mà người dùng đã thực hiện trong hoạt động đều được giữ lại sao cho khi hoạt động trở về
+tiền cảnh (khi nó "tiếp tục"), thì những thay đổi này vẫn còn đó.</p>
+
+<p>Tuy nhiên, khi hệ thống hủy một hoạt động để khôi phục bộ nhớ, đối tượng {@link
+android.app.Activity} bị hủy, vì vậy hệ thống không thể đơn thuần tiếp tục hoạt động với trạng thái
+không bị ảnh hưởng. Thay vào đó, hệ thống phải tạo lại đối tượng {@link android.app.Activity} nếu người dùng
+điều hướng trở lại nó. Tuy vậy, người dùng không biết
+rằng hệ thống đã hủy hoạt động và tạo lại nó và, vì thế, có thể
+cho rằng hoạt động sẽ vẫn nguyên như cũ. Trong tình huống này, bạn có thể đảm bảo rằng
+thông tin quan trọng về trạng thái của hoạt động được giữ nguyên bằng cách triển khai một phương pháp gọi lại
+bổ sung cho phép bạn lưu thông tin về trạng thái của hoạt động của mình: {@link
+android.app.Activity#onSaveInstanceState onSaveInstanceState()}.</p>
+
+<p>Hệ thống gọi {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()}
+trước khi khiến hoạt động dễ bị hủy. Hệ thống chuyển cho phương pháp này
+một {@link android.os.Bundle} trong đó bạn có thể lưu
+thông tin trạng thái về hoạt động như cặp tên giá trị, bằng cách sử dụng các phương pháp như {@link
+android.os.Bundle#putString putString()} và {@link
+android.os.Bundle#putInt putInt()}. Sau đó, nếu hệ thống tắt bỏ tiến trình ứng dụng của bạn
+và người dùng điều hướng trở lại hoạt động của bạn, hệ thống sẽ tạo lại hoạt động đó và
+chuyển {@link android.os.Bundle} cho cả {@link android.app.Activity#onCreate onCreate()} và {@link
+android.app.Activity#onRestoreInstanceState onRestoreInstanceState()}. Sử dụng một trong
+hai phương pháp này, bạn có thể trích xuất trạng thái đã lưu của mình từ {@link android.os.Bundle} và khôi phục
+trạng thái của hoạt động. Nếu không có thông tin trạng thái để khôi phục, khi đó {@link
+android.os.Bundle} được chuyển cho bạn sẽ rỗng (là trường hợp khi hoạt động được tạo
+lần đầu).</p>
+
+<img src="{@docRoot}images/fundamentals/restore_instance.png" alt="" />
+<p class="img-caption"><strong>Hình 2.</strong> Hai cách mà theo đó một hoạt động trở về tiêu điểm
+của người dùng với trạng thái không thay đổi: hoặc hoạt động bị hủy, rồi tạo lại và hoạt động phải khôi phục
+trạng thái đã lưu trước đó, hoặc hoạt động bị dừng, rồi tiếp tục và trạng thái của hoạt động
+giữ nguyên không đổi.</p>
+
+<p class="note"><strong>Lưu ý:</strong> Không có gì bảo đảm rằng {@link
+android.app.Activity#onSaveInstanceState onSaveInstanceState()} sẽ được gọi trước khi hoạt động
+của bạn bị hủy, vì có những trường hợp mà sẽ không cần lưu trạng thái
+(chẳng hạn như khi người dùng rời bỏ hoạt động của bạn bằng cách sử dụng nút <em>Quay lại</em>, vì người dùng
+rõ ràng
+đang đóng hoạt động). Nếu hệ thống gọi {@link android.app.Activity#onSaveInstanceState
+onSaveInstanceState()}, nó làm vậy trước {@link
+android.app.Activity#onStop onStop()} và có thể trước cả {@link android.app.Activity#onPause
+onPause()}.</p>
+
+<p>Tuy nhiên, ngay cả khi bạn không làm gì và không triển khai {@link
+android.app.Activity#onSaveInstanceState onSaveInstanceState()}, một phần trạng thái của hoạt động được khôi phục
+bởi việc lớp {@link android.app.Activity} triển khai mặc định {@link
+android.app.Activity#onSaveInstanceState onSaveInstanceState()}. Cụ thể, triển khai
+mặc định sẽ gọi phương pháp {@link
+android.view.View#onSaveInstanceState onSaveInstanceState()} tương ứng cho mọi {@link
+android.view.View} trong bố trí, nó cho phép mỗi chế độ xem cung cấp thông tin về chính nó
+mà sẽ được lưu. Gần như mọi widget trong khuôn khổ Android đều triển khai phương pháp này nếu
+phù hợp, sao cho mọi thay đổi hiển thị đối với UI đều tự động được lưu và khôi phục khi hoạt động
+của bạn được tạo lại. Ví dụ, widget {@link android.widget.EditText} lưu mọi văn bản
+do người dùng điền vào và widget {@link android.widget.CheckBox} lưu sẽ thông tin cho dù đã được kiểm tra
+hay chưa. Việc duy nhất bạn cần làm đó là cung cấp một ID duy nhất (với thuộc tính <a href="{@docRoot}guide/topics/resources/layout-resource.html#idvalue">{@code android:id}</a>
+) cho mỗi widget bạn muốn lưu trạng thái của nó. Nếu một widget không có ID thì hệ thống
+không thể lưu trạng thái của nó.</p>
+
+<div class="sidebox-wrapper">
+<div class="sidebox">
+<p>Bạn cũng có thể rõ ràng dừng một chế độ xem trong bố trí của mình khỏi việc lưu trạng thái của nó bằng cách đặt thuộc tính
+{@link android.R.attr#saveEnabled android:saveEnabled} thành {@code "false"} hoặc bằng cách gọi
+phương pháp {@link android.view.View#setSaveEnabled setSaveEnabled()}. Thường thì bạn không nên
+vô hiệu hóa điều này, nhưng có thể làm nếu bạn muốn khôi phục trạng thái của UI hoạt động khác đi.</p>
+</div>
+</div>
+
+<p>Mặc dù việc triển khai mặc định {@link
+android.app.Activity#onSaveInstanceState onSaveInstanceState()} lưu thông tin hữu ích về
+UI hoạt động của bạn, bạn có thể vẫn cần khống chế nó để lưu thêm thông tin.
+Ví dụ, bạn có thể cần lưu các giá trị thành viên đã thay đổi trong vòng đời của hoạt động (mà
+có thể tương quan với các giá trị được khôi phục trong UI, nhưng các thành viên nắm giữ giá trị UI đó không được
+khôi phục theo mặc định).</p>
+
+<p>Vì việc triển khai mặc định {@link
+android.app.Activity#onSaveInstanceState onSaveInstanceState()} giúp lưu trạng thái của UI, nếu
+bạn khống chế phương pháp để lưu thêm thông tin trạng thái, bạn nên luôn luôn gọi
+triển khai siêu lớp của {@link android.app.Activity#onSaveInstanceState onSaveInstanceState()}
+trước khi thực hiện bất kỳ công việc nào. Tương tự, bạn cũng nên gọi triển khai siêu lớp {@link
+android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} nếu bạn khống chế nó, để
+triển khai mặc định có thể khôi phục các trạng thái xem.</p>
+
+<p class="note"><strong>Lưu ý:</strong> Vì {@link android.app.Activity#onSaveInstanceState
+onSaveInstanceState()} không đảm bảo
+sẽ được gọi, bạn chỉ nên sử dụng nó để ghi trạng thái giao thời của hoạt động (trạng thái của
+UI)&mdash;bạn không nên sử dụng nó để lưu giữ dữ liệu liên tục. Thay vào đó, bạn nên sử dụng {@link
+android.app.Activity#onPause onPause()} để lưu giữ dữ liệu liên tục (chẳng hạn như dữ liệu mà nên được lưu
+vào một cơ sở dữ liệu) khi người dùng rời bỏ hoạt động.</p>
+
+<p>Một cách hay để kiểm tra khả năng khôi phục trạng thái của ứng dụng của bạn đó là chỉ cần xoay
+thiết bị sao cho hướng màn hình thay đổi. Khi hướng màn hình thay đổi, hệ thống
+hủy và tạo lại hoạt động để áp dụng các tài nguyên thay thế mà có thể có sẵn
+cho cấu hình màn hình mới. Chỉ với lý do này mà một điều rất quan trọng đó là hoạt động của bạn
+hoàn toàn khôi phục trạng thái của mình khi nó được tạo lại, vì người dùng thường xoay màn hình trong khi
+sử dụng ứng dụng.</p>
+
+
+<h3 id="ConfigurationChanges">Xử lý thay đổi về cấu hình</h3>
+
+<p>Một số cấu hình thiết bị có thể thay đổi trong thời gian chạy (chẳng hạn như hướng màn hình, sự sẵn có
+của bàn phím, và ngôn ngữ). Khi sự thay đổi đó diễn ra, Android tạo lại hoạt động đang chạy
+(hệ thống gọi {@link android.app.Activity#onDestroy}, rồi ngay lập tức gọi {@link
+android.app.Activity#onCreate onCreate()}). Hành vi này
+được thiết kế để giúp ứng dụng của bạn điều chỉnh theo những cấu hình mới bằng cách tự động tải lại ứng dụng
+của bạn bằng các tài nguyên thay thế mà bạn đã cung cấp (chẳng hạn như bố trí khác cho
+các hướng và kích cỡ màn hình khác).</p>
+
+<p>Nếu bạn thiết kế hoạt động của mình một cách phù hợp để xử lý khởi động lại do thay đổi hướng màn hình và
+khôi phục trạng thái hoạt động như nêu trên, ứng dụng của bạn sẽ linh hoạt hơn trước
+những sự kiện bất ngờ khác trong vòng đời của hoạt động.</p>
+
+<p>Cách tốt nhất để xử lý khởi động lại đó là
+ lưu và khôi phục trạng thái hoạt động của bạn bằng cách sử dụng {@link
+ android.app.Activity#onSaveInstanceState onSaveInstanceState()} và {@link
+android.app.Activity#onRestoreInstanceState onRestoreInstanceState()} (hoặc {@link
+android.app.Activity#onCreate onCreate()}), như đã đề cập trong phần trước.</p>
+
+<p>Để biết thêm thông tin về những thay đổi cấu hình xảy ra tại thời điểm chạy và cách bạn có thể xử lý
+chúng, hãy đọc hướng dẫn <a href="{@docRoot}guide/topics/resources/runtime-changes.html">Xử lý
+Thay đổi trong Thời gian chạy</a>.</p>
+
+
+
+<h3 id="CoordinatingActivities">Điều phối hoạt động</h3>
+
+ <p>Khi một hoạt động bắt đầu một hoạt động khác, cả hai đều trải qua những chuyển tiếp vòng đời. Hoạt động thứ nhất
+tạm dừng và dừng (tuy nhiên, nó sẽ không dừng nếu vẫn hiển thị được dưới nền), trong khi hoạt động kia
+được tạo. Trong trường hợp những hoạt động này chia sẻ dữ liệu được lưu vào đĩa hoặc nơi khác, điều quan trọng là
+phải hiểu rằng hoạt động thứ nhất không bị dừng hoàn toàn trước khi hoạt động thứ hai được tạo.
+Thay vào đó, tiến trình bắt đầu hoạt động thứ hai chồng lấp với tiến trình dừng hoạt động
+thứ nhất.</p>
+
+<p>Thứ tự gọi lại vòng đời được định nghĩa rõ, cụ thể là khi hai hoạt động trong cùng tiến trình
+và hoạt động này bắt đầu hoạt động kia. Sau đây là thứ tự thao tác diễn ra khi Hoạt động
+A bắt đầu Hoạt động B: </p>
+
+<ol>
+<li>Phương pháp {@link android.app.Activity#onPause onPause()} của Hoạt động A thực thi.</li>
+
+<li>{@link android.app.Activity#onCreate onCreate()} của Hoạt động B, {@link
+android.app.Activity#onStart onStart()}, và các phương pháp {@link android.app.Activity#onResume onResume()}
+thực thi theo trình tự. (Hoạt động B lúc này có tiêu điểm của người dùng.)</li>
+
+<li>Sau đó, nếu Hoạt động A không còn hiển thị trên màn hình, phương pháp {@link
+android.app.Activity#onStop onStop()} của nó sẽ thực thi.</li>
+</ol>
+
+ <p>Trình tự gọi lại vòng đời có thể dự đoán này cho phép bạn quản lý chuyển tiếp
+thông tin từ hoạt động này sang hoạt động khác. Ví dụ, nếu bạn phải ghi vào một cơ sở dữ liệu khi
+hoạt động thứ nhất dừng sao cho hoạt động theo sau có thể đọc nó, khi đó bạn nên ghi vào
+cơ sở dữ liệu trong khi {@link android.app.Activity#onPause onPause()} thay vì trong khi {@link
+android.app.Activity#onStop onStop()}.</p>
+
+<!--
+<h2>Beginner's Path</h2>
+
+<p>For more information about how Android maintains a history of activities and
+enables user multitasking, continue with the <b><a
+href="{@docRoot}guide/components/tasks-and-back-stack.html">Tasks and Back
+Stack</a></b> document.</p>
+-->
diff --git a/docs/html-intl/intl/vi/guide/components/bound-services.jd b/docs/html-intl/intl/vi/guide/components/bound-services.jd
new file mode 100644
index 000000000000..7a2ddbaf6321
--- /dev/null
+++ b/docs/html-intl/intl/vi/guide/components/bound-services.jd
@@ -0,0 +1,658 @@
+page.title=Dịch vụ Gắn kết
+parent.title=Dịch vụ
+parent.link=services.html
+@jd:body
+
+
+<div id="qv-wrapper">
+<ol id="qv">
+<h2>Trong tài liệu này</h2>
+<ol>
+ <li><a href="#Basics">Nội dung Cơ bản</a></li>
+ <li><a href="#Creating">Tạo một Dịch vụ Gắn kết</a>
+ <ol>
+ <li><a href="#Binder">Mở rộng lớp Trình gắn kết</a></li>
+ <li><a href="#Messenger">Sử dụng một Hàm nhắn tin</a></li>
+ </ol>
+ </li>
+ <li><a href="#Binding">Gắn kết với một Dịch vụ</a></li>
+ <li><a href="#Lifecycle">Quản lý Vòng đời của một Dịch vụ Gắn kết</a></li>
+</ol>
+
+<h2>Lớp khóa</h2>
+<ol>
+ <li>{@link android.app.Service}</li>
+ <li>{@link android.content.ServiceConnection}</li>
+ <li>{@link android.os.IBinder}</li>
+</ol>
+
+<h2>Mẫu</h2>
+<ol>
+ <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.html">{@code
+ RemoteService}</a></li>
+ <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LocalService.html">{@code
+ LocalService}</a></li>
+</ol>
+
+<h2>Xem thêm</h2>
+<ol>
+ <li><a href="{@docRoot}guide/components/services.html">Dịch vụ</a></li>
+</ol>
+</div>
+
+
+<p>Dịch vụ gắn kết là máy chủ trong một giao diện máy khách-máy chủ. Dịch vụ gắn kết cho phép các thành phần
+(chẳng hạn như các hoạt động) gắn kết với dịch vụ, gửi yêu cầu, nhận phản hồi, và thậm chí thực hiện
+truyền thông liên tiến trình (IPC). Dịch vụ gắn kết thường chỉ hoạt động khi nó phục vụ một thành phần
+ứng dụng khác và không chạy ngầm mãi liên tục.</p>
+
+<p>Tài liệu này cho bạn biết cách tạo một dịch vụ gắn kết, bao gồm cách gắn kết
+với dịch vụ từ các thành phần ứng dụng khác. Tuy nhiên, bạn cũng nên tham khảo tài liệu <a href="{@docRoot}guide/components/services.html">Dịch vụ</a> để biết thêm thông tin
+về các dịch vụ nói chung, chẳng hạn như cách gửi thông báo từ một dịch vụ, đặt
+dịch vụ để chạy trong tiền cảnh, và nhiều nội dung khác.</p>
+
+
+<h2 id="Basics">Nội dung Cơ bản</h2>
+
+<p>Dịch vụ gắn kết là một sự triển khai lớp {@link android.app.Service} cho phép
+các ứng dụng khác gắn kết và tương tác với nó. Để thực hiện gắn kết cho một
+dịch vụ, bạn phải triển khai phương pháp gọi lại {@link android.app.Service#onBind onBind()}. Phương pháp này
+trả về một đối tượng {@link android.os.IBinder} định nghĩa giao diện lập trình mà
+các máy khách có thể sử dụng để tương tác với dịch vụ.</p>
+
+<div class="sidebox-wrapper">
+<div class="sidebox">
+ <h3>Gắn kết với một Dịch vụ được Bắt đầu</h3>
+
+<p>Như đã đề cập trong tài liệu <a href="{@docRoot}guide/components/services.html">Dịch vụ</a>
+, bạn có thể tạo một dịch vụ được bắt đầu và gắn kết. Cụ thể, dịch vụ có thể được
+bắt đầu bằng cách gọi {@link android.content.Context#startService startService()}, nó cho phép dịch vụ
+chạy mãi, và cũng cho phép một máy khách gắn kết với dịch vụ bằng cách gọi {@link
+android.content.Context#bindService bindService()}.
+ <p>Nếu bạn có cho phép dịch vụ của mình được bắt đầu và gắn kết, thì khi dịch vụ đã được
+bắt đầu, hệ thống sẽ <em>không</em> hủy dịch vụ đó khi tất cả máy khách bỏ gắn kết. Thay vào đó, bạn phải
+dừng dịch vụ một cách rõ ràng bằng cách gọi {@link android.app.Service#stopSelf stopSelf()} hoặc {@link
+android.content.Context#stopService stopService()}.</p>
+
+<p>Mặc dù bạn nên thường xuyên triển khai hoặc {@link android.app.Service#onBind onBind()}
+<em>hoặc</em> {@link android.app.Service#onStartCommand onStartCommand()}, đôi khi cần phải
+triển khai cả hai. Ví dụ, một trình chơi nhạc có thể cho rằng nên cho phép dịch vụ của nó chạy
+mãi và cũng thực hiện gắn kết. Bằng cách này, một hoạt động có thể bắt đầu dịch vụ để chơi vài
+bản nhạc và nhạc tiếp tục chơi ngay cả khi người dùng rời khỏi ứng dụng. Lúc đó, khi người dùng
+trở lại ứng dụng, hoạt động có thể gắn kết với dịch vụ để giành lại quyền kiểm soát phát lại.</p>
+
+<p>Đảm bảo đọc phần về <a href="#Lifecycle">Quản lý Vòng đời của một Dịch vụ
+Gắn kết</a> để biết thêm thông tin về vòng đời của dịch vụ khi thêm gắn kết vào một
+dịch vụ được bắt đầu.</p>
+</div>
+</div>
+
+<p>Một máy khách có thể gắn kết với dịch vụ bằng cách gọi {@link android.content.Context#bindService
+bindService()}. Khi làm vậy, nó phải cung cấp việc triển khai {@link
+android.content.ServiceConnection}, có chức năng theo dõi kết nối với dịch vụ. Phương pháp {@link
+android.content.Context#bindService bindService()} trả về ngay lập tức mà không có giá trị, nhưng
+khi hệ thống Android tạo kết nối giữa
+máy khách và dịch vụ, nó gọi {@link
+android.content.ServiceConnection#onServiceConnected onServiceConnected()} trên {@link
+android.content.ServiceConnection}, để giao {@link android.os.IBinder} mà
+máy khách có thể sử dụng để giao tiếp với dịch vụ.</p>
+
+<p>Nhiều máy khách có thể kết nối với dịch vụ đồng thời. Tuy nhiên, hệ thống sẽ gọi phương pháp
+{@link android.app.Service#onBind onBind()} của dịch vụ của bạn để truy xuất {@link android.os.IBinder} chỉ
+khi máy khách đầu tiên gắn kết. Sau đó, hệ thống sẽ giao cùng một {@link android.os.IBinder} đó cho bất kỳ
+máy khách bổ sung nào có gắn kết mà không gọi lại {@link android.app.Service#onBind onBind()}.</p>
+
+<p>Khi máy khách cuối cùng bỏ gắn kết với dịch vụ, hệ thống sẽ hủy dịch vụ (trừ khi dịch vụ
+cũng được bắt đầu bởi {@link android.content.Context#startService startService()}).</p>
+
+<p>Khi bạn triển khai dịch vụ gắn kết của mình, phần quan trọng nhất là định nghĩa giao diện
+mà phương pháp gọi lại {@link android.app.Service#onBind onBind()} của bạn sẽ trả về. Có một vài
+cách khác nhau mà bạn có thể định nghĩa giao diện {@link android.os.IBinder} của dịch vụ của mình và phần
+sau đây sẽ bàn về từng kỹ thuật.</p>
+
+
+
+<h2 id="Creating">Tạo một Dịch vụ Gắn kết</h2>
+
+<p>Khi tạo một dịch vụ thực hiện gắn kết, bạn phải nêu một {@link android.os.IBinder}
+cung cấp giao diện lập trình mà các máy khách có thể sử dụng để tương tác với dịch vụ. Có
+ba cách bạn có thể định nghĩa giao diện:</p>
+
+<dl>
+ <dt><a href="#Binder">Mở rộng lớp Trình gắn kết</a></dt>
+ <dd>Nếu dịch vụ của bạn chỉ riêng cho ứng dụng của chính bạn và chạy trong cùng tiến trình như máy khách
+(điều này thường hay gặp), bạn nên tạo giao diện của mình bằng cách mở rộng lớp {@link android.os.Binder}
+và trả về một thực thể của nó từ
+{@link android.app.Service#onBind onBind()}. Máy khách nhận được {@link android.os.Binder} và
+có thể sử dụng nó để trực tiếp truy cập các phương pháp công khai có sẵn trong triển khai {@link android.os.Binder}
+hoặc thậm chí trong {@link android.app.Service}.
+ <p>Nên áp dụng kỹ thuật này khi dịch vụ của bạn chỉ là một trình thực hiện chạy ngầm cho ứng dụng
+của chính bạn. Lý do duy nhất bạn không nên tạo giao diện của mình bằng cách này đó là
+dịch vụ của bạn được sử dụng bởi các ứng dụng khác hoặc giữa những tiến trình khác nhau.</dd>
+
+ <dt><a href="#Messenger">Sử dụng một Hàm nhắn tin</a></dt>
+ <dd>Nếu bạn cần giao diện của mình thực hiện các tiến trình khác nhau, bạn có thể tạo
+một giao diện cho dịch vụ bằng {@link android.os.Messenger}. Bằng cách này, dịch vụ
+định nghĩa một {@link android.os.Handler} phản hồi các loại đối tượng {@link
+android.os.Message} khác nhau. {@link android.os.Handler}
+này là cơ sở cho một {@link android.os.Messenger} mà sau đó có thể chia sẻ một {@link android.os.IBinder}
+với máy khách, cho phép máy khách gửi lệnh tới dịch vụ bằng cách sử dụng các đối tượng {@link
+android.os.Message}. Ngoài ra, máy khách có thể định nghĩa {@link android.os.Messenger} của
+chính nó để dịch vụ có thể gửi lại thông báo.
+ <p>Đây là cách đơn giản nhất để thực hiện truyền thông liên tiến trình (IPC), vì {@link
+android.os.Messenger} xếp hàng tất cả yêu cầu thành một luồng duy nhất sao cho bạn không phải thiết kế
+dịch vụ của mình an toàn với luồng.</p>
+ </dd>
+
+ <dt>Sử dụng AIDL</dt>
+ <dd>AIDL (Ngôn ngữ Định nghĩa Giao diện Android) thực hiện tất cả công việc để phân tách đối tượng thành
+các phần tử mà hệ điều hành có thể hiểu được và ghép nối chúng qua các tiến trình để thực hiện
+IPC. Bằng cách sử dụng {@link android.os.Messenger}, kỹ thuật trước đó thực tế được dựa trên AIDL như là
+cấu trúc cơ bản của nó. Như đã đề cập bên trên, {@link android.os.Messenger} tạo một hàng chờ
+gồm tất cả yêu cầu của máy khách trong một luồng duy nhất, vì thế dịch vụ nhận được từng yêu cầu một. Tuy nhiên, nếu
+bạn muốn dịch vụ xử lý nhiều yêu cầu đồng thời, bạn có thể sử dụng AIDL
+trực tiếp. Trong trường hợp này, dịch vụ của bạn phải có khả năng tạo đa luồng và được xây dựng an toàn với luồng.
+ <p>Để sử dụng AIDL trực tiếp, bạn phải
+tạo một tệp {@code .aidl} định nghĩa giao diện lập trình. Các công cụ SDK Android sử dụng tệp
+này để khởi tạo một lớp tóm tắt (abstract class) nhằm triển khai giao diện và xử lý IPC, mà sau đó
+bạn có thể mở rộng trong dịch vụ của mình.</p>
+ </dd>
+</dl>
+
+ <p class="note"><strong>Lưu ý:</strong> Hầu hết ứng dụng <strong>không nên</strong> sử dụng AIDL để
+tạo một dịch vụ gắn kết, vì nó có thể yêu cầu khả năng tạo đa luồng và
+có thể dẫn đến việc triển khai phức tạp hơn. Như vậy, AIDL không phù hợp với hầu hết ứng dụng
+và tài liệu này không bàn về cách sử dụng nó cho dịch vụ của bạn. Nếu bạn chắc chắn rằng mình cần
+sử dụng AIDL trực tiếp, hãy xem tài liệu <a href="{@docRoot}guide/components/aidl.html">AIDL</a>
+.</p>
+
+
+
+
+<h3 id="Binder">Mở rộng lớp Trình gắn kết</h3>
+
+<p>Nếu dịch vụ của bạn chỉ được sử dụng bởi ứng dụng cục bộ và không cần làm việc qua nhiều tiến trình,
+khi đó bạn có thể triển khai lớp {@link android.os.Binder} của chính mình để cung cấp quyền truy cập
+trực tiếp cho máy khách của bạn để truy nhập các phương pháp công khai trong dịch vụ.</p>
+
+<p class="note"><strong>Lưu ý:</strong> Cách này chỉ có tác dụng nếu máy khách và dịch vụ nằm trong cùng
+ứng dụng và tiến trình, là trường hợp phổ biến nhất. Ví dụ, cách này sẽ hoạt động tốt đối với một ứng dụng
+nhạc cần gắn kết một hoạt động với dịch vụ của chính nó đang phát nhạc
+chạy ngầm.</p>
+
+<p>Sau đây là cách thiết lập:</p>
+<ol>
+ <li>Trong dịch vụ của bạn, hãy tạo một thực thể {@link android.os.Binder} mà hoặc:
+ <ul>
+ <li>chứa các phương pháp công khai mà máy khách có thể gọi</li>
+ <li>trả về thực thể {@link android.app.Service} hiện tại, trong đó có các phương pháp công khai mà
+máy khách có thể gọi</li>
+ <li>hoặc, trả về một thực thể của một lớp khác được lưu trữ bởi dịch vụ bằng các phương pháp công khai mà
+máy khách có thể gọi</li>
+ </ul>
+ <li>Trả về thực thể {@link android.os.Binder} này từ phương pháp gọi lại {@link
+android.app.Service#onBind onBind()}.</li>
+ <li>Trong máy khách, nhận {@link android.os.Binder} từ phương pháp gọi lại {@link
+android.content.ServiceConnection#onServiceConnected onServiceConnected()} và
+thực hiện gọi tới dịch vụ gắn kết bằng cách sử dụng các phương pháp đã nêu.</li>
+</ol>
+
+<p class="note"><strong>Lưu ý:</strong> Lý do dịch vụ và máy khách phải ở trong cùng
+ứng dụng đó là máy khách có thể đổi kiểu đối tượng được trả về và gọi các API của nó một cách phù hợp. Dịch vụ
+và máy khách cũng phải ở trong cùng tiến trình, vì kỹ thuật này không thực hiện bất kỳ thao tác
+ghép nối qua các tiến trình nào.</p>
+
+<p>Ví dụ, sau đây là một dịch vụ cung cấp cho máy khách quyền truy cập các phương pháp trong dịch vụ thông qua
+việc triển khai {@link android.os.Binder}:</p>
+
+<pre>
+public class LocalService extends Service {
+ // Binder given to clients
+ private final IBinder mBinder = new LocalBinder();
+ // Random number generator
+ private final Random mGenerator = new Random();
+
+ /**
+ * Class used for the client Binder. Because we know this service always
+ * runs in the same process as its clients, we don't need to deal with IPC.
+ */
+ public class LocalBinder extends Binder {
+ LocalService getService() {
+ // Return this instance of LocalService so clients can call public methods
+ return LocalService.this;
+ }
+ }
+
+ &#64;Override
+ public IBinder onBind(Intent intent) {
+ return mBinder;
+ }
+
+ /** method for clients */
+ public int getRandomNumber() {
+ return mGenerator.nextInt(100);
+ }
+}
+</pre>
+
+<p>{@code LocalBinder} cung cấp phương pháp {@code getService()} cho máy khách để truy xuất
+thực thể hiện tại của {@code LocalService}. Điều này cho phép máy khách gọi các phương pháp công khai trong
+dịch vụ. Ví dụ, máy khách có thể gọi {@code getRandomNumber()} từ dịch vụ.</p>
+
+<p>Sau đây là một hoạt động gắn kết với {@code LocalService} và sẽ gọi {@code getRandomNumber()}
+khi nhấp vào nút:</p>
+
+<pre>
+public class BindingActivity extends Activity {
+ LocalService mService;
+ boolean mBound = false;
+
+ &#64;Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+ }
+
+ &#64;Override
+ protected void onStart() {
+ super.onStart();
+ // Bind to LocalService
+ Intent intent = new Intent(this, LocalService.class);
+ bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
+ }
+
+ &#64;Override
+ protected void onStop() {
+ super.onStop();
+ // Unbind from the service
+ if (mBound) {
+ unbindService(mConnection);
+ mBound = false;
+ }
+ }
+
+ /** Called when a button is clicked (the button in the layout file attaches to
+ * this method with the android:onClick attribute) */
+ public void onButtonClick(View v) {
+ if (mBound) {
+ // Call a method from the LocalService.
+ // However, if this call were something that might hang, then this request should
+ // occur in a separate thread to avoid slowing down the activity performance.
+ int num = mService.getRandomNumber();
+ Toast.makeText(this, "number: " + num, Toast.LENGTH_SHORT).show();
+ }
+ }
+
+ /** Defines callbacks for service binding, passed to bindService() */
+ private ServiceConnection mConnection = new ServiceConnection() {
+
+ &#64;Override
+ public void onServiceConnected(ComponentName className,
+ IBinder service) {
+ // We've bound to LocalService, cast the IBinder and get LocalService instance
+ LocalBinder binder = (LocalBinder) service;
+ mService = binder.getService();
+ mBound = true;
+ }
+
+ &#64;Override
+ public void onServiceDisconnected(ComponentName arg0) {
+ mBound = false;
+ }
+ };
+}
+</pre>
+
+<p>Mẫu trên cho thấy cách mà máy khách gắn kết với dịch vụ bằng cách sử dụng triển khai
+{@link android.content.ServiceConnection} và gọi lại {@link
+android.content.ServiceConnection#onServiceConnected onServiceConnected()}. Phần tiếp theo
+cung cấp thêm thông tin về tiến trình gắn kết này với dịch vụ.</p>
+
+<p class="note"><strong>Lưu ý:</strong> Ví dụ trên không công khai bỏ gắn kết khỏi dịch vụ,
+nhưng tất cả máy khách cần bỏ gắn kết tại một thời điểm phù hợp (chẳng hạn như khi hoạt động tạm dừng).</p>
+
+<p>Để biết thêm mã ví dụ, hãy xem lớp <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LocalService.html">{@code
+LocalService.java}</a> và lớp <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LocalServiceActivities.html">{@code
+LocalServiceActivities.java}</a> trong <a href="{@docRoot}resources/samples/ApiDemos/index.html">ApiDemos</a>.</p>
+
+
+
+
+
+<h3 id="Messenger">Sử dụng một Hàm nhắn tin</h3>
+
+<div class="sidebox-wrapper">
+<div class="sidebox">
+ <h4>So sánh với AIDL</h4>
+ <p>Khi bạn cần thực hiện IPC, việc sử dụng một {@link android.os.Messenger} cho giao diện của bạn
+sẽ đơn giản hơn so với việc triển khai nó bằng AIDL, vì {@link android.os.Messenger} xếp hàng
+tất cả lệnh gọi đối với dịch vụ, trong khi đó, giao diện AIDL thuần túy sẽ gửi các yêu cầu đồng thời tới
+dịch vụ, sau đó dịch vụ phải xử lý tạo đa luồng.</p>
+ <p>Đối với hầu hết ứng dụng, dịch vụ không cần thực hiện tạo đa luồng, vì vậy sử dụng một {@link
+android.os.Messenger} sẽ cho phép dịch vụ xử lý từng lệnh gọi tại một thời điểm. Nếu quan trọng là
+dịch vụ của bạn phải được tạo đa luồng, khi đó bạn nên sử dụng <a href="{@docRoot}guide/components/aidl.html">AIDL</a> để định nghĩa giao diện của mình.</p>
+</div>
+</div>
+
+<p>Nếu bạn cần dịch vụ của mình giao tiếp với các tiến trình từ xa, khi đó bạn có thể sử dụng một
+{@link android.os.Messenger} để cung cấp giao diện cho dịch vụ của mình. Kỹ thuật này cho phép
+bạn thực hiện truyền thông liên tiến trình (IPC) mà không cần sử dụng AIDL.</p>
+
+<p>Sau đây là tóm tắt cách sử dụng {@link android.os.Messenger}:</p>
+
+<ul>
+ <li>Dịch vụ triển khai {@link android.os.Handler} để nhận lệnh gọi lại cho mỗi
+lệnh gọi từ một máy khách.</li>
+ <li>{@link android.os.Handler} được sử dụng để tạo một đối tượng {@link android.os.Messenger}
+(là một tham chiếu tới {@link android.os.Handler}).</li>
+ <li>{@link android.os.Messenger} tạo một {@link android.os.IBinder} mà dịch vụ
+trả về máy khách từ {@link android.app.Service#onBind onBind()}.</li>
+ <li>Máy khách sử dụng {@link android.os.IBinder} để khởi tạo {@link android.os.Messenger}
+(tham chiếu tới {@link android.os.Handler} của dịch vụ), mà máy khách sử dụng để gửi các đối tượng
+{@link android.os.Message} tới dịch vụ.</li>
+ <li>Dịch vụ nhận được từng {@link android.os.Message} trong {@link
+android.os.Handler} của mình&mdash;cụ thể là theo phương pháp {@link android.os.Handler#handleMessage
+handleMessage()}.</li>
+</ul>
+
+
+<p>Theo cách này, không có "phương pháp" nào để máy khách gọi đối với dịch vụ. Thay vào đó, máy khách
+gửi “thông báo” (đối tượng {@link android.os.Message}) mà dịch vụ nhận được trong
+{@link android.os.Handler} của mình.</p>
+
+<p>Sau đây là một dịch vụ ví dụ đơn giản sử dụng một giao diện {@link android.os.Messenger}:</p>
+
+<pre>
+public class MessengerService extends Service {
+ /** Command to the service to display a message */
+ static final int MSG_SAY_HELLO = 1;
+
+ /**
+ * Handler of incoming messages from clients.
+ */
+ class IncomingHandler extends Handler {
+ &#64;Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_SAY_HELLO:
+ Toast.makeText(getApplicationContext(), "hello!", Toast.LENGTH_SHORT).show();
+ break;
+ default:
+ super.handleMessage(msg);
+ }
+ }
+ }
+
+ /**
+ * Target we publish for clients to send messages to IncomingHandler.
+ */
+ final Messenger mMessenger = new Messenger(new IncomingHandler());
+
+ /**
+ * When binding to the service, we return an interface to our messenger
+ * for sending messages to the service.
+ */
+ &#64;Override
+ public IBinder onBind(Intent intent) {
+ Toast.makeText(getApplicationContext(), "binding", Toast.LENGTH_SHORT).show();
+ return mMessenger.getBinder();
+ }
+}
+</pre>
+
+<p>Để ý rằng phương pháp {@link android.os.Handler#handleMessage handleMessage()} trong
+{@link android.os.Handler} là nơi dịch vụ nhận được {@link android.os.Message}
+đến và quyết định việc cần làm dựa trên thành viên {@link android.os.Message#what}.</p>
+
+<p>Tất cả việc mà một máy khách cần làm đó là tạo một {@link android.os.Messenger} dựa trên {@link
+android.os.IBinder} được dịch vụ trả về và gửi một thông báo bằng cách sử dụng {@link
+android.os.Messenger#send send()}. Ví dụ, sau đây là một hoạt động đơn giản gắn kết với dịch vụ
+và gửi tin nhắn {@code MSG_SAY_HELLO} cho dịch vụ:</p>
+
+<pre>
+public class ActivityMessenger extends Activity {
+ /** Messenger for communicating with the service. */
+ Messenger mService = null;
+
+ /** Flag indicating whether we have called bind on the service. */
+ boolean mBound;
+
+ /**
+ * Class for interacting with the main interface of the service.
+ */
+ private ServiceConnection mConnection = new ServiceConnection() {
+ public void onServiceConnected(ComponentName className, IBinder service) {
+ // This is called when the connection with the service has been
+ // established, giving us the object we can use to
+ // interact with the service. We are communicating with the
+ // service using a Messenger, so here we get a client-side
+ // representation of that from the raw IBinder object.
+ mService = new Messenger(service);
+ mBound = true;
+ }
+
+ public void onServiceDisconnected(ComponentName className) {
+ // This is called when the connection with the service has been
+ // unexpectedly disconnected -- that is, its process crashed.
+ mService = null;
+ mBound = false;
+ }
+ };
+
+ public void sayHello(View v) {
+ if (!mBound) return;
+ // Create and send a message to the service, using a supported 'what' value
+ Message msg = Message.obtain(null, MessengerService.MSG_SAY_HELLO, 0, 0);
+ try {
+ mService.send(msg);
+ } catch (RemoteException e) {
+ e.printStackTrace();
+ }
+ }
+
+ &#64;Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+ }
+
+ &#64;Override
+ protected void onStart() {
+ super.onStart();
+ // Bind to the service
+ bindService(new Intent(this, MessengerService.class), mConnection,
+ Context.BIND_AUTO_CREATE);
+ }
+
+ &#64;Override
+ protected void onStop() {
+ super.onStop();
+ // Unbind from the service
+ if (mBound) {
+ unbindService(mConnection);
+ mBound = false;
+ }
+ }
+}
+</pre>
+
+<p>Để ý rằng ví dụ này không cho biết cách mà dịch vụ có thể phản hồi máy khách. Nếu bạn muốn dịch vụ
+phản hồi, khi đó bạn cũng cần tạo một {@link android.os.Messenger} trong máy khách. Sau đó
+khi máy khách nhận được lệnh gọi lại {@link android.content.ServiceConnection#onServiceConnected
+onServiceConnected()}, nó sẽ gửi một {@link android.os.Message} tới dịch vụ, trong đó bao gồm
+{@link android.os.Messenger} của máy khách trong tham số {@link android.os.Message#replyTo}
+của phương pháp {@link android.os.Messenger#send send()}.</p>
+
+<p>Bạn có thể xem một ví dụ về cách cung cấp tính năng nhắn tin hai chiều trong <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/MessengerService.html">{@code
+MessengerService.java}</a> (dịch vụ) và các mẫu <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/MessengerServiceActivities.html">{@code
+MessengerServiceActivities.java}</a> (máy khách).</p>
+
+
+
+
+
+<h2 id="Binding">Gắn kết với một Dịch vụ</h2>
+
+<p>Các thành phần ứng dụng (máy khách) có thể gắn kết với một dịch vụ bằng cách gọi
+{@link android.content.Context#bindService bindService()}. Hệ thống Android
+khi đó sẽ gọi phương pháp {@link android.app.Service#onBind
+onBind()} của dịch vụ, nó trả về một {@link android.os.IBinder} để tương tác với dịch vụ.</p>
+
+<p>Việc gắn kết diễn ra không đồng bộ. {@link android.content.Context#bindService
+bindService()} trả về ngay lập tức và <em>không</em> trả {@link android.os.IBinder} về
+máy khách. Để nhận một {@link android.os.IBinder}, máy khách phải tạo một thực thể của {@link
+android.content.ServiceConnection} và chuyển nó cho {@link android.content.Context#bindService
+bindService()}. {@link android.content.ServiceConnection} bao gồm một phương pháp gọi lại mà hệ thống
+gọi để gửi {@link android.os.IBinder}.</p>
+
+<p class="note"><strong>Lưu ý:</strong> Chỉ các hoạt động, dịch vụ, và trình cung cấp nội dung mới có thể gắn kết
+với một dịch vụ&mdash;bạn <strong>không thể</strong> gắn kết với một dịch vụ từ một hàm nhận quảng bá (broadcast receiver).</p>
+
+<p>Vì vậy, để gắn kết với một dịch vụ từ máy khách của mình, bạn phải: </p>
+<ol>
+ <li>Triển khai {@link android.content.ServiceConnection}.
+ <p>Việc triển khai của bạn phải khống chế hai phương pháp gọi lại:</p>
+ <dl>
+ <dt>{@link android.content.ServiceConnection#onServiceConnected onServiceConnected()}</dt>
+ <dd>Hệ thống gọi phương pháp này để gửi {@link android.os.IBinder} được trả về bởi
+phương pháp {@link android.app.Service#onBind onBind()} của dịch vụ.</dd>
+ <dt>{@link android.content.ServiceConnection#onServiceDisconnected
+onServiceDisconnected()}</dt>
+ <dd>Hệ thống Android gọi phương pháp này khi kết nối với dịch vụ bị mất
+đột ngột, chẳng hạn như khi dịch vụ bị lỗi hoặc bị tắt bỏ. Phương pháp này <em>không</em> được gọi khi
+máy khách bỏ gắn kết.</dd>
+ </dl>
+ </li>
+ <li>Gọi {@link
+android.content.Context#bindService bindService()}, chuyển việc triển khai {@link
+android.content.ServiceConnection}. </li>
+ <li>Khi hệ thống gọi phương pháp gọi lại {@link android.content.ServiceConnection#onServiceConnected
+onServiceConnected()} của bạn, bạn có thể bắt đầu thực hiện các lệnh gọi tới dịch vụ bằng các phương pháp
+được định nghĩa bởi giao diện.</li>
+ <li>Để ngắt kết nối khỏi dịch vụ, hãy gọi {@link
+android.content.Context#unbindService unbindService()}.
+ <p>Khi máy khách của bạn bị hủy, nó sẽ bỏ gắn kết khỏi dịch vụ, nhưng bạn nên luôn bỏ gắn kết
+khi bạn đã tương tác xong với dịch vụ hoặc khi hoạt động của bạn tạm dừng sao cho dịch vụ có thể
+tắt khi không dùng đến. (Thời điểm phù hợp để gắn kết và bỏ gắn kết được đề cập
+kỹ hơn ở bên dưới.)</p>
+ </li>
+</ol>
+
+<p>Ví dụ, đoạn mã HTML sau sẽ kết nối máy khách với dịch vụ được tạo bên trên bằng cách
+<a href="#Binder">mở rộng lớp Trình gắn kết</a>, vì vậy tất cả những việc mà nó phải làm là đổi kiểu
+{@link android.os.IBinder} được trả về thành lớp {@code LocalService} và yêu cầu thực thể {@code
+LocalService}:</p>
+
+<pre>
+LocalService mService;
+private ServiceConnection mConnection = new ServiceConnection() {
+ // Called when the connection with the service is established
+ public void onServiceConnected(ComponentName className, IBinder service) {
+ // Because we have bound to an explicit
+ // service that is running in our own process, we can
+ // cast its IBinder to a concrete class and directly access it.
+ LocalBinder binder = (LocalBinder) service;
+ mService = binder.getService();
+ mBound = true;
+ }
+
+ // Called when the connection with the service disconnects unexpectedly
+ public void onServiceDisconnected(ComponentName className) {
+ Log.e(TAG, "onServiceDisconnected");
+ mBound = false;
+ }
+};
+</pre>
+
+<p>Với {@link android.content.ServiceConnection} này, máy khách có thể gắn kết với một dịch vụ bằng cách chuyển
+nó cho {@link android.content.Context#bindService bindService()}. Ví dụ:</p>
+
+<pre>
+Intent intent = new Intent(this, LocalService.class);
+bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
+</pre>
+
+<ul>
+ <li>Tham số đầu tiên của {@link android.content.Context#bindService bindService()} là một
+{@link android.content.Intent} trong đó nêu rõ tên của các dịch vụ sẽ gắn kết (mặc dù ý định
+có thể ngầm hiểu).</li>
+<li>Tham số thứ hai là đối tượng {@link android.content.ServiceConnection}.</li>
+<li>Tham số thứ ba là một cờ cho biết các tùy chọn cho gắn kết. Nên luôn luôn là {@link
+android.content.Context#BIND_AUTO_CREATE} để tạo dịch vụ nếu nó chưa hoạt động.
+Các giá trị có thể khác là {@link android.content.Context#BIND_DEBUG_UNBIND}
+và {@link android.content.Context#BIND_NOT_FOREGROUND}, hoặc {@code 0} trong trường hợp không có.</li>
+</ul>
+
+
+<h3>Lưu ý bổ sung</h3>
+
+<p>Sau đây là một số lưu ý quan trọng về việc gắn kết với một dịch vụ:</p>
+<ul>
+ <li>Bạn nên luôn bẫy các lỗi ngoại lệ {@link android.os.DeadObjectException} phát sinh khi
+kết nối bị đứt. Đây là lỗi ngoại lệ duy nhất phát sinh bởi các phương pháp từ xa.</li>
+ <li>Các đối tượng được xem là tham chiếu khắp các tiến trình. </li>
+ <li>Bạn nên luôn ghép đôi gắn kết và bỏ gắn kết trong khi
+khớp những khoảnh khắc kết nối và đứt kết nối trong vòng đời của máy khách. Ví dụ:
+ <ul>
+ <li>Nếu bạn chỉ cần tương tác với dịch vụ trong khi hoạt động của bạn hiển thị, bạn
+nên gắn kết trong khi {@link android.app.Activity#onStart onStart()} và bỏ gắn kết trong khi {@link
+android.app.Activity#onStop onStop()}.</li>
+ <li>Nếu bạn muốn hoạt động của mình nhận được phản hồi ngay cả trong khi bị dừng khi đang
+dưới nền, khi đó bạn có thể gắn kết trong khi {@link android.app.Activity#onCreate onCreate()} và bỏ gắn kết
+trong khi {@link android.app.Activity#onDestroy onDestroy()}. Chú ý rằng điều này hàm ý rằng hoạt động
+của bạn cần sử dụng dịch vụ trong toàn bộ thời gian khi nó đang chạy (ngay cả khi chạy ngầm), do đó nếu
+dịch vụ ở trong một tiến trình khác thì bạn hãy tăng trọng số của tiến trình và khả năng hệ thống
+tắt bỏ tiến trình đó sẽ cao hơn.</li>
+ </ul>
+ <p class="note"><strong>Lưu ý:</strong> Thông thường bạn <strong>không</strong> nên gắn kết và bỏ gắn kết
+trong khi {@link android.app.Activity#onResume onResume()} và {@link
+android.app.Activity#onPause onPause()} cho hoạt động của mình, vì những lệnh gọi lại này diễn ra tại mọi thời điểm chuyển tiếp vòng đời
+và bạn nên duy trì xử lý tại những thời điểm chuyển tiếp này ở mức tối thiểu. Đồng thời, nếu
+nhiều hoạt động trong ứng dụng của bạn gắn kết với cùng dịch vụ và có sự chuyển tiếp giữa
+hai trong số những hoạt động đó, dịch vụ có thể bị hủy và tạo lại khi hoạt động hiện tại bỏ gắn kết
+(trong khi tạm dừng) trước khi hoạt động tiếp theo gắn kết (trong khi tiếp tục). (Sự chuyển tiếp hoạt động này đối với cách mà các hoạt động
+phối hợp vòng đời của chúng được mô tả trong tài liệu <a href="{@docRoot}guide/components/activities.html#CoordinatingActivities">Hoạt động</a>
+.)</p>
+</ul>
+
+<p>Để biết thêm mã ví dụ, thể hiện cách gắn kết với một dịch vụ, hãy xem lớp <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/RemoteService.html">{@code
+RemoteService.java}</a> trong <a href="{@docRoot}resources/samples/ApiDemos/index.html">ApiDemos</a>.</p>
+
+
+
+
+
+<h2 id="Lifecycle">Quản lý Vòng đời của một Dịch vụ Gắn kết</h2>
+
+<p>Khi một dịch vụ bị bỏ gắn kết khỏi tất cả máy khách, hệ thống Android sẽ hủy nó (trừ khi nó cũng
+được bắt đầu bằng {@link android.app.Service#onStartCommand onStartCommand()}). Như vậy, bạn không phải
+ quản lý vòng đời dịch vụ của mình nếu nó thuần túy là một
+dịch vụ gắn kết&mdash;hệ thống Android sẽ quản lý nó cho bạn dựa trên việc nó có gắn kết với bất kỳ máy khách nào không.</p>
+
+<p>Tuy nhiên, nếu bạn chọn triển khai phương pháp gọi lại {@link android.app.Service#onStartCommand
+onStartCommand()}, vậy thì bạn phải dừng dịch vụ một cách tường minh, vì dịch vụ
+lúc này đang được coi là <em>được bắt đầu</em>. Trong trường hợp này, dịch vụ sẽ chạy cho tới khi dịch vụ
+tự dừng bằng {@link android.app.Service#stopSelf()} hoặc một thành phần khác sẽ gọi {@link
+android.content.Context#stopService stopService()}, bất kể nó có gắn kết với bất kỳ máy khách
+nào không.</p>
+
+<p>Ngoài ra, nếu dịch vụ của bạn được bắt đầu và chấp nhận gắn kết, lúc đó khi hệ thống gọi
+phương pháp {@link android.app.Service#onUnbind onUnbind()} của bạn, bạn có thể tùy chọn trả về
+{@code true} nếu bạn muốn nhận một lệnh gọi tới {@link android.app.Service#onRebind
+onRebind()} vào lần tới khi một máy khách gắn kết với dịch vụ (thay vì nhận một lệnh gọi tới {@link
+android.app.Service#onBind onBind()}). {@link android.app.Service#onRebind
+onRebind()} sẽ trả về rỗng, nhưng máy khách vẫn nhận được {@link android.os.IBinder} trong gọi lại
+{@link android.content.ServiceConnection#onServiceConnected onServiceConnected()} của mình.
+Hình 1 bên dưới minh họa lô-gic cho loại vòng đời này.</p>
+
+
+<img src="{@docRoot}images/fundamentals/service_binding_tree_lifecycle.png" alt="" />
+<p class="img-caption"><strong>Hình 1.</strong> Vòng đời của một dịch vụ được bắt đầu
+và cũng cho phép gắn kết.</p>
+
+
+<p>Để biết thêm thông tin về vòng đời của một dịch vụ được bắt đầu, hãy xem tài liệu <a href="{@docRoot}guide/components/services.html#Lifecycle">Dịch vụ</a>.</p>
+
+
+
+
diff --git a/docs/html-intl/intl/vi/guide/components/fragments.jd b/docs/html-intl/intl/vi/guide/components/fragments.jd
new file mode 100644
index 000000000000..95d9c76337fc
--- /dev/null
+++ b/docs/html-intl/intl/vi/guide/components/fragments.jd
@@ -0,0 +1,812 @@
+page.title=Phân đoạn
+parent.title=Hoạt động
+parent.link=activities.html
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+ <h2>Trong tài liệu này</h2>
+ <ol>
+ <li><a href="#Design">Triết lý Thiết kế</a></li>
+ <li><a href="#Creating">Tạo một Phân đoạn</a>
+ <ol>
+ <li><a href="#UI">Thêm một giao diện người dùng</a></li>
+ <li><a href="#Adding">Thêm một phân đoạn vào một hoạt động</a></li>
+ </ol>
+ </li>
+ <li><a href="#Managing">Quản lý Phân đoạn</a></li>
+ <li><a href="#Transactions">Thực hiện Giao tác Phân đoạn</a></li>
+ <li><a href="#CommunicatingWithActivity">Giao tiếp với Hoạt động</a>
+ <ol>
+ <li><a href="#EventCallbacks">Tạo gọi lại sự kiện cho hoạt động</a></li>
+ <li><a href="#ActionBar">Thêm mục vào Thanh Hành động</a></li>
+ </ol>
+ </li>
+ <li><a href="#Lifecycle">Xử lý Vòng đời của Phân đoạn</a>
+ <ol>
+ <li><a href="#CoordinatingWithActivity">Phối hợp với vòng đời của hoạt động</a></li>
+ </ol>
+ </li>
+ <li><a href="#Example">Ví dụ</a></li>
+ </ol>
+
+ <h2>Lớp khóa</h2>
+ <ol>
+ <li>{@link android.app.Fragment}</li>
+ <li>{@link android.app.FragmentManager}</li>
+ <li>{@link android.app.FragmentTransaction}</li>
+ </ol>
+
+ <h2>Xem thêm</h2>
+ <ol>
+ <li><a href="{@docRoot}training/basics/fragments/index.html">Xây dựng một UI Động bằng các Phân đoạn</a></li>
+ <li><a href="{@docRoot}guide/practices/tablets-and-handsets.html">Hỗ trợ Máy tính bảng
+và Thiết bị cầm tay</a></li>
+ </ol>
+</div>
+</div>
+
+<p>{@link android.app.Fragment} biểu diễn một hành vi hay một phần giao diện người dùng trong một
+{@link android.app.Activity}. Bạn có thể kết hợp nhiều phân đoạn trong một hoạt động duy nhất để xây dựng một
+UI nhiều bảng và sử dụng lại phân đoạn trong nhiều hoạt động. Bạn có thể coi phân đoạn như là một
+phần mô-đun của một hoạt động, có vòng đời của chính nó, nhận các sự kiện đầu vào của chính nó, và
+bạn có thể thêm hoặc gỡ bỏ trong khi hoạt động đang chạy (kiểu như một "hoạt động con" mà
+bạn có thể sử dụng lại trong các hoạt động khác nhau).</p>
+
+<p>Phân đoạn phải luôn được nhúng trong một hoạt động và vòng đời của phân đoạn bị ảnh hưởng trực tiếp bởi
+vòng đời của hoạt động chủ. Ví dụ, khi hoạt động bị tạm dừng, tất cả
+phân đoạn trong nó cũng vậy, và khi hoạt động bị hủy, tất cả phân đoạn cũng vậy. Tuy nhiên, trong khi một
+hoạt động đang chạy (nó ở trong trạng thái vòng đời <em>được tiếp tục</em><a href="{@docRoot}guide/components/activities.html#Lifecycle"></a>), bạn có thể
+thao tác từng phân đoạn độc lập, chẳng hạn như thêm hay xóa chúng. Khi bạn thực hiện một
+giao tác phân đoạn, bạn cũng có thể thêm nó vào một ngăn xếp được quản lý bởi
+hoạt động đó&mdash;từng mục nhập vào ngăn xếp trong hoạt động là một bản ghi giao tác phân đoạn
+đã xảy ra. Ngăn xếp cho phép người dùng đảo ngược một giao tác phân đoạn (điều hướng ngược lại),
+bằng cách nhấn nút <em>Quay lại</em>.</p>
+
+<p>Khi bạn thêm một phân đoạn như một phần trong bố trí hoạt động của mình, nó sẽ ở trong một {@link
+android.view.ViewGroup} bên trong phân cấp dạng xem của hoạt động đó và phân đoạn này sẽ định nghĩa bố trí
+dạng xem của chính nó.
+Bạn có thể chèn một phân đoạn vào bố trí hoạt động của mình bằng cách khai báo phân đoạn trong tệp
+bố trí của hoạt động, dưới dạng một phần tử {@code &lt;fragment&gt;}, hoặc từ mã ứng dụng của bạn bằng cách thêm nó vào một
+{@link android.view.ViewGroup} hiện hữu. Tuy nhiên, không bắt buộc phải có một phân đoạn là một bộ phận của bố trí hoạt động
+; bạn cũng có thể sử dụng một phân đoạn mà không cần UI của chính nó như một trình thực hiện vô hình cho hoạt động
+.</p>
+
+<p>Tài liệu này mô tả cách xây dựng ứng dụng của bạn để sử dụng phân đoạn, bao gồm
+cách các phân đoạn có thể duy trì trạng thái của chúng khi được thêm vào ngăn xếp của hoạt động, chia sẻ
+các sự kiện với hoạt động và các phân đoạn khác trong hoạt động, đóng góp vào thanh hành động của hoạt động
+và nhiều thông tin khác.</p>
+
+
+<h2 id="Design">Triết lý Thiết kế</h2>
+
+<p>Android giới thiệu phân đoạn trong phiên bản Android 3.0 (API mức 11), chủ yếu nhằm hỗ trợ
+các thiết kế UI động và linh hoạt hơn trên màn hình lớn, chẳng hạn như máy tính bảng. Vì
+màn hình của máy tính bảng lớn hơn nhiều màn hình của thiết bị cầm tay, có nhiều khoảng trống hơn để kết hợp và
+trao đổi các thành phần UI. Phân đoạn cho phép những thiết kế như vậy mà không cần bạn phải quản lý những thay đổi
+phức tạp về phân cấp dạng xem. Bằng cách chia bố trí của một hoạt động thành các phân đoạn, bạn có thể
+sửa đổi diện mạo của hoạt động vào thời gian chạy và giữ những thay đổi đó trong một ngăn xếp
+được quản lý bởi hoạt động.</p>
+
+<p>Ví dụ, một ứng dụng tin tức có thể sử dụng một phân đoạn để hiển thị một danh sách bài viết ở
+bên trái và một phân đoạn khác để hiển thị một bài viết ở bên phải&mdash;cả hai phân đoạn đều xuất hiện trong một
+hoạt động, bên cạnh nhau, và từng phân đoạn có tập phương pháp gọi lại vòng đời riêng và xử lý
+các sự kiện nhập liệu người dùng riêng của mình. Vì thế, thay vì sử dụng một hoạt động để chọn một bài viết và một
+hoạt động khác để đọc bài viết, người dùng có thể chọn một bài viết và đọc nó trong cùng
+hoạt động, như được minh họa trong bố trí máy tính bảng trong hình 1.</p>
+
+<p>Bạn nên thiết kế từng phân đoạn như một thành phần hoạt động dạng mô-đun và có thể sử dụng lại. Đó là bởi
+mỗi phân đoạn sẽ định nghĩa bố trí và hành vi của chính nó với các phương pháp gọi lại vòng đời của chính nó, bạn có thể
+bao gồm một phân đoạn trong nhiều hoạt động, vì thế bạn nên thiết kế để tái sử dụng và tránh trực tiếp
+thao tác một phân đoạn từ một phân đoạn khác. Điều này đặc biệt quan trọng vì một phân đoạn
+mô-đun cho phép bạn thay đổi kết hợp phân đoạn của mình cho các kích cỡ màn hình khác nhau. Khi thiết kế
+ứng dụng của bạn để hỗ trợ cả máy tính bảng và thiết bị cầm tay, bạn có thể sử dụng lại phân đoạn của mình trong các cấu hình
+bố trí khác nhau nhằm tối ưu hóa trải nghiệm người dùng dựa trên không gian màn hình có sẵn. Ví
+dụ, trên một thiết bị cầm tay, có thể cần phải tách riêng các phân đoạn để cung cấp một UI đơn bảng khi mà
+không thể làm vừa khít nhiều hơn một phân đoạn trong cùng hoạt động.</p>
+
+<img src="{@docRoot}images/fundamentals/fragments.png" alt="" />
+<p class="img-caption"><strong>Hình 1.</strong> Ví dụ về cách hai mô-đun UI được định nghĩa
+bởi các phân đoạn có thể được kết hợp thành một hoạt động đối với thiết kế máy tính bảng, nhưng được tách riêng đối với
+thiết kế thiết bị cầm tay.</p>
+
+<p>Ví dụ&mdash;để tiếp tục với ví dụ về ứng dụng tin tức&mdash;ứng dụng có thể nhúng
+hai phân đoạn trong <em>Hoạt động A</em>, khi đang chạy trên một thiết bị có kích cỡ máy tính bảng. Tuy nhiên, trên một
+màn hình kích cỡ thiết bị cầm tay, không có đủ khoảng trống cho cả hai phân đoạn, vì thế <em>Hoạt động A</em> chỉ
+bao gồm phân đoạn cho danh sách bài viết, và khi người dùng chọn một bài viết, nó sẽ khởi động
+<em>Hoạt động B</em>, hoạt động này chứa phân đoạn thứ hai là đọc bài viết. Vì thế, ứng dụng
+hỗ trợ cả máy tính bảng và thiết bị cầm tay bằng cách sử dụng lại các phân đoạn theo các cách kết hợp khác nhau như được minh họa trong
+hình 1.</p>
+
+<p>Để biết thêm thông tin về việc thiết kế ứng dụng của bạn bằng các cách kết hợp phân đoạn khác nhau cho
+cấu hình màn hình khác nhau, hãy xem hướng dẫn <a href="{@docRoot}guide/practices/tablets-and-handsets.html">Hỗ trợ Máy tính bảng và Thiết bị cầm tay</a>.</p>
+
+
+
+<h2 id="Creating">Tạo một Phân đoạn</h2>
+
+<div class="figure" style="width:327px">
+<img src="{@docRoot}images/fragment_lifecycle.png" alt="" />
+<p class="img-caption"><strong>Hình 2.</strong> Vòng đời của một phân đoạn (trong khi hoạt động
+của nó đang chạy).</p>
+</div>
+
+<p>Để tạo một phân đoạn, bạn phải tạo một lớp con của {@link android.app.Fragment} (hoặc
+một lớp con hiện tại của nó). Lớp {@link android.app.Fragment} có mã trông rất giống
+một {@link android.app.Activity}. Nó chứa các phương pháp gọi lại tương tự như hoạt động, chẳng
+hạn như {@link android.app.Fragment#onCreate onCreate()}, {@link android.app.Fragment#onStart onStart()},
+{@link android.app.Fragment#onPause onPause()}, và {@link android.app.Fragment#onStop onStop()}. Trên
+thực tế, nếu bạn đang chuyển đổi một ứng dụng Android hiện tại để sử dụng các phân đoạn, bạn có thể chỉ cần di chuyển
+mã khỏi các phương pháp gọi lại của hoạt động của bạn vào các phương pháp gọi lại tương ứng của phân đoạn
+của bạn.</p>
+
+<p>Thường thì ít nhất bạn nên triển khai các phương pháp vòng đời sau:</p>
+
+<dl>
+ <dt>{@link android.app.Fragment#onCreate onCreate()}</dt>
+ <dd>Hệ thống sẽ gọi phương pháp này khi tạo phân đoạn. Trong triển khai của mình, bạn nên
+khởi tạo các thành phần thiết yếu của phân đoạn mà bạn muốn giữ lại khi phân đoạn
+bị tạm dừng hoặc dừng hẳn, sau đó tiếp tục.</dd>
+ <dt>{@link android.app.Fragment#onCreateView onCreateView()}</dt>
+ <dd>Hệ thống sẽ gọi phương pháp này khi đến lúc phân đoạn vẽ giao diện người dùng của nó
+lần đầu tiên. Để vẽ một UI cho phân đoạn của mình, bạn phải trả về một {@link android.view.View} từ phương pháp
+này, đây là gốc của bố trí phân đoạn của bạn. Bạn có thể trả về giá trị rỗng nếu phân đoạn không
+cung cấp UI.</dd>
+ <dt>{@link android.app.Activity#onPause onPause()}</dt>
+ <dd>Hệ thống gọi phương pháp này là dấu hiệu đầu tiên về việc người dùng đang rời khỏi
+phân đoạn (mặc dù không phải lúc nào cũng có nghĩa rằng phân đoạn đang bị hủy). Trường hợp này thường là khi bạn
+định thực hiện bất kỳ thay đổi nào vẫn cần có hiệu lực ngoài phiên của người dùng hiện thời (vì
+người dùng có thể không quay lại).</dd>
+</dl>
+
+<p>Phần lớn ứng dụng nên triển khai ít nhất ba phương pháp sau đối với mọi phân đoạn, nhưng có một vài
+phương pháp gọi lại khác mà bạn cũng nên sử dụng để xử lý các giai đoạn khác nhau trong
+vòng đời của phân đoạn. Tất cả phương pháp gọi lại vòng đời được đề cập chi tiết hơn trong phần
+về <a href="#Lifecycle">Xử lý Vòng đời của Phân đoạn</a>.</p>
+
+
+<p>Cũng có một vài lớp con mà bạn có thể muốn mở rộng thay vì lớp cơ bản {@link
+android.app.Fragment}:</p>
+
+<dl>
+ <dt>{@link android.app.DialogFragment}</dt>
+ <dd>Hiển thị một hộp thoại trôi nổi. Sử dụng lớp này để tạo một hộp thoại là một phương án hay cho việc sử dụng các phương pháp trình trợ giúp
+hộp thoại trong lớp {@link android.app.Activity}, vì bạn có thể
+kết hợp một hộp thoại phân đoạn vào ngăn xếp của các phân đoạn được quản lý bởi hoạt động,
+cho phép người dùng trả về một phân đoạn bị bỏ.</dd>
+
+ <dt>{@link android.app.ListFragment}</dt>
+ <dd>Hiển thị một danh sách các mục được quản lý bởi một trình điều hợp (chẳng hạn như một {@link
+android.widget.SimpleCursorAdapter}), tương tự như {@link android.app.ListActivity}. Nó cung cấp
+một vài phương pháp để quản lý một dạng xem danh sách, chẳng hạn như phương pháp gọi lại {@link
+android.app.ListFragment#onListItemClick(ListView,View,int,long) onListItemClick()} để
+xử lý các sự kiện nhấp.</dd>
+
+ <dt>{@link android.preference.PreferenceFragment}</dt>
+ <dd>Hiển thị một phân cấp các đối tượng {@link android.preference.Preference} dưới dạng một danh sách, tương tự như
+{@link android.preference.PreferenceActivity}. Điều này hữu ích khi tạo một hoạt động "thiết đặt"
+cho ứng dụng của bạn.</dd>
+</dl>
+
+
+<h3 id="UI">Thêm một giao diện người dùng</h3>
+
+<p>Phân đoạn thường được sử dụng như một phần giao diện người dùng của hoạt động và đóng góp bố trí của
+chính nó cho hoạt động.</p>
+
+<p>Để cung cấp một bố trí cho một phân đoạn, bạn phải triển khai phương pháp gọi lại {@link
+android.app.Fragment#onCreateView onCreateView()}, phương pháp này được hệ thống Android gọi
+khi đến lúc phân đoạn vẽ bố trí của nó. Việc bạn triển khai phương pháp này phải trả về một
+{@link android.view.View} là phần gốc cho bố trí phân đoạn của bạn.</p>
+
+<p class="note"><strong>Lưu ý:</strong> Nếu phân đoạn của bạn là một lớp con của {@link
+android.app.ListFragment}, triển khai mặc định sẽ trả về một {@link android.widget.ListView} từ
+{@link android.app.Fragment#onCreateView onCreateView()}, vì thế bạn không cần triển khai nó.</p>
+
+<p>Để trả về một bố trí từ {@link
+android.app.Fragment#onCreateView onCreateView()}, bạn có thể bung nó từ một <a href="{@docRoot}guide/topics/resources/layout-resource.html">tài nguyên bố trí</a> được định nghĩa trong XML. Để
+giúp bạn làm vậy, {@link android.app.Fragment#onCreateView onCreateView()} cung cấp một đối tượng
+{@link android.view.LayoutInflater}.</p>
+
+<p>Ví dụ, sau đây là một lớp con của {@link android.app.Fragment} với chức năng nạp một bố trí từ tệp
+{@code example_fragment.xml}:</p>
+
+<pre>
+public static class ExampleFragment extends Fragment {
+ &#64;Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ // Inflate the layout for this fragment
+ return inflater.inflate(R.layout.example_fragment, container, false);
+ }
+}
+</pre>
+
+<div class="sidebox-wrapper">
+<div class="sidebox">
+ <h3>Tạo một bố trí</h3>
+ <p>Trong ví dụ trên, {@code R.layout.example_fragment} là một tham chiếu tới tài nguyên bố trí
+có tên {@code example_fragment.xml} được lưu trong tài nguyên ứng dụng. Để biết thông tin về cách
+tạo một bố trí trong XML, hãy xem tài liệu <a href="{@docRoot}guide/topics/ui/index.html">Giao diện Người dùng</a>
+.</p>
+</div>
+</div>
+
+<p>Tham số {@code container} được chuyển tới {@link android.app.Fragment#onCreateView
+onCreateView()} là {@link android.view.ViewGroup} mẹ (tức bố trí của hoạt động), trong đó
+bố trí phân đoạn của bạn
+sẽ được chèn vào. Tham số {@code savedInstanceState} là một {@link android.os.Bundle} có chức năng
+cung cấp dữ liệu về thực thể trước đó của phân đoạn, nếu phân đoạn đang được tiếp tục
+(việc khôi phục trạng thái được bàn kỹ hơn trong phần về <a href="#Lifecycle">Xử lý
+Vòng đời của Phân đoạn</a>).</p>
+
+<p>Phương pháp {@link android.view.LayoutInflater#inflate(int,ViewGroup,boolean) inflate()} có
+ba tham đối:</p>
+<ul>
+ <li>ID tài nguyên của bố trí mà bạn muốn bung.</li>
+ <li>{@link android.view.ViewGroup} là mẹ của bố trí được bung. Việc chuyển {@code
+container} có vai trò quan trọng để hệ thống áp dụng các tham số bố trí cho dạng xem gốc của bố trí
+được bung, được quy định bởi dạng xem mẹ là nơi mà nó diễn ra trong đó.</li>
+ <li>Một boolean cho biết bố trí được bung có nên được gắn với {@link
+android.view.ViewGroup} (tham số thứ hai) trong khi bung hay không. (Trong trường hợp này, điều này là
+sai vì hệ thống đã đang chèn bố trí được bung vào {@code
+container}&mdash;việc chuyển đúng sẽ tạo ra một nhóm dạng xem thừa trong bố trí cuối cùng.)</li>
+</ul>
+
+<p>Giờ bạn đã thấy cách tạo một phân đoạn nhằm cung cấp một bố trí. Tiếp theo, bạn cần thêm
+phân đoạn vào hoạt động của mình.</p>
+
+
+
+<h3 id="Adding">Thêm một phân đoạn vào một hoạt động</h3>
+
+<p>Thường thì một phân đoạn đóng góp một phần UI vào hoạt động chủ, nó được nhúng như một phần
+trong phân cấp dạng xem tổng thể của hoạt động. Có hai cách mà bạn có thể thêm một phân đoạn vào bố trí
+của hoạt động:</p>
+
+<ul>
+ <li><b>Khai báo phân đoạn bên trong tệp bố trí của hoạt động.</b>
+<p>Trong trường hợp này, bạn có thể
+chỉ định các tính chất bố trí cho phân đoạn như thể nó là một dạng xem. Ví dụ, sau đây là tệp bố trí
+cho một hoạt động có hai phân đoạn:</p>
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
+&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="horizontal"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"&gt;
+ &lt;fragment android:name="com.example.news.ArticleListFragment"
+ android:id="@+id/list"
+ android:layout_weight="1"
+ android:layout_width="0dp"
+ android:layout_height="match_parent" /&gt;
+ &lt;fragment android:name="com.example.news.ArticleReaderFragment"
+ android:id="@+id/viewer"
+ android:layout_weight="2"
+ android:layout_width="0dp"
+ android:layout_height="match_parent" /&gt;
+&lt;/LinearLayout&gt;
+</pre>
+ <p>Thuộc tính {@code android:name} trong {@code &lt;fragment&gt;} sẽ chỉ định lớp {@link
+android.app.Fragment} để khởi tạo trong bố trí.</p>
+
+<p>Khi hệ thống tạo bố trí hoạt động này, nó sẽ khởi tạo từng phân đoạn được chỉ định trong bố trí
+và gọi ra phương pháp {@link android.app.Fragment#onCreateView onCreateView()} cho từng phân đoạn,
+để truy xuất bố trí của từng phân đoạn. Hệ thống sẽ chèn {@link android.view.View} được trả về bởi phân đoạn
+trực tiếp thế chỗ phần tử {@code &lt;fragment&gt;}.</p>
+
+<div class="note">
+ <p><strong>Lưu ý:</strong> Mỗi phân đoạn yêu cầu một mã định danh duy nhất
+mà hệ thống có thể sử dụng để khôi phục phân đoạn nếu hoạt động bị khởi động lại (và bạn có thể sử dụng để
+nắm bắt phân đoạn sẽ thực hiện giao tác, chẳng hạn như gỡ bỏ nó). Có ba cách để cung cấp ID cho một
+phân đoạn:</p>
+ <ul>
+ <li>Cung cấp thuộc tính {@code android:id} với một ID duy nhất.</li>
+ <li>Cung cấp thuộc tính {@code android:tag} với một xâu duy nhất.</li>
+ <li>Nếu bạn không cung cấp được thuộc tính nào, hệ thống sẽ sử dụng ID của dạng xem
+của bộ chứa.</li>
+ </ul>
+</div>
+ </li>
+
+ <li><b>Hoặc, bằng cách lập trình, thêm phân đoạn vào một {@link android.view.ViewGroup} hiện hữu.</b>
+<p>Vào bất cứ lúc nào trong khi hoạt động của bạn đang chạy, bạn có thể thêm phân đoạn vào bố trí hoạt động của mình. Bạn
+chỉ cần chỉ định một {@link
+android.view.ViewGroup} là nơi mà bạn sẽ đặt phân đoạn vào.</p>
+ <p>Để thực hiện giao tác phân đoạn trong hoạt động của mình (chẳng hạn như thêm, gỡ bỏ, hay thay thế một
+phân đoạn), bạn phải sử dụng các API từ {@link android.app.FragmentTransaction}. Bạn có thể nhận một thực thể
+của {@link android.app.FragmentTransaction} từ {@link android.app.Activity} của mình như sau:</p>
+
+<pre>
+FragmentManager fragmentManager = {@link android.app.Activity#getFragmentManager()}
+FragmentTransaction fragmentTransaction = fragmentManager.{@link android.app.FragmentManager#beginTransaction()};
+</pre>
+
+<p>Sau đó, bạn có thể thêm một phân đoạn bằng cách sử dụng phương pháp {@link
+android.app.FragmentTransaction#add(int,Fragment) add()}, chỉ định phân đoạn sẽ thêm và
+dạng xem mà bạn sẽ chèn nó vào. Ví dụ:</p>
+
+<pre>
+ExampleFragment fragment = new ExampleFragment();
+fragmentTransaction.add(R.id.fragment_container, fragment);
+fragmentTransaction.commit();
+</pre>
+
+ <p>Tham đối đầu tiên được chuyển cho {@link android.app.FragmentTransaction#add(int,Fragment) add()}
+là {@link android.view.ViewGroup}, là nơi mà phân đoạn sẽ được đặt vào, được chỉ định bởi
+ID tài nguyên, và tham đối thứ hai là phân đoạn cần thêm.</p>
+ <p>Sau khi bạn đã thực hiện các thay đổi của mình bằng
+{@link android.app.FragmentTransaction}, bạn phải
+gọi {@link android.app.FragmentTransaction#commit} để các thay đổi có hiệu lực.</p>
+ </li>
+</ul>
+
+
+<h4 id="AddingWithoutUI">Thêm một phân đoạn không có UI</h4>
+
+<p>Các ví dụ nêu trên cho biết cách thêm một phân đoạn vào hoạt động của bạn để cung cấp một UI. Tuy nhiên,
+bạn cũng có thể sử dụng một phân đoạn để cung cấp một hành vi chạy ngầm cho hoạt động mà không cần đưa
+UI bổ sung.</p>
+
+<p>Để thêm một phân đoạn không có UI, hãy thêm phân đoạn từ hoạt động đang bằng cách sử dụng {@link
+android.app.FragmentTransaction#add(Fragment,String)} (cung cấp một "tag" xâu duy nhất cho phân đoạn
+, thay vì một ID dạng xem). Làm vậy sẽ thêm phân đoạn, nhưng vì không liên kết với một dạng xem
+trong bố trí hoạt động, nó sẽ không nhận được lệnh gọi tới {@link
+android.app.Fragment#onCreateView onCreateView()}. Vì thế, bạn không cần triển khai phương pháp đó.</p>
+
+<p>Việc cung cấp tag xâu cho phân đoạn không chỉ áp dụng cho các phân đoạn không có UI&mdash;bạn cũng có thể
+cung cấp tag xâu cho phân đoạn có UI&mdash;nhưng nếu phân đoạn không có
+UI, khi đó, tag xâu là cách duy nhất để nhận biết nó. Nếu sau này bạn muốn nhận phân đoạn từ
+hoạt động, bạn cần sử dụng {@link android.app.FragmentManager#findFragmentByTag
+findFragmentByTag()}.</p>
+
+<p>Để biết ví dụ về hoạt động sử dụng phân đoạn như một trình thực hiện nền, không có UI, hãy xem mẫu {@code
+FragmentRetainInstance.java}, mẫu này có trong các mẫu SDK (có sẵn thông qua
+Trình quản lý SDK Android) và nằm trên hệ thống của bạn như là
+<code>&lt;sdk_root&gt;/APIDemos/app/src/main/java/com/example/android/apis/app/FragmentRetainInstance.java</code>.</p>
+
+
+
+<h2 id="Managing">Quản lý Phân đoạn</h2>
+
+<p>Để quản lý các phân đoạn trong hoạt động của mình, bạn cần sử dụng {@link android.app.FragmentManager}. Để
+có nó, hãy gọi {@link android.app.Activity#getFragmentManager()} từ hoạt động của bạn.</p>
+
+<p>Một số việc bạn có thể làm với {@link android.app.FragmentManager} bao gồm:</p>
+
+<ul>
+ <li>Nhận các phân đoạn tồn tại trong hoạt động, bằng {@link
+android.app.FragmentManager#findFragmentById findFragmentById()} (đối với các phân đoạn cung cấp UI trong
+bố trí hoạt động) hoặc {@link android.app.FragmentManager#findFragmentByTag
+findFragmentByTag()} (đối với các phân đoạn có hoặc không cung cấp UI).</li>
+ <li>Lấy phân đoạn ra khỏi ngăn xếp, bằng {@link
+android.app.FragmentManager#popBackStack()} (mô phỏng một câu lệnh <em>Quay lại</em> của người dùng).</li>
+ <li>Đăng ký một đối tượng theo dõi cho những thay đổi đối với ngăn xếp, bằng {@link
+android.app.FragmentManager#addOnBackStackChangedListener addOnBackStackChangedListener()}.</li>
+</ul>
+
+<p>Để biết thêm thông tin về những phương pháp này và phương pháp khác, hãy tham khảo tài liệu lớp {@link
+android.app.FragmentManager}.</p>
+
+<p>Như minh họa trong phần trước, bạn cũng có thể sử dụng {@link android.app.FragmentManager}
+để mở một {@link android.app.FragmentTransaction}, nó cho phép bạn thực hiện các giao tác, ví dụ như
+thêm hoặc gỡ bỏ phân đoạn.</p>
+
+
+<h2 id="Transactions">Thực hiện Giao tác Phân đoạn</h2>
+
+<p>Một tính năng tuyệt vời khi sử dụng phân đoạn trong hoạt động của bạn đó là khả năng thêm, gỡ bỏ, thay thế,
+và thực hiện các hành động khác với chúng, để hồi đáp lại tương tác của người dùng. Mỗi tập hợp thay đổi mà bạn
+thực thi cho hoạt động được gọi là một giao tác và bạn có thể thực hiện một giao tác bằng cách sử dụng các API trong {@link
+android.app.FragmentTransaction}. Bạn cũng có thể lưu từng giao tác vào một ngăn xếp được quản lý bởi
+hoạt động, cho phép người dùng điều hướng ngược lại thông qua những thay đổi phân đoạn (tương tự như điều hướng
+ngược lại thông qua hoạt động).</p>
+
+<p>Bạn có thể thu được một thực thể của {@link android.app.FragmentTransaction} từ {@link
+android.app.FragmentManager} như sau:</p>
+
+<pre>
+FragmentManager fragmentManager = {@link android.app.Activity#getFragmentManager()};
+FragmentTransaction fragmentTransaction = fragmentManager.{@link android.app.FragmentManager#beginTransaction()};
+</pre>
+
+<p>Mỗi giao tác là một tập hợp những thay đổi mà bạn muốn thực hiện tại cùng thời điểm. Bạn có thể thiết lập
+tất cả thay đổi mà mình muốn thực hiện đối với một giao tác cho trước bằng cách sử dụng các phương pháp như {@link
+android.app.FragmentTransaction#add add()}, {@link android.app.FragmentTransaction#remove remove()},
+và {@link android.app.FragmentTransaction#replace replace()}. Sau đó, để áp dụng giao tác
+cho hoạt động, bạn phải gọi {@link android.app.FragmentTransaction#commit()}.</p>
+</dl>
+
+<p>Trước khi bạn gọi {@link
+android.app.FragmentTransaction#commit()}, tuy nhiên, bạn có thể muốn gọi {@link
+android.app.FragmentTransaction#addToBackStack addToBackStack()}, để thêm giao tác
+vào một ngăn xếp của các giao tác phân đoạn. Ngăn xếp này được quản lý bởi hoạt động và cho phép
+người dùng trở về trạng thái phân đoạn trước đó, bằng cách nhấp nút <em>Quay lại</em>.</p>
+
+<p>Ví dụ, sau đây là cách bạn có thể thay thế phân đoạn này bằng phân đoạn khác, và giữ nguyên
+trạng thái trước đó của ngăn xếp:</p>
+
+<pre>
+// Create new fragment and transaction
+Fragment newFragment = new ExampleFragment();
+FragmentTransaction transaction = getFragmentManager().beginTransaction();
+
+// Replace whatever is in the fragment_container view with this fragment,
+// and add the transaction to the back stack
+transaction.replace(R.id.fragment_container, newFragment);
+transaction.addToBackStack(null);
+
+// Commit the transaction
+transaction.commit();
+</pre>
+
+<p>Trong ví dụ này, {@code newFragment} thay thế mọi phân đoạn (nếu có) hiện đang ở trong
+bộ chứa bố trí được nhận biết bởi ID {@code R.id.fragment_container}. Bằng cách gọi {@link
+android.app.FragmentTransaction#addToBackStack addToBackStack()}, giao tác thay thế
+được lưu vào ngăn xếp, vì thế người dùng có thể đảo ngược giao tác và mang
+giao tác trước đó trở lại bằng cách nhấn nút <em>Quay lại</em>.</p>
+
+<p>Nếu bạn thêm nhiều thay đổi vào giao tác (chẳng hạn như một {@link
+android.app.FragmentTransaction#add add()} khác hoặc {@link android.app.FragmentTransaction#remove
+remove()}) và gọi {@link
+android.app.FragmentTransaction#addToBackStack addToBackStack()}, khi đó, tất cả thay đổi được áp dụng
+trước khi bạn gọi {@link android.app.FragmentTransaction#commit commit()} đều được thêm vào
+ngăn xếp như một giao tác riêng lẻ và nút <em>Quay lại</em> sẽ đảo ngược tất cả cùng nhau.</p>
+
+<p>Thứ tự mà bạn thêm thay đổi vào một {@link android.app.FragmentTransaction} không quan trọng,
+ngoại trừ:</p>
+<ul>
+ <li>Bạn phải gọi {@link android.app.FragmentTransaction#commit()} cuối cùng</li>
+ <li>Nếu bạn thêm nhiều phân đoạn vào cùng bộ chứa, khi đó thứ tự mà
+bạn thêm chúng sẽ xác định thứ tự chúng xuất hiện trong phân cấp dạng xem</li>
+</ul>
+
+<p>Nếu bạn không gọi {@link android.app.FragmentTransaction#addToBackStack(String)
+addToBackStack()} khi thực hiện một giao tác để xóa một phân đoạn, khi đó, phân đoạn đó sẽ bị
+hủy khi giao tác được thực hiện và người dùng không thể điều hướng trở lại nó. Trong khi đó, nếu bạn
+gọi {@link android.app.FragmentTransaction#addToBackStack(String) addToBackStack()} khi
+gỡ bỏ một phân đoạn, khi đó phân đoạn bị <em>dừng</em> và sẽ được khôi phục nếu người dùng điều hướng
+trở lại.</p>
+
+<p class="note"><strong>Mẹo:</strong> Với mỗi giao tác phân đoạn, bạn có thể áp dụng một hoạt ảnh
+chuyển tiếp bằng cách gọi {@link android.app.FragmentTransaction#setTransition setTransition()} trước khi
+thực thi.</p>
+
+<p>Việc gọi {@link android.app.FragmentTransaction#commit()} không thực hiện giao tác
+ngay lập tức. Thay vào đó, nó lập lịch biểu để chạy trên luồng UI của hoạt động (luồng "chính") ngay khi
+luồng có thể làm vậy. Tuy nhiên, nếu cần, bạn có thể gọi {@link
+android.app.FragmentManager#executePendingTransactions()} từ luồng UI của mình để ngay lập tức thực hiện
+các giao tác được gửi bởi {@link android.app.FragmentTransaction#commit()}. Làm vậy
+thường không cần thiết trừ khi giao tác đó là phụ thuộc cho các tác vụ ở những luồng khác.</p>
+
+<p class="caution"><strong>Chú ý:</strong> Bạn có thể thực thi một giao tác bằng cách sử dụng {@link
+android.app.FragmentTransaction#commit commit()} chỉ trước khi hoạt động <a href="{@docRoot}guide/components/activities.html#SavingActivityState">lưu
+trạng thái</a> của nó (khi người dùng rời khỏi hoạt động). Nếu bạn định thực thi sau thời điểm đó sẽ phát sinh một lỗi
+ngoại lệ. Nguyên nhân là vì trạng thái sau khi thực thi có thể bị mất nếu hoạt động
+cần được khôi phục. Đối với những trường hợp mà bạn có thể mất thực thi, hãy sử dụng {@link
+android.app.FragmentTransaction#commitAllowingStateLoss()}.</p>
+
+
+
+
+<h2 id="CommunicatingWithActivity">Giao tiếp với Hoạt động</h2>
+
+<p>Mặc dù {@link android.app.Fragment} được triển khai như một đối tượng độc lập với
+{@link android.app.Activity} và có thể được sử dụng bên trong nhiều hoạt động, một thực thể đã cho của
+phân đoạn sẽ được gắn kết trực tiếp với hoạt động chứa nó.</p>
+
+<p>Cụ thể, phân đoạn có thể truy cập thực thể {@link android.app.Activity} bằng {@link
+android.app.Fragment#getActivity()} và dễ dàng thực hiện các tác vụ như tìm một dạng xem trong bố trí
+hoạt động:</p>
+
+<pre>
+View listView = {@link android.app.Fragment#getActivity()}.{@link android.app.Activity#findViewById findViewById}(R.id.list);
+</pre>
+
+<p>Tương tự, hoạt động của bạn có thể gọi ra các phương pháp trong phân đoạn bằng cách thu được một tham chiếu tới
+{@link android.app.Fragment} từ {@link android.app.FragmentManager}, bằng cách sử dụng {@link
+android.app.FragmentManager#findFragmentById findFragmentById()} hoặc {@link
+android.app.FragmentManager#findFragmentByTag findFragmentByTag()}. Ví dụ:</p>
+
+<pre>
+ExampleFragment fragment = (ExampleFragment) getFragmentManager().findFragmentById(R.id.example_fragment);
+</pre>
+
+
+<h3 id="EventCallbacks">Tạo gọi lại sự kiện cho hoạt động</h3>
+
+<p>Trong một số trường hợp, bạn có thể cần một phân đoạn để chia sẻ sự kiện với hoạt động. Một cách hay để làm điều này
+đó là định nghĩa một giao diện gọi lại bên trong phân đoạn và yêu cầu hoạt động chủ triển khai
+nó. Khi hoạt động nhận được một lệnh gọi lại thông qua giao diện, nó có thể chia sẻ thông tin với
+các phân đoạn khác trong bố trí nếu cần.</p>
+
+<p>Ví dụ, nếu một ứng dụng tin tức có hai phân đoạn trong một hoạt động&mdash;một để hiển thị danh sách
+bài viết (phân đoạn A) và một để hiển thị một bài viết (phân đoạn B)&mdash;khi đó, phân đoạn A phải thông báo với
+hoạt động khi nào thì một mục danh sách được chọn để nó có thể yêu cầu phân đoạn B hiển thị bài viết đó. Trong
+trường hợp này, giao diện {@code OnArticleSelectedListener} sẽ được khai báo bên trong phân đoạn A:</p>
+
+<pre>
+public static class FragmentA extends ListFragment {
+ ...
+ // Container Activity must implement this interface
+ public interface OnArticleSelectedListener {
+ public void onArticleSelected(Uri articleUri);
+ }
+ ...
+}
+</pre>
+
+<p>Khi đó, hoạt động lưu trữ phân đoạn sẽ triển khai giao diện {@code OnArticleSelectedListener}
+và
+khống chế {@code onArticleSelected()} để thông báo với phân đoạn B về sự kiện từ phân đoạn A. Để đảm bảo
+rằng hoạt động chủ triển khai giao diện này, phương pháp gọi lại {@link
+android.app.Fragment#onAttach onAttach()} của phân đoạn A (mà hệ thống gọi khi thêm
+phân đoạn vào hoạt động) sẽ khởi tạo một thực thể của {@code OnArticleSelectedListener} bằng cách
+đổi kiểu {@link android.app.Activity} mà được chuyển vào {@link android.app.Fragment#onAttach
+onAttach()}:</p>
+
+<pre>
+public static class FragmentA extends ListFragment {
+ OnArticleSelectedListener mListener;
+ ...
+ &#64;Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+ try {
+ mListener = (OnArticleSelectedListener) activity;
+ } catch (ClassCastException e) {
+ throw new ClassCastException(activity.toString() + " must implement OnArticleSelectedListener");
+ }
+ }
+ ...
+}
+</pre>
+
+<p>Nếu hoạt động chưa triển khai giao diện, khi đó phân đoạn sẽ đưa ra lỗi
+{@link java.lang.ClassCastException}.
+Nếu thành công, thành viên {@code mListener} giữ một tham chiếu tới triển khai
+{@code OnArticleSelectedListener}của hoạt động, sao cho phân đoạn A có thể chia sẻ sự kiện với hoạt động bằng cách gọi các phương pháp
+được định nghĩa bởi giao diện {@code OnArticleSelectedListener}. Ví dụ, nếu phân đoạn A là một
+phần mở rộng của {@link android.app.ListFragment}, mỗi lần
+người dùng nhấp vào một mục danh sách, hệ thống sẽ gọi ra {@link android.app.ListFragment#onListItemClick
+onListItemClick()} trong phân đoạn, và nó lại gọi {@code onArticleSelected()} để chia sẻ
+sự kiện với hoạt động:</p>
+
+<pre>
+public static class FragmentA extends ListFragment {
+ OnArticleSelectedListener mListener;
+ ...
+ &#64;Override
+ public void onListItemClick(ListView l, View v, int position, long id) {
+ // Append the clicked item's row ID with the content provider Uri
+ Uri noteUri = ContentUris.{@link android.content.ContentUris#withAppendedId withAppendedId}(ArticleColumns.CONTENT_URI, id);
+ // Send the event and Uri to the host activity
+ mListener.onArticleSelected(noteUri);
+ }
+ ...
+}
+</pre>
+
+<p>Tham số {@code id} được chuyển vào {@link
+android.app.ListFragment#onListItemClick onListItemClick()} là ID hàng của mục được nhấp,
+nó được sử dụng bởi hoạt động (hoặc phân đoạn kia) để tải bài viết từ {@link
+android.content.ContentProvider} của ứng dụng.</p>
+
+<p><!--To see a complete implementation of this kind of callback interface, see the <a
+href="{@docRoot}resources/samples/NotePad/index.html">NotePad sample</a>. -->Bạn có thể xem thêm thông tin về
+cách sử dụng một trình cung cấp nội dung trong tài liệu <a href="{@docRoot}guide/topics/providers/content-providers.html">Trình cung cấp Nội dung</a>.</p>
+
+
+
+<h3 id="ActionBar">Thêm mục vào Thanh Hành động</h3>
+
+<p>Phân đoạn của bạn có thể đóng góp các mục menu vào <a href="{@docRoot}guide/topics/ui/menus.html#options-menu">Menu Tùy chọn</a> của hoạt động (và tiếp đó là cả <a href="{@docRoot}guide/topics/ui/actionbar.html">Thanh Hành động</a>) bằng cách triển khai
+{@link android.app.Fragment#onCreateOptionsMenu(Menu,MenuInflater) onCreateOptionsMenu()}. Tuy nhiên, để
+phương pháp này nhận lệnh gọi, bạn phải gọi {@link
+android.app.Fragment#setHasOptionsMenu(boolean) setHasOptionsMenu()} trong khi {@link
+android.app.Fragment#onCreate(Bundle) onCreate()}, để cho biết rằng phân đoạn
+sẽ muốn thêm mục vào Menu Tùy chọn (nếu không, phân đoạn sẽ không nhận được lệnh gọi tới
+{@link android.app.Fragment#onCreateOptionsMenu onCreateOptionsMenu()}).</p>
+
+<p>Bất kỳ mục nào mà bạn thêm vào Menu Tùy chọn sau đó từ phân đoạn đều được nối với các mục menu
+hiện tại. Phân đoạn cũng nhận các lệnh gọi lại tới {@link
+android.app.Fragment#onOptionsItemSelected(MenuItem) onOptionsItemSelected()} khi một mục menu
+được chọn.</p>
+
+<p>Bạn cũng có thể đăng ký một dạng xem trong bố trí phân đoạn của mình để cung cấp một menu ngữ cảnh bằng cách gọi {@link
+android.app.Fragment#registerForContextMenu(View) registerForContextMenu()}. Khi người dùng mở
+menu ngữ cảnh, phân đoạn nhận một lệnh gọi tới {@link
+android.app.Fragment#onCreateContextMenu(ContextMenu,View,ContextMenu.ContextMenuInfo)
+onCreateContextMenu()}. Khi người dùng chọn một mục, phân đoạn nhận được một lệnh gọi tới {@link
+android.app.Fragment#onContextItemSelected(MenuItem) onContextItemSelected()}.</p>
+
+<p class="note"><strong>Lưu ý:</strong> Mặc dù phân đoạn của bạn nhận được một lệnh gọi khi chọn mục
+đối với từng mục menu mà nó thêm, trước tiên hoạt động sẽ nhận phương pháp gọi lại tương ứng khi người dùng
+chọn một mục menu. Nếu việc triển khai gọi lại khi chọn mục của hoạt động không
+xử lý mục được chọn, khi đó sự kiện được chuyển sang phương pháp gọi lại của phân đoạn. Điều này đúng đối với
+Menu Tùy chọn và các menu ngữ cảnh.</p>
+
+<p>Để biết thêm thông tin về các menu, xem các hướng dẫn cho nhà phát triển <a href="{@docRoot}guide/topics/ui/menus.html">Menu</a> và <a href="{@docRoot}guide/topics/ui/actionbar.html">Thanh Hành động</a>.</p>
+
+
+
+
+<h2 id="Lifecycle">Xử lý Vòng đời của Phân đoạn</h2>
+
+<div class="figure" style="width:350px">
+<img src="{@docRoot}images/activity_fragment_lifecycle.png" alt="" />
+<p class="img-caption"><strong>Hình 3.</strong> Ảnh hưởng của vòng đời hoạt động tới vòng đời
+của phân đoạn.</p>
+</div>
+
+<p>Việc quản lý vòng đời của một phân đoạn rất giống với quản lý vòng đời của một hoạt động. Giống như
+hoạt động, phân đoạn có thể tồn tại ở ba trạng thái:</p>
+
+<dl>
+ <dt><i>Tiếp tục</i></dt>
+ <dd>Phân đoạn hiển thị trong hoạt động đang chạy.</dd>
+
+ <dt><i>Tạm dừng</i></dt>
+ <dd>Một hoạt động khác ở trong tiền cảnh và có tiêu điểm, nhưng hoạt động mà phân đoạn
+này nằm trong vẫn hiển thị (hoạt động tiền cảnh mờ một phần hoặc không
+che phủ toàn bộ màn hình).</dd>
+
+ <dt><i>Dừng</i></dt>
+ <dd>Phân đoạn không hiển thị. Hoặc là hoạt động chủ đã bị dừng hoặc
+phân đoạn đã được gỡ bỏ khỏi hoạt động, nhưng được thêm vào ngăn xếp. Phân đoạn dừng
+vẫn còn hoạt động (tất cả thông tin về trạng thái và thành viên đều được hệ thống giữ lại). Tuy nhiên, nó không còn
+hiển thị với người dùng nữa và sẽ bị tắt bỏ nếu hoạt động bị tắt bỏ.</dd>
+</dl>
+
+<p>Cũng như một hoạt động, bạn có thể giữ lại trạng thái của một phân đoạn bằng cách sử dụng {@link
+android.os.Bundle}, trong trường hợp tiến trình của hoạt động bị tắt bỏ và bạn cần khôi phục
+trạng thái của phân đoạn khi hoạt động được tạo lại. Bạn có thể lưu trạng thái trong phương pháp gọi lại {@link
+android.app.Fragment#onSaveInstanceState onSaveInstanceState()} của phân đoạn và khôi phục nó trong
+hoặc {@link android.app.Fragment#onCreate onCreate()}, {@link
+android.app.Fragment#onCreateView onCreateView()}, hoặc {@link
+android.app.Fragment#onActivityCreated onActivityCreated()}. Để biết thêm thông tin về việc lưu
+trạng thái, xem tài liệu <a href="{@docRoot}guide/components/activities.html#SavingActivityState">Hoạt động</a>
+.</p>
+
+<p>Sự khác nhau quan trọng nhất trong vòng đời giữa một hoạt động và một phân đoạn đó là cách chúng
+được lưu trữ trong ngăn xếp tương ứng. Hoạt động được đặt vào một ngăn xếp gồm nhiều hoạt động
+, được quản lý bởi hệ thống theo mặc định khi bị dừng (sao cho người dùng có thể điều hướng lại
+nó bằng nút <em>Quay lại</em> như được đề cập trong <a href="{@docRoot}guide/components/tasks-and-back-stack.html">Tác vụ và Ngăn xếp</a>).
+Tuy nhiên, phân đoạn chỉ được đặt vào một ngăn xếp do hoạt động chủ quản lý khi bạn
+yêu cầu rõ ràng rằng trường hợp đó phải được lưu bằng cách gọi {@link
+android.app.FragmentTransaction#addToBackStack(String) addToBackStack()} trong một giao tác
+gỡ bỏ phân đoạn.</p>
+
+<p>Nếu không thì việc quản lý vòng đời của phân đoạn rất giống với việc quản lý vòng đời
+của hoạt động. Vì thế, những nội dung áp dụng cho <a href="{@docRoot}guide/components/activities.html#Lifecycle">quản lý vòng đời của
+hoạt động</a> cũng áp dụng cho phân đoạn. Tuy nhiên, việc mà bạn cũng cần phải hiểu đó là cách
+vòng đời của hoạt động ảnh hưởng tới vòng đời của phân đoạn.</p>
+
+<p class="caution"><strong>Chú ý:</strong> Nếu bạn cần một đối tượng {@link android.content.Context} trong
+{@link android.app.Fragment}của mình, bạn có thể gọi {@link android.app.Fragment#getActivity()}.
+Tuy nhiên, nhớ chỉ được gọi {@link android.app.Fragment#getActivity()} khi phân đoạn được gắn với
+một hoạt động. Khi phân đoạn chưa được gắn, hoặc bị gỡ trong khi kết thúc
+vòng đời của nó, {@link android.app.Fragment#getActivity()} sẽ trả về rỗng.</p>
+
+
+<h3 id="CoordinatingWithActivity">Phối hợp với vòng đời của hoạt động</h3>
+
+<p>Vòng đời của hoạt động mà phân đoạn có ở trong đó sẽ trực tiếp ảnh hưởng tới vòng đời của phân đoạn
+, sao cho mỗi lệnh gọi lại vòng đời cho hoạt động đó sẽ dẫn tới một lệnh gọi lại tương tự cho từng
+phân đoạn. Ví dụ, khi hoạt động nhận được {@link android.app.Activity#onPause}, mỗi
+phân đoạn trong hoạt động sẽ nhận được {@link android.app.Fragment#onPause}.</p>
+
+<p>Tuy nhiên, các phân đoạn có thêm một vài lệnh gọi lại vòng đời nhằm xử lý tương tác duy nhất với
+hoạt động để thực hiện các hành động như xây dựng và hủy UI của phân đoạn. Những phương pháp gọi lại
+bổ sung này là:</p>
+
+<dl>
+ <dt>{@link android.app.Fragment#onAttach onAttach()}</dt>
+ <dd>Được gọi khi phân đoạn đã được liên kết với hoạt động {@link
+android.app.Activity} được chuyển ở đây).</dd>
+ <dt>{@link android.app.Fragment#onCreateView onCreateView()}</dt>
+ <dd>Được gọi khi tạo phân cấp dạng xem được liên kết với phân đoạn.</dd>
+ <dt>{@link android.app.Fragment#onActivityCreated onActivityCreated()}</dt>
+ <dd>Được gọi khi phương pháp {@link android.app.Activity#onCreate
+onCreate()} của hoạt động đã trả về.</dd>
+ <dt>{@link android.app.Fragment#onDestroyView onDestroyView()}</dt>
+ <dd>Được gọi khi phân cấp dạng xem được liên kết với phân đoạn đang được gỡ bỏ.</dd>
+ <dt>{@link android.app.Fragment#onDetach onDetach()}</dt>
+ <dd>Được gọi khi phân đoạn đang được bỏ liên kết khỏi hoạt động.</dd>
+</dl>
+
+<p>Tiến trình vòng đời của một phân đoạn, do bị ảnh hưởng bởi hoạt động chủ của nó, được minh họa
+bởi hình 3. Trong hình này, bạn có thể thấy cách thức mỗi trạng thái nối tiếp nhau của hoạt động sẽ xác định
+các phương pháp gọi lại nào mà một phân đoạn có thể nhận được. Ví dụ, khi hoạt động đã nhận được lệnh gọi lại {@link
+android.app.Activity#onCreate onCreate()} của nó, phân đoạn trong hoạt động sẽ nhận được không quá
+lệnh gọi lại {@link android.app.Fragment#onActivityCreated onActivityCreated()}.</p>
+
+<p>Sau khi hoạt động đạt trạng thái tiếp tục, bạn có thể tự do thêm và gỡ bỏ phân đoạn vào
+hoạt động. Vì thế, chỉ trong khi hoạt động ở trạng thái tiếp tục thì vòng đời của một phân đoạn
+mới có thể thay đổi độc lập.</p>
+
+<p>Tuy nhiên, khi hoạt động rời khỏi trạng thái tiếp tục, phân đoạn lại bị hoạt động đẩy qua vòng đời
+của mình.</p>
+
+
+
+
+<h2 id="Example">Ví dụ</h2>
+
+<p>Để kết hợp mọi nội dung được đề cập trong tài liệu này, sau đây là một ví dụ về hoạt động
+sử dụng hai phân đoạn để tạo một bố trí hai bảng. Hoạt động bên dưới bao gồm một phân đoạn để
+hiển thị danh sách các vở kịch của Shakespeare và một phân đoạn khác để hiển thị tóm tắt về vở kịch khi được chọn
+từ danh sách. Nó cũng minh họa cách cung cấp các cấu hình phân đoạn khác nhau,
+dựa trên cấu hình màn hình.</p>
+
+<p class="note"><strong>Lưu ý:</strong> Mã nguồn hoàn chỉnh cho hoạt động này có sẵn trong
+<a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.html">{@code
+FragmentLayout.java}</a>.</p>
+
+<p>Hoạt động chính áp dụng một bố trí theo cách thông thường, trong {@link
+android.app.Activity#onCreate onCreate()}:</p>
+
+{@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.java main}
+
+<p>Bố trí được áp dụng là {@code fragment_layout.xml}:</p>
+
+{@sample development/samples/ApiDemos/res/layout-land/fragment_layout.xml layout}
+
+<p>Khi sử dụng bố trí này, hệ thống sẽ khởi tạo {@code TitlesFragment} (liệt kê tên
+các vở kịch) ngay khi hoạt động nạp bố trí, trong khi {@link android.widget.FrameLayout}
+(nơi sẽ xuất hiện phân đoạn hiển thị tóm tắt về vở kịch) chiếm khoảng trống phía bên phải của
+màn hình, nhưng ban đầu vẫn trống. Như bạn sẽ thấy bên dưới, mãi tới khi người dùng chọn một mục
+từ danh sách thì một phân đoạn mới được đặt vào {@link android.widget.FrameLayout}.</p>
+
+<p>Tuy nhiên, không phải tất cả cấu hình màn hình đều đủ rộng để hiển thị cả danh sách
+các vở kịch và tóm tắt bên cạnh nhau. Vì thế, bố trí trên chỉ được sử dụng cho cấu hình
+màn hình khổ ngang bằng cách lưu nó dưới dạng {@code res/layout-land/fragment_layout.xml}.</p>
+
+<p>Vì thế, khi màn hình hướng đứng, hệ thống sẽ áp dụng bố trí sau, nó
+được lưu tại {@code res/layout/fragment_layout.xml}:</p>
+
+{@sample development/samples/ApiDemos/res/layout/fragment_layout.xml layout}
+
+<p>Bố trí này chỉ bao gồm {@code TitlesFragment}. Điều này có nghĩa là, khi thiết bị ở
+hướng đứng, chỉ danh sách tên vở kịch được hiển thị. Vì thế, khi người dùng nhấp vào một
+mục danh sách trong cấu hình này, ứng dụng sẽ bắt đầu một hoạt động mới để hiển thị tóm tắt,
+thay vì tải một phân đoạn thứ hai.</p>
+
+<p>Tiếp theo, bạn có thể thấy cách hoàn thành điều này trong các lớp phân đoạn. Đầu tiên là {@code
+TitlesFragment}, hiển thị danh sách tên các vở kịch của Shakespeare. Phân đoạn này sẽ mở rộng {@link
+android.app.ListFragment} và dựa vào nó để xử lý hầu hết công việc về dạng xem danh sách.</p>
+
+<p>Khi bạn kiểm tra đoạn mã này, hãy để ý rằng có hai hành vi có thể khi người dùng nhấp vào một
+mục danh sách: phụ thuộc vào bố trí nào trong hai bố trí đang hiện hoạt, nó có thể hoặc tạo và hiển thị một phân đoạn
+mới để hiển thị chi tiết trong cùng hoạt động (thêm phân đoạn vào {@link
+android.widget.FrameLayout}), hoặc bắt đầu một hoạt động mới (tại đó phân đoạn có thể được hiển thị).</p>
+
+{@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.java titles}
+
+<p>Phân đoạn thứ hai, {@code DetailsFragment} sẽ hiển thị tóm tắt vở kịch cho mục được chọn từ
+danh sách trong {@code TitlesFragment}:</p>
+
+{@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.java details}
+
+<p>Nhớ lại ở lớp {@code TitlesFragment} rằng, nếu người dùng nhấp vào một mục danh sách và bố trí
+hiện tại <em>không</em> có dạng xem {@code R.id.details} (là nơi mà
+{@code DetailsFragment} thuộc về), khi đó, ứng dụng sẽ bắt đầu hoạt động {@code DetailsActivity}
+để hiển thị nội dung của mục đó.</p>
+
+<p>Sau đây là {@code DetailsActivity}, nó chỉ đơn thuần nhúng {@code DetailsFragment} để hiển thị
+tóm tắt vở kịch được chọn khi màn hình ở hướng đứng:</p>
+
+{@sample development/samples/ApiDemos/src/com/example/android/apis/app/FragmentLayout.java
+details_activity}
+
+<p>Lưu ý rằng hoạt động này tự kết thúc nếu cấu hình là khổ ngang, sao cho hoạt động
+chính có thể chiếm lấy và hiển thị {@code DetailsFragment} bên cạnh {@code TitlesFragment}.
+Điều này có thể xảy ra nếu người dùng bắt đầu {@code DetailsActivity} ở dạng hướng đứng, nhưng
+sau đó xoay thành khổ ngang (làm vậy sẽ bắt đầu lại hoạt động hiện tại).</p>
+
+
+<p>Để biết thêm mẫu sử dụng phân đoạn (và toàn bộ tệp nguồn cho ví dụ này),
+hãy xem ứng dụng mẫu API Demos có sẵn trong <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/index.html#Fragment">
+ApiDemos</a> (có thể tải xuống từ <a href="{@docRoot}resources/samples/get.html">Thành phần SDK Mẫu</a>).</p>
+
+
diff --git a/docs/html-intl/intl/vi/guide/components/fundamentals.jd b/docs/html-intl/intl/vi/guide/components/fundamentals.jd
new file mode 100644
index 000000000000..4b70140723d9
--- /dev/null
+++ b/docs/html-intl/intl/vi/guide/components/fundamentals.jd
@@ -0,0 +1,480 @@
+page.title=Đại cương về Ứng dụng
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>Trong tài liệu này</h2>
+<ol>
+<li><a href="#Components">Thành phần của Ứng dụng</a>
+ <ol>
+ <li><a href="#ActivatingComponents">Kích hoạt các thành phần</a></li>
+ </ol>
+</li>
+<li><a href="#Manifest">Tệp Bản kê khai</a>
+ <ol>
+ <li><a href="#DeclaringComponents">Khai báo các thành phần</a></li>
+ <li><a href="#DeclaringRequirements">Khai báo các yêu cầu của ứng dụng</a></li>
+ </ol>
+</li>
+<li><a href="#Resources">Tài nguyên Ứng dụng</a></li>
+</ol>
+</div>
+</div>
+
+<p>Ứng dụng Android được viết bằng ngôn ngữ lập trình Java. Bộ công cụ SDK Android sẽ biên dịch
+mã của bạn&mdash;cùng với bất kỳ tệp dữ liệu và tài nguyên nào&mdash;vào một APK: một <i>gói Android</i>,
+đó là một tệp lưu trữ có hậu tố {@code .apk}. Một tệp APK chứa tất cả nội dung
+của một ứng dụng Android và là tệp mà các thiết bị dựa trên nền tảng Android sử dụng để cài đặt ứng dụng.</p>
+
+<p>Sau khi được cài đặt lên một thiết bị, từng ứng dụng Android sẽ ở bên trong hộp cát bảo mật của chính nó: </p>
+
+<ul>
+ <li>Hệ điều hành Android là một hệ thống Linux đa người dùng trong đó mỗi ứng dụng là một
+người dùng khác nhau.</li>
+
+<li>Theo mặc định, hệ thống gán cho từng ứng dụng một ID người dùng Linux duy nhất (ID chỉ được sử dụng bởi
+hệ thống và không xác định đối với ứng dụng). Hệ thống sẽ đặt quyền cho tất cả tệp trong một ứng dụng
+sao cho chỉ ID người dùng được gán cho ứng dụng đó mới có thể truy cập chúng. </li>
+
+<li>Mỗi tiến trình có máy ảo (VM) riêng của mình, vì thế mã của một ứng dụng sẽ chạy độc lập với
+các ứng dụng khác.</li>
+
+<li>Theo mặc định, mọi ứng dụng chạy trong tiến trình Linux của chính nó. Android khởi động tiến trình khi bất kỳ
+thành phần nào của ứng dụng cần được thực thi, sau đó tắt tiến trình khi không còn
+cần nữa hoặc khi hệ thống phải khôi phục bộ nhớ cho các ứng dụng khác.</li>
+</ul>
+
+<p>Bằng cách này, hệ thống Android triển khai <em>nguyên tắc đặc quyền ít nhất</em>. Cụ thể,
+theo mặc định, mỗi ứng dụng chỉ có thể truy cập vào các thành phần mà nó cần để thực hiện công việc của mình và
+không hơn. Điều này tạo ra một môi trường rất bảo mật mà trong đó một ứng dụng không thể truy cập các bộ phận của
+hệ thống mà nó không được cấp quyền.</p>
+
+<p>Tuy nhiên, có nhiều cách để một ứng dụng chia sẻ dữ liệu với các ứng dụng khác và để một
+ứng dụng truy cập vào các dịch vụ của hệ thống:</p>
+
+<ul>
+ <li>Có thể sắp xếp để hai ứng dụng chia sẻ cùng ID người dùng Linux, trong trường hợp đó
+chúng có thể truy cập các tệp của nhau. Để tiết kiệm tài nguyên của hệ thống, các ứng dụng có
+cùng ID người dùng cũng có thể sắp xếp để chạy trong cùng tiến trình Linux và chia sẻ cùng VM (các
+ứng dụng cũng phải được ký bằng cùng chứng chỉ).</li>
+ <li>Một ứng dụng có thể yêu cầu quyền truy cập dữ liệu của thiết bị chẳng hạn như
+danh bạ của người dùng, tin nhắn SMS, thiết bị lưu trữ gắn được (thẻ SD), máy ảnh, Bluetooth và nhiều nữa. Tất cả
+quyền ứng dụng đều phải được cấp bởi người dùng tại thời điểm cài đặt.</li>
+</ul>
+
+<p>Đó là nội dung cơ bản về cách mà một ứng dụng Android tồn tại trong hệ thống. Phần còn lại của
+tài liệu này giới thiệu với bạn về:</p>
+<ul>
+ <li>Các thành phần khuôn khổ cốt lõi định nghĩa ứng dụng của bạn.</li>
+ <li>Tệp bản kê khai mà trong đó bạn khai báo các thành phần và tính năng yêu cầu của thiết bị cho ứng dụng
+của bạn.</li>
+ <li>Các tài nguyên tách riêng với mã ứng dụng và cho phép ứng dụng của bạn
+tối ưu hóa hành vi của nó cho nhiều loại cấu hình thiết bị đa dạng.</li>
+</ul>
+
+
+
+<h2 id="Components">Thành phần của Ứng dụng</h2>
+
+<p>Thành phần của ứng dụng là những khối dựng thiết yếu của một ứng dụng Android. Mỗi
+thành phần là một điểm khác nhau mà qua đó hệ thống có thể vào ứng dụng của bạn. Không phải tất cả
+thành phần đều là các điểm nhập thực tế cho người dùng và một số phụ thuộc vào nhau, nhưng mỗi thành phần tồn tại
+như một thực thể riêng và đóng một vai trò riêng&mdash;mỗi thành phần là một khối dựng duy nhất
+giúp định nghĩa hành vi chung của ứng dụng của bạn.</p>
+
+<p>Có bốn loại thành phần ứng dụng khác nhau. Mỗi loại có một mục đích riêng
+và có một vòng đời riêng, xác định cách thành phần được tạo lập và hủy.</p>
+
+<p>Sau đây là bốn loại thành phần ứng dụng:</p>
+
+<dl>
+
+<dt><b>Hoạt động</b></dt>
+
+<dd>Một <i>hoạt động</i> biểu diễn một màn hình đơn với một giao diện người dùng. Ví dụ,
+một ứng dụng e-mail có thể có một hoạt động với chức năng hiển thị một danh sách
+e-mail mới, một hoạt động khác để soạn e-mail, và một hoạt động khác để đọc e-mail. Mặc dù
+các hoạt động cùng nhau tạo thành một trải nghiệm người dùng gắn kết trong ứng dụng e-mail, mỗi hoạt động
+lại độc lập với nhau. Như vậy, một ứng dụng khác có thể khởi động bất kỳ hoạt động nào
+trong số này (nếu ứng dụng e-mail cho phép nó). Ví dụ, một ứng dụng máy ảnh có thể khởi động
+hoạt động trong ứng dụng e-mail có chức năng soạn thư mới, để người dùng chia sẻ một bức ảnh.
+
+<p>Hoạt động được triển khai như một lớp con của {@link android.app.Activity} và bạn có thể tìm hiểu thêm
+về nó trong hướng dẫn dành cho nhà phát triển <a href="{@docRoot}guide/components/activities.html">Hoạt động</a>
+.</p>
+</dd>
+
+
+<dt><b>Dịch vụ</b></dt>
+
+<dd>Một <i>dịch vụ</i> là một thành phần chạy ngầm để thực hiện các thao tác
+chạy lâu hoặc để thực hiện công việc cho các tiến trình từ xa. Dịch vụ
+không cung cấp giao diện người dùng. Ví dụ, một dịch vụ có thể phát nhạc dưới nền trong khi
+người dùng đang ở một ứng dụng khác, hoặc nó có thể tải dữ liệu qua mạng mà không
+chặn người dùng tương tác với hoạt động. Một thành phần khác, chẳng hạn như một hoạt động, có thể khởi động
+dịch vụ và để nó chạy hoặc gắn kết với nó để tương tác với nó.
+
+<p>Dịch vụ được triển khai như một lớp con của {@link android.app.Service} và bạn có thể tìm hiểu
+thêm về nó trong hướng dẫn cho nhà phát triển <a href="{@docRoot}guide/components/services.html">Dịch vụ</a>
+.</p>
+</dd>
+
+
+<dt><b>Trình cung cấp Nội dung</b></dt>
+
+<dd>Một <i>trình cung cấp nội dung</i> sẽ quản lý một tập dữ liệu ứng dụng được chia sẻ. Bạn có thể lưu trữ dữ liệu trong
+hệ thống tệp, một cơ sở dữ liệu SQLite, trên web, hay bất kỳ vị trí lưu trữ liên tục nào khác mà
+ứng dụng của bạn có thể truy cập. Thông qua trình cung cấp nội dung, các ứng dụng khác có thể truy vấn hay thậm chí sửa đổi
+dữ liệu (nếu trình cung cấp nội dung cho phép). Ví dụ, hệ thống Android cung cấp một trình cung cấp
+nội dung có chức năng quản lý thông tin danh bạ của người dùng. Như vậy, bất kỳ ứng dụng nào có các quyền
+phù hợp đều có thể truy vấn bất kỳ phần nào của trình cung cấp nội dung (chẳng hạn như {@link
+android.provider.ContactsContract.Data}) để đọc và ghi thông tin về một người cụ thể.
+
+<p>Trình cung cấp nội dung cũng hữu ích với việc đọc và ghi dữ liệu riêng tư đối với
+ứng dụng của bạn và không được chia sẻ. Ví dụ, ứng dụng mẫu <a href="{@docRoot}resources/samples/NotePad/index.html">Note Pad</a> sử dụng một
+trình cung cấp nội dung để lưu các ghi chú.</p>
+
+<p>Trình cung cấp nội dung được triển khai như một lớp con của {@link android.content.ContentProvider}
+và phải triển khai một tập các API tiêu chuẩn cho phép các ứng dụng khác thực hiện
+giao tác. Để biết thêm thông tin, xem hướng dẫn cho nhà phát triển <a href="{@docRoot}guide/topics/providers/content-providers.html">Trình cung cấp Nội dung</a>
+.</p>
+</dd>
+
+
+<dt><b>Hàm nhận quảng bá</b></dt>
+
+<dd>Một <i>hàm nhận quảng bá</i> (broadcast receiver) là một thành phần có chức năng hồi đáp lại các thông báo
+quảng bá trên toàn hệ thống. Nhiều quảng bá khởi nguồn từ hệ thống&mdash;ví dụ, một quảng bá thông báo
+rằng màn hình đã tắt, pin yếu, hoặc một bức ảnh được chụp.
+Các ứng dụng cũng có thể khởi tạo quảng bá&mdash;ví dụ như để các ứng dụng khác biết rằng
+một phần dữ liệu đã được tải xuống thiết bị và có sẵn để họ sử dụng. Mặc dù các hàm nhận quảng bá
+không hiển thị giao diện người dùng, chúng có thể <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">tạo một thông báo thanh trạng thái</a>
+để cảnh báo người tiếp nhận khi xảy ra một sự kiện quảng bá. Tuy nhiên trường hợp phổ biến hơn đó là hàm nhận quảng bá chỉ
+là một "cổng kết nối" tới các thành phần khác và nhằm mục đích thực hiện lượng công việc rất ít. Ví
+dụ, nó có thể khởi tạo một dịch vụ để thực hiện một số công việc dựa trên sự kiện.
+
+<p>Hàm nhận quảng bá được triển khai như một lớp con của {@link android.content.BroadcastReceiver}
+và mỗi quảng bá được chuyển giao như một đối tượng {@link android.content.Intent}. Để biết thêm thông tin,
+hãy xem lớp {@link android.content.BroadcastReceiver}.</p>
+</dd>
+
+</dl>
+
+
+
+<p>Một khía cạnh độc đáo trong thiết kế hệ thống Android đó là bất kỳ ứng dụng nào cũng có thể khởi động một thành phần của
+ứng dụng khác. Ví dụ, nếu bạn muốn người dùng chụp
+ảnh bằng máy ảnh của thiết bị, có thể có một ứng dụng khác có chức năng đó và
+ứng dụng của bạn có thể sử dụng nó thay vì phát triển một hoạt động để tự chụp ảnh. Bạn không
+cần tích hợp hay thậm chí là liên kết với mã từ ứng dụng của máy ảnh.
+Thay vào đó, bạn đơn giản có thể khởi động hoạt động đó trong ứng dụng máy ảnh có chức năng
+chụp ảnh. Khi hoàn thành, ảnh thậm chí được trả về ứng dụng của bạn để bạn có thể sử dụng nó. Đối với người dùng,
+có vẻ như máy ảnh là một bộ phận thực sự trong ứng dụng của bạn.</p>
+
+<p>Khi hệ thống khởi động một thành phần, nó sẽ khởi động tiến trình cho ứng dụng đó (nếu tiến trình không
+đang chạy) và khởi tạo các lớp cần thiết cho thành phần. Ví dụ, nếu ứng dụng
+của bạn khởi động hoạt động trong ứng dụng máy ảnh có chức năng chụp ảnh, hoạt động đó
+sẽ chạy trong tiến trình thuộc về ứng dụng máy ảnh chứ không chạy trong tiến trình của ứng dụng của bạn.
+Vì thế, không như ứng dụng trên hầu hết các hệ thống khác, ứng dụng Android không có một điểm nhập
+duy nhất (ví dụ, không có chức năng {@code main()}).</p>
+
+<p>Vì hệ thống chạy từng ứng dụng trong một tiến trình riêng với các quyền của tệp mà
+hạn chế truy cập vào các ứng dụng khác, ứng dụng của bạn không thể trực tiếp kích hoạt một thành phần từ
+một ứng dụng khác. Tuy nhiên, hệ thống Android có thể. Vì thế, để kích hoạt một thành phần trong
+một ứng dụng khác, bạn phải chuyển giao một thông báo tới hệ thống trong đó nêu rõ <em>ý định</em> của bạn để
+khởi động một thành phần cụ thể. Sau đó, hệ thống sẽ kích hoạt thành phần cho bạn.</p>
+
+
+<h3 id="ActivatingComponents">Kích hoạt Thành phần</h3>
+
+<p>Ba trong bốn loại thành phần&mdash;hoạt động, dịch vụ và
+hàm nhận quảng bá&mdash;sẽ được kích hoạt bằng một thông báo không đồng bộ gọi là <em>ý định</em>.
+Ý định sẽ gắn kết từng thành phần với nhau vào thời gian chạy (bạn có thể nghĩ chúng như là
+các hàm nhắn tin có chức năng yêu cầu một hành động từ các thành phần khác), dù thành phần đó thuộc
+về ứng dụng của bạn hay ứng dụng khác.</p>
+
+<p>Một ý định được tạo thành bằng một đối tượng {@link android.content.Intent}, nó định nghĩa một thông báo để
+kích hoạt một thành phần cụ thể hoặc một <em>loại</em> thành phần cụ thể&mdash;tương ứng, một ý định
+có thể biểu thị hoặc không biểu thị.</p>
+
+<p>Đối với các hoạt động và dịch vụ, ý định có chức năng định nghĩa một hành động sẽ thực hiện (ví dụ, "xem" hoặc
+"gửi" gì đó) và có thể chỉ định URI của dữ liệu để hành động dựa trên đó (ngoài những điều khác mà
+thành phần được khởi động có thể cần biết). Ví dụ, một ý định có thể truyền tải một yêu cầu
+để một hoạt động hiển thị một hình ảnh hay mở một trang web. Trong một số trường hợp, bạn có thể khởi động một
+hoạt động để nhận kết quả, trong trường hợp đó, hoạt động cũng trả về
+kết quả trong một {@link android.content.Intent} (ví dụ, bạn có thể phát hành một ý định để cho phép
+người dùng chọn một liên lạc cá nhân và yêu cầu trả nó về cho bạn&mdash;ý định trả về bao gồm một
+URI chỉ đến liên lạc được chọn).</p>
+
+<p>Đối với hàm nhận quảng bá, ý định chỉ định nghĩa
+thông báo đang được quảng bá (ví dụ, một quảng bá để báo rằng pin của thiết bị yếu
+sẽ chỉ bao gồm một xâu hành động chỉ báo rằng "pin yếu").</p>
+
+<p>Loại thành phần còn lại, trình cung cấp nội dung, không được kích hoạt bởi ý định. Thay vào đó, nó được
+kích hoạt khi được nhằm tới bởi một yêu cầu từ một {@link android.content.ContentResolver}. Bộ giải quyết
+nội dung xử lý tất cả giao tác trực tiếp với trình cung cấp nội dung sao cho thành phần mà
+đang thực hiện giao tác với trình cung cấp sẽ không cần mà thay vào đó gọi các phương pháp trên đối tượng {@link
+android.content.ContentResolver}. Điều này để lại một lớp tóm tắt giữa trình cung cấp
+nội dung và thành phần yêu cầu thông tin (để bảo mật).</p>
+
+<p>Có các phương pháp riêng để kích hoạt từng loại thành phần:</p>
+<ul>
+ <li>Bạn có thể khởi động một hoạt động (hoặc giao cho nó việc gì mới để làm) bằng cách
+chuyển một {@link android.content.Intent} đến {@link android.content.Context#startActivity
+startActivity()} hoặc {@link android.app.Activity#startActivityForResult startActivityForResult()}
+(khi bạn muốn hoạt động trả về một kết quả).</li>
+ <li>Bạn có thể khởi động một dịch vụ (hoặc gửi chỉ dẫn mới tới một dịch vụ đang diễn ra) bằng cách
+chuyển một {@link android.content.Intent} đến {@link android.content.Context#startService
+startService()}. Hoặc bạn có thể gắn kết với dịch vụ bằng cách chuyển một {@link android.content.Intent} đến
+{@link android.content.Context#bindService bindService()}.</li>
+ <li>Bạn có thể khởi tạo một quảng bá bằng cách chuyển {@link android.content.Intent} tới các phương pháp như
+{@link android.content.Context#sendBroadcast(Intent) sendBroadcast()}, {@link
+android.content.Context#sendOrderedBroadcast(Intent, String) sendOrderedBroadcast()}, hoặc {@link
+android.content.Context#sendStickyBroadcast sendStickyBroadcast()}.</li>
+ <li>Bạn có thể thực hiện một truy vấn tới một trình cung cấp nội dung bằng cách gọi {@link
+android.content.ContentProvider#query query()} trên một {@link android.content.ContentResolver}.</li>
+</ul>
+
+<p>Để biết thêm thông tin về việc sử dụng ý định, hãy xem tài liệu <a href="{@docRoot}guide/components/intents-filters.html">Ý định và Bộ lọc
+Ý định</a>. Bạn cũng có thể xem thêm thông tin về việc kích hoạt các thành phần cụ thể
+trong những tài liệu sau: <a href="{@docRoot}guide/components/activities.html">Hoạt động</a>, <a href="{@docRoot}guide/components/services.html">Dịch vụ</a>, {@link
+android.content.BroadcastReceiver} và <a href="{@docRoot}guide/topics/providers/content-providers.html">Trình cung cấp Nội dung</a>.</p>
+
+
+<h2 id="Manifest">Tệp Bản kê khai</h2>
+
+<p>Trước khi hệ thống Android có thể khởi động một thành phần ứng dụng, hệ thống phải biết rằng
+thành phần đó tồn tại bằng cách đọc tệp {@code AndroidManifest.xml} của ứng dụng (tệp
+"bản kê khai"). Ứng dụng của bạn phải khai báo tất cả thành phần của nó trong tệp này, nó phải nằm ở gốc của
+thư mục dự án của ứng dụng.</p>
+
+<p>Bản kê khai làm nhiều việc bên cạnh việc khai báo các thành phần của ứng dụng,
+chẳng hạn như:</p>
+<ul>
+ <li>Xác định bất kỳ quyền của người dùng nào mà ứng dụng yêu cầu, chẳng hạn như truy cập Internet hay
+truy cập đọc vào danh bạ của người dùng.</li>
+ <li>Khai báo <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#ApiLevels">Mức API</a>
+tối thiểu mà ứng dụng yêu cầu dựa trên những API mà ứng dụng sử dụng.</li>
+ <li>Khai báo các tính năng phần cứng và phần mềm được sử dụng hoặc yêu cầu bởi ứng dụng, chẳng hạn như máy ảnh,
+dịch vụ Bluetooth, hoặc màn hình cảm ứng đa điểm.</li>
+ <li>Các thư viện API mà ứng dụng cần được liên kết với (ngoài các API khuôn khổ
+Android), chẳng hạn như <a href="http://code.google.com/android/add-ons/google-apis/maps-overview.html">thư viện Google Maps
+</a>.</li>
+ <li>Và hơn thế nữa</li>
+</ul>
+
+
+<h3 id="DeclaringComponents">Khai báo các thành phần</h3>
+
+<p>Nhiệm vụ chính của bản kê khai là thông báo cho hệ thống về các thành phần của ứng dụng. Ví
+dụ, một tệp bản kê khai có thể khai báo một hoạt động như sau: </p>
+
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
+&lt;manifest ... &gt;
+ &lt;application android:icon="@drawable/app_icon.png" ... &gt;
+ &lt;activity android:name="com.example.project.ExampleActivity"
+ android:label="@string/example_label" ... &gt;
+ &lt;/activity&gt;
+ ...
+ &lt;/application&gt;
+&lt;/manifest&gt;</pre>
+
+<p>Trong phần tử <code><a
+href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code>
+, thuộc tính {@code android:icon} sẽ trỏ đến các tài nguyên cho một biểu tượng có chức năng nhận biết
+ứng dụng.</p>
+
+<p>Trong phần tử <code><a
+href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>,
+thuộc tính {@code android:name} quy định tên lớp hoàn toàn đủ tiêu chuẩn của lớp con {@link
+android.app.Activity} và các thuộc tính {@code android:label} quy định một xâu
+để sử dụng làm nhãn hiển thị với người dùng đối với hoạt động.</p>
+
+<p>Bạn phải khai báo tất cả thành phần của ứng dụng như sau:</p>
+<ul>
+ <li>Các phần tử <code><a
+href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
+cho hoạt động</li>
+ <li>Các phần tử <code><a
+href="{@docRoot}guide/topics/manifest/service-element.html">&lt;service&gt;</a></code> cho
+dịch vụ</li>
+ <li>Các phần tử <code><a
+href="{@docRoot}guide/topics/manifest/receiver-element.html">&lt;receiver&gt;</a></code>
+cho hàm nhận quảng bá</li>
+ <li>Các phần tử <code><a
+href="{@docRoot}guide/topics/manifest/provider-element.html">&lt;provider&gt;</a></code>
+cho trình cung cấp nội dung</li>
+</ul>
+
+<p>Các hoạt động, dịch vụ và trình cung cấp nội dung mà bạn bao gồm trong nguồn của mình nhưng không khai báo
+trong bản kê khai sẽ không hiển thị với hệ thống và hệ quả là không bao giờ chạy được. Tuy nhiên,
+hàm nhận
+quảng bá có thể hoặc được khai báo trong bản kê khai hoặc được tạo linh hoạt trong mã (dạng đối tượng
+{@link android.content.BroadcastReceiver}) và được đăng ký với hệ thống bằng cách gọi
+{@link android.content.Context#registerReceiver registerReceiver()}.</p>
+
+<p>Để tìm hiểu thêm về cách cấu trúc tệp bản kê khai cho ứng dụng của mình, hãy xem tài liệu <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">Tệp AndroidManifest.xml</a>
+. </p>
+
+
+
+<h3 id="DeclaringComponentCapabilities">Khai báo các khả năng của thành phần</h3>
+
+<p>Như đã nêu bên trên trong phần <a href="#ActivatingComponents">Kích hoạt các Thành phần</a>, bạn có thể sử dụng một
+{@link android.content.Intent} để khởi động các hoạt động, dịch vụ và hàm nhận quảng bá. Bạn có thể làm vậy bằng cách
+công khai chỉ định thành phần đích (sử dụng tên lớp thành phần) trong ý định. Tuy nhiên,
+sức mạnh thực sự của ý định nằm trong khái niệm <em>ý định không biểu thị</em>. Ý định không biểu thị
+đơn thuần mô tả kiểu hành động cần thực hiện (và có thể có cả dữ liệu mà bạn muốn
+thực hiện hành động) và cho phép hệ thống tìm một thành phần trên thiết bị có khả năng thực hiện
+hành động và khởi động nó. Nếu có nhiều thành phần có thể thực hiện hành động được mô tả bởi
+ý định, khi đó người dùng chọn ý định sẽ sử dụng.</p>
+
+<p>Cách hệ thống nhận biết các thành phần có khả năng hồi đáp lại một ý định là bằng cách so sánh
+ý định nhận được với <i>các bộ lọc ý định</i> được cung cấp trong tệp bản kê khai của các ứng dụng khác trên
+thiết bị.</p>
+
+<p>Khi bạn khai báo một hoạt động trong bản kê khai ứng dụng của mình, bạn có thể tùy chọn bao gồm
+các bộ lọc ý định có chức năng khai báo các khả năng của hoạt động sao cho nó có thể hồi đáp lại ý định
+từ các ứng dụng khác. Bạn có thể khai báo một bộ lọc ý định cho thành phần của mình bằng cách
+thêm một phần tử <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code
+&lt;intent-filter&gt;}</a> làm con của phần tử công khai của thành phần đó.</p>
+
+<p>Ví dụ, nếu bạn đã xây dựng một ứng dụng e-mail có một hoạt động soạn e-mail mới, bạn có thể
+khai báo bộ lọc ý định đó để trả lời các ý định "gửi" (để gửi một e-mail mới) như sau:</p>
+<pre>
+&lt;manifest ... >
+ ...
+ &lt;application ... &gt;
+ &lt;activity android:name="com.example.project.ComposeEmailActivity">
+ &lt;intent-filter>
+ &lt;action android:name="android.intent.action.SEND" />
+ &lt;data android:type="*/*" />
+ &lt;category android:name="android.intent.category.DEFAULT" />
+ &lt;/intent-filter>
+ &lt;/activity>
+ &lt;/application&gt;
+&lt;/manifest>
+</pre>
+
+<p>Sau đó, nếu một ứng dụng khác tạo một ý định với hành động {@link
+android.content.Intent#ACTION_SEND} và chuyển nó cho {@link android.app.Activity#startActivity
+startActivity()}, hệ thống có thể khởi động hoạt động của bạn để người dùng có thể soạn thảo và gửi một
+e-mail.</p>
+
+<p>Để tìm hiểu thêm về việc tạo các bộ lọc ý định, hãy xem tài liệu <a href="{@docRoot}guide/components/intents-filters.html">Ý định và Bộ lọc Ý định</a>.
+</p>
+
+
+
+<h3 id="DeclaringRequirements">Khai báo các yêu cầu của ứng dụng</h3>
+
+<p>Có nhiều loại thiết bị dựa trên nền tảng Android và không phải tất cả chúng đều cung cấp
+các tính năng và khả năng như nhau. Để tránh việc ứng dụng của bạn bị cài đặt trên các thiết bị
+thiếu những tính năng mà ứng dụng của bạn cần, điều quan trọng là bạn phải định nghĩa rõ ràng một hồ sơ cho
+các kiểu thiết bị mà ứng dụng của bạn hỗ trợ bằng cách khai báo các yêu cầu về thiết bị và phần mềm trong tệp
+bản kê khai của mình. Hầu hết những khai báo này đều chỉ mang tính chất thông báo và hệ thống không đọc
+chúng, nhưng các dịch vụ bên ngoài như Google Play thì có đọc để cung cấp tính năng lọc
+cho người dùng khi họ tìm kiếm ứng dụng từ thiết bị của mình.</p>
+
+<p>Ví dụ, nếu ứng dụng của bạn yêu cầu máy ảnh và sử dụng các API được giới thiệu trong Android 2.1 (<a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#ApiLevels">API Mức</a> 7),
+bạn cần khai báo những điều này như yêu cầu trong tệp bản kê khai của mình như sau:</p>
+
+<pre>
+&lt;manifest ... >
+ &lt;uses-feature android:name="android.hardware.camera.any"
+ android:required="true" />
+ &lt;uses-sdk android:minSdkVersion="7" android:targetSdkVersion="19" />
+ ...
+&lt;/manifest>
+</pre>
+
+<p>Lúc này, những thiết bị mà <em>không</em> có máy ảnh và có một phiên bản
+Android <em>thấp</em> hơn 2.1 sẽ không thể cài đặt ứng dụng của bạn từ Google Play.</p>
+
+<p>Tuy nhiên, bạn cũng có thể khai báo rằng ứng dụng của bạn sử dụng máy ảnh, nhưng không
+<em>yêu cầu</em> nó. Trong trường hợp đó, ứng dụng của bạn phải đặt thuộc tính <a href="{@docRoot}guide/topics/manifest/uses-feature-element.html#required">{@code required}</a>
+thành {@code "false"} và kiểm tra tại thời gian chạy xem
+thiết bị có máy ảnh không và vô hiệu hóa bất kỳ tính năng máy ảnh nào cho phù hợp.</p>
+
+<p>Bạn có thể tìm hiểu thêm thông tin về cách bạn có thể quản lý tính tương thích của ứng dụng của bạn với các thiết bị khác nhau
+trong tài liệu <a href="{@docRoot}guide/practices/compatibility.html">Tính tương thích với Thiết bị</a>
+.</p>
+
+
+
+<h2 id="Resources">Tài nguyên Ứng dụng</h2>
+
+<p>Một ứng dụng Android được soạn không chỉ có mã&mdash;nó còn yêu cầu các tài nguyên
+tách riêng với mã nguồn, chẳng hạn như hình ảnh, tệp âm thanh và bất kỳ thứ gì liên quan tới trình chiếu
+trực quan của ứng dụng. Ví dụ, bạn nên định nghĩa các hoạt cảnh, menu, kiểu, màu sắc,
+và bố trí của giao diện người dùng của hoạt động bằng các tệp XML. Việc sử dụng các tài nguyên ứng dụng giúp dễ dàng
+cập nhật các đặc điểm khác nhau trong ứng dụng của bạn mà không sửa đổi mã và&mdash;bằng cách cung cấp
+các tập hợp tài nguyên thay thế&mdash;cho phép bạn tối ưu hóa ứng dụng của mình cho nhiều loại
+cấu hình thiết bị (chẳng hạn như ngôn ngữ và kích cỡ màn hình khác nhau).</p>
+
+<p>Đối với mọi tài nguyên mà bạn bao gồm trong dự án Android của mình, bộ công cụ xây dựng SDK định nghĩa một ID số nguyên
+duy nhất mà bạn có thể sử dụng để tham chiếu tài nguyên từ mã ứng dụng của mình hoặc từ
+các tài nguyên khác được định nghĩa trong XML. Ví dụ, nếu ứng dụng của bạn chứa một tệp hình ảnh có tên {@code
+logo.png} (được lưu trong thư mục {@code res/drawable/}), bộ công cụ SDK sẽ khởi tạo một ID tài nguyên
+đặt tên là {@code R.drawable.logo} mà bạn có thể sử dụng để tham chiếu hình ảnh và chèn nó vào trong giao diện người dùng
+của mình.</p>
+
+<p>Một trong những khía cạnh quan trọng nhất của việc cung cấp tài nguyên tách riêng với mã nguồn của bạn
+là khả năng cho phép bạn cung cấp các tài nguyên thay thế cho các
+cấu hình thiết bị khác nhau. Ví dụ, bằng cách định nghĩa các xâu UI trong XML, bạn có thể biên dịch xâu sang
+các ngôn ngữ khác và lưu các xâu đó vào tệp riêng. Sau đó, dựa vào một <em>hạn định</em> ngôn ngữ
+mà bạn nối với tên của thư mục tài nguyên (chẳng hạn như {@code res/values-fr/} đối với các giá trị xâu
+tiếng Pháp) và thiết đặt ngôn ngữ của người dùng, hệ thống Android sẽ áp dụng các xâu ngôn ngữ phù hợp
+cho UI của bạn.</p>
+
+<p>Android hỗ trợ nhiều <em>hạn định</em> khác nhau cho các tài nguyên thay thế của bạn. Hạn định
+là một xâu ngắn mà bạn bao gồm trong tên của các thư mục tài nguyên của mình nhằm
+định nghĩa cấu hình thiết bị cho những tài nguyên đó nên được sử dụng. Lấy một
+ví dụ khác, bạn nên thường xuyên tạo các bố trí khác nhau cho hoạt động của mình, tùy vào hướng và kích cỡ
+màn hình của thiết bị. Ví dụ, khi màn hình thiết bị ở hướng
+đứng (cao), bạn có thể muốn một bố trí có các nút thẳng đứng, nhưng khi màn hình ở hướng
+khổ ngang (rộng), các nút nên được căn ngang. Để thay đổi bố trí
+tùy vào hướng, bạn có thể định nghĩa hai bố trí khác nhau và áp dụng hạn định
+phù hợp cho tên thư mục của từng bố trí. Sau đó, hệ thống sẽ tự động áp dụng bố trí
+phù hợp tùy thuộc vào hướng hiện tại của thiết bị.</p>
+
+<p>Để biết thêm thông tin về các loại tài nguyên khác nhau mà bạn có thể bao gồm trong ứng dụng của mình và cách
+tạo các tài nguyên thay thế cho những cấu hình thiết bị khác nhau, hãy đọc <a href="{@docRoot}guide/topics/resources/providing-resources.html">Cung cấp Tài nguyên</a>.</p>
+
+
+
+<div class="next-docs">
+<div class="col-6">
+ <h2 class="norule">Tiếp tục đọc về:</h2>
+ <dl>
+ <dt><a href="{@docRoot}guide/components/intents-filters.html">Ý định và Bộ lọc Ý định</a>
+ </dt>
+ <dd>Thông tin về cách sử dụng các API {@link android.content.Intent} để
+ kích hoạt các thành phần của ứng dụng, chẳng hạn như hoạt động và dịch vụ, và cách tạo các thành phần cho ứng dụng của bạn
+ có sẵn để cho các ứng dụng khác sử dụng.</dd>
+ <dt><a href="{@docRoot}guide/components/activities.html">Hoạt động</a></dt>
+ <dd>Thông tin về cách tạo một thực thể của lớp {@link android.app.Activity},
+ có chức năng cung cấp một màn hình riêng trong ứng dụng của bạn với một giao diện người dùng.</dd>
+ <dt><a href="{@docRoot}guide/topics/resources/providing-resources.html">Cung cấp Tài nguyên</a></dt>
+ <dd>Thông tin về cách các ứng dụng Android được cấu trúc để tách riêng các tài nguyên ứng dụng khỏi
+ mã ứng dụng, bao gồm cách bạn có thể cung cấp các tài nguyên thay thế cho những
+ cấu hình thiết bị cụ thể.
+ </dd>
+ </dl>
+</div>
+<div class="col-6">
+ <h2 class="norule">Bạn cũng có thể quan tâm tới:</h2>
+ <dl>
+ <dt><a href="{@docRoot}guide/practices/compatibility.html">Tính tương thích của Thiết bị</a></dt>
+ <dd>Thông tin về Android hoạt động trên các loại thiết bị khác nhau và giới thiệu
+ về cách bạn có thể tối ưu hóa ứng dụng của mình cho từng thiết bị hoặc hạn chế tính sẵn có của ứng dụng của bạn
+ đối với các thiết bị khác nhau.</dd>
+ <dt><a href="{@docRoot}guide/topics/security/permissions.html">Quyền của Hệ thống</a></dt>
+ <dd>Thông tin về cách Android hạn chế truy cập của ứng dụng vào một số API nhất định bằng một hệ thống
+ quyền cần có sự đồng ý của người dùng cho phép ứng dụng của bạn có thể sử dụng các API đó.</dd>
+ </dl>
+</div>
+</div>
+
diff --git a/docs/html-intl/intl/vi/guide/components/index.jd b/docs/html-intl/intl/vi/guide/components/index.jd
new file mode 100644
index 000000000000..966597d999c2
--- /dev/null
+++ b/docs/html-intl/intl/vi/guide/components/index.jd
@@ -0,0 +1,57 @@
+page.title=Thành phần Ứng dụng
+page.landing=true
+page.landing.intro=Khuôn khổ ứng dụng của Android cho phép bạn tạo lập nhiều ứng dụng đa dạng và sáng tạo bằng cách sử dụng một tập hợp các thành phần có thể tái sử dụng. Phần này giải thích cách bạn có thể xây dựng các thành phần định nghĩa các khối dựng cho ứng dụng của mình và cách kết nối chúng với nhau bằng cách sử dụng ý định.
+page.metaDescription=Khuôn khổ ứng dụng của Android cho phép bạn tạo lập nhiều ứng dụng đa dạng và sáng tạo bằng cách sử dụng một tập hợp các thành phần có thể tái sử dụng. Phần này giải thích cách bạn có thể xây dựng các thành phần định nghĩa các khối dựng cho ứng dụng của mình và cách kết nối chúng với nhau bằng cách sử dụng ý định.
+page.landing.image=images/develop/app_components.png
+page.image=images/develop/app_components.png
+
+@jd:body
+
+<div class="landing-docs">
+
+ <div class="col-6">
+ <h3>Bài viết Blog</h3>
+
+ <a href="http://android-developers.blogspot.com/2012/05/using-dialogfragments.html">
+ <h4>Sử dụng DialogFragments</h4>
+ <p>Trong bài viết này, tôi sẽ trình bày cách sử dụng DialogFragments bằng thư viện hỗ trợ v4 (cho khả năng tương thích ngược trên các thiết bị chạy phiên bản trước Honeycomb) để hiển thị một hộp thoại chỉnh sửa đơn giản và trả về một kết quả cho lệnh gọi Hoạt động bằng cách sử dụng một giao diện.</p>
+ </a>
+
+ <a href="http://android-developers.blogspot.com/2011/03/fragments-for-all.html">
+ <h4>Phân đoạn cho Tất cả</h4>
+ <p>Hôm nay, chúng tôi đã phát hành một thư viện tĩnh giới thiệu API Phân đoạn (cũng như LoaderManager mới và một vài lớp khác) tương tự sao cho các ứng dụng tương thích với phiên bản Android 1.6 hoặc mới hơn có thể sử dụng phân đoạn để tạo các giao diện người dùng tương thích với máy tính bảng. </p>
+ </a>
+
+ <a href="http://android-developers.blogspot.com/2010/07/multithreading-for-performance.html">
+ <h4>Tạo đa luồng cho Hiệu năng</h4>
+ <p>Một cách làm hay trong khi tạo các ứng dụng hồi đáp đó là đảm bảo luồng UI chính của bạn
+thực hiện lượng công việc tối thiểu. Bất kỳ tác vụ dài tiềm ẩn nào mà có thể làm treo ứng dụng của bạn đều cần được
+xử lý trong một luồng khác.</p>
+ </a>
+ </div>
+
+ <div class="col-6">
+ <h3>Đào tạo</h3>
+
+ <a href="http://developer.android.com/training/basics/activity-lifecycle/index.html">
+ <h4>Quản lý Vòng đời của Hoạt động</h4>
+ <p>Lớp này giải thích các phương pháp gọi lại vòng đời quan trọng mà mỗi thực thể
+ Hoạt động nhận được và cách bạn có thể sử dụng chúng sao cho hoạt động của bạn thực hiện như người dùng kỳ vọng và không tiêu tốn tài nguyên
+ của hệ thống khi hoạt động của bạn không cần chúng.</p>
+ </a>
+
+ <a href="http://developer.android.com/training/basics/fragments/index.html">
+ <h4>Xây dựng một UI Động bằng các Phân đoạn</h4>
+ <p>Lớp này trình bày với bạn cách tạo một trải nghiệm người dùng động bằng các phân đoạn và tối ưu hóa
+trải nghiệm người dùng của ứng dụng của bạn đối với các thiết bị có kích cỡ màn hình khác nhau trong khi vẫn tiếp tục hỗ trợ
+các thiết bị chạy phiên bản cũ như Android 1.6.</p>
+ </a>
+
+ <a href="http://developer.android.com/training/sharing/index.html">
+ <h4>Chia sẻ Nội dung</h4>
+ <p>Lớp này trình bày một số cách thông dụng mà bạn có thể gửi và nhận nội dung giữa
+ các ứng dụng bằng cách sử dụng các API Ý định và đối tượng ActionProvider.</p>
+ </a>
+ </div>
+
+</div>
diff --git a/docs/html-intl/intl/vi/guide/components/intents-filters.jd b/docs/html-intl/intl/vi/guide/components/intents-filters.jd
new file mode 100644
index 000000000000..5bd0ddb2ee2e
--- /dev/null
+++ b/docs/html-intl/intl/vi/guide/components/intents-filters.jd
@@ -0,0 +1,901 @@
+page.title=Ý định và Bộ lọc Ý định
+page.tags="IntentFilter"
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>Trong tài liệu này</h2>
+<ol>
+ <li><a href="#Types">Các Loại Ý định</a></li>
+ <li><a href="#Building">Xây dựng một Ý định</a>
+ <ol>
+ <li><a href="#ExampleExplicit">Ví dụ về ý định biểu thị</a></li>
+ <li><a href="#ExampleSend">Ví dụ về ý định không biểu thị</a></li>
+ <li><a href="#ForceChooser">Bắt buộc một bộ chọn ứng dụng</a></li>
+ </ol>
+ </li>
+ <li><a href="#Receiving">Nhận một Ý định Không biểu thị</a>
+ <ol>
+ <li><a href="#ExampleFilters">Ví dụ về bộ lọc</a></li>
+ </ol>
+ </li>
+ <li><a href="#PendingIntent">Sử dụng một Ý định Chờ</a></li>
+ <li><a href="#Resolution">Giải quyết Ý định</a>
+ <ol>
+ <li><a href="#ActionTest">Kiểm tra hành động</a></li>
+ <li><a href="#CategoryTest">Kiểm tra thể loại</a></li>
+ <li><a href="#DataTest">Kiểm tra dữ liệu</a></li>
+ <li><a href="#imatch">So khớp ý định</a></li>
+ </ol>
+ </li>
+</ol>
+
+<h2>Xem thêm</h2>
+<ol>
+<li><a href="{@docRoot}training/basics/intents/index.html">Tương tác với các Ứng dụng khác</a></li>
+<li><a href="{@docRoot}training/sharing/index.html">Chia sẻ Nội dung</a></li>
+</ol>
+
+</div>
+</div>
+
+
+
+
+<p>{@link android.content.Intent} là một đối tượng nhắn tin mà bạn có thể sử dụng để yêu cầu một hành động
+từ một <a href="{@docRoot}guide/components/fundamentals.html#Components">thành phần ứng dụng</a> khác.
+Mặc dù các ý định sẽ tạo điều kiện cho giao tiếp giữa các thành phần bằng một vài cách, có ba
+trường hợp sử dụng cơ bản:</p>
+
+<ul>
+<li><b>Để bắt đầu một hoạt động:</b>
+<p>{@link android.app.Activity} biểu diễn một màn hình đơn trong một ứng dụng. Bạn có thể bắt đầu một thực thể
+mới của một {@link android.app.Activity} bằng cách chuyển {@link android.content.Intent}
+sang {@link android.content.Context#startActivity startActivity()}. {@link android.content.Intent}
+mô tả hoạt động cần bắt đầu và mang theo mọi dữ liệu cần thiết.</p>
+
+<p>Nếu bạn muốn nhận một kết quả từ hoạt động khi nó hoàn thành,
+hãy gọi {@link android.app.Activity#startActivityForResult
+startActivityForResult()}. Hoạt động của bạn nhận được kết quả
+dưới dạng một đối tượng {@link android.content.Intent} riêng biệt trong lệnh gọi lại {@link
+android.app.Activity#onActivityResult onActivityResult()} của hoạt động của bạn.
+Để biết thêm thông tin, hãy xem hướng dẫn <a href="{@docRoot}guide/components/activities.html">Hoạt động</a>.</p></li>
+
+<li><b>Để bắt đầu một dịch vụ:</b>
+<p>{@link android.app.Service} là một thành phần có chức năng thực hiện các thao tác dưới nền
+mà không cần giao diện người dùng. Bạn có thể bắt đầu một dịch vụ để thực hiện một thao tác một lần
+(chẳng hạn như tải xuống một tệp) bằng cách chuyển {@link android.content.Intent}
+tới {@link android.content.Context#startService startService()}. {@link android.content.Intent}
+mô tả dịch vụ cần bắt đầu và mang theo mọi dữ liệu cần thiết.</p>
+
+<p>Nếu dịch vụ được thiết kế với một giao diện máy khách-máy chủ, bạn có thể gắn kết với dịch vụ
+từ một thành phần khác bằng cách chuyển {@link android.content.Intent} sang {@link
+android.content.Context#bindService bindService()}</code>. Để biết thêm thông tin, hãy xem hướng dẫn <a href="{@docRoot}guide/components/services.html">Dịch vụ</a>.</p></li>
+
+<li><b>Để chuyển một quảng bá:</b>
+<p>Quảng bá là một tin nhắn mà bất kỳ ứng dụng nào cũng có thể nhận được. Hệ thống sẽ chuyển các quảng bá
+khác nhau tới các sự kiện hệ thống, chẳng hạn như khi hệ thống khởi động hoặc thiết bị bắt đầu sạc.
+Bạn có thể chuyển một quảng bá tới các ứng dụng khác bằng cách chuyển một {@link android.content.Intent}
+tới {@link android.content.Context#sendBroadcast(Intent) sendBroadcast()},
+{@link android.content.Context#sendOrderedBroadcast(Intent, String)
+sendOrderedBroadcast()}, hoặc {@link
+android.content.Context#sendStickyBroadcast sendStickyBroadcast()}.</p>
+</li>
+</ul>
+
+
+
+
+<h2 id="Types">Các Loại Ý định</h2>
+
+<p>Có hai loại ý định:</p>
+
+<ul>
+<li><b>Ý định biểu thị</b> quy định thành phần cần bắt đầu theo tên (tên lớp hoàn toàn đạt tiêu chuẩn
+). Thường bạn sẽ sử dụng một ý định biểu thị để bắt đầu một thành phần trong
+ứng dụng của chính mình, vì bạn biết tên lớp của hoạt động hay dịch vụ mà mình muốn bắt đầu. Ví dụ
+, bắt đầu một hoạt động mới để hồi đáp một hành động của người dùng hay bắt đầu một dịch vụ để tải xuống
+tệp dưới nền.</li>
+
+<li><b>Ý định không biểu thị</b> không chỉ định một thành phần cụ thể mà thay vào đó, sẽ khai báo một hành động thông thường
+cần thực hiện, cho phép một thành phần từ một ứng dụng khác xử lý nó. Ví dụ, nếu bạn muốn
+hiển thị cho người dùng một vị trí trên bản đồ, bạn có thể sử dụng một ý định không biểu thị để yêu cầu một ứng dụng
+có khả năng khác hiển thị một vị trí được chỉ định trên bản đồ.</li>
+</ul>
+
+<p>Khi bạn tạo một ý định biểu thị để bắt đầu một hoạt động hoặc dịch vụ, hệ thống ngay lập tức
+sẽ bắt đầu thành phần ứng dụng được quy định trong đối tượng {@link android.content.Intent}.</p>
+
+<div class="figure" style="width:446px">
+<img src="{@docRoot}images/components/intent-filters@2x.png" width="446" alt="" />
+<p class="img-caption"><strong>Hình 1.</strong> Minh họa về cách một ý định không biểu thị được
+chuyển thông qua hệ thống để bắt đầu một hoạt động khác: <b>[1]</b> <em>Hoạt động A</em> tạo một
+{@link android.content.Intent} bằng một mô tả hành động và chuyển nó cho {@link
+android.content.Context#startActivity startActivity()}. <b>[2]</b> Hệ thống Android tìm kiếm tất cả
+ứng dụng xem có một bộ lọc ý định khớp với ý định đó không. Khi tìm thấy kết quả khớp, <b>[3]</b> hệ thống
+sẽ bắt đầu hoạt động so khớp đó (<em>Hoạt động B</em>) bằng cách gọi ra phương pháp {@link
+android.app.Activity#onCreate onCreate()} và chuyển nó cho {@link android.content.Intent}.
+</p>
+</div>
+
+<p>Khi bạn tạo một ý định không biểu thị, hệ thống Android sẽ tìm kiếm thành phần phù hợp để bắt đầu
+bằng cách so sánh nội dung của ý định với các <em>bộ lọc ý định</em> được khai báo trong <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">tệp bản kê khai</a> của các ứng dụng khác trên
+thiết bị. Nếu ý định khớp với một bộ lọc ý định, hệ thống sẽ bắt đầu thành phần đó và chuyển cho nó
+đối tượng {@link android.content.Intent}. Nếu có nhiều bộ lọc ý định tương thích, hệ thống
+sẽ hiển thị một hộp thoại để người dùng có thể chọn ứng dụng sẽ sử dụng.</p>
+
+<p>Bộ lọc ý định là một biểu thức trong tệp bản kê khai của một ứng dụng, có chức năng
+chỉ định loại ý định mà thành phần
+muốn nhận. Ví dụ, bằng cách khai báo một bộ lọc ý định cho một hoạt động,
+bạn giúp các ứng dụng khác có thể trực tiếp bắt đầu hoạt động của mình với một loại ý định nhất định.
+Tương tự, nếu bạn <em>không</em> khai báo bất kỳ bộ lọc ý định nào cho một hoạt động, khi đó nó chỉ có thể
+được bắt đầu bằng một ý định biểu thị.</p>
+
+<p class="caution"><strong>Chú ý:</strong> Để đảm bảo ứng dụng của bạn được bảo mật, luôn sử dụng một ý định
+biểu thị khi bắt đầu một {@link android.app.Service} và không được
+khai báo bộ lọc ý định cho các dịch vụ của bạn. Việc sử dụng một ý định không biểu thị để bắt đầu một dịch vụ sẽ là một nguy cơ
+về bảo mật vì bạn không thể chắc chắn dịch vụ nào sẽ hồi đáp ý định đó,
+và người dùng không thể thấy dịch vụ nào bắt đầu. Bắt đầu với Android 5.0 (API mức 21), hệ thống
+sẽ đưa ra lỗi ngoại lệ nếu bạn gọi {@link android.content.Context#bindService bindService()}
+bằng một ý định không biểu thị.</p>
+
+
+
+
+
+<h2 id="Building">Xây dựng một Ý định</h2>
+
+<p>Đối tượng {@link android.content.Intent} mang thông tin mà hệ thống Android sử dụng
+để xác định thành phần nào sẽ bắt đầu (chẳng hạn như tên thành phần chính xác hoặc thể loại
+thành phần mà sẽ nhận ý định), cộng với thông tin mà thành phần nhận sử dụng để
+thực hiện hành động cho phù hợp (chẳng hạn như hành động sẽ thực hiện và dữ liệu để dựa vào đó mà thực hiện).</p>
+
+
+<p>Thông tin chính chứa trong một {@link android.content.Intent} như sau:</p>
+
+<dl>
+
+<dt><b>Tên thành phần</b></dt>
+<dd>Tên của thành phần sẽ bắt đầu.
+
+<p>Nội dung này không bắt buộc, nhưng đó là một thông tin trọng yếu để khiến một ý định trở nên
+<b>biểu thị</b>, có nghĩa là ý định nên chỉ được chuyển tới thành phần ứng dụng
+được xác định bởi tên thành phần đó. Nếu thiếu một tên thành phần, ý định trở thành <b>không biểu thị</b> và hệ thống
+sẽ quyết định thành phần nào nhận ý định đó dựa trên các thông tin còn lại của ý định
+(chẳng hạn như hành động, dữ liệu và thể loại&mdash;được mô tả bên dưới). Vì vậy, nếu bạn bắt đầu một thành phần
+cụ thể trong ứng dụng của mình, bạn nên chỉ định tên thành phần.</p>
+
+<p class="note"><strong>Lưu ý:</strong> Khi bắt đầu một {@link android.app.Service}, bạn nên
+<strong>luôn chỉ định tên thành phần</strong>. Nếu không, bạn không thể chắc chắn dịch vụ nào
+sẽ hồi đáp ý định và người dùng không thể thấy dịch vụ nào bắt đầu.</p>
+
+<p>Trường này của {@link android.content.Intent} là một đối tượng
+{@link android.content.ComponentName} mà bạn có thể chỉ định bằng cách sử dụng một tên lớp
+hoàn toàn đủ tiêu chuẩn của thành phần đích, bao gồm tên gói của ứng dụng. Ví dụ,
+{@code com.example.ExampleActivity}. Bạn có thể đặt tên thành phần bằng {@link
+android.content.Intent#setComponent setComponent()}, {@link android.content.Intent#setClass
+setClass()}, {@link android.content.Intent#setClassName(String, String) setClassName()}, hoặc bằng
+ hàm dựng {@link android.content.Intent}.</p>
+
+</dd>
+
+<p><dt><b>Hành động</b></dt>
+<dd>Một xâu quy định hành động thông thường sẽ thực hiện (chẳng hạn như <em>xem</em> hoặc <em>chọn</em>).
+
+<p>Trong trường hợp một ý định quảng bá, đây là hành động đã diễn ra và đang được báo cáo.
+Hành động này quyết định phần lớn cách thức xác định cấu trúc phần còn lại của ý định&mdash;đặc biệt là
+những gì chứa trong dữ liệu và phụ thêm.
+
+<p>Bạn có thể quy định các hành động của chính mình để các ý định bên trong ứng dụng của bạn sử dụng (hoặc để
+các ứng dụng khác sử dụng nhằm gọi ra các thành phần trong ứng dụng của mình), nhưng bạn nên thường xuyên sử dụng hằng số hành động
+được định nghĩa bởi lớp {@link android.content.Intent} hoặc các lớp khuôn khổ khác. Sau đây là một số
+hành động thường dùng để bắt đầu một hoạt động:</p>
+
+<dl>
+<dt>{@link android.content.Intent#ACTION_VIEW}</dt>
+ <dd>Sử dụng hành động này trong một ý định với {@link
+ android.content.Context#startActivity startActivity()} khi bạn có một số thông tin mà
+ một hoạt động có thể hiển thị cho người dùng, chẳng hạn như ảnh để xem trong một ứng dụng bộ sưu tập ảnh, hay địa chỉ để
+ xem trong ứng dụng bản đồ.</dd>
+
+<dt>{@link android.content.Intent#ACTION_SEND}</dt>
+ <dd>Còn được biết đến như là ý định "chia sẻ", bạn nên sử dụng kiểu này trong một ý định với {@link
+ android.content.Context#startActivity startActivity()} khi bạn có một số dữ liệu mà người dùng có thể
+ chia sẻ thông qua một ứng dụng khác, chẳng hạn như một ứng dụng e-mail hay ứng dụng chia sẻ mạng xã hội.</dd>
+</dl>
+
+<p>Xem tham chiếu lớp {@link android.content.Intent} để biết thêm
+hằng số có chức năng định nghĩa các hành động thông thường. Những hành động khác được định nghĩa
+ở phần khác trong khuôn khổ Android, chẳng hạn như trong {@link android.provider.Settings} đối với những hành động
+có chức năng mở màn hình cụ thể trong ứng dụng Cài đặt của hệ thống.</p>
+
+<p>Bạn có thể quy định hành động cho một ý định với {@link android.content.Intent#setAction
+setAction()} hoặc với một hàm dựng {@link android.content.Intent}.</p>
+
+<p>Nếu bạn định nghĩa các hành động của chính mình, nhớ nêu tên gói ứng dụng của bạn
+làm tiền tố. Ví dụ:</p>
+<pre>static final String ACTION_TIMETRAVEL = "com.example.action.TIMETRAVEL";</pre>
+</dd>
+
+<dt><b>Dữ liệu</b></dt>
+<dd>URI (một đối tượng {@link android.net.Uri}) tham chiếu dữ liệu sẽ được hành động dựa trên nó và/hoặc kiểu MIME
+của dữ liệu đó. Kiểu dữ liệu được cung cấp thường sẽ bị chi phối bởi hành động của ý định. Ví
+dụ, nếu hành động là {@link android.content.Intent#ACTION_EDIT}, dữ liệu cần chứa
+URI của tài liệu cần chỉnh sửa.
+
+<p>Khi tạo một ý định,
+một điều thường quan trọng đó là quy định kiểu dữ liệu (kiểu MIME của nó) ngoài URI của nó.
+Ví dụ, một hoạt động có thể hiển thị hình ảnh có thể sẽ không
+phát được tệp âm thanh, ngay cả khi định dạng URI có thể tương tự.
+Vì thế, việc quy định kiểu MIME cho dữ liệu của bạn sẽ giúp hệ thống
+Android tìm được thành phần tốt nhất để nhận ý định của bạn.
+Tuy nhiên, kiểu MIME đôi khi có thể được suy ra từ URI&mdash;cụ thể, khi dữ liệu là một URI
+{@code content:}, có chức năng cho biết dữ liệu nằm trên thiết bị và được kiểm soát bởi một
+{@link android.content.ContentProvider}, điều này khiến kiểu MIME của dữ liệu hiển thị đối với hệ thống.</p>
+
+<p>Để chỉ đặt URI dữ liệu, hãy gọi {@link android.content.Intent#setData setData()}.
+Để chỉ đặt kiểu MIME, hãy gọi {@link android.content.Intent#setType setType()}. Nếu cần, bạn
+bạn có thể công khai đặt cả hai với {@link
+android.content.Intent#setDataAndType setDataAndType()}.</p>
+
+<p class="caution"><strong>Chú ý:</strong> Nếu bạn muốn đặt cả URI và kiểu MIME,
+<strong>không</strong> gọi {@link android.content.Intent#setData setData()} và
+{@link android.content.Intent#setType setType()} vì chúng sẽ vô hiệu hóa giá trị của nhau.
+Luôn sử dụng {@link android.content.Intent#setDataAndType setDataAndType()} để đặt cả
+URI và kiểu MIME.</p>
+</dd>
+
+<p><dt><b>Thể loại</b></dt>
+<dd>Một xâu chứa thông tin bổ sung về kiểu thành phần
+sẽ xử lý ý định. Trong một ý định có thể chứa
+nhiều mô tả thể loại, nhưng hầu hết các ý định lại không yêu cầu thể loại.
+Sau đây là một số thể loại thường gặp:
+
+<dl>
+<dt>{@link android.content.Intent#CATEGORY_BROWSABLE}</dt>
+ <dd>Hoạt động mục tiêu cho phép chính nó được bắt đầu bởi một trình duyệt web để hiển thị dữ liệu
+ được một liên kết tham chiếu&mdash;chẳng hạn như một hình ảnh hay thư e-mail.
+ </dd>
+<dt>{@link android.content.Intent#CATEGORY_LAUNCHER}</dt>
+ <dd>Hoạt động là hoạt động ban đầu của một tác vụ và được liệt kê trong
+ trình khởi chạy ứng dụng của hệ thống.
+ </dd>
+</dl>
+
+<p>Xem mô tả lớp {@link android.content.Intent} để biết danh sách đầy đủ về các
+thể loại.</p>
+
+<p>Bạn có thể quy định một thể loại bằng {@link android.content.Intent#addCategory addCategory()}.</p>
+</dd>
+</dl>
+
+
+<p>Những tính chất này được liệt kê ở trên (tên thành phần, hành động, dữ liệu và thể loại) biểu hiện các
+đặc điểm xác định của một ý định. Bằng cách đọc những tính chất này, hệ thống Android
+có thể quyết định nó sẽ bắt đầu thành phần ứng dụng nào.</p>
+
+<p>Tuy nhiên, một ý định có thể mang thông tin bổ sung không ảnh hưởng tới
+cách nó được giải quyết đối với một thành phần ứng dụng. Một ý định cũng có thể cung cấp:</p>
+
+<dl>
+<dt><b>Phụ thêm</b></dt>
+<dd>Các cặp khóa-giá trị mang thông tin bổ sung cần thiết để hoàn thành hành động được yêu cầu.
+Giống như việc một số hành động sử dụng các kiểu URI dữ liệu riêng, một số hành động cũng sử dụng các phần phụ thêm riêng.
+
+<p>Bạn có thể thêm dữ liệu phụ thêm bằng các phương pháp {@link android.content.Intent#putExtra putExtra()} khác nhau,
+mỗi phương pháp chấp nhận hai tham số: tên khóa và giá trị.
+Bạn cũng có thể tạo một đối tượng {@link android.os.Bundle} bằng tất cả dữ liệu phụ thêm, sau đó chèn
+ {@link android.os.Bundle} vào {@link android.content.Intent} bằng {@link
+android.content.Intent#putExtras putExtras()}.</p>
+
+<p>Ví dụ, khi tạo một ý định để gửi một e-mail bằng
+{@link android.content.Intent#ACTION_SEND}, bạn có thể chỉ định người nhận "tới" bằng khóa
+{@link android.content.Intent#EXTRA_EMAIL}, và chỉ định "chủ đề" bằng khóa
+{@link android.content.Intent#EXTRA_SUBJECT}.</p>
+
+<p>Lớp {@link android.content.Intent} quy định nhiều hằng số {@code EXTRA_*} cho
+các kiểu dữ liệu chuẩn hóa. Nếu bạn cần khai báo các khóa phụ thêm của riêng mình (cho những ý định
+mà ứng dụng của bạn nhận), hãy chắc chắn nêu tên gói ứng dụng của bạn
+làm tiền tố. Ví dụ:</p>
+<pre>static final String EXTRA_GIGAWATTS = "com.example.EXTRA_GIGAWATTS";</pre>
+</dd>
+
+<dt><b>Cờ</b></dt>
+<dd>Cờ được định nghĩa trong lớp {@link android.content.Intent} có chức năng như siêu dữ liệu cho
+ý định. Cờ có thể chỉ lệnh hệ thống Android về cách khởi chạy một hoạt động (ví dụ, hoạt động sẽ thuộc về
+<a href="{@docRoot}guide/components/tasks-and-back-stack.html">tác vụ</a> nào
+) và cách xử lý sau khi nó được khởi chạy (ví dụ, nó có thuộc về danh sách hoạt động
+gần đây hay không).
+
+<p>Để biết thêm thông tin, hãy xem phương pháp {@link android.content.Intent#setFlags setFlags()}.</p>
+</dd>
+
+</dl>
+
+
+
+
+<h3 id="ExampleExplicit">Ví dụ về ý định biểu thị</h3>
+
+<p>Ý định biểu thị là ý định mà bạn sử dụng để khởi chạy một thành phần ứng dụng cụ thể
+chẳng hạn như một hoạt động hay dịch vụ cụ thể trong ứng dụng của bạn. Để tạo một ý định biểu thị, hãy định nghĩa
+tên thành phần cho đối tượng {@link android.content.Intent} &mdash;tất cả các
+tính chất ý định khác đều không bắt buộc.</p>
+
+<p>Ví dụ, nếu bạn đã xây dựng một dịch vụ trong ứng dụng của mình, đặt tên là {@code DownloadService},
+được thiết kế để tải xuống một tệp từ web, bạn có thể bắt đầu nó bằng mã sau:</p>
+
+<pre>
+// Executed in an Activity, so 'this' is the {@link android.content.Context}
+// The fileUrl is a string URL, such as "http://www.example.com/image.png"
+Intent downloadIntent = new Intent(this, DownloadService.class);
+downloadIntent.setData({@link android.net.Uri#parse Uri.parse}(fileUrl));
+startService(downloadIntent);
+</pre>
+
+<p>Hàm dựng {@link android.content.Intent#Intent(Context,Class)}
+cung cấp cho ứng dụng {@link android.content.Context} và thành phần
+một đối tượng {@link java.lang.Class}. Như vậy,
+ý định này rõ ràng sẽ bắt đầu lớp {@code DownloadService} trong ứng dụng.</p>
+
+<p>Để biết thêm thông tin về việc xây dựng và bắt đầu một dịch vụ, hãy xem hướng dẫn
+<a href="{@docRoot}guide/components/services.html">Dịch vụ</a>.</p>
+
+
+
+
+<h3 id="ExampleSend">Ví dụ về ý định không biểu thị</h3>
+
+<p>Ý định không biểu thị quy định một hành động mà có thể gọi ra bất kỳ ứng dụng nào trên thiết bị mà có
+khả năng thực hiện hành động đó. Việc sử dụng ý định không biểu thị có ích khi ứng dụng của bạn không thể thực hiện
+hành động, nhưng các ứng dụng khác có thể và bạn muốn người dùng chọn ứng dụng sẽ sử dụng.</p>
+
+<p>Ví dụ, nếu bạn có nội dung mà mình muốn người dùng chia sẻ với người khác, hãy tạo một ý định
+với hành động {@link android.content.Intent#ACTION_SEND} và
+bổ sung phần phụ thêm quy định nội dung sẽ chia sẻ. Khi bạn gọi
+{@link android.content.Context#startActivity startActivity()} bằng ý định đó, người dùng có thể
+chọn một ứng dụng để chia sẻ nội dung thông qua đó.</p>
+
+<p class="caution"><strong>Chú ý:</strong> Có thể là người dùng sẽ không có <em>bất kỳ</em>
+ứng dụng nào xử lý được ý định không biểu thị mà bạn gửi tới {@link android.content.Context#startActivity
+startActivity()}. Nếu chuyện đó xảy ra, phương pháp gọi sẽ thất bại và ứng dụng của bạn sẽ gặp lỗi. Để xác minh rằng
+một hoạt động sẽ nhận được ý định, hãy gọi {@link android.content.Intent#resolveActivity
+resolveActivity()} trên đối tượng {@link android.content.Intent} của bạn. Nếu kết quả không rỗng
+thì có ít nhất một ứng dụng có thể xử lý ý định và sẽ an toàn nếu gọi
+{@link android.content.Context#startActivity startActivity()}. Nếu kết quả rỗng,
+bạn không nên sử dụng ý định và, nếu có thể, bạn nên vô hiệu hóa tính năng phát hành
+ý định.</p>
+
+
+<pre>
+// Create the text message with a string
+Intent sendIntent = new Intent();
+sendIntent.setAction(Intent.ACTION_SEND);
+sendIntent.putExtra(Intent.EXTRA_TEXT, textMessage);
+sendIntent.setType({@link
+ org.apache.http.protocol.HTTP#PLAIN_TEXT_TYPE
+ HTTP.PLAIN_TEXT_TYPE}); // "text/plain" MIME type
+
+// Verify that the intent will resolve to an activity
+if (sendIntent.resolveActivity(getPackageManager()) != null) {
+ startActivity(sendIntent);
+}
+</pre>
+
+<p class="note"><strong>Lưu ý:</strong> Trong trường hợp này, URI không được sử dụng, nhưng kiểu dữ liệu của ý định
+sẽ được khai báo để quy định nội dung được thực hiện bởi phần phụ thêm.</p>
+
+
+<p>Khi {@link android.content.Context#startActivity startActivity()} được gọi, hệ thống
+sẽ kiểm tra tất cả ứng dụng đã cài đặt để xác định những ứng dụng có thể xử lý kiểu ý định này (một
+ý định với hành động {@link android.content.Intent#ACTION_SEND} và có mang dữ liệu
+"văn bản/thuần"). Nếu chỉ có một ứng dụng có thể xử lý nó, ứng dụng đó sẽ mở ngay lập tức và được cấp cho
+ý định. Nếu có nhiều hoạt động chấp nhận ý định, hệ thống
+sẽ hiển thị một hộp thoại để người dùng có thể chọn ứng dụng sẽ sử dụng.</p>
+
+
+<div class="figure" style="width:200px">
+ <img src="{@docRoot}images/training/basics/intent-chooser.png" alt="">
+ <p class="img-caption"><strong>Hình 2.</strong> Hộp thoại bộ chọn.</p>
+</div>
+
+<h3 id="ForceChooser">Bắt buộc một bộ chọn ứng dụng</h3>
+
+<p>Khi có nhiều hơn một ứng dụng hồi đáp ý định không biểu thị của bạn,
+người dùng có thể chọn ứng dụng nào sẽ sử dụng và đặt ứng dụng đó làm lựa chọn mặc định cho
+hành động. Điều này tốt khi thực hiện một hành động mà người dùng
+có thể muốn sử dụng ứng dụng tương tự từ lúc này trở đi, chẳng hạn như khi mở một trang web (người dùng
+thường thích ưu tiên sử dụng chỉ một trình duyệt web).</p>
+
+<p>Tuy nhiên, nếu nhiều ứng dụng có thể hồi đáp ý định và người dùng có thể muốn sử dụng mỗi
+lần một ứng dụng khác, bạn nên công khai hiển thị một hộp thoại bộ chọn. Hộp thoại bộ chọn yêu cầu
+người dùng phải chọn ứng dụng sẽ sử dụng mỗi lần cho hành động (người dùng không thể chọn một ứng dụng mặc định cho
+hành động). Ví dụ, khi ứng dụng của bạn thực hiện "chia sẻ" với hành động {@link
+android.content.Intent#ACTION_SEND}, người dùng có thể muốn chia sẻ bằng cách sử dụng một ứng dụng khác tùy vào
+tình hình thực tế của họ, vì thế bạn nên luôn sử dụng hộp thoại bộ chọn như minh họa trong hình 2.</p>
+
+
+
+
+<p>Để hiển thị bộ chọn, hãy tạo một {@link android.content.Intent} bằng cách sử dụng {@link
+android.content.Intent#createChooser createChooser()} và chuyển nó sang {@link
+android.app.Activity#startActivity startActivity()}. Ví dụ:</p>
+
+<pre>
+Intent sendIntent = new Intent(Intent.ACTION_SEND);
+...
+
+// Always use string resources for UI text.
+// This says something like "Share this photo with"
+String title = getResources().getString(R.string.chooser_title);
+// Create intent to show the chooser dialog
+Intent chooser = Intent.createChooser(sendIntent, title);
+
+// Verify the original intent will resolve to at least one activity
+if (sendIntent.resolveActivity(getPackageManager()) != null) {
+ startActivity(chooser);
+}
+</pre>
+
+<p>Một hộp thoại hiển thị với một danh sách ứng dụng hồi đáp lại ý định được chuyển sang phương pháp {@link
+android.content.Intent#createChooser createChooser()} và sử dụng văn bản được cung cấp làm
+tiêu đề của hộp thoại.</p>
+
+
+
+
+
+
+
+
+
+<h2 id="Receiving">Nhận một Ý định Không biểu thị</h2>
+
+<p>Để quảng cáo những ý định không biểu thị mà ứng dụng của bạn có thể nhận, hãy khai báo một hoặc nhiều bộ lọc ý định cho
+từng thành phần ứng dụng của bạn với một phần tử <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code &lt;intent-filter&gt;}</a>
+trong <a href="{@docRoot}guide/topics/manifest/manifest-intro.html">tệp bản kê khai của mình</a>.
+Mỗi bộ lọc ý định sẽ quy định loại ý định mà nó chấp nhận dựa trên hành động,
+dữ liệu và thể loại của ý định. Hệ thống sẽ chỉ chuyển một ý định không biểu thị tới thành phần ứng dụng của bạn nếu
+ý định đó có thể chuyển qua một trong các bộ lọc ý định của bạn.</p>
+
+<p class="note"><strong>Lưu ý:</strong> Ý định biểu thị luôn được chuyển tới mục tiêu của mình,
+không phụ thuộc vào bất kỳ bộ lọc ý định nào mà thành phần khai báo.</p>
+
+<p>Một thành phần ứng dụng nên khai báo các bộ lọc riêng cho từng công việc duy nhất mà nó có thể thực hiện.
+Ví dụ, một hoạt động trong một ứng dụng bộ sưu tập ảnh có thể có hai bộ lọc: một bộ lọc
+để xem một hình ảnh và một bộ lọc để chỉnh sửa một hình ảnh. Khi hoạt động bắt đầu,
+nó sẽ kiểm tra {@link android.content.Intent} và quyết định cách xử lý dựa trên thông tin
+trong {@link android.content.Intent} (chẳng hạn như có hiển thị các điều khiển của trình chỉnh sửa hoặc không).</p>
+
+<p>Mỗi bộ lọc ý định sẽ được định nghĩa bởi một phần tử <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code &lt;intent-filter&gt;}</a>
+trong tệp bản kê khai của ứng dụng, được lồng trong thành phần ứng dụng tương ứng (chẳng hạn như
+một phần tử <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a>
+). Bên trong <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">{@code &lt;intent-filter&gt;}</a>,
+bạn có thể quy định loại ý định sẽ chấp nhận bằng cách sử dụng một hoặc nhiều
+phần tử trong ba phần tử sau:</p>
+
+<dl>
+<dt><a href="{@docRoot}guide/topics/manifest/action-element.html">{@code &lt;action&gt;}</a></dt>
+ <dd>Khai báo hành động ý định được chấp nhận, trong thuộc tính {@code name}. Giá trị
+ phải là giá trị xâu ký tự của một hành động chứ không phải hằng số lớp.</dd>
+<dt><a href="{@docRoot}guide/topics/manifest/data-element.html">{@code &lt;data&gt;}</a></dt>
+ <dd>Khai báo kiểu dữ liệu được chấp nhận, bằng cách sử dụng một hoặc nhiều thuộc tính quy định
+ các khía cạnh của URI dữ liệu (<code>scheme</code>, <code>host</code>, <code>port</code>,
+ <code>path</code>, v.v.) và kiểu MIME.</dd>
+<dt><a href="{@docRoot}guide/topics/manifest/category-element.html">{@code &lt;category&gt;}</a></dt>
+ <dd>Khai báo thể loại ý định được chấp nhận, trong thuộc tính {@code name}. Giá trị
+ phải là giá trị xâu ký tự của một hành động chứ không phải hằng số lớp.
+
+ <p class="note"><strong>Lưu ý:</strong> Để nhận các ý định không biểu thị, bạn
+ <strong>phải nêu</strong> thể loại
+ {@link android.content.Intent#CATEGORY_DEFAULT} trong bộ lọc ý định. Các phương pháp
+ {@link android.app.Activity#startActivity startActivity()} và
+ {@link android.app.Activity#startActivityForResult startActivityForResult()} xử lý tất cả ý định
+ như thể chúng khai báo thể loại {@link android.content.Intent#CATEGORY_DEFAULT}.
+ Nếu bạn không khai báo thể loại này trong bộ lọc ý định của mình, không có ý định không biểu thị nào sẽ phân giải thành
+ hoạt động của bạn.</p>
+ </dd>
+</dl>
+
+<p>Ví dụ, sau đây là một khai báo hoạt động với một bộ lọc ý định để nhận một ý định
+{@link android.content.Intent#ACTION_SEND} khi kiểu dữ liệu là văn bản:</p>
+
+<pre>
+&lt;activity android:name="ShareActivity">
+ &lt;intent-filter>
+ &lt;action android:name="android.intent.action.SEND"/>
+ &lt;category android:name="android.intent.category.DEFAULT"/>
+ &lt;data android:mimeType="text/plain"/>
+ &lt;/intent-filter>
+&lt;/activity>
+</pre>
+
+<p>Không sao nếu tạo một bộ lọc chứa nhiều hơn một thực thể của
+<a href="{@docRoot}guide/topics/manifest/action-element.html">{@code &lt;action&gt;}</a>,
+<a href="{@docRoot}guide/topics/manifest/data-element.html">{@code &lt;data&gt;}</a>, hoặc
+<a href="{@docRoot}guide/topics/manifest/category-element.html">{@code &lt;category&gt;}</a>.
+Nếu làm vậy, bạn chỉ cần chắc chắn rằng thành phần có thể xử lý bất kỳ và tất cả các cách kết hợp
+những phần tử bộ lọc đó.</p>
+
+<p>Khi bạn muốn xử lý nhiều kiểu ý định, nhưng chỉ theo các cách kết hợp cụ thể giữa
+hành động, dữ liệu và kiểu thể loại, khi đó bạn cần tạo nhiều bộ lọc ý định.</p>
+
+
+<div class="sidebox-wrapper">
+<div class="sidebox">
+<h2>Hạn chế truy cập vào các thành phần</h2>
+<p>Sử dụng một bộ lọc ý định không phải là một cách bảo mật để ngăn các ứng dụng khác bắt đầu
+các thành phần của bạn. Mặc dù bộ lọc ý định hạn chế một thành phần chỉ hồi đáp
+một số kiểu ý định không biểu thị nhất định, một ứng dụng khác có thể có khả năng bắt đầu thành phần ứng dụng của bạn
+bằng cách sử dụng ý định biểu thị nếu nhà phát triển xác định tên thành phần của bạn.
+Nếu điều quan trọng là <em>chỉ ứng dụng của chính bạn</em> mới có thể bắt đầu một trong các thành phần của bạn,
+hãy đặt thuộc tính <a href="{@docRoot}guide/topics/manifest/activity-element.html#exported">{@code
+exported}</a> thành {@code "false"} cho thành phần đó.
+</p>
+</div>
+</div>
+
+<p>Ý định không biểu thị sẽ được kiểm tra dựa trên một bộ lọc bằng cách so sánh ý định với từng phần tử trong số
+ba phần tử. Để được chuyển tới thành phần, ý định phải vượt qua tất cả ba lần kiểm tra.
+Nếu không khớp với thậm chí chỉ một lần thì hệ thống Android sẽ không chuyển ý định tới
+thành phần. Tuy nhiên, vì một thành phần có thể có nhiều bộ lọc ý định, ý định mà không chuyển qua
+một trong các bộ lọc của thành phần có thể chuyển qua trên một bộ lọc khác.
+Bạn có thể tìm hiểu thêm thông tin về cách hệ thống giải quyết ý định trong phần bên dưới
+về <a href="#Resolution">Giải quyết Ý định</a>.</p>
+
+<p class="caution"><strong>Chú ý:</strong> Để tránh vô ý chạy
+{@link android.app.Service} của một ứng dụng khác, hãy luôn sử dụng một ý định biểu thị để bắt đầu dịch vụ của chính bạn và không được
+khai báo các bộ lọc ý định cho dịch vụ của bạn.</p>
+
+<p class="note"><strong>Lưu ý:</strong>
+Đối với tất cả hoạt động, bạn phải khai báo các bộ lọc ý định của mình trong một tệp bản kê khai.
+Tuy nhiên, các bộ lọc cho hàm nhận quảng bá có thể được đăng ký linh hoạt bằng cách gọi
+{@link android.content.Context#registerReceiver(BroadcastReceiver, IntentFilter, String,
+Handler) registerReceiver()}. Sau đó, bạn có thể bỏ đăng ký hàm nhận đó bằng {@link
+android.content.Context#unregisterReceiver unregisterReceiver()}. Làm vậy sẽ cho phép ứng dụng của bạn
+lắng nghe các quảng bá cụ thể chỉ trong một khoảng thời gian xác định trong khi ứng dụng của bạn
+đang chạy.</p>
+
+
+
+
+
+
+
+<h3 id="ExampleFilters">Ví dụ về bộ lọc</h3>
+
+<p>Để hiểu hơn về một số hành vi của bộ lọc ý định, hãy xem đoạn mã HTML sau
+từ tệp bản kê khai của một ứng dụng chia sẻ mạng xã hội.</p>
+
+<pre>
+&lt;activity android:name="MainActivity">
+ &lt;!-- This activity is the main entry, should appear in app launcher -->
+ &lt;intent-filter>
+ &lt;action android:name="android.intent.action.MAIN" />
+ &lt;category android:name="android.intent.category.LAUNCHER" />
+ &lt;/intent-filter>
+&lt;/activity>
+
+&lt;activity android:name="ShareActivity">
+ &lt;!-- This activity handles "SEND" actions with text data -->
+ &lt;intent-filter&gt;
+ &lt;action android:name="android.intent.action.SEND"/>
+ &lt;category android:name="android.intent.category.DEFAULT"/>
+ &lt;data android:mimeType="text/plain"/>
+ &lt;/intent-filter&gt;
+ &lt;!-- This activity also handles "SEND" and "SEND_MULTIPLE" with media data -->
+ &lt;intent-filter&gt;
+ &lt;action android:name="android.intent.action.SEND"/>
+ &lt;action android:name="android.intent.action.SEND_MULTIPLE"/>
+ &lt;category android:name="android.intent.category.DEFAULT"/>
+ &lt;data android:mimeType="application/vnd.google.panorama360+jpg"/>
+ &lt;data android:mimeType="image/*"/>
+ &lt;data android:mimeType="video/*"/>
+ &lt;/intent-filter&gt;
+&lt;/activity&gt;
+</pre>
+
+<p>Hoạt động thứ nhất, {@code MainActivity}, là điểm mục nhập chính của ứng dụng&mdash;hoạt động này
+sẽ mở khi người dùng khởi tạo ban đầu ứng dụng bằng biểu tượng trình khởi chạy:</p>
+<ul>
+ <li>Hành động {@link android.content.Intent#ACTION_MAIN} thể hiện
+ đây là điểm mục nhập chính và không yêu cầu bất kỳ dữ liệu ý định nào.</li>
+ <li>Thể loại {@link android.content.Intent#CATEGORY_LAUNCHER} cho biết rằng biểu tượng
+ của hoạt động này nên được đặt trong trình khởi chạy ứng dụng của hệ thống. Nếu phần tử <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a>
+ không quy định một biểu tượng bằng {@code icon}, khi đó hệ thống sẽ sử dụng biểu tượng từ phần tử <a href="{@docRoot}guide/topics/manifest/application-element.html">{@code &lt;application&gt;}</a>
+.</li>
+</ul>
+<p>Hai nội dung này phải được ghép đôi cùng nhau để hoạt động xuất hiện trong trình khởi chạy ứng dụng.</p>
+
+<p>Hoạt động thứ hai, {@code ShareActivity}, có mục đích để tạo điều kiện chia sẻ nội dung văn bản và
+phương tiện. Mặc dù người dùng có thể nhập hoạt động này bằng cách điều hướng tới nó từ {@code MainActivity},
+họ cũng có thể nhập {@code ShareActivity} trực tiếp từ một ứng dụng khác mà phát hành
+ý định không biểu thị khớp với một trong hai bộ lọc ý định.</p>
+
+<p class="note"><strong>Lưu ý:</strong> Kiểu MIME,
+<a href="https://developers.google.com/panorama/android/">{@code
+application/vnd.google.panorama360+jpg}</a>, là một kiểu dữ liệu đặc biệt quy định
+ảnh chụp toàn cảnh mà bạn có thể xử lý bằng các API <a href="{@docRoot}reference/com/google/android/gms/panorama/package-summary.html">Google
+panorama</a>.</p>
+
+
+
+
+
+
+
+
+
+
+
+
+
+<h2 id="PendingIntent">Sử dụng một Ý định Chờ</h2>
+
+<p>Đối tượng {@link android.app.PendingIntent} là một trình bao bọc xung quanh một đối tượng {@link
+android.content.Intent}. Mục đích chính của một {@link android.app.PendingIntent}
+ là cấp quyền cho một ứng dụng ngoài
+để sử dụng {@link android.content.Intent} chứa trong nó như thể nó được thực thi từ tiến trình
+của chính ứng dụng của bạn.</p>
+
+<p>Các trường hợp sử dụng chính đối với một ý định chờ bao gồm:</p>
+<ul>
+ <li>Khai báo một ý định cần được thực thi khi người dùng thực hiện một hành động bằng <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Thông báo</a> của bạn
+ ({@link android.app.NotificationManager}
+ của hệ thống Android thực thi {@link android.content.Intent}).
+ <li>Khai báo một ý định cần được thực thi khi người dùng thực hiện một hành động bằng
+ <a href="{@docRoot}guide/topics/appwidgets/index.html">App Widget</a> của bạn
+ (ứng dụng màn hình Trang chủ thực thi {@link android.content.Intent}).
+ <li>Khai báo một ý định cần được thực thi tại một thời điểm xác định trong tương lai (
+{@link android.app.AlarmManager} của hệ thống Android thực thi {@link android.content.Intent}).
+</ul>
+
+<p>Vì mỗi đối tượng {@link android.content.Intent} được thiết kế để được xử lý bởi một
+loại thành phần ứng dụng cụ thể (hoặc là {@link android.app.Activity}, {@link android.app.Service}, hay
+ {@link android.content.BroadcastReceiver}), vì thế {@link android.app.PendingIntent} cũng
+phải được tạo lập với cân nhắc tương tự. Khi sử dụng một ý định chờ, ứng dụng của bạn sẽ không
+thực thi ý định bằng một lệnh gọi chẳng hạn như {@link android.content.Context#startActivity
+startActivity()}. Thay vào đó, bạn phải khai báo loại thành phần theo ý định khi bạn tạo lập
+{@link android.app.PendingIntent} bằng cách gọi phương pháp trình tạo lập tương ứng:</p>
+
+<ul>
+ <li>{@link android.app.PendingIntent#getActivity PendingIntent.getActivity()} đối với một
+ {@link android.content.Intent} mà bắt đầu {@link android.app.Activity}.</li>
+ <li>{@link android.app.PendingIntent#getService PendingIntent.getService()} đối với một
+ {@link android.content.Intent} mà bắt đầu {@link android.app.Service}.</li>
+ <li>{@link android.app.PendingIntent#getBroadcast PendingIntent.getBroadcast()} đối với một
+ {@link android.content.Intent} mà bắt đầu {@link android.content.BroadcastReceiver}.</li>
+</ul>
+
+<p>Trừ khi ứng dụng của bạn đang <em>nhận</em> ý định chờ từ các ứng dụng khác,
+các phương pháp để tạo lập {@link android.app.PendingIntent} trên là những phương pháp
+{@link android.app.PendingIntent} duy nhất mà bạn sẽ cần.</p>
+
+<p>Mỗi phương pháp sẽ lấy ứng dụng {@link android.content.Context} hiện tại,
+{@link android.content.Intent} mà bạn muốn bao bọc, và một hoặc nhiều cờ quy định
+cách thức sử dụng ý định (chẳng hạn như ý định có thể được sử dụng nhiều hơn một lần hay không).</p>
+
+<p>Bạn có thể tham khảo thêm thông tin về việc sử dụng ý định chờ trong tài liệu cho từng
+trường hợp sử dụng tương ứng chẳng hạn như trong hướng dẫn về API <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Thông báo</a>
+và <a href="{@docRoot}guide/topics/appwidgets/index.html">App Widgets</a>.</p>
+
+
+
+
+
+
+
+<h2 id="Resolution">Giải quyết Ý định</h2>
+
+
+<p>Khi hệ thống nhận được một ý định không biểu thị nhằm bắt đầu một hoạt động, nó sẽ tìm
+hoạt động tốt nhất cho ý định đó bằng cách so sánh ý định với các bộ lọc ý định dựa trên ba phương diện:</p>
+
+<ul>
+ <li>Hành động của ý định
+ <li>Dữ liệu của ý định (cả URI và kiểu dữ liệu)
+ <li>Thể loại của ý định
+</ul>
+
+<p>Các phần sau mô tả cách một ý định được so khớp với (các) thành phần phù hợp
+về phương diện bộ lọc ý định được khai báo như thế nào trong tệp bản kê khai của một ứng dụng.</p>
+
+
+<h3 id="ActionTest">Kiểm tra hành động</h3>
+
+<p>Để quy định các hành động của ý định được chấp nhận, một bộ lọc ý định có thể khai báo 0 phần tử
+<a href="{@docRoot}guide/topics/manifest/action-element.html">{@code
+&lt;action&gt;}</a> hoặc nhiều hơn. Ví dụ:</p>
+
+<pre>
+&lt;intent-filter&gt;
+ &lt;action android:name="android.intent.action.EDIT" /&gt;
+ &lt;action android:name="android.intent.action.VIEW" /&gt;
+ ...
+&lt;/intent-filter&gt;
+</pre>
+
+<p>Để vượt qua bộ lọc này, hành động được quy định trong {@link android.content.Intent}
+ phải khớp với một trong các hành động được liệt kê trong bộ lọc.</p>
+
+<p>Nếu bộ lọc không liệt kê bất kỳ hành động nào thì sẽ không có gì để
+ý định so khớp, vì thế tất cả ý định sẽ không vượt qua kiểm tra. Tuy nhiên, nếu một {@link android.content.Intent}
+không quy định một hành động, nó sẽ vượt qua kiểm tra (miễn là bộ lọc
+chứa ít nhất một hành động).</p>
+
+
+
+<h3 id="CategoryTest">Kiểm tra thể loại</h3>
+
+<p>Để quy định các thể loại của ý định được chấp nhận, một bộ lọc ý định có thể khai báo 0 phần tử
+<a href="{@docRoot}guide/topics/manifest/category-element.html">{@code
+&lt;category&gt;}</a> hoặc nhiều hơn. Ví dụ:</p>
+
+<pre>
+&lt;intent-filter&gt;
+ &lt;category android:name="android.intent.category.DEFAULT" /&gt;
+ &lt;category android:name="android.intent.category.BROWSABLE" /&gt;
+ ...
+&lt;/intent-filter&gt;
+</pre>
+
+<p>Để một ý định vượt qua kiểm tra thể loại, mỗi thể loại trong {@link android.content.Intent}
+phải khớp với một thể loại trong bộ lọc. Trường hợp ngược lại là không cần thiết&mdash;bộ lọc ý định có thể
+khai báo nhiều thể loại hơn được quy định trong {@link android.content.Intent} và
+{@link android.content.Intent} sẽ vẫn vượt qua. Vì thế, ý định không có thể loại
+luôn vượt qua kiểm tra này, không phụ thuộc vào những thể loại nào được khai báo trong bộ lọc.</p>
+
+<p class="note"><strong>Lưu ý:</strong>
+Android sẽ tự động áp dụng thể loại {@link android.content.Intent#CATEGORY_DEFAULT}
+cho tất cả ý định không biểu thị được chuyển tới {@link
+android.content.Context#startActivity startActivity()} và {@link
+android.app.Activity#startActivityForResult startActivityForResult()}.
+Vì thế, nếu bạn muốn hoạt động của mình nhận ý định không biểu thị, nó phải
+nêu một thể loại cho {@code "android.intent.category.DEFAULT"} trong các bộ lọc ý định của mình (như
+được minh họa trong ví dụ {@code &lt;intent-filter&gt;} trước đó.</p>
+
+
+
+<h3 id="DataTest">Kiểm tra dữ liệu</h3>
+
+<p>Để quy định dữ liệu của ý định được chấp nhận, một bộ lọc ý định có thể khai báo 0 phần tử
+<a href="{@docRoot}guide/topics/manifest/data-element.html">{@code
+&lt;data&gt;}</a> hoặc nhiều hơn. Ví dụ:</p>
+
+<pre>
+&lt;intent-filter&gt;
+ &lt;data android:mimeType="video/mpeg" android:scheme="http" ... /&gt;
+ &lt;data android:mimeType="audio/mpeg" android:scheme="http" ... /&gt;
+ ...
+&lt;/intent-filter&gt;
+</pre>
+
+<p>Mỗi phần tử <code><a href="{@docRoot}guide/topics/manifest/data-element.html">&lt;data&gt;</a></code>
+có thể quy định một cấu trúc URI và kiểu dữ liệu (kiểu phương tiện MIME). Có các thuộc tính
+riêng &mdash; {@code scheme}, {@code host}, {@code port},
+và {@code path} &mdash; cho từng phần của URI:
+</p>
+
+<p style="margin-left: 2em">{@code &lt;scheme&gt;://&lt;host&gt;:&lt;port&gt;/&lt;path&gt;}</p>
+
+<p>
+Ví dụ:
+</p>
+
+<p style="margin-left: 2em">{@code content://com.example.project:200/folder/subfolder/etc}</p>
+
+<p>Trong URI này, lược đồ là {@code content}, máy chủ là {@code com.example.project},
+cổng là {@code 200}, và đường dẫn là {@code folder/subfolder/etc}.
+</p>
+
+<p>Mỗi thuộc tính sau đều không bắt buộc trong một phần tử <a href="{@docRoot}guide/topics/manifest/data-element.html">{@code &lt;data&gt;}</a>,
+nhưng có sự phụ thuộc mang tính chất tuyến tính:</p>
+<ul>
+ <li>Nếu không quy định một lược đồ thì máy chủ bị bỏ qua.</li>
+ <li>Nếu không quy định một máy chủ thì cổng bị bỏ qua.</li>
+ <li>Nếu không quy định cả lược đồ và máy chủ thì đường dẫn bị bỏ qua.</li>
+</ul>
+
+<p>Khi URI trong một ý định được so sánh với đặc tả URI trong một bộ lọc,
+nó chỉ được so sánh với các bộ phận của URI được nêu trong bộ lọc. Ví dụ:</p>
+<ul>
+ <li>Nếu một bộ lọc chỉ quy định một lược đồ, tất cả URI có lược đồ đó sẽ khớp
+với bộ lọc.</li>
+ <li>Nếu một bộ lọc quy định một lược đồ và thẩm quyền nhưng không có đường dẫn, tất cả URI
+với cùng lược đồ và thẩm quyền sẽ thông qua bộ lọc, không phụ thuộc vào đường dẫn của nó.</li>
+ <li>Nếu bộ lọc quy định một lược đồ, thẩm quyền và đường dẫn, chỉ những URI có cùng lược đồ,
+thẩm quyền và đường dẫn mới thông qua bộ lọc.</li>
+</ul>
+
+<p class="note"><strong>Lưu ý:</strong> Đặc tả đường dẫn có thể
+chứa một ký tự đại diện dấu sao (*) để yêu cầu chỉ khớp một phần với tên đường dẫn.</p>
+
+<p>Kiểm tra dữ liệu so sánh cả URI và kiểu MIME trong ý định với một URI
+và kiểu MIME được quy định trong bộ lọc. Các quy tắc như sau:
+</p>
+
+<ol type="a">
+<li>Một ý định mà không chứa URI cũng như kiểu MIME sẽ chỉ vượt qua
+kiểm tra nếu bộ lọc không quy định bất kỳ URI hay kiểu MIME nào.</li>
+
+<li>Một ý định chứa URI nhưng không có kiểu MIME (không biểu thị cũng như suy luận được từ
+URI) sẽ chỉ vượt qua kiểm tra nếu URI của nó khớp với định dạng URI của bộ lọc
+và bộ lọc tương tự không quy định một kiểu MIME.</li>
+
+<li>Một ý định chứa kiểu MIME nhưng không chứa URI sẽ chỉ vượt qua kiểm tra
+nếu bộ lọc liệt kê cùng kiểu MIME và không quy định một định dạng URI.</li>
+
+<li>Ý định mà chứa cả URI và kiểu MIME (hoặc biểu thị hoặc suy ra được từ
+URI) sẽ chỉ vượt qua phần kiểu MIME của kiểm tra nếu kiểu đó
+khớp với kiểu được liệt kê trong bộ lọc. Nó vượt qua phần URI của kiểm tra
+nếu URI của nó khớp với một URI trong bộ lọc hoặc nếu nó có một {@code content:}
+hoặc {@code file:} URI và bộ lọc không quy định một URI. Nói cách khác,
+một thành phần được giả định là hỗ trợ dữ liệu {@code content:} và {@code file:} nếu
+bộ lọc của nó liệt kê <em>chỉ</em> một kiểu MIME.</p></li>
+</ol>
+
+<p>
+Quy tắc cuối cùng này, quy tắc (d), phản ánh kỳ vọng
+rằng các thành phần có thể nhận được dữ liệu cục bộ từ một tệp hoặc trình cung cấp nội dung.
+Vì thế, các bộ lọc của chúng có thể chỉ liệt kê một kiểu dữ liệu và không cần công khai
+nêu tên {@code content:} và các lược đồ {@code file:}.
+Đây là một trường hợp điển hình. Phần tử <a href="{@docRoot}guide/topics/manifest/data-element.html">{@code &lt;data&gt;}</a> như
+ sau, ví dụ, sẽ thông báo cho Android biết rằng thành phần có thể nhận được dữ liệu ảnh từ một trình cung cấp
+nội dung và sẽ hiển thị nó:
+</p>
+
+<pre>
+&lt;intent-filter&gt;
+ &lt;data android:mimeType="image/*" /&gt;
+ ...
+&lt;/intent-filter&gt;</pre>
+
+<p>
+Vì hầu hết dữ liệu có sẵn đều được cấp phát bởi các trình cung cấp nội dung, những bộ lọc mà
+quy định một kiểu dữ liệu chứ không phải URI có lẽ là phổ biến nhất.
+</p>
+
+<p>
+Một cấu hình phổ biến khác đó là các bộ lọc có một lược đồ và một kiểu dữ liệu. Ví
+dụ, một phần tử <a href="{@docRoot}guide/topics/manifest/data-element.html">{@code &lt;data&gt;}</a>
+như sau thông báo cho Android rằng
+thành phần có thể truy xuất dữ liệu video từ mạng để thực hiện hành động:
+</p>
+
+<pre>
+&lt;intent-filter&gt;
+ &lt;data android:scheme="http" android:type="video/*" /&gt;
+ ...
+&lt;/intent-filter&gt;</pre>
+
+
+
+<h3 id="imatch">So khớp ý định</h3>
+
+<p>Các ý định được so khớp với các bộ lọc ý định không chỉ để khám phá một thành phần
+mục tiêu cần kích hoạt, mà còn để khám phá điều gì đó về tập hợp
+các thành phần trên thiết bị. Ví dụ, ứng dụng Trang chủ đưa trình khởi chạy ứng dụng
+vào bằng cách tìm tất cả hoạt động có bộ lọc ý định mà quy định hành động
+{@link android.content.Intent#ACTION_MAIN} và thể loại
+{@link android.content.Intent#CATEGORY_LAUNCHER}.</p>
+
+<p>Ứng dụng của bạn có thể sử dụng so khớp ý định theo cách tương tự.
+{@link android.content.pm.PackageManager} có một tập hợp các phương pháp{@code query...()}
+trả về tất cả thành phần có thể chấp nhận một ý định cụ thể, và
+một chuỗi các phương pháp {@code resolve...()} tương tự để xác định thành phần
+tốt nhất nhằm hồi đáp lại một ý định. Ví dụ,
+{@link android.content.pm.PackageManager#queryIntentActivities
+queryIntentActivities()} sẽ trả về một danh sách tất cả hoạt động có thể thực hiện
+ý định được chuyển qua như một tham đối, và {@link
+android.content.pm.PackageManager#queryIntentServices
+queryIntentServices()} trả về một danh sách dịch vụ tương tự.
+Cả hai phương pháp đều không kích hoạt các thành phần; chúng chỉ liệt kê những thành phần
+có thể hồi đáp. Có một phương pháp tương tự,
+{@link android.content.pm.PackageManager#queryBroadcastReceivers
+queryBroadcastReceivers()}, dành cho hàm nhận quảng bá.
+</p>
+
+
+
+
diff --git a/docs/html-intl/intl/vi/guide/components/loaders.jd b/docs/html-intl/intl/vi/guide/components/loaders.jd
new file mode 100644
index 000000000000..b6d277f3d527
--- /dev/null
+++ b/docs/html-intl/intl/vi/guide/components/loaders.jd
@@ -0,0 +1,494 @@
+page.title=Trình tải
+parent.title=Hoạt động
+parent.link=activities.html
+@jd:body
+<div id="qv-wrapper">
+<div id="qv">
+ <h2>Trong tài liệu này</h2>
+ <ol>
+ <li><a href="#summary">Tổng quan về API Trình tải</a></li>
+ <li><a href="#app">Sử dụng các Trình tải trong một Ứng dụng</a>
+ <ol>
+ <li><a href="#requirements"></a></li>
+ <li><a href="#starting">Khởi động một Trình tải</a></li>
+ <li><a href="#restarting">Khởi động lại một Trình tải</a></li>
+ <li><a href="#callback">Sử dụng các Phương pháp Gọi lại LoaderManager</a></li>
+ </ol>
+ </li>
+ <li><a href="#example">Ví dụ</a>
+ <ol>
+ <li><a href="#more_examples">Thêm Ví dụ</a></li>
+ </ol>
+ </li>
+ </ol>
+
+ <h2>Lớp khóa</h2>
+ <ol>
+ <li>{@link android.app.LoaderManager}</li>
+ <li>{@link android.content.Loader}</li>
+
+ </ol>
+
+ <h2>Các mẫu liên quan</h2>
+ <ol>
+ <li> <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderCursor.html">
+LoaderCursor</a></li>
+ <li> <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderThrottle.html">
+LoaderThrottle</a></li>
+ </ol>
+ </div>
+</div>
+
+<p>Được giới thiệu trong Android 3.0, trình tải giúp việc tải dữ liệu không đồng bộ
+trong một hoạt động hoặc phân đoạn trở nên dễ dàng. Trình tải có những đặc điểm sau:</p>
+ <ul>
+ <li>Chúng sẵn có cho mọi {@link android.app.Activity} và {@link
+android.app.Fragment}.</li>
+ <li>Chúng cung cấp khả năng tải dữ liệu không đồng bộ.</li>
+ <li>Chúng theo dõi nguồn dữ liệu của mình và chuyển giao kết quả mới khi nội dung
+thay đổi.</li>
+ <li>Chúng tự động kết nối lại với con chạy của trình tải cuối cùng khi được
+tạo lại sau khi cấu hình thay đổi. Vì thế, chúng không cần truy vấn lại dữ liệu
+của mình.</li>
+ </ul>
+
+<h2 id="summary">Tổng quan về API Trình tải</h2>
+
+<p>Có nhiều lớp và giao diện có thể có liên quan trong khi sử dụng
+các trình tải trong một ứng dụng. Chúng được tóm tắt trong bảng này.</p>
+
+<table>
+ <tr>
+ <th>Lớp/Giao diện</th>
+ <th>Mô tả</th>
+ </tr>
+ <tr>
+ <td>{@link android.app.LoaderManager}</td>
+ <td>Một lớp tóm tắt được liên kết với {@link android.app.Activity} hoặc
+{@link android.app.Fragment} để quản lý một hoặc nhiều thực thể {@link
+android.content.Loader}. Nó giúp ứng dụng quản lý
+các thao tác chạy lâu hơn cùng với vòng đời {@link android.app.Activity}
+hoặc {@link android.app.Fragment}; công dụng phổ biến nhất của lớp này là khi dùng với
+{@link android.content.CursorLoader}, tuy nhiên, các ứng dụng được tự do ghi
+trình tải của chính mình để tải các kiểu dữ liệu khác.
+ <br />
+ <br />
+ Chỉ có một {@link android.app.LoaderManager} trên mỗi hoạt động hoặc phân đoạn. Nhưng một {@link android.app.LoaderManager} có thể có
+nhiều trình tải.</td>
+ </tr>
+ <tr>
+ <td>{@link android.app.LoaderManager.LoaderCallbacks}</td>
+ <td>Một giao diện gọi lại để một máy khách tương tác với {@link
+android.app.LoaderManager}. Ví dụ, bạn sử dụng phương pháp gọi lại {@link
+android.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()}
+để tạo một trình tải mới.</td>
+ </tr>
+ <tr>
+ <td>{@link android.content.Loader}</td>
+ <td>Một lớp tóm tắt có vai trò thực hiện việc tải dữ liệu không đồng bộ. Đây là
+lớp cơ bản cho một trình tải. Thông thường, bạn sẽ sử dụng {@link
+android.content.CursorLoader}, nhưng bạn có thể triển khai lớp con của chính mình. Trong khi
+các trình tải đang hoạt động, chúng sẽ theo dõi nguồn dữ liệu của mình và chuyển giao
+kết quả mới khi nội dung thay đổi. </td>
+ </tr>
+ <tr>
+ <td>{@link android.content.AsyncTaskLoader}</td>
+ <td>Trình tải tóm tắt có chức năng cung cấp {@link android.os.AsyncTask} để thực hiện công việc.</td>
+ </tr>
+ <tr>
+ <td>{@link android.content.CursorLoader}</td>
+ <td>Một lớp con của {@link android.content.AsyncTaskLoader} có chức năng truy vấn
+{@link android.content.ContentResolver} và trả về một {@link
+android.database.Cursor}. Lớp này triển khai giao thức {@link
+android.content.Loader} theo một cách chuẩn hóa để truy vấn các con chạy,
+xây dựng trên {@link android.content.AsyncTaskLoader} để thực hiện truy vấn con chạy
+trên một luồng nền sao cho nó không chặn UI của ứng dụng. Sử dụng
+trình tải này là cách tốt nhất để tải dữ liệu không đồng bộ từ một {@link
+android.content.ContentProvider}, thay vì phải thực hiện một truy vấn được quản lý thông qua
+phân đoạn hoặc các API của hoạt động.</td>
+ </tr>
+</table>
+
+<p>Các lớp và giao diện trong bảng trên là những thành phần thiết yếu
+mà bạn sẽ sử dụng để triển khai một trình tải trong ứng dụng của mình. Bạn sẽ không cần tất cả chúng
+cho từng trình tải mà bạn tạo lập, nhưng bạn sẽ luôn cần một tham chiếu tới {@link
+android.app.LoaderManager} để khởi tạo một trình tải và triển khai
+một lớp {@link android.content.Loader} chẳng hạn như {@link
+android.content.CursorLoader}. Các phần sau đây trình bày với bạn cách sử dụng những
+lớp và giao diện này trong một ứng dụng.</p>
+
+<h2 id ="app">Sử dụng các Trình tải trong một Ứng dụng</h2>
+<p>Phần này mô tả cách sử dụng các trình tải trong một ứng dụng Android. Một
+ứng dụng sử dụng trình tải thường bao gồm:</p>
+<ul>
+ <li>Một {@link android.app.Activity} hoặc {@link android.app.Fragment}.</li>
+ <li>Một thực thể của {@link android.app.LoaderManager}.</li>
+ <li>Một {@link android.content.CursorLoader} để tải dữ liệu được dự phòng bởi một {@link
+android.content.ContentProvider}. Hoặc cách khác, bạn có thể triển khai lớp con
+của {@link android.content.Loader} hoặc {@link android.content.AsyncTaskLoader} của chính mình để tải
+dữ liệu từ một số nguồn khác.</li>
+ <li>Một triển khai cho {@link android.app.LoaderManager.LoaderCallbacks}.
+Đây là nơi bạn tạo trình tải mới và quản lý các tham chiếu của mình tới các
+trình tải hiện có.</li>
+<li>Một cách để hiển thị dữ liệu của trình tải, chẳng hạn như {@link
+android.widget.SimpleCursorAdapter}.</li>
+ <li>Một nguồn dữ liệu, chẳng hạn như một {@link android.content.ContentProvider}, khi sử dụng một
+{@link android.content.CursorLoader}.</li>
+</ul>
+<h3 id="starting">Khởi động một Trình tải</h3>
+
+<p>{@link android.app.LoaderManager} quản lý một hoặc nhiều thực thể {@link
+android.content.Loader} trong một {@link android.app.Activity} hoặc
+{@link android.app.Fragment}. Chỉ có một {@link
+android.app.LoaderManager} trên mỗi hoạt động hoặc phân đoạn.</p>
+
+<p>Thông thường, bạn
+sẽ khởi tạo một {@link android.content.Loader} bên trong phương pháp {@link
+android.app.Activity#onCreate onCreate()} của hoạt động, hoặc trong phương pháp
+{@link android.app.Fragment#onActivityCreated onActivityCreated()} của phân đoạn. Bạn
+làm điều này như sau:</p>
+
+<pre>// Prepare the loader. Either re-connect with an existing one,
+// or start a new one.
+getLoaderManager().initLoader(0, null, this);</pre>
+
+<p>Phương pháp {@link android.app.LoaderManager#initLoader initLoader()} sẽ lấy những
+tham số sau:</p>
+<ul>
+ <li>Một ID duy nhất xác định trình tải. Trong ví dụ này, ID là 0.</li>
+<li>Các tham đối tùy chọn để cung cấp cho trình tải khi
+xây dựng (<code>null</code> trong ví dụ này).</li>
+
+<li>Triển khai {@link android.app.LoaderManager.LoaderCallbacks}, phương pháp mà
+{@link android.app.LoaderManager} gọi để báo cáo các sự kiện trình tải. Trong ví dụ này
+, lớp cục bộ triển khai giao diện {@link
+android.app.LoaderManager.LoaderCallbacks}, vì thế nó chuyển một tham chiếu
+tới chính nó, {@code this}.</li>
+</ul>
+<p>Lệnh gọi {@link android.app.LoaderManager#initLoader initLoader()} đảm bảo rằng một trình tải
+được khởi tạo và hiện hoạt. Nó có hai kết quả có thể xảy ra:</p>
+<ul>
+ <li>Nếu trình tải được quy định bởi ID đã tồn tại, trình tải được tạo lập cuối cùng
+sẽ được sử dụng lại.</li>
+ <li>Nếu trình tải được quy định bởi ID <em>không</em> tồn tại,
+{@link android.app.LoaderManager#initLoader initLoader()} sẽ kích khởi phương pháp
+{@link android.app.LoaderManager.LoaderCallbacks}{@link android.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()}.
+Đây là nơi bạn triển khai mã để khởi tạo và trả về một trình tải mới.
+Để bàn thêm, hãy xem phần <a href="#onCreateLoader">onCreateLoader</a>.</li>
+</ul>
+<p>Dù trong trường hợp nào, triển khai {@link android.app.LoaderManager.LoaderCallbacks}
+đã cho được liên kết với trình tải, và sẽ được gọi khi
+trạng thái của trình tải thay đổi. Nếu tại điểm thực hiện lệnh gọi này, hàm gọi đang trong trạng thái
+được khởi động của nó, và trình tải được yêu cầu đã tồn tại và đã khởi tạo
+dữ liệu của nó, khi đó hệ thống sẽ gọi {@link
+android.app.LoaderManager.LoaderCallbacks#onLoadFinished onLoadFinished()}
+ngay lập tức (trong khi {@link android.app.LoaderManager#initLoader initLoader()}),
+vì thế bạn phải sẵn sàng khi điều này xảy ra. Xem <a href="#onLoadFinished">
+onLoadFinished</a> để thảo luận thêm về lệnh gọi lại này</p>
+
+<p>Lưu ý rằng phương pháp {@link android.app.LoaderManager#initLoader initLoader()}
+sẽ trả về {@link android.content.Loader} đã được tạo lập, nhưng bạn không
+cần bắt lại một tham chiếu tới nó. {@link android.app.LoaderManager} tự động quản lý
+vòng đời của trình tải. {@link android.app.LoaderManager}
+khởi động và dừng tải khi cần và duy trì trạng thái của trình tải
+và nội dung đi kèm của nó. Như hàm ý, bạn hiếm khi tương tác trực tiếp với các trình tải
+(thông qua một ví dụ về việc sử dụng các phương pháp trình tải để tinh chỉnh hành vi
+của một trình tải, hãy xem ví dụ <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderThrottle.html"> LoaderThrottle</a>).
+Bạn thường sử dụng nhất là các phương pháp {@link
+android.app.LoaderManager.LoaderCallbacks} để can thiệp vào tiến trình tải
+khi diễn ra một sự kiện đặc biệt. Để thảo luận thêm về chủ đề này, hãy xem phần <a href="#callback">Sử dụng Phương pháp Gọi lại LoaderManager</a>.</p>
+
+<h3 id="restarting">Khởi động lại một Trình tải</h3>
+
+<p>Khi bạn sử dụng {@link android.app.LoaderManager#initLoader initLoader()}, như
+trình bày bên trên, nó sử dụng một trình tải hiện hữu với ID được quy định nếu có.
+Nếu không có, nó sẽ tạo một trình tải. Nhưng đôi khi bạn muốn bỏ dữ liệu cũ của mình
+và bắt đầu lại.</p>
+
+<p>Để bỏ dữ liệu cũ của mình, hãy sử dụng {@link
+android.app.LoaderManager#restartLoader restartLoader()}. Ví dụ, việc
+triển khai {@link android.widget.SearchView.OnQueryTextListener} này sẽ khởi động lại
+trình tải khi truy vấn của người dùng thay đổi. Trình tải cần được khởi động lại sao cho
+nó có thể sử dụng bộ lọc tìm kiếm được điều chỉnh để thực hiện một truy vấn mới:</p>
+
+<pre>
+public boolean onQueryTextChanged(String newText) {
+ // Called when the action bar search text has changed. Update
+ // the search filter, and restart the loader to do a new query
+ // with this filter.
+ mCurFilter = !TextUtils.isEmpty(newText) ? newText : null;
+ getLoaderManager().restartLoader(0, null, this);
+ return true;
+}</pre>
+
+<h3 id="callback">Sử dụng các Phương pháp Gọi lại LoaderManager</h3>
+
+<p>{@link android.app.LoaderManager.LoaderCallbacks} là một giao diện gọi lại
+cho phép một máy khách tương tác với {@link android.app.LoaderManager}. </p>
+<p>Các trình tải, đặc biệt là {@link android.content.CursorLoader}, được kỳ vọng sẽ
+giữ lại dữ liệu của chúng sau khi bị dừng. Điều này cho phép ứng dụng giữ lại
+dữ liệu của chúng qua hoạt động hoặc các phương pháp {@link android.app.Activity#onStop
+onStop()} và {@link android.app.Activity#onStart onStart()} của phân đoạn, sao cho khi
+người dùng quay lại một ứng dụng, họ không phải chờ dữ liệu
+tải lại. Bạn sử dụng các phương pháp {@link android.app.LoaderManager.LoaderCallbacks}
+khi cần biết khi nào thì nên tạo một trình tải mới, và để thông báo với ứng dụng khi nào
+ thì đến lúc để dừng sử dụng dữ liệu của một trình tải.</p>
+
+<p>{@link android.app.LoaderManager.LoaderCallbacks} bao gồm những phương pháp
+sau:</p>
+<ul>
+ <li>{@link android.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()} —
+Khởi tạo và trả về một {@link android.content.Loader} mới cho ID đã cho.
+</li></ul>
+<ul>
+ <li> {@link android.app.LoaderManager.LoaderCallbacks#onLoadFinished onLoadFinished()}
+— Được gọi khi một trình tải được tạo trước đó đã hoàn tất việc tải.
+</li></ul>
+<ul>
+ <li>{@link android.app.LoaderManager.LoaderCallbacks#onLoaderReset onLoaderReset()}
+ — Được gọi khi một trình tải được tạo trước đó đang được đặt lại, vì thế mà khiến dữ liệu
+của nó không sẵn có.
+</li>
+</ul>
+<p>Những phương pháp này được mô tả chi tiết hơn trong các phần sau.</p>
+
+<h4 id ="onCreateLoader">onCreateLoader</h4>
+
+<p>Khi bạn định truy cập một trình tải (ví dụ, thông qua {@link
+android.app.LoaderManager#initLoader initLoader()}), nó kiểm tra xem
+trình tải được quy định bởi ID có tồn tại không. Nếu không, nó sẽ kích khởi phương pháp {@link
+android.app.LoaderManager.LoaderCallbacks} {@link
+android.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()}. Đây
+là lúc bạn tạo một trình tải mới. Thông thường sẽ có một {@link
+android.content.CursorLoader}, nhưng bạn có thể triển khai lớp con {@link
+android.content.Loader} của chính mình. </p>
+
+<p>Trong ví dụ này, phương pháp gọi lại {@link
+android.app.LoaderManager.LoaderCallbacks#onCreateLoader onCreateLoader()}
+sẽ tạo một {@link android.content.CursorLoader}. Bạn phải xây dựng
+{@link android.content.CursorLoader} bằng cách sử dụng phương pháp hàm dựng của nó mà yêu cầu
+trọn bộ thông tin cần thiết để thực hiện một truy vấn tới {@link
+android.content.ContentProvider}. Cụ thể, nó cần:</p>
+<ul>
+ <li><em>uri</em> — URI của nội dung cần truy xuất. </li>
+ <li><em>dự thảo</em> — Một danh sách các cột sẽ trả về. Việc chuyển
+<code>null</code> sẽ trả về tất cả cột, điều này không hiệu quả. </li>
+ <li><em>lựa chọn</em> — Một bộ lọc khai báo các hàng nào sẽ trả về,
+có định dạng như một mệnh đề SQL WHERE (không gồm chính mệnh đề WHERE). Việc chuyển
+<code>null</code> sẽ trả về tất cả hàng cho URI đã cho. </li>
+ <li><em>selectionArgs</em> — Bạn có thể thêm ?s vào lựa chọn,
+chúng sẽ được thay thế bằng các giá trị từ <em>selectionArgs</em>, theo thứ tự xuất hiện trong
+lựa chọn. Giá trị sẽ được gắn kết thành các Xâu. </li>
+ <li><em>sortOrder</em> — Cách sắp xếp thứ tự các hàng, được định dạng như một mệnh đề SQL
+ORDER BY (không bao gồm chính mệnh đề ORDER BY). Việc chuyển <code>null</code> sẽ
+sử dụng thứ tự sắp xếp mặc định, điều này có thể dẫn đến kết quả không theo thứ tự.</li>
+</ul>
+<p>Ví dụ:</p>
+<pre>
+ // If non-null, this is the current filter the user has provided.
+String mCurFilter;
+...
+public Loader&lt;Cursor&gt; onCreateLoader(int id, Bundle args) {
+ // This is called when a new Loader needs to be created.  This
+ // sample only has one Loader, so we don't care about the ID.
+ // First, pick the base URI to use depending on whether we are
+ // currently filtering.
+ Uri baseUri;
+    if (mCurFilter != null) {
+        baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
+                Uri.encode(mCurFilter));
+    } else {
+        baseUri = Contacts.CONTENT_URI;
+    }
+
+    // Now create and return a CursorLoader that will take care of
+    // creating a Cursor for the data being displayed.
+    String select = &quot;((&quot; + Contacts.DISPLAY_NAME + &quot; NOTNULL) AND (&quot;
+            + Contacts.HAS_PHONE_NUMBER + &quot;=1) AND (&quot;
+            + Contacts.DISPLAY_NAME + &quot; != '' ))&quot;;
+    return new CursorLoader(getActivity(), baseUri,
+            CONTACTS_SUMMARY_PROJECTION, select, null,
+            Contacts.DISPLAY_NAME + &quot; COLLATE LOCALIZED ASC&quot;);
+}</pre>
+<h4 id="onLoadFinished">onLoadFinished</h4>
+
+<p>Phương pháp này được gọi khi một trình tải được tạo trước đó đã hoàn thành việc tải của mình.
+Phương pháp này được bảo đảm sẽ được gọi trước khi giải phóng dữ liệu cuối cùng
+được cung cấp cho trình tải này. Tại điểm này, bạn nên loại bỏ mọi trường hợp sử dụng
+dữ liệu cũ (do nó sẽ được giải phóng sớm), nhưng không nên
+tự mình giải phóng dữ liệu do trình tải sở hữu dữ liệu và sẽ đảm nhận việc này.</p>
+
+
+<p>Trình tải sẽ giải phóng dữ liệu sau khi nó biết ứng dụng đang không còn
+sử dụng nó nữa. Ví dụ, nếu dữ liệu là một con chạy từ một {@link
+android.content.CursorLoader}, bạn không nên tự mình gọi {@link
+android.database.Cursor#close close()} trên dữ liệu đó. Nếu con chạy đang được đặt
+trong một {@link android.widget.CursorAdapter}, bạn nên sử dụng phương pháp {@link
+android.widget.SimpleCursorAdapter#swapCursor swapCursor()} sao cho
+ {@link android.database.Cursor} cũ không bị đóng. Ví dụ:</p>
+
+<pre>
+// This is the Adapter being used to display the list's data.<br
+/>SimpleCursorAdapter mAdapter;
+...
+
+public void onLoadFinished(Loader&lt;Cursor&gt; loader, Cursor data) {
+ // Swap the new cursor in.  (The framework will take care of closing the
+ // old cursor once we return.)
+ mAdapter.swapCursor(data);
+}</pre>
+
+<h4 id="onLoaderReset">onLoaderReset</h4>
+
+<p>Phương pháp này được gọi khi một trình tải được tạo trước đó đang được đặt lại, vì thế mà khiến
+dữ liệu của nó không sẵn có. Lệnh gọi lại này cho phép bạn tìm hiểu xem khi nào thì dữ liệu
+sẽ được giải phóng để bạn có thể loại bỏ tham chiếu của mình tới nó.  </p>
+<p>Sự triển khai này gọi ra
+{@link android.widget.SimpleCursorAdapter#swapCursor swapCursor()}
+với một giá trị <code>null</code>:</p>
+
+<pre>
+// This is the Adapter being used to display the list's data.
+SimpleCursorAdapter mAdapter;
+...
+
+public void onLoaderReset(Loader&lt;Cursor&gt; loader) {
+ // This is called when the last Cursor provided to onLoadFinished()
+ // above is about to be closed.  We need to make sure we are no
+ // longer using it.
+ mAdapter.swapCursor(null);
+}</pre>
+
+
+<h2 id="example">Ví dụ</h2>
+
+<p>Lấy một ví dụ, sau đây là triển khai đầy đủ của {@link
+android.app.Fragment} có chức năng hiển thị một {@link android.widget.ListView} chứa
+kết quả của một truy vấn đối với trình cung cấp nội dung danh bạ. Nó sử dụng một {@link
+android.content.CursorLoader} để quản lý truy vấn trên trình cung cấp.</p>
+
+<p>Để một ứng dụng truy cập danh bạ của một người dùng, như minh họa trong ví dụ này, bản kê khai
+của nó phải bao gồm quyền
+{@link android.Manifest.permission#READ_CONTACTS READ_CONTACTS}.</p>
+
+<pre>
+public static class CursorLoaderListFragment extends ListFragment
+        implements OnQueryTextListener, LoaderManager.LoaderCallbacks&lt;Cursor&gt; {
+
+ // This is the Adapter being used to display the list's data.
+    SimpleCursorAdapter mAdapter;
+
+    // If non-null, this is the current filter the user has provided.
+    String mCurFilter;
+
+    @Override public void onActivityCreated(Bundle savedInstanceState) {
+        super.onActivityCreated(savedInstanceState);
+
+        // Give some text to display if there is no data.  In a real
+        // application this would come from a resource.
+        setEmptyText(&quot;No phone numbers&quot;);
+
+        // We have a menu item to show in action bar.
+        setHasOptionsMenu(true);
+
+        // Create an empty adapter we will use to display the loaded data.
+        mAdapter = new SimpleCursorAdapter(getActivity(),
+                android.R.layout.simple_list_item_2, null,
+                new String[] { Contacts.DISPLAY_NAME, Contacts.CONTACT_STATUS },
+                new int[] { android.R.id.text1, android.R.id.text2 }, 0);
+        setListAdapter(mAdapter);
+
+        // Prepare the loader.  Either re-connect with an existing one,
+        // or start a new one.
+        getLoaderManager().initLoader(0, null, this);
+    }
+
+    @Override public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+        // Place an action bar item for searching.
+        MenuItem item = menu.add(&quot;Search&quot;);
+        item.setIcon(android.R.drawable.ic_menu_search);
+        item.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+        SearchView sv = new SearchView(getActivity());
+        sv.setOnQueryTextListener(this);
+        item.setActionView(sv);
+    }
+
+    public boolean onQueryTextChange(String newText) {
+        // Called when the action bar search text has changed.  Update
+        // the search filter, and restart the loader to do a new query
+        // with this filter.
+        mCurFilter = !TextUtils.isEmpty(newText) ? newText : null;
+        getLoaderManager().restartLoader(0, null, this);
+        return true;
+    }
+
+    @Override public boolean onQueryTextSubmit(String query) {
+        // Don't care about this.
+        return true;
+    }
+
+    @Override public void onListItemClick(ListView l, View v, int position, long id) {
+        // Insert desired behavior here.
+        Log.i(&quot;FragmentComplexList&quot;, &quot;Item clicked: &quot; + id);
+    }
+
+    // These are the Contacts rows that we will retrieve.
+    static final String[] CONTACTS_SUMMARY_PROJECTION = new String[] {
+        Contacts._ID,
+        Contacts.DISPLAY_NAME,
+        Contacts.CONTACT_STATUS,
+        Contacts.CONTACT_PRESENCE,
+        Contacts.PHOTO_ID,
+        Contacts.LOOKUP_KEY,
+    };
+    public Loader&lt;Cursor&gt; onCreateLoader(int id, Bundle args) {
+        // This is called when a new Loader needs to be created.  This
+        // sample only has one Loader, so we don't care about the ID.
+        // First, pick the base URI to use depending on whether we are
+        // currently filtering.
+        Uri baseUri;
+        if (mCurFilter != null) {
+            baseUri = Uri.withAppendedPath(Contacts.CONTENT_FILTER_URI,
+                    Uri.encode(mCurFilter));
+        } else {
+            baseUri = Contacts.CONTENT_URI;
+        }
+
+        // Now create and return a CursorLoader that will take care of
+        // creating a Cursor for the data being displayed.
+        String select = &quot;((&quot; + Contacts.DISPLAY_NAME + &quot; NOTNULL) AND (&quot;
+                + Contacts.HAS_PHONE_NUMBER + &quot;=1) AND (&quot;
+                + Contacts.DISPLAY_NAME + &quot; != '' ))&quot;;
+        return new CursorLoader(getActivity(), baseUri,
+                CONTACTS_SUMMARY_PROJECTION, select, null,
+                Contacts.DISPLAY_NAME + &quot; COLLATE LOCALIZED ASC&quot;);
+    }
+
+    public void onLoadFinished(Loader&lt;Cursor&gt; loader, Cursor data) {
+        // Swap the new cursor in.  (The framework will take care of closing the
+        // old cursor once we return.)
+        mAdapter.swapCursor(data);
+    }
+
+    public void onLoaderReset(Loader&lt;Cursor&gt; loader) {
+        // This is called when the last Cursor provided to onLoadFinished()
+        // above is about to be closed.  We need to make sure we are no
+        // longer using it.
+        mAdapter.swapCursor(null);
+    }
+}</pre>
+<h3 id="more_examples">Thêm Ví dụ</h3>
+
+<p>Có một vài mẫu khác trong <strong>ApiDemos</strong> để
+minh họa cách sử dụng các trình tải:</p>
+<ul>
+ <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderCursor.html">
+LoaderCursor</a> — Một phiên bản hoàn chỉnh của
+đoạn mã HTML trình bày ở trên.</li>
+ <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LoaderThrottle.html"> LoaderThrottle</a> — Một ví dụ về cách sử dụng điều chỉnh để giảm
+số truy vấn mà một trình cung cấp nội dung thực hiện khi dữ liệu của nó thay đổi.</li>
+</ul>
+
+<p>Để biết thông tin về việc tải xuống và cài đặt các mẫu SDK, hãy xem phần <a href="http://developer.android.com/resources/samples/get.html"> Tải
+Mẫu</a>. </p>
+
diff --git a/docs/html-intl/intl/vi/guide/components/processes-and-threads.jd b/docs/html-intl/intl/vi/guide/components/processes-and-threads.jd
new file mode 100644
index 000000000000..390ca156a1f0
--- /dev/null
+++ b/docs/html-intl/intl/vi/guide/components/processes-and-threads.jd
@@ -0,0 +1,411 @@
+page.title=Tiến trình và Luồng
+page.tags=vòng đời, nền
+
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>Trong tài liệu này</h2>
+<ol>
+<li><a href="#Processes">Tiến trình</a>
+ <ol>
+ <li><a href="#Lifecycle">Vòng đời tiến trình</a></li>
+ </ol>
+</li>
+<li><a href="#Threads">Luồng</a>
+ <ol>
+ <li><a href="#WorkerThreads">Luồng trình thực hiện</a></li>
+ <li><a href="#ThreadSafe">Phương pháp an toàn với luồng</a></li>
+ </ol>
+</li>
+<li><a href="#IPC">Truyền thông Liên Tiến trình</a></li>
+</ol>
+
+</div>
+</div>
+
+<p>Khi một thành phần ứng dụng bắt đầu và ứng dụng không có bất kỳ thành phần nào khác
+đang chạy, hệ thống Android sẽ khởi động một tiến trình Linux mới cho ứng dụng bằng một luồng
+thực thi đơn lẻ. Theo mặc định, tất cả thành phần của cùng ứng dụng sẽ chạy trong cùng tiến trình và luồng
+(được gọi là luồng "chính"). Nếu một thành phần ứng dụng bắt đầu và đã tồn tại một tiến trình
+cho ứng dụng đó (bởi một thành phần khác từ ứng dụng đã tồn tại), khi đó thành phần được
+bắt đầu bên trong tiến trình đó và sử dụng cùng luồng thực thi. Tuy nhiên, bạn có thể sắp xếp cho
+các thành phần khác nhau trong ứng dụng của mình để chạy trong các tiến trình riêng biệt, và bạn có thể tạo thêm
+luồng cho bất kỳ tiến trình nào.</p>
+
+<p>Tài liệu này trình bày về cách các tiến trình và luồng vận hành trong một ứng dụng Android.</p>
+
+
+<h2 id="Processes">Tiến trình</h2>
+
+<p>Theo mặc định, tất cả thành phần của cùng ứng dụng sẽ chạy trong cùng tiến trình và hầu hết các ứng dụng
+sẽ không thay đổi điều này. Tuy nhiên, nếu bạn thấy rằng mình cần kiểm soát một thành phần
+cụ thể thuộc về một tiến trình nào đó, bạn có thể làm vậy trong tệp bản kê khai.</p>
+
+<p>Mục nhập bản kê khai đối với mỗi loại phần tử thành phần&mdash;<a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code
+&lt;activity&gt;}</a>, <a href="{@docRoot}guide/topics/manifest/service-element.html">{@code
+&lt;service&gt;}</a>, <a href="{@docRoot}guide/topics/manifest/receiver-element.html">{@code
+&lt;receiver&gt;}</a>, và <a href="{@docRoot}guide/topics/manifest/provider-element.html">{@code
+&lt;provider&gt;}</a>&mdash;sẽ hỗ trợ một thuộc tính {@code android:process} mà có thể quy định một
+tiến trình mà thành phần đó sẽ chạy trong đó. Bạn có thể đặt thuộc tính này sao cho từng thành phần chạy
+trong chính tiến trình của nó hoặc sao cho một số thành phần chia sẻ một tiến trình trong khi các thành phần khác thì không. Bạn cũng có thể đặt
+{@code android:process} sao cho các thành phần của những ứng dụng khác nhau chạy trong cùng
+tiến trình&mdash;với điều kiện rằng ứng dụng chia sẻ cùng ID người dùng Linux và được ký bằng cùng các
+chứng chỉ.</p>
+
+<p>Phần tử <a href="{@docRoot}guide/topics/manifest/application-element.html">{@code
+&lt;application&gt;}</a> cũng hỗ trợ một thuộc tính {@code android:process}, để đặt một
+giá trị mặc định áp dụng cho tất cả thành phần.</p>
+
+<p>Android có thể quyết định tắt một tiến trình tại một thời điểm nào đó, khi bộ nhớ thấp và theo yêu cầu của các
+tiến trình khác đang phục vụ người dùng tức thì hơn. Các thành phần
+ứng dụng đang chạy trong tiến trình bị tắt bỏ thì sau đó sẽ bị hủy. Tiến trình được
+khởi động lại cho những thành phần đó khi lại có việc cho chúng thực hiện.</p>
+
+<p>Khi quyết định bỏ những tiến trình nào, hệ thống Android sẽ cân nhắc tầm quan trọng tương đối so với
+người dùng. Ví dụ, hệ thống sẵn sàng hơn khi tắt một tiến trình lưu trữ các hoạt động không còn
+hiển thị trên màn hình, so với một tiến trình lưu trữ các hoạt động đang hiển thị. Vì thế, quyết định về việc có
+chấm dứt một tiến trình hay không phụ thuộc vào trạng thái của các thành phần đang chạy trong tiến trình đó. Các quy tắc
+được sử dụng để quyết định sẽ chấm dứt tiến trình nào được trình bày ở bên dưới. </p>
+
+
+<h3 id="Lifecycle">Vòng đời tiến trình</h3>
+
+<p>Hệ thống Android cố gắng duy trì một tiến trình ứng dụng lâu nhất có thể, nhưng
+cuối cùng thì nó cũng cần loại bỏ các tiến trình cũ để lấy lại bộ nhớ cho các tiến trình mới hoặc quan trọng hơn. Để
+xác định giữ lại những tiến trình nào
+và loại bỏ những tiến trình nào, hệ thống sẽ đặt từng tiến trình vào một "phân cấp tầm quan trọng" dựa trên
+những thành phần đang chạy trong tiến trình và trạng thái của những thành phần đó. Những tiến trình có tầm quan trọng
+thấp nhất bị loại bỏ trước, rồi đến những tiến trình có tầm quan trọng thấp thứ hai, và cứ thế tiếp tục, miễn là còn cần thiết
+để khôi phục tài nguyên của hệ thống.</p>
+
+<p>Có năm cấp trong phân cấp tầm quan trọng. Danh sách sau trình bày các loại
+tiến trình khác nhau theo thứ tự tầm quan trọng (tiến trình thứ nhất là <em>quan trọng nhất</em> và được
+<em>tắt bỏ sau cùng</em>):</p>
+
+<ol>
+ <li><b>Tiến trình tiền cảnh</b>
+ <p>Một tiến trình được yêu cầu cho việc mà người dùng đang thực hiện. Một
+ tiến trình được coi là đang trong tiền cảnh nếu bất kỳ điều nào sau đây là đúng:</p>
+
+ <ul>
+ <li>Nó lưu trữ một {@link android.app.Activity} mà người dùng đang tương tác với (phương pháp của {@link
+android.app.Activity}, {@link android.app.Activity#onResume onResume()}, đã được
+gọi).</li>
+
+ <li>Nó lưu trữ một {@link android.app.Service} gắn kết với hoạt động mà người dùng đang
+tương tác với.</li>
+
+ <li>Nó lưu trữ một {@link android.app.Service} đang chạy "trong tiền cảnh"&mdash;mà
+dịch vụ đã gọi {@link android.app.Service#startForeground startForeground()}.
+
+ <li>Nó lưu trữ một {@link android.app.Service} mà đang thực thi một trong các lệnh
+gọi lại của vòng đời của nó ({@link android.app.Service#onCreate onCreate()}, {@link android.app.Service#onStart
+onStart()}, hoặc {@link android.app.Service#onDestroy onDestroy()}).</li>
+
+ <li>Nó lưu trữ một {@link android.content.BroadcastReceiver} mà đang thực thi phương pháp {@link
+ android.content.BroadcastReceiver#onReceive onReceive()} của nó.</li>
+ </ul>
+
+ <p>Nhìn chung, tại bất kỳ thời điểm xác định nào cũng chỉ tồn tại một vài tiến trình tiền cảnh. Chúng chỉ bị tắt bỏ
+như một giải pháp cuối cùng&mdash;nếu bộ nhớ quá thấp tới mức chúng đều không thể tiếp tục chạy được. Nhìn chung, tại thời điểm
+đó, thiết bị đã đạt tới trạng thái phân trang bộ nhớ, vì thế việc tắt bỏ một số tiến trình tiền cảnh là
+bắt buộc để đảm bảo giao diện người dùng có phản hồi.</p></li>
+
+ <li><b>Tiến trình hiển thị</b>
+ <p>Một tiến trình mà không có bất kỳ thành phần tiền cảnh nào, nhưng vẫn có thể
+ ảnh hưởng tới nội dung mà người dùng nhìn thấy trên màn hình. Một tiến trình được coi là hiển thị nếu một trong hai
+ điều kiện sau là đúng:</p>
+
+ <ul>
+ <li>Nó lưu trữ một {@link android.app.Activity} mà không nằm trong tiền cảnh, nhưng vẫn
+hiển thị với người dùng (phương pháp {@link android.app.Activity#onPause onPause()} của nó đã được gọi).
+Điều này có thể xảy ra, ví dụ, nếu hoạt động tiền cảnh đã bắt đầu một hộp thoại, nó cho phép
+hoạt động trước được nhìn thấy phía sau nó.</li>
+
+ <li>Nó lưu trữ một {@link android.app.Service} được gắn kết với một hoạt động
+hiển thị (hoặc tiền cảnh).</li>
+ </ul>
+
+ <p>Một tiến trình tiền cảnh được coi là cực kỳ quan trọng và sẽ không bị tắt bỏ trừ khi làm vậy
+là bắt buộc để giữ cho tất cả tiến trình tiền cảnh chạy. </p>
+ </li>
+
+ <li><b>Tiến trình dịch vụ</b>
+ <p>Một tiến trình mà đang chạy một dịch vụ đã được bắt đầu bằng phương pháp {@link
+android.content.Context#startService startService()} và không rơi vào một trong hai
+thể loại cao hơn. Mặc dù tiến trình dịch vụ không trực tiếp gắn với bất kỳ thứ gì mà người dùng thấy, chúng
+thường đang làm những việc mà người dùng quan tâm đến (chẳng hạn như phát nhạc chạy ngầm hoặc
+tải xuống dữ liệu trên mạng), vì thế hệ thống vẫn giữ chúng chạy trừ khi không có đủ bộ nhớ để
+duy trì chúng cùng với tất cả tiến trình tiền cảnh và hiển thị. </p>
+ </li>
+
+ <li><b>Tiến trình nền</b>
+ <p>Một tiến trình lưu trữ một hoạt động mà hiện tại không hiển thị với người dùng (phương pháp
+{@link android.app.Activity#onStop onStop()} của hoạt động đã được gọi). Những tiến trình này không có tác động
+trực tiếp tới trải nghiệm người dùng, và hệ thống có thể bỏ chúng đi vào bất cứ lúc nào để lấy lại bộ nhớ cho một
+tiến trình tiền cảnh,
+hiển thị hoặc dịch vụ. Thường thì có nhiều tiến trình ngầm đang chạy, vì thế chúng được giữ
+trong một danh sách LRU (ít sử dụng gần đây nhất) để đảm bảo rằng tiến trình với hoạt động
+mà người dùng nhìn thấy gần đây nhất là tiến trình cuối cùng sẽ bị tắt bỏ. Nếu một hoạt động triển khai các phương pháp vòng đời của nó
+đúng cách, và lưu trạng thái hiện tại của nó, việc tắt bỏ tiến trình của hoạt động đó sẽ không có ảnh hưởng có thể thấy được tới
+trải nghiệm người dùng, vì khi người dùng điều hướng lại hoạt động đó, hoạt động sẽ khôi phục
+tất cả trạng thái hiển thị của nó. Xem tài liệu <a href="{@docRoot}guide/components/activities.html#SavingActivityState">Hoạt động</a>
+để biết thông tin về việc lưu và khôi phục trạng thái.</p>
+ </li>
+
+ <li><b>Tiến trình trống</b>
+ <p>Một tiến trình mà không giữ bất kỳ thành phần ứng dụng hiện hoạt nào. Lý do duy nhất để giữ cho
+kiểu tiến trình này hoạt động đó là nhằm mục đích lưu bộ nhớ ẩn, để cải thiện thời gian khởi động vào lần tới khi thành phần
+cần chạy trong nó. Hệ thống thường tắt bỏ những tiến trình này để cân bằng tài nguyên tổng thể
+của hệ thống giữa các bộ đệm ẩn tiến trình và bộ đệm ẩn nhân liên quan.</p>
+ </li>
+</ol>
+
+
+ <p>Android xếp hạng một tiến trình ở mức cao nhất mà nó có thể, dựa vào tầm quan trọng của
+các thành phần đang hoạt động trong tiến trình đó. Ví dụ, nếu một tiến trình lưu giữ một dịch vụ và hoạt động
+hiển thị, tiến trình đó sẽ được xếp hạng là tiến trình hiển thị chứ không phải tiến trình dịch vụ.</p>
+
+ <p>Ngoài ra, xếp hạng của một tiến trình có thể tăng bởi các tiến trình khác phụ thuộc vào
+nó&mdash;một tiến trình mà đang phục vụ một tiến trình khác không thể bị xếp thấp hơn tiến trình mà nó
+đang phục vụ. Ví dụ, nếu một trình cung cấp nội dung trong tiến trình A đang phục vụ một máy khách trong tiến trình B, hoặc nếu một
+dịch vụ trong tiến trình A được gắn kết với một thành phần trong tiến trình B, ít nhất tiến trình A sẽ luôn được coi
+là quan trọng như tiến trình B.</p>
+
+ <p>Do một tiến trình đang chạy một dịch vụ được xếp hạng cao hơn một tiến trình có các hoạt động nền,
+một hoạt động mà khởi động một thao tác nhấp giữ có thể làm tốt việc khởi động một <a href="{@docRoot}guide/components/services.html">dịch vụ</a> cho thao tác đó, thay vì
+chỉ tạo một luồng trình thực hiện&mdash;nhất là khi thao tác đó sẽ có thể diễn ra lâu hơn hoạt động.
+Ví dụ, một hoạt động mà đang tải một ảnh lên một trang web nên bắt đầu một dịch vụ để thực hiện
+việc tải lên sao cho việc tải lên có thể tiếp tục chạy ngầm ngay cả khi người dùng rời khỏi hoạt động.
+Việc sử dụng một dịch vụ sẽ bảo đảm rằng thao tác ít nhất sẽ có mức ưu tiên như "tiến trình dịch vụ",
+không phụ thuộc vào điều xảy ra với hoạt động. Đây cũng chính là lý do hàm nhận quảng bá nên
+sử dụng dịch vụ thay vì chỉ đưa các thao tác tốn thời gian vào một luồng.</p>
+
+
+
+
+<h2 id="Threads">Luồng</h2>
+
+<p>Khi một ứng dụng được khởi chạy, hệ thống sẽ tạo một luồng thực thi cho ứng dụng,
+gọi là luồng "chính." Luồng này rất quan trọng bởi nó phụ trách phân phối các sự kiện tới
+những widget giao diện người dùng phù hợp, bao gồm các sự kiện vẽ. Nó cũng là luồng mà
+trong đó ứng dụng của bạn tương tác với các thành phần từ bộ công cụ UI của Android (các thành phần từ các gói {@link
+android.widget} và {@link android.view}). Như vậy, luồng chính đôi khi cũng được gọi là
+luồng UI.</p>
+
+<p>Hệ thống <em>không</em> tạo một luồng riêng cho từng thực thể của thành phần. Tất cả
+thành phần chạy trong cùng tiến trình đều được khởi tạo trong luồng UI, và các lệnh gọi của hệ thống tới
+từng thành phần được phân phối từ luồng đó. Hệ quả là các phương pháp hồi đáp lại lệnh
+gọi lại của hệ thống (chẳng hạn như {@link android.view.View#onKeyDown onKeyDown()} để báo cáo hành động của người dùng
+hoặc một phương pháp gọi lại vòng đời) sẽ luôn chạy trong luồng UI của tiến trình.</p>
+
+<p>Ví dụ, khi người dùng chạm vào một nút trên màn hình, luồng UI của ứng dụng của bạn sẽ phân phối
+sự kiện chạm tới widget, đến lượt mình, widget sẽ đặt trạng thái được nhấn và đăng một yêu cầu vô hiệu hóa tới
+hàng đợi sự kiện. Luồng UI loại yêu cầu khỏi hàng đợi và thông báo với widget rằng nó nên tự vẽ lại
+.</p>
+
+<p>Khi ứng dụng của bạn thực hiện công việc nặng để hồi đáp tương tác của người dùng, mô hình luồng đơn nhất
+này có thể dẫn đến hiệu năng kém trừ khi bạn triển khai ứng dụng của mình một cách phù hợp. Cụ thể, nếu
+mọi thứ đang xảy ra trong luồng UI, việc thực hiện những thao tác kéo dài như truy cập mạng hay
+truy vấn cơ sở dữ liệu sẽ chặn toàn bộ UI. Khi luồng bị chặn, không sự kiện nào có thể được phân phối,
+bao gồm cả sự kiện vẽ. Từ phương diện của người dùng, ứng dụng
+có vẻ như đang bị treo. Thậm chí tệ hơn, nếu luồng UI bị chặn trong lâu hơn vài giây
+(hiện tại là khoảng 5 giây), người dùng sẽ được hiển thị hộp thoại không phổ biến "<a href="http://developer.android.com/guide/practices/responsiveness.html">ứng dụng
+không phản hồi</a>" (ANR). Khi đó, người dùng có thể quyết định thoát ứng dụng của mình và gỡ cài đặt nó
+nếu họ không thoải mái.</p>
+
+<p>Ngoài ra, bộ công cụ UI của Android <em>không</em> an toàn với luồng. Vì vậy, bạn không được thao tác
+UI của mình từ một luồng trình thực hiện&mdash;bạn phải thực hiện tất cả thao tác đối với giao diện người dùng của mình từ luồng
+UI. Vì vậy, có hai quy tắc đơn giản đối với mô hình luồng đơn lẻ của Android:</p>
+
+<ol>
+<li>Không được chặn luồng UI
+<li>Không được truy cập bộ công cụ UI của Android từ bên ngoài luồng UI
+</ol>
+
+<h3 id="WorkerThreads">Luồng trình thực hiện</h3>
+
+<p>Vì mô hình luồng đơn lẻ nêu trên, điều thiết yếu đối với tính phản hồi của UI
+ứng dụng của bạn đó là bạn không được chặn luồng UI. Nếu bạn có thao tác cần thực hiện
+không mang tính chất tức thời, bạn nên đảm bảo thực hiện chúng trong các luồng riêng (luồng “chạy ngầm" hoặc
+"trình thực hiện").</p>
+
+<p>Ví dụ, bên dưới là một số mã cho một đối tượng theo dõi nhấp có chức năng tải xuống một hình ảnh từ một luồng
+riêng và hiển thị nó trong một {@link android.widget.ImageView}:</p>
+
+<pre>
+public void onClick(View v) {
+ new Thread(new Runnable() {
+ public void run() {
+ Bitmap b = loadImageFromNetwork("http://example.com/image.png");
+ mImageView.setImageBitmap(b);
+ }
+ }).start();
+}
+</pre>
+
+<p>Thoạt đầu, điều này có vẻ như diễn ra ổn thỏa, vì nó tạo một luồng mới để xử lý thao tác
+mạng. Tuy nhiên, nó vi phạm quy tắc thứ hai của mô hình luồng đơn nhất: <em>không được truy cập
+bộ công cụ UI của Android từ bên ngoài luồng UI</em>&mdash;mẫu này sửa đổi {@link
+android.widget.ImageView} từ luồng trình thực hiện thay vì từ luồng UI. Điều này có thể dẫn đến
+hành vi bất ngờ, không được định nghĩa mà có thể gây khó khăn và tốn thời gian theo dõi.</p>
+
+<p>Để sửa vấn đề này, Android giới thiệu một vài cách để truy cập luồng UI từ các luồng
+khác. Sau đây là một danh sách các phương pháp có thể trợ giúp:</p>
+
+<ul>
+<li>{@link android.app.Activity#runOnUiThread(java.lang.Runnable)
+Activity.runOnUiThread(Runnable)}</li>
+<li>{@link android.view.View#post(java.lang.Runnable) View.post(Runnable)}</li>
+<li>{@link android.view.View#postDelayed(java.lang.Runnable, long) View.postDelayed(Runnable,
+long)}</li>
+</ul>
+
+<p>Ví dụ, bạn có thể sửa mã trên bằng cách sử dụng phương pháp {@link
+android.view.View#post(java.lang.Runnable) View.post(Runnable)}:</p>
+
+<pre>
+public void onClick(View v) {
+ new Thread(new Runnable() {
+ public void run() {
+ final Bitmap bitmap = loadImageFromNetwork("http://example.com/image.png");
+ mImageView.post(new Runnable() {
+ public void run() {
+ mImageView.setImageBitmap(bitmap);
+ }
+ });
+ }
+ }).start();
+}
+</pre>
+
+<p>Giờ thì triển khai này đã an toàn với luồng: thao tác mạng được thực hiện từ một luồng riêng
+trong khi {@link android.widget.ImageView} được thao tác từ luồng UI.</p>
+
+<p>Tuy nhiên, khi mà sự phức tạp của thao tác tăng lên, kiểu mã này có thể bị phức tạp hóa và
+khó duy trì. Để xử lý những tương tác phức tạp hơn bằng một luồng trình thực hiện, bạn có thể cân nhắc
+sử dụng một {@link android.os.Handler} trong luồng trình thực hiện của mình, để xử lý các thư được chuyển từ luồng
+UI. Mặc dù vậy, giải pháp tốt nhất là mở rộng lớp {@link android.os.AsyncTask},
+điều này sẽ đơn giản hóa việc thực thi các tác vụ của luồng trình thực hiện cần tương tác với UI.</p>
+
+
+<h4 id="AsyncTask">Sử dụng AsyncTask</h4>
+
+<p>{@link android.os.AsyncTask} cho phép bạn thực hiện công việc không đồng bộ trên giao diện
+người dùng của mình. Nó thực hiện các thao tác chặn trong một luồng trình thực hiện rồi phát hành kết quả trên
+luồng UI mà không yêu cầu bạn tự xử lý các luồng và/hoặc trình xử lý.</p>
+
+<p>Để sử dụng nó, bạn phải tạo lớp con {@link android.os.AsyncTask} và triển khai phương pháp gọi lại {@link
+android.os.AsyncTask#doInBackground doInBackground()}, phương pháp này chạy trong một tập hợp
+các luồng chạy ngầm. Để cập nhật UI của mình, bạn nên triển khai {@link
+android.os.AsyncTask#onPostExecute onPostExecute()}, nó sẽ mang lại kết quả từ {@link
+android.os.AsyncTask#doInBackground doInBackground()} và chạy trong luồng UI, vì thế bạn có thể nâng cấp
+UI của mình một cách an toàn. Sau đó, bạn có thể chạy tác vụ bằng cách gọi {@link android.os.AsyncTask#execute execute()}
+từ luồng UI.</p>
+
+<p>Ví dụ, bạn có thể triển khai ví dụ trước bằng cách sử dụng {@link android.os.AsyncTask} theo
+cách này:</p>
+
+<pre>
+public void onClick(View v) {
+ new DownloadImageTask().execute("http://example.com/image.png");
+}
+
+private class DownloadImageTask extends AsyncTask&lt;String, Void, Bitmap&gt; {
+ /** The system calls this to perform work in a worker thread and
+ * delivers it the parameters given to AsyncTask.execute() */
+ protected Bitmap doInBackground(String... urls) {
+ return loadImageFromNetwork(urls[0]);
+ }
+
+ /** The system calls this to perform work in the UI thread and delivers
+ * the result from doInBackground() */
+ protected void onPostExecute(Bitmap result) {
+ mImageView.setImageBitmap(result);
+ }
+}
+</pre>
+
+<p>Lúc này, UI an toàn và mã đơn giản hơn, vì nó tách riêng công việc thành
+phần sẽ được thực hiện trên một luồng trình thực hiện và phần sẽ được thực hiện trên luồng UI.</p>
+
+<p>Bạn nên đọc tài liệu tham khảo {@link android.os.AsyncTask}để hiểu đầy đủ về
+cách sử dụng lớp này, nhưng sau đây là phần trình bày tổng quan nhanh về hoạt động của nó:</p>
+
+<ul>
+<li>Bạn có thể quy định loại tham số, các giá trị tiến độ, và giá trị
+cuối cùng của tác vụ, bằng cách sử dụng các kiểu chung</li>
+<li>Phương pháp {@link android.os.AsyncTask#doInBackground doInBackground()} sẽ tự động thực thi
+trên một luồng trình thực hiện</li>
+<li>{@link android.os.AsyncTask#onPreExecute onPreExecute()}, {@link
+android.os.AsyncTask#onPostExecute onPostExecute()}, và {@link
+android.os.AsyncTask#onProgressUpdate onProgressUpdate()} đều được gọi ra trên luồng UI</li>
+<li>Giá trị được trả về bởi {@link android.os.AsyncTask#doInBackground doInBackground()} được gửi tới
+{@link android.os.AsyncTask#onPostExecute onPostExecute()}</li>
+<li>Bạn có thể gọi {@link android.os.AsyncTask#publishProgress publishProgress()} vào bất cứ lúc nào trong {@link
+android.os.AsyncTask#doInBackground doInBackground()} để thực thi {@link
+android.os.AsyncTask#onProgressUpdate onProgressUpdate()} trên luồng UI</li>
+<li>Bạn có thể hủy bỏ tác vụ vào bất cứ lúc nào từ bất kỳ luồng nào</li>
+</ul>
+
+<p class="caution"><strong>Chú ý:</strong> Một vấn đề khác mà bạn có thể gặp phải khi sử dụng một luồng
+trình thực hiện đó là những lần khởi động lại bất ngờ trong hoạt động của bạn do một <a href="{@docRoot}guide/topics/resources/runtime-changes.html">thay đổi trong cấu hình thời gian chạy</a>
+(chẳng hạn như khi người dùng thay đổi hướng màn hình), điều này có thể làm hỏng luồng trình thực hiện của bạn. Để
+xem cách bạn có thể duy trì tác vụ của mình khi diễn ra một trong những lần khởi động lại này và cách hủy bỏ tác vụ cho phù hợp
+khi hoạt động bị hủy, hãy xem mã nguồn cho ứng dụng mẫu <a href="http://code.google.com/p/shelves/">Shelves</a>.</p>
+
+
+<h3 id="ThreadSafe">Phương pháp an toàn với luồng</h3>
+
+<p> Trong một số tình huống, các phương pháp bạn triển khai có thể được gọi ra từ nhiều hơn một luồng, và vì thế
+phải được ghi sao cho an toàn với luồng. </p>
+
+<p>Điều này chủ yếu đúng với các phương pháp mà có thể được gọi từ xa&mdash;chẳng hạn như các phương pháp trong một <a href="{@docRoot}guide/components/bound-services.html">dịch vụ gắn kết</a>. Khi một lệnh gọi trên một
+phương pháp được triển khai trong một {@link android.os.IBinder} khởi đầu trong cùng tiến trình mà
+{@link android.os.IBinder IBinder} đang chạy, phương pháp đó sẽ được thực thi trong luồng của hàm gọi.
+Tuy nhiên, khi lệnh gọi khởi đầu trong một tiến trình khác, phương pháp sẽ được thực thi trong một luồng được chọn từ
+một tập hợp các luồng mà hệ thống duy trì trong cùng tiến trình như {@link android.os.IBinder
+IBinder} (nó không được thực thi trong luồng UI của tiến trình). Ví dụ, trong khi phương pháp
+{@link android.app.Service#onBind onBind()} của dịch vụ sẽ được gọi từ luồng UI của tiến trình
+của dịch vụ, các phương pháp được triển khai trong đối tượng mà {@link android.app.Service#onBind
+onBind()} trả về (ví dụ, một lớp con triển khai các phương pháp RPC) sẽ được gọi từ các luồng
+trong tập hợp. Vì một dịch vụ có thể có nhiều hơn một máy khách, nhiều hơn một luồng tập hợp có thể sử dụng
+cùng một phương pháp {@link android.os.IBinder IBinder} tại cùng một thời điểm. Vì thế, các phương pháp {@link android.os.IBinder
+IBinder} phải được triển khai sao cho an toàn với luồng.</p>
+
+<p> Tương tự, một trình cung cấp nội dung có thể nhận các yêu cầu dữ liệu khởi nguồn trong các tiến trình khác.
+Mặc dù các lớp {@link android.content.ContentResolver} và {@link android.content.ContentProvider}
+ẩn đi chi tiết về cách truyền thông liên tiến trình được quản lý, các phương pháp {@link
+android.content.ContentProvider} hồi đáp những yêu cầu đó&mdash;các phương pháp {@link
+android.content.ContentProvider#query query()}, {@link android.content.ContentProvider#insert
+insert()}, {@link android.content.ContentProvider#delete delete()}, {@link
+android.content.ContentProvider#update update()}, và {@link android.content.ContentProvider#getType
+getType()}&mdash;được gọi từ một tập hợp luồng trong tiến trình của trình cung cấp nội dung, chứ không phải luồng
+UI cho tiến trình đó. Vì những phương pháp này có thể được gọi từ bất kỳ số lượng luồng nào tại
+cùng thời điểm, chúng cũng phải được triển khai sao cho an toàn với luồng. </p>
+
+
+<h2 id="IPC">Truyền thông Liên Tiến trình</h2>
+
+<p>Android cung cấp một cơ chế cho truyền thông liên tiến trình (IPC) bằng cách sử dụng các lệnh gọi thủ tục từ xa
+(RPC), trong đó một phương pháp được gọi bởi một hoạt động hoặc thành phần ứng dụng khác, nhưng được thực thi
+từ xa (trong một tiến trình khác), với bất kỳ kết quả nào được trả về
+hàm gọi. Điều này đòi hỏi việc phân tích một lệnh gọi phương pháp và dữ liệu của nó về cấp độ mà hệ điều hành
+có thể hiểu được, truyền phát nó từ tiến trình và khoảng trống địa chỉ cục bộ đến tiến trình và
+khoảng trống địa chỉ từ xa, sau đó tổ hợp lại và phát hành lại lệnh gọi ở đó. Sau đó, các giá trị trả về được
+phát theo hướng ngược lại. Android cung cấp tất cả mã để thực hiện những giao tác
+IPC này, vì thế bạn có thể tập trung vào việc định nghĩa và triển khai giao diện lập trình RPC. </p>
+
+<p>Để thực hiện IPC, ứng dụng của bạn phải liên kết với một dịch vụ, bằng cách sử dụng {@link
+android.content.Context#bindService bindService()}. Để biết thêm thông tin, hãy xem hướng dẫn cho nhà phát triển <a href="{@docRoot}guide/components/services.html">Dịch vụ</a>.</p>
+
+
+<!--
+<h2>Beginner's Path</h2>
+
+<p>For information about how to perform work in the background for an indefinite period of time
+(without a user interface), continue with the <b><a
+href="{@docRoot}guide/components/services.html">Services</a></b> document.</p>
+-->
diff --git a/docs/html-intl/intl/vi/guide/components/recents.jd b/docs/html-intl/intl/vi/guide/components/recents.jd
new file mode 100644
index 000000000000..0a176145f9ca
--- /dev/null
+++ b/docs/html-intl/intl/vi/guide/components/recents.jd
@@ -0,0 +1,256 @@
+page.title=Màn hình Tổng quan
+page.tags="recents","overview"
+
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+ <h2>Trong tài liệu này</h2>
+ <ol>
+ <li><a href="#adding">Thêm Tác vụ vào Màn hình Tổng quan</a>
+ <ol>
+ <li><a href="#flag-new-doc">Sử dụng cờ Ý định để thêm một tác vụ</a></li>
+ <li><a href="#attr-doclaunch">Sử dụng thuộc tính Hoạt động để thêm một tác vụ</a></li>
+ </ol>
+ </li>
+ <li><a href="#removing">Loại bỏ Tác vụ</a>
+ <ol>
+ <li><a href="#apptask-remove">Sử dụng lớp AppTask để loại bỏ tác vụ</a></li>
+ <li><a href="#retain-finished">Giữ lại tác vụ đã hoàn thành</a></li>
+ </ol>
+ </li>
+ </ol>
+
+ <h2>Lớp khóa</h2>
+ <ol>
+ <li>{@link android.app.ActivityManager.AppTask}</li>
+ <li>{@link android.content.Intent}</li>
+ </ol>
+
+ <h2>Mã mẫu</h2>
+ <ol>
+ <li><a href="{@docRoot}samples/DocumentCentricApps/index.html">Ứng dụng tập trung vào tài liệu</a></li>
+ </ol>
+
+</div>
+</div>
+
+<p>Màn hình tổng quan (còn được gọi là màn hình gần đây, danh sách tác vụ gần đây, hay ứng dụng gần đây)
+là một UI cấp hệ thống liệt kê các <a href="{@docRoot}guide/components/activities.html">
+hoạt động</a> và <a href="{@docRoot}guide/components/tasks-and-back-stack.html">tác vụ</a> mới được truy cập gần đây. Người dùng
+có thể điều hướng qua danh sách này và chọn một tác vụ để tiếp tục, hoặc người dùng có thể loại bỏ một tác vụ khỏi
+danh sách bằng cách trượt nhanh nó đi. Với việc phát hành Android 5.0 (API mức 21), nhiều thực thể của
+hoạt động tương tự chứa các tài liệu khác nhau có thể xuất hiện dưới dạng các tác vụ trong màn hình tổng quan. Ví dụ,
+Google Drive có thể có một tác vụ cho từng tài liệu trong một vài tài liệu Google. Mỗi tài liệu xuất hiện thành một
+tác vụ trong màn hình tổng quan.</p>
+
+<img src="{@docRoot}images/components/recents.png" alt="" width="284" />
+<p class="img-caption"><strong>Hình 1.</strong> Màn hình tổng quan hiển thị ba tài liệu Google Drive
+, mỗi tài liệu được biểu diễn như một tác vụ riêng.</p>
+
+<p>Thường thì bạn sẽ cho phép hệ thống định nghĩa cách tác vụ và
+hoạt động của mình được biểu diễn như thế nào trong màn hình tổng quan, và bạn không cần sửa đổi hành vi này.
+Tuy nhiên, ứng dụng của bạn có thể xác định cách thức và thời gian các hoạt động xuất hiện trong màn hình tổng quan. Lớp
+{@link android.app.ActivityManager.AppTask} cho phép bạn quản lý tác vụ, và cờ hoạt động của
+lớp {@link android.content.Intent} cho phép bạn quy định khi nào thì một hoạt động được thêm hoặc loại bỏ khỏi
+màn hình tổng quan. Đồng thời, thuộc tính <code><a href="{@docRoot}guide/topics/manifest/activity-element.html">
+&lt;activity&gt;</a></code> cho phép bạn đặt hành vi trong bản kê khai.</p>
+
+<h2 id="adding">Thêm Tác vụ vào Màn hình Tổng quan</h2>
+
+<p>Sử dụng cờ của lớp {@link android.content.Intent} để thêm một tác vụ cho phép kiểm soát nhiều hơn
+đối với thời điểm và cách thức một tài liệu được mở hoặc mở lại trong màn hình tổng quan. Khi sử dụng các thuộc tính
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
+, bạn có thể chọn giữa luôn mở tài liệu trong một tác vụ mới hoặc sử dụng lại một
+tác vụ hiện có cho tài liệu.</p>
+
+<h3 id="flag-new-doc">Sử dụng cờ Ý định để thêm một tác vụ</h3>
+
+<p>Khi tạo một tài liệu mới cho hoạt động của bạn, bạn gọi phương pháp
+{@link android.app.ActivityManager.AppTask#startActivity(android.content.Context, android.content.Intent, android.os.Bundle) startActivity()}
+của lớp {@link android.app.ActivityManager.AppTask}, chuyển cho nó ý định có
+chức năng khởi chạy hoạt động. Để chèn một ngắt lô-gic sao cho hệ thống coi hoạt động của bạn như một tác vụ
+mới trong màn hình tổng quan, hãy chuyển cờ {@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT}
+trong phương pháp {@link android.content.Intent#addFlags(int) addFlags()} của {@link android.content.Intent}
+có chức năng khởi chạy hoạt động.</p>
+
+<p class="note"><strong>Lưu ý:</strong> Cờ {@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT}
+thay thế cờ {@link android.content.Intent#FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET},
+được rút bớt kể từ phiên bản Android 5.0 (API mức 21).</p>
+
+<p>Nếu bạn đặt cờ {@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK} khi tạo
+tài liệu mới, hệ thống sẽ luôn tạo một tác vụ mới lấy hoạt động mục tiêu đó làm gốc.
+Thiết đặt này cho phép mở cùng tài liệu trong nhiều hơn một tác vụ. Đoạn mã sau thể hiện
+cách mà hoạt động chính thực hiện điều này:</p>
+
+<p class="code-caption"><a href="{@docRoot}samples/DocumentCentricApps/index.html">
+DocumentCentricActivity.java</a></p>
+<pre>
+public void createNewDocument(View view) {
+ final Intent newDocumentIntent = newDocumentIntent();
+ if (useMultipleTasks) {
+ newDocumentIntent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
+ }
+ startActivity(newDocumentIntent);
+ }
+
+ private Intent newDocumentIntent() {
+ boolean useMultipleTasks = mCheckbox.isChecked();
+ final Intent newDocumentIntent = new Intent(this, NewDocumentActivity.class);
+ newDocumentIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT);
+ newDocumentIntent.putExtra(KEY_EXTRA_NEW_DOCUMENT_COUNTER, incrementAndGet());
+ return newDocumentIntent;
+ }
+
+ private static int incrementAndGet() {
+ Log.d(TAG, "incrementAndGet(): " + mDocumentCounter);
+ return mDocumentCounter++;
+ }
+}
+</pre>
+
+<p class="note"><strong>Lưu ý:</strong> Các hoạt động được khởi chạy bằng cờ {@code FLAG_ACTIVITY_NEW_DOCUMENT}
+phải có giá trị thuộc tính {@code android:launchMode="standard"} (mặc định) được đặt trong
+bản kê khai.</p>
+
+<p>Khi hoạt động chính khởi chạy một hoạt động mới, hệ thống sẽ tìm kiếm thông qua các tác vụ hiện tại để
+xem tác vụ nào có ý định khớp với tên thành phần ý định và dữ liệu Ý định cho hoạt động đó. Nếu tác vụ
+không được tìm thấy, hoặc ý định chứa cờ {@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK}
+thì một tác vụ mới sẽ được tạo lấy hoạt động làm gốc. Nếu tìm thấy, nó sẽ mang tác vụ đó
+tới phía trước và chuyển ý định mới tới {@link android.app.Activity#onNewIntent onNewIntent()}.
+Hoạt động mới sẽ nhận ý định và tạo một tài liệu mới trong màn hình tổng quan, như trong ví dụ
+sau:</p>
+
+<p class="code-caption"><a href="{@docRoot}samples/DocumentCentricApps/index.html">
+NewDocumentActivity.java</a></p>
+<pre>
+&#64;Override
+protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_new_document);
+ mDocumentCount = getIntent()
+ .getIntExtra(DocumentCentricActivity.KEY_EXTRA_NEW_DOCUMENT_COUNTER, 0);
+ mDocumentCounterTextView = (TextView) findViewById(
+ R.id.hello_new_document_text_view);
+ setDocumentCounterText(R.string.hello_new_document_counter);
+}
+
+&#64;Override
+protected void onNewIntent(Intent intent) {
+ super.onNewIntent(intent);
+ /* If FLAG_ACTIVITY_MULTIPLE_TASK has not been used, this activity
+ is reused to create a new document.
+ */
+ setDocumentCounterText(R.string.reusing_document_counter);
+}
+</pre>
+
+
+<h3 id="#attr-doclaunch">Sử dụng thuộc tính hoạt động để thêm một tác vụ</h3>
+
+<p>Một hoạt động cũng có thể quy định trong bản kê khai của nó rằng nó luôn khởi chạy vào một tác vụ mới bằng cách sử dụng
+thuộc tính <code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
+, <a href="{@docRoot}guide/topics/manifest/activity-element.html#dlmode">
+{@code android:documentLaunchMode}</a>. Thuộc tính này có bốn giá trị tạo ra hiệu ứng
+sau khi người dùng mở một tài liệu bằng ứng dụng:</p>
+
+<dl>
+ <dt>"{@code intoExisting}"</dt>
+ <dd>Hoạt động sử dụng lại một tác vụ hiện có cho tài liệu. Điều này giống như khi thiết đặt cờ
+ {@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT} mà <em>không</em> thiết đặt cờ
+ {@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK}, như được mô tả trong phần
+ <a href="#flag-new-doc">Sử dụng cờ Ý định để thêm một tác vụ</a> bên trên.</dd>
+
+ <dt>"{@code always}"</dt>
+ <dd>Hoạt động tạo một tác vụ mới cho tài liệu, ngay cả khi tài liệu đã được mở. Sử dụng
+ giá trị này giống như thiết đặt cả cờ {@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT}
+ và {@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK}.</dd>
+
+ <dt>"{@code none”}"</dt>
+ <dd>Hoạt động không tạo một tác vụ mới cho tài liệu. Màn hình tổng quan xử lý hoạt động
+ như theo mặc định: nó hiển thị một tác vụ đơn lẻ cho ứng dụng, tác vụ này
+ tiếp tục từ bất kỳ hoạt động nào mà người dùng đã gọi ra cuối cùng.</dd>
+
+ <dt>"{@code never}"</dt>
+ <dd>Hoạt động không tạo một tác vụ mới cho tài liệu. Việc thiết đặt giá trị này sẽ khống chế
+ hành vi của {@link android.content.Intent#FLAG_ACTIVITY_NEW_DOCUMENT}
+ và cờ {@link android.content.Intent#FLAG_ACTIVITY_MULTIPLE_TASK}, nếu một trong hai được đặt
+ trong ý định, và màn hình tổng quan sẽ hiển thị một tác vụ đơn lẻ cho ứng dụng, tác vụ này tiếp tục từ
+ bất kỳ hoạt động nào mà người dùng đã gọi ra cuối cùng.</dd>
+</dl>
+
+<p class="note"><strong>Lưu ý:</strong> Đối với những giá trị ngoài {@code none} và {@code never}
+hoạt động phải được định nghĩa bằng {@code launchMode="standard"}. Nếu thuộc tính này không được quy định thì
+{@code documentLaunchMode="none"} sẽ được sử dụng.</p>
+
+<h2 id="removing">Loại bỏ Tác vụ</h2>
+
+<p>Theo mặc định, một tác vụ tài liệu sẽ tự động được loại bỏ khỏi màn hình tổng quan khi hoạt động của nó
+hoàn thành. Bạn có thể khống chế hành vi này bằng lớp {@link android.app.ActivityManager.AppTask},
+bằng một cờ {@link android.content.Intent}, hoặc bằng một thuộc tính<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">
+&lt;activity&gt;</a></code>.</p>
+
+<p>Bạn có thể luôn loại trừ hoàn toàn một tác vụ khỏi màn hình tổng quan bằng cách thiết đặt thuộc tính
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
+, <a href="{@docRoot}guide/topics/manifest/activity-element.html#exclude">
+{@code android:excludeFromRecents}</a> thành {@code true}.</p>
+
+<p>Bạn có thể thiết đặt số lượng tác vụ tối đa mà ứng dụng của bạn có thể bao gồm trong màn hình tổng quan bằng cách đặt thuộc tính
+ <code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
+ <a href="{@docRoot}guide/topics/manifest/activity-element.html#maxrecents">{@code android:maxRecents}
+</a> thành một giá trị số nguyên. Mặc định là 16. Khi đạt được số tác vụ tối đa,
+tác vụ ít sử dụng gần đây nhất sẽ bị loại bỏ khỏi màn hình tổng quan. Giá trị tối đa {@code android:maxRecents}
+bằng 50 (25 trên các thiết bị có bộ nhớ thấp); giá trị thấp hơn 1 không hợp lệ.</p>
+
+<h3 id="#apptask-remove">Sử dụng lớp AppTask để loại bỏ tác vụ</h3>
+
+<p>Trong hoạt động mà tạo một tác vụ mới trong màn hình tổng quan, bạn có thể
+quy định khi nào thì loại bỏ tác vụ và hoàn thành tất cả các hoạt động gắn liền với nó bằng cách gọi
+phương pháp {@link android.app.ActivityManager.AppTask#finishAndRemoveTask() finishAndRemoveTask()}.</p>
+
+<p class="code-caption"><a href="{@docRoot}samples/DocumentCentricApps/index.html">
+NewDocumentActivity.java</a></p>
+<pre>
+public void onRemoveFromRecents(View view) {
+ // The document is no longer needed; remove its task.
+ finishAndRemoveTask();
+}
+</pre>
+
+<p class="note"><strong>Lưu ý:</strong> Sử dụng phương pháp
+{@link android.app.ActivityManager.AppTask#finishAndRemoveTask() finishAndRemoveTask()}
+sẽ khống chế việc sử dụng tag {@link android.content.Intent#FLAG_ACTIVITY_RETAIN_IN_RECENTS},
+như được trình bày ở bên dưới.</p>
+
+<h3 id="#retain-finished">Giữ lại tác vụ đã hoàn thành</h3>
+
+<p>Nếu bạn muốn giữ lại một tác vụ trong màn hình tổng quan, ngay cả khi hoạt động của nó đã hoàn thành, hãy chuyển
+cờ {@link android.content.Intent#FLAG_ACTIVITY_RETAIN_IN_RECENTS} trong phương pháp
+{@link android.content.Intent#addFlags(int) addFlags()} của Ý định mà khởi chạy hoạt động.</p>
+
+<p class="code-caption"><a href="{@docRoot}samples/DocumentCentricApps/index.html">
+DocumentCentricActivity.java</a></p>
+<pre>
+private Intent newDocumentIntent() {
+ final Intent newDocumentIntent = new Intent(this, NewDocumentActivity.class);
+ newDocumentIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_DOCUMENT |
+ android.content.Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
+ newDocumentIntent.putExtra(KEY_EXTRA_NEW_DOCUMENT_COUNTER, incrementAndGet());
+ return newDocumentIntent;
+}
+</pre>
+
+<p>Để đạt được cùng kết quả như vậy, hãy đặt thuộc tính
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
+<a href="{@docRoot}guide/topics/manifest/activity-element.html#autoremrecents">
+{@code android:autoRemoveFromRecents}</a> thành {@code false}. Giá trị mặc định bằng {@code true}
+đối với các hoạt động tài liệu, và {@code false} đối với các hoạt động thông thường. Việc sử dụng thuộc tính này sẽ khống chế
+cờ {@link android.content.Intent#FLAG_ACTIVITY_RETAIN_IN_RECENTS}, như đã trình bày trước đó.</p>
+
+
+
+
+
+
+
diff --git a/docs/html-intl/intl/vi/guide/components/services.jd b/docs/html-intl/intl/vi/guide/components/services.jd
new file mode 100644
index 000000000000..9e3e6c75eccf
--- /dev/null
+++ b/docs/html-intl/intl/vi/guide/components/services.jd
@@ -0,0 +1,813 @@
+page.title=Dịch vụ
+@jd:body
+
+<div id="qv-wrapper">
+<ol id="qv">
+<h2>Trong tài liệu này</h2>
+<ol>
+<li><a href="#Basics">Nội dung Cơ bản</a></li>
+<ol>
+ <li><a href="#Declaring">Khai báo một dịch vụ trong bản kê khai</a></li>
+</ol>
+<li><a href="#CreatingAService">Tạo một Dịch vụ được Bắt đầu</a>
+ <ol>
+ <li><a href="#ExtendingIntentService">Mở rộng lớp IntentService</a></li>
+ <li><a href="#ExtendingService">Mở rộng lớp Dịch vụ</a></li>
+ <li><a href="#StartingAService">Bắt đầu một dịch vụ</a></li>
+ <li><a href="#Stopping">Dừng một dịch vụ</a></li>
+ </ol>
+</li>
+<li><a href="#CreatingBoundService">Tạo một Dịch vụ Gắn kết</a></li>
+<li><a href="#Notifications">Gửi Thông báo tới Người dùng</a></li>
+<li><a href="#Foreground">Chạy một Dịch vụ trong Tiền cảnh</a></li>
+<li><a href="#Lifecycle">Quản lý Vòng đời của một Dịch vụ</a>
+<ol>
+ <li><a href="#LifecycleCallbacks">Triển khai gọi lại vòng đời</a></li>
+</ol>
+</li>
+</ol>
+
+<h2>Lớp khóa</h2>
+<ol>
+ <li>{@link android.app.Service}</li>
+ <li>{@link android.app.IntentService}</li>
+</ol>
+
+<h2>Mẫu</h2>
+<ol>
+ <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/ServiceStartArguments.html">{@code
+ ServiceStartArguments}</a></li>
+ <li><a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/app/LocalService.html">{@code
+ LocalService}</a></li>
+</ol>
+
+<h2>Xem thêm</h2>
+<ol>
+<li><a href="{@docRoot}guide/components/bound-services.html">Dịch vụ Gắn kết</a></li>
+</ol>
+
+</div>
+
+
+<p>{@link android.app.Service} là một thành phần ứng dụng có khả năng thực hiện
+các thao tác chạy kéo dài trong nền và không cung cấp giao diện người dùng. Một
+thành phần ứng dụng khác có thể bắt đầu một dịch vụ và nó sẽ tiếp tục chạy ngầm ngay cả khi người dùng
+chuyển sang một ứng dụng khác. Ngoài ra, một thành phần có thể gắn kết với một dịch vụ để
+tương tác với nó và thậm chí thực hiện truyền thông liên tiến trình (IPC). Ví dụ, một dịch vụ có thể
+xử lý các giao dịch mạng, phát nhạc, thực hiện I/O tệp, hoặc tương tác với một trình cung cấp nội dung, tất cả
+đều xuất phát từ nền.</p>
+
+<p>Về cơ bản, một dịch vụ có thể có hai dạng:</p>
+
+<dl>
+ <dt>Được bắt đầu</dt>
+ <dd>Dịch vụ có dạng "được bắt đầu" khi một thành phần ứng dụng (chẳng hạn như một hoạt động) bắt đầu nó bằng cách
+gọi {@link android.content.Context#startService startService()}. Sau khi được bắt đầu, dịch vụ
+có thể chạy ngầm vô thời hạn, ngay cả khi thành phần bắt đầu nó bị hủy. Thông thường,
+dịch vụ được bắt đầu sẽ thực hiện một thao tác đơn lẻ và không trả về kết quả cho hàm gọi.
+Ví dụ, nó có thể tải xuống hoặc tải lên một tệp thông qua mạng. Khi thao tác được hoàn thành, dịch vụ
+tự nó sẽ dừng lại.</dd>
+ <dt>Gắn kết</dt>
+ <dd>Dịch vụ có dạng "gắn kết" khi một thành phần ứng dụng gắn kết với nó bằng cách gọi {@link
+android.content.Context#bindService bindService()}. Dịch vụ gắn kết sẽ đưa ra
+một giao diện máy khách-máy chủ cho phép các thành phần tương tác với dịch vụ, gửi yêu cầu, nhận kết quả, và thậm chí
+làm vậy thông qua truyền thông liên tiến trình (IPC). Dịch vụ gắn kết chỉ chạy trong khi
+một thành phần ứng dụng khác được gắn kết với nó. Nhiều thành phần có thể gắn kết cùng lúc với dịch vụ,
+nhưng khi tất cả bị bỏ gắn kết thì dịch vụ sẽ bị hủy.</dd>
+</dl>
+
+<p>Mặc dù tài liệu này thường đề cập tới hai loại dịch vụ riêng rẽ, dịch vụ
+của bạn có thể hoạt động theo cả hai cách&mdash;nó có thể được bắt đầu (để chạy vô thời hạn) và cũng cho phép gắn kết.
+Đó đơn giản là vấn đề bạn có triển khai một cặp phương pháp gọi lại hay không: {@link
+android.app.Service#onStartCommand onStartCommand()} để cho phép thành phần bắt đầu nó và {@link
+android.app.Service#onBind onBind()} để cho phép nó gắn kết.</p>
+
+<p>Không phụ thuộc vào việc ứng dụng của bạn được bắt đầu, gắn kết, hay cả hai, bất kỳ thành phần ứng dụng nào
+cũng có thể sử dụng dịch vụ (thậm chí từ một ứng dụng riêng biệt), giống như cách mà bất kỳ thành phần nào cũng có thể sử dụng
+một hoạt động&mdash;bằng cách bắt đầu nó bằng một {@link android.content.Intent}. Tuy nhiên, bạn có thể khai báo
+dịch vụ là riêng tư trong tệp bản kê khai, và chặn truy cập từ các ứng dụng khác. Điều này
+được trình bày kỹ hơn trong phần về <a href="#Declaring">Khai báo dịch vụ trong
+bản kê khai</a>.</p>
+
+<p class="caution"><strong>Chú ý:</strong> Một dịch vụ chạy trong
+luồng chính của tiến trình lưu trữ của nó&mdash;dịch vụ <strong>không</strong> tạo luồng của chính nó
+và <strong>không</strong> chạy trong một tiến trình riêng biệt (trừ khi bạn quy định khác). Điều này có nghĩa
+là, nếu dịch vụ của bạn định thực hiện bất kỳ công việc nặng nào đối với CPU hay chặn các thao tác (chẳng hạn như phát lại MP3
+hay kết nối mạng), bạn nên tạo một luồng mới bên trong dịch vụ để thực hiện công việc đó. Bằng cách sử dụng
+một luồng riêng biệt, bạn sẽ giảm rủi ro gặp lỗi Ứng dụng Không Hồi đáp (ANR) và luồng chính của ứng dụng có thể
+vẫn dành riêng cho tương tác giữa người dùng với các hoạt động của bạn.</p>
+
+
+<h2 id="Basics">Nội dung Cơ bản</h2>
+
+<div class="sidebox-wrapper">
+<div class="sidebox">
+ <h3>Bạn nên sử dụng dịch vụ hay luồng?</h3>
+ <p>Dịch vụ đơn thuần là một thành phần có thể chạy ngầm ngay cả khi người dùng không
+đang tương tác với ứng dụng của bạn. Vì thế, bạn chỉ nên tạo một dịch vụ nếu đó là điều bạn
+cần.</p>
+ <p>Nếu bạn cần thực hiện công việc bên ngoài luồng chính của mình, nhưng chỉ trong khi người dùng đang tương tác với
+ứng dụng của bạn, thì thay vào đó, bạn nên tạo một luồng mới chứ không phải một dịch vụ. Ví
+dụ, nếu bạn muốn phát một bản nhạc, nhưng chỉ trong khi hoạt động của bạn đang chạy, bạn có thể tạo
+một luồng trong {@link android.app.Activity#onCreate onCreate()}, bắt đầu chạy nó trong {@link
+android.app.Activity#onStart onStart()}, rồi dừng nó trong {@link android.app.Activity#onStop
+onStop()}. Cũng xem xét việc sử dụng {@link android.os.AsyncTask} hoặc {@link android.os.HandlerThread},
+thay vì sử dụng lớp {@link java.lang.Thread} truyền thống. Xem tài liệu <a href="{@docRoot}guide/components/processes-and-threads.html#Threads">Tiến trình và
+Luồng</a> để biết thêm thông tin về luồng.</p>
+ <p>Hãy nhớ rằng nếu bạn sử dụng một dịch vụ, nó vẫn chạy trong luồng chính của ứng dụng của bạn theo
+mặc định, vì thế bạn vẫn nên tạo một luồng mới trong dịch vụ nếu nó thực hiện các thao tác tăng cường hoặc
+chặn.</p>
+</div>
+</div>
+
+<p>Để tạo một dịch vụ, bạn phải tạo một lớp con của {@link android.app.Service} (hoặc một
+trong các lớp con hiện tại của nó). Trong triển khai của mình, bạn cần khống chế một số phương pháp gọi lại có chức năng
+xử lý những khía cạnh chính trong vòng đời của dịch vụ và cung cấp một cơ chế để các thành phần gắn kết với
+dịch vụ đó, nếu phù hợp. Những phương pháp gọi lại quan trọng nhất mà bạn nên khống chế là:</p>
+
+<dl>
+ <dt>{@link android.app.Service#onStartCommand onStartCommand()}</dt>
+ <dd>Hệ thống sẽ gọi phương pháp này khi một thành phần khác, chẳng hạn như một hoạt động,
+yêu cầu dịch vụ phải được bắt đầu, bằng cách gọi {@link android.content.Context#startService
+startService()}. Sau khi phương pháp này thực thi, dịch vụ sẽ được bắt đầu và có thể chạy vô thời hạn trong
+nền. Nếu bạn triển khai điều này, bạn có trách nhiệm dừng dịch vụ khi
+công việc của nó được hoàn thành, bằng cách gọi {@link android.app.Service#stopSelf stopSelf()} hoặc {@link
+android.content.Context#stopService stopService()}. (Nếu chỉ muốn cung cấp khả năng gắn kết, bạn không
+cần triển khai phương pháp này.)</dd>
+ <dt>{@link android.app.Service#onBind onBind()}</dt>
+ <dd>Hệ thống sẽ gọi phương pháp này khi một thành phần khác muốn gắn kết với
+dịch vụ (chẳng hạn như để thực hiện RPC), bằng cách gọi {@link android.content.Context#bindService
+bindService()}. Trong triển khai phương pháp này của mình, bạn phải cung cấp một giao diện mà các máy khách
+sử dụng để giao tiếp với dịch vụ, bằng cách trả về {@link android.os.IBinder}. Bạn phải luôn
+triển khai phương pháp này, nhưng nếu bạn không muốn cho phép gắn kết thì bạn nên trả về rỗng.</dd>
+ <dt>{@link android.app.Service#onCreate()}</dt>
+ <dd>Hệ thống sẽ gọi phương pháp này khi dịch vụ được tạo lập lần đầu, để thực hiện quy trình thiết lập một lần
+(trước khi nó có thể gọi hoặc {@link android.app.Service#onStartCommand onStartCommand()} hoặc
+{@link android.app.Service#onBind onBind()}). Nếu dịch vụ đã đang chạy, phương pháp này sẽ không được
+gọi.</dd>
+ <dt>{@link android.app.Service#onDestroy()}</dt>
+ <dd>Hệ thống sẽ gọi phương pháp này khi dịch vụ không còn được sử dụng và đang bị hủy.
+Dịch vụ của bạn sẽ triển khai phương pháp này để dọn dẹp mọi tài nguyên như luồng, đối tượng theo dõi
+được đăng ký, hàm nhận, v.v... Đây là lệnh gọi cuối cùng mà dịch vụ nhận được.</dd>
+</dl>
+
+<p>Nếu một thành phần bắt đầu dịch vụ bằng cách gọi {@link
+android.content.Context#startService startService()} (kết quả là một lệnh gọi tới {@link
+android.app.Service#onStartCommand onStartCommand()}), khi đó dịch vụ
+sẽ vẫn chạy tới khi tự nó dừng bằng {@link android.app.Service#stopSelf()} hoặc một
+thành phần khác dừng nó bằng cách gọi {@link android.content.Context#stopService stopService()}.</p>
+
+<p>Nếu một thành phần gọi
+{@link android.content.Context#bindService bindService()} để tạo dịch vụ (và {@link
+android.app.Service#onStartCommand onStartCommand()} <em>không</em> được gọi), khi đó dịch vụ sẽ chỉ chạy
+khi nào mà thành phần đó còn gắn kết với nó. Sau khi dịch vụ được bỏ gắn kết khỏi tất cả máy khách, hệ thống
+sẽ hủy nó.</p>
+
+<p>Hệ thống Android sẽ buộc dừng một dịch vụ chỉ khi bộ nhớ thấp và nó phải khôi phục tài nguyên
+của hệ thống cho hoạt động có tiêu điểm của người dùng. Nếu dịch vụ gắn kết với một hoạt động mà có tiêu điểm
+của người dùng, khi đó sẽ có ít khả năng nó sẽ bị tắt bỏ hơn, và nếu dịch vụ được khai báo là <a href="#Foreground">chạy trong tiền cảnh</a> (đề cập sau), khi đó nó sẽ hầu như không bao giờ bị tắt bỏ.
+Mặt khác, nếu dịch vụ được bắt đầu và chạy trong thời gian dài, hệ thống sẽ hạ thấp vị trí của nó
+trong danh sách tác vụ chạy ngầm qua thời gian và dịch vụ sẽ rất có thể bị
+tắt bỏ&mdash;nếu dịch vụ của bạn được bắt đầu, khi đó bạn phải thiết kế nó để
+xử lý việc khởi động lại do hệ thống một cách uyển chuyển. Nếu hệ thống tắt bỏ dịch vụ của bạn, nó sẽ khởi động lại dịch vụ ngay khi tài nguyên
+có sẵn trở lại (mặc dù điều này cũng phụ thuộc vào giá trị mà bạn trả về từ {@link
+android.app.Service#onStartCommand onStartCommand()}, vấn đề này sẽ được bàn sau). Để biết thêm thông tin
+về thời điểm mà hệ thống có thể hủy một dịch vụ, hãy xem tài liệu <a href="{@docRoot}guide/components/processes-and-threads.html">Tiến trình và Luồng</a>
+.</p>
+
+<p>Trong những phần sau, bạn sẽ thấy cách bạn có thể tạo từng loại dịch vụ và cách sử dụng
+nó từ các thành phần ứng dụng khác.</p>
+
+
+
+<h3 id="Declaring">Khai báo một dịch vụ trong bản kê khai</h3>
+
+<p>Giống như hoạt động (và các thành phần khác), bạn phải khai báo tất cả dịch vụ trong tệp bản kê khai
+của ứng dụng của mình.</p>
+
+<p>Để khai báo dịch vụ của bạn, hãy thêm một phần tử <a href="{@docRoot}guide/topics/manifest/service-element.html">{@code &lt;service&gt;}</a> làm
+con của phần tử <a href="{@docRoot}guide/topics/manifest/application-element.html">{@code &lt;application&gt;}</a>
+. Ví dụ:</p>
+
+<pre>
+&lt;manifest ... &gt;
+ ...
+ &lt;application ... &gt;
+ &lt;service android:name=".ExampleService" /&gt;
+ ...
+ &lt;/application&gt;
+&lt;/manifest&gt;
+</pre>
+
+<p>Xem tham chiếu phần tử <a href="{@docRoot}guide/topics/manifest/service-element.html">{@code &lt;service&gt;}</a>
+để biết thêm thông tin về việc khai báo dịch vụ của bạn trong bản kê khai.</p>
+
+<p>Có các thuộc tính khác mà bạn có thể bao gồm trong phần tử <a href="{@docRoot}guide/topics/manifest/service-element.html">{@code &lt;service&gt;}</a> để
+định nghĩa các tính chất chẳng hạn như những quyền cần để bắt đầu dịch vụ và tiến trình mà
+dịch vụ sẽ chạy trong đó. Thuộc tính <a href="{@docRoot}guide/topics/manifest/service-element.html#nm">{@code android:name}</a>
+là thuộc tính bắt buộc duy nhất&mdash;nó quy định tên lớp của dịch vụ. Một khi
+bạn phát hành ứng dụng của mình, bạn không nên thay đổi tên này, vì nếu bạn làm vậy, bạn sẽ gặp rủi ro làm gãy
+mã do sự phụ thuộc vào các ý định biểu thị để bắt đầu hoặc gắn kết dịch vụ (đọc bài đăng blog, <a href="http://android-developers.blogspot.com/2011/06/things-that-cannot-change.html">Những Điều
+Không Thay Đổi Được</a>).
+
+<p>Để đảm bảo ứng dụng của bạn được bảo mật, <strong>luôn sử dụng một ý định biểu thị khi bắt đầu hoặc gắn kết
+{@link android.app.Service}</strong> của bạn và không được khai báo bộ lọc ý định cho dịch vụ. Nếu
+điều trọng yếu là bạn phải cho phép một chút không rõ ràng về dịch vụ nào sẽ bắt đầu, bạn có thể
+cung cấp bộ lọc ý định cho dịch vụ của mình và loại bỏ tên thành phần khỏi {@link
+android.content.Intent}, nhưng sau đó bạn có thể đặt gói cho ý định bằng {@link
+android.content.Intent#setPackage setPackage()}, điều này cung cấp sự không rõ ràng vừa đủ cho
+dịch vụ mục tiêu đó.</p>
+
+<p>Ngoài ra, bạn có thể đảm bảo rằng dịch vụ của mình chỉ sẵn có cho ứng dụng của bạn bằng cách
+đưa vào thuộc tính <a href="{@docRoot}guide/topics/manifest/service-element.html#exported">{@code android:exported}</a>
+và đặt nó thành {@code "false"}. Điều này sẽ dừng việc các ứng dụng khác bắt đầu
+dịch vụ của bạn, ngay cả khi sử dụng một ý định biểu thị.</p>
+
+
+
+
+<h2 id="CreatingStartedService">Tạo một Dịch vụ được Bắt đầu</h2>
+
+<p>Dịch vụ được bắt đầu là dịch vụ mà một thành phần khác bắt đầu bằng cách gọi {@link
+android.content.Context#startService startService()}, kết quả là một lệnh gọi tới phương pháp
+{@link android.app.Service#onStartCommand onStartCommand()} của dịch vụ.</p>
+
+<p>Khi một dịch vụ được bắt đầu, nó có một vòng đời độc lập với
+thành phần đã bắt đầu nó và dịch vụ có thể chạy ngầm vô thời hạn, ngay cả khi
+thành phần bắt đầu nó bị hủy. Như vậy, dịch vụ sẽ tự dừng khi làm xong công việc của nó
+bằng cách gọi {@link android.app.Service#stopSelf stopSelf()}, hoặc một thành phần khác có thể dừng nó
+bằng cách gọi {@link android.content.Context#stopService stopService()}.</p>
+
+<p>Một thành phần ứng dụng chẳng hạn như một hoạt động có thể bắt đầu dịch vụ bằng cách gọi {@link
+android.content.Context#startService startService()} và chuyển một {@link android.content.Intent}
+trong đó quy định dịch vụ và bao gồm bất kỳ dữ liệu nào để cho dịch vụ sử dụng. Dịch vụ sẽ nhận
+{@link android.content.Intent} này trong phương pháp {@link android.app.Service#onStartCommand
+onStartCommand()}.</p>
+
+<p>Ví dụ, giả sử một hoạt động cần lưu một số dữ liệu vào cơ sở dữ liệu trực tuyến. Hoạt động có thể
+bắt đầu một dịch vụ đồng hành và truyền cho nó dữ liệu để lưu bằng cách chuyển một ý định tới {@link
+android.content.Context#startService startService()}. Dịch vụ sẽ nhận ý định trong {@link
+android.app.Service#onStartCommand onStartCommand()}, kết nối với Internet và thực hiện
+giao tác cơ sở dữ liệu. Khi giao tác được thực hiện, dịch vụ sẽ tự dừng lại và nó bị
+hủy.</p>
+
+<p class="caution"><strong>Chú ý:</strong> Một dịch vụ sẽ chạy trong cùng tiến trình như ứng dụng
+mà nó được khai báo trong đó và trong luồng chính của ứng dụng đó theo mặc định. Vì vậy, nếu dịch vụ của bạn
+thực hiện các thao tác tăng cường hoặc chặn trong khi người dùng tương tác với một hoạt động từ cùng
+ứng dụng, dịch vụ sẽ làm chậm hiệu năng của hoạt động. Để tránh tác động tới hiệu năng của
+ứng dụng, bạn nên bắt đầu một luồng mới bên trong dịch vụ.</p>
+
+<p>Thông thường, có hai lớp mà bạn có thể mở rộng để tạo một dịch vụ được bắt đầu:</p>
+<dl>
+ <dt>{@link android.app.Service}</dt>
+ <dd>Đây là lớp cơ bản cho tất cả dịch vụ. Khi bạn mở rộng lớp này, điều quan trọng là
+bạn tạo một luồng mới để thực hiện tất cả công việc của dịch vụ trong đó, do dịch vụ sử dụng luồng chính
+của ứng dụng của bạn, theo mặc định, điều này có thể làm chậm hiệu năng của bất kỳ hoạt động nào mà ứng dụng
+của bạn đang chạy.</dd>
+ <dt>{@link android.app.IntentService}</dt>
+ <dd>Đây là một lớp con của {@link android.app.Service} có chức năng sử dụng một luồng trình thực hiện để xử lý tất cả
+yêu cầu bắt đầu một cách lần lượt. Đây là lựa chọn tốt nhất nếu bạn không yêu cầu dịch vụ của mình
+xử lý đồng thời nhiều yêu cầu. Tất cả những gì bạn cần làm đó là triển khai {@link
+android.app.IntentService#onHandleIntent onHandleIntent()}, nó sẽ nhận ý định cho mỗi
+yêu cầu bắt đầu để bạn có thể thực hiện công việc chạy ngầm.</dd>
+</dl>
+
+<p>Các phần sau mô tả cách bạn có thể triển khai dịch vụ của mình bằng cách sử dụng một trong các cách cho những lớp
+này.</p>
+
+
+<h3 id="ExtendingIntentService">Mở rộng lớp IntentService</h3>
+
+<p>Vì phần lớn các dịch vụ được bắt đầu không cần xử lý nhiều yêu cầu một cách đồng thời
+(điều này thực sự có thể là một kịch bản tạo đa luồng nguy hiểm), có lẽ tốt nhất là nếu bạn
+triển khai dịch vụ của mình bằng cách sử dụng lớp {@link android.app.IntentService}.</p>
+
+<p>{@link android.app.IntentService} làm điều sau đây:</p>
+
+<ul>
+ <li>Tạo một luồng trình thực hiện mặc định để thực thi tất cả ý định được chuyển tới {@link
+android.app.Service#onStartCommand onStartCommand()} tách riêng với luồng
+chính của ứng dụng của bạn.</li>
+ <li>Tạo một hàng đợi công việc để chuyển lần lượt từng ý định tới triển khai {@link
+android.app.IntentService#onHandleIntent onHandleIntent()} của bạn, vì thế bạn không bao giờ phải
+lo lắng về vấn đề tạo đa luồng.</li>
+ <li>Dừng dịch vụ sau khi tất cả yêu cầu bắt đầu đều đã được xử lý, vì thế bạn không bao giờ phải gọi
+{@link android.app.Service#stopSelf}.</li>
+ <li>Cung cấp triển khai mặc định của {@link android.app.IntentService#onBind onBind()} mà
+trả về rỗng.</li>
+ <li>Cung cấp triển khai mặc định của {@link android.app.IntentService#onStartCommand
+onStartCommand()} mà gửi ý định tới hàng đợi công việc rồi tới triển khai {@link
+android.app.IntentService#onHandleIntent onHandleIntent()} của bạn.</li>
+</ul>
+
+<p>Tất cả đều nói lên một thực tế rằng tất cả những việc bạn cần làm đó là triển khai {@link
+android.app.IntentService#onHandleIntent onHandleIntent()} để thực hiện công việc mà
+máy khách cung cấp. (Mặc dù bạn cũng cần cung cấp một hàm dựng nhỏ cho dịch vụ.)</p>
+
+<p>Sau đây là ví dụ về triển khai {@link android.app.IntentService}:</p>
+
+<pre>
+public class HelloIntentService extends IntentService {
+
+ /**
+ * A constructor is required, and must call the super {@link android.app.IntentService#IntentService}
+ * constructor with a name for the worker thread.
+ */
+ public HelloIntentService() {
+ super("HelloIntentService");
+ }
+
+ /**
+ * The IntentService calls this method from the default worker thread with
+ * the intent that started the service. When this method returns, IntentService
+ * stops the service, as appropriate.
+ */
+ &#64;Override
+ protected void onHandleIntent(Intent intent) {
+ // Normally we would do some work here, like download a file.
+ // For our sample, we just sleep for 5 seconds.
+ long endTime = System.currentTimeMillis() + 5*1000;
+ while (System.currentTimeMillis() &lt; endTime) {
+ synchronized (this) {
+ try {
+ wait(endTime - System.currentTimeMillis());
+ } catch (Exception e) {
+ }
+ }
+ }
+ }
+}
+</pre>
+
+<p>Đó là tất cả những gì bạn cần: một hàm dựng và triển khai {@link
+android.app.IntentService#onHandleIntent onHandleIntent()}.</p>
+
+<p>Nếu bạn quyết định cũng khống chế các phương pháp gọi lại khác, chẳng hạn như {@link
+android.app.IntentService#onCreate onCreate()}, {@link
+android.app.IntentService#onStartCommand onStartCommand()}, hoặc {@link
+android.app.IntentService#onDestroy onDestroy()}, hãy nhớ gọi ra siêu triển khai, sao
+cho {@link android.app.IntentService} có thể xử lý hợp lý vòng đời của luồng trình thực hiện.</p>
+
+<p>Ví dụ, {@link android.app.IntentService#onStartCommand onStartCommand()} phải trả về
+triển khai mặc định (đó là cách mà ý định được chuyển tới {@link
+android.app.IntentService#onHandleIntent onHandleIntent()}):</p>
+
+<pre>
+&#64;Override
+public int onStartCommand(Intent intent, int flags, int startId) {
+ Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
+ return super.onStartCommand(intent,flags,startId);
+}
+</pre>
+
+<p>Bên cạnh {@link android.app.IntentService#onHandleIntent onHandleIntent()}, phương pháp duy nhất mà
+từ đó bạn không cần gọi siêu lớp là {@link android.app.IntentService#onBind
+onBind()} (nhưng bạn chỉ cần triển khai điều đó nếu dịch vụ của bạn cho phép gắn kết).</p>
+
+<p>Trong phần tiếp theo, bạn sẽ thấy cách mà cùng loại dịch vụ được triển khai khi mở rộng
+lớp {@link android.app.Service} cơ sở, nó có nhiều mã hơn nhưng có thể
+phù hợp nếu bạn cần xử lý các yêu cầu bắt đầu đồng thời.</p>
+
+
+<h3 id="ExtendingService">Mở rộng lớp Dịch vụ</h3>
+
+<p>Như bạn thấy trong phần trước, sử dụng {@link android.app.IntentService} giúp việc
+triển khai một dịch vụ được bắt đầu của bạn trở nên rất đơn giản. Tuy nhiên, nếu bạn cần dịch vụ của mình
+thực hiện tạo đa luồng (thay vì xử lý các yêu cầu bắt đầu thông qua một hàng đợi công việc), khi đó bạn
+có thể mở rộng lớp {@link android.app.Service} để xử lý từng ý định.</p>
+
+<p>Để so sánh, đoạn mã mẫu sau là triển khai lớp {@link
+android.app.Service} mà thực hiện chính xác cùng công việc như ví dụ bên trên bằng cách sử dụng {@link
+android.app.IntentService}. Cụ thể, đối với mỗi yêu cầu bắt đầu, nó sẽ sử dụng một luồng trình thực hiện để thực hiện
+công việc và chỉ xử lý lần lượt từng yêu cầu một.</p>
+
+<pre>
+public class HelloService extends Service {
+ private Looper mServiceLooper;
+ private ServiceHandler mServiceHandler;
+
+ // Handler that receives messages from the thread
+ private final class ServiceHandler extends Handler {
+ public ServiceHandler(Looper looper) {
+ super(looper);
+ }
+ &#64;Override
+ public void handleMessage(Message msg) {
+ // Normally we would do some work here, like download a file.
+ // For our sample, we just sleep for 5 seconds.
+ long endTime = System.currentTimeMillis() + 5*1000;
+ while (System.currentTimeMillis() &lt; endTime) {
+ synchronized (this) {
+ try {
+ wait(endTime - System.currentTimeMillis());
+ } catch (Exception e) {
+ }
+ }
+ }
+ // Stop the service using the startId, so that we don't stop
+ // the service in the middle of handling another job
+ stopSelf(msg.arg1);
+ }
+ }
+
+ &#64;Override
+ public void onCreate() {
+ // Start up the thread running the service. Note that we create a
+ // separate thread because the service normally runs in the process's
+ // main thread, which we don't want to block. We also make it
+ // background priority so CPU-intensive work will not disrupt our UI.
+ HandlerThread thread = new HandlerThread("ServiceStartArguments",
+ Process.THREAD_PRIORITY_BACKGROUND);
+ thread.start();
+
+ // Get the HandlerThread's Looper and use it for our Handler
+ mServiceLooper = thread.getLooper();
+ mServiceHandler = new ServiceHandler(mServiceLooper);
+ }
+
+ &#64;Override
+ public int onStartCommand(Intent intent, int flags, int startId) {
+ Toast.makeText(this, "service starting", Toast.LENGTH_SHORT).show();
+
+ // For each start request, send a message to start a job and deliver the
+ // start ID so we know which request we're stopping when we finish the job
+ Message msg = mServiceHandler.obtainMessage();
+ msg.arg1 = startId;
+ mServiceHandler.sendMessage(msg);
+
+ // If we get killed, after returning from here, restart
+ return START_STICKY;
+ }
+
+ &#64;Override
+ public IBinder onBind(Intent intent) {
+ // We don't provide binding, so return null
+ return null;
+ }
+
+ &#64;Override
+ public void onDestroy() {
+ Toast.makeText(this, "service done", Toast.LENGTH_SHORT).show();
+ }
+}
+</pre>
+
+<p>Như bạn có thể thấy, có nhiều việc hơn nhiều so với việc sử dụng {@link android.app.IntentService}.</p>
+
+<p>Tuy nhiên, do bạn tự mình xử lý từng lệnh gọi đến {@link android.app.Service#onStartCommand
+onStartCommand()}, bạn có thể thực hiện nhiều yêu cầu một cách đồng thời. Đó không phải là việc
+mà ví dụ này làm, nhưng nếu đó là việc bạn muốn, vậy bạn có thể tạo một luồng mới cho từng
+yêu cầu và ngay lập tức trả chúng về (thay vì đợi tới khi yêu cầu trước hoàn thành).</p>
+
+<p>Để ý rằng phương pháp {@link android.app.Service#onStartCommand onStartCommand()} phải trả về một
+số nguyên. Số nguyên là một giá trị mô tả cách hệ thống nên tiếp tục dịch vụ trong
+trường hợp hệ thống tắt bỏ nó (như được đề cập ở trên, triển khai mặc định cho {@link
+android.app.IntentService} sẽ xử lý điều này cho bạn dù bạn có thể sửa đổi nó). Giá trị trả về
+từ {@link android.app.Service#onStartCommand onStartCommand()} phải là một trong các
+hằng số sau:</p>
+
+<dl>
+ <dt>{@link android.app.Service#START_NOT_STICKY}</dt>
+ <dd>Nếu hệ thống tắt bỏ dịch vụ sau khi {@link android.app.Service#onStartCommand
+onStartCommand()} trả về, <em>không</em> được tạo lại dịch vụ đó, trừ khi có các ý định
+đang chờ để được chuyển. Đây là lựa chọn an toàn nhất để tránh chạy dịch vụ của bạn khi không cần thiết
+và khi ứng dụng của bạn có thể đơn thuần khởi động lại bất kỳ công việc chưa hoàn thành nào.</dd>
+ <dt>{@link android.app.Service#START_STICKY}</dt>
+ <dd>Nếu hệ thống tắt bỏ dịch vụ sau khi {@link android.app.Service#onStartCommand
+onStartCommand()} trả về, hãy tạo lại dịch vụ và gọi {@link
+android.app.Service#onStartCommand onStartCommand()}, nhưng <em>không</em> chuyển lại ý định cuối cùng.
+Thay vào đó, hệ thống sẽ gọi {@link android.app.Service#onStartCommand onStartCommand()} bằng một
+ý định rỗng, trừ khi có các ý định đang chờ để bắt đầu dịch vụ, trong trường hợp đó,
+những ý định này sẽ được chuyển. Điều này phù hợp với các trình phát phương tiện (hoặc dịch vụ tương tự) mà không
+đang thực thi lệnh, nhưng đang chạy vô thời hạn và chờ một tác vụ.</dd>
+ <dt>{@link android.app.Service#START_REDELIVER_INTENT}</dt>
+ <dd>Nếu hệ thống tắt bỏ dịch vụ sau khi {@link android.app.Service#onStartCommand
+onStartCommand()} trả về, hãy tạo lại dịch vụ và gọi {@link
+android.app.Service#onStartCommand onStartCommand()} bằng ý định cuối cùng được chuyển tới
+dịch vụ. Mọi ý định chờ đều được chuyển lần lượt. Điều này phù hợp với các dịch vụ đang
+chủ động thực hiện một công việc mà nên được tiếp tục ngay lập tức, chẳng hạn như tải xuống một tệp.</dd>
+</dl>
+<p>Để biết thêm chi tiết về những giá trị trả về này, hãy xem tài liệu tham khảo được liên kết cho từng
+hằng số.</p>
+
+
+
+<h3 id="StartingAService">Bắt đầu một Dịch vụ</h3>
+
+<p>Bạn có thể bắt đầu một dịch vụ từ một hoạt động hoặc thành phần ứng dụng khác bằng cách chuyển một
+{@link android.content.Intent} (quy định dịch vụ sẽ bắt đầu) đến {@link
+android.content.Context#startService startService()}. Hệ thống Android sẽ gọi phương pháp {@link
+android.app.Service#onStartCommand onStartCommand()} của dịch vụ và chuyển cho nó {@link
+android.content.Intent}. (Bạn tuyệt đối không nên trực tiếp gọi {@link android.app.Service#onStartCommand
+onStartCommand()}.)</p>
+
+<p>Ví dụ, một hoạt động có thể bắt đầu dịch vụ ví dụ trong phần trước ({@code
+HelloSevice}) bằng cách sử dụng một ý định biểu thị với {@link android.content.Context#startService
+startService()}:</p>
+
+<pre>
+Intent intent = new Intent(this, HelloService.class);
+startService(intent);
+</pre>
+
+<p>Phương pháp {@link android.content.Context#startService startService()} ngay lập tức trả về và
+hệ thống Android sẽ gọi phương pháp {@link android.app.Service#onStartCommand
+onStartCommand()} của dịch vụ. Nếu dịch vụ không đang chạy, trước tiên hệ thống sẽ gọi {@link
+android.app.Service#onCreate onCreate()}, rồi gọi {@link android.app.Service#onStartCommand
+onStartCommand()}.</p>
+
+<p>Nếu dịch vụ cũng không cung cấp khả năng gắn kết, ý định được chuyển bằng {@link
+android.content.Context#startService startService()} sẽ là phương thức giao tiếp duy nhất giữa
+thành phần ứng dụng và dịch vụ. Tuy nhiên, nếu bạn muốn dịch vụ gửi một kết quả trở lại, khi đó
+máy khách mà bắt đầu dịch vụ có thể tạo một {@link android.app.PendingIntent} cho một quảng bá
+(bằng {@link android.app.PendingIntent#getBroadcast getBroadcast()}) và chuyển nó tới dịch vụ
+trong {@link android.content.Intent} mà bắt đầu dịch vụ. Khi đó, dịch vụ có thể sử dụng
+quảng bá để chuyển kết quả.</p>
+
+<p>Nhiều yêu cầu bắt đầu dịch vụ sẽ dẫn đến nhiều lệnh gọi tương ứng tới
+{@link android.app.Service#onStartCommand onStartCommand()} của dịch vụ. Tuy nhiên, chỉ có một yêu cầu dừng
+dịch vụ (bằng {@link android.app.Service#stopSelf stopSelf()} hoặc {@link
+android.content.Context#stopService stopService()}) là bắt buộc để dừng nó.</p>
+
+
+<h3 id="Stopping">Dừng một dịch vụ</h3>
+
+<p>Dịch vụ được bắt đầu phải quản lý vòng đời của chính nó. Cụ thể, hệ thống không dừng
+hay hủy dịch vụ trừ khi nó phải khôi phục bộ nhớ của hệ thống và dịch vụ
+sẽ tiếp tục chạy sau khi {@link android.app.Service#onStartCommand onStartCommand()} trả về. Vì vậy,
+dịch vụ phải tự dừng bằng cách gọi {@link android.app.Service#stopSelf stopSelf()} hoặc một thành phần
+khác có thể dừng nó bằng cách gọi {@link android.content.Context#stopService stopService()}.</p>
+
+<p>Sau khi được yêu cầu dừng bằng {@link android.app.Service#stopSelf stopSelf()} hoặc {@link
+android.content.Context#stopService stopService()}, hệ thống sẽ hủy dịch vụ ngay khi
+có thể.</p>
+
+<p>Tuy nhiên, nếu dịch vụ của bạn xử lý nhiều yêu cầu {@link
+android.app.Service#onStartCommand onStartCommand()} đồng thời, khi đó bạn không nên dừng
+dịch vụ khi bạn đã hoàn thành xử lý yêu cầu bắt đầu, vì bạn có thể đã nhận được một
+yêu cầu bắt đầu mới kể từ thời điểm đó (dừng khi kết thúc yêu cầu thứ nhất sẽ chấm dứt yêu cầu thứ hai). Để tránh
+vấn đề này, bạn có thể sử dụng {@link android.app.Service#stopSelf(int)} để đảm bảo rằng yêu cầu
+dừng dịch vụ của bạn luôn được dựa trên yêu cầu bắt đầu gần đây nhất. Cụ thể, khi bạn gọi {@link
+android.app.Service#stopSelf(int)}, bạn sẽ chuyển ID của yêu cầu bắt đầu (<code>startId</code>
+được chuyển tới {@link android.app.Service#onStartCommand onStartCommand()}) mà yêu cầu dừng của bạn
+tương ứng với. Khi đó, nếu dịch vụ đã nhận được một yêu cầu bắt đầu mới trước khi bạn có thể gọi {@link
+android.app.Service#stopSelf(int)}, vậy ID sẽ không khớp và dịch vụ sẽ không dừng.</p>
+
+<p class="caution"><strong>Chú ý:</strong> Điều quan trọng là ứng dụng của bạn dừng dịch vụ của nó
+khi nó hoàn thành xong công việc để tránh lãng phí tài nguyên của hệ thống và tốn pin. Nếu cần,
+các thành phần khác có thể dừng dịch vụ bằng cách gọi {@link
+android.content.Context#stopService stopService()}. Ngay cả khi bạn kích hoạt gắn kết cho dịch vụ,
+bạn phải luôn tự mình dừng dịch vụ nếu dịch vụ đã nhận được lệnh gọi tới {@link
+android.app.Service#onStartCommand onStartCommand()}.</p>
+
+<p>Để biết thêm thông tin về vòng đời của một dịch vụ, hãy xem phần bên dưới về <a href="#Lifecycle">Quản lý Vòng đời của một Dịch vụ</a>.</p>
+
+
+
+<h2 id="CreatingBoundService">Tạo một Dịch vụ Gắn kết</h2>
+
+<p>Dịch vụ gắn kết là một dịch vụ cho phép các thành phần ứng dụng gắn kết với nó bằng cách gọi {@link
+android.content.Context#bindService bindService()} để tạo một kết nối lâu dài
+(và thường không cho phép các thành phần <em>bắt đầu</em> nó bằng cách gọi {@link
+android.content.Context#startService startService()}).</p>
+
+<p>Bạn nên tạo một dịch vụ gắn kết khi muốn tương tác với dịch vụ từ hoạt động
+và các thành phần khác trong ứng dụng của mình hoặc để hiển thị một số tính năng trong ứng dụng của bạn cho
+các ứng dụng khác thông qua truyền thông liên tiến trình (IPC).</p>
+
+<p>Để tạo một dịch vụ gắn kết, bạn phải triển khai phương pháp gọi lại {@link
+android.app.Service#onBind onBind()} để trả về một {@link android.os.IBinder} mà
+định nghĩa giao diện cho giao tiếp với dịch vụ đó. Khi đó, các thành phần ứng dụng khác có thể gọi
+{@link android.content.Context#bindService bindService()} để truy xuất giao diện và
+bắt đầu các phương pháp gọi trên dịch vụ. Dịch vụ tồn tại chỉ nhằm phục vụ thành phần ứng dụng mà
+được gắn kết với nó, vì thế khi không có thành phần được gắn kết với dịch vụ, hệ thống sẽ hủy nó
+(bạn <em>không</em> cần dừng một dịch vụ gắn kết theo cách phải làm khi dịch vụ được bắt đầu
+thông qua {@link android.app.Service#onStartCommand onStartCommand()}).</p>
+
+<p>Để tạo một dịch vụ gắn kết, điều đầu tiên bạn phải làm là định nghĩa giao diện quy định
+cách thức mà một máy khách có thể giao tiếp với dịch vụ. Giao diện giữa dịch vụ và
+máy khách này phải là một triển khai {@link android.os.IBinder} và được dịch vụ của bạn phải
+trả về từ phương pháp gọi lại {@link android.app.Service#onBind
+onBind()}. Sau khi máy khách nhận được {@link android.os.IBinder}, nó có thể bắt đầu
+tương tác với dịch vụ thông qua giao diện đó.</p>
+
+<p>Nhiều máy khách có thể gắn kết với dịch vụ đồng thời. Khi một máy khách hoàn thành tương tác với
+dịch vụ, nó sẽ gọi {@link android.content.Context#unbindService unbindService()} để bỏ gắn kết. Sau khi
+không còn máy khách nào được gắn kết với dịch vụ, hệ thống sẽ hủy dịch vụ.</p>
+
+<p>Có nhiều cách để triển khai một dịch vụ gắn kết và triển khai sẽ phức tạp
+hơn so với dịch vụ được bắt đầu, vì thế nội dung bàn về dịch vụ gắn kết được trình bày trong một
+tài liệu riêng về <a href="{@docRoot}guide/components/bound-services.html">Dịch vụ Gắn kết</a>.</p>
+
+
+
+<h2 id="Notifications">Gửi Thông báo tới Người dùng</h2>
+
+<p>Sau khi chạy, một dịch vụ có thể thông báo cho người dùng về sự kiện bằng cách sử dụng <a href="{@docRoot}guide/topics/ui/notifiers/toasts.html">Thông báo Cửa sổ</a> hoặc <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Thông báo Thanh Trạng thái</a>.</p>
+
+<p>Thông báo cửa sổ là một thông báo xuất hiện một lúc trên bề mặt của cửa sổ hiện tại
+rồi biến mất, trong khi thông báo thanh trạng thái cung cấp một biểu tượng trong thanh trạng thái cùng một
+thông báo, người dùng có thể chọn nó để thực hiện một hành động (chẳng hạn như bắt đầu một hoạt động).</p>
+
+<p>Thông thường thông báo thanh trạng thái là kỹ thuật tốt nhất khi một công việc nền nào đó đã hoàn thành
+(chẳng hạn như một tệp đã hoàn thành
+việc tải xuống) và lúc này người dùng có thể hành động dựa trên nó. Khi người dùng chọn thông báo từ dạng xem mở rộng
+, thông báo có thể bắt đầu một hoạt động (chẳng hạn như xem tệp được tải xuống).</p>
+
+<p>Xem hướng dẫn dành cho nhà phát triển <a href="{@docRoot}guide/topics/ui/notifiers/toasts.html">Thông báo Cửa sổ</a> hoặc <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Thông báo Thanh Trạng thái</a>
+để biết thêm thông tin.</p>
+
+
+
+<h2 id="Foreground">Chạy một Dịch vụ trong Tiền cảnh</h2>
+
+<p>Dịch vụ tiền cảnh là một dịch vụ được coi là điều mà
+người dùng đang chủ động quan tâm, vì thế nó không được đề nghị để hệ thống tắt bỏ khi bộ nhớ thấp. Dịch vụ
+tiền cảnh phải cung cấp một thông báo cho thanh trạng thái, nó được đặt dưới tiêu đề
+"Đang diễn ra", điều này có nghĩa là thông báo không thể loại bỏ được trừ khi dịch vụ
+bị dừng hoặc loại bỏ khỏi tiền cảnh.</p>
+
+<p>Ví dụ, một trình chơi nhạc đang phát nhạc từ một dịch vụ nên được đặt để chạy trong
+tiền cảnh, vì người dùng rõ ràng ý thức được
+hoạt động của nó. Thông báo trong thanh trạng thái có thể cho biết bài hát đang chơi và cho phép
+người dùng khởi chạy một hoạt động để tương tác với trình chơi nhạc.</p>
+
+<p>Để yêu cầu dịch vụ của bạn chạy trong tiền cảnh, hãy gọi {@link
+android.app.Service#startForeground startForeground()}. Phương pháp này dùng hai tham số: một số nguyên
+để xác định duy nhất thông báo và {@link
+android.app.Notification} cho thanh trạng thái. Ví dụ:</p>
+
+<pre>
+Notification notification = new Notification(R.drawable.icon, getText(R.string.ticker_text),
+ System.currentTimeMillis());
+Intent notificationIntent = new Intent(this, ExampleActivity.class);
+PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
+notification.setLatestEventInfo(this, getText(R.string.notification_title),
+ getText(R.string.notification_message), pendingIntent);
+startForeground(ONGOING_NOTIFICATION_ID, notification);
+</pre>
+
+<p class="caution"><strong>Chú ý:</strong> ID số nguyên mà bạn cấp cho {@link
+android.app.Service#startForeground startForeground()} không được bằng 0.</p>
+
+
+<p>Để xóa bỏ dịch vụ khỏi tiền cảnh, hãy gọi {@link
+android.app.Service#stopForeground stopForeground()}. Phương pháp này dùng một boolean, cho biết
+có loại bỏ cả thông báo thanh trạng thái hay không. Phương pháp này <em>không</em> dừng
+dịch vụ. Tuy nhiên, nếu bạn dừng dịch vụ trong khi nó vẫn đang chạy trong tiền cảnh, khi đó thông báo
+cũng bị loại bỏ.</p>
+
+<p>Để biết thêm thông tin về thông báo, hãy xem phần <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Tạo Thông báo
+Thanh Trạng thái</a>.</p>
+
+
+
+<h2 id="Lifecycle">Quản lý Vòng đời của một Dịch vụ</h2>
+
+<p>Vòng đời của một dịch vụ đơn giản hơn nhiều so với vòng đời của một hoạt động. Tuy nhiên, một điều thậm chí còn quan trọng hơn
+đó là bạn phải thật chú ý tới cách dịch vụ của bạn được tạo và hủy, bởi một dịch vụ
+có thể chạy ngầm mà người dùng không biết.</p>
+
+<p>Vòng đời của dịch vụ&mdash;từ khi nó được tạo tới khi nó bị hủy&mdash;có thể đi theo hai
+con đường khác nhau:</p>
+
+<ul>
+<li>Dịch vụ được bắt đầu
+ <p>Dịch vụ được tạo khi một thành phần khác gọi {@link
+android.content.Context#startService startService()}. Sau đó, dịch vụ sẽ chạy vô thời hạn và phải
+tự dừng bằng cách gọi {@link
+android.app.Service#stopSelf() stopSelf()}. Một thành phần khác cũng có thể dừng
+dịch vụ bằng cách gọi {@link android.content.Context#stopService
+stopService()}. Khi dịch vụ bị dừng, hệ thống sẽ hủy nó.</p></li>
+
+<li>Dịch vụ gắn kết
+ <p>Dịch vụ được tạo khi một thành phần khác (máy khách) gọi {@link
+android.content.Context#bindService bindService()}. Khi đó, máy khách giao tiếp với dịch vụ
+thông qua một giao diện {@link android.os.IBinder}. Máy khách có thể đóng kết nối bằng cách gọi
+{@link android.content.Context#unbindService unbindService()}. Nhiều máy khách có thể gắn kết với
+cùng dịch vụ và khi tất cả chúng bỏ gắn kết, hệ thống sẽ hủy dịch vụ. (Dịch vụ
+<em>không</em> cần tự mình dừng.)</p></li>
+</ul>
+
+<p>Hai con đường này hoàn toàn riêng biệt. Cụ thể, bạn có thể gắn kết với một dịch vụ đã
+được bắt đầu bằng {@link android.content.Context#startService startService()}. Ví dụ, một dịch vụ
+nhạc nền có thể được bắt đầu bằng cách gọi {@link android.content.Context#startService
+startService()} bằng một {@link android.content.Intent} mà sẽ nhận biết nhạc để phát. Sau đó,
+có thể là khi người dùng muốn thực thi một quyền điều khiển đối với trình phát đó hoặc lấy thông tin về
+bài hát đang phát, hoạt động có thể gắn kết với dịch vụ bằng cách gọi {@link
+android.content.Context#bindService bindService()}. Trong những trường hợp như vậy, {@link
+android.content.Context#stopService stopService()} hoặc {@link android.app.Service#stopSelf
+stopSelf()} không thực sự dừng dịch vụ tới khi tất cả máy khách bỏ gắn kết. </p>
+
+
+<h3 id="LifecycleCallbacks">Triển khai gọi lại vòng đời</h3>
+
+<p>Giống như một hoạt động, dịch vụ có các phương pháp gọi lại vòng đời mà bạn có thể triển khai để theo dõi
+những thay đổi về trạng thái của dịch vụ và thực hiện công việc tại những thời điểm phù hợp. Dịch vụ khung sau
+minh họa từng phương pháp vòng đời:</p>
+
+<pre>
+public class ExampleService extends Service {
+ int mStartMode; // indicates how to behave if the service is killed
+ IBinder mBinder; // interface for clients that bind
+ boolean mAllowRebind; // indicates whether onRebind should be used
+
+ &#64;Override
+ public void {@link android.app.Service#onCreate onCreate}() {
+ // The service is being created
+ }
+ &#64;Override
+ public int {@link android.app.Service#onStartCommand onStartCommand}(Intent intent, int flags, int startId) {
+ // The service is starting, due to a call to {@link android.content.Context#startService startService()}
+ return <em>mStartMode</em>;
+ }
+ &#64;Override
+ public IBinder {@link android.app.Service#onBind onBind}(Intent intent) {
+ // A client is binding to the service with {@link android.content.Context#bindService bindService()}
+ return <em>mBinder</em>;
+ }
+ &#64;Override
+ public boolean {@link android.app.Service#onUnbind onUnbind}(Intent intent) {
+ // All clients have unbound with {@link android.content.Context#unbindService unbindService()}
+ return <em>mAllowRebind</em>;
+ }
+ &#64;Override
+ public void {@link android.app.Service#onRebind onRebind}(Intent intent) {
+ // A client is binding to the service with {@link android.content.Context#bindService bindService()},
+ // after onUnbind() has already been called
+ }
+ &#64;Override
+ public void {@link android.app.Service#onDestroy onDestroy}() {
+ // The service is no longer used and is being destroyed
+ }
+}
+</pre>
+
+<p class="note"><strong>Lưu ý:</strong> Không như các phương pháp gọi lại vòng đời của hoạt động, bạn
+<em>không</em> phải gọi triển khai siêu lớp với những phương pháp gọi lại này.</p>
+
+<img src="{@docRoot}images/service_lifecycle.png" alt="" />
+<p class="img-caption"><strong>Hình 2.</strong> Vòng đời dịch vụ. Sơ đồ phía bên trái
+minh họa vòng đời khi dịch vụ được tạo bằng {@link android.content.Context#startService
+startService()} và sơ đồ phía bên phải minh họa vòng đời khi dịch vụ được tạo
+bằng {@link android.content.Context#bindService bindService()}.</p>
+
+<p>Bằng việc triển khai những phương pháp này, bạn có thể theo dõi hai vòng lặp lồng nhau trong vòng đời của dịch vụ: </p>
+
+<ul>
+<li><strong>Toàn bộ vòng đời</strong> của một dịch vụ xảy ra giữa thời điểm gọi {@link
+android.app.Service#onCreate onCreate()} và thời điểm {@link
+android.app.Service#onDestroy} trả về. Giống như hoạt động, dịch vụ thực hiện thiết lập ban đầu của nó trong
+{@link android.app.Service#onCreate onCreate()} và giải phóng tất cả tài nguyên còn lại trong {@link
+android.app.Service#onDestroy onDestroy()}. Ví dụ, một
+dịch vụ phát lại nhạc có thể tạo luồng mà tại đó nhạc sẽ được phát trong {@link
+android.app.Service#onCreate onCreate()}, sau đó dừng luồng trong {@link
+android.app.Service#onDestroy onDestroy()}.
+
+<p>Các phương pháp {@link android.app.Service#onCreate onCreate()} và {@link android.app.Service#onDestroy
+onDestroy()} được gọi cho tất cả dịch vụ, dù
+chúng được tạo bởi {@link android.content.Context#startService startService()} hay {@link
+android.content.Context#bindService bindService()}.</p></li>
+
+<li><strong>Vòng đời hiện hoạt</strong> của một dịch vụ sẽ bắt đầu bằng một lệnh gọi đến hoặc {@link
+android.app.Service#onStartCommand onStartCommand()} hoặc {@link android.app.Service#onBind onBind()}.
+Mỗi phương pháp sẽ được giao {@link
+android.content.Intent} mà được chuyển tương ứng cho hoặc {@link android.content.Context#startService
+startService()} hoặc {@link android.content.Context#bindService bindService()}.
+<p>Nếu dịch vụ được bắt đầu, vòng đời hiện hoạt sẽ chấm dứt tại cùng thời điểm khi toàn bộ vòng đời
+chấm dứt (dịch vụ sẽ vẫn hiện hoạt ngay cả sau khi {@link android.app.Service#onStartCommand
+onStartCommand()} trả về). Nếu dịch vụ bị gắn kết, vòng đời hiện hoạt sẽ chấm dứt khi {@link
+android.app.Service#onUnbind onUnbind()} trả về.</p>
+</li>
+</ul>
+
+<p class="note"><strong>Lưu ý:</strong> Mặc dù dịch vụ được bắt đầu bị dừng bởi một lệnh gọi đến
+hoặc {@link android.app.Service#stopSelf stopSelf()} hoặc {@link
+android.content.Context#stopService stopService()}, sẽ không có một lệnh gọi lại tương ứng cho
+dịch vụ (không có lệnh gọi lại {@code onStop()}). Vì thế, trừ khi dịch vụ được gắn kết với một máy khách,
+hệ thống sẽ hủy nó khi dịch vụ bị dừng&mdash;{@link
+android.app.Service#onDestroy onDestroy()} là lệnh gọi lại duy nhất nhận được.</p>
+
+<p>Hình 2 minh họa các phương pháp gọi lại điển hình cho một dịch vụ. Mặc dù hình tách riêng
+các dịch vụ được tạo bởi {@link android.content.Context#startService startService()} với các dịch vụ
+được tạo bởi {@link android.content.Context#bindService bindService()}, hãy
+ghi nhớ rằng bất kỳ dịch vụ nào, dù được bắt đầu như thế nào, đều có thể cho phép máy khách gắn kết với nó.
+Vì thế, một dịch vụ được bắt đầu từ đầu bằng {@link android.app.Service#onStartCommand
+onStartCommand()} (bởi một máy khách gọi {@link android.content.Context#startService startService()})
+vẫn có thể nhận một lệnh gọi đến {@link android.app.Service#onBind onBind()} (khi máy khách gọi
+{@link android.content.Context#bindService bindService()}).</p>
+
+<p>Để biết thêm thông tin về việc tao một dịch vụ có tính năng gắn kết, hãy xem tài liệu <a href="{@docRoot}guide/components/bound-services.html">Dịch vụ Gắn kết</a>,
+trong đó có thêm thông tin về phương pháp gọi lại {@link android.app.Service#onRebind onRebind()}
+trong phần về <a href="{@docRoot}guide/components/bound-services.html#Lifecycle">Quản lý Vòng đời của
+một Dịch vụ Gắn kết</a>.</p>
+
+
+<!--
+<h2>Beginner's Path</h2>
+
+<p>To learn how to query data from the system or other applications (such as contacts or media
+stored on the device), continue with the <b><a
+href="{@docRoot}guide/topics/providers/content-providers.html">Content Providers</a></b>
+document.</p>
+-->
diff --git a/docs/html-intl/intl/vi/guide/components/tasks-and-back-stack.jd b/docs/html-intl/intl/vi/guide/components/tasks-and-back-stack.jd
new file mode 100644
index 000000000000..85afffff5ba5
--- /dev/null
+++ b/docs/html-intl/intl/vi/guide/components/tasks-and-back-stack.jd
@@ -0,0 +1,578 @@
+page.title=Tác vụ và Ngăn xếp
+parent.title=Hoạt động
+parent.link=activities.html
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>Trong tài liệu này</h2>
+<ol>
+<li><a href="#ActivityState">Lưu Trạng thái của Hoạt động</a></li></li>
+<li><a href="#ManagingTasks">Quản lý Tác vụ</a>
+ <ol>
+ <li><a href="#TaskLaunchModes">Định nghĩa các chế độ khởi chạy</a></li>
+ <li><a href="#Affinities">Xử lý quan hệ</a></li>
+ <li><a href="#Clearing">Xóa ngăn xếp</a></li>
+ <li><a href="#Starting">Bắt đầu một tác vụ</a></li>
+ </ol>
+</li>
+</ol>
+
+<h2>Bài viết</h2>
+<ol>
+ <li><a href="http://android-developers.blogspot.com/2010/04/multitasking-android-way.html">
+ Đa nhiệm theo cách của Android</a></li>
+</ol>
+
+<h2>Xem thêm</h2>
+<ol>
+ <li><a href="{@docRoot}design/patterns/navigation.html">Thiết kế Android:
+Điều hướng</a></li>
+ <li><a href="{@docRoot}guide/topics/manifest/activity-element.html">Phần tử bản kê khai {@code &lt;activity&gt;}
+</a></li>
+ <li><a href="{@docRoot}guide/components/recents.html">Màn hình Tổng quan</a></li>
+</ol>
+</div>
+</div>
+
+
+<p>Một ứng dụng thường chứa nhiều <a href="{@docRoot}guide/components/activities.html">hoạt động</a>. Mỗi hoạt động
+nên được thiết kế xung quanh một kiểu hành động cụ thể mà người dùng có thể thực hiện và bắt đầu các hoạt động
+khác. Ví dụ, một ứng dụng e-mail có thể có một hoạt động để hiển thị một danh sách các thư mới.
+Khi người dùng chọn một thư, một hoạt động mới sẽ mở ra để xem thư đó.</p>
+
+<p>Hoạt động thậm chí có thể bắt đầu các hoạt động tồn tại trong các ứng dụng khác trên thiết bị. Ví
+dụ, nếu ứng dụng của bạn muốn gửi một thư e-mail, bạn có thể định nghĩa một ý định để thực hiện một hành động
+"gửi" và bao gồm một số dữ liệu, chẳng hạn như địa chỉ e-mail và nội dung. Một hoạt động từ một ứng dụng
+khác tự khai báo là có khả năng xử lý kiểu ý định này sẽ mở ra. Trong trường hợp này,
+ý định sẽ gửi một e-mail, sao cho hoạt động "soạn" của một ứng dụng e-mail sẽ bắt đầu (nếu nhiều hoạt động
+hỗ trợ cùng ý định, khi đó hệ thống cho phép người dùng chọn hoạt động sẽ sử dụng). Khi e-mail được
+gửi, hoạt động của bạn tiếp tục và dường như hoạt động e-mail là một phần ứng dụng của bạn. Mặc dù
+các hoạt động có thể đến từ những ứng dụng khác nhau, Android duy trì trải nghiệm người dùng
+mượt mà này bằng cách giữ cả hai hoạt động trong cùng <em>tác vụ</em>.</p>
+
+<p>Tác vụ là một tập hợp gồm nhiều hoạt động mà người dùng tương tác với
+khi thực hiện một công việc nhất định. Các hoạt động được sắp xếp trong một chồng (<em>ngăn xếp</em>), theo
+thứ tự mở mỗi hoạt động.</p>
+
+<!-- SAVE FOR WHEN THE FRAGMENT DOC IS ADDED
+<div class="sidebox-wrapper">
+<div class="sidebox">
+<h3>Adding fragments to a task's back stack</h3>
+
+<p>Your activity can also include {@link android.app.Fragment}s to the back stack. For example,
+suppose you have a two-pane layout using fragments, one of which is a list view (fragment A) and the
+other being a layout to display an item from the list (fragment B). When the user selects an item
+from the list, fragment B is replaced by a new fragment (fragment C). In this case, it might be
+desireable for the user to navigate back to reveal fragment B, using the <em>Back</em> button.</p>
+<p>In order to add fragment B to the back stack so that this is possible, you must call {@link
+android.app.FragmentTransaction#addToBackStack addToBackStack()} before you {@link
+android.app.FragmentTransaction#commit()} the transaction that replaces fragment B with fragment
+C.</p>
+<p>For more information about using fragments and adding them to the back stack, see the {@link
+android.app.Fragment} class documentation.</p>
+
+</div>
+</div>
+-->
+
+<p>Màn hình Trang chủ của thiết bị là nơi bắt đầu đối với hầu hết tác vụ. Khi người dùng chạm vào một biểu tượng trong trình khởi chạy
+ứng dụng
+ (hoặc lối tắt trên màn hình Trang chủ), tác vụ của ứng dụng đó sẽ tiến ra tiền cảnh. Nếu không
+có tác vụ nào cho ứng dụng (ứng dụng chưa được sử dụng gần đây), khi đó một tác vụ mới
+sẽ được tạo và hoạt động "chính" cho ứng dụng đó sẽ mở ra thành hoạt động gốc trong chồng.</p>
+
+<p>Khi hoạt động hiện tại bắt đầu một hoạt động khác, hoạt động mới sẽ bị đẩy lên trên cùng của chồng và
+có tiêu điểm. Hoạt động trước vẫn nằm trong chồng, nhưng bị dừng lại. Khi một hoạt động
+dừng, hệ thống giữ lại trạng thái hiện tại của giao diện người dùng của hoạt động đó. Khi người dùng nhấn nút
+<em>Quay lại</em>
+, hoạt động hiện tại được bật khỏi trên cùng của chồng (hoạt động bị hủy) và
+hoạt động trước tiếp tục (trạng thái trước đó của UI của nó được khôi phục). Các hoạt động trong chồng
+không bao giờ được sắp xếp lại, mà chỉ bị đẩy và bật khỏi chồng&mdash;bị đẩy lên trên chồng khi được bắt đầu bởi
+hoạt động hiện tại và bị bật khỏi chồng khi người dùng rời nó bằng cách sử dụng nút <em>Quay lại</em>. Như vậy,
+ngăn xếp
+vận hành như một cấu trúc đối tượng "vào cuối, ra đầu". Hình 1 minh họa
+hành vi này cùng một dòng thời gian thể hiện tiến độ giữa các hoạt động dọc theo ngăn xếp
+hiện tại ở từng thời điểm.</p>
+
+<img src="{@docRoot}images/fundamentals/diagram_backstack.png" alt="" />
+<p class="img-caption"><strong>Hình 1.</strong> Biểu diễn cách mỗi hoạt động mới trong một
+tác vụ thêm một mục vào ngăn xếp. Khi người dùng nhấn nút <em>Quay lại</em>, hoạt động
+hiện tại
+bị hủy và hoạt động trước đó tiếp tục.</p>
+
+
+<p>Nếu người dùng tiếp tục nhấn <em>Quay lại</em>, khi đó mỗi hoạt động trong chồng bị bật khỏi để
+hiện ra
+hoạt động trước, tới khi người dùng quay lại màn hình Trang chủ (hoặc trở về hoạt động đang chạy khi
+tác vụ bắt đầu). Khi tất cả hoạt động bị loại bỏ khỏi chồng, tác vụ sẽ không còn tồn tại.</p>
+
+<div class="figure" style="width:287px">
+<img src="{@docRoot}images/fundamentals/diagram_multitasking.png" alt="" /> <p
+class="img-caption"><strong>Hình 2.</strong> Hai tác vụ: Tác vụ B nhận tương tác người dùng
+trong tiền cảnh, trong khi Tác vụ A nằm dưới nền, chờ được tiếp tục.</p>
+</div>
+<div class="figure" style="width:215px">
+ <img src="{@docRoot}images/fundamentals/diagram_multiple_instances.png" alt="" /> <p
+class="img-caption"><strong>Hình 3.</strong> Một hoạt động đơn lẻ được khởi tạo nhiều lần.</p>
+</div>
+
+<p>Tác vụ là một đơn vị dính kết, có thể di chuyển tới "nền" khi người dùng bắt đầu một tác vụ mới hoặc đi đến
+màn hình Trang chủ, thông qua nút <em>Home</em>. Khi ở trong nền, tất cả hoạt động trong
+tác vụ bị
+dừng, nhưng ngăn xếp cho tác vụ vẫn không bị ảnh hưởng&mdash;tác vụ chỉ đơn thuần mất tiêu điểm trong khi
+một tác vụ khác thay thế, như minh họa trong hình 2. Khi đó, một tác vụ có thể quay lại "tiền cảnh" để người dùng
+có thể chọn ở nơi họ đã rời đi. Ví dụ, giả sử rằng tác vụ hiện tại (Tác vụ A) có ba
+hoạt động trong chồng của mình&mdash;hai trong số đó nằm dưới hoạt động hiện tại. Người dùng nhấn nút <em>Trang chủ</em>
+, sau đó
+bắt đầu một ứng dụng mới từ trình khởi chạy ứng dụng. Khi màn hình Trang chủ xuất hiện, Tác vụ A đi vào
+nền. Khi ứng dụng mới bắt đầu, hệ thống sẽ bắt đầu một tác vụ cho ứng dụng đó
+(Tác vụ B) bằng chồng các hoạt động của chính mình. Sau khi tương tác với
+ứng dụng đó, người dùng quay lại Trang chủ lần nữa và chọn ứng dụng
+đã bắt đầu Tác vụ A lúc đầu. Lúc này, Tác vụ A đi đến
+tiền cảnh&mdash;cả ba hoạt động trong chồng của nó đều giữ nguyên và hoạt động trên cùng
+của chồng được tiếp tục. Tại
+điểm này, người dùng cũng có thể chuyển trở lại Tác vụ B bằng cách đến Trang chủ và chọn biểu tượng ứng dụng
+đã bắt đầu tác vụ đó (hoặc bằng cách chọn tác vụ của ứng dụng từ
+<a href="{@docRoot}guide/components/recents.html">màn hình tổng quan</a>).
+Đây là một ví dụ về đa nhiệm trên Android.</p>
+
+<p class="note"><strong>Lưu ý:</strong> Nhiều tác vụ có thể được lưu giữ cùng lúc trong nền.
+Tuy nhiên, nếu người dùng đang chạy nhiều tác vụ nền tại cùng thời điểm, hệ thống có thể bắt đầu
+hủy các hoạt động nền để khôi phục bộ nhớ, khiến trạng thái của hoạt động bị mất.
+Xem phần sau đây về <a href="#ActivityState">Trạng thái của hoạt động</a>.</p>
+
+<p>Vì các hoạt động trong ngăn xếp không bao giờ được sắp xếp lại, nếu ứng dụng của bạn cho phép
+người dùng bắt đầu một hoạt động cụ thể từ nhiều hơn một hoạt động, một thực thể mới của
+hoạt động đó sẽ được tạo và đẩy lên chồng (thay vì mang bất kỳ thực thể nào trước đó của
+hoạt động lên trên cùng). Như vậy, một hoạt động trong ứng dụng của bạn có thể được tạo phiên bản nhiều
+lần (thậm chí từ các tác vụ khác nhau), như minh họa trong hình 3. Như vậy, nếu người dùng điều hướng ngược lại
+bằng cách sử dụng nút <em>Quay lại</em>, mỗi thực thể của hoạt động được hiển thị theo thứ tự được
+mở (mỗi hoạt động
+có trạng thái UI của chính chúng). Tuy nhiên, bạn có thể sửa đổi hành vi này nếu không muốn một hoạt động được
+khởi tạo nhiều hơn một lần. Cách làm như vậy được bàn trong phần sau về <a href="#ManagingTasks">Quản lý Tác vụ</a>.</p>
+
+
+<p>Để tóm tắt hành vi mặc định đối với các hoạt động và tác vụ:</p>
+
+<ul>
+ <li>Khi Hoạt động A bắt đầu Hoạt động B, Hoạt động A bị dừng, nhưng hệ thống giữ lại trạng thái của nó
+(chẳng hạn như vị trí cuộn và văn bản được nhập vào các mẫu).
+Nếu người dùng nhấn nút <em>Quay lại</em> khi đang trong Hoạt động B, Hoạt động A sẽ tiếp tục với trạng thái
+được khôi phục.</li>
+ <li>Khi người dùng rời khỏi một tác vụ bằng cách nhấn nút <em>Trang chủ</em>, hoạt động hiện tại bị
+dừng và
+tác vụ của nó sẽ đưa xuống dưới nền. Hệ thống sẽ giữ lại trạng thái của mọi hoạt động trong tác vụ. Nếu
+sau đó người dùng tiếp tục tác vụ bằng cách chọn biểu tượng trình khởi chạy đã bắt đầu tác vụ, tác vụ sẽ vào
+tiền cảnh và tiếp tục hoạt động ở trên cùng của chồng.</li>
+ <li>Nếu người dùng nhấn nút <em>Quay lại</em>, hoạt động hiện tại bị bật khỏi chồng
+và
+bị hủy. Hoạt động trước đó ở trong chồng sẽ được tiếp tục. Khi một hoạt động bị hủy, hệ thống
+<em>không</em> giữ lại trạng thái của hoạt động đó.</li>
+ <li>Hoạt động có thể được khởi tạo nhiều lần, thậm chí từ các tác vụ khác.</li>
+</ul>
+
+
+<div class="note design">
+<p><strong>Thiết kế Điều hướng</strong></p>
+ <p>Để biết thêm về cách điều hướng ứng dụng hoạt động trên Android, hãy đọc hướng dẫn <a href="{@docRoot}design/patterns/navigation.html">Điều hướng</a> của Thiết kế Android.</p>
+</div>
+
+
+<h2 id="ActivityState">Lưu Trạng thái của Hoạt động</h2>
+
+<p>Như được đề cập ở trên, hành vi mặc định của hệ thống giữ nguyên trạng thái của một hoạt động khi nó bị
+dừng. Bằng cách này, khi người dùng điều hướng trở lại một hoạt động trước đó, giao diện người dùng của nó sẽ xuất hiện
+ như lúc bị rời đi. Tuy nhiên, bạn có thể&mdash;và <strong>nên</strong>&mdash;chủ động giữ lại
+trạng thái của các hoạt động của mình bằng cách sử dụng các phương pháp gọi lại, trong trường hợp hoạt động bị hủy và phải
+được tạo lại.</p>
+
+<p>Khi hệ thống dừng một trong các hoạt động của bạn (chẳng hạn như khi một hoạt động mới bắt đầu hoặc tác vụ
+di chuyển về nền), hệ thống có thể hoàn toàn hủy hoạt động đó nếu nó cần khôi phục
+bộ nhớ hệ thống. Khi điều này xảy ra, thông tin về trạng thái của hoạt động sẽ bị mất. Nếu điều này xảy ra,
+hệ thống vẫn
+biết rằng hoạt động có một vị trí trong ngăn xếp, nhưng khi hoạt động được đưa tới vị trí trên cùng
+của chồng, hệ thống phải tạo lại nó (thay vì tiếp tục). Để tránh
+làm mất công việc của người dùng, bạn nên chủ động giữ lại nó bằng cách triển khai phương pháp gọi lại
+{@link android.app.Activity#onSaveInstanceState onSaveInstanceState()} trong
+hoạt động của mình.</p>
+
+<p>Để biết thêm thông tin về cách lưu trạng thái hoạt động của mình, hãy xem tài liệu <a href="{@docRoot}guide/components/activities.html#SavingActivityState">Hoạt động</a>
+.</p>
+
+
+
+<h2 id="ManagingTasks">Quản lý Tác vụ</h2>
+
+<p>Cách Android quản lý tác vụ và ngăn xếp, như được mô tả bên trên&mdash;bằng cách đặt tất cả
+hoạt động được bắt đầu nối tiếp nhau vào cùng tác vụ và trong một chồng "vào cuối, ra đầu"&mdash;rất
+hiệu quả đối với hầu hết ứng dụng và bạn không phải lo lắng về cách thức các hoạt động của mình được liên kết với
+các tác vụ hay cách chúng tồn tại trong ngăn xếp. Tuy nhiên, bạn có thể quyết định rằng mình muốn gián đoạn
+hành vi thông thường. Có thể bạn muốn một hoạt động trong ứng dụng của mình bắt đầu một tác vụ mới khi nó được
+bắt đầu (thay vì được đặt trong tác vụ hiện tại); hoặc, khi bạn bắt đầu một hoạt động, bạn muốn
+mang lên trước một thực thể hiện tại của nó (thay vì tạo một
+thực thể mới trên cùng của ngăn xếp); hoặc, bạn muốn ngăn xếp của mình được xóa sạch tất cả các
+hoạt động, ngoại trừ hoạt động gốc khi người dùng rời khỏi tác vụ.</p>
+
+<p>Bạn có thể làm những điều này và nhiều điều khác với các thuộc tính trong phần tử bản kê khai
+<a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a>
+và cờ trong ý định mà bạn chuyển cho
+{@link android.app.Activity#startActivity startActivity()}.</p>
+
+<p>Về mặt này, các thuộc tính <a href="{@docRoot}guide/topics/manifest/activity-element.html">
+{@code &lt;activity&gt;}</a> chính mà bạn có thể sử dụng là:</p>
+
+<ul class="nolist">
+ <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">
+ {@code taskAffinity}</a></li>
+ <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">
+ {@code launchMode}</a></li>
+ <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#reparent">
+ {@code allowTaskReparenting}</a></li>
+ <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#clear">
+ {@code clearTaskOnLaunch}</a></li>
+ <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#always">
+ {@code alwaysRetainTaskState}</a></li>
+ <li><a href="{@docRoot}guide/topics/manifest/activity-element.html#finish">
+ {@code finishOnTaskLaunch}</a></li>
+</ul>
+
+<p>Và các cờ ý định chính mà bạn có thể sử dụng là:</p>
+
+<ul class="nolist">
+ <li>{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}</li>
+ <li>{@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP}</li>
+ <li>{@link android.content.Intent#FLAG_ACTIVITY_SINGLE_TOP}</li>
+</ul>
+
+<p>Trong những phần sau, bạn sẽ thấy cách bạn có thể sử dụng những thuộc tính của bản kê khai
+và cờ ý định này để định nghĩa cách các hoạt động được liên kết với tác vụ và hành vi của chúng như thế nào trong ngăn xếp.</p>
+
+<p>Bên cạnh đó, có phần bàn riêng về việc cân nhắc cách các tác vụ và hoạt động có thể
+được biểu diễn và quản lý trong màn hình tổng quan. Xem phần <a href="{@docRoot}guide/components/recents.html">Màn hình Tổng quan</a>
+để biết thêm thông tin. Thông thường, bạn nên cho phép hệ thống định nghĩa tác vụ và các hoạt động
+của bạn được biểu diễn như thế nào trong màn hình tổng quan, và bạn không cần sửa đổi hành vi này.</p>
+
+<p class="caution"><strong>Chú ý:</strong> Hầu hết các ứng dụng không nên gián đoạn hành vi
+mặc định cho các hoạt động và tác vụ. Nếu bạn xác định rằng hoạt động của bạn cần phải sửa đổi
+hành vi mặc định, hãy thận trọng và đảm bảo kiểm tra khả năng sử dụng được của hoạt động đó trong khi
+khởi chạy và khi điều hướng trở lại nó từ các hoạt động và tác vụ khác bằng nút <em>Quay lại</em>.
+Đảm bảo kiểm tra hành vi điều hướng mà có thể xung đột với hành vi được kỳ vọng của người dùng.</p>
+
+
+<h3 id="TaskLaunchModes">Định nghĩa các chế độ khởi chạy</h3>
+
+<p>Các chế độ khởi chạy cho phép bạn định nghĩa một thực thể mới của một hoạt động được liên kết với tác vụ hiện tại
+như thế nào. Bạn có thể định nghĩa các chế độ khởi chạy khác nhau theo hai cách:</p>
+<ul class="nolist">
+ <li><a href="#ManifestForTasks">Sử dụng tệp bản kê khai</a>
+ <p>Khi bạn khai báo một hoạt động trong tệp bản kê khai của mình, bạn có thể quy định hoạt động
+sẽ liên kết với các tác vụ như thế nào khi nó bắt đầu.</li>
+ <li><a href="#IntentFlagsForTasks">Sử dụng cờ Ý định</a>
+ <p>Khi bạn gọi {@link android.app.Activity#startActivity startActivity()},
+bạn có thể thêm một cờ vào {@link android.content.Intent} mà khai báo cách (hoặc
+liệu có hay không) hoạt động mới sẽ liên kết với tác vụ hiện tại.</p></li>
+</ul>
+
+<p>Như vậy, nếu Hoạt động A bắt đầu Hoạt động B, Hoạt động B có thể định nghĩa trong bản kê khai của mình cách nó
+sẽ liên kết với tác vụ hiện tại (nếu có) và Hoạt động A cũng có thể yêu cầu cách mà Hoạt động
+B sẽ liên kết với tác vụ hiện tại. Nếu cả hai hoạt động đều định nghĩa cách Hoạt động B
+nên liên kết với một tác vụ thì yêu cầu của Hoạt động A (như định nghĩa trong ý định) được ưu tiên
+so với yêu cầu của Hoạt động B (như được định nghĩa trong bản kê khai của nó).</p>
+
+<p class="note"><strong>Lưu ý:</strong> Một số chế độ khởi chạy sẵn có cho tệp bản kê khai
+không sẵn có dưới dạng cờ cho một ý định và, tương tự, một số chế độ khởi chạy sẵn có dưới dạng cờ
+cho một ý định không thể được định nghĩa trong bản kê khai.</p>
+
+
+<h4 id="ManifestForTasks">Sử dụng tệp bản kê khai</h4>
+
+<p>Khi khai báo một hoạt động trong tệp bản kê khai của bạn, bạn có thể quy định cách mà hoạt động
+sẽ liên kết với một tác vụ bằng cách sử dụng thuộc tính của phần tử <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a>
+, <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code
+launchMode}</a>.</p>
+
+<p>Thuộc tính <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code
+launchMode}</a> quy định một chỉ lệnh về cách hoạt động sẽ được khởi chạy vào một
+tác vụ. Có bốn chế độ khởi chạy khác nhau mà bạn có thể gán cho thuộc tính
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">launchMode</a></code>
+:</p>
+
+<dl>
+<dt>{@code "standard"} (chế độ mặc định)</dt>
+ <dd>Mặc định. Hệ thống tạo một thực thể mới của hoạt động trong tác vụ là nơi
+mà nó được bắt đầu và định tuyến ý định tới đó. Hoạt động có thể được khởi tạo nhiều lần,
+mỗi thực thể có thể thuộc về các tác vụ khác nhau, và một tác vụ có thể có nhiều thực thể.</dd>
+<dt>{@code "singleTop"}</dt>
+ <dd>Nếu một thực thể của hoạt động đã tồn tại ở trên cùng của tác vụ hiện tại, hệ thống
+sẽ định tuyến ý định tới thực thể đó thông qua một lệnh gọi tới phương pháp {@link
+android.app.Activity#onNewIntent onNewIntent()} của nó, thay vì tạo một thực thể mới của
+hoạt động. Hoạt động có thể được tạo phiên bản nhiều lần, mỗi thực thể có thể
+thuộc về các tác vụ khác nhau, và một tác vụ có thể có nhiều thực thể (nhưng chỉ nếu
+hoạt động nằm trên cùng của ngăn xếp <em>không</em> phải là một thực thể của hoạt động hiện có).
+ <p>Ví dụ, giả sử ngăn xếp của một tác vụ bao gồm hoạt động gốc A với các hoạt động B, C,
+và D ở trên cùng (chồng là A-B-C-D; D ở trên cùng). Một ý định đến cho loại hoạt động D.
+Nếu D có chế độ khởi chạy {@code "standard"} mặc định, một thực thể mới của lớp sẽ được khởi chạy và
+chồng trở thành A-B-C-D-D. Tuy nhiên, nếu chế độ khởi chạy của D là {@code "singleTop"}, thực thể hiện tại
+của D sẽ nhận ý định thông qua {@link
+android.app.Activity#onNewIntent onNewIntent()}, bởi nó nằm ở vị trí trên cùng của chồng&mdash;chồng
+vẫn là A-B-C-D. Tuy nhiên, nếu một ý định đến cho hoạt động loại B, khi đó một thực thể
+mới của B sẽ được thêm vào chồng ngay cả khi chế độ khởi chạy của nó là {@code "singleTop"}.</p>
+ <p class="note"><strong>Lưu ý:</strong> Khi một thực thể mới của hoạt động được tạo,
+người dùng có thể nhấn nút <em>Quay lại</em> để quay về hoạt động trước đó. Nhưng khi một thực thể
+hiện tại của
+hoạt động xử lý một ý định mới, người dùng không thể nhấn nút <em>Quay lại</em> để quay về trạng thái
+của
+hoạt động trước khi ý định mới đến trong {@link android.app.Activity#onNewIntent
+onNewIntent()}.</p>
+</dd>
+
+<dt>{@code "singleTask"}</dt>
+ <dd>Hệ thống sẽ tạo ra một tác vụ mới và khởi tạo hoạt động ở gốc của tác vụ mới.
+Tuy nhiên, nếu một thực thể của hoạt động đã tồn tại trong một tác vụ riêng, hệ thống sẽ định tuyến
+ý định tới thực thể hiện tại thông qua một lệnh gọi tới phương pháp {@link
+android.app.Activity#onNewIntent onNewIntent()} của nó thay vì tạo một thực thể mới. Chỉ
+một thực thể của hoạt động có thể tồn tại ở một thời điểm.
+ <p class="note"><strong>Lưu ý:</strong> Mặc dù hoạt động bắt đầu một tác vụ mới, nút
+<em>Quay lại</em> sẽ vẫn đưa người dùng quay về hoạt động trước đó.</p></dd>
+<dt>{@code "singleInstance"}.</dt>
+ <dd>Giống như {@code "singleTask"}, trừ khi hệ thống không khởi chạy bất kỳ hoạt động nào khác vào
+tác vụ đang nắm giữ thực thể. Hoạt động luôn là thành viên đơn lẻ và duy nhất của tác vụ;
+bất kỳ hoạt động nào được bắt đầu bởi hoạt động này sẽ mở ra trong một tác vụ riêng.</dd>
+</dl>
+
+
+<p>Lấy một ví dụ khác, ứng dụng Trình duyệt của Android khai báo rằng hoạt động trình duyệt web sẽ
+luôn mở tác vụ của chính mình&mdash;bằng cách quy định chế độ khởi chạy {@code singleTask} trong phần tử <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a>.
+Điều này có nghĩa rằng nếu ứng dụng của bạn phát hành một
+ý định để mở Trình duyệt Android, hoạt động của nó <em>không</em> được đặt trong cùng
+tác vụ như ứng dụng của bạn. Thay vào đó, hoặc là một tác vụ mới bắt đầu cho Trình duyệt hoặc, nếu Trình duyệt
+đã có một tác vụ đang chạy trong nền thì tác vụ đó sẽ được đưa lên trước để xử lý
+ý định mới.</p>
+
+<p>Không phụ thuộc vào việc một hoạt động bắt đầu trong một tác vụ mới hay trong cùng tác vụ mà hoạt động
+đã bắt đầu, nút <em>Quay lại</em> sẽ luôn đưa người dùng về hoạt động trước đó. Tuy nhiên, nếu bạn
+bắt đầu một hoạt động mà quy định chế độ khởi chạy {@code singleTask}, khi đó nếu một thực thể của
+hoạt động đó tồn tại trong một tác vụ nền, toàn bộ tác vụ đó sẽ được đưa ra tiền cảnh. Tại thời điểm này
+, lúc này ngăn xếp bao gồm tất cả hoạt động từ tác vụ được mang ra, ở vị trí trên cùng của
+chồng. Hình 4 minh họa loại kịch bản này.</p>
+
+<img src="{@docRoot}images/fundamentals/diagram_backstack_singletask_multiactivity.png" alt="" />
+<p class="img-caption"><strong>Hình 4.</strong> Biểu diễn cách thức một hoạt động với
+chế độ khởi chạy "singleTask" được thêm vào ngăn xếp. Nếu hoạt động đã là một phần của một
+tác vụ nền với ngăn xếp của chính nó, khi đó toàn bộ ngăn xếp cũng tiến
+về phía trước, ở trên cùng tác vụ hiện tại.</p>
+
+<p>Để biết thêm thông tin về việc sử dụng các chế độ khởi chạy trong tệp bản kê khai, hãy xem tài liệu phần tử
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
+, trong đó có trình bày thêm về thuộc tính {@code launchMode} và các giá trị
+được chấp nhận.</p>
+
+<p class="note"><strong>Lưu ý:</strong> Hành vi mà bạn quy định cho hoạt động của mình bằng thuộc tính <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a> có thể
+bị khống chế bởi cờ có ý định bắt đầu hoạt động của bạn, như được trình bày trong
+phần tiếp theo.</p>
+
+
+
+<h4 id="#IntentFlagsForTasks">Sử dụng cờ Ý định</h4>
+
+<p>Khi bắt đầu một hoạt động, bạn có thể sửa đổi liên kết mặc định giữa một hoạt động với tác vụ của nó
+bằng cách thêm cờ vào trong ý định mà bạn chuyển tới {@link
+android.app.Activity#startActivity startActivity()}. Những cờ mà bạn có thể sử dụng để sửa đổi
+hành vi mặc định là:</p>
+
+<p>
+ <dt>{@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}</dt>
+ <dd>Bắt đầu một hoạt động trong một tác vụ mới. Nếu đã có một tác vụ đang chạy cho hoạt động mà bạn đang
+bắt đầu, tác vụ đó sẽ được đưa ra tiền cảnh với trạng thái cuối cùng được khôi phục và hoạt động
+nhận ý định mới trong {@link android.app.Activity#onNewIntent onNewIntent()}.
+ <p>Điều này sẽ tạo ra cùng hành vi như giá trị {@code "singleTask"} <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a>,
+đã được trình bày ở phần trước.</p></dd>
+ <dt>{@link android.content.Intent#FLAG_ACTIVITY_SINGLE_TOP}</dt>
+ <dd>Nếu hoạt động đang được bắt đầu là hoạt động hiện tại (ở trên cùng của ngăn xếp), khi đó
+thực thể hiện có sẽ nhận một lệnh gọi đến {@link android.app.Activity#onNewIntent onNewIntent()},
+thay vì tạo một thực thể của hoạt động mới.
+ <p>Điều này sẽ tạo ra cùng hành vi như giá trị {@code "singleTop"} <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a>,
+đã được trình bày ở phần trước.</p></dd>
+ <dt>{@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TOP}</dt>
+ <dd>Nếu hoạt động đang được bắt đầu đang chạy trong tác vụ hiện tại, khi đó
+thay vì khởi chạy một thực thể mới của hoạt động đó, tất cả các hoạt động khác bên trên nó đều
+bị hủy và ý định này được chuyển tới thực thể được tiếp tục của hoạt động (lúc này đang ở trên cùng),
+thông qua {@link android.app.Activity#onNewIntent onNewIntent()}).
+ <p>Không có giá trị cho thuộc tính <a href="{@docRoot}guide/topics/manifest/activity-element.html#lmode">{@code launchMode}</a>
+mà sinh ra hành vi này.</p>
+ <p>{@code FLAG_ACTIVITY_CLEAR_TOP} được sử dụng thường xuyên nhất cùng với
+ {@code FLAG_ACTIVITY_NEW_TASK}.
+Khi được sử dụng cùng nhau, những cờ này là một cách để định vị hoạt động hiện tại
+trong một tác vụ khác và đặt nó vào vị trí nơi nó có thể hồi đáp ý định. </p>
+ <p class="note"><strong>Lưu ý:</strong> Nếu chế độ khởi chạy của hoạt động được chỉ định là
+ {@code "standard"},
+nó cũng bị loại bỏ khỏi chồng và một thực thể mới sẽ được khởi chạy thay chỗ nó để xử lý
+ý định đến. Đó là bởi một thực thể mới luôn được tạo cho ý định mới khi chế độ khởi chạy
+là {@code "standard"}. </p>
+</dd>
+</dl>
+
+
+
+
+
+<h3 id="Affinities">Xử lý quan hệ</h3>
+
+<p><em>Quan hệ</em> sẽ cho biết một hoạt động ưu tiên thuộc về tác vụ nào hơn. Theo mặc định, tất cả
+các hoạt động từ cùng ứng dụng có quan hệ với nhau. Vì thế, theo mặc định, tất cả
+hoạt động trong cùng ứng dụng ưu tiên ở trong cùng tác vụ hơn. Tuy nhiên, bạn có thể sửa đổi
+quan hệ mặc định cho một hoạt động. Các hoạt động được định nghĩa trong
+các ứng dụng khác nhau có thể chia sẻ một quan hệ, hoặc các hoạt động được định nghĩa trong cùng ứng dụng có thể
+được gán các quan hệ tác vụ khác nhau.</p>
+
+<p>Bạn có thể sửa đổi quan hệ cho bất kỳ hoạt động đã cho nào bằng thuộc tính <a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code taskAffinity}</a> của
+phần tử <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a>
+.</p>
+
+<p>Thuộc tính <a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code taskAffinity}</a>
+lấy một giá trị xâu, đó phải là giá trị duy nhất từ tên gói mặc định
+được khai báo trong phần tử <a href="{@docRoot}guide/topics/manifest/manifest-element.html">
+{@code &lt;manifest&gt;}
+</a>, do hệ thống sử dụng tên đó để nhận biết quan hệ
+tác vụ mặc định cho ứng dụng.</p>
+
+<p>Vấn đề quan hệ được xét trong hai trường hợp:</p>
+<ul>
+ <li>Khi ý định khởi chạy hoạt động chứa cờ
+ {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}
+.
+
+<p>Theo mặc định, một hoạt động mới được khởi chạy vào tác vụ của hoạt động
+đã gọi {@link android.app.Activity#startActivity startActivity()}. Nó được đẩy lên cùng
+ngăn xếp như trình gọi. Tuy nhiên, nếu ý định được chuyển tới
+{@link android.app.Activity#startActivity startActivity()}
+chứa cờ {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK}
+, hệ thống sẽ tìm một tác vụ khác để chứa hoạt động mới. Thường thì đó là một tác vụ mới.
+Tuy nhiên, không nhất thiết phải như vậy. Nếu đã có một tác vụ hiện tại với cùng quan hệ như
+hoạt động mới, hoạt động sẽ được khởi chạy vào tác vụ đó. Nếu không, nó sẽ bắt đầu một tác vụ mới.</p>
+
+<p>Nếu cờ này khiến một hoạt động bắt đầu một tác vụ mới và người dùng nhấn nút <em>Home</em>
+để rời
+nó thì phải có một cách nào đó để người dùng điều hướng quay lại tác vụ. Một số đối tượng (chẳng hạn như
+trình quản lý thông báo) luôn bắt đầu các hoạt động trong một tác vụ bên ngoài, không bao giờ bắt đầu trong chính tác vụ của mình, vì thế
+chúng luôn đặt {@code FLAG_ACTIVITY_NEW_TASK} vào ý định mà chúng chuyển tới
+{@link android.app.Activity#startActivity startActivity()}.
+Nếu bạn có một hoạt động có thể được gọi ra bởi
+một đối tượng bên ngoài mà có thể sử dụng cờ này, hãy lưu ý là người dùng có một cách độc lập để quay lại
+tác vụ đã được bắt đầu, chẳng hạn như bằng một biểu tượng trình khởi chạy (hoạt động gốc của tác vụ
+có một bộ lọc ý định {@link android.content.Intent#CATEGORY_LAUNCHER}; xem phần <a href="#Starting">Bắt đầu một tác vụ</a> ở bên dưới).</p>
+</li>
+
+ <li>Khi một hoạt động có thuộc tính <a href="{@docRoot}guide/topics/manifest/activity-element.html#reparent">
+{@code allowTaskReparenting}</a> của nó được đặt thành {@code "true"}.
+ <p>Trong trường hợp này, hoạt động có thể di chuyển từ tác vụ mà nó bắt đầu tới tác vụ mà nó có quan hệ
+ khi tác vụ đó đi ra tiền cảnh.</p>
+ <p>Ví dụ, giả sử rằng một hoạt động với chức năng báo cáo tình hình thời tiết ở các thành phố được chọn
+được định nghĩa là một phần trong một ứng dụng du lịch. Nó có cùng quan hệ như các hoạt động khác trong cùng
+ứng dụng (quan hệ ứng dụng mặc định) và nó cho phép tạo lại tập mẹ với thuộc tính này.
+Khi một trong các hoạt động của bạn bắt đầu hoạt động trình báo cáo thời tiết, ban đầu nó thuộc về cùng
+tác vụ như hoạt động của bạn. Tuy nhiên, khi tác vụ của ứng dụng du lịch đi ra tiền cảnh, hoạt động
+của trình báo cáo thời tiết được gán lại cho tác vụ đó và được hiển thị bên trong nó.</p>
+</li>
+</ul>
+
+<p class="note"><strong>Mẹo:</strong> Nếu một tệp {@code .apk} chứa nhiều hơn một "ứng dụng"
+từ quan điểm của người dùng, bạn có thể muốn sử dụng thuộc tính <a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">{@code taskAffinity}</a>
+để gán các quan hệ khác nhau cho hoạt động được liên kết với từng "ứng dụng".</p>
+
+
+
+<h3 id="Clearing">Xóa ngăn xếp</h3>
+
+<p>Nếu người dùng rời một tác vụ trong khoảng thời gian dài, hệ thống sẽ xóa tác vụ của tất cả hoạt động ngoại trừ
+hoạt động gốc. Khi người dùng quay trở lại tác vụ, chỉ hoạt động gốc được khôi phục.
+Hệ thống sẽ hoạt động theo cách này, vì, sau một khoảng thời gian dài, người dùng có thể đã từ bỏ
+việc mà họ đang làm trước đó và quay lại tác vụ để bắt đầu một việc mới. </p>
+
+<p>Có một số thuộc tính hoạt động mà bạn có thể sử dụng để sửa đổi hành vi này: </p>
+
+<dl>
+<dt><code><a
+href="{@docRoot}guide/topics/manifest/activity-element.html#always">alwaysRetainTaskState</a></code>
+</dt>
+<dd>Nếu thuộc tính này được đặt thành {@code "true"} trong hoạt động gốc của một tác vụ,
+hành vi mặc định được mô tả sẽ không xảy ra.
+Tác vụ giữ lại tất cả hoạt động trong chồng của mình kể cả sau một khoảng thời gian dài.</dd>
+
+<dt><code><a
+href="{@docRoot}guide/topics/manifest/activity-element.html#clear">clearTaskOnLaunch</a></code></dt>
+<dd>Nếu thuộc tính này được đặt thành {@code "true"} trong hoạt động gốc của một tác vụ,
+chồng sẽ bị xóa tới hoạt động gốc bất cứ khi nào người dùng rời khỏi tác vụ
+và quay lại. Nói cách khác, nó ngược với
+<a href="{@docRoot}guide/topics/manifest/activity-element.html#always">
+{@code alwaysRetainTaskState}</a>. Người dùng luôn quay lại tác vụ ở
+trạng thái ban đầu của nó, ngay cả sau khi rời khỏi tác vụ trong chỉ một lúc.</dd>
+
+<dt><code><a
+href="{@docRoot}guide/topics/manifest/activity-element.html#finish">finishOnTaskLaunch</a></code>
+</dt>
+<dd>Thuộc tính này giống như <a href="{@docRoot}guide/topics/manifest/activity-element.html#clear">{@code clearTaskOnLaunch}</a>,
+nhưng nó hoạt động trên một tác vụ
+đơn lẻ chứ không phải một tác vụ toàn bộ. Nó cũng có thể khiến bất kỳ hoạt động nào
+thoát mất, bao gồm cả hoạt động gốc. Khi nó được đặt thành {@code "true"}, hoạt động
+vẫn là một bộ phận của tác vụ chỉ cho phiên làm việc hiện tại. Nếu người dùng rời đi
+rồi quay lại tác vụ, nó không còn xuất hiện nữa.</dd>
+</dl>
+
+
+
+
+<h3 id="Starting">Bắt đầu một tác vụ</h3>
+
+<p>Bạn có thể thiết lập một hoạt động làm điểm bắt đầu cho một tác vụ bằng cách đưa cho nó một bộ lọc ý định với
+{@code "android.intent.action.MAIN"} là hành động được quy định và
+{@code "android.intent.category.LAUNCHER"}
+là thể loại được quy định. Ví dụ:</p>
+
+<pre>
+&lt;activity ... &gt;
+ &lt;intent-filter ... &gt;
+ &lt;action android:name="android.intent.action.MAIN" /&gt;
+ &lt;category android:name="android.intent.category.LAUNCHER" /&gt;
+ &lt;/intent-filter&gt;
+ ...
+&lt;/activity&gt;
+</pre>
+
+<p>Một bộ lọc ý định loại này khiến một biểu tượng và nhãn cho
+hoạt động được hiển thị trong trình khởi chạy ứng dụng, cho phép người dùng khởi chạy hoạt động và
+quay lại tác vụ mà nó tạo ra vào bất cứ lúc nào sau khi nó được khởi chạy.
+</p>
+
+<p>Khả năng thứ hai này là quan trọng: Người dùng chắc chắn có thể rời một tác vụ rồi quay lại
+sau bằng cách sử dụng trình khởi chạy hoạt động này. Vì lý do này, hai <a href="#LaunchModes">chế độ
+khởi chạy</a> mà đánh dấu các hoạt động là luôn khởi tạo một tác vụ, {@code "singleTask"} và
+{@code "singleInstance"}, sẽ chỉ được sử dụng khi hoạt động có một
+{@link android.content.Intent#ACTION_MAIN}
+và một bộ lọc {@link android.content.Intent#CATEGORY_LAUNCHER}. Ví dụ, hãy tưởng tượng chuyện gì
+sẽ xảy ra nếu thiếu bộ lọc: Một ý định khởi chạy một hoạt động {@code "singleTask"}, khởi đầu một
+tác vụ mới và người dùng dành một khoảng thời gian làm việc trong tác vụ đó. Khi đó, người dùng nhấn nút <em>Home</em>
+. Lúc này, tác vụ được gửi tới nền và không hiển thị. Bây giờ, người dùng không có cách nào để quay lại
+tác vụ bởi nó không được biểu diễn trong trình khởi chạy ứng dụng.</p>
+
+<p>Đối với những trường hợp mà bạn không muốn người dùng có thể quay lại một hoạt động, hãy đặt giá trị của phần tử
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
+,
+<a href="{@docRoot}guide/topics/manifest/activity-element.html#finish">{@code finishOnTaskLaunch}</a>
+thành {@code "true"} (xem <a href="#Clearing">Xóa chồng</a>).</p>
+
+<p>Bạn có thể tham khảo thêm thông tin về cách các tác vụ và hoạt động được trình bày và quản lý trong
+màn hình tổng quan sẵn có tại phần <a href="{@docRoot}guide/components/recents.html">
+Màn hình Tổng quan</a>.</p>
+
+<!--
+<h2>Beginner's Path</h2>
+
+<p>For more information about how to use intents to
+activate other application components and publish the intents to which your components
+respond, continue with the <b><a
+href="{@docRoot}guide/components/intents-filters.html">Intents and Intent
+Filters</a></b> document.</p>
+-->
diff --git a/docs/html-intl/intl/vi/guide/index.jd b/docs/html-intl/intl/vi/guide/index.jd
new file mode 100644
index 000000000000..7be2d89a2d17
--- /dev/null
+++ b/docs/html-intl/intl/vi/guide/index.jd
@@ -0,0 +1,74 @@
+page.title=Giới thiệu về Android
+
+@jd:body
+
+
+<div class="sidebox" style="width:220px"><!-- width to match col-4 below -->
+<p>Để tìm hiểu về cách các ứng dụng hoạt động, hãy bắt đầu với phần
+<a href="{@docRoot}guide/components/fundamentals.html">Đại cương về Ứng dụng</a>.</p>
+<p>Để bắt đầu ngay với việc viết mã, hãy đọc phần <a href="{@docRoot}training/basics/firstapp/index.html">Xây dựng Ứng dụng Đầu tiên của Bạn</a>.</p>
+</div>
+
+<p>Android cung cấp một khuôn khổ ứng dụng phong phú cho phép bạn xây dựng các ứng dụng và trò chơi mới
+cho các thiết bị di động trong môi trường ngôn ngữ Java. Tài liệu được liệt kê trong vùng điều hướng
+bên trái sẽ cung cấp chi tiết về cách xây dựng ứng dụng bằng cách sử dụng các API khác nhau của Android.</p>
+
+<p>Nếu bạn mới làm quen với việc phát triển Android, quan trọng là bạn phải hiểu
+những khái niệm cơ bản sau về khuôn khổ ứng dụng Android:</p>
+
+
+<div class="landing-banner">
+
+<div class="col-6">
+
+<h4>Các ứng dụng cung cấp nhiều điểm nhập</h4>
+
+<p>Các ứng dụng Android được tích hợp như một sự kết hợp giữa các thành phần khác nhau có thể được gọi ra
+riêng. Ví dụ, một <em>hoạt động</em> riêng lẻ cung cấp một màn hình
+duy nhất cho một giao diện người dùng, và một <em>dịch vụ</em> chạy ngầm thực hiện độc lập
+công việc.</p>
+
+<p>Từ một thành phần, bạn có thể khởi động một thành phần khác bằng cách sử dụng một <em>ý định</em>. Thậm chí bạn có thể bắt đầu
+một thành phần trong một ứng dụng khác, chẳng hạn như một hoạt động trong một ứng dụng bản đồ để hiển thị một địa chỉ. Mô hình này
+cung cấp nhiều điểm nhập cho một ứng dụng duy nhất và cho phép bất kỳ ứng dụng nào xử lý như "mặc định"
+của một người dùng đối với một hành động mà các ứng dụng khác có thể gọi ra.</p>
+
+
+<p><b>Tìm hiểu thêm:</b></p>
+<ul class="nolist">
+<li><a href="{@docRoot}guide/components/fundamentals.html">Đại cương về Ứng dụng</a>
+<li><a href="{@docRoot}guide/components/intents-filters.html">Ý định và Bộ lọc Ý định</a>
+<li><a href="{@docRoot}guide/components/activities.html">Hoạt động</a>
+</ul>
+
+</div>
+
+
+<div class="col-6">
+
+<h4>Các ứng dụng sẽ thích ứng theo các thiết bị khác nhau</h4>
+
+<p>Android cung cấp một khuôn khổ ứng dụng thích ứng cho phép bạn cung cấp các tài nguyên duy nhất
+cho các cấu hình thiết bị khác nhau. Ví dụ, bạn có thể tạo các tệp bố trí
+XML khác nhau cho các kích cỡ màn hình khác nhau và hệ thống
+sẽ xác định bố trí nào sẽ áp dụng dựa trên kích cỡ màn hình hiện tại của thiết bị.</p>
+
+<p>Bạn có thể truy vấn về sự sẵn có của các tính năng trên thiết bị vào thời gian chạy nếu bất kỳ tính năng nào của ứng dụng
+yêu cầu phần cứng cụ thể, chẳng hạn như máy ảnh. Nếu cần, bạn cũng có thể khai báo các tính năng mà ứng dụng của mình yêu cầu
+vì vậy, những chợ ứng dụng như Google Play Store không cho phép cài đặt trên những thiết bị không hỗ trợ
+tính năng đó.</p>
+
+
+<p><b>Tìm hiểu thêm:</b></p>
+<ul class="nolist">
+<li><a href="{@docRoot}guide/practices/compatibility.html">Tính tương thích của Thiết bị</a>
+<li><a href="{@docRoot}guide/topics/resources/overview.html">Tổng quan về Tài nguyên</a>
+<li><a href="{@docRoot}guide/topics/ui/overview.html">Tổng quan về Giao diện Người dùng</a>
+</ul>
+
+</div>
+
+</div><!-- end landing-banner -->
+
+
+
diff --git a/docs/html-intl/intl/vi/guide/topics/manifest/manifest-intro.jd b/docs/html-intl/intl/vi/guide/topics/manifest/manifest-intro.jd
new file mode 100644
index 000000000000..ca2ed26270f2
--- /dev/null
+++ b/docs/html-intl/intl/vi/guide/topics/manifest/manifest-intro.jd
@@ -0,0 +1,517 @@
+page.title=Bản kê khai Ứng dụng
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>Trong tài liệu này</h2>
+<ol>
+<li><a href="#filestruct">Cấu trúc của Tệp Bản kê khai</a></li>
+<li><a href="#filec">Các Quy ước Tệp</a>
+<li><a href="#filef">Các Tính năng Tệp</a>
+ <ol>
+ <li><a href="#ifs">Bộ lọc Ý định</a></li>
+ <li><a href="#iconlabel">Biểu tượng và Nhãn</a></li>
+ <li><a href="#perms">Quyền</a></li>
+ <li><a href="#libs">Thư viện</a></li>
+ </ol></li>
+</ol>
+</div>
+</div>
+
+<p>
+ Mọi ứng dụng đều phải có một tệp AndroidManifest.xml (chính xác là
+ tên gọi này) trong thư mục gốc của mình. <span itemprop="description">Tệp bản kê khai
+ trình bày những thông tin thiết yếu về ứng dụng của bạn với hệ thống Android,
+ thông tin mà hệ thống phải có trước khi có thể chạy bất kỳ mã nào
+ của ứng dụng.</span> Ngoài một số mục đích khác, bản kê khai thực hiện những điều sau:
+</p>
+
+<ul>
+<li>Nó đặt tên gói Java cho ứng dụng.
+Tên gói đóng vai trò như một mã nhận diện duy nhất cho ứng dụng.</li>
+
+<li>Nó mô tả các thành phần của ứng dụng &mdash; hoạt động,
+dịch vụ, hàm nhận quảng bá, và trình cung cấp nội dung mà ứng dụng
+được soạn bởi. Nó đặt tên các lớp triển khai từng thành phần và
+công bố các khả năng của chúng (ví dụ, những tin nhắn {@link android.content.Intent
+Intent} mà chúng có thể xử lý). Những khai báo này cho phép hệ thống Android
+biết các thành phần là gì và chúng có thể được khởi chạy trong những điều kiện nào.</li>
+
+<li>Nó xác định những tiến trình nào sẽ lưu trữ các thành phần ứng dụng.</li>
+
+<li>Nó khai báo các quyền mà ứng dụng phải có để
+truy cập các phần được bảo vệ của API và tương tác với các ứng dụng khác.</li>
+
+<li>Nó cũng khai báo các quyền mà ứng dụng khác phải có để
+tương tác với các thành phần của ứng dụng.</li>
+
+<li>Nó liệt kê các lớp {@link android.app.Instrumentation} cung cấp
+tính năng tạo hồ sơ và các thông tin khác khi ứng dụng đang chạy. Những khai báo này
+chỉ xuất hiện trong bản kê khai khi ứng dụng đang được phát triển và
+thử nghiệm; chúng bị loại bỏ trước khi ứng dụng được công bố.</li>
+
+<li>Nó khai báo mức tối thiểu của API Android mà ứng dụng
+yêu cầu.</li>
+
+<li>Nó liệt kê các thư viện mà ứng dụng phải được liên kết với.</li>
+</ul>
+
+
+<h2 id="filestruct">Cấu trúc của Tệp Bản kê khai</h2>
+
+<p>
+Sơ đồ bên dưới minh họa cấu trúc chung của tệp bản kê khai và mọi
+phần tử mà nó có thể chứa. Từng phần tử, cùng với tất cả thuộc tính
+của mình, sẽ được lập tài liệu theo dõi đầy đủ vào một tệp riêng. Để xem thông tin
+chi tiết về mọi phần tử, hãy nhấp vào tên phần tử trong sơ đồ,
+trong danh sách các phần tử theo thứ tự chữ cái mà tuân theo sơ đồ, hoặc trên bất kỳ
+nội dung nào khác đề cập tới tên phần tử.
+</p>
+
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
+
+<a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a>
+
+ <a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/permission-element.html">&lt;permission /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/permission-tree-element.html">&lt;permission-tree /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/permission-group-element.html">&lt;permission-group /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/instrumentation-element.html">&lt;instrumentation /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">&lt;uses-sdk /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/uses-configuration-element.html">&lt;uses-configuration /&gt;</a> <!-- ##api level 3## -->
+ <a href="{@docRoot}guide/topics/manifest/uses-feature-element.html">&lt;uses-feature /&gt;</a> <!-- ##api level 4## -->
+ <a href="{@docRoot}guide/topics/manifest/supports-screens-element.html">&lt;supports-screens /&gt;</a> <!-- ##api level 4## -->
+ <a href="{@docRoot}guide/topics/manifest/compatible-screens-element.html">&lt;compatible-screens /&gt;</a> <!-- ##api level 9## -->
+ <a href="{@docRoot}guide/topics/manifest/supports-gl-texture-element.html">&lt;supports-gl-texture /&gt;</a> <!-- ##api level 11## -->
+
+ <a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a>
+
+ <a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/action-element.html">&lt;action /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/category-element.html">&lt;category /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/data-element.html">&lt;data /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;/intent-filter&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">&lt;meta-data /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;/activity&gt;</a>
+
+ <a href="{@docRoot}guide/topics/manifest/activity-alias-element.html">&lt;activity-alias&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a> . . . <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;/intent-filter&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">&lt;meta-data /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/activity-alias-element.html">&lt;/activity-alias&gt;</a>
+
+ <a href="{@docRoot}guide/topics/manifest/service-element.html">&lt;service&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a> . . . <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;/intent-filter&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">&lt;meta-data/&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/service-element.html">&lt;/service&gt;</a>
+
+ <a href="{@docRoot}guide/topics/manifest/receiver-element.html">&lt;receiver&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a> . . . <a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;/intent-filter&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">&lt;meta-data /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/receiver-element.html">&lt;/receiver&gt;</a>
+
+ <a href="{@docRoot}guide/topics/manifest/provider-element.html">&lt;provider&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/grant-uri-permission-element.html">&lt;grant-uri-permission /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">&lt;meta-data /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/path-permission-element.html">&lt;path-permission /&gt;</a>
+ <a href="{@docRoot}guide/topics/manifest/provider-element.html">&lt;/provider&gt;</a>
+
+ <a href="{@docRoot}guide/topics/manifest/uses-library-element.html">&lt;uses-library /&gt;</a>
+
+ <a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;/application&gt;</a>
+
+<a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;/manifest&gt;</a>
+</pre>
+
+<p>
+Tất cả phần tử có thể xuất hiện trong tệp bản kê khai được liệt kê ở bên dưới
+theo thứ tự chữ cái. Đây là những phần tử hợp pháp duy nhất; bạn không thể
+thêm các phần tử hay thuộc tính của chính mình.
+</p>
+
+<p style="margin-left: 2em">
+<code><a href="{@docRoot}guide/topics/manifest/action-element.html">&lt;action&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/activity-alias-element.html">&lt;activity-alias&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/category-element.html">&lt;category&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/data-element.html">&lt;data&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/grant-uri-permission-element.html">&lt;grant-uri-permission&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/instrumentation-element.html">&lt;instrumentation&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html">&lt;meta-data&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/permission-element.html">&lt;permission&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/permission-group-element.html">&lt;permission-group&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/permission-tree-element.html">&lt;permission-tree&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/provider-element.html">&lt;provider&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/receiver-element.html">&lt;receiver&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/service-element.html">&lt;service&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/supports-screens-element.html">&lt;supports-screens&gt;</a></code> <!-- ##api level 4## -->
+<br/><code><a href="{@docRoot}guide/topics/manifest/uses-configuration-element.html">&lt;uses-configuration&gt;</a></code> <!-- ##api level 3## -->
+<br/><code><a href="{@docRoot}guide/topics/manifest/uses-feature-element.html">&lt;uses-feature&gt;</a></code> <!-- ##api level 4## -->
+<br/><code><a href="{@docRoot}guide/topics/manifest/uses-library-element.html">&lt;uses-library&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission&gt;</a></code>
+<br/><code><a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html">&lt;uses-sdk&gt;</a></code>
+</p>
+
+
+
+
+<h2 id="filec">Các Quy ước Tệp</h2>
+
+<p>
+Một số quy ước và quy tắc áp dụng chung cho tất cả các phần tử và thuộc tính
+trong bản kê khai:
+</p>
+
+<dl>
+<dt><b>Phần tử</b></dt>
+<dd>Chỉ các phần tử
+<code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code> và
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code>
+là bắt buộc phải có, chúng đều phải có mặt và chỉ có thể xảy ra một lần.
+Hầu hết các phần tử khác có thể xảy ra nhiều lần hoặc không xảy ra &mdash; mặc dù ít
+nhất một vài trong số chúng phải có mặt để bản kê khai thực sự có
+ý nghĩa nào đó.
+
+<p>
+Nếu một phần tử chứa bất kỳ nội dung nào, nó có thể chứa các phần tử khác.
+Tất cả giá trị sẽ được đặt thông qua thuộc tính, chứ không phải là dữ liệu ký tự trong một phần tử.
+</p>
+
+<p>
+Các phần tử cùng cấp thường không theo thứ tự. Ví dụ, các phần tử
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>,
+<code><a href="{@docRoot}guide/topics/manifest/provider-element.html">&lt;provider&gt;</a></code>, và
+<code><a href="{@docRoot}guide/topics/manifest/service-element.html">&lt;service&gt;</a></code>
+có thể được trộn lẫn với nhau theo bất kỳ trình tự nào. (Phần tử
+<code><a href="{@docRoot}guide/topics/manifest/activity-alias-element.html">&lt;activity-alias&gt;</a></code>
+là trường hợp ngoại lệ đối với quy tắc này: Nó phải tuân theo
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
+, đối tượng mà nó là bí danh cho.)
+</p></dd>
+
+<dt><b>Thuộc tính</b></dt>
+<dd>Theo cách hiểu thông thường, tất cả thuộc tính đều mang tính tùy chọn. Tuy nhiên, có một số thuộc tính
+phải được quy định cho một phần tử để hoàn thành mục đích của nó. Sử dụng
+tài liệu làm hướng dẫn. Đối với những thuộc tính thực sự tùy chọn, nó đề cập tới một giá trị
+mặc định hoặc thông báo điều gì sẽ xảy ra nếu không có một đặc tả.
+
+<p>Ngoài một số thuộc tính của phần tử
+<code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code>
+gốc, tất cả tên thuộc tính đều bắt đầu bằng một tiền tố {@code android:}&mdash;
+ví dụ, {@code android:alwaysRetainTaskState}. Do tiền tố này
+phổ dụng, tài liệu thường bỏ sót nó khi tham chiếu tới các thuộc tính
+theo tên.</p></dd>
+
+<dt><b>Khai báo tên lớp</b></dt>
+<dd>Nhiều thuộc tính tương ứng với các đối tượng Java, bao gồm các phần tử cho
+chính ứng dụng (phần tử
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code>
+) và các thành phần chính của nó &mdash; hoạt động
+(<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>),
+dịch vụ
+(<code><a href="{@docRoot}guide/topics/manifest/service-element.html">&lt;service&gt;</a></code>),
+hàm nhận quảng bá
+(<code><a href="{@docRoot}guide/topics/manifest/receiver-element.html">&lt;receiver&gt;</a></code>),
+và trình cung cấp nội dung
+(<code><a href="{@docRoot}guide/topics/manifest/provider-element.html">&lt;provider&gt;</a></code>).
+
+<p>
+Nếu bạn định nghĩa một lớp con như vẫn luôn làm đối với lớp thành phần
+({@link android.app.Activity}, {@link android.app.Service},
+{@link android.content.BroadcastReceiver}, và {@link android.content.ContentProvider}),
+lớp con sẽ được khai báo thông qua một thuộc tính {@code name}. Tên phải bao gồm
+chỉ định gói đầy đủ.
+Ví dụ, một lớp con {@link android.app.Service} có thể được khai báo như sau:
+</p>
+
+<pre>&lt;manifest . . . &gt;
+ &lt;application . . . &gt;
+ &lt;service android:name="com.example.project.SecretService" . . . &gt;
+ . . .
+ &lt;/service&gt;
+ . . .
+ &lt;/application&gt;
+&lt;/manifest&gt;</pre>
+
+<p>
+Tuy nhiên, do cách viết tốc ký, nếu ký tự đầu tiên của xâu là một dấu chấm,
+xâu sẽ được nối với tên gói của ứng dụng (như được quy định bởi
+thuộc tính của phần tử <code><a href="{@docRoot}guide/topics/manifest/manifest-element.html">&lt;manifest&gt;</a></code>
+
+<code>, <a href="{@docRoot}guide/topics/manifest/manifest-element.html#package">package</a></code>
+). Cách gán sau cũng giống như trên:
+</p>
+
+<pre>&lt;manifest package="com.example.project" . . . &gt;
+ &lt;application . . . &gt;
+ &lt;service android:name=".SecretService" . . . &gt;
+ . . .
+ &lt;/service&gt;
+ . . .
+ &lt;/application&gt;
+&lt;/manifest&gt;</pre>
+
+<p>
+Khi khởi động một thành phần, Android sẽ tạo một thực thể của lớp con được nêu tên.
+Nếu lớp con không được quy định, nó sẽ tạo một thực thể của lớp cơ sở.
+</p></dd>
+
+<dt><b>Nhiều giá trị</b></dt>
+<dd>Nếu có thể quy định nhiều hơn một giá trị, phần tử gần như luôn
+được lặp lại, thay vì liệt kê nhiều giá trị trong một phần tử duy nhất.
+Ví dụ, một bộ lọc ý định có thể liệt kê vài hành động:
+
+<pre>&lt;intent-filter . . . &gt;
+ &lt;action android:name="android.intent.action.EDIT" /&gt;
+ &lt;action android:name="android.intent.action.INSERT" /&gt;
+ &lt;action android:name="android.intent.action.DELETE" /&gt;
+ . . .
+&lt;/intent-filter&gt;</pre></dd>
+
+<dt><b>Giá trị tài nguyên</b></dt>
+<dd>Một số thuộc tính có các giá trị có thể được hiển thị với người dùng &mdash; ví
+dụ, một nhãn và một biểu tượng cho một hoạt động. Giá trị của những thuộc tính này
+cần được cục bộ hóa và vì thế phải được thiết đặt từ một tài nguyên hoặc chủ đề. Giá trị
+tài nguyên được biểu diễn theo định dạng sau,</p>
+
+<p style="margin-left: 2em">{@code @[<i>gói</i>:]<i>kiểu</i>:<i>tên</i>}</p>
+
+<p>
+trong đó <i>gói</i> có thể được bỏ qua nếu tài nguyên nằm trong cùng gói
+với ứng dụng, <i>kiểu</i> là kiểu của tài nguyên &mdash; chẳng hạn như "xâu" hoặc
+&mdash; "vẽ được" và <i>tên</i> là tên nhận biết tài nguyên cụ thể.
+Ví dụ:
+</p>
+
+<pre>&lt;activity android:icon="@drawable/smallPic" . . . &gt</pre>
+
+<p>
+Các giá trị từ một chủ đề được biểu diễn theo cách tương tự, nhưng với một '{@code ?}'
+thay vì '{@code @}' ở đầu:
+</p>
+
+<p style="margin-left: 2em">{@code ?[<i>gói</i>:]<i>kiểu</i>:<i>tên</i>}
+</p></dd>
+
+<dt><b>Giá trị xâu</b></dt>
+<dd>Trường hợp giá trị của một thuộc tính là một xâu, phải sử dụng hai dấu xuyệc ngược ('{@code \\}')
+để thoát các ký tự &mdash; ví dụ, '{@code \\n}' đối với
+một dòng tin tức hoặc '{@code \\uxxxx}' đối với một ký tự Unicode.</dd>
+</dl>
+
+
+<h2 id="filef">Các Tính năng Tệp</h2>
+
+<p>
+Phần sau đây mô tả cách phản ánh một số tính năng của Android
+trong tệp bản kê khai.
+</p>
+
+
+<h3 id="ifs">Bộ lọc Ý định</h3>
+
+<p>
+Các thành phần cốt lõi của một ứng dụng (hoạt động, dịch vụ và hàm nhận
+quảng bá) được kích hoạt bởi <i>ý định</i>. Ý định là một
+gói thông tin (một đối tượng {@link android.content.Intent}) mô tả một
+hành động mong muốn &mdash; bao gồm dữ liệu sẽ được dựa trên, thể loại của
+thành phần mà sẽ thực hiện hành động, và các chỉ dẫn thích hợp khác.
+Android định vị một thành phần phù hợp để hồi đáp ý định, khởi chạy
+một thực thể mới của thành phần nếu cần, và chuyển cho nó đối tượng đó
+Ý định.
+</p>
+
+<p>
+Các thành phần sẽ quảng cáo khả năng của mình &mdash; các kiểu ý định mà chúng có thể
+hồi đáp &mdash; thông qua <i>các bộ lọc ý định</i>. Do hệ thống Android phải
+tìm hiểu một thành phần có thể xử lý những ý định nào trước khi khởi chạy thành phần đó,
+bộ lọc ý định được quy định trong bản kê khai như là các phần tử
+<code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a></code>
+. Một thành phần có thể có nhiều bộ lọc, mỗi bộ lọc lại mô tả
+một khả năng khác nhau.
+</p>
+
+<p>
+Một ý định mà công khai nêu tên một thành phần mục tiêu sẽ kích hoạt thành phần đó;
+bộ lọc không có vai trò gì ở đây. Nhưng một ý định mà không quy định một mục tiêu
+theo tên sẽ chỉ có thể kích hoạt thành phần nếu nó có thể chuyển qua một trong các bộ lọc của
+thành phần.
+</p>
+
+<p>
+Để biết thông tin về cách các đối tượng Ý định được kiểm tra thông qua bộ lọc ý định,
+hãy xem tài liệu riêng có tiêu đề
+<a href="{@docRoot}guide/components/intents-filters.html">Ý định
+và Bộ lọc Ý định</a>.
+</p>
+
+
+<h3 id="iconlabel">Biểu tượng và Nhãn</h3>
+
+<p>
+Nhiều phần tử có thuộc tính {@code icon} và {@code label} cho một
+biểu tượng nhỏ và nhãn văn bản mà có thể được hiển thị với người dùng. Một số cũng có thuộc tính
+{@code description} cho văn bản giải trình dài hơn mà cũng có thể
+được hiển thị trên màn hình. Ví dụ, phần tử
+<code><a href="{@docRoot}guide/topics/manifest/permission-element.html">&lt;permission&gt;</a></code>
+có cả ba thuộc tính này, vì thế khi người dùng được hỏi xem có
+cấp quyền cho một ứng dụng yêu cầu hay không, biểu tượng thể hiện
+quyền, tên của quyền, và mô tả nội dung
+của quyền đó đều có thể được trình bày cho người dùng xem.
+</p>
+
+<p>
+Trong mọi trường hợp, biểu tượng và nhãn được đặt trong một phần tử chứa sẽ trở thành các thiết đặt
+{@code icon} và {@code label} mặc định cho tất cả phần tử con của bộ chứa đó.
+Vì thế, biểu tượng và nhãn được đặt trong phần tử
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code>
+là biểu tượng và nhãn mặc định cho từng thành phần của ứng dụng.
+Tương tự, biểu tượng và nhãn được đặt cho một thành phần &mdash; ví dụ, một phần tử
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
+&mdash; sẽ là các cài đặt mặc định cho từng phần tử
+<code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html">&lt;intent-filter&gt;</a></code>
+của thành phần đó. Nếu một phần tử
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html">&lt;application&gt;</a></code>
+thiết đặt một nhãn, nhưng hoạt động và bộ lọc ý định của nó thì không,
+nhãn ứng dụng sẽ được coi là nhãn của cả hoạt động và
+bộ lọc ý định.
+</p>
+
+<p>
+Biểu tượng và nhãn được đặt cho một bộ lọc ý định sẽ được sử dụng để biểu diễn một thành phần
+bất cứ khi nào thành phần đó được trình bày với người dùng để thực hiện chức năng
+mà bộ lọc đã quảng cáo. Ví dụ, một bộ lọc với các thiết đặt
+"{@code android.intent.action.MAIN}" và
+"{@code android.intent.category.LAUNCHER}" quảng cáo một hoạt động
+là hoạt động khởi đầu một ứng dụng &mdash; cụ thể, là
+hoạt động sẽ được hiển thị trong trình khởi chạy ứng dụng. Vì thế, biểu tượng và nhãn
+được đặt trong bộ lọc là những nội dung được hiển thị trong trình khởi chạy.
+</p>
+
+
+<h3 id="perms">Quyền</h3>
+
+<p>
+Một <i>quyền</i> là sự 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.
+</p>
+
+<p>
+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:
+</p>
+
+<p style="margin-left: 2em">{@code android.permission.CALL_EMERGENCY_NUMBERS}
+<br/>{@code android.permission.READ_OWNER_DATA}
+<br/>{@code android.permission.SET_WALLPAPER}
+<br/>{@code android.permission.DEVICE_POWER}</p>
+
+<p>
+Một tính năng có thể được bảo vệ bởi nhiều nhất một quyền.
+</p>
+
+<p>
+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ử
+<code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission&gt;</a></code>
+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.
+</p>
+
+<p>
+Một ứng dụng cũng có thể bảo vệ các thành phần của chính nó (hoạt động, dịch vụ,
+hàm nhận quảng bá và trình cung cấp nội dung) bằng các quyền. Nó có thể sử dụng
+bất kỳ quyền nào được định nghĩa bởi Android (được liệt kê trong
+{@link android.Manifest.permission android.Manifest.permission}) hoặc được khai báo
+bởi các ứng dụng khác. Hoặc nó có thể tự định nghĩa quyền của mình. Một quyền mới được khai báo
+bằng phần tử
+<code><a href="{@docRoot}guide/topics/manifest/permission-element.html">&lt;permission&gt;</a></code>
+. Ví dụ, một hoạt động có thể được bảo vệ như sau:
+</p>
+
+<pre>
+&lt;manifest . . . &gt;
+ &lt;permission android:name="com.example.project.DEBIT_ACCT" . . . /&gt;
+ &lt;uses-permission android:name="com.example.project.DEBIT_ACCT" /&gt;
+ . . .
+ &lt;application . . .&gt;
+ &lt;activity android:name="com.example.project.FreneticActivity"
+ android:permission="com.example.project.DEBIT_ACCT"
+ . . . &gt;
+ . . .
+ &lt;/activity&gt;
+ &lt;/application&gt;
+&lt;/manifest&gt;
+</pre>
+
+<p>
+Lưu ý rằng trong ví dụ này, quyền {@code DEBIT_ACCT} không chỉ
+được khai báo bằng phần tử
+<code><a href="{@docRoot}guide/topics/manifest/permission-element.html">&lt;permission&gt;</a></code>
+, việc sử dụng quyền cũng được yêu cầu bằng phần tử
+<code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission&gt;</a></code>
+. Phải yêu cầu sử dụng quyền để các thành phần khác của
+ứng dụng nhằm khởi chạy hoạt động được bảo vệ, mặc dù việc bảo vệ
+do chính ứng dụng áp đặt.
+</p>
+
+<p>
+Trong cùng ví dụ này, nếu thuộc tính {@code permission} được đặt thành một quyền
+được khai báo ở nơi khác
+(chẳng hạn như {@code android.permission.CALL_EMERGENCY_NUMBERS}, sẽ không
+cần phải khai báo lại nó bằng một phần tử
+<code><a href="{@docRoot}guide/topics/manifest/permission-element.html">&lt;permission&gt;</a></code>
+. Tuy nhiên, sẽ vẫn cần phải yêu cầu sử dụng nó bằng
+<code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission&gt;</a></code>.
+</p>
+
+<p>
+Phần tử
+<code><a href="{@docRoot}guide/topics/manifest/permission-tree-element.html">&lt;permission-tree&gt;</a></code>
+sẽ khai báo một vùng tên cho nhóm quyền mà sẽ được định nghĩa trong
+mã. Và
+<code><a href="{@docRoot}guide/topics/manifest/permission-group-element.html">&lt;permission-group&gt;</a></code>
+sẽ định nghĩa một nhãn cho một tập hợp quyền (cả được khai báo trong bản kê khai bằng phần tử
+<code><a href="{@docRoot}guide/topics/manifest/permission-element.html">&lt;permission&gt;</a></code>
+và được khai báo ở chỗ khác). Nó chỉ ảnh hưởng tới cách các quyền được
+nhóm lại khi được trình bày với người dùng. Phần tử
+<code><a href="{@docRoot}guide/topics/manifest/permission-group-element.html">&lt;permission-group&gt;</a></code>
+không quy định những quyền nào thuộc về nhóm;
+nó chỉ đặt cho nhóm một cái tên. Một quyền được đặt vào nhóm
+bằng cách gán tên nhóm với thuộc tính của phần tử
+<code><a href="{@docRoot}guide/topics/manifest/permission-element.html">&lt;permission&gt;</a></code>
+,
+<code><a href="{@docRoot}guide/topics/manifest/permission-element.html#pgroup">permissionGroup</a></code>
+.
+</p>
+
+
+<h3 id="libs">Thư viện</h3>
+
+<p>
+Mọi ứng dụng đều được liên kết với thư viện Android mặc định, nó
+bao gồm các gói cơ bản để xây dựng ứng dụng (bằng các lớp thông dụng
+chẳng hạn như Hoạt động, Dịch vụ, Ý định, Dạng xem, Nút, Ứng dụng, Trình cung cấp Nội dung,
+v.v.).
+</p>
+
+<p>
+Tuy nhiên, một số gói nằm trong thư viện của chính mình. Nếu ứng dụng của bạn
+sử dụng mã từ bất kỳ gói nào trong những gói này, nó phải công khai yêu cầu được liên kết
+với chúng. Bản kê khai phải chứa một phần tử
+<code><a href="{@docRoot}guide/topics/manifest/uses-library-element.html">&lt;uses-library&gt;</a></code>
+riêng để đặt tên cho từng thư viện. (Tên thư viện có thể được tìm thấy trong tài liệu
+của gói.)
+</p>
diff --git a/docs/html-intl/intl/vi/guide/topics/providers/calendar-provider.jd b/docs/html-intl/intl/vi/guide/topics/providers/calendar-provider.jd
new file mode 100644
index 000000000000..e2ecdb32b2e8
--- /dev/null
+++ b/docs/html-intl/intl/vi/guide/topics/providers/calendar-provider.jd
@@ -0,0 +1,1184 @@
+page.title=Trình cung cấp Lịch
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+ <h2>Trong tài liệu này</h2>
+ <ol>
+ <li><a href="#overview">Nội dung Cơ bản</a></li>
+ <li><a href="#manifest">Quyền của Người dùng</a></li>
+ <li><a href="#calendar">Bảng Lịch</a>
+<ol>
+ <li><a href="#query">Truy vấn một lịch</a></li>
+ <li><a href="#modify-calendar">Sửa đổi một lịch</a></li>
+ <li><a href="#insert-calendar">Chèn một lịch</a></li>
+ </ol>
+ </li>
+ <li><a href="#events">Bảng Sự kiện</a>
+<ol>
+ <li><a href="#add-event">Thêm Sự kiện</a></li>
+ <li><a href="#update-event">Cập nhật Sự kiện</a></li>
+ <li><a href="#delete-event">Xóa Sự kiện</a></li>
+ </ol>
+ </li>
+ <li><a href="#attendees">Bảng Người dự</a>
+<ol>
+ <li><a href="#add-attendees">Thêm Người dự</a></li>
+ </ol>
+ </li>
+ <li><a href="#reminders">Bảng Nhắc nhở</a>
+<ol>
+ <li><a href="#add-reminders">Thêm Nhắc nhở</a></li>
+ </ol>
+ </li>
+ <li><a href="#instances">Bảng Thực thể</a>
+ <ol>
+ <li><a href="#query-instances">Truy vấn bảng Thực thể</a></li>
+ </ol></li>
+ <li><a href="#intents">Ý định Lịch</a>
+ <ol>
+ <li><a href="#intent-insert">Sử dụng ý định để chèn một sự kiện</a></li>
+ <li><a href="#intent-edit">Sử dụng ý định để chỉnh sửa một sự kiện</a></li>
+ <li><a href="#intent-view">Sử dụng ý định để xem dữ liệu lịch</a></li>
+ </ol>
+ </li>
+
+ <li><a href="#sync-adapter">Trình điều hợp Đồng bộ</a></li>
+</ol>
+
+ <h2>Lớp khóa</h2>
+ <ol>
+ <li>{@link android.provider.CalendarContract.Calendars}</li>
+ <li>{@link android.provider.CalendarContract.Events}</li>
+ <li>{@link android.provider.CalendarContract.Attendees}</li>
+ <li>{@link android.provider.CalendarContract.Reminders}</li>
+ </ol>
+</div>
+</div>
+
+<p>Trình cung cấp Lịch là một kho lưu trữ các sự kiện lịch của người dùng. API
+Trình cung cấp Lịch cho phép bạn thực hiện truy vấn, chèn, cập nhật và xóa
+các thao tác trên lịch, sự kiện, người dự, nhắc nhở, v.v.</p>
+
+
+<p>API Trình cung cấp Lịch có thể được sử dụng bởi các ứng dụng và trình điều hợp đồng bộ. Các quy tắc
+thay đổi tùy vào loại chương trình đang thực hiện lệnh gọi. Tài liệu này
+tập trung chủ yếu vào việc sử dụng API Trình cung cấp Lịch như một ứng dụng. Để bàn
+về việc các trình điều hợp đồng bộ khác nhau như thế nào, hãy xem phần
+<a href="#sync-adapter">Trình điều hợp Đồng bộ</a>.</p>
+
+
+<p>Thông thường, để đọc hoặc ghi dữ liệu lịch, bản kê khai của ứng dụng phải
+bao gồm các quyền thích hợp của người dùng, được nêu trong phần <a href="#manifest">Quyền
+của Người dùng</a>. Để thực hiện các thao tác chung dễ hơn, Trình cung cấp
+Lịch đưa ra một tập hợp ý định, như được mô tả trong phần <a href="#intents">Ý định
+Lịch</a>. Những ý định này đưa người dùng tới ứng dụng Lịch để chèn, xem,
+và chỉnh sửa sự kiện. Người dùng tương tác với ứng dụng Lịch rồi
+quay lại ứng dụng ban đầu. Vì thế, ứng dụng của bạn không cần yêu cầu quyền,
+và cũng không cần cung cấp một giao diện người dùng để xem hoặc tạo sự kiện.</p>
+
+<h2 id="overview">Nội dung Cơ bản</h2>
+
+<p><a href="{@docRoot}guide/topics/providers/content-providers.html">Các trình cung cấp nội dung</a> sẽ lưu trữ dữ liệu và cho phép truy cập
+ứng dụng. Trình cung cấp nội dung được nền tảng Android giới thiệu (bao gồm Trình cung cấp Lịch) thường trình bày dữ liệu như một tập hợp gồm nhiều bảng dựa trên một
+mô hình cơ sở dữ liệu quan hệ, trong đó mỗi hàng là một bản ghi và mỗi cột là dữ liệu thuộc
+một loại và có ý nghĩa cụ thể. Thông qua API Trình cung cấp Lịch, các ứng dụng
+và trình điều hợp đồng bộ có thể nhận được quyền truy cập đọc/ghi vào các bảng trong cơ sở dữ liệu là nơi chứa
+dữ liệu lịch của người dùng.</p>
+
+<p>Mọi trình cung cấp nội dung đều đưa ra một URI công khai (được bẻ dòng như một đối tượng
+{@link android.net.Uri}
+) để xác định tập dữ liệu của nó một cách duy nhất. Trình cung cấp nội dung mà kiểm soát nhiều
+ tập dữ liệu (nhiều bảng) sẽ đưa ra một URI riêng cho từng bảng. Tất cả
+URI cho trình cung cấp đều bắt đầu bằng xâu "content://". Điều này
+sẽ xác định dữ liệu là đang được kiểm soát bởi một trình cung cấp nội dung. Trình cung cấp
+Lịch định nghĩa các hằng số cho URI đối với từng lớp (bảng) của nó. Những URI
+này có định dạng <code><em>&lt;class&gt;</em>.CONTENT_URI</code>. Ví
+dụ, {@link android.provider.CalendarContract.Events#CONTENT_URI Events.CONTENT_URI}.</p>
+
+<p>Hình 1 cho biết biểu diễn đồ họa của mô hình dữ liệu Trình cung cấp Lịch. Nó cho biết
+các bảng chính và các trường liên kết chúng với nhau.</p>
+
+<img src="{@docRoot}images/providers/datamodel.png" alt="Calendar Provider Data Model" />
+<p class="img-caption"><strong>Hình 1.</strong> Mô hình dữ liệu Trình cung cấp Lịch.</p>
+
+<p>Một người dùng có thể có nhiều lịch, và các lịch khác nhau có thể được liên kết với các loại tài khoản khác nhau (Google Calendar, Exchange, v.v.).</p>
+
+<p>{@link android.provider.CalendarContract} sẽ định nghĩa mô hình dữ liệu của thông tin liên quan tới lịch và sự kiện. Dữ liệu này được lưu trữ trong nhiều bảng như liệt kê bên dưới.</p>
+
+<table>
+ <tr>
+ <th>Bảng (Lớp)</th>
+ <th>Mô tả</th>
+ </tr>
+ <tr>
+ <td><p>{@link android.provider.CalendarContract.Calendars}</p></td>
+
+ <td>Bảng này chứa
+thông tin riêng của lịch. Mỗi hàng trong bảng này chứa chi tiết của
+một lịch duy nhất, chẳng hạn như tên, màu, thông tin đồng bộ, v.v.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.Events}</td>
+
+ <td>Bảng này chứa
+thông tin riêng theo sự kiện. Mỗi hàng trong bảng có thông tin cho một
+sự kiện duy nhất&mdash;ví dụ: tiêu đề sự kiện, địa điểm, thời gian bắt đầu
+, thời gian kết thúc, v.v. Sự kiện có thể xảy ra một lần hoặc lặp lại nhiều lần. Người dự,
+nhắc nhở, và các tính chất mở rộng được lưu trữ trong các bảng riêng.
+Mỗi mục đều có một {@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID}
+tham chiếu tới {@link android.provider.BaseColumns#_ID} trong bảng Sự kiện.</td>
+
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.Instances}</td>
+
+ <td>Bảng này chứa
+thời gian bắt đầu và thời gian kết thúc của mỗi lần xảy ra một sự kiện. Mỗi hàng trong bảng này
+đại diện cho một lần xảy ra sự kiện. Với các sự kiện xảy ra một lần thì có một ánh xạ 1:1
+của thực thể tới sự kiện. Đối với các sự kiện định kỳ, nhiều hàng sẽ tự động
+ được khởi tạo tương ứng với nhiều lần xảy ra sự kiện đó.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.Attendees}</td>
+
+ <td>Bảng này chứa
+thông tin về người dự (khách) của sự kiện. Mỗi hàng đại diện một khách duy nhất của
+một sự kiện. Nó quy định loại khách và phản hồi tham dự của khách
+cho một sự kiện.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.Reminders}</td>
+
+ <td>Bảng này chứa
+dữ liệu về cảnh báo/thông báo. Mỗi hàng đại diện một cảnh báo duy nhất cho một sự kiện. Một
+sự kiện có thể có nhiều nhắc nhở. Số nhắc nhở tối đa của một sự kiện
+được quy định trong
+{@link android.provider.CalendarContract.CalendarColumns#MAX_REMINDERS},
+được đặt bởi trình điều hợp đồng bộ đang
+sở hữu lịch đã cho. Nhắc nhở được quy định bằng số phút trước khi diễn ra sự kiện
+và có một phương pháp để xác định cách người dùng sẽ được cảnh báo.</td>
+ </tr>
+
+</table>
+
+<p>API Trình cung cấp Lịch được thiết kế để linh hoạt và mạnh mẽ. Đồng
+thời, điều quan trọng là phải cung cấp một trải nghiệm người dùng cuối tốt và
+bảo vệ sự toàn vẹn của lịch và dữ liệu lịch. Để làm điều này, sau đây là một số
+điều cần ghi nhớ khi sử dụng API này:</p>
+
+<ul>
+
+<li><strong>Chèn, cập nhật, và xem sự kiện lịch.</strong> Để trực tiếp chèn, sửa đổi, và đọc sự kiện từ Trình cung cấp Lịch, bạn cần <a href="#manifest">các quyền</a> phù hợp. Tuy nhiên, nếu bạn không đang xây dựng một ứng dụng lịch hoặc trình điều hợp đồng bộ chính thức, việc yêu cầu những quyền này là không cần thiết. Thay vào đó, bạn có thể sử dụng những ý định được cung cấp bởi ứng dụng Lịch của Android để chuyển giao các thao tác đọc và ghi cho ứng dụng đó. Khi bạn sử dụng ý định, ứng dụng của bạn sẽ gửi người dùng tới ứng dụng Lịch để thực hiện thao tác mong muốn
+trong một mẫu được điền trước. Sau khi xong, họ sẽ được trả về ứng dụng của bạn.
+Bằng việc thiết kế ứng dụng của bạn để thực hiện các thao tác thường gặp thông qua Lịch,
+bạn cung cấp cho người dùng một giao diện người dùng nhất quán, thiết thực. Đây là phương pháp
+được khuyến cáo nên dùng. Để biết thêm thông tin, hãy xem phần <a href="#intents">Ý định
+Lịch</a>.</p>
+
+
+<li><strong>Trình điều hợp đồng bộ.</strong> Trình điều hợp đồng bộ có chức năng đồng bộ dữ liệu lịch
+lên thiết bị của một người dùng bằng một máy chủ hoặc nguồn dữ liệu khác. Trong bảng
+{@link android.provider.CalendarContract.Calendars} và
+{@link android.provider.CalendarContract.Events},
+có các cột để cho trình điều hợp đồng bộ sử dụng.
+Trình cung cấp và ứng dụng không nên sửa đổi chúng. Trên thực tế, chúng không
+hiển thị trừ khi được truy cập như một trình điều hợp đồng bộ. Để biết thêm thông tin về
+trình điều hợp đồng bộ, hãy xem phần <a href="#sync-adapter">Trình điều hợp Đồng bộ</a>.</li>
+
+</ul>
+
+
+<h2 id="manifest">Quyền của Người dùng</h2>
+
+<p>Để đọc dữ liệu lịch, một ứng dụng phải bao gồm quyền {@link
+android.Manifest.permission#READ_CALENDAR} trong tệp bản kê khai của mình. Nó
+phải bao gồm quyền {@link android.Manifest.permission#WRITE_CALENDAR}
+để xóa, chèn hoặc cập nhật dữ liệu lịch:</p>
+
+<pre>
+&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
+&lt;manifest xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;...&gt;
+ &lt;uses-sdk android:minSdkVersion=&quot;14&quot; /&gt;
+ &lt;uses-permission android:name=&quot;android.permission.READ_CALENDAR&quot; /&gt;
+ &lt;uses-permission android:name=&quot;android.permission.WRITE_CALENDAR&quot; /&gt;
+ ...
+&lt;/manifest&gt;
+</pre>
+
+
+<h2 id="calendar">Bảng Lịch</h2>
+
+<p>Bảng {@link android.provider.CalendarContract.Calendars} chứa thông tin chi tiết
+cho từng lịch. Các cột
+Lịch sau có thể ghi được bởi cả ứng dụng và <a href="#sync-adapter">trình điều hợp đồng bộ</a>.
+Để xem danh sách đầy đủ về các trường được hỗ trợ, hãy xem tài liệu tham khảo
+{@link android.provider.CalendarContract.Calendars}.</p>
+<table>
+ <tr>
+ <th>Hằng số</th>
+ <th>Mô tả</th>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.Calendars#NAME}</td>
+ <td>Tên của lịch.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.Calendars#CALENDAR_DISPLAY_NAME}</td>
+ <td>Tên của lịch này mà được hiển thị cho người dùng.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.Calendars#VISIBLE}</td>
+
+ <td>Một boolean cho biết lịch có được chọn để hiển thị hay không. Giá trị
+bằng 0 cho biết các sự kiện liên kết với lịch này sẽ không được
+hiển thị. Giá trị bằng 1 cho biết các sự kiện liên kết với lịch này sẽ được
+hiển thị. Giá trị này ảnh hưởng tới việc khởi tạo hàng trong bảng {@link
+android.provider.CalendarContract.Instances}.</td>
+
+
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.CalendarColumns#SYNC_EVENTS}</td>
+
+ <td>Một boolean cho biết lịch sẽ được đồng bộ và có các sự kiện
+của mình được lưu trữ trên thiết bị hay không. Giá trị bằng 0 tức là không đồng bộ lịch này hay
+lưu giữ các sự kiện của nó lên thiết bị. Giá trị bằng 1 tức là đồng bộ các sự kiện cho lịch này
+và lưu trữ các sự kiện của nó lên thiết bị.</td>
+ </tr>
+</table>
+
+<h3 id="query">Truy vấn một lịch</h3>
+
+<p>Sau đây là một ví dụ về cách nhận được lịch do một người dùng
+cụ thể sở hữu. Để đơn giản, trong ví dụ này, thao tác truy vấn được thể hiện trong
+ luồng giao diện người dùng ("luồng chính"). Trong thực hành, nên làm điều này trong một luồng
+không đồng bộ thay vì trên luồng chính. Để bàn thêm, hãy xem phần
+<a href="{@docRoot}guide/components/loaders.html">Trình tải</a>. Nếu bạn đang không chỉ
+đọc dữ liệu mà còn sửa đổi nó, hãy xem {@link android.content.AsyncQueryHandler}.
+</p>
+
+
+<pre>
+// Projection array. Creating indices for this array instead of doing
+// dynamic lookups improves performance.
+public static final String[] EVENT_PROJECTION = new String[] {
+ Calendars._ID, // 0
+ Calendars.ACCOUNT_NAME, // 1
+ Calendars.CALENDAR_DISPLAY_NAME, // 2
+ Calendars.OWNER_ACCOUNT // 3
+};
+
+// The indices for the projection array above.
+private static final int PROJECTION_ID_INDEX = 0;
+private static final int PROJECTION_ACCOUNT_NAME_INDEX = 1;
+private static final int PROJECTION_DISPLAY_NAME_INDEX = 2;
+private static final int PROJECTION_OWNER_ACCOUNT_INDEX = 3;</pre>
+
+
+<div class="sidebox-wrapper"> <div class="sidebox"> <h3>Tại sao bạn phải nêu
+ACCOUNT_TYPE?</h3> <p>Nếu bạn truy vấn trên một {@link
+android.provider.CalendarContract.Calendars#ACCOUNT_NAME
+Calendars.ACCOUNT_NAME}, bạn cũng phải nêu
+{@link android.provider.CalendarContract.Calendars#ACCOUNT_TYPE Calendars.ACCOUNT_TYPE}
+trong lựa chọn. Đó là vì một tài khoản đã cho chỉ
+được coi là duy nhất nếu có cả <code>ACCOUNT_NAME</code> và
+<code>ACCOUNT_TYPE</code> của nó. <code>ACCOUNT_TYPE</code> là xâu tương ứng với
+trình xác thực tài khoản mà đã được sử dụng khi tài khoản đó được đăng ký với
+{@link android.accounts.AccountManager}. Cũng có một loại tài khoản đặc biệt gọi là {@link
+android.provider.CalendarContract#ACCOUNT_TYPE_LOCAL} dành cho các lịch
+không liên kết với một tài khoản thiết bị. Tài khoản {@link
+android.provider.CalendarContract#ACCOUNT_TYPE_LOCAL} không được
+đồng bộ.</p> </div> </div>
+
+
+<p> Trong phần tiếp theo của ví dụ, bạn sẽ xây dựng truy vấn của mình. Lựa chọn
+này sẽ quy định các tiêu chí cho truy vấn. Trong ví dụ này, truy vấn đang tìm
+các lịch có <code>ACCOUNT_NAME</code>
+"sampleuser@google.com", <code>ACCOUNT_TYPE</code>
+"com.google", và <code>OWNER_ACCOUNT</code>
+"sampleuser@google.com". Nếu bạn muốn xem tất cả lịch mà một người dùng
+đã xem, không chỉ các lịch mà người dùng sở hữu, hãy bỏ qua <code>OWNER_ACCOUNT</code>.
+Truy vấn sẽ trả về đối tượng {@link android.database.Cursor}
+mà bạn có thể sử dụng để xem xét tập kết quả được trả về bởi truy vấn
+cơ sở dữ liệu. Để bàn thêm về việc sử dụng các truy vấn trong trình cung cấp nội dung,
+hãy xem phần <a href="{@docRoot}guide/topics/providers/content-providers.html">Trình cung cấp Nội dung</a>.</p>
+
+
+<pre>// Run query
+Cursor cur = null;
+ContentResolver cr = getContentResolver();
+Uri uri = Calendars.CONTENT_URI;
+String selection = "((" + Calendars.ACCOUNT_NAME + " = ?) AND ("
+ + Calendars.ACCOUNT_TYPE + " = ?) AND ("
+ + Calendars.OWNER_ACCOUNT + " = ?))";
+String[] selectionArgs = new String[] {"sampleuser@gmail.com", "com.google",
+ "sampleuser@gmail.com"};
+// Submit the query and get a Cursor object back.
+cur = cr.query(uri, EVENT_PROJECTION, selection, selectionArgs, null);</pre>
+
+<p>Phần tiếp theo sử dụng con chạy để duyệt qua tập kết quả. Nó sử dụng
+các hằng số được thiết lập ngay từ đầu ví dụ để trả về các giá trị
+cho mỗi trường.</p>
+
+<pre>// Use the cursor to step through the returned records
+while (cur.moveToNext()) {
+ long calID = 0;
+ String displayName = null;
+ String accountName = null;
+ String ownerName = null;
+
+ // Get the field values
+ calID = cur.getLong(PROJECTION_ID_INDEX);
+ displayName = cur.getString(PROJECTION_DISPLAY_NAME_INDEX);
+ accountName = cur.getString(PROJECTION_ACCOUNT_NAME_INDEX);
+ ownerName = cur.getString(PROJECTION_OWNER_ACCOUNT_INDEX);
+
+ // Do something with the values...
+
+ ...
+}
+</pre>
+
+<h3 id="modify-calendar">Sửa đổi một lịch</h3>
+
+<p>Để thực hiện cập nhật một lịch, bạn có thể cung cấp {@link
+android.provider.BaseColumns#_ID} của lịch hoặc dưới dạng ID được nối vào cho
+Uri
+
+({@link android.content.ContentUris#withAppendedId(android.net.Uri,long) withAppendedId()})
+hoặc dưới dạng mục chọn đầu tiên. Lựa chọn
+nên bắt đầu bằng <code>&quot;_id=?&quot;</code>, và
+<code>selectionArg</code> đầu tiên sẽ là {@link
+android.provider.BaseColumns#_ID} của lịch.
+Bạn cũng có thể thực hiện cập nhật bằng cách mã hóa ID trong URI. Ví dụ này thay đổi tên hiển thị
+của một lịch bằng cách sử dụng phương pháp
+({@link android.content.ContentUris#withAppendedId(android.net.Uri,long) withAppendedId()})
+:</p>
+
+<pre>private static final String DEBUG_TAG = "MyActivity";
+...
+long calID = 2;
+ContentValues values = new ContentValues();
+// The new display name for the calendar
+values.put(Calendars.CALENDAR_DISPLAY_NAME, &quot;Trevor's Calendar&quot;);
+Uri updateUri = ContentUris.withAppendedId(Calendars.CONTENT_URI, calID);
+int rows = getContentResolver().update(updateUri, values, null, null);
+Log.i(DEBUG_TAG, &quot;Rows updated: &quot; + rows);</pre>
+
+<h3 id="insert-calendar">Chèn một lịch</h2>
+
+<p>Lịch được thiết kế để được quản lý chủ yếu bởi một trình điều hợp đồng bộ, vì vậy bạn chỉ nên
+chèn các lịch mới như một trình điều hợp đồng bộ. Phần lớn thì các ứng dụng
+chỉ có thể thực hiện những thay đổi bề mặt về lịch chẳng hạn như thay đổi tên hiển thị. Nếu
+một ứng dụng cần tạo một lịch cục bộ, nó có thể làm điều này bằng cách thực hiện
+chèn lịch dưới dạng một trình điều hợp đồng bộ, sử dụng {@link
+android.provider.CalendarContract.SyncColumns#ACCOUNT_TYPE} của {@link
+android.provider.CalendarContract#ACCOUNT_TYPE_LOCAL}.
+{@link android.provider.CalendarContract#ACCOUNT_TYPE_LOCAL}
+là một loại tài khoản đặc biệt dành cho các lịch không
+liên kết với một tài khoản thiết bị. Các lịch loại này không được đồng bộ với một máy chủ. Để
+bàn về trình điều hợp đồng bộ, hãy xem phần <a href="#sync-adapter">Trình điều hợp Đồng bộ</a>.</p>
+
+<h2 id="events">Bảng Sự kiện</h2>
+
+<p>Bảng {@link android.provider.CalendarContract.Events} chứa thông tin chi tiết
+cho các sự kiện riêng lẻ. Để thêm, cập nhật hoặc xóa sự kiện, ứng dụng phải
+bao gồm quyền {@link android.Manifest.permission#WRITE_CALENDAR} trong
+<a href="#manifest">tệp bản kê khai</a> của mình.</p>
+
+<p>Các cột Sự kiện sau có thể ghi được bởi cả ứng dụng và trình điều hợp
+đồng bộ. Để xem danh sách đầy đủ về các trường được hỗ trợ, hãy xem tài liệu tham khảo {@link
+android.provider.CalendarContract.Events}.</p>
+
+<table>
+ <tr>
+ <th>Hằng số</th>
+ <th>Mô tả</th>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#CALENDAR_ID}</td>
+ <td>{@link android.provider.BaseColumns#_ID} của lịch mà chứa sự kiện.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#ORGANIZER}</td>
+ <td>E-mail của người tổ chức (người chủ) của sự kiện.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#TITLE}</td>
+ <td>Tiêu đề của sự kiện.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#EVENT_LOCATION}</td>
+ <td>Nơi sự kiện diễn ra. </td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#DESCRIPTION}</td>
+ <td>Mô tả sự kiện.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#DTSTART}</td>
+ <td>Thời gian sự kiện bắt đầu tính bằng mili giây UTC trôi qua kể từ giờ epoch. </td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#DTEND}</td>
+ <td>Thời gian sự kiện kết thúc tính bằng mili giây UTC trôi qua kể từ giờ epoch. </td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#EVENT_TIMEZONE}</td>
+ <td>Múi giờ của sự kiện.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#EVENT_END_TIMEZONE}</td>
+ <td>Múi giờ của thời điểm kết thúc sự kiện.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#DURATION}</td>
+
+ <td>Thời lượng của sự kiện theo định dạng <a href="http://tools.ietf.org/html/rfc5545#section-3.8.2.5">RFC5545</a>.
+Ví dụ, giá trị bằng <code>&quot;PT1H&quot;</code> cho biết sự kiện sẽ kéo dài
+một giờ và giá trị bằng <code>&quot;P2W&quot;</code> cho biết
+thời lượng là 2 tuần. </td>
+
+
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#ALL_DAY}</td>
+
+ <td>Giá trị bằng 1 cho biết sự kiện này chiếm cả ngày, được xác định bởi
+múi giờ tại địa phương. Giá trị bằng 0 cho biết đó là một sự kiện thường xuyên mà có thể bắt đầu
+và kết thúc vào bất cứ lúc nào trong một ngày.</td>
+
+
+ </tr>
+
+
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#RRULE}</td>
+
+ <td>Quy tắc lặp lại đối với định dạng sự kiện. Ví
+dụ, <code>&quot;FREQ=WEEKLY;COUNT=10;WKST=SU&quot;</code>. Bạn có thể tìm thêm
+nhiều ví dụ hơn <a href="http://tools.ietf.org/html/rfc5545#section-3.8.5.3">ở đây</a>.</td>
+
+ </tr>
+
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#RDATE}</td>
+ <td>Ngày lặp lại đối với sự kiện.
+ Bạn thường sử dụng {@link android.provider.CalendarContract.EventsColumns#RDATE}
+ cùng với {@link android.provider.CalendarContract.EventsColumns#RRULE}
+ để định nghĩa một tập tổng hợp
+các trường hợp xảy ra lặp lại. Để bàn thêm, hãy xem phần <a href="http://tools.ietf.org/html/rfc5545#section-3.8.5.2">RFC5545 spec</a>.</td>
+</tr>
+
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#AVAILABILITY}</td>
+
+ <td>Xem sự kiện này được tính là thời gian bận hay là thời gian rảnh có thể được
+xếp lại lịch. </td>
+
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#GUESTS_CAN_MODIFY}</td>
+ <td>Khách có thể sửa đổi sự kiện được hay không. </td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#GUESTS_CAN_INVITE_OTHERS}</td>
+ <td>Khách có thể mời khách khác được hay không. </td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#GUESTS_CAN_SEE_GUESTS}</td>
+ <td>Khách có thể xem danh sách người dự được hay không.</td>
+ </tr>
+</table>
+
+<h3 id="add-event">Thêm Sự kiện</h3>
+
+<p>Khi ứng dụng của bạn chèn một sự kiện mới, chúng tôi khuyến cáo bạn nên sử dụng một Ý định
+{@link android.content.Intent#ACTION_INSERT INSERT}, như được mô tả trong <a href="#intent-insert">Sử dụng ý định để chèn một sự kiện</a>. Tuy nhiên, nếu
+cần, bạn có thể chèn sự kiện trực tiếp. Phần này mô tả cách làm điều
+này.</p>
+
+
+<p>Sau đây là các quy tắc để chèn một sự kiện mới: </p>
+<ul>
+
+ <li>Bạn phải đưa vào {@link
+android.provider.CalendarContract.EventsColumns#CALENDAR_ID} và {@link
+android.provider.CalendarContract.EventsColumns#DTSTART}.</li>
+
+<li>Bạn phải đưa vào một {@link
+android.provider.CalendarContract.EventsColumns#EVENT_TIMEZONE}. Để nhận một danh sách
+các ID múi giờ được cài đặt của hệ thống, hãy sử dụng {@link
+java.util.TimeZone#getAvailableIDs()}. Lưu ý rằng quy tắc này không áp dụng nếu
+bạn đang chèn một sự kiện thông qua Ý định {@link
+android.content.Intent#ACTION_INSERT INSERT} như được mô tả trong <a href="#intent-insert">Sử dụng ý định để chèn một sự kiện</a>&mdash;trong kịch bản
+đó, một múi giờ mặc định sẽ được cung cấp.</li>
+
+ <li>Đối với các sự kiện không định kỳ, bạn phải đưa vào {@link
+android.provider.CalendarContract.EventsColumns#DTEND}. </li>
+
+
+ <li>Đối với các sự kiện định kỳ, bạn phải đưa vào một {@link
+android.provider.CalendarContract.EventsColumns#DURATION} bên cạnh {@link
+android.provider.CalendarContract.EventsColumns#RRULE} hay {@link
+android.provider.CalendarContract.EventsColumns#RDATE}. Lưu ý rằng quy tắc này không áp dụng nếu
+bạn đang chèn một sự kiện thông qua Ý định {@link
+android.content.Intent#ACTION_INSERT INSERT} như được mô tả trong <a href="#intent-insert">Sử dụng ý định để chèn một sự kiện</a>&mdash;trong kịch bản
+đó, bạn có thể sử dụng một {@link
+android.provider.CalendarContract.EventsColumns#RRULE} cùng với {@link android.provider.CalendarContract.EventsColumns#DTSTART} và {@link android.provider.CalendarContract.EventsColumns#DTEND}, và ứng dụng Lịch
+sẽ tự động chuyển nó thành một thời lượng.</li>
+
+</ul>
+
+<p>Sau đây là một ví dụ về cách chèn một sự kiện. Ví dụ này đang được thực hiện trong luồng
+UI để cho đơn giản. Trong thực hành, chèn và cập nhật nên được thực hiện trong một
+luồng không đồng bộ để di chuyển hành động vào một luồng chạy ngầm. Để biết thêm
+thông tin, hãy xem phần {@link android.content.AsyncQueryHandler}.</p>
+
+
+<pre>
+long calID = 3;
+long startMillis = 0;
+long endMillis = 0;
+Calendar beginTime = Calendar.getInstance();
+beginTime.set(2012, 9, 14, 7, 30);
+startMillis = beginTime.getTimeInMillis();
+Calendar endTime = Calendar.getInstance();
+endTime.set(2012, 9, 14, 8, 45);
+endMillis = endTime.getTimeInMillis();
+...
+
+ContentResolver cr = getContentResolver();
+ContentValues values = new ContentValues();
+values.put(Events.DTSTART, startMillis);
+values.put(Events.DTEND, endMillis);
+values.put(Events.TITLE, &quot;Jazzercise&quot;);
+values.put(Events.DESCRIPTION, &quot;Group workout&quot;);
+values.put(Events.CALENDAR_ID, calID);
+values.put(Events.EVENT_TIMEZONE, "America/Los_Angeles");
+Uri uri = cr.insert(Events.CONTENT_URI, values);
+
+// get the event ID that is the last element in the Uri
+long eventID = Long.parseLong(uri.getLastPathSegment());
+//
+// ... do something with event ID
+//
+//</pre>
+
+<p class="note"><strong>Lưu ý:</strong> Xem cách mà ví dụ này bắt được ID
+sự kiện sau khi sự kiện được tạo. Đây là cách dễ nhất để nhận được một ID sự kiện. Bạn thường
+cần ID sự kiện để thực hiện các thao tác lịch khác&mdash;ví dụ: để thêm
+người dự hoặc nhắc nhở vào một sự kiện.</p>
+
+
+<h3 id="update-event">Cập nhật Sự kiện</h3>
+
+<p>Khi ứng dụng của bạn muốn cho phép người dùng chỉnh sửa một sự kiện, chúng tôi khuyến cáo
+bạn nên sử dụng một Ý định {@link android.content.Intent#ACTION_EDIT EDIT} như được mô tả
+trong <a href="#intent-edit">Sử dụng ý định để chỉnh sửa một sự kiện</a>.
+Tuy nhiên, nếu cần, bạn có thể chỉnh sửa sự kiện trực tiếp. Để thực hiện cập nhật
+một Sự kiện, bạn có thể cung cấp <code>_ID</code> của sự kiện
+hoặc dưới dạng ID được nối vào cho Uri ({@link
+android.content.ContentUris#withAppendedId(android.net.Uri,long) withAppendedId()})
+hoặc dưới dạng mục chọn đầu tiên.
+Lựa chọn nên bắt đầu bằng <code>&quot;_id=?&quot;</code>, và
+<code>selectionArg</code> đầu tiên nên là <code>_ID</code> của sự kiện. Bạn cũng có thể
+thực hiện cập nhật bằng cách sử dụng một lựa chọn không có ID. Sau đây là một ví dụ về cách cập nhật một
+sự kiện. Nó thay đổi tiêu đề của sự kiện bằng cách sử dụng phương pháp
+{@link android.content.ContentUris#withAppendedId(android.net.Uri,long) withAppendedId()}
+:</p>
+
+
+<pre>private static final String DEBUG_TAG = "MyActivity";
+...
+long eventID = 188;
+...
+ContentResolver cr = getContentResolver();
+ContentValues values = new ContentValues();
+Uri updateUri = null;
+// The new title for the event
+values.put(Events.TITLE, &quot;Kickboxing&quot;);
+updateUri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID);
+int rows = getContentResolver().update(updateUri, values, null, null);
+Log.i(DEBUG_TAG, &quot;Rows updated: &quot; + rows); </pre>
+
+<h3 id="delete-event">Xóa Sự kiện</h3>
+
+<p>Bạn có thể xóa một sự kiện hoặc theo {@link
+android.provider.BaseColumns#_ID} của nó như một ID được nối trên URI, hoặc bằng cách sử dụng
+lựa chọn tiêu chuẩn. Nếu sử dụng một ID được nối, bạn không thể lựa chọn đồng thời.
+Có hai kiểu xóa: như một ứng dụng và như một trình điều hợp đồng bộ. Xóa
+như một ứng dụng sẽ đặt cột <em>đã xóa</em> thành 1. Cờ này sẽ báo cho
+trình điều hợp đồng bộ rằng hàng đó đã được xóa và rằng việc xóa này nên
+được truyền tới máy chủ. Xóa trình điều hợp đồng bộ sẽ gỡ bỏ sự kiện khỏi
+cơ sở dữ liệu cùng với tất cả dữ liệu được liên kết của nó. Sau đây là một ví dụ về ứng dụng
+xóa một sự kiện thông qua {@link android.provider.BaseColumns#_ID} của nó:</p>
+
+
+<pre>private static final String DEBUG_TAG = "MyActivity";
+...
+long eventID = 201;
+...
+ContentResolver cr = getContentResolver();
+ContentValues values = new ContentValues();
+Uri deleteUri = null;
+deleteUri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID);
+int rows = getContentResolver().delete(deleteUri, null, null);
+Log.i(DEBUG_TAG, &quot;Rows deleted: &quot; + rows);
+</pre>
+
+<h2 id="attendees">Bảng Người dự</h2>
+
+<p>Mỗi hàng của bảng {@link android.provider.CalendarContract.Attendees} đại diện
+cho một người dự hoặc khách duy nhất của một sự kiện. Gọi
+{@link android.provider.CalendarContract.Reminders#query(android.content.ContentResolver, long, java.lang.String[]) query()}
+sẽ trả về một danh sách người dự cho sự kiện
+với {@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID} đã cho.
+{@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID} này
+phải khớp với {@link
+android.provider.BaseColumns#_ID} của một sự kiện cụ thể.</p>
+
+<p>Bảng sau liệt kê các trường
+có thể ghi được. Khi chèn một người dự mới, bạn phải điền tất cả
+ngoại trừ <code>ATTENDEE_NAME</code>.
+</p>
+
+
+<table>
+ <tr>
+ <th>Hằng số</th>
+ <th>Mô tả</th>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID}</td>
+ <td>ID của sự kiện.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_NAME}</td>
+ <td>Tên của người dự.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_EMAIL}</td>
+ <td>Địa chỉ e-mail của người dự.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_RELATIONSHIP}</td>
+ <td><p>Mối quan hệ của người dự với sự kiện. Một trong:</p>
+ <ul>
+ <li>{@link android.provider.CalendarContract.AttendeesColumns#RELATIONSHIP_ATTENDEE}</li>
+ <li>{@link android.provider.CalendarContract.AttendeesColumns#RELATIONSHIP_NONE}</li>
+ <li>{@link android.provider.CalendarContract.AttendeesColumns#RELATIONSHIP_ORGANIZER}</li>
+ <li>{@link android.provider.CalendarContract.AttendeesColumns#RELATIONSHIP_PERFORMER}</li>
+ <li>{@link android.provider.CalendarContract.AttendeesColumns#RELATIONSHIP_SPEAKER}</li>
+ </ul>
+ </td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_TYPE}</td>
+ <td><p>Loại người dự. Một trong: </p>
+ <ul>
+ <li>{@link android.provider.CalendarContract.AttendeesColumns#TYPE_REQUIRED}</li>
+ <li>{@link android.provider.CalendarContract.AttendeesColumns#TYPE_OPTIONAL}</li>
+ </ul></td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS}</td>
+ <td><p>Trạng thái tham dự của người dự. Một trong:</p>
+ <ul>
+ <li>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS_ACCEPTED}</li>
+ <li>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS_DECLINED}</li>
+ <li>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS_INVITED}</li>
+ <li>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS_NONE}</li>
+ <li>{@link android.provider.CalendarContract.AttendeesColumns#ATTENDEE_STATUS_TENTATIVE}</li>
+ </ul></td>
+ </tr>
+</table>
+
+<h3 id="add-attendees">Thêm Người dự</h3>
+
+<p>Sau đây là một ví dụ về cách thêm một người dự vào một sự kiện. Lưu ý rằng
+{@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID}
+là bắt buộc:</p>
+
+<pre>
+long eventID = 202;
+...
+ContentResolver cr = getContentResolver();
+ContentValues values = new ContentValues();
+values.put(Attendees.ATTENDEE_NAME, &quot;Trevor&quot;);
+values.put(Attendees.ATTENDEE_EMAIL, &quot;trevor@example.com&quot;);
+values.put(Attendees.ATTENDEE_RELATIONSHIP, Attendees.RELATIONSHIP_ATTENDEE);
+values.put(Attendees.ATTENDEE_TYPE, Attendees.TYPE_OPTIONAL);
+values.put(Attendees.ATTENDEE_STATUS, Attendees.ATTENDEE_STATUS_INVITED);
+values.put(Attendees.EVENT_ID, eventID);
+Uri uri = cr.insert(Attendees.CONTENT_URI, values);
+</pre>
+
+<h2 id="reminders">Bảng Nhắc nhở</h2>
+
+<p>Mỗi hàng của bảng {@link android.provider.CalendarContract.Reminders} đại diện
+cho một nhắc nhở của một sự kiện. Gọi
+{@link android.provider.CalendarContract.Reminders#query(android.content.ContentResolver, long, java.lang.String[]) query()} sẽ trả về một danh sách nhắc nhở cho
+sự kiện với
+{@link android.provider.CalendarContract.AttendeesColumns#EVENT_ID} đã cho.</p>
+
+
+<p>Bảng sau liệt kê các trường ghi được đối với nhắc nhở. Tất cả đều phải được
+đưa vào khi chèn một nhắc nhở mới. Lưu ý rằng các trình điều hợp đồng bộ quy định
+các loại nhắc nhở chúng hỗ trợ trong bảng {@link
+android.provider.CalendarContract.Calendars}. Xem
+{@link android.provider.CalendarContract.CalendarColumns#ALLOWED_REMINDERS}
+để biết chi tiết.</p>
+
+
+<table>
+ <tr>
+ <th>Hằng số</th>
+ <th>Mô tả</th>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.RemindersColumns#EVENT_ID}</td>
+ <td>ID của sự kiện.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.RemindersColumns#MINUTES}</td>
+ <td>Số phút trước khi diễn ra sự kiện mà nhắc nhở cần báo.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.RemindersColumns#METHOD}</td>
+ <td><p>Phương pháp báo thức, như được đặt trên máy chủ. Một trong:</p>
+ <ul>
+ <li>{@link android.provider.CalendarContract.RemindersColumns#METHOD_ALERT}</li>
+ <li>{@link android.provider.CalendarContract.RemindersColumns#METHOD_DEFAULT}</li>
+ <li>{@link android.provider.CalendarContract.RemindersColumns#METHOD_EMAIL}</li>
+ <li>{@link android.provider.CalendarContract.RemindersColumns#METHOD_SMS}</li>
+ </ul></td>
+ </tr>
+</table>
+
+<h3 id="add-reminders">Thêm Nhắc nhở</h3>
+
+<p>Ví dụ này thêm nhắc nhở vào một sự kiện. Nhắc nhở sẽ báo 15
+phút trước khi xảy ra sự kiện.</p>
+<pre>
+long eventID = 221;
+...
+ContentResolver cr = getContentResolver();
+ContentValues values = new ContentValues();
+values.put(Reminders.MINUTES, 15);
+values.put(Reminders.EVENT_ID, eventID);
+values.put(Reminders.METHOD, Reminders.METHOD_ALERT);
+Uri uri = cr.insert(Reminders.CONTENT_URI, values);</pre>
+
+<h2 id="instances">Bảng Thực thể</h2>
+
+<p>Bảng
+{@link android.provider.CalendarContract.Instances} chứa
+thời gian bắt đầu và thời gian kết thúc của các lần xảy ra một sự kiện. Mỗi hàng trong bảng này
+đại diện cho một lần xảy ra sự kiện. Bảng thực thể không ghi được và chỉ
+đưa ra một cách để truy vấn các lần xảy ra sự kiện. </p>
+
+<p>Bảng sau liệt kê một số trường mà bạn có thể truy vấn đối với một thực thể. Lưu ý
+rằng múi giờ được định nghĩa bởi
+{@link android.provider.CalendarContract.CalendarCache#KEY_TIMEZONE_TYPE}
+và
+{@link android.provider.CalendarContract.CalendarCache#KEY_TIMEZONE_INSTANCES}.</p>
+
+
+<table>
+ <tr>
+ <th>Hằng số</th>
+ <th>Mô tả</th>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.Instances#BEGIN}</td>
+ <td>Thời gian bắt đầu của thực thể, tính bằng mili giây UTC.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.Instances#END}</td>
+ <td>Thời gian kết thúc của thực thể, tính bằng mili giây UTC.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.Instances#END_DAY}</td>
+
+ <td>Ngày kết thúc theo lịch Julian của thực thể theo múi giờ
+của Lịch.
+
+</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.Instances#END_MINUTE}</td>
+
+ <td>Phút kết thúc của thực thể được xác định từ nửa đêm theo múi giờ
+của Lịch.</td>
+
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.Instances#EVENT_ID}</td>
+ <td><code>_ID</code> của sự kiện đối với thực thể này.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.Instances#START_DAY}</td>
+ <td>Ngày bắt đầu theo lịch Julian của thực thể theo múi giờ của Lịch.
+ </td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.Instances#START_MINUTE}</td>
+
+ <td>Phút bắt đầu của thực thể được xác định từ nửa đêm theo múi giờ
+của Lịch.
+</td>
+
+ </tr>
+
+</table>
+
+<h3 id="query-instances">Truy vấn bảng Thực thể</h3>
+
+<p>Để truy vấn bảng Thực thể, bạn cần chỉ định một khoảng thời gian cho truy vấn
+trong URI. Trong ví dụ này, {@link android.provider.CalendarContract.Instances}
+có quyền truy cập trường {@link
+android.provider.CalendarContract.EventsColumns#TITLE} thông qua việc
+triển khai giao diện {@link android.provider.CalendarContract.EventsColumns} của nó.
+Nói cách khác, {@link
+android.provider.CalendarContract.EventsColumns#TITLE} được trả về qua một
+chế độ xem cơ sở dữ liệu, chứ không qua việc truy vấn bảng {@link
+android.provider.CalendarContract.Instances} thô.</p>
+
+<pre>
+private static final String DEBUG_TAG = "MyActivity";
+public static final String[] INSTANCE_PROJECTION = new String[] {
+ Instances.EVENT_ID, // 0
+ Instances.BEGIN, // 1
+ Instances.TITLE // 2
+ };
+
+// The indices for the projection array above.
+private static final int PROJECTION_ID_INDEX = 0;
+private static final int PROJECTION_BEGIN_INDEX = 1;
+private static final int PROJECTION_TITLE_INDEX = 2;
+...
+
+// Specify the date range you want to search for recurring
+// event instances
+Calendar beginTime = Calendar.getInstance();
+beginTime.set(2011, 9, 23, 8, 0);
+long startMillis = beginTime.getTimeInMillis();
+Calendar endTime = Calendar.getInstance();
+endTime.set(2011, 10, 24, 8, 0);
+long endMillis = endTime.getTimeInMillis();
+
+Cursor cur = null;
+ContentResolver cr = getContentResolver();
+
+// The ID of the recurring event whose instances you are searching
+// for in the Instances table
+String selection = Instances.EVENT_ID + " = ?";
+String[] selectionArgs = new String[] {"207"};
+
+// Construct the query with the desired date range.
+Uri.Builder builder = Instances.CONTENT_URI.buildUpon();
+ContentUris.appendId(builder, startMillis);
+ContentUris.appendId(builder, endMillis);
+
+// Submit the query
+cur = cr.query(builder.build(),
+ INSTANCE_PROJECTION,
+ selection,
+ selectionArgs,
+ null);
+
+while (cur.moveToNext()) {
+ String title = null;
+ long eventID = 0;
+ long beginVal = 0;
+
+ // Get the field values
+ eventID = cur.getLong(PROJECTION_ID_INDEX);
+ beginVal = cur.getLong(PROJECTION_BEGIN_INDEX);
+ title = cur.getString(PROJECTION_TITLE_INDEX);
+
+ // Do something with the values.
+ Log.i(DEBUG_TAG, "Event: " + title);
+ Calendar calendar = Calendar.getInstance();
+ calendar.setTimeInMillis(beginVal);
+ DateFormat formatter = new SimpleDateFormat("MM/dd/yyyy");
+ Log.i(DEBUG_TAG, "Date: " + formatter.format(calendar.getTime()));
+ }
+ }</pre>
+
+<h2 id="intents">Ý định Lịch</h2>
+<p>Ứng dụng của bạn không cần <a href="#manifest">quyền</a> để ghi và đọc dữ liệu lịch. Thay vào đó, nó có thể sử dụng những ý định được cung cấp bởi ứng dụng Lịch của Android để chuyển giao các thao tác đọc và ghi cho ứng dụng đó. Bảng sau đây liệt kê các ý định được Trình cung cấp Lịch hỗ trợ:</p>
+<table>
+ <tr>
+ <th>Hành động</th>
+ <th>URI</th>
+
+ <th>Mô tả</th>
+ <th>Phụ thêm</th>
+ </tr>
+ <tr>
+ <td><br>
+ {@link android.content.Intent#ACTION_VIEW VIEW} <br></td>
+ <td><p><code>content://com.android.calendar/time/&lt;ms_since_epoch&gt;</code></p>
+ Bạn cũng có thể tham khảo tới URI bằng
+{@link android.provider.CalendarContract#CONTENT_URI CalendarContract.CONTENT_URI}.
+Để xem một ví dụ về cách sử dụng ý định này, hãy xem <a href="{@docRoot}guide/topics/providers/calendar-provider.html#intent-view">Sử dụng ý định để xem dữ liệu lịch</a>.
+
+ </td>
+ <td>Mở lịch đến thời gian được chỉ định bởi <code>&lt;ms_since_epoch&gt;</code>.</td>
+ <td>Không có.</td>
+ </tr>
+ <tr>
+ <td><p>{@link android.content.Intent#ACTION_VIEW VIEW} </p>
+
+ </td>
+ <td><p><code>content://com.android.calendar/events/&lt;event_id&gt;</code></p>
+
+ Bạn cũng có thể tham khảo tới URI bằng
+{@link android.provider.CalendarContract.Events#CONTENT_URI Events.CONTENT_URI}.
+Để xem một ví dụ về cách sử dụng ý định này, hãy xem <a href="{@docRoot}guide/topics/providers/calendar-provider.html#intent-view">Sử dụng ý định để xem dữ liệu lịch</a>.
+
+ </td>
+ <td>Xem sự kiện được chỉ định bởi <code>&lt;event_id&gt;</code>.</td>
+
+ <td>{@link android.provider.CalendarContract#EXTRA_EVENT_BEGIN_TIME CalendarContract.EXTRA_EVENT_BEGIN_TIME}<br>
+ <br>
+ <br>
+ {@link android.provider.CalendarContract#EXTRA_EVENT_END_TIME CalendarContract.EXTRA_EVENT_END_TIME}</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.content.Intent#ACTION_EDIT EDIT} </td>
+ <td><p><code>content://com.android.calendar/events/&lt;event_id&gt;</code></p>
+
+ Bạn cũng có thể tham khảo tới URI bằng
+{@link android.provider.CalendarContract.Events#CONTENT_URI Events.CONTENT_URI}.
+Để xem một ví dụ về cách sử dụng ý định này, hãy xem <a href="{@docRoot}guide/topics/providers/calendar-provider.html#intent-edit">Sử dụng ý định để chỉnh sửa một sự kiện</a>.
+
+
+ </td>
+ <td>Chỉnh sửa sự kiện được chỉ định bởi <code>&lt;event_id&gt;</code>.</td>
+
+ <td>{@link android.provider.CalendarContract#EXTRA_EVENT_BEGIN_TIME CalendarContract.EXTRA_EVENT_BEGIN_TIME}<br>
+ <br>
+ <br>
+ {@link android.provider.CalendarContract#EXTRA_EVENT_END_TIME CalendarContract.EXTRA_EVENT_END_TIME}</td>
+ </tr>
+
+ <tr>
+ <td>{@link android.content.Intent#ACTION_EDIT EDIT} <br>
+ <br>
+ {@link android.content.Intent#ACTION_INSERT INSERT} </td>
+ <td><p><code>content://com.android.calendar/events</code></p>
+
+ Bạn cũng có thể tham khảo tới URI bằng
+{@link android.provider.CalendarContract.Events#CONTENT_URI Events.CONTENT_URI}.
+Để xem một ví dụ về cách sử dụng ý định này, hãy xem <a href="{@docRoot}guide/topics/providers/calendar-provider.html#intent-insert">Sử dụng ý định để chèn một sự kiện</a>.
+
+ </td>
+
+ <td>Tạo một sự kiện.</td>
+ <td>Bất kỳ phụ thêm nào được liệt kê trong bảng bên dưới.</td>
+ </tr>
+</table>
+
+<p>Bảng sau đây liệt kê các phụ thêm ý định được Trình cung cấp Lịch hỗ trợ:
+</p>
+<table>
+ <tr>
+ <th>Phụ thêm Ý định</th>
+ <th>Mô tả</th>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#TITLE Events.TITLE}</td>
+ <td>Tên cho sự kiện.</td>
+ </tr>
+ <tr>
+
+ <td>{@link android.provider.CalendarContract#EXTRA_EVENT_BEGIN_TIME
+CalendarContract.EXTRA_EVENT_BEGIN_TIME}</td>
+ <td>Thời gian bắt đầu sự kiện tính bằng mili giây trôi qua kể từ giờ epoch.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract#EXTRA_EVENT_END_TIME
+CalendarContract.EXTRA_EVENT_END_TIME}</td>
+
+ <td>Thời gian kết thúc sự kiện tính bằng mili giây trôi qua kể từ giờ epoch.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract#EXTRA_EVENT_ALL_DAY
+CalendarContract.EXTRA_EVENT_ALL_DAY}</td>
+
+ <td>Một boolean cho biết đó là một sự kiện cả ngày. Giá trị có thể bằng
+<code>true</code> hoặc <code>false</code>.</td> </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#EVENT_LOCATION
+Events.EVENT_LOCATION}</td>
+
+ <td>Địa điểm của sự kiện.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#DESCRIPTION
+Events.DESCRIPTION}</td>
+
+ <td>Mô tả sự kiện.</td>
+ </tr>
+ <tr>
+ <td>
+ {@link android.content.Intent#EXTRA_EMAIL Intent.EXTRA_EMAIL}</td>
+ <td>Địa chỉ e-mail của những người cần mời dưới dạng một danh sách phân cách bởi dấu phẩy.</td>
+ </tr>
+ <tr>
+ <td>
+ {@link android.provider.CalendarContract.EventsColumns#RRULE Events.RRULE}</td>
+ <td>Quy tắc lặp lại đối với sự kiện.</td>
+ </tr>
+ <tr>
+ <td>
+ {@link android.provider.CalendarContract.EventsColumns#ACCESS_LEVEL
+Events.ACCESS_LEVEL}</td>
+
+ <td>Sự kiện là riêng tư hay công khai.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.CalendarContract.EventsColumns#AVAILABILITY
+Events.AVAILABILITY}</td>
+
+ <td>Xem sự kiện này tính là thời gian bận hay là thời gian rảnh có thể được xếp lại lịch.</td>
+
+</table>
+<p>Các phần sau mô tả cách sử dụng những ý định này.</p>
+
+
+<h3 id="intent-insert">Sử dụng ý định để chèn một sự kiện</h3>
+
+<p>Sử dụng Ý định {@link android.content.Intent#ACTION_INSERT INSERT} cho phép
+ứng dụng của bạn chuyển giao tác vụ chèn sự kiện cho bản thân Lịch.
+Bằng cách này, ứng dụng của bạn thậm chí không cần phải có quyền {@link
+android.Manifest.permission#WRITE_CALENDAR} được bao gồm trong <a href="#manifest">tệp bản kê khai</a> của mình.</p>
+
+
+<p>Khi người dùng chạy một ứng dụng mà sử dụng cách này, ứng dụng sẽ gửi
+chúng tới Lịch để hoàn thành việc thêm một sự kiện. Ý định {@link
+android.content.Intent#ACTION_INSERT INSERT} sử dụng các trường phụ thêm để
+điền trước vào một mẫu bằng các chi tiết của sự kiện trong Lịch. Khi đó, người dùng có thể
+hủy bỏ sự kiện, chỉnh sửa mẫu nếu cần, hoặc lưu sự kiện vào lịch
+của mình.</p>
+
+
+
+<p>Sau đây là một đoạn mã HTML lập biểu một sự kiện vào ngày 19/1/2012, diễn ra
+từ 7:30 sáng đến 8:30 sáng. Lưu ý điều sau đây về đoạn mã HTML này:</p>
+
+<ul>
+ <li>Nó quy định {@link android.provider.CalendarContract.Events#CONTENT_URI Events.CONTENT_URI}
+ là Uri.</li>
+
+ <li>Nó sử dụng các trường phụ {@link
+android.provider.CalendarContract#EXTRA_EVENT_BEGIN_TIME
+CalendarContract.EXTRA_EVENT_BEGIN_TIME} và {@link
+android.provider.CalendarContract#EXTRA_EVENT_END_TIME
+CalendarContract.EXTRA_EVENT_END_TIME} để điền trước thời gian của sự kiện
+vào mẫu. Các giá trị đối với những thời gian này phải tính bằng mili giây UTC
+trôi qua kể từ giờ epoch.</li>
+
+ <li>Nó sử dụng trường phụ {@link android.content.Intent#EXTRA_EMAIL Intent.EXTRA_EMAIL}
+để cung cấp một danh sách người được mời phân cách bằng dấu phẩy, được chỉ định theo địa chỉ e-mail.</li>
+
+</ul>
+<pre>
+Calendar beginTime = Calendar.getInstance();
+beginTime.set(2012, 0, 19, 7, 30);
+Calendar endTime = Calendar.getInstance();
+endTime.set(2012, 0, 19, 8, 30);
+Intent intent = new Intent(Intent.ACTION_INSERT)
+ .setData(Events.CONTENT_URI)
+ .putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis())
+ .putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis())
+ .putExtra(Events.TITLE, &quot;Yoga&quot;)
+ .putExtra(Events.DESCRIPTION, &quot;Group class&quot;)
+ .putExtra(Events.EVENT_LOCATION, &quot;The gym&quot;)
+ .putExtra(Events.AVAILABILITY, Events.AVAILABILITY_BUSY)
+ .putExtra(Intent.EXTRA_EMAIL, &quot;rowan@example.com,trevor@example.com&quot;);
+startActivity(intent);
+</pre>
+
+<h3 id="intent-edit">Sử dụng ý định để chỉnh sửa một sự kiện</h3>
+
+<p>Bạn có thể cập nhật một sự kiện trực tiếp như được mô tả trong phần <a href="#update-event">Cập nhật sự kiện</a>. Nhưng việc sử dụng Ý định {@link
+android.content.Intent#ACTION_EDIT EDIT} cho phép một ứng dụng
+không có quyền được chuyển giao chỉnh sửa sự kiện cho ứng dụng Lịch.
+Khi người dùng hoàn thành chỉnh sửa sự kiện của mình trong Lịch, họ được trả về ứng dụng
+ban đầu.</p> <p>Sau đây là một ví dụ về ý định đặt một tiêu đề mới
+cho một sự kiện được quy định và cho phép người dùng chỉnh sửa sự kiện trong Lịch.</p>
+
+
+<pre>long eventID = 208;
+Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID);
+Intent intent = new Intent(Intent.ACTION_EDIT)
+ .setData(uri)
+ .putExtra(Events.TITLE, &quot;My New Title&quot;);
+startActivity(intent);</pre>
+
+<h3 id="intent-view">Sử dụng ý định để xem dữ liệu lịch</h3>
+<p>Trình cung cấp Lịch giới thiệu hai cách khác nhau để sử dụng Ý định {@link android.content.Intent#ACTION_VIEW VIEW}:</p>
+<ul>
+ <li>Để mở Lịch tới một ngày cụ thể.</li>
+ <li>Để xem một sự kiện.</li>
+
+</ul>
+<p>Sau đây là một ví dụ cho biết cách mở Lịch tới một ngày cụ thể:</p>
+<pre>// A date-time specified in milliseconds since the epoch.
+long startMillis;
+...
+Uri.Builder builder = CalendarContract.CONTENT_URI.buildUpon();
+builder.appendPath(&quot;time&quot;);
+ContentUris.appendId(builder, startMillis);
+Intent intent = new Intent(Intent.ACTION_VIEW)
+ .setData(builder.build());
+startActivity(intent);</pre>
+
+<p>Sau đây là một ví dụ cho biết cách mở một sự kiện để xem:</p>
+<pre>long eventID = 208;
+...
+Uri uri = ContentUris.withAppendedId(Events.CONTENT_URI, eventID);
+Intent intent = new Intent(Intent.ACTION_VIEW)
+ .setData(uri);
+startActivity(intent);
+</pre>
+
+
+<h2 id="sync-adapter">Trình điều hợp Đồng bộ</h2>
+
+
+<p>Chỉ có vài điểm khác nhau nhỏ giữa cách một ứng dụng và cách một trình điều hợp đồng bộ
+truy cập Trình cung cấp Lịch:</p>
+
+<ul>
+ <li>Trình điều hợp đồng bộ cần chỉ định rằng nó là một trình điều hợp đồng bộ bằng cách đặt {@link android.provider.CalendarContract#CALLER_IS_SYNCADAPTER} thành <code>true</code>.</li>
+
+
+ <li>Trình điều hợp đồng bộ cần cung cấp một {@link
+android.provider.CalendarContract.SyncColumns#ACCOUNT_NAME} và một {@link
+android.provider.CalendarContract.SyncColumns#ACCOUNT_TYPE} làm tham số truy vấn trong URI. </li>
+
+ <li>Trình điều hợp đồng bộ có quyền truy nhập ghi vào nhiều cột hơn ứng dụng hay widget.
+ Ví dụ, một ứng dụng chỉ có thể sửa đổi một vài đặc điểm của một lịch,
+ chẳng hạn như tên lịch, tên hiển thị, thiết đặt hiển thị, và lịch có được
+ đồng bộ hay không. Nếu so sánh, một trình điều hợp đồng bộ có thể truy cập không chỉ những cột đó, mà còn nhiều cột khác,
+ chẳng hạn như màu lịch, múi giờ, mức truy nhập, địa điểm, v.v.
+Tuy nhiên, trình điều hợp đồng bộ bị hạn chế đối với <code>ACCOUNT_NAME</code> và
+<code>ACCOUNT_TYPE</code> mà nó quy định.</li> </ul>
+
+<p>Sau đây là một phương pháp hữu ích hơn mà bạn có thể sử dụng để trả về một URI để dùng với một trình điều hợp đồng bộ:</p>
+<pre> static Uri asSyncAdapter(Uri uri, String account, String accountType) {
+ return uri.buildUpon()
+ .appendQueryParameter(android.provider.CalendarContract.CALLER_IS_SYNCADAPTER,&quot;true&quot;)
+ .appendQueryParameter(Calendars.ACCOUNT_NAME, account)
+ .appendQueryParameter(Calendars.ACCOUNT_TYPE, accountType).build();
+ }
+</pre>
+<p>Để biết việc triển khai mẫu trình điều hợp đồng bộ (không liên quan cụ thể tới Lịch), hãy xem phần
+<a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">SampleSyncAdapter</a>.
diff --git a/docs/html-intl/intl/vi/guide/topics/providers/contacts-provider.jd b/docs/html-intl/intl/vi/guide/topics/providers/contacts-provider.jd
new file mode 100644
index 000000000000..e4f839f261fc
--- /dev/null
+++ b/docs/html-intl/intl/vi/guide/topics/providers/contacts-provider.jd
@@ -0,0 +1,2356 @@
+page.title=Trình cung cấp Danh bạ
+@jd:body
+<div id="qv-wrapper">
+<div id="qv">
+<h2>Xem nhanh</h2>
+<ul>
+ <li>Kho lưu giữ thông tin về con người của Android.</li>
+ <li>
+ Đồng bộ với web.
+ </li>
+ <li>
+ Tích hợp dữ liệu theo luồng xã hội.
+ </li>
+</ul>
+<h2>Trong tài liệu này</h2>
+<ol>
+ <li>
+ <a href="#InformationTypes">Tổ chức Trình cung cấp Danh bạ</a>
+ </li>
+ <li>
+ <a href="#RawContactBasics">Liên lạc thô</a>
+ </li>
+ <li>
+ <a href="#DataBasics">Dữ liệu</a>
+ </li>
+ <li>
+ <a href="#ContactBasics">Danh bạ</a>
+ </li>
+ <li>
+ <a href="#Sources">Dữ liệu từ Trình điều hợp Đồng bộ</a>
+ </li>
+ <li>
+ <a href="#Permissions">Quyền được Yêu cầu</a>
+ </li>
+ <li>
+ <a href="#UserProfile">Hồ sơ Người dùng</a>
+ </li>
+ <li>
+ <a href="#ContactsProviderMetadata">Siêu dữ liệu Trình cung cấp Danh bạ</a>
+ </li>
+ <li>
+ <a href="#Access">Truy cập Trình cung cấp Danh bạ</a>
+ <li>
+ </li>
+ <li>
+ <a href="#SyncAdapters">Trình điều hợp Đồng bộ Trình cung cấp Danh bạ</a>
+ </li>
+ <li>
+ <a href="#SocialStream">Dữ liệu từ Luồng Xã hội</a>
+ </li>
+ <li>
+ <a href="#AdditionalFeatures">Các Tính năng Bổ sung của Trình cung cấp Danh bạ</a>
+ </li>
+</ol>
+<h2>Lớp khóa</h2>
+<ol>
+ <li>{@link android.provider.ContactsContract.Contacts}</li>
+ <li>{@link android.provider.ContactsContract.RawContacts}</li>
+ <li>{@link android.provider.ContactsContract.Data}</li>
+ <li>{@link android.provider.ContactsContract.StreamItems}</li>
+</ol>
+<h2>Các Mẫu Liên quan</h2>
+<ol>
+ <li>
+ <a href="{@docRoot}resources/samples/ContactManager/index.html">
+ Trình quản lý Danh bạ
+ </a>
+ </li>
+ <li>
+ <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">
+ Trình điều hợp Đồng bộ Mẫu</a>
+ </li>
+</ol>
+<h2>Xem thêm</h2>
+<ol>
+ <li>
+ <a href="{@docRoot}guide/topics/providers/content-provider-basics.html">
+ Nội dung Cơ bản về Trình cung cấp Nội dung
+ </a>
+ </li>
+</ol>
+</div>
+</div>
+<p>
+ Trình cung cấp Danh bạ là một thành phần Android mạnh mẽ và linh hoạt có chức năng quản lý
+ kho dữ liệu trung tâm về con người của thiết bị. Trình cung cấp Danh bạ là nguồn của những dữ liệu
+ mà bạn thấy trong ứng dụng danh bạ của thiết bị, và bạn cũng có thể truy cập dữ liệu của nó trong
+ ứng dụng của chính mình và chuyển dữ liệu giữa thiết bị và các dịch vụ trực tuyến. Trình cung cấp chứa
+ đủ loại nguồn dữ liệu và cố gắng quản lý nhiều dữ liệu nhất có thể cho mỗi người, kết quả
+ là tổ chức của nó trở nên phức tạp. Vì điều này, API của trình cung cấp bao gồm một
+ tập mở rộng gồm các lớp hợp đồng và giao diện tạo điều kiện cho việc truy xuất và sửa đổi
+ dữ liệu.
+</p>
+<p>
+ Hướng dẫn này trình bày những nội dung sau:
+</p>
+ <ul>
+ <li>
+ Cấu trúc cơ bản của trình cung cấp.
+ </li>
+ <li>
+ Cách truy xuất dữ liệu từ trình cung cấp.
+ </li>
+ <li>
+ Cách sửa đổi dữ liệu trong trình cung cấp.
+ </li>
+ <li>
+ Cách ghi một trình điều hợp đồng bộ để đồng bộ hóa dữ liệu từ máy chủ của bạn với
+ Trình cung cấp Danh bạ.
+ </li>
+ </ul>
+<p>
+ Hướng dẫn này giả sử rằng bạn biết những nội dung cơ bản về trình cung cấp nội dung Android. Để tìm hiểu thêm
+ về trình cung cấp nội dung Android, hãy đọc hướng dẫn
+ <a href="{@docRoot}guide/topics/providers/content-provider-basics.html">
+ Nội dung Cơ bản về Trình cung cấp Nội dung</a>. Ứng dụng mẫu
+ <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">Trình điều hợp Đồng bộ Mẫu</a>
+ là một ví dụ về cách sử dụng một trình điều hợp đồng bộ để chuyển dữ liệu giữa Trình cung cấp
+ Danh bạ và ứng dụng mẫu được lưu trữ bởi Dịch vụ Web Google.
+</p>
+<h2 id="InformationTypes">Tổ chức Trình cung cấp Danh bạ</h2>
+<p>
+ Trình cung cấp Danh bạ là một thành phần của trình cung cấp nội dung Android. Nó chứa ba loại
+ dữ liệu về một người, từng loại tương ứng với một bảng do trình cung cấp đưa ra, như
+ được minh họa trong hình 1:
+</p>
+<img src="{@docRoot}images/providers/contacts_structure.png" alt="" height="364" id="figure1" />
+<p class="img-caption">
+ <strong>Hình 1.</strong> Cấu trúc bảng của Trình cung cấp Danh bạ.
+</p>
+<p>
+ Ba bảng này thường được đề cập theo tên các lớp hợp đồng của chúng. Các lớp này
+ sẽ định nghĩa các hằng số cho URI nội dung, tên cột và giá trị cột được sử dụng bởi các bảng:
+</p>
+<dl>
+ <dt>
+ Bảng {@link android.provider.ContactsContract.Contacts}
+ </dt>
+ <dd>
+ Hàng thể hiện những người khác nhau dựa trên tổng hợp của các hàng liên lạc thô.
+ </dd>
+ <dt>
+ Bảng {@link android.provider.ContactsContract.RawContacts}
+ </dt>
+ <dd>
+ Hàng chứa một bản tổng hợp dữ liệu về một người, liên quan tới tài khoản và loại người dùng.
+ </dd>
+ <dt>
+ Bảng {@link android.provider.ContactsContract.Data}
+ </dt>
+ <dd>
+ Hàng chứa các thông tin chi tiết về liên lạc thô, chẳng hạn như địa chỉ e-mail hoặc số điện thoại.
+ </dd>
+</dl>
+<p>
+ Các bảng khác được đại diện bởi các lớp hợp đồng trong {@link android.provider.ContactsContract}
+ là bảng phụ mà Trình cung cấp Danh bạ sử dụng để quản lý thao tác của nó hoặc hỗ trợ
+ các chức năng cụ thể trong ứng dụng danh bạ hoặc điện thoại của thiết bị.
+</p>
+<h2 id="RawContactBasics">Liên lạc thô</h2>
+<p>
+ Một liên lạc thô thể hiện dữ liệu của một người xuất phát từ một loại tài khoản và tên tài khoản
+ riêng. Vì Trình cung cấp Danh bạ cho phép nhiều hơn một dịch vụ trực tuyến làm nguồn
+ dữ liệu cho một người, Trình cung cấp Danh bạ cho phép nhiều liên lạc thô cho cùng một người.
+ Nhiều liên lạc thô cũng cho phép người dùng kết hợp dữ liệu của một người từ nhiều hơn một tài khoản
+ từ cùng loại tài khoản.
+</p>
+<p>
+ Hầu hết dữ liệu của một liên lạc thô không được lưu giữ trong bảng
+ {@link android.provider.ContactsContract.RawContacts}. Thay vào đó, nó được lưu giữ trong một hoặc nhiều
+ hàng trong bảng {@link android.provider.ContactsContract.Data}. Mỗi hàng dữ liệu có một cột
+ {@link android.provider.ContactsContract.DataColumns#RAW_CONTACT_ID Data.RAW_CONTACT_ID} chứa
+ giá trị {@link android.provider.BaseColumns#_ID RawContacts._ID} của
+ hàng {@link android.provider.ContactsContract.RawContacts} mẹ của nó.
+</p>
+<h3 id="RawContactsColumns">Các cột liên lạc thô quan trọng</h3>
+<p>
+ Các cột quan trọng trong bảng {@link android.provider.ContactsContract.RawContacts} được
+ liệt kê trong bảng 1. Hãy đọc các lưu ý theo sau bảng dưới đây:
+</p>
+<p class="table-caption" id="table1">
+ <strong>Bảng 1.</strong> Các cột liên lạc thô quan trọng.
+</p>
+<table>
+ <tr>
+ <th scope="col">Tên cột</th>
+ <th scope="col">Sử dụng</th>
+ <th scope="col">Lưu ý</th>
+ </tr>
+ <tr>
+ <td>
+ {@link android.provider.ContactsContract.SyncColumns#ACCOUNT_NAME}
+ </td>
+ <td>
+ Tên tài khoản cho loại tài khoản là nguồn của liên lạc thô này.
+ Ví dụ, tên tài khoản của một tài khoản Google là một trong các địa chỉ Gmail
+ của chủ sở hữu thiết bị. Xem mục nhập tiếp theo cho
+ {@link android.provider.ContactsContract.SyncColumns#ACCOUNT_TYPE} để biết thêm
+ thông tin.
+ </td>
+ <td>
+ Định dạng của tên này áp dụng theo loại tài khoản của nó. Đó không nhất thiết
+ là một địa chỉ e-mail.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ {@link android.provider.ContactsContract.SyncColumns#ACCOUNT_TYPE}
+ </td>
+ <td>
+ Loại tài khoản là nguồn của liên lạc thô này. Ví dụ, loại tài khoản
+ của một tài khoản Google là <code>com.google</code>. Luôn xác định loại tài khoản của bạn
+ bằng một mã định danh miền cho một miền mà bạn sở hữu hoặc kiểm soát. Điều này đảm bảo rằng loại tài khoản
+ của bạn là duy nhất.
+ </td>
+ <td>
+ Một loại tài khoản cung cấp dữ liệu danh bạ thường có một trình điều hợp đồng bộ liên kết để
+ đồng bộ hoá với Trình điều hợp Đồng bộ.
+ </tr>
+ <tr>
+ <td>
+ {@link android.provider.ContactsContract.RawContactsColumns#DELETED}
+ </td>
+ <td>
+ Cờ "đã xóa" cho một liên lạc thô.
+ </td>
+ <td>
+ Cờ này cho phép Trình cung cấp Danh bạ duy trì hàng bên trong tới khi trình điều hợp đồng bộ
+ có thể xóa hàng đó khỏi máy chủ của chúng rồi cuối cùng là xóa hàng
+ khỏi kho lưu giữ.
+ </td>
+ </tr>
+</table>
+<h4>Lưu ý</h4>
+<p>
+ Sau đây là các ghi chú quan trọng về bảng
+ {@link android.provider.ContactsContract.RawContacts}:
+</p>
+<ul>
+ <li>
+ Tên của liên lạc thô không được lưu giữ trong hàng của nó trong
+ {@link android.provider.ContactsContract.RawContacts}. Thay vào đó, nó được lưu giữ trong
+ bảng {@link android.provider.ContactsContract.Data}, trong một hàng
+ {@link android.provider.ContactsContract.CommonDataKinds.StructuredName}. Liên lạc thô
+ chỉ có một hàng thuộc loại này trong bảng {@link android.provider.ContactsContract.Data}.
+ </li>
+ <li>
+ <strong>Chú ý:</strong> Để sử dụng dữ liệu tài khoản của chính bạn trong một hàng liên lạc thô, trước tiên dữ liệu
+ phải được đăng ký với {@link android.accounts.AccountManager}. Để làm điều này, hãy nhắc
+ người dùng thêm loại tài khoản và tên tài khoản của chúng vào danh sách tài khoản. Nếu bạn không
+ làm vậy, Trình cung cấp Danh bạ sẽ tự động xóa hàng liên lạc thô của bạn.
+ <p>
+ Ví dụ, nếu bạn muốn ứng dụng của mình duy trì dữ liệu danh bạ cho dịch vụ dựa trên nền web của mình
+ với miền {@code com.example.dataservice}, và tài khoản của người dùng cho dịch vụ của bạn
+ là {@code becky.sharp@dataservice.example.com}, trước tiên, người dùng phải thêm
+ "loại" tài khoản ({@code com.example.dataservice}) và "tên" tài khoản
+ ({@code becky.smart@dataservice.example.com}) trước khi ứng dụng của bạn có thể thêm hàng liên lạc thô.
+ Bạn có thể giải thích yêu cầu này với người dùng bằng tài liệu, hoặc bạn có thể nhắc
+ người dùng thêm loại và tên này, hoặc cả hai. Loại tài khoản và tên tài khoản
+ được trình bày chi tiết hơn trong phần sau.
+ </li>
+</ul>
+<h3 id="RawContactsExample">Các nguồn dữ liệu liên lạc thô</h3>
+<p>
+ Để hiểu cách hoạt động của liên lạc thô, hãy xét người dùng "Emily Dickinson", cô ta có ba tài khoản
+ người dùng sau được xác định trên thiết bị của mình:
+</p>
+<ul>
+ <li><code>emily.dickinson@gmail.com</code></li>
+ <li><code>emilyd@gmail.com</code></li>
+ <li>Tài khoản Twitter "belle_of_amherst"</li>
+</ul>
+<p>
+ Người dùng này đã kích hoạt <em>Đồng bộ Danh bạ</em> cho cả ba tài khoản này trong cài đặt
+ <em>Tài khoản</em>.
+</p>
+<p>
+ Giả sử Emily Dickinson mở một cửa sổ trình duyệt, đăng nhập vào Gmail bằng tài khoản
+ <code>emily.dickinson@gmail.com</code>, mở
+ Danh bạ, và thêm "Thomas Higginson". Sau đó, cô đăng nhập vào Gmail bằng tài khoản
+ <code>emilyd@gmail.com</code> và gửi một e-mail tới "Thomas Higginson", làm vậy sẽ tự động
+ thêm người này làm một liên lạc. Cô ấy cũng theo dõi "colonel_tom" (ID Twitter của Thomas Higginson) trên
+ Twitter.
+</p>
+<p>
+ Trình cung cấp Danh bạ sẽ tạo ba liên lạc thô do kết quả của việc làm này:
+</p>
+<ol>
+ <li>
+ Một liên lạc thô cho "Thomas Higginson" liên kết với <code>emily.dickinson@gmail.com</code>.
+ Loại tài khoản người dùng là Google.
+ </li>
+ <li>
+ Một liên lạc thô thứ hai cho "Thomas Higginson" liên kết với <code>emilyd@gmail.com</code>.
+ Loại tài khoản người dùng cũng là Google. Có một liên lạc thô thứ hai ngay cả khi
+ tên giống với một tên trước đó, vì người này đã được thêm cho một
+ tài khoản người dùng khác.
+ </li>
+ <li>
+ Một liên lạc thô thứ ba cho "Thomas Higginson" liên kết với "belle_of_amherst". Loại tài khoản người dùng
+ là Twitter.
+ </li>
+</ol>
+<h2 id="DataBasics">Dữ liệu</h2>
+<p>
+ Như đề cập trước đó, dữ liệu của một liên lạc thô được lưu giữ trong một hàng
+ {@link android.provider.ContactsContract.Data} được liên kết với giá trị
+ <code>_ID</code> của liên lạc thô. Điều này cho phép một liên lạc thô có nhiều thực thể cùng loại
+ dữ liệu chẳng hạn như địa chỉ e-mail hay số điện thoại. Ví dụ, nếu
+ "Thomas Higginson" của {@code emilyd@gmail.com} (hàng liên lạc thô cho Thomas Higginson
+ liên kết với tài khoản Google <code>emilyd@gmail.com</code>) có một địa chỉ e-mail nhà là
+ <code>thigg@gmail.com</code> và một địa chỉ e-mail cơ quan là
+ <code>thomas.higginson@gmail.com</code>, Trình cung cấp Danh bạ sẽ lưu trữ hai hàng địa chỉ e-mail đó
+ và liên kết cả hai với liên lạc thô.
+</p>
+<p>
+ Để ý rằng các loại dữ liệu khác nhau được lưu giữ trong một bảng này. Các hàng tên hiển thị,
+ số điện thoại, e-mail, địa chỉ gửi thư, ảnh và chi tiết trang web đều được tìm thấy trong bảng
+ {@link android.provider.ContactsContract.Data}. Để giúp quản lý điều này, bảng
+ {@link android.provider.ContactsContract.Data} có một số cột có tên mô tả,
+ và các cột còn lại có tên chung. Các nội dung của cột tên mô tả có cùng ý nghĩa
+ không phụ thuộc vào loại dữ liệu trong hàng, trong khi nội dung của cột tên chung có
+ ý nghĩa khác nhau tùy vào loại dữ liệu.
+</p>
+<h3 id="DescriptiveColumns">Tên cột mô tả</h3>
+<p>
+ Một số ví dụ về tên cột mô tả là:
+</p>
+<dl>
+ <dt>
+ {@link android.provider.ContactsContract.Data#RAW_CONTACT_ID}
+ </dt>
+ <dd>
+ Giá trị của cột <code>_ID</code> của liên lạc thô đối với dữ liệu này.
+ </dd>
+ <dt>
+ {@link android.provider.ContactsContract.Data#MIMETYPE}
+ </dt>
+ <dd>
+ Loại dữ liệu được lưu giữ trong hàng này, được thể hiện dưới dạng một kiểu MIME tùy chỉnh. Trình cung cấp Danh bạ
+ sử dụng các kiểu MIME được định nghĩa trong lớp con của
+ {@link android.provider.ContactsContract.CommonDataKinds}. Các kiểu MIME là nguồn mở,
+ và có thể được sử dụng bởi bất kỳ ứng dụng hay trình điều hợp đồng bộ nào hoạt động với Trình cung cấp Danh bạ.
+ </dd>
+ <dt>
+ {@link android.provider.ContactsContract.DataColumns#IS_PRIMARY}
+ </dt>
+ <dd>
+ Nếu kiểu hàng dữ liệu này có thể xảy ra nhiều hơn một lần đối với một liên lạc thô, cột
+ {@link android.provider.ContactsContract.DataColumns#IS_PRIMARY} sẽ gắn cờ
+ hàng dữ liệu chứa dữ liệu sơ cấp cho kiểu đó. Ví dụ, nếu
+ người dùng nhấn giữ một số điện thoại cho một liên lạc và chọn <strong>Đặt mặc định</strong>,
+ khi đó hàng {@link android.provider.ContactsContract.Data} chứa số đó
+ có cột tương ứng {@link android.provider.ContactsContract.DataColumns#IS_PRIMARY} được đặt thành một
+ giá trị khác 0.
+ </dd>
+</dl>
+<h3 id="GenericColumns">Tên cột chung</h3>
+<p>
+ Có 15 cột chung được đặt tên <code>DATA1</code> thông qua
+ <code>DATA15</code> thường có sẵn và thêm bốn cột
+ chung <code>SYNC1</code> thông qua <code>SYNC4</code> mà chỉ được sử dụng bởi trình điều hợp
+ đồng bộ. Các hằng số tên cột chung luôn có tác dụng, không phụ thuộc vào loại
+ dữ liệu mà hàng đó chứa.
+</p>
+<p>
+ Cột <code>DATA1</code> được đánh chỉ mục. Trình cung cấp Danh bạ luôn sử dụng cột này cho
+ dữ liệu mà trình cung cấp kỳ vọng sẽ là đối tượng truy vấn thường xuyên nhất. Ví dụ,
+ trong một hàng e-mail, cột này chứa địa chỉ e-mail thực sự.
+</p>
+<p>
+ Theo quy ước, cột <code>DATA15</code> được dành để lưu giữ dữ liệu Binary Large Object
+ (BLOB) chẳng hạn như hình thu nhỏ của ảnh.
+</p>
+<h3 id="TypeSpecificNames">Tên cột theo kiểu</h3>
+<p>
+ Để tạo điều kiện làm việc với các cột đối với một kiểu hàng cụ thể, Trình cung cấp Danh bạ
+ cũng cung cấp các hằng số tên cột theo kiểu, được định nghĩa trong các lớp con của
+ {@link android.provider.ContactsContract.CommonDataKinds}. Các hằng số chỉ cấp một
+ tên hằng số khác cho cùng tên cột, điều này giúp bạn truy cập dữ liệu trong một hàng thuộc
+ một kiểu cụ thể.
+</p>
+<p>
+ Ví dụ, lớp {@link android.provider.ContactsContract.CommonDataKinds.Email} định nghĩa
+ các hằng số tên cột theo kiểu cho một hàng {@link android.provider.ContactsContract.Data} mà
+ có kiểu MIME
+ {@link android.provider.ContactsContract.CommonDataKinds.Email#CONTENT_ITEM_TYPE
+ Email.CONTENT_ITEM_TYPE}. Lớp chứa hằng số
+ {@link android.provider.ContactsContract.CommonDataKinds.Email#ADDRESS} cho cột
+ địa chỉ e-mail. Giá trị thực sự của
+ {@link android.provider.ContactsContract.CommonDataKinds.Email#ADDRESS} là "data1", giá trị này
+ giống hệt như tên chung của cột.
+</p>
+<p class="caution">
+ <strong>Chú ý:</strong> Không được thêm dữ liệu tùy chỉnh của chính bạn vào bảng
+ {@link android.provider.ContactsContract.Data} bằng cách sử dụng một hàng có một trong các kiểu MIME được xác định trước
+ của trình cung cấp. Nếu làm vậy, bạn có thể làm mất dữ liệu hoặc khiến trình cung cấp
+ gặp trục trặc. Ví dụ, bạn không nên thêm một hàng có kiểu MIME
+ {@link android.provider.ContactsContract.CommonDataKinds.Email#CONTENT_ITEM_TYPE
+ Email.CONTENT_ITEM_TYPE} mà chứa tên người dùng thay vì địa chỉ e-mail trong cột
+ <code>DATA1</code>. Nếu sử dụng kiểu MIME tùy chỉnh của mình cho hàng, khi đó bạn được tự do
+ định nghĩa tên cột theo kiểu của chính mình và sử dụng các cột theo cách bạn muốn.
+</p>
+<p>
+ Hình 2 minh họa cách các cột mô tả và cột dữ liệu xuất hiện trong hàng
+ {@link android.provider.ContactsContract.Data}, và cách mà tên cột theo kiểu "phủ lên"
+ tên cột chung
+</p>
+<img src="{@docRoot}images/providers/data_columns.png" alt="How type-specific column names map to generic column names" height="311" id="figure2" />
+<p class="img-caption">
+ <strong>Hình 2.</strong> Tên cột theo kiểu và tên cột chung.
+</p>
+<h3 id="ColumnMaps">Lớp tên cột theo kiểu</h3>
+<p>
+ Bảng 2 liệt kê các lớp tên cột theo kiểu thường được sử dụng nhất:
+</p>
+<p class="table-caption" id="table2">
+ <strong>Bảng 2.</strong> Lớp tên cột theo kiểu</p>
+<table>
+ <tr>
+ <th scope="col">Lớp ánh xạ</th>
+ <th scope="col">Kiểu dữ liệu</th>
+ <th scope="col">Lưu ý</th>
+ </tr>
+ <tr>
+ <td>{@link android.provider.ContactsContract.CommonDataKinds.StructuredName}</td>
+ <td>Dữ liệu tên của liên lạc thô liên kết với hàng dữ liệu này.</td>
+ <td>Một liên lạc thô chỉ có một trong những hàng này.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.ContactsContract.CommonDataKinds.Photo}</td>
+ <td>Ảnh chính của liên lạc thô được liên kết với hàng dữ liệu này.</td>
+ <td>Một liên lạc thô chỉ có một trong những hàng này.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.ContactsContract.CommonDataKinds.Email}</td>
+ <td>Địa chỉ e-mail của liên lạc thô được liên kết với hàng dữ liệu này.</td>
+ <td>Một liên lạc thô có thể có nhiều địa chỉ e-mail.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.ContactsContract.CommonDataKinds.StructuredPostal}</td>
+ <td>Địa chỉ cổng của liên lạc thô được liên kết với hàng dữ liệu này.</td>
+ <td>Một liên lạc thô có thể có nhiều địa chỉ cổng.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.ContactsContract.CommonDataKinds.GroupMembership}</td>
+ <td>Mã định danh liên kết liên lạc thô với một trong các nhóm trong Trình cung cấp Danh bạ.</td>
+ <td>
+ Nhóm là một tính năng tùy chọn của loại tài khoản và tên tài khoản. Chúng được mô tả
+ chi tiết hơn trong phần <a href="#Groups">Nhóm liên lạc</a>.
+ </td>
+ </tr>
+</table>
+<h3 id="ContactBasics">Danh bạ</h3>
+<p>
+ Trình cung cấp Danh bạ kết hợp các hàng liên lạc thô giữa tất cả các loại tài khoản và tên tài khoản
+ để tạo thành một <strong>liên lạc</strong>. Điều này tạo điều kiện để hiển thị và sửa đổi tất cả dữ liệu mà một
+ người dùng đã thu thập cho một người. Trình cung cấp Danh bạ quản lý việc tạo các hàng liên lạc mới
+ và tổng hợp các liên lạc thô với hàng liên lạc hiện có. Ứng dụng lẫn
+ trình điều hợp đồng bộ đều không được cho phép thêm liên lạc và một số cột trong một hàng liên lạc là cột chỉ đọc.
+</p>
+<p class="note">
+ <strong>Lưu ý:</strong> Nếu bạn cố gắng thêm một liên lạc vào Trình cung cấp Danh bạ có một
+ {@link android.content.ContentResolver#insert(Uri,ContentValues) insert()}, bạn sẽ gặp
+ lỗi ngoại lệ {@link java.lang.UnsupportedOperationException}. Nếu bạn cố gắng cập nhật một cột
+ mà được liệt kê là "chỉ đọc," cập nhật sẽ bị bỏ qua.
+</p>
+<p>
+ Trình cung cấp Danh bạ tạo một liên lạc mới để hồi đáp lại việc thêm một liên lạc thô mới
+ không khớp với bất kỳ liên lạc nào hiện có. Trình cung cấp cũng làm vậy nếu dữ liệu
+ của một liên lạc thô hiện có thay đổi sao cho nó không còn khớp với liên lạc mà trước đó
+ nó được gắn với. Nếu một ứng dụng hoặc trình điều hợp đồng bộ tạo một liên lạc thô mới mà
+ <em>khớp</em> với một liên lạc hiện tại, liên lạc thô mới sẽ được tổng hợp vào liên lạc
+ hiện có.
+</p>
+<p>
+ Trình cung cấp Danh bạ sẽ liên kết một hàng liên lạc với các hàng liên lạc thô của nó bằng cột
+ <code>_ID</code> của hàng liên lạc đó trong bảng {@link android.provider.ContactsContract.Contacts Contacts}
+. Cột <code>CONTACT_ID</code> của bảng liên lạc thô
+ {@link android.provider.ContactsContract.RawContacts} chứa các giá trị <code>_ID</code> cho
+ các hàng liên lạc liên kết với từng hàng liên lạc thô.
+</p>
+<p>
+ Bảng {@link android.provider.ContactsContract.Contacts} cũng có cột
+ {@link android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY} mà là một liên kết
+ "cố định" với hàng liên lạc đó. Vì Trình cung cấp Danh bạ tự động duy trì
+ các liên lạc, nó có thể thay đổi giá trị {@link android.provider.BaseColumns#_ID} của một hàng liên lạc
+ hồi đáp lại một sự tổng hợp hoặc đồng bộ. Ngay cả khi điều này xảy ra, URI nội dung
+ {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI} kết hợp với
+ {@link android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY} của liên lạc sẽ vẫn
+ chỉ về hàng liên lạc đó, vì thế bạn có thể sử dụng
+ {@link android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY}
+ để duy trì các liên kết đến liên lạc "yêu thích", v.v. Cột này có định dạng riêng không
+ liên quan tới định dạng của cột {@link android.provider.BaseColumns#_ID}.
+</p>
+<p>
+ Hình 3 minh họa mối liên quan giữa ba bảng chính này với nhau.
+</p>
+<img src="{@docRoot}images/providers/contacts_tables.png" alt="Contacts provider main tables" height="514" id="figure4" />
+<p class="img-caption">
+ <strong>Hình 3.</strong> Mối quan hệ giữa các bảng Danh bạ, Liên lạc Thô, và Chi tiết.
+</p>
+<h2 id="Sources">Dữ liệu từ Trình điều hợp Đồng bộ</h2>
+<p>
+ Người dùng nhập dữ liệu danh bạ trực tiếp vào thiết bị, nhưng dữ liệu cũng đi đến Trình cung cấp
+ Danh bạ từ các dịch vụ web thông qua <strong>trình điều hợp đồng bộ</strong>, giúp tự động
+ chuyển dữ liệu giữa thiết bị và các dịch vụ. Trình điều hợp đồng bộ chạy ngầm
+ dưới sự kiểm soát của hệ thống, và chúng gọi các phương pháp {@link android.content.ContentResolver} để
+ quản lý dữ liệu.
+</p>
+<p>
+ Trong Android, dịch vụ web mà một trình điều hợp đồng bộ làm việc cùng sẽ được xác định bằng một loại tài khoản.
+ Mỗi trình điều hợp đồng bộ làm việc với một loại tài khoản, nhưng nó có thể hỗ trợ nhiều tên tài khoản cho
+ loại đó. Các loại tài khoản và tên tài khoản được mô tả sơ qua trong phần
+ <a href="#RawContactsExample">Các nguồn dữ liệu liên lạc thô</a>. Các định nghĩa sau trình bày
+ chi tiết hơn và mô tả mối liên quan giữa loại và tên tài khoản với các trình điều hợp đồng bộ và dịch vụ.
+</p>
+<dl>
+ <dt>
+ Loại tài khoản
+ </dt>
+ <dd>
+ Xác định một dịch vụ mà người dùng đã lưu giữ dữ liệu trong đó. Trong phần lớn thời gian, người dùng phải
+ xác thực dịch vụ. Ví dụ, Google Contacts là một loại tài khoản được xác định
+ bởi mã <code>google.com</code>. Giá trị này tương ứng với loại tài khoản được sử dụng bởi
+ {@link android.accounts.AccountManager}.
+ </dd>
+ <dt>
+ Tên tài khoản
+ </dt>
+ <dd>
+ Xác định một tài khoản hoặc đăng nhập cụ thể cho một loại tài khoản. Tài khoản Google Contacts
+ giống như tài khoản Google, chúng có một địa chỉ e-mail làm tên tài khoản.
+ Các dịch vụ khác có thể sử dụng tên người dùng là một từ hoặc id chữ số.
+ </dd>
+</dl>
+<p>
+ Loại tài khoản không nhất thiết phải duy nhất. Một người dùng có thể cấu hình nhiều tài khoản Google Contacts
+ và tải xuống dữ liệu của chúng vào Trình cung cấp Danh bạ; điều này có thể xảy ra nếu người dùng có một tập hợp
+ các liên lạc cá nhân cho một tên tài khoản cá nhân, và một tập hợp khác cho cơ quan. Tên tài khoản thường
+ là duy nhất. Cùng nhau, chúng xác định một dòng dữ liệu cụ thể giữa Trình cung cấp Danh bạ và
+ một dịch vụ bên ngoài.
+</p>
+<p>
+ Nếu muốn chuyển dữ liệu từ dịch vụ của bạn sang Trình cung cấp Danh bạ, bạn cần ghi
+ vào trình điều hợp đồng bộ của chính mình. Điều này được mô tả chi tiết hơn trong phần
+ <a href="#SyncAdapters">Trình điều hợp Đồng bộ Trình cung cấp Danh bạ</a>.
+</p>
+<p>
+ Hình 4 minh họa cách mà Trình cung cấp Danh bạ phù hợp với dòng dữ liệu
+ về con người. Trong hộp được đánh dấu "trình điều hợp đồng bộ," mỗi trình điều hợp được ghi nhãn theo loại tài khoản của nó.
+</p>
+<img src="{@docRoot}images/providers/ContactsDataFlow.png" alt="Flow of data about people" height="252" id="figure5" />
+<p class="img-caption">
+ <strong>Hình 4.</strong> Luồng dữ liệu của Trình cung cấp Danh bạ.
+</p>
+<h2 id="Permissions">Quyền được Yêu cầu</h2>
+<p>
+ Những ứng dụng muốn truy cập Trình cung cấp Danh bạ phải yêu cầu các quyền
+ sau:
+</p>
+<dl>
+ <dt>Quyền truy cập đọc vào một hoặc nhiều bảng</dt>
+ <dd>
+ {@link android.Manifest.permission#READ_CONTACTS}, được quy định trong
+ <code>AndroidManifest.xml</code> với phần tử
+ <code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">
+ &lt;uses-permission&gt;</a></code> là
+ <code>&lt;uses-permission android:name="android.permission.READ_CONTACTS"&gt;</code>.
+ </dd>
+ <dt>Quyền truy cập ghi vào một hoặc nhiều bảng</dt>
+ <dd>
+ {@link android.Manifest.permission#WRITE_CONTACTS}, được quy định trong
+ <code>AndroidManifest.xml</code> với phần tử
+ <code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">
+ &lt;uses-permission&gt;</a></code> là
+ <code>&lt;uses-permission android:name="android.permission.WRITE_CONTACTS"&gt;</code>.
+ </dd>
+</dl>
+<p>
+ Những quyền này không mở rộng sang dữ liệu hồ sơ người dùng. Hồ sơ người dùng và các quyền
+ được yêu cầu được đề cập trong phần sau,
+ <a href="#UserProfile">Hồ sơ Người dùng</a>.
+</p>
+<p>
+ Nhớ rằng dữ liệu danh bạ của người dùng là dữ liệu cá nhân và nhạy cảm. Người dùng quan tâm về
+ quyền riêng tư của họ, vì thế họ không muốn các ứng dụng thu thập dữ liệu về mình hoặc danh bạ của mình.
+ Nếu không rõ ràng về lý do bạn cần quyền truy cập dữ liệu danh bạ của họ, họ có thể cho
+ ứng dụng của bạn đánh giá thấp hoặc từ chối cài đặt ứng dụng.
+</p>
+<h2 id="UserProfile">Hồ sơ Người dùng</h2>
+<p>
+ Bảng {@link android.provider.ContactsContract.Contacts} có một hàng đơn chứa
+ dữ liệu hồ sơ cho người dùng của thiết bị. Dữ liệu này mô tả <code>user</code> của thiết bị chứ không phải
+ của một trong các liên lạc của người dùng. Hàng liên lạc hồ sơ được liên kết với hàng
+ liên lạc thô đối với từng hệ thống sử dụng hồ sơ.
+ Mỗi hàng liên lạc thô của hồ sơ có thể có nhiều hàng dữ liệu. Các hằng số để truy cập hồ sơ
+ người dùng có sẵn trong lớp {@link android.provider.ContactsContract.Profile}.
+</p>
+<p>
+ Truy cập hồ sơ người dùng đòi hỏi phải có các quyền đặc biệt. Ngoài các quyền
+ {@link android.Manifest.permission#READ_CONTACTS} và
+ {@link android.Manifest.permission#WRITE_CONTACTS} cần để đọc và ghi, truy cập
+ hồ sơ người dùng còn yêu cầu quyền {@link android.Manifest.permission#READ_PROFILE} và
+ {@link android.Manifest.permission#WRITE_PROFILE} tương ứng cho quyền truy cập đọc và
+ ghi.
+</p>
+<p>
+ Nhớ rằng bạn nên coi hồ sơ của một người dùng là nội dung nhạy cảm. Quyền
+ {@link android.Manifest.permission#READ_PROFILE} cho phép bạn truy cập dữ liệu xác định cá nhân
+ của người dùng thiết bị. Chắc chắn phải nói cho người dùng biết lý do tại sao
+ bạn cần các quyền truy cập hồ sơ người dùng trong phần mô tả ứng dụng của mình.
+</p>
+<p>
+ Để truy xuất hàng liên lạc chứa hồ sơ của người dùng,
+ hãy gọi {@link android.content.ContentResolver#query(Uri,String[], String, String[], String)
+ ContentResolver.query()}. Đặt URI nội dung thành
+ {@link android.provider.ContactsContract.Profile#CONTENT_URI} và không cung cấp bất kỳ
+ tiêu chí lựa chọn nào. Bạn cũng có thể sử dụng URI nội dung này làm URI cơ sở để truy xuất các liên lạc thô
+ hoặc dữ liệu cho hồ sơ. Ví dụ, đoạn mã HTML này truy xuất dữ liệu cho hồ sơ:
+</p>
+<pre>
+// Sets the columns to retrieve for the user profile
+mProjection = new String[]
+ {
+ Profile._ID,
+ Profile.DISPLAY_NAME_PRIMARY,
+ Profile.LOOKUP_KEY,
+ Profile.PHOTO_THUMBNAIL_URI
+ };
+
+// Retrieves the profile from the Contacts Provider
+mProfileCursor =
+ getContentResolver().query(
+ Profile.CONTENT_URI,
+ mProjection ,
+ null,
+ null,
+ null);
+</pre>
+<p class="note">
+ <strong>Lưu ý:</strong> Nếu bạn truy xuất nhiều hàng liên lạc và muốn xác định xem một trong số chúng có phải
+ là hồ sơ người dùng không, hãy kiểm tra cột
+ {@link android.provider.ContactsContract.ContactsColumns#IS_USER_PROFILE} của hàng. Cột này
+ được đặt thành "1" nếu liên lạc là hồ sơ người dùng.
+</p>
+<h2 id="ContactsProviderMetadata">Siêu dữ liệu Trình cung cấp Danh bạ</h2>
+<p>
+ Trình cung cấp Danh bạ quản lý dữ liệu theo dõi trạng thái của dữ liệu danh bạ trong
+ kho lưu giữ. Siêu dữ liệu về kho lưu giữ này được lưu giữ ở nhiều nơi khác nhau, bao gồm
+ các hàng bảng Liên lạc Thô, Dữ liệu, và Danh bạ, bảng
+ {@link android.provider.ContactsContract.Settings}, và bảng
+ {@link android.provider.ContactsContract.SyncState}. Bảng sau đây cho biết
+ ảnh hưởng của từng mục trong siêu dữ liệu này:
+</p>
+<p class="table-caption" id="table3">
+ <strong>Bảng 3.</strong> Siêu dữ liệu trong Trình cung cấp Danh bạ</p>
+<table>
+ <tr>
+ <th scope="col">Bảng</th>
+ <th scope="col">Cột</th>
+ <th scope="col">Giá trị</th>
+ <th scope="col">Ý nghĩa</th>
+ </tr>
+ <tr>
+ <td rowspan="2">{@link android.provider.ContactsContract.RawContacts}</td>
+ <td rowspan="2">{@link android.provider.ContactsContract.SyncColumns#DIRTY}</td>
+ <td>"0" - không thay đổi kể từ lần đồng bộ cuối cùng.</td>
+ <td rowspan="2">
+ Đánh dấu các liên lạc thô đã được thay đổi trên thiết bị và phải được đồng bộ trở lại
+ máy chủ. Giá trị được đặt tự động bởi Trình cung cấp Danh bạ khi các ứng dụng
+ Android cập nhật một hàng.
+ <p>
+ Các trình điều hợp đồng bộ sửa đổi bảng liên lạc thô hoặc dữ liệu nên luôn nối
+ xâu {@link android.provider.ContactsContract#CALLER_IS_SYNCADAPTER} với
+ URI nội dung mà chúng sử dụng. Làm vậy sẽ ngăn không cho trình cung cấp đánh dấu hàng là không tốt.
+ Nếu không, các sửa đổi trình điều hợp đồng bộ xem như sửa đổi cục bộ và được
+ gửi tới máy chủ, ngay cả khi máy chủ là nguồn sửa đổi.
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td>"1" - đã thay đổi kể từ lần đồng bộ cuối cùng, cần được đồng bộ lại máy chủ.</td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.ContactsContract.RawContacts}</td>
+ <td>{@link android.provider.ContactsContract.SyncColumns#VERSION}</td>
+ <td>Số phiên bản của hàng này.</td>
+ <td>
+ Trình cung cấp Danh bạ tự động tăng dần giá trị này bất cứ khi nào hàng hoặc
+ dữ liệu có liên quan của hàng thay đổi.
+ </td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.ContactsContract.Data}</td>
+ <td>{@link android.provider.ContactsContract.DataColumns#DATA_VERSION}</td>
+ <td>Số phiên bản của hàng này.</td>
+ <td>
+ Trình cung cấp Danh bạ tự động tăng dần giá trị này bất cứ khi nào hàng dữ liệu
+ bị thay đổi.
+ </td>
+ </tr>
+ <tr>
+ <td>{@link android.provider.ContactsContract.RawContacts}</td>
+ <td>{@link android.provider.ContactsContract.SyncColumns#SOURCE_ID}</td>
+ <td>
+ Một xâu giá trị xác định duy nhất liên lạc thô này cho tài khoản mà
+ nó được tạo trong đó.
+ </td>
+ <td>
+ Khi một trình điều hợp đồng bộ tạo một liên lạc thô mới, cột này nên được đặt thành
+ ID duy nhất của máy chủ dành cho liên lạc thô đó. Khi một ứng dụng Android tạo một liên lạc thô
+ mới, ứng dụng đó sẽ để trống cột này. Điều này báo hiệu với trình điều hợp
+ đồng bộ rằng nó nên tạo một liên lạc thô mới trên máy chủ, và lấy một
+ giá trị cho {@link android.provider.ContactsContract.SyncColumns#SOURCE_ID}.
+ <p>
+ Cụ thể, id nguồn phải là <strong>duy nhất</strong> đối với từng loại tài khoản
+ và nên ổn định giữa các lần đồng bộ:
+ </p>
+ <ul>
+ <li>
+ Duy nhất: Mỗi liên lạc thô đối với một tài khoản phải có id nguồn riêng của mình. Nếu không
+ thi hành điều này, bạn sẽ gây ra sự cố trong ứng dụng danh bạ.
+ Để ý rằng hai liên lạc thô đối với cùng <em>loại</em> tài khoản có thể có
+ cùng id nguồn. Ví dụ, liên lạc thô "Thomas Higginson" đối với
+ tài khoản {@code emily.dickinson@gmail.com} được cho phép có cùng id nguồn
+ như liên lạc thô "Thomas Higginson" đối với tài khoản
+ {@code emilyd@gmail.com}.
+ </li>
+ <li>
+ Ổn định: Id nguồn là một bộ phận cố định của dữ liệu từ dịch vụ trực tuyến đối với
+ liên lạc thô. Ví dụ, nếu người dùng xóa Lưu trữ Danh bạ khỏi
+ cài đặt Ứng dụng và đồng bộ lại, các liên lạc thô được khôi phục sẽ có cùng
+ id nguồn như trước. Nếu bạn không thi hành điều này, các lối tắt sẽ dừng
+ hoạt động.
+ </li>
+ </ul>
+ </td>
+ </tr>
+ <tr>
+ <td rowspan="2">{@link android.provider.ContactsContract.Groups}</td>
+ <td rowspan="2">{@link android.provider.ContactsContract.GroupsColumns#GROUP_VISIBLE}</td>
+ <td>"0" - Các liên lạc trong nhóm này không nên được hiển thị trong UI ứng dụng Android.</td>
+ <td>
+ Cột này dành cho tính tương thích với các máy chủ mà cho phép người dùng ẩn các liên lạc trong
+ một số nhóm.
+ </td>
+ </tr>
+ <tr>
+ <td>"1" - Các liên lạc trong nhóm này được cho phép hiển thị trong UI ứng dụng.</td>
+ </tr>
+ <tr>
+ <td rowspan="2">{@link android.provider.ContactsContract.Settings}</td>
+ <td rowspan="2">
+ {@link android.provider.ContactsContract.SettingsColumns#UNGROUPED_VISIBLE}</td>
+ <td>
+ "0" - Đối với tài khoản và loại tài khoản này, những liên lạc không thuộc về nhóm
+ được ẩn đối với UI ứng dụng Android.
+ </td>
+ <td rowspan="2">
+ Theo mặc định, các liên lạc được hiển thị nếu không có liên lạc thô nào của chúng thuộc về một nhóm
+ (Tư cách thành viên nhóm đối với một liên lạc thô được thể hiện bằng một hoặc nhiều hàng
+ {@link android.provider.ContactsContract.CommonDataKinds.GroupMembership} trong
+ bảng {@link android.provider.ContactsContract.Data}).
+ Bằng cách đặt cờ này trong hàng bảng {@link android.provider.ContactsContract.Settings} đối với
+ một loại tài khoản và tài khoản, bạn có thể buộc những liên lạc không có nhóm phải hiển thị.
+ Một công dụng của cờ này đó là để hiển thị liên lạc từ các máy chủ không sử dụng nhóm.
+ </td>
+ </tr>
+ <tr>
+ <td>
+ "1" - Đối với tài khoản và loại tài khoản này, những liên lạc không thuộc về nhóm
+ sẽ được hiển thị đối với UI ứng dụng.
+ </td>
+
+ </tr>
+ <tr>
+ <td>{@link android.provider.ContactsContract.SyncState}</td>
+ <td>(tất cả)</td>
+ <td>
+ Sử dụng bảng này để lưu giữ siêu dữ liệu cho trình điều hợp đồng bộ của bạn.
+ </td>
+ <td>
+ Với bảng này, bạn có thể lưu giữ trạng thái đồng bộ và các dữ liệu khác liên quan tới đồng bộ một cách lâu dài
+ trên thiết bị.
+ </td>
+ </tr>
+</table>
+<h2 id="Access">Truy cập Trình cung cấp Danh bạ</h2>
+<p>
+ Phần này mô tả các hướng dẫn về truy cập dữ liệu từ Trình cung cấp Danh bạ, tập trung vào những
+ nội dung sau:
+</p>
+<ul>
+ <li>
+ Truy vấn thực thể.
+ </li>
+ <li>
+ Sửa đổi hàng loạt.
+ </li>
+ <li>
+ Truy xuất và sửa đổi bằng ý định.
+ </li>
+ <li>
+ Toàn vẹn dữ liệu.
+ </li>
+</ul>
+<p>
+ Thực hiện sửa đổi từ một trình điều hợp đồng bộ cũng được đề cập chi tiết hơn trong phần
+ <a href="#SyncAdapters">Trình điều hợp Đồng bộ Trình cung cấp Danh bạ</a>.
+</p>
+<h3 id="Entities">Truy vấn thực thể</h3>
+<p>
+ Vì các bảng của Trình cung cấp Danh bạ được tổ chức theo một phân cấp, thường sẽ hữu ích nếu
+ truy xuất một hàng và tất cả hàng "con" được liên kết với nó. Ví dụ, để hiển thị
+ tất cả thông tin cho một người, bạn có thể muốn truy xuất tất cả hàng
+ {@link android.provider.ContactsContract.RawContacts} đối với một hàng
+ {@link android.provider.ContactsContract.Contacts} đơn, hoặc tất cả hàng
+ {@link android.provider.ContactsContract.CommonDataKinds.Email} đối với một hàng
+ {@link android.provider.ContactsContract.RawContacts} đơn. Để tạo điều kiện cho điều này, Trình cung cấp
+ Danh bạ sẽ cung cấp các cấu trúc <strong>thực thể</strong> đóng vai trò như liên kết cơ sở dữ liệu
+ giữa các bảng.
+</p>
+<p>
+ Thực thể giống như một bảng bao gồm các cột được chọn từ một bảng mẹ và bảng con của nó.
+ Khi bạn truy vấn một thực thể, bạn cung cấp một dự thảo và các tiêu chí dựa trên các cột
+ có sẵn từ thực thể. Kết quả là một {@link android.database.Cursor} trong đó chứa
+ một hàng cho từng hàng bảng con được truy xuất. Ví dụ, nếu bạn truy vấn
+ {@link android.provider.ContactsContract.Contacts.Entity} cho một tên liên lạc
+ và tất cả hàng {@link android.provider.ContactsContract.CommonDataKinds.Email} đối với tất cả
+ liên lạc thô cho tên đó, bạn sẽ nhận lại một {@link android.database.Cursor} chứa một hàng
+ cho mỗi hàng {@link android.provider.ContactsContract.CommonDataKinds.Email}.
+</p>
+<p>
+ Các thực thể sẽ đơn giản hóa việc truy vấn. Bằng cách sử dụng một thực thể, bạn có thể truy xuất ngay lập tức tất cả dữ liệu danh bạ cho một
+ liên lạc hoặc liên lạc thô, thay vì phải truy vấn bảng mẹ trước để nhận một
+ ID, và rồi phải truy xuất bảng con bằng ID đó. Đồng thời, Trình cung cấp Danh bạ xử lý
+ một truy vấn đối với một thực thể trong một giao tác đơn, điều này đảm bảo rằng dữ liệu được truy xuất sẽ được
+ nhất quán trong nội bộ.
+</p>
+<p class="note">
+ <strong>Lưu ý:</strong> Một thực thể thường không chứa tất cả cột của bảng mẹ và
+ bảng con. Nếu bạn cố gắng làm việc với một tên cột không có trong danh sách các hằng số tên cột
+ đối với thực thể đó, bạn sẽ nhận được một {@link java.lang.Exception}.
+</p>
+<p>
+ Đoạn mã HTML sau cho biết cách truy xuất tất cả hàng liên lạc thô cho một liên lạc. Đoạn mã HTML
+ là bộ phận của một ứng dụng lớn hơn có hai hoạt động, "chính" và "chi tiết". Hoạt động chính
+ hiển thị một danh sách các hàng liên lạc; khi người dùng chọn một hàng, hoạt động sẽ gửi ID của hàng tới hoạt động
+ chi tiết. Hoạt động chi tiết sử dụng {@link android.provider.ContactsContract.Contacts.Entity}
+ để hiển thị tất cả hàng dữ liệu từ tất cả liên lạc thô được liên kết với liên lạc
+ đã chọn.
+</p>
+<p>
+ Đoạn mã HTML này được lấy từ hoạt động "chi tiết":
+</p>
+<pre>
+...
+ /*
+ * Appends the entity path to the URI. In the case of the Contacts Provider, the
+ * expected URI is content://com.google.contacts/#/entity (# is the ID value).
+ */
+ mContactUri = Uri.withAppendedPath(
+ mContactUri,
+ ContactsContract.Contacts.Entity.CONTENT_DIRECTORY);
+
+ // Initializes the loader identified by LOADER_ID.
+ getLoaderManager().initLoader(
+ LOADER_ID, // The identifier of the loader to initialize
+ null, // Arguments for the loader (in this case, none)
+ this); // The context of the activity
+
+ // Creates a new cursor adapter to attach to the list view
+ mCursorAdapter = new SimpleCursorAdapter(
+ this, // the context of the activity
+ R.layout.detail_list_item, // the view item containing the detail widgets
+ mCursor, // the backing cursor
+ mFromColumns, // the columns in the cursor that provide the data
+ mToViews, // the views in the view item that display the data
+ 0); // flags
+
+ // Sets the ListView's backing adapter.
+ mRawContactList.setAdapter(mCursorAdapter);
+...
+&#64;Override
+public Loader&lt;Cursor&gt; onCreateLoader(int id, Bundle args) {
+
+ /*
+ * Sets the columns to retrieve.
+ * RAW_CONTACT_ID is included to identify the raw contact associated with the data row.
+ * DATA1 contains the first column in the data row (usually the most important one).
+ * MIMETYPE indicates the type of data in the data row.
+ */
+ String[] projection =
+ {
+ ContactsContract.Contacts.Entity.RAW_CONTACT_ID,
+ ContactsContract.Contacts.Entity.DATA1,
+ ContactsContract.Contacts.Entity.MIMETYPE
+ };
+
+ /*
+ * Sorts the retrieved cursor by raw contact id, to keep all data rows for a single raw
+ * contact collated together.
+ */
+ String sortOrder =
+ ContactsContract.Contacts.Entity.RAW_CONTACT_ID +
+ " ASC";
+
+ /*
+ * Returns a new CursorLoader. The arguments are similar to
+ * ContentResolver.query(), except for the Context argument, which supplies the location of
+ * the ContentResolver to use.
+ */
+ return new CursorLoader(
+ getApplicationContext(), // The activity's context
+ mContactUri, // The entity content URI for a single contact
+ projection, // The columns to retrieve
+ null, // Retrieve all the raw contacts and their data rows.
+ null, //
+ sortOrder); // Sort by the raw contact ID.
+}
+</pre>
+<p>
+ Khi hoàn thành việc tải, {@link android.app.LoaderManager} gọi ra một lệnh gọi lại đến
+ {@link android.app.LoaderManager.LoaderCallbacks#onLoadFinished(Loader, D)
+ onLoadFinished()}. Một trong các tham đối đến với phương pháp này là một
+ {@link android.database.Cursor} với các kết quả của truy vấn. Trong ứng dụng của chính mình, bạn có thể nhận dữ liệu
+ từ {@link android.database.Cursor} này để hiển thị nó hoặc thao tác thêm với nó.
+</p>
+<h3 id="Transactions">Sửa đổi hàng loạt</h3>
+<p>
+ Bất cứ khi nào có thể, bạn nên chèn, cập nhật và xóa dữ liệu trong Trình cung cấp Danh bạ trong
+ "chế độ hàng loạt", bằng cách tạo một {@link java.util.ArrayList} của các đối tượng
+ {@link android.content.ContentProviderOperation} và gọi
+ {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()}. Vì
+ Trình cung cấp Danh bạ thực hiện tất cả thao tác trong một
+ {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()} trong một giao tác
+ đơn, các sửa đổi của bạn sẽ không bao giờ ra khỏi kho lưu giữ danh bạ một cách
+ không nhất quán. Sửa đổi hàng loạt cũng tạo điều kiện cho việc chèn một liên lạc thô và dữ liệu chi tiết của liên lạc
+ tại cùng thời điểm.
+</p>
+<p class="note">
+ <strong>Lưu ý:</strong> Để sửa đổi một liên lạc thô <em>đơn</em>, hãy xét gửi một ý định tới
+ ứng dụng danh bạ của thiết bị thay vì xử lý sửa đổi trong ứng dụng của bạn.
+ Việc làm này được mô tả chi tiết hơn trong phần
+ <a href="#Intents">Truy xuất và sửa đổi bằng ý định</a>.
+</p>
+<h4>Điểm kết quả</h4>
+<p>
+ Sửa đổi hàng loạt chứa nhiều thao tác có thể chặn các tiến trình khác,
+ dẫn đến trải nghiệm người dùng tổng thể không tốt. Để sắp xếp tổ chức tất cả sửa đổi mà bạn muốn
+ thực hiện trong ít danh sách riêng nhất có thể, và đồng thời ngăn chúng
+ chặn hệ thống, bạn nên đặt các <strong>điểm kết quả</strong> cho một hoặc nhiều thao tác.
+ Điểm kết quả là một đối tượng {@link android.content.ContentProviderOperation} có giá trị
+ {@link android.content.ContentProviderOperation#isYieldAllowed()} được đặt thành
+ <code>true</code>. Khi các Trình cung cấp Danh bạ gặp phải một điểm kết quả, nó tạm dừng công việc để
+ cho phép các tiến trình khác chạy và đóng giao tác hiện tại. Khi trình cung cấp bắt đầu lại, nó
+ tiếp tục với thao tác tiếp theo trong {@link java.util.ArrayList} và bắt đầu một giao tác
+ mới.
+</p>
+<p>
+ Điểm kết quả dẫn đến có nhiều hơn một giao tác trên mỗi lệnh gọi tới
+ {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()}. Vì
+ điều này, bạn nên đặt một điểm kết quả cho thao tác cuối cùng đối với một tập hợp các hàng có liên quan.
+ Ví dụ, bạn nên đặt một điểm kết quả cho thao tác cuối cùng trong một tập hợp mà thêm
+ các hàng liên lạc thô và hàng dữ liệu liên kết của chúng, hoặc thao tác cuối cùng đối với một tập hợp các hàng liên quan tới
+ một liên lạc riêng lẻ.
+</p>
+<p>
+ Điểm kết quả cũng là một đơn vị thao tác nguyên tử. Tất cả truy cập giữa hai điểm kết quả sẽ
+ hoặc thành công hoặc thất bại như một đơn vị riêng lẻ. Nếu bạn không đặt bất kỳ điểm kết quả nào, thao tác
+ nguyên tử nhỏ nhất chính là toàn bộ loạt thao tác. Nếu sử dụng điểm kết quả, bạn ngăn cản
+ các thao tác làm giảm hiệu suất của hệ thống, đồng thời đảm bảo rằng một tập con của
+ thao tác là tập nguyên tử.
+</p>
+<h4>Tham chiếu lại sửa đổi</h4>
+<p>
+ Khi bạn đang chèn một hàng liên lạc thô mới và các hàng dữ liệu liên kết của nó như một tập hợp các đối tượng
+ {@link android.content.ContentProviderOperation}, bạn phải liên kết các hàng dữ liệu với
+ hàng liên lạc thô bằng cách chèn giá trị
+ {@link android.provider.BaseColumns#_ID} của liên lạc thô làm giá trị
+ {@link android.provider.ContactsContract.DataColumns#RAW_CONTACT_ID}. Tuy nhiên, giá trị
+ này không có sẵn khi bạn đang tạo {@link android.content.ContentProviderOperation}
+ cho hàng dữ liệu, vì bạn chưa áp dụng
+ {@link android.content.ContentProviderOperation} cho hàng liên lạc thô. Để khắc phục điều này,
+ lớp {@link android.content.ContentProviderOperation.Builder} có phương pháp
+ {@link android.content.ContentProviderOperation.Builder#withValueBackReference(String, int) withValueBackReference()}.
+ Phương pháp này cho phép bạn chèn hoặc sửa đổi một cột bằng
+ kết quả của một thao tác trước đó.
+</p>
+<p>
+ Phương pháp {@link android.content.ContentProviderOperation.Builder#withValueBackReference(String, int) withValueBackReference()}
+ có hai tham đối:
+</p>
+ <dl>
+ <dt>
+ <code>key</code>
+ </dt>
+ <dd>
+ Khóa của một cặp khóa-giá trị. Giá trị của tham đối này nên là tên của một cột
+ trong bảng mà bạn đang sửa đổi.
+ </dd>
+ <dt>
+ <code>previousResult</code>
+ </dt>
+ <dd>
+ Chỉ mục dựa trên 0 của một giá trị trong mảng đối tượng
+ {@link android.content.ContentProviderResult} từ
+ {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()}. Khi
+ thao tác hàng loạt được áp dụng, kết quả của mỗi thao tác được lưu giữ trong một mảng kết quả
+ trung gian. Giá trị <code>previousResult</code> là chỉ mục
+ của một trong những kết quả này, nó được truy xuất và lưu giữ với giá trị <code>key</code>
+. Điều này cho phép bạn chèn một bản ghi liên lạc thô mới và nhận lại giá trị
+ {@link android.provider.BaseColumns#_ID} của nó, rồi thực hiện một "tham chiếu ngược" về
+ giá trị đó khi bạn thêm một hàng {@link android.provider.ContactsContract.Data}.
+ <p>
+ Toàn bộ mảng kết quả được tạo khi bạn lần đầu gọi
+ {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()},
+ với kích cỡ bằng với kích cỡ của {@link java.util.ArrayList} của các đối tượng
+ {@link android.content.ContentProviderOperation} mà bạn cung cấp. Tuy nhiên, tất cả
+ các phần tử trong mảng kết quả được đặt thành <code>null</code>, và nếu bạn cố gắng
+ thực hiện tham chiếu ngược tới một kết quả cho một thao tác chưa được áp dụng,
+{@link android.content.ContentProviderOperation.Builder#withValueBackReference(String, int) withValueBackReference()}
+ sẽ đưa ra một lỗi {@link java.lang.Exception}.
+
+ </p>
+ </dd>
+ </dl>
+<p>
+ Các đoạn mã HTML sau minh họa cách chèn một liên lạc thô mới và dữ liệu hàng loạt. Chúng
+ bao gồm mã thiết lập một điểm kết quả và sử dụng một tham chiếu lại. Đoạn mã HTML là một
+ phiên bản mở rộng của phương pháp <code>createContacEntry()</code>, nó là một phần của lớp
+ <code>ContactAdder</code> trong ứng dụng mẫu
+ <code><a href="{@docRoot}resources/samples/ContactManager/index.html">
+ Contact Manager</a></code>.
+</p>
+<p>
+ Đoạn mã HTML đầu tiên truy xuất dữ liệu liên lạc từ UI. Tại điểm này, người dùng đã
+ chọn tài khoản mà liên lạc thô mới nên được thêm cho tài khoản đó.
+</p>
+<pre>
+// Creates a contact entry from the current UI values, using the currently-selected account.
+protected void createContactEntry() {
+ /*
+ * Gets values from the UI
+ */
+ String name = mContactNameEditText.getText().toString();
+ String phone = mContactPhoneEditText.getText().toString();
+ String email = mContactEmailEditText.getText().toString();
+
+ int phoneType = mContactPhoneTypes.get(
+ mContactPhoneTypeSpinner.getSelectedItemPosition());
+
+ int emailType = mContactEmailTypes.get(
+ mContactEmailTypeSpinner.getSelectedItemPosition());
+</pre>
+<p>
+ Đoạn mã HTML tiếp theo tạo một thao tác để chèn hàng liên lạc thô vào bảng
+ {@link android.provider.ContactsContract.RawContacts}:
+</p>
+<pre>
+ /*
+ * Prepares the batch operation for inserting a new raw contact and its data. Even if
+ * the Contacts Provider does not have any data for this person, you can't add a Contact,
+ * only a raw contact. The Contacts Provider will then add a Contact automatically.
+ */
+
+ // Creates a new array of ContentProviderOperation objects.
+ ArrayList&lt;ContentProviderOperation&gt; ops =
+ new ArrayList&lt;ContentProviderOperation&gt;();
+
+ /*
+ * Creates a new raw contact with its account type (server type) and account name
+ * (user's account). Remember that the display name is not stored in this row, but in a
+ * StructuredName data row. No other data is required.
+ */
+ ContentProviderOperation.Builder op =
+ ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
+ .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, mSelectedAccount.getType())
+ .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, mSelectedAccount.getName());
+
+ // Builds the operation and adds it to the array of operations
+ ops.add(op.build());
+</pre>
+<p>
+ Tiếp theo, mã tạo các hàng dữ liệu cho hàng tên hiển thị, điện thoại và e-mail.
+</p>
+<p>
+ Từng đối tượng bộ dựng thao tác sẽ sử dụng
+ {@link android.content.ContentProviderOperation.Builder#withValueBackReference(String, int) withValueBackReference()}
+ để nhận
+ {@link android.provider.ContactsContract.DataColumns#RAW_CONTACT_ID}. Tham chiếu đó sẽ trỏ
+ ngược về đối tượng {@link android.content.ContentProviderResult} từ thao tác đầu tiên,
+ là thao tác thêm hàng liên lạc thô và trả về giá trị {@link android.provider.BaseColumns#_ID}
+ mới của nó. Kết quả là, mỗi hàng dữ liệu được tự động liên kết bởi
+ {@link android.provider.ContactsContract.DataColumns#RAW_CONTACT_ID}
+ của nó với hàng {@link android.provider.ContactsContract.RawContacts} mới mà nó thuộc về.
+</p>
+<p>
+ Đối tượng {@link android.content.ContentProviderOperation.Builder} thêm hàng e-mail sẽ được
+ gắn cờ bằng {@link android.content.ContentProviderOperation.Builder#withYieldAllowed(boolean)
+ withYieldAllowed()}, mà điều này đặt một điểm kết quả:
+</p>
+<pre>
+ // Creates the display name for the new raw contact, as a StructuredName data row.
+ op =
+ ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
+ /*
+ * withValueBackReference sets the value of the first argument to the value of
+ * the ContentProviderResult indexed by the second argument. In this particular
+ * call, the raw contact ID column of the StructuredName data row is set to the
+ * value of the result returned by the first operation, which is the one that
+ * actually adds the raw contact row.
+ */
+ .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
+
+ // Sets the data row's MIME type to StructuredName
+ .withValue(ContactsContract.Data.MIMETYPE,
+ ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
+
+ // Sets the data row's display name to the name in the UI.
+ .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME, name);
+
+ // Builds the operation and adds it to the array of operations
+ ops.add(op.build());
+
+ // Inserts the specified phone number and type as a Phone data row
+ op =
+ ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
+ /*
+ * Sets the value of the raw contact id column to the new raw contact ID returned
+ * by the first operation in the batch.
+ */
+ .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
+
+ // Sets the data row's MIME type to Phone
+ .withValue(ContactsContract.Data.MIMETYPE,
+ ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE)
+
+ // Sets the phone number and type
+ .withValue(ContactsContract.CommonDataKinds.Phone.NUMBER, phone)
+ .withValue(ContactsContract.CommonDataKinds.Phone.TYPE, phoneType);
+
+ // Builds the operation and adds it to the array of operations
+ ops.add(op.build());
+
+ // Inserts the specified email and type as a Phone data row
+ op =
+ ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
+ /*
+ * Sets the value of the raw contact id column to the new raw contact ID returned
+ * by the first operation in the batch.
+ */
+ .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
+
+ // Sets the data row's MIME type to Email
+ .withValue(ContactsContract.Data.MIMETYPE,
+ ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE)
+
+ // Sets the email address and type
+ .withValue(ContactsContract.CommonDataKinds.Email.ADDRESS, email)
+ .withValue(ContactsContract.CommonDataKinds.Email.TYPE, emailType);
+
+ /*
+ * Demonstrates a yield point. At the end of this insert, the batch operation's thread
+ * will yield priority to other threads. Use after every set of operations that affect a
+ * single contact, to avoid degrading performance.
+ */
+ op.withYieldAllowed(true);
+
+ // Builds the operation and adds it to the array of operations
+ ops.add(op.build());
+</pre>
+<p>
+ Đoạn mã HTML cuối cùng hiển thị lệnh gọi tới
+ {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()} mà
+ chèn liên lạc thô mới và các hàng dữ liệu.
+</p>
+<pre>
+ // Ask the Contacts Provider to create a new contact
+ Log.d(TAG,"Selected account: " + mSelectedAccount.getName() + " (" +
+ mSelectedAccount.getType() + ")");
+ Log.d(TAG,"Creating contact: " + name);
+
+ /*
+ * Applies the array of ContentProviderOperation objects in batch. The results are
+ * discarded.
+ */
+ try {
+
+ getContentResolver().applyBatch(ContactsContract.AUTHORITY, ops);
+ } catch (Exception e) {
+
+ // Display a warning
+ Context ctx = getApplicationContext();
+
+ CharSequence txt = getString(R.string.contactCreationFailure);
+ int duration = Toast.LENGTH_SHORT;
+ Toast toast = Toast.makeText(ctx, txt, duration);
+ toast.show();
+
+ // Log exception
+ Log.e(TAG, "Exception encountered while inserting contact: " + e);
+ }
+}
+</pre>
+<p>
+ Thao tác hàng loạt cũng cho phép bạn triển khai <strong>kiểm soát đồng thời lạc quan</strong>,
+ một phương pháp áp dụng các giao tác sửa đổi mà không phải khóa kho lưu giữ liên quan.
+ Để sử dụng phương pháp này, bạn áp dụng giao tác đó rồi kiểm tra các sửa đổi khác mà
+ có thể đã được thực hiện tại cùng thời điểm. Nếu bạn thấy đã diễn ra một sửa đổi không nhất quán,
+ hãy quay lui giao tác của bạn và thử lại.
+</p>
+<p>
+ Kiểm soát đồng thời lạc quan rất hữu ích đối với thiết bị di động, khi đó mỗi lúc chỉ có một người dùng
+ và việc truy cập đồng thời vào một kho lưu giữ dữ liệu hiếm khi xảy ra. Vì không sử dụng khóa nên
+ không bị lãng phí thời gian cho việc thiết đặt khóa hay chờ các giao tác khác nhả khóa của mình.
+</p>
+<p>
+ Để sử dụng kiểm soát đồng thời lạc quan trong khi đang cập nhật một hàng
+ {@link android.provider.ContactsContract.RawContacts} đơn, hãy làm theo các bước sau:
+</p>
+<ol>
+ <li>
+ Truy xuất cột {@link android.provider.ContactsContract.SyncColumns#VERSION}
+ của liên lạc thô cùng với dữ liệu khác mà bạn truy xuất.
+ </li>
+ <li>
+ Tạo một đối tượng {@link android.content.ContentProviderOperation.Builder} phù hợp để
+ thi hành một ràng buộc, bằng cách sử dụng phương pháp
+ {@link android.content.ContentProviderOperation#newAssertQuery(Uri)}. Đối với URI nội dung,
+ sử dụng {@link android.provider.ContactsContract.RawContacts#CONTENT_URI
+ RawContacts.CONTENT_URI}
+ với {@link android.provider.BaseColumns#_ID} của liên lạc thô được nối với nó.
+ </li>
+ <li>
+ Đối với đối tượng {@link android.content.ContentProviderOperation.Builder}, hãy gọi
+ {@link android.content.ContentProviderOperation.Builder#withValue(String, Object)
+ withValue()} để so sánh cột {@link android.provider.ContactsContract.SyncColumns#VERSION}
+ với số phiên bản bạn vừa truy xuất.
+ </li>
+ <li>
+ Đối với cùng {@link android.content.ContentProviderOperation.Builder}, hãy gọi
+ {@link android.content.ContentProviderOperation.Builder#withExpectedCount(int)
+ withExpectedCount()} để đảm bảo rằng chỉ một hàng được kiểm tra bằng xác nhận này.
+ </li>
+ <li>
+ Gọi {@link android.content.ContentProviderOperation.Builder#build()} để tạo đối tượng
+ {@link android.content.ContentProviderOperation}, rồi thêm đối tượng này làm
+ đối tượng đầu tiên trong {@link java.util.ArrayList} mà bạn chuyển cho
+ {@link android.content.ContentResolver#applyBatch(String, ArrayList) applyBatch()}.
+ </li>
+ <li>
+ Áp dụng giao tác hàng loạt.
+ </li>
+</ol>
+<p>
+ Nếu hàng liên lạc thô được cập nhật bởi một thao tác khác giữa thời điểm bạn đọc hàng và
+ thời điểm bạn cố gắng sửa đổi nó, "xác nhận" {@link android.content.ContentProviderOperation}
+ sẽ thất bại, và toàn bộ loạt thao tác sẽ được rút khỏi. Sau đó, bạn có thể chọn thử lại
+ loạt hoặc thực hiện một hành động khác.
+</p>
+<p>
+ Đoạn mã HTML sau minh họa cách tạo một "xác nhận"
+ {@link android.content.ContentProviderOperation} sau khi truy vấn một liên lạc thô đơn bằng cách sử dụng
+ một {@link android.content.CursorLoader}:
+</p>
+<pre>
+/*
+ * The application uses CursorLoader to query the raw contacts table. The system calls this method
+ * when the load is finished.
+ */
+public void onLoadFinished(Loader&lt;Cursor&gt; loader, Cursor cursor) {
+
+ // Gets the raw contact's _ID and VERSION values
+ mRawContactID = cursor.getLong(cursor.getColumnIndex(BaseColumns._ID));
+ mVersion = cursor.getInt(cursor.getColumnIndex(SyncColumns.VERSION));
+}
+
+...
+
+// Sets up a Uri for the assert operation
+Uri rawContactUri = ContentUris.withAppendedId(RawContacts.CONTENT_URI, mRawContactID);
+
+// Creates a builder for the assert operation
+ContentProviderOperation.Builder assertOp = ContentProviderOperation.netAssertQuery(rawContactUri);
+
+// Adds the assertions to the assert operation: checks the version and count of rows tested
+assertOp.withValue(SyncColumns.VERSION, mVersion);
+assertOp.withExpectedCount(1);
+
+// Creates an ArrayList to hold the ContentProviderOperation objects
+ArrayList ops = new ArrayList&lt;ContentProviderOperationg&gt;;
+
+ops.add(assertOp.build());
+
+// You would add the rest of your batch operations to "ops" here
+
+...
+
+// Applies the batch. If the assert fails, an Exception is thrown
+try
+ {
+ ContentProviderResult[] results =
+ getContentResolver().applyBatch(AUTHORITY, ops);
+
+ } catch (OperationApplicationException e) {
+
+ // Actions you want to take if the assert operation fails go here
+ }
+</pre>
+<h3 id="Intents">Truy xuất và sửa đổi bằng ý định</h3>
+<p>
+ Việc gửi một ý định tới ứng dụng danh bạ của thiết bị cho phép bạn truy cập Trình cung cấp Danh bạ
+ một cách gián tiếp. Ý định sẽ khởi động UI ứng dụng danh bạ của thiết bị, trong đó người dùng có thể
+ thực hiện công việc liên quan tới danh bạ. Với kiểu truy cập này, người dùng có thể:
+ <ul>
+ <li>Chọn một liên lạc từ danh sách và trả nó về ứng dụng của bạn để làm việc tiếp.</li>
+ <li>Chỉnh sửa dữ liệu của một liên lạc hiện có.</li>
+ <li>Chèn một liên lạc thô mới cho bất kỳ tài khoản nào của họ.</li>
+ <li>Xóa một liên lạc hoặc dữ liệu danh bạ.</li>
+ </ul>
+<p>
+ Nếu người dùng đang chèn hoặc cập nhật dữ liệu, bạn có thể thu thập dữ liệu trước và gửi nó như
+ một phần của ý định.
+</p>
+<p>
+ Khi bạn sử dụng ý định để truy cập Trình cung cấp Danh bạ thông qua ứng dụng danh bạ của thiết bị, bạn
+ không phải ghi UI hay mã của chính mình để truy nhập trình cung cấp. Bạn cũng không phải
+ yêu cầu quyền đọc hoặc ghi đến trình cung cấp. Ứng dụng danh bạ của thiết bị có thể
+ cấp quyền đọc đối với một liên lạc cho bạn, và vì bạn đang thực hiện sửa đổi đối với
+ trình cung cấp thông qua một ứng dụng khác, bạn không cần phải có quyền ghi.
+</p>
+<p>
+ Tiến trình chung để gửi một ý định nhằm truy cập một trình cung cấp được mô tả chi tiết trong hướng dẫn
+ <a href="{@docRoot}guide/topics/providers/content-provider-basics.html">
+ Nội dung Cơ bản về Trình cung cấp Nội dung</a> trong phần "Truy cập dữ liệu thông qua ý định." Hành động,
+ kiểu MIME, và các giá trị dữ liệu bạn sử dụng cho các tác vụ có sẵn được tóm tắt trong Bảng 4, trong khi các giá trị
+ phụ thêm mà bạn có thể sử dụng với
+ {@link android.content.Intent#putExtra(String, String) putExtra()} được liệt kê trong
+ tài liệu tham khảo cho {@link android.provider.ContactsContract.Intents.Insert}:
+</p>
+<p class="table-caption" id="table4">
+ <strong>Bảng 4.</strong> Ý định của Trình cung cấp Danh bạ.
+</p>
+<table style="width:75%">
+ <tr>
+ <th scope="col" style="width:10%">Tác vụ</th>
+ <th scope="col" style="width:5%">Hành động</th>
+ <th scope="col" style="width:10%">Dữ liệu</th>
+ <th scope="col" style="width:10%">Kiểu MIME</th>
+ <th scope="col" style="width:25%">Lưu ý</th>
+ </tr>
+ <tr>
+ <td><strong>Chọn một liên lạc từ danh sách</strong></td>
+ <td>{@link android.content.Intent#ACTION_PICK}</td>
+ <td>
+ Một trong:
+ <ul>
+ <li>
+{@link android.provider.ContactsContract.Contacts#CONTENT_URI Contacts.CONTENT_URI},
+ mà hiển thị một danh sách các liên lạc.
+ </li>
+ <li>
+{@link android.provider.ContactsContract.CommonDataKinds.Phone#CONTENT_URI Phone.CONTENT_URI},
+ mà hiển thị một danh sách các số điện thoại cho một liên lạc thô.
+ </li>
+ <li>
+{@link android.provider.ContactsContract.CommonDataKinds.StructuredPostal#CONTENT_URI
+StructuredPostal.CONTENT_URI},
+ mà hiển thị một danh sách các địa chỉ bưu điện cho một liên lạc thô.
+ </li>
+ <li>
+{@link android.provider.ContactsContract.CommonDataKinds.Email#CONTENT_URI Email.CONTENT_URI},
+ mà hiển thị một danh sách các địa chỉ e-mail cho một liên lạc thô.
+ </li>
+ </ul>
+ </td>
+ <td>
+ Không sử dụng
+ </td>
+ <td>
+ Hiển thị một danh sách các liên lạc thô hoặc danh sách dữ liệu từ một liên lạc thô, tùy vào kiểu
+ URI nội dung mà bạn cung cấp.
+ <p>
+ Gọi
+ {@link android.app.Activity#startActivityForResult(Intent, int) startActivityForResult()},
+ nó trả về URI nội dung của hàng được chọn. Hình thức của URI là URI nội dung
+ của bảng với <code>LOOKUP_ID</code> của hàng được nối với nó.
+ Ứng dụng danh bạ của thiết bị cấp quyền đọc và ghi cho URI nội dung này
+ trong suốt thời gian hoạt động của bạn. Xem hướng dẫn
+ <a href="{@docRoot}guide/topics/providers/content-provider-basics.html">
+ Nội dung Cơ bản về Trình cung cấp Nội dung</a> để biết thêm chi tiết.
+ </p>
+ </td>
+ </tr>
+ <tr>
+ <td><strong>Chèn một liên lạc thô mới</strong></td>
+ <td>{@link android.provider.ContactsContract.Intents.Insert#ACTION Insert.ACTION}</td>
+ <td>Không áp dụng</td>
+ <td>
+ {@link android.provider.ContactsContract.RawContacts#CONTENT_TYPE
+ RawContacts.CONTENT_TYPE}, kiểu MIME cho một tập hợp liên các lạc thô.
+ </td>
+ <td>
+ Hiển thị màn hình <strong>Thêm Liên lạc</strong> của ứng dụng danh bạ của thiết bị. Các
+ giá trị phụ thêm mà bạn thêm vào ý định sẽ được hiển thị. Nếu được gửi bằng
+ {@link android.app.Activity#startActivityForResult(Intent, int) startActivityForResult()},
+ URI nội dung của liên lạc thô mới thêm sẽ được chuyển lại cho phương pháp gọi lại
+ {@link android.app.Activity#onActivityResult(int, int, Intent) onActivityResult()}
+ của hoạt động của bạn trong tham đối {@link android.content.Intent}, trong
+ trường "dữ liệu". Để nhận giá trị, hãy gọi {@link android.content.Intent#getData()}.
+ </td>
+ </tr>
+ <tr>
+ <td><strong>Chỉnh sửa một liên lạc</strong></td>
+ <td>{@link android.content.Intent#ACTION_EDIT}</td>
+ <td>
+ {@link android.provider.ContactsContract.Contacts#CONTENT_LOOKUP_URI} đối với
+ liên lạc. Hoạt động của trình chỉnh sửa sẽ cho phép người dùng chỉnh sửa bất kỳ dữ liệu nào được liên kết
+ với liên lạc này.
+ </td>
+ <td>
+ {@link android.provider.ContactsContract.Contacts#CONTENT_ITEM_TYPE
+ Contacts.CONTENT_ITEM_TYPE}, một liên lạc đơn.</td>
+ <td>
+ Hiển thị màn hình Chỉnh sửa Liên lạc trong ứng dụng danh bạ. Các giá trị phụ thêm mà bạn thêm
+ vào ý định sẽ được hiển thị. Khi người dùng nhấp vào <strong>Xong</strong> để lưu các
+ chỉnh sửa, hoạt động của bạn quay lại tiền cảnh.
+ </td>
+ </tr>
+ <tr>
+ <td><strong>Hiển thị một trình chọn mà cũng có thể thêm dữ liệu.</strong></td>
+ <td>{@link android.content.Intent#ACTION_INSERT_OR_EDIT}</td>
+ <td>
+ Không áp dụng
+ </td>
+ <td>
+ {@link android.provider.ContactsContract.Contacts#CONTENT_ITEM_TYPE}
+ </td>
+ <td>
+ Ý định này luôn hiển thị màn hình bộ chọn của ứng dụng danh bạ. Người dùng có thể hoặc
+ chọn một liên lạc để chỉnh sửa, hoặc thêm một liên lạc mới. Hoặc màn hình chỉnh sửa hoặc màn hình thêm
+ sẽ xuất hiện, tùy vào lựa chọn của người dùng, và dữ liệu phụ thêm mà bạn chuyển trong ý định
+ sẽ được hiển thị. Nếu ứng dụng của bạn hiển thị dữ liệu chẳng hạn như e-mail hoặc số điện thoại, hãy sử dụng
+ ý định này để cho phép người dùng thêm dữ liệu vào một liên lạc hiện tại.
+ liên lạc,
+ <p class="note">
+ <strong>Lưu ý:</strong> Không cần gửi một giá trị tên trong phần phụ thêm của ý định,
+ vì người dùng luôn chọn một tên hiện có hoặc thêm một tên mới. Thêm nữa,
+ nếu bạn gửi một tên, và người dùng chọn thực hiện chỉnh sửa, ứng dụng danh bạ sẽ
+ hiển thị tên mà bạn gửi, ghi đè giá trị trước. Nếu người dùng không
+ để ý thấy điều này và lưu chỉnh sửa, giá trị cũ sẽ bị mất.
+ </p>
+ </td>
+ </tr>
+</table>
+<p>
+ Ứng dụng danh bạ của thiết bị không cho phép bạn xóa một liên lạc thô hay bất kỳ dữ liệu nào bằng một
+ ý định. Thay vào đó, để xóa một liên lạc thô, hãy sử dụng
+ {@link android.content.ContentResolver#delete(Uri, String, String[]) ContentResolver.delete()}
+ hoặc {@link android.content.ContentProviderOperation#newDelete(Uri)
+ ContentProviderOperation.newDelete()}.
+</p>
+<p>
+ Đoạn mã HTML sau minh họa cách xây dựng và gửi một ý định để chèn một liên lạc thô mới và
+ dữ liệu:
+</p>
+<pre>
+// Gets values from the UI
+String name = mContactNameEditText.getText().toString();
+String phone = mContactPhoneEditText.getText().toString();
+String email = mContactEmailEditText.getText().toString();
+
+String company = mCompanyName.getText().toString();
+String jobtitle = mJobTitle.getText().toString();
+
+// Creates a new intent for sending to the device's contacts application
+Intent insertIntent = new Intent(ContactsContract.Intents.Insert.ACTION);
+
+// Sets the MIME type to the one expected by the insertion activity
+insertIntent.setType(ContactsContract.RawContacts.CONTENT_TYPE);
+
+// Sets the new contact name
+insertIntent.putExtra(ContactsContract.Intents.Insert.NAME, name);
+
+// Sets the new company and job title
+insertIntent.putExtra(ContactsContract.Intents.Insert.COMPANY, company);
+insertIntent.putExtra(ContactsContract.Intents.Insert.JOB_TITLE, jobtitle);
+
+/*
+ * Demonstrates adding data rows as an array list associated with the DATA key
+ */
+
+// Defines an array list to contain the ContentValues objects for each row
+ArrayList&lt;ContentValues&gt; contactData = new ArrayList&lt;ContentValues&gt;();
+
+
+/*
+ * Defines the raw contact row
+ */
+
+// Sets up the row as a ContentValues object
+ContentValues rawContactRow = new ContentValues();
+
+// Adds the account type and name to the row
+rawContactRow.put(ContactsContract.RawContacts.ACCOUNT_TYPE, mSelectedAccount.getType());
+rawContactRow.put(ContactsContract.RawContacts.ACCOUNT_NAME, mSelectedAccount.getName());
+
+// Adds the row to the array
+contactData.add(rawContactRow);
+
+/*
+ * Sets up the phone number data row
+ */
+
+// Sets up the row as a ContentValues object
+ContentValues phoneRow = new ContentValues();
+
+// Specifies the MIME type for this data row (all data rows must be marked by their type)
+phoneRow.put(
+ ContactsContract.Data.MIMETYPE,
+ ContactsContract.CommonDataKinds.Phone.CONTENT_ITEM_TYPE
+);
+
+// Adds the phone number and its type to the row
+phoneRow.put(ContactsContract.CommonDataKinds.Phone.NUMBER, phone);
+
+// Adds the row to the array
+contactData.add(phoneRow);
+
+/*
+ * Sets up the email data row
+ */
+
+// Sets up the row as a ContentValues object
+ContentValues emailRow = new ContentValues();
+
+// Specifies the MIME type for this data row (all data rows must be marked by their type)
+emailRow.put(
+ ContactsContract.Data.MIMETYPE,
+ ContactsContract.CommonDataKinds.Email.CONTENT_ITEM_TYPE
+);
+
+// Adds the email address and its type to the row
+emailRow.put(ContactsContract.CommonDataKinds.Email.ADDRESS, email);
+
+// Adds the row to the array
+contactData.add(emailRow);
+
+/*
+ * Adds the array to the intent's extras. It must be a parcelable object in order to
+ * travel between processes. The device's contacts app expects its key to be
+ * Intents.Insert.DATA
+ */
+insertIntent.putParcelableArrayListExtra(ContactsContract.Intents.Insert.DATA, contactData);
+
+// Send out the intent to start the device's contacts app in its add contact activity.
+startActivity(insertIntent);
+</pre>
+<h3 id="DataIntegrity">Toàn vẹn dữ liệu</h3>
+<p>
+ Vì kho lưu giữ danh bạ chứa dữ liệu quan trọng và nhạy cảm mà người dùng cho là
+ đúng và cập nhật, Trình cung cấp Danh bạ có các quy tắc về toàn vẹn dữ liệu được định nghĩa rõ ràng. Bạn có
+ trách nhiệm tuân theo những quy tắc này khi sửa đổi dữ liệu danh bạ. Các quy tắc
+ quan trọng được liệt kê ở đây:
+</p>
+<dl>
+ <dt>
+ Luôn thêm một hàng {@link android.provider.ContactsContract.CommonDataKinds.StructuredName} cho
+ mỗi hàng {@link android.provider.ContactsContract.RawContacts} mà bạn thêm.
+ </dt>
+ <dd>
+ Hàng {@link android.provider.ContactsContract.RawContacts} không có một hàng
+ {@link android.provider.ContactsContract.CommonDataKinds.StructuredName} trong bảng
+ {@link android.provider.ContactsContract.Data} có thể gây ra sự cố trong khi
+ tổng hợp.
+ </dd>
+ <dt>
+ Luôn liên kết các hàng {@link android.provider.ContactsContract.Data} mới với hàng
+ {@link android.provider.ContactsContract.RawContacts} mẹ của chúng.
+ </dt>
+ <dd>
+ Mỗi hàng {@link android.provider.ContactsContract.Data} mà không được liên kết với một
+ {@link android.provider.ContactsContract.RawContacts} sẽ không hiển thị trong ứng dụng danh bạ
+ của thiết bị, và nó có thể gây ra sự cố với trình điều hợp đồng bộ.
+ </dd>
+ <dt>
+ Chỉ thay đổi dữ liệu đối với những liên lạc thô mà bạn sở hữu.
+ </dt>
+ <dd>
+ Nhớ rằng Trình cung cấp Danh bạ luôn quản lý dữ liệu từ vài
+ loại tài khoản/dịch vụ trực tuyến khác nhau. Bạn cần đảm bảo rằng ứng dụng của bạn chỉ sửa đổi
+ hoặc xóa dữ liệu đối với các hàng thuộc về bạn, và rằng nó chỉ chèn dữ liệu có
+ loại và tên tài khoản mà bạn kiểm soát.
+ </dd>
+ <dt>
+ Luôn sử dụng các hằng số được định nghĩa trong {@link android.provider.ContactsContract} và các lớp con của nó
+ đối với thẩm quyền, URI nội dung, đường dẫn URI, tên cột, kiểu MIME, và các giá trị
+ {@link android.provider.ContactsContract.CommonDataKinds.CommonColumns#TYPE}.
+ </dt>
+ <dd>
+ Sử dụng những hằng số này sẽ giúp bạn tránh gặp lỗi. Bạn cũng sẽ được thông báo bằng cảnh báo
+ từ trình biên dịch nếu bất kỳ hằng số nào không được chấp nhận.
+ </dd>
+</dl>
+<h3 id="CustomData">Hàng dữ liệu tùy chỉnh</h3>
+<p>
+ Bằng cách tạo và sử dụng các kiểu MIME tùy chỉnh của chính mình, bạn có thể chèn, chỉnh sửa, xóa và truy xuất
+ các hàng dữ liệu của chính mình trong bảng {@link android.provider.ContactsContract.Data}. Các hàng của bạn
+ bị giới hạn bằng cách sử dụng cột được định nghĩa trong
+ {@link android.provider.ContactsContract.DataColumns}, mặc dù bạn có thể ánh xạ
+ tên cột theo kiểu của chính mình với tên cột mặc định. Trong ứng dụng danh bạ của thiết bị,
+ dữ liệu cho các hàng của bạn được hiển thị nhưng không thể chỉnh sửa hay xóa được, và người dùng không thể thêm
+ dữ liệu bổ sung. Để cho phép người dùng sửa đổi các hàng dữ liệu tùy chỉnh của mình, bạn phải cung cấp một hoạt động
+ trình chỉnh sửa trong ứng dụng của chính mình.
+</p>
+<p>
+ Để hiển thị dữ liệu tùy chỉnh của mình, hãy cung cấp một tệp <code>contacts.xml</code> chứa một phần tử
+ <code>&lt;ContactsAccountType&gt;</code> và một hoặc nhiều phần tử con
+ <code>&lt;ContactsDataKind&gt;</code> của nó. Điều này được mô tả chi tiết hơn trong
+ phần <a href="#SocialStreamDataKind"><code>&lt;ContactsDataKind&gt; element</code></a>.
+</p>
+<p>
+ Để tìm hiểu thêm về các kiểu MIME tùy chỉnh, hãy đọc hướng dẫn
+ <a href="{@docRoot}guide/topics/providers/content-provider-creating.html">
+ Tạo một Trình cung cấp Nội dung</a>.
+</p>
+<h2 id="SyncAdapters">Trình điều hợp Đồng bộ Trình cung cấp Danh bạ</h2>
+<p>
+ Trình cung cấp Danh bạ được thiết kế riêng để xử lý <strong>đồng bộ hoá</strong>
+ dữ liệu danh bạ giữa một thiết bị và một dịch vụ trực tuyến. Điều này cho phép người dùng tải
+ dữ liệu hiện có xuống một thiết bị mới và tải dữ liệu hiện có lên một tài khoản mới.
+ Đồng bộ hoá cũng đảm bảo rằng người dùng có sẵn dữ liệu mới nhất, không phụ thuộc vào
+ nguồn của các bổ sung và thay đổi. Một ưu điểm khác của đồng bộ hoá đó là nó khiến
+ dữ liệu danh bạ có sẵn ngay cả khi thiết bị không được kết nối với mạng.
+</p>
+<p>
+ Mặc dù bạn có thể triển khai đồng bộ hoá theo nhiều cách, hệ thống Android cung cấp
+ một khuôn khổ đồng bộ hóa bổ trợ có khả năng tự động hóa những tác vụ sau:
+ <ul>
+
+ <li>
+ Kiểm tra sự sẵn sàng của mạng.
+ </li>
+ <li>
+ Lập lịch biểu và thực hiện đồng bộ hoá dựa trên tùy chọn của người dùng.
+ </li>
+ <li>
+ Khởi động lại những đồng bộ hoá đã dừng.
+ </li>
+ </ul>
+<p>
+ Để sử dụng khuôn khổ này, bạn phải cung cấp một phần bổ trợ trình điều hợp đồng bộ. Mỗi trình điều hợp đồng bộ là duy nhất đối với
+ một dịch vụ và trình cung cấp nội dung, nhưng có thể xử lý nhiều tên tài khoản cho cùng dịch vụ. Khuôn khổ
+ cũng cho phép nhiều trình điều hợp đồng bộ cho cùng dịch vụ và trình cung cấp.
+</p>
+<h3 id="SyncClassesFiles">Các lớp và tệp trình điều hợp đồng bộ</h3>
+<p>
+ Bạn triển khai một trình điều hợp đồng bộ làm lớp con của
+ {@link android.content.AbstractThreadedSyncAdapter} và cài đặt nó như một phần của một ứng dụng
+ Android. Hệ thống biết về trình điều hợp đồng bộ từ các phần tử trong bản kê khai ứng dụng
+ của nó, và từ một tệp XML đặc biệt được chỉ đến trong bản kê khai. Tệp XML sẽ định nghĩa
+ loại tài khoản cho dịch vụ trực tuyến và thẩm quyền cho trình cung cấp nội dung, cùng nhau chúng
+ xác định duy nhất một trình điều hợp. Trình điều hợp đồng bộ không được kích hoạt cho tới khi người dùng thêm một
+ tài khoản cho loại tài khoản của trình điều hợp đồng bộ và kích hoạt đồng bộ hoá cho trình cung cấp
+ nội dung mà trình điều hợp đồng bộ sẽ đồng bộ cùng. Tại thời điểm đó, hệ thống bắt đầu quản lý trình điều hợp,
+ gọi nó nếu cần thiết để đồng bộ hoá giữa trình cung cấp nội dung và máy chủ.
+</p>
+<p class="note">
+ <strong>Lưu ý:</strong> Việc sử dụng một loại tài khoản để tham gia nhận biết trình điều hợp đồng bộ sẽ cho phép
+ hệ thống phát hiện và nhóm cùng nhau những trình điều hợp đồng bộ truy cập các dịch vụ khác nhau từ
+ cùng tổ chức. Ví dụ, các trình điều hợp đồng bộ cho dịch vụ trực tuyến của Google đều có cùng
+ loại tài khoản <code>com.google</code>. Khi người dùng thêm một tài khoản Google vào thiết bị của mình, tất cả
+ trình điều hợp đồng bộ được cài đặt cho dịch vụ Google được liệt kê cùng nhau; mỗi trình điều hợp đồng bộ
+ được liệt kê sẽ đồng bộ với một trình cung cấp nội dung khác nhau trên thiết bị.
+</p>
+<p>
+ Vì hầu hết dịch vụ đều yêu cầu người dùng xác minh danh tính của họ trước khi truy cập
+ dữ liệu, hệ thống Android cung cấp một khuôn khổ xác thực tương tự như và thường
+ được sử dụng cùng với khuôn khổ của trình điều hợp đồng bộ. Khuôn khổ xác thực sử dụng
+ các trình xác thực bổ trợ là lớp con của
+ {@link android.accounts.AbstractAccountAuthenticator}. Một trình xác thực sẽ xác minh
+ danh tính của người dùng theo các bước sau:
+ <ol>
+ <li>
+ Thu thập tên, mật khẩu hoặc thông tin tương tự của người dùng (
+<strong>thông tin xác thực</strong> của người dùng).
+ </li>
+ <li>
+ Gửi thông tin xác thực tới dịch vụ
+ </li>
+ <li>
+ Kiểm tra trả lời của dịch vụ.
+ </li>
+ </ol>
+<p>
+ Nếu dịch vụ chấp nhận thông tin xác thực, trình xác thực có thể
+ lưu giữ thông tin xác thực đó để sử dụng sau. Vì khuôn khổ trình xác thực bổ trợ,
+ {@link android.accounts.AccountManager} có thể cung cấp quyền truy cập bất kỳ token xác thực nào mà một trình xác thực
+ hỗ trợ và chọn hiện ra, chẳng hạn như token xác thực OAuth2.
+</p>
+<p>
+ Mặc dù không yêu cầu xác thực, phần lớn dịch vụ danh bạ đều sử dụng nó.
+ Tuy nhiên, bạn không phải sử dụng khuôn khổ xác thực của Android để thực hiện xác thực.
+</p>
+<h3 id="SyncAdapterImplementing">Triển khai trình điều hợp đồng bộ</h3>
+<p>
+ Để triển khai một trình điều hợp đồng bộ cho Trình cung cấp Danh bạ, bạn bắt đầu bằng cách tạo một
+ ứng dụng Android chứa:
+</p>
+ <dl>
+ <dt>
+ Một thành phần {@link android.app.Service} để hồi đáp lại các yêu cầu từ hệ thống nhằm
+ gắn kết với trình điều hợp đồng bộ.
+ </dt>
+ <dd>
+ Khi hệ thống muốn chạy đồng bộ hoá, nó gọi phương pháp
+ {@link android.app.Service#onBind(Intent) onBind()} của dịch vụ và nhận một
+ {@link android.os.IBinder} cho trình điều hợp đồng bộ. Điều này cho phép hệ thống thực hiện
+ lệnh gọi liên tiến trình tới các phương pháp của trình điều hợp.
+ <p>
+ Trong ứng dụng mẫu<a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">
+ Trình điều hợp Đồng bộ Mẫu</a>, tên lớp của dịch vụ này là
+ <code>com.example.android.samplesync.syncadapter.SyncService</code>.
+ </p>
+ </dd>
+ <dt>
+ Trình điều hợp đồng bộ thực tế, được triển khai như một lớp con cụ thể của
+ {@link android.content.AbstractThreadedSyncAdapter}.
+ </dt>
+ <dd>
+ Lớp này thực hiện công việc tải xuống dữ liệu từ máy chủ, tải lên dữ liệu từ
+ thiết bị, và xử lý xung đột. Công việc chính của trình điều hợp được
+ thực hiện trong phương pháp {@link android.content.AbstractThreadedSyncAdapter#onPerformSync(
+ Account, Bundle, String, ContentProviderClient, SyncResult)
+ onPerformSync()}. Lớp này phải được khởi tạo như một đối tượng duy nhất (singleton).
+ <p>
+ Trong ứng dụng mẫu <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">
+ Trình điều hợp Đồng bộ Mẫu</a>, trình điều hợp đồng bộ được định nghĩa trong lớp
+ <code>com.example.android.samplesync.syncadapter.SyncAdapter</code>.
+ </p>
+ </dd>
+ <dt>
+ Một lớp con của {@link android.app.Application}.
+ </dt>
+ <dd>
+ Lớp này đóng vai trò như một nhà máy cho đối tượng duy nhất của trình điều hợp đồng bộ. Sử dụng phương pháp
+ {@link android.app.Application#onCreate()} để khởi tạo trình điều hợp đồng bộ, và
+ cung cấp một phương pháp "bộ nhận" tĩnh để trả đối tượng duy nhất về phương pháp
+ {@link android.app.Service#onBind(Intent) onBind()} của dịch vụ
+ của trình điều hợp đồng bộ.
+ </dd>
+ <dt>
+ <strong>Tùy chọn:</strong> Một thành phần {@link android.app.Service} để hồi đáp lại
+ các yêu cầu từ hệ thống về xác thực người dùng.
+ </dt>
+ <dd>
+ {@link android.accounts.AccountManager} khởi động dịch vụ này để bắt đầu tiến trình
+ xác thực. Phương pháp {@link android.app.Service#onCreate()} của dịch vụ này sẽ khởi tạo một
+ đối tượng trình xác thực. Khi hệ thống muốn xác thực một tài khoản người dùng cho trình điều hợp đồng bộ
+ của ứng dụng, nó sẽ gọi phương pháp
+ {@link android.app.Service#onBind(Intent) onBind()} của dịch vụ để nhận một
+ {@link android.os.IBinder} cho trình xác thực. Điều này cho phép hệ thống thực hiện
+ lệnh gọi liên tiến trình tới các phương pháp của trình xác thực.
+ <p>
+ Trong ứng dụng mẫu<a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">
+ Trình điều hợp Đồng bộ Mẫu</a>, tên lớp của dịch vụ này là
+ <code>com.example.android.samplesync.authenticator.AuthenticationService</code>.
+ </p>
+ </dd>
+ <dt>
+ <strong>Tùy chọn:</strong> Một lớp con cụ thể của
+ {@link android.accounts.AbstractAccountAuthenticator} để xử lý các yêu cầu về
+ xác thực.
+ </dt>
+ <dd>
+ Lớp này cung cấp các phương pháp mà {@link android.accounts.AccountManager} gọi ra
+ để xác thực các thông tin xác thực của người dùng với máy chủ. Các chi tiết của
+ tiến trình xác thực rất khác nhau dựa trên công nghệ máy chủ đang sử dụng. Bạn nên
+ tham khảo tài liệu cho phần mềm máy chủ của mình để tìm hiểu thêm về xác thực.
+ <p>
+ Trong ứng dụng mẫu <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">
+ Trình điều hợp Đồng bộ Mẫu</a>, trình xác thực được định nghĩa trong lớp
+ <code>com.example.android.samplesync.authenticator.Authenticator</code>.
+ </p>
+ </dd>
+ <dt>
+ Các tệp XML để định nghĩa trình điều hợp đồng bộ và trình xác thực cho hệ thống.
+ </dt>
+ <dd>
+ Các thành phần dịch vụ trình điều hợp đồng bộ và trình xác thực đã nêu được
+ định nghĩa trong các phần tử
+<code>&lt;<a href="{@docRoot}guide/topics/manifest/service-element.html">service</a>&gt;</code>
+ ở bản kê khai của ứng dụng. Những phần tử này
+ chứa các phần tử con
+<code>&lt;<a href="{@docRoot}guide/topics/manifest/meta-data-element.html">meta-data</a>&gt;</code>
+mà cung cấp dữ liệu cụ thể cho
+ hệ thống:
+ <ul>
+ <li>
+ Phần tử
+<code>&lt;<a href="{@docRoot}guide/topics/manifest/meta-data-element.html">meta-data</a>&gt;</code>
+ cho dịch vụ trình điều hợp đồng bộ sẽ trỏ về
+ tệp XML <code>res/xml/syncadapter.xml</code>. Đến lượt mình, tệp này quy định
+ một URI cho dịch vụ web mà sẽ được đồng bộ hóa với Trình cung cấp Danh bạ,
+ và một loại tài khoản cho dịch vụ web.
+ </li>
+ <li>
+ <strong>Tùy chọn:</strong> Phần tử
+<code>&lt;<a href="{@docRoot}guide/topics/manifest/meta-data-element.html">meta-data</a>&gt;</code>
+ cho trình xác thực sẽ trỏ về tệp XML
+ <code>res/xml/authenticator.xml</code>. Đến lượt mình, tệp này quy định
+ loại tài khoản mà trình xác thực này hỗ trợ, cũng như các tài nguyên UI mà
+ xuất hiện trong tiến trình xác thực. Loại tài khoản được quy định trong phần tử
+ này phải giống như loại tài khoản được quy định cho trình điều hợp
+ đồng bộ.
+ </li>
+ </ul>
+ </dd>
+ </dl>
+<h2 id="SocialStream">Dữ liệu từ Luồng Xã hội</h2>
+<p>
+ Các bảng {@link android.provider.ContactsContract.StreamItems} và
+ {@link android.provider.ContactsContract.StreamItemPhotos} quản lý
+ dữ liệu đến từ các mạng xã hội. Bạn có thể ghi một trình điều hợp đồng bộ mà thêm dữ liệu luồng từ
+ mạng của chính mình vào những bảng này, hoặc bạn có thể đọc dữ liệu luồng từ những bảng này và
+ hiển thị nó trong ứng dụng của chính mình, hoặc cả hai. Với những tính năng này, các dịch vụ và ứng dụng
+ mạng xã hội của bạn có thể được tích hợp vào trải nghiệm mạng xã hội của Android.
+</p>
+<h3 id="StreamText">Văn bản từ luồng xã hội</h3>
+<p>
+ Các mục dòng dữ liệu luôn được liên kết với một liên lạc thô.
+ {@link android.provider.ContactsContract.StreamItemsColumns#RAW_CONTACT_ID} liên kết với giá trị
+ <code>_ID</code> của liên lạc thô mới. Loại tài khoản và tên tài khoản của liên lạc thô
+ cũng được lưu giữ trong hàng mục dòng.
+</p>
+<p>
+ Lưu giữ dữ liệu từ luồng của bạn vào những cột sau:
+</p>
+<dl>
+ <dt>
+ {@link android.provider.ContactsContract.StreamItemsColumns#ACCOUNT_TYPE}
+ </dt>
+ <dd>
+ <strong>Bắt buộc.</strong> Loại tài khoản của người dùng đối với liên lạc thô được liên kết với mục dòng
+ này. Nhớ đặt giá trị này khi bạn chèn một mục dòng.
+ </dd>
+ <dt>
+ {@link android.provider.ContactsContract.StreamItemsColumns#ACCOUNT_NAME}
+ </dt>
+ <dd>
+ <strong>Bắt buộc.</strong> Tên tài khoản của người dùng đối với liên lạc thô được liên kết với mục dòng
+ này. Nhớ đặt giá trị này khi bạn chèn một mục dòng.
+ </dd>
+ <dt>
+ Cột mã định danh
+ </dt>
+ <dd>
+ <strong>Bắt buộc.</strong> Bạn phải chèn các cột mã định danh sau khi chèn
+ một mục dòng:
+ <ul>
+ <li>
+ {@link android.provider.ContactsContract.StreamItemsColumns#CONTACT_ID}: Giá trị
+ {@link android.provider.BaseColumns#_ID} của liên lạc mà mục dòng
+ này được liên kết với.
+ </li>
+ <li>
+ {@link android.provider.ContactsContract.StreamItemsColumns#CONTACT_LOOKUP_KEY}: Giá trị
+ {@link android.provider.ContactsContract.ContactsColumns#LOOKUP_KEY} của liên lạc
+ mà mục dòng này được liên kết với.
+ </li>
+ <li>
+ {@link android.provider.ContactsContract.StreamItemsColumns#RAW_CONTACT_ID}: Giá trị
+ {@link android.provider.BaseColumns#_ID} của liên lạc thô mà mục dòng này
+ được liên kết với.
+ </li>
+ </ul>
+ </dd>
+ <dt>
+ {@link android.provider.ContactsContract.StreamItemsColumns#COMMENTS}
+ </dt>
+ <dd>
+ Tùy chọn. Lưu giữ thông tin tóm tắt mà bạn có thể hiển thị ở phần đầu của một mục dòng.
+ </dd>
+ <dt>
+ {@link android.provider.ContactsContract.StreamItemsColumns#TEXT}
+ </dt>
+ <dd>
+ Văn bản của mục dòng, hoặc là nội dung đã được đăng bởi nguồn của mục đó,
+ hoặc là mô tả về một số hành động đã khởi tạo mục dòng. Cột này có thể chứa
+ bất kỳ hình ảnh tài nguyên định dạng và được nhúng nào mà có thể được kết xuất bởi
+ {@link android.text.Html#fromHtml(String) fromHtml()}. Trình cung cấp có thể cắt bớt hoặc
+ cắt ngắn bằng dấu ba chấm các nội dung dài, nhưng sẽ cố gắng tránh làm hỏng các tag.
+ </dd>
+ <dt>
+ {@link android.provider.ContactsContract.StreamItemsColumns#TIMESTAMP}
+ </dt>
+ <dd>
+ Xâu văn bản chứa thời gian mà mục dòng được chèn hoặc cập nhật, có
+ dạng <em>mili giây</em> trôi qua kể từ giờ epoch. Những ứng dụng chèn hoặc cập nhật mục dòng sẽ chịu
+ trách nhiệm duy trì cột này; nó không được tự động duy trì bởi
+ Trình cung cấp Danh bạ.
+ </dd>
+</dl>
+<p>
+ Để hiển thị thông tin nhận dạng cho các mục dòng của bạn, hãy sử dụng
+ {@link android.provider.ContactsContract.StreamItemsColumns#RES_ICON},
+ {@link android.provider.ContactsContract.StreamItemsColumns#RES_LABEL}, và
+ {@link android.provider.ContactsContract.StreamItemsColumns#RES_PACKAGE} để liên kết với các tài nguyên
+ trong ứng dụng của mình.
+</p>
+<p>
+ Bảng {@link android.provider.ContactsContract.StreamItems} chứa các cột
+ {@link android.provider.ContactsContract.StreamItemsColumns#SYNC1} thông qua
+ {@link android.provider.ContactsContract.StreamItemsColumns#SYNC4} dành riêng để sử dụng
+ trình điều hợp đồng bộ.
+</p>
+<h3 id="StreamPhotos">Ảnh từ luồng xã hội</h3>
+<p>
+ Bảng {@link android.provider.ContactsContract.StreamItemPhotos} lưu giữ ảnh được liên kết
+ với một mục dòng. Cột
+ {@link android.provider.ContactsContract.StreamItemPhotosColumns#STREAM_ITEM_ID} của bảng
+ liên kết với các giá trị trong {@link android.provider.BaseColumns#_ID} của bảng
+ {@link android.provider.ContactsContract.StreamItems}. Các tham chiếu ảnh được lưu giữ trong
+ bảng ở những cột này:
+</p>
+<dl>
+ <dt>
+ Cột {@link android.provider.ContactsContract.StreamItemPhotos#PHOTO} (một BLOB).
+ </dt>
+ <dd>
+ Biểu diễn dạng nhị phân của ảnh, được trình cung cấp đổi kích cỡ để lưu giữ và hiển thị.
+ Cột này có sẵn để tương thích ngược với các phiên bản trước của Trình cung cấp
+ Danh bạ mà đã sử dụng nó để lưu giữ ảnh. Tuy nhiên, trong phiên bản hiện tại
+ bạn không nên sử dụng cột này để lưu giữ ảnh. Thay vào đó, hãy sử dụng
+ hoặc {@link android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_FILE_ID} hoặc
+ {@link android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_URI} (cả hai
+ đều được mô tả trong các điểm sau) để lưu giữ ảnh trong một tệp. Lúc này, cột này
+ chứa một hình thu nhỏ của ảnh sẵn sàng để đọc.
+ </dd>
+ <dt>
+ {@link android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_FILE_ID}
+ </dt>
+ <dd>
+ Một mã định danh dạng số của ảnh cho một liên lạc thô. Nối giá trị này với hằng số
+ {@link android.provider.ContactsContract.DisplayPhoto#CONTENT_URI DisplayPhoto.CONTENT_URI}
+ để nhận một URI nội dung trỏ về một tệp ảnh đơn, rồi gọi
+ {@link android.content.ContentResolver#openAssetFileDescriptor(Uri, String)
+ openAssetFileDescriptor()} để nhận một điều khiển (handle) cho tệp ảnh.
+ </dd>
+ <dt>
+ {@link android.provider.ContactsContract.StreamItemPhotosColumns#PHOTO_URI}
+ </dt>
+ <dd>
+ Một URI nội dung trỏ trực tiếp tới tệp ảnh cho ảnh được đại diện bởi hàng này.
+ Gọi {@link android.content.ContentResolver#openAssetFileDescriptor(Uri, String)
+ openAssetFileDescriptor()} bằng URI này để nhận một điều khiển (handle) cho tệp ảnh.
+ </dd>
+</dl>
+<h3 id="SocialStreamTables">Sử dụng các bảng luồng xã hội</h3>
+<p>
+ Những bảng này hoạt động giống như các bảng chính khác trong Trình cung cấp Danh bạ, ngoại trừ:
+</p>
+ <ul>
+ <li>
+ Những bảng này yêu cầu quyền truy cập bổ sung. Để đọc từ chúng, ứng dụng của bạn
+ phải có quyền {@link android.Manifest.permission#READ_SOCIAL_STREAM}. Để
+ sửa đổi chúng, ứng dụng của bạn phải có quyền
+ {@link android.Manifest.permission#WRITE_SOCIAL_STREAM}.
+ </li>
+ <li>
+ Đối với bảng {@link android.provider.ContactsContract.StreamItems}, số hàng
+ được lưu giữ cho mỗi liên lạc thô sẽ bị giới hạn. Sau khi đạt đến giới hạn này,
+ Trình cung cấp Danh bạ sẽ tạo khoảng trống cho các hàng mục dòng mới bằng cách tự động xóa
+ những hàng có
+ {@link android.provider.ContactsContract.StreamItemsColumns#TIMESTAMP} lâu nhất. Để nhận
+ giới hạn, hãy phát hành một truy vấn tới URI nội dung
+ {@link android.provider.ContactsContract.StreamItems#CONTENT_LIMIT_URI}. Bạn có thể để
+ tất cả các tham đối khác ngoài URI nội dung được đặt về <code>null</code>. Truy vấn
+ trả về một Con chạy chứa một hàng đơn, với cột đơn
+ {@link android.provider.ContactsContract.StreamItems#MAX_ITEMS}.
+ </li>
+ </ul>
+
+<p>
+ Lớp {@link android.provider.ContactsContract.StreamItems.StreamItemPhotos} định nghĩa một
+ bảng con {@link android.provider.ContactsContract.StreamItemPhotos} chứa các hàng ảnh
+ cho một mục dòng đơn.
+</p>
+<h3 id="SocialStreamInteraction">Tương tác từ luồng xã hội</h3>
+<p>
+ Dữ liệu từ luồng xã hội được quản lý bởi Trình cung cấp Danh bạ, kết hợp với
+ ứng dụng danh bạ của thiết bị, cung cấp một cách hiệu quả để kết nối hệ thống mạng xã hội của bạn
+ với các liên lạc hiện tại. Có sẵn những tính năng sau:
+</p>
+ <ul>
+ <li>
+ Bằng cách đồng bộ dịch vụ mạng xã hội của bạn với Trình cung cấp Danh bạ bằng một trình điều hợp
+ đồng bộ, bạn có thể truy xuất hoạt động gần đây đối với danh bạ của một người dùng và lưu giữ nó trong
+ các bảng {@link android.provider.ContactsContract.StreamItems} và
+ {@link android.provider.ContactsContract.StreamItemPhotos} để sử dụng sau.
+ </li>
+ <li>
+ Bên cạnh việc đồng bộ hoá thường xuyên, bạn có thể kích khởi trình điều hợp đồng bộ của mình để truy xuất
+ dữ liệu bổ sung khi người dùng chọn một liên lạc để xem. Điều này cho phép trình điều hợp đồng bộ của bạn
+ truy xuất ảnh độ phân giải cao và các mục dòng gần đây nhất cho liên lạc đó.
+ </li>
+ <li>
+ Bằng cách đăng ký một thông báo với ứng dụng danh bạ của thiết bị và Trình cung cấp
+ Danh bạ, bạn có thể <em>nhận</em> một ý định khi một liên lạc được xem, và tại thời điểm đó,
+ cập nhật trạng thái của liên lạc đó từ dịch vụ của bạn. Phương pháp này có thể nhanh hơn và sử dụng ít
+ băng thông hơn việc thực hiện đồng bộ đầy đủ với một trình điều hợp đồng bộ.
+ </li>
+ <li>
+ Người dùng có thể thêm một liên lạc vào dịch vụ mạng xã hội của mình trong khi đang xem liên lạc đó
+ trong ứng dụng danh bạ của thiết bị. Bạn kích hoạt điều này bằng tính năng "mời liên lạc",
+ theo đó cho phép kết hợp một hoạt động để thêm một liên lạc hiện có vào mạng
+ của bạn, và một tệp XML để cung cấp cho ứng dụng danh bạ của thiết bị và
+ Trình cung cấp Danh bạ thông tin chi tiết về ứng dụng của bạn.
+ </li>
+ </ul>
+<p>
+ Đồng bộ hóa thường xuyên các mục dòng với Trình cung cấp Danh bạ giống như
+ các trường hợp đồng bộ hoá khác. Để tìm hiểu thêm về đồng bộ hoá, hãy xem phần
+ <a href="#SyncAdapters">Trình điều hợp Đồng bộ Trình cung cấp Danh bạ</a>. Việc đăng ký thông tin và
+ mời liên lạc được đề cập trong hai phần tiếp theo.
+</p>
+<h4>Đăng ký để xử lý các lượt xem mạng xã hội</h4>
+<p>
+ Để đăng ký để trình điều hợp đồng bộ của bạn nhận thông báo khi người dùng xem một liên lạc do
+ trình điều hợp đồng bộ của bạn quản lý:
+</p>
+<ol>
+ <li>
+ Tạo một tệp có tên <code>contacts.xml</code> trong thư mục <code>res/xml/</code>
+ của dự án của bạn. Nếu đã có tệp này, bạn có thể bỏ qua bước này.
+ </li>
+ <li>
+ Trong tệp này, hãy thêm phần tử
+<code>&lt;ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android"&gt;</code>.
+ Nếu phần tử này đã tồn tại, bạn có thể bỏ qua bước này.
+ </li>
+ <li>
+ Để đăng ký một dịch vụ được thông báo khi người dùng mở trang chi tiết của một liên lạc trong
+ ứng dụng danh bạ của thiết bị, hãy thêm thuộc tính
+ <code>viewContactNotifyService="<em>serviceclass</em>"</code> vào phần tử, trong đó
+ <code><em>serviceclass</em></code> là tên lớp được đáp ứng đầy đủ của dịch vụ
+ mà sẽ nhận ý định từ ứng dụng danh bạ của thiết bị. Đối với dịch vụ
+ trình thông báo, hãy sử dụng một lớp mở rộng {@link android.app.IntentService}, để cho phép dịch vụ
+ nhận các ý định. Dữ liệu trong ý định đến chứa URI nội dung của liên lạc
+ thô mà người dùng đã nhấp vào. Từ dịch vụ trình thông báo, bạn có thể gắn kết với rồi gọi trình điều hợp đồng bộ
+ của bạn để cập nhật dữ liệu cho liên lạc thô.
+ </li>
+</ol>
+<p>
+ Để đăng ký một hoạt động sẽ được gọi khi người dùng nhấp vào một mục dòng hay ảnh hoặc cả hai:
+</p>
+<ol>
+ <li>
+ Tạo một tệp có tên <code>contacts.xml</code> trong thư mục <code>res/xml/</code>
+ của dự án của bạn. Nếu đã có tệp này, bạn có thể bỏ qua bước này.
+ </li>
+ <li>
+ Trong tệp này, hãy thêm phần tử
+<code>&lt;ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android"&gt;</code>.
+ Nếu phần tử này đã tồn tại, bạn có thể bỏ qua bước này.
+ </li>
+ <li>
+ Để đăng ký một trong các hoạt động của bạn sẽ xử lý khi người dùng nhấp vào một mục dòng trong
+ ứng dụng danh bạ của thiết bị, hãy thêm thuộc tính
+ <code>viewStreamItemActivity="<em>activityclass</em>"</code> vào phần tử đó, trong đó
+ <code><em>activityclass</em></code> là tên lớp được xác định đầy đủ của hoạt động
+ mà sẽ nhận ý định từ ứng dụng danh bạ của thiết bị.
+ </li>
+ <li>
+ Để đăng ký một trong các hoạt động của bạn sẽ xử lý khi người dùng nhấp vào một ảnh luồng trong
+ ứng dụng danh bạ của thiết bị, hãy thêm thuộc tính
+ <code>viewStreamItemPhotoActivity="<em>activityclass</em>"</code> vào phần tử đó, trong đó
+ <code><em>activityclass</em></code> là tên lớp được xác định đầy đủ của hoạt động
+ mà sẽ nhận ý định từ ứng dụng danh bạ của thiết bị.
+ </li>
+</ol>
+<p>
+ Phần tử <code>&lt;ContactsAccountType&gt;</code> được mô tả chi tiết hơn trong mục
+ phần tử <a href="#SocialStreamAcctType">&lt;ContactsAccountType&gt;</a>.
+</p>
+<p>
+ Ý định đến chứa URI nội dung của mục hoặc ảnh mà người dùng đã nhấp vào.
+ Để có các hoạt động riêng cho các mục văn bản và ảnh, hãy sử dụng cả hai thuộc tính trong cùng tệp.
+</p>
+<h4>Tương tác với dịch vụ mạng xã hội của bạn</h4>
+<p>
+ Người dùng không phải rời ứng dụng danh bạ của thiết bị để mời một liên lạc tới trang mạng xã hội
+ của bạn. Thay vào đó, bạn có thể thiết đặt để ứng dụng danh bạ của thiết bị gửi một ý định để mời
+ liên lạc đó tới một trong các hoạt động của mình. Để thiết đặt điều này:
+</p>
+<ol>
+ <li>
+ Tạo một tệp có tên <code>contacts.xml</code> trong thư mục <code>res/xml/</code>
+ của dự án của bạn. Nếu đã có tệp này, bạn có thể bỏ qua bước này.
+ </li>
+ <li>
+ Trong tệp này, hãy thêm phần tử
+<code>&lt;ContactsAccountType xmlns:android="http://schemas.android.com/apk/res/android"&gt;</code>.
+ Nếu phần tử này đã tồn tại, bạn có thể bỏ qua bước này.
+ </li>
+ <li>
+ Thêm các thuộc tính sau:
+ <ul>
+ <li><code>inviteContactActivity="<em>activityclass</em>"</code></li>
+ <li>
+ <code>inviteContactActionLabel="&#64;string/<em>invite_action_label</em>"</code>
+ </li>
+ </ul>
+ Giá trị <code><em>activityclass</em></code> là tên lớp được xác định đầy đủ của hoạt động
+ mà sẽ nhận được ý định. Giá trị <code><em>invite_action_label</em></code>
+ là một xâu văn bản được hiển thị trong menu <strong>Thêm Kết nối</strong> trong ứng dụng danh bạ
+ của thiết bị.
+ </li>
+</ol>
+<p class="note">
+ <strong>Lưu ý:</strong> <code>ContactsSource</code> là một tên tag không được chấp nhận đối với
+ <code>ContactsAccountType</code>.
+</p>
+<h3 id="ContactsFile">Tham chiếu contacts.xml</h3>
+<p>
+ Tệp <code>contacts.xml</code> chứa các phần tử XML có chức năng kiểm soát tương tác giữa
+ trình điều hợp đồng bộ và ứng dụng của bạn với ứng dụng danh bạ và Trình cung cấp Danh bạ. Những
+ phần tử này được mô tả trong các mục sau.
+</p>
+<h4 id="SocialStreamAcctType">Thành phần &lt;ContactsAccountType&gt;</h4>
+<p>
+ Phần tử <code>&lt;ContactsAccountType&gt;</code> kiểm soát tương tác giữa
+ ứng dụng của bạn với ứng dụng danh bạ. Nó có những cú pháp sau:
+</p>
+<pre>
+&lt;ContactsAccountType
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ inviteContactActivity="<em>activity_name</em>"
+ inviteContactActionLabel="<em>invite_command_text</em>"
+ viewContactNotifyService="<em>view_notify_service</em>"
+ viewGroupActivity="<em>group_view_activity</em>"
+ viewGroupActionLabel="<em>group_action_text</em>"
+ viewStreamItemActivity="<em>viewstream_activity_name</em>"
+ viewStreamItemPhotoActivity="<em>viewphotostream_activity_name</em>"&gt;
+</pre>
+<p>
+ <strong>chứa trong:</strong>
+</p>
+<p>
+ <code>res/xml/contacts.xml</code>
+</p>
+<p>
+ <strong>có thể chứa:</strong>
+</p>
+<p>
+ <strong><code>&lt;ContactsDataKind&gt;</code></strong>
+</p>
+<p>
+ <strong>Mô tả:</strong>
+</p>
+<p>
+ Khai báo các thành phần Android và nhãn UI mà cho phép người dùng mời một trong các liên lạc của mình đến
+ một mạng xã hội, thông báo người dùng khi một trong các luồng mạng xã hội của họ được cập nhật,
+ v.v.
+</p>
+<p>
+ Để ý rằng tiền tố thuộc tính <code>android:</code> không nhất thiết áp dụng cho các thuộc tính
+ của <code>&lt;ContactsAccountType&gt;</code>.
+</p>
+<p>
+ <strong>Thuộc tính:</strong>
+</p>
+<dl>
+ <dt>{@code inviteContactActivity}</dt>
+ <dd>
+ Tên lớp được xác định đầy đủ của hoạt động trong ứng dụng của bạn mà bạn muốn
+ kích hoạt khi người dùng chọn <strong>Thêm kết nối</strong> từ ứng dụng danh bạ
+ của thiết bị.
+ </dd>
+ <dt>{@code inviteContactActionLabel}</dt>
+ <dd>
+ Một xâu văn bản được hiển thị cho hoạt động được quy định trong
+ {@code inviteContactActivity}, trong menu <strong>Thêm kết nối</strong>.
+ Ví dụ, bạn có thể sử dụng xâu "Follow in my network". Bạn có thể sử dụng mã định danh
+ tài nguyên xâu cho nhãn này.
+ </dd>
+ <dt>{@code viewContactNotifyService}</dt>
+ <dd>
+ Tên lớp được xác định đầy đủ của một dịch vụ trong ứng dụng của bạn mà sẽ nhận được
+ thông báo khi người dùng xem một liên lạc. Thông báo này được gửi từ ứng dụng danh bạ
+ của thiết bị; nó cho phép ứng dụng của bạn tạm hoãn các thao tác dùng nhiều dữ liệu tới
+ khi cần. Ví dụ, ứng dụng của bạn có thể hồi đáp lại thông báo này
+ bằng cách đọc và hiển thị ảnh độ phân giải cao của danh bạ và các mục dòng mạng xã hội
+ gần đây nhất. Tính năng này được mô tả chi tiết hơn trong phần
+ <a href="#SocialStreamInteraction">Tương tác với luồng xã hội</a>. Bạn có thể thấy một
+ ví dụ về dịch vụ thông báo trong tệp <code>NotifierService.java</code> trong ứng dụng mẫu
+ <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">SampleSyncAdapter</a>
+.
+ </dd>
+ <dt>{@code viewGroupActivity}</dt>
+ <dd>
+ Tên lớp được xác định đầy đủ của một hoạt động trong ứng dụng của bạn mà có thể
+ hiển thị thông tin nhóm. Khi người dùng nhấp vào nhãn nhóm trong ứng dụng danh bạ
+ của thiết bị, UI cho hoạt động này sẽ được hiển thị.
+ </dd>
+ <dt>{@code viewGroupActionLabel}</dt>
+ <dd>
+ Nhãn mà ứng dụng danh bạ hiển thị cho một điều khiển UI có cho phép
+ người dùng xem các nhóm trong ứng dụng của bạn.
+ <p>
+ Ví dụ, nếu bạn cài đặt ứng dụng Google+ trên thiết bị của mình và bạn đồng bộ
+ Google+ với ứng dụng danh bạ, bạn sẽ thấy các vòng tròn Google+ được liệt kê thành các nhóm
+ trong tab <strong>Nhóm</strong> của ứng dụng danh bạ của bạn. Nếu bạn nhấp vào một vòng tròn
+ Google+, bạn sẽ thấy những người trong vòng tròn đó được liệt kê thành một "nhóm". Phía bên trên của
+ hiển thị, bạn sẽ thấy một biểu tượng Google+; nếu bạn nhấp vào đó, điều khiển sẽ chuyển sang ứng dụng
+ Google+. Ứng dụng danh bạ làm điều này bằng
+ {@code viewGroupActivity}, bằng cách sử dụng biểu tượng Google+ làm giá trị của
+ {@code viewGroupActionLabel}.
+ </p>
+ <p>
+ Một mã định danh tài nguyên xâu được cho phép cho thuộc tính này.
+ </p>
+ </dd>
+ <dt>{@code viewStreamItemActivity}</dt>
+ <dd>
+ Tên lớp được xác định đầy đủ của một hoạt động trong ứng dụng của bạn mà
+ ứng dụng danh bạ của thiết bị khởi chạy khi người dùng nhấp vào một mục dòng đối với một liên lạc thô.
+ </dd>
+ <dt>{@code viewStreamItemPhotoActivity}</dt>
+ <dd>
+ Tên lớp được xác định đầy đủ của một hoạt động trong ứng dụng của bạn mà
+ ứng dụng danh bạ của thiết bị khởi chạy khi người dùng nhấp vào một ảnh trong mục dòng
+ đối với một liên lạc thô.
+ </dd>
+</dl>
+<h4 id="SocialStreamDataKind">Phần tử &lt;ContactsDataKind&gt;</h4>
+<p>
+ Phần tử <code>&lt;ContactsDataKind&gt;</code> kiểm soát việc hiển thị các hàng
+ dữ liệu tùy chỉnh của ứng dụng của bạn trong UI của ứng dụng danh bạ. Nó có những cú pháp sau:
+</p>
+<pre>
+&lt;ContactsDataKind
+ android:mimeType="<em>MIMEtype</em>"
+ android:icon="<em>icon_resources</em>"
+ android:summaryColumn="<em>column_name</em>"
+ android:detailColumn="<em>column_name</em>"&gt;
+</pre>
+<p>
+ <strong>chứa trong:</strong>
+</p>
+<code>&lt;ContactsAccountType&gt;</code>
+<p>
+ <strong>Mô tả:</strong>
+</p>
+<p>
+ Sử dụng phần tử này để ứng dụng danh bạ hiển thị các nội dung trong một hàng dữ liệu tùy chỉnh như
+ một phần chi tiết của một liên lạc thô. Mỗi phần tử con <code>&lt;ContactsDataKind&gt;</code>
+ của <code>&lt;ContactsAccountType&gt;</code> đại diện cho một kiểu hàng dữ liệu tùy chỉnh mà trình điều hợp
+ đồng bộ của bạn thêm vào bảng {@link android.provider.ContactsContract.Data}. Thêm một phần tử
+ <code>&lt;ContactsDataKind&gt;</code> cho mỗi kiểu MIME tùy chỉnh mà bạn sử dụng. Bạn không phải
+ thêm phần tử nếu có một hàng dữ liệu tùy chỉnh mà bạn không muốn hiển thị dữ liệu.
+</p>
+<p>
+ <strong>Thuộc tính:</strong>
+</p>
+<dl>
+ <dt>{@code android:mimeType}</dt>
+ <dd>
+ Kiểu MIME tùy chỉnh mà bạn đã định nghĩa cho một trong các kiểu hàng dữ liệu tùy chỉnh của bạn trong bảng
+ {@link android.provider.ContactsContract.Data}. Ví dụ, giá trị
+ <code>vnd.android.cursor.item/vnd.example.locationstatus</code> có thể là một kiểu
+ MIME tùy chỉnh cho một hàng dữ liệu có chức năng ghi lại vị trí được biết đến cuối cùng của một liên lạc.
+ </dd>
+ <dt>{@code android:icon}</dt>
+ <dd>
+ Một tài nguyên
+ <a href="{@docRoot}guide/topics/resources/drawable-resource.html">có thể vẽ của Android</a>
+ mà ứng dụng danh bạ hiển thị bên cạnh dữ liệu của bạn. Sử dụng nó để thể hiện với
+ người dùng rằng dữ liệu xuất phát từ dịch vụ của bạn.
+ </dd>
+ <dt>{@code android:summaryColumn}</dt>
+ <dd>
+ Tên cột của giá trị thứ nhất trong hai giá trị được truy xuất từ hàng dữ liệu. Giá trị
+ được hiển thị là dòng thứ nhất của mục nhập cho hàng dữ liệu này. Dòng thứ nhất có
+ mục đích sử dụng làm bản tóm tắt dữ liệu, nhưng điều đó là tùy chọn. Xem thêm
+ <a href="#detailColumn">android:detailColumn</a>.
+ </dd>
+ <dt>{@code android:detailColumn}</dt>
+ <dd>
+ Tên cột của giá trị thứ hai trong hai giá trị được truy xuất từ hàng dữ liệu. Giá trị
+ được hiển thị là dòng thứ hai của mục nhập cho hàng dữ liệu này. Xem thêm
+ {@code android:summaryColumn}.
+ </dd>
+</dl>
+<h2 id="AdditionalFeatures">Các Tính năng Bổ sung của Trình cung cấp Danh bạ</h2>
+<p>
+ Bên cạnh các tính năng chính được mô tả trong các phần trước, Trình cung cấp Danh bạ còn cung cấp
+ những tính năng hữu ích sau khi làm việc với dữ liệu danh bạ:
+</p>
+ <ul>
+ <li>Nhóm liên lạc</li>
+ <li>Tính năng ảnh</li>
+ </ul>
+<h3 id="Groups">Nhóm liên lạc</h3>
+<p>
+ Trình cung cấp Danh bạ có thể tùy chọn đánh nhãn các bộ sưu tập liên lạc có liên quan bằng dữ liệu
+ <strong>nhóm</strong>. Nếu máy chủ liên kết với một tài khoản người dùng
+ muốn duy trì nhóm, trình điều hợp đồng bộ cho loại tài khoản của tài khoản đó sẽ chuyển
+ dữ liệu nhóm giữa Trình cung cấp Danh bạ và máy chủ. Khi người dùng thêm một liên lạc mới vào
+ máy chủ, trình điều hợp đồng bộ phải thêm nhóm mới
+ vào bảng {@link android.provider.ContactsContract.Groups}. Nhóm hoặc các nhóm mà một liên lạc
+ thô thuộc về được lưu giữ trong bảng {@link android.provider.ContactsContract.Data}, bằng cách sử dụng
+ kiểu MIME {@link android.provider.ContactsContract.CommonDataKinds.GroupMembership}.
+</p>
+<p>
+ Nếu bạn đang thiết kế một trình điều hợp đồng bộ mà sẽ thêm dữ liệu liên lạc thô từ
+ máy chủ tới Trình cung cấp Danh bạ, và bạn không sử dụng các nhóm, khi đó bạn cần báo cho
+ Trình cung cấp làm các dữ liệu của bạn thấy được. Trong đoạn mã được thực hiện khi một người dùng thêm một tài khoản
+ vào thiết bị, hãy cập nhật hàng {@link android.provider.ContactsContract.Settings}
+ mà Trình cung cấp Danh bạ thêm cho tài khoản. Trong hàng này, đặt giá trị của cột
+ {@link android.provider.ContactsContract.SettingsColumns#UNGROUPED_VISIBLE
+ Settings.UNGROUPED_VISIBLE} thành 1. Khi bạn làm vậy, Trình cung cấp Danh bạ sẽ luôn
+ làm cho dữ liệu danh bạ của bạn thấy được, ngay cả khi bạn không sử dụng nhóm.
+</p>
+<h3 id="Photos">Ảnh liên lạc</h3>
+<p>
+ Bảng {@link android.provider.ContactsContract.Data} lưu giữ ảnh thành hàng với kiểu MIME
+ {@link android.provider.ContactsContract.CommonDataKinds.Photo#CONTENT_ITEM_TYPE
+ Photo.CONTENT_ITEM_TYPE}. Cột
+ {@link android.provider.ContactsContract.RawContactsColumns#CONTACT_ID} của hàng được liên kết với cột
+ {@link android.provider.BaseColumns#_ID} của liên lạc thô mà nó thuộc về.
+ Lớp {@link android.provider.ContactsContract.Contacts.Photo} định nghĩa một bảng con của
+ {@link android.provider.ContactsContract.Contacts} chứa thông tin ảnh về ảnh chính
+ của một liên lạc, đây là ảnh chính của liên lạc thô chính của liên lạc. Tương tự,
+ lớp {@link android.provider.ContactsContract.RawContacts.DisplayPhoto} định nghĩa một bảng con
+ của {@link android.provider.ContactsContract.RawContacts} chứa thông tin ảnh đối với ảnh chính
+ của một liên lạc thô.
+</p>
+<p>
+ Tài liệu tham khảo cho {@link android.provider.ContactsContract.Contacts.Photo} và
+ {@link android.provider.ContactsContract.RawContacts.DisplayPhoto} có các ví dụ về
+ việc truy xuất thông tin ảnh. Không có lớp thuận tiện cho việc truy xuất hình thu nhỏ
+ chính đối với một liên lạc thô, nhưng bạn có thể gửi một truy vấn tới bảng
+ {@link android.provider.ContactsContract.Data}, chọn
+ {@link android.provider.BaseColumns#_ID} của liên lạc thô,
+ {@link android.provider.ContactsContract.CommonDataKinds.Photo#CONTENT_ITEM_TYPE
+ Photo.CONTENT_ITEM_TYPE}, và cột {@link android.provider.ContactsContract.Data#IS_PRIMARY}
+ để tìm hàng ảnh chính của liên lạc thô.
+</p>
+<p>
+ Dữ liệu từ luồng xã hội đối với một người cũng có thể bao gồm ảnh. Những ảnh này được lưu giữ trong bảng
+ {@link android.provider.ContactsContract.StreamItemPhotos}, được mô tả chi tiết hơn
+ trong phần <a href="#StreamPhotos">Ảnh từ luồng xã hội</a>.
+</p>
diff --git a/docs/html-intl/intl/vi/guide/topics/providers/content-provider-basics.jd b/docs/html-intl/intl/vi/guide/topics/providers/content-provider-basics.jd
new file mode 100644
index 000000000000..5f868cacf5ae
--- /dev/null
+++ b/docs/html-intl/intl/vi/guide/topics/providers/content-provider-basics.jd
@@ -0,0 +1,1196 @@
+page.title=Nội dung Cơ bản về Trình cung cấp Nội dung
+@jd:body
+<div id="qv-wrapper">
+<div id="qv">
+<!-- In this document -->
+<h2>Trong tài liệu này</h2>
+<ol>
+ <li>
+ <a href="#Basics">Tổng quan</a>
+ <ol>
+ <li>
+ <a href="#ClientProvider">Truy cập một trình cung cấp</a>
+ </li>
+ <li>
+ <a href="#ContentURIs">URI Nội dung</a>
+ </li>
+ </ol>
+ </li>
+ <li>
+ <a href="#SimpleQuery">Truy xuất Dữ liệu từ Trình cung cấp</a>
+ <ol>
+ <li>
+ <a href="#RequestPermissions">Yêu cầu quyền truy cập đọc</a>
+ </li>
+ <li>
+ <a href="#Query">Xây dựng truy vấn</a>
+ </li>
+ <li>
+ <a href="#DisplayResults">Hiển thị các kết quả truy vấn</a>
+ </li>
+ <li>
+ <a href="#GettingResults">Lấy dữ liệu từ các kết quả truy vấn</a>
+ </li>
+ </ol>
+ </li>
+ <li>
+ <a href="#Permissions">Quyền của Trình cung cấp Nội dung</a>
+ </li>
+ <li>
+ <a href="#Modifications">Chèn, Cập nhật, và Xóa Dữ liệu</a>
+ <ol>
+ <li>
+ <a href="#Inserting">Chèn dữ liệu</a>
+ </li>
+ <li>
+ <a href="#Updating">Cập nhật dữ liệu</a>
+ </li>
+ <li>
+ <a href="#Deleting">Xóa dữ liệu</a>
+ </li>
+ </ol>
+ </li>
+ <li>
+ <a href="#DataTypes">Các Kiểu Dữ liệu của Trình cung cấp</a>
+ </li>
+ <li>
+ <a href="#AltForms">Các Hình thức Truy cập Trình cung cấp Thay thế</a>
+ <ol>
+ <li>
+ <a href="#Batch">Truy cập hàng loạt</a>
+ </li>
+ <li>
+ <a href="#Intents">Truy cập dữ liệu thông qua ý định</a>
+ </li>
+ </ol>
+ </li>
+ <li>
+ <a href="#ContractClasses">Các Lớp Hợp đồng</a>
+ </li>
+ <li>
+ <a href="#MIMETypeReference">Tham khảo Kiểu MIME</a>
+ </li>
+</ol>
+
+ <!-- Key Classes -->
+<h2>Lớp khóa</h2>
+ <ol>
+ <li>
+ {@link android.content.ContentProvider}
+ </li>
+ <li>
+ {@link android.content.ContentResolver}
+ </li>
+ <li>
+ {@link android.database.Cursor}
+ </li>
+ <li>
+ {@link android.net.Uri}
+ </li>
+ </ol>
+
+ <!-- Related Samples -->
+<h2>Các Mẫu Liên quan</h2>
+ <ol>
+ <li>
+ <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/List2.html">
+ Con chạy (Danh bạ)</a>
+ </li>
+ <li>
+ <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/List7.html">
+ Con chạy (Điện thoại)</a>
+ </li>
+ </ol>
+
+ <!-- See also -->
+<h2>Xem thêm</h2>
+ <ol>
+ <li>
+ <a href="{@docRoot}guide/topics/providers/content-provider-creating.html">
+ Tạo một Trình cung cấp Nội dung</a>
+ </li>
+ <li>
+ <a href="{@docRoot}guide/topics/providers/calendar-provider.html">
+ Trình cung cấp Lịch</a>
+ </li>
+ </ol>
+</div>
+</div>
+
+ <!-- Intro paragraphs -->
+<p>
+ Trình cung cấp nội dung quản lý truy cập vào một kho dữ liệu tập trung. Trình cung cấp
+ là bộ phận của một ứng dụng Android, nó thường cung cấp UI của chính mình để làm việc cùng
+ dữ liệu. Tuy nhiên, trình cung cấp nội dung được thiết kế chủ yếu cho các ứng dụng khác
+ sử dụng, giúp truy cập trình cung cấp bằng cách sử dụng một đối tượng máy khách cung cấp. Cùng nhau, trình cung cấp
+ và máy khách cung cấp sẽ mang đến một giao diện nhất quán, tiêu chuẩn cho dữ liệu, giao diện này
+ cũng đồng thời xử lý truyền thông liên tiến trình và bảo mật truy cập dữ liệu.
+</p>
+<p>
+ Chủ đề này đề cập đến những nội dung cơ bản sau đây:
+</p>
+ <ul>
+ <li>Cách trình cung cấp nội dung hoạt động.</li>
+ <li>API bạn sử dụng để truy xuất dữ liệu từ một trình cung cấp nội dung.</li>
+ <li>API bạn sử dụng để chèn, cập nhật, hoặc xóa dữ liệu trong một trình cung cấp nội dung.</li>
+ <li>Các tính năng API khác tạo điều kiện làm việc cùng các trình cung cấp.</li>
+ </ul>
+
+ <!-- Basics -->
+<h2 id="Basics">Tổng quan</h2>
+<p>
+ Trình cung cấp nội dung trình bày dữ liệu cho các ứng dụng bên ngoài dưới dạng một hoặc nhiều bảng tương tự
+ như các bảng được tìm thấy trong một cơ sở dữ liệu quan hệ. Mỗi hàng thể hiện một thực thể của một số kiểu dữ liệu
+ mà trình cung cấp thu thập, và mỗi cột trong hàng thể hiện một phần riêng biệt của dữ liệu được thu thập
+ đối với một thực thể.
+</p>
+<p>
+ Ví dụ, một trong các trình cung cấp tích hợp trong nền tảng Android đó là từ điển người dùng, nó
+ lưu giữ chính tả của những từ phi tiêu chuẩn mà người dùng muốn giữ lại. Bảng 1 minh họa
+ cách mà dữ liệu có thể được trình bày trong bảng của trình cung cấp này:
+</p>
+<p class="table-caption">
+ <strong>Bảng 1:</strong> Bảng từ điển người dùng mẫu.
+</p>
+<table id="table1" style="width: 50%;">
+ <tr>
+ <th style="width:20%" align="center" scope="col">từ</th>
+ <th style="width:20%" align="center" scope="col">id ứng dụng</th>
+ <th style="width:20%" align="center" scope="col">tần suất</th>
+ <th style="width:20%" align="center" scope="col">bản địa</th>
+ <th style="width:20%" align="center" scope="col">_ID</th>
+ </tr>
+ <tr>
+ <td align="center" scope="row">mapreduce</td>
+ <td align="center">user1</td>
+ <td align="center">100</td>
+ <td align="center">en_US</td>
+ <td align="center">1</td>
+ </tr>
+ <tr>
+ <td align="center" scope="row">precompiler</td>
+ <td align="center">user14</td>
+ <td align="center">200</td>
+ <td align="center">fr_FR</td>
+ <td align="center">2</td>
+ </tr>
+ <tr>
+ <td align="center" scope="row">applet</td>
+ <td align="center">user2</td>
+ <td align="center">225</td>
+ <td align="center">fr_CA</td>
+ <td align="center">3</td>
+ </tr>
+ <tr>
+ <td align="center" scope="row">const</td>
+ <td align="center">user1</td>
+ <td align="center">255</td>
+ <td align="center">pt_BR</td>
+ <td align="center">4</td>
+ </tr>
+ <tr>
+ <td align="center" scope="row">int</td>
+ <td align="center">user5</td>
+ <td align="center">100</td>
+ <td align="center">en_UK</td>
+ <td align="center">5</td>
+ </tr>
+</table>
+<p>
+ Trong bảng 1, mỗi hàng thể hiện một thực thể của một từ mà có thể không thấy có
+ trong từ điển chuẩn. Mỗi cột thể hiện một số dữ liệu cho từ đó, chẳng hạn như
+ từ bản địa được dùng lần đầu cho từ đó. Tiêu đề cột là các tên cột được lưu giữ trong
+ trình cung cấp. Để tham khảo tới bản địa của một hàng, bạn tham khảo tới cột <code>locale</code> của hàng đó. Đối với
+ trình cung cấp này, cột <code>_ID</code> đóng vai trò là cột "khóa chính" mà
+ trình cung cấp tự động duy trì.
+</p>
+<p class="note">
+ <strong>Lưu ý:</strong> Trình cung cấp không bắt buộc phải có một khóa chính, và không bắt buộc phải
+ sử dụng <code>_ID</code> làm tên cột của một khóa chính nếu có khóa. Tuy nhiên,
+ nếu bạn muốn gắn kết dữ liệu từ một trình cung cấp với một {@link android.widget.ListView}, một trong các
+ tên cột sẽ phải là <code>_ID</code>. Yêu cầu này được giải thích chi tiết hơn trong
+ phần <a href="#DisplayResults">Hiển thị các kết quả truy vấn</a>.
+</p>
+<h3 id="ClientProvider">Truy cập một trình cung cấp</h3>
+<p>
+ Một ứng dụng truy cập dữ liệu từ một trình cung cấp nội dung bằng
+ một đối tượng máy khách {@link android.content.ContentResolver}. Đối tượng này có các phương pháp để gọi
+ những phương pháp có tên giống nhau trong đối tượng trình cung cấp, một thực thể của một trong những lớp con
+ cụ thể của {@link android.content.ContentProvider}. Các phương pháp
+ {@link android.content.ContentResolver} cung cấp các chức năng
+ "CRUD" (tạo, truy xuất, cập nhật, và xóa) cơ bản của thiết bị lưu trữ liên tục.
+</p>
+<p>
+ Đối tượng {@link android.content.ContentResolver} trong tiến trình
+ của ứng dụng máy khách và đối tượng {@link android.content.ContentProvider} trong ứng dụng mà sở hữu
+ trình cung cấp sẽ tự động xử lý truyền thông liên tiến trình.
+ {@link android.content.ContentProvider} cũng đóng vai trò như một lớp rút gọn giữa kho dữ liệu
+ của nó và biểu diễn bên ngoài của dữ liệu dưới dạng bảng.
+</p>
+<p class="note">
+ <strong>Lưu ý:</strong> Để truy cập một trình cung cấp, ứng dụng của bạn thường phải yêu cầu các quyền
+ cụ thể trong tệp bản kê khai của mình. Điều này được mô tả chi tiết hơn trong phần
+ <a href="#Permissions">Quyền của Trình cung cấp Nội dung</a>
+</p>
+<p>
+ Ví dụ, để có một danh sách các từ và nội dung bản địa của chúng từ Trình cung cấp Từ điển Người dùng,
+ bạn hãy gọi {@link android.content.ContentResolver#query ContentResolver.query()}.
+ Phương pháp {@link android.content.ContentResolver#query query()} sẽ gọi phương pháp
+ {@link android.content.ContentProvider#query ContentProvider.query()} được định nghĩa bởi
+ Trình cung cấp Từ điển Người dùng. Các dòng mã sau thể hiện một lệnh gọi
+ {@link android.content.ContentResolver#query ContentResolver.query()}:
+<p>
+<pre>
+// Queries the user dictionary and returns results
+mCursor = getContentResolver().query(
+ UserDictionary.Words.CONTENT_URI, // The content URI of the words table
+ mProjection, // The columns to return for each row
+ mSelectionClause // Selection criteria
+ mSelectionArgs, // Selection criteria
+ mSortOrder); // The sort order for the returned rows
+</pre>
+<p>
+ Bảng 2 cho biết các tham đối tới
+ {@link android.content.ContentResolver#query
+ query(Uri,projection,selection,selectionArgs,sortOrder)} khớp với một câu lệnh SQL SELECT như thế nào:
+</p>
+<p class="table-caption">
+ <strong>Bảng 2:</strong> Query() so với truy vấn SQL.
+</p>
+<table id="table2" style="width: 75%;">
+ <tr>
+ <th style="width:25%" align="center" scope="col">tham đối query()</th>
+ <th style="width:25%" align="center" scope="col">Từ khóa/tham số SELECT</th>
+ <th style="width:50%" align="center" scope="col">Lưu ý</th>
+ </tr>
+ <tr>
+ <td align="center"><code>Uri</code></td>
+ <td align="center"><code>FROM <em>table_name</em></code></td>
+ <td><code>Uri</code> ánh xạ tới bảng trong trình cung cấp có tên <em>table_name</em>.</td>
+ </tr>
+ <tr>
+ <td align="center"><code>projection</code></td>
+ <td align="center"><code><em>col,col,col,...</em></code></td>
+ <td>
+ <code>projection</code> là một mảng gồm các cột nên được đưa vào đối với mỗi hàng
+ được truy xuất.
+ </td>
+ </tr>
+ <tr>
+ <td align="center"><code>selection</code></td>
+ <td align="center"><code>WHERE <em>col</em> = <em>value</em></code></td>
+ <td><code>selection</code> quy định các tiêu chí để lựa chọn hàng.</td>
+ </tr>
+ <tr>
+ <td align="center"><code>selectionArgs</code></td>
+ <td align="center">
+ (Không có sự tương đương chính xác. Các tham đối lựa chọn sẽ thay thế các chỗ dành sẵn <code>?</code> trong
+ mệnh đề lựa chọn.)
+ </td>
+ </tr>
+ <tr>
+ <td align="center"><code>sortOrder</code></td>
+ <td align="center"><code>ORDER BY <em>col,col,...</em></code></td>
+ <td>
+ <code>sortOrder</code> quy định thứ tự các hàng xuất hiện trong
+ {@link android.database.Cursor} được trả về.
+ </td>
+ </tr>
+</table>
+<h3 id="ContentURIs">URI Nội dung</h3>
+<p>
+ <strong>URI nội dung</strong> là một URI xác định dữ liệu trong một trình cung cấp. URI nội dung
+ bao gồm tên biểu tượng của toàn bộ trình cung cấp (<strong>quyền</strong> của nó) và một
+ tên trỏ đến một bảng (<strong>đường dẫn</strong>). Khi bạn gọi
+ một phương pháp máy khách để truy cập một bảng trong một trình cung cấp, URI nội dung cho bảng là một trong các
+ tham đối.
+</p>
+<p>
+ Trong các dòng mã trước, hằng số
+ {@link android.provider.UserDictionary.Words#CONTENT_URI} chứa URI nội dung của
+ bảng "từ" của từ điển người dùng. Đối tượng {@link android.content.ContentResolver}
+ sẽ phân tích quyền của URI, và sử dụng nó để "giải quyết" trình cung cấp bằng cách
+ so sánh quyền với một bảng hệ thống của các trình cung cấp đã biết. Khi đó,
+ {@link android.content.ContentResolver} có thể phân phối các tham đối truy vấn tới đúng
+ trình cung cấp.
+</p>
+<p>
+ {@link android.content.ContentProvider} sử dụng phần đường dẫn của URI nội dung nhằm chọn
+ bảng để truy cập. Trình cung cấp thường có một <strong>đường dẫn</strong> cho mỗi bảng mà nó hiện ra.
+</p>
+<p>
+ Trong các dòng mã trước, URI đầy đủ cho bảng "từ" là:
+</p>
+<pre>
+content://user_dictionary/words
+</pre>
+<p>
+ trong đó xâu <code>user_dictionary</code> là quyền của trình cung cấp, và
+xâu <code>words</code> là đường dẫn của bảng. Xâu
+ <code>content://</code> (<strong>lược đồ</strong>) sẽ luôn có mặt,
+ và xác định đây là một URI nội dung.
+</p>
+<p>
+ Nhiều trình cung cấp cho phép bạn truy cập một hàng đơn lẻ trong một bảng bằng cách nối một giá trị ID
+ với đuôi của URI. Ví dụ, để truy xuất một hàng có <code>_ID</code> là
+ <code>4</code> từ một từ điển người dùng, bạn có thể sử dụng URI nội dung này:
+</p>
+<pre>
+Uri singleUri = ContentUris.withAppendedId(UserDictionary.Words.CONTENT_URI,4);
+</pre>
+<p>
+ Bạn thường sử dụng các giá trị id khi bạn đã truy xuất một tập hợp các hàng, sau đó muốn cập nhật hoặc xóa
+ một trong số chúng.
+</p>
+<p class="note">
+ <strong>Lưu ý:</strong> Các lớp {@link android.net.Uri} và {@link android.net.Uri.Builder}
+ chứa các phương pháp thuận tiện để xây dựng đối tượng URI định dạng tốt từ các xâu.
+ {@link android.content.ContentUris} chứa các phương pháp thuận tiện để nối các giá trị id với
+ một URI. Đoạn mã HTML trước sử dụng {@link android.content.ContentUris#withAppendedId
+withAppendedId()} để nối một id với URI nội dung Từ điển Người dùng.
+</p>
+
+
+ <!-- Retrieving Data from the Provider -->
+<h2 id="SimpleQuery">Truy xuất Dữ liệu từ Trình cung cấp</h2>
+<p>
+ Phần này mô tả cách truy xuất dữ liệu từ một trình cung cấp bằng cách sử dụng Trình cung cấp Từ điển Người dùng
+ làm ví dụ.
+</p>
+<p class="note">
+ Để giải thích rõ, đoạn mã HTML trong phần này gọi
+ {@link android.content.ContentResolver#query ContentResolver.query()} trên "luồng UI"". Tuy nhiên, trong
+ mã thực sự, bạn nên thực hiện các truy vấn không đồng bộ trên một luồng riêng. Một cách để làm
+ điều này đó là sử dụng lớp {@link android.content.CursorLoader}, nó được mô tả chi tiết hơn
+ trong hướng dẫn <a href="{@docRoot}guide/components/loaders.html">
+ Trình tải</a>. Bênh cạnh đó, các dòng mã chỉ là đoạn mã HTML; chúng không thể hiện một ứng dụng
+ hoàn chỉnh.
+</p>
+<p>
+ Để truy xuất dữ liệu từ một trình cung cấp, hãy làm theo các bước cơ bản sau:
+</p>
+<ol>
+ <li>
+ Yêu cầu quyền truy cập đọc cho trình cung cấp.
+ </li>
+ <li>
+ Định nghĩa mã để gửi một truy vấn tới trình cung cấp.
+ </li>
+</ol>
+<h3 id="RequestPermissions">Yêu cầu quyền truy cập đọc</h3>
+<p>
+ Để truy xuất dữ liệu từ một trình cung cấp, ứng dụng của bạn cần "quyền truy cập đọc" cho
+ trình cung cấp. Bạn không thể yêu cầu quyền này trong thời gian chạy; thay vào đó, bạn phải chỉ định rằng
+ bạn cần quyền này trong bản kê khai của mình bằng cách sử dụng phần tử
+<code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission&gt;</a></code>
+ và tên quyền chính xác được định nghĩa bởi
+ trình cung cấp. Khi bạn chỉ định phần tử này trong bản kê khai của mình, bạn đang thực tế hóa "yêu cầu" quyền
+ này cho ứng dụng của mình. Khi người dùng cài đặt ứng dụng của bạn, họ ngầm hiểu cấp
+ yêu cầu này.
+</p>
+<p>
+ Để tìm tên chính xác của quyền truy cập đọc cho trình cung cấp bạn đang sử dụng, cũng như
+ tên cho các quyền truy cập khác được sử dụng bởi trình truy cập, hãy xem trong tài liệu
+ của trình cung cấp.
+</p>
+<p>
+ Vai trò của quyền trong việc truy cập các trình cung cấp được mô tả chi tiết hơn trong phần
+ <a href="#Permissions">Quyền của Trình cung cấp Nội dung</a>.
+</p>
+<p>
+ Trình cung cấp Từ điển Người dùng sẽ định nghĩa quyền
+ <code>android.permission.READ_USER_DICTIONARY</code> trong tệp bản kê khai của nó, vì vậy một
+ ứng dụng muốn đọc từ trình cung cấp sẽ phải yêu cầu quyền này.
+</p>
+<!-- Constructing the query -->
+<h3 id="Query">Xây dựng truy vấn</h3>
+<p>
+ Bước tiếp theo trong việc truy xuất dữ liệu từ một trình cung cấp đó là xây dựng một truy vấn. Đoạn mã HTML đầu tiên
+ này định nghĩa một số biến cho việc truy cập Trình cung cấp Từ điển Người dùng:
+</p>
+<pre class="prettyprint">
+
+// A "projection" defines the columns that will be returned for each row
+String[] mProjection =
+{
+ UserDictionary.Words._ID, // Contract class constant for the _ID column name
+ UserDictionary.Words.WORD, // Contract class constant for the word column name
+ UserDictionary.Words.LOCALE // Contract class constant for the locale column name
+};
+
+// Defines a string to contain the selection clause
+String mSelectionClause = null;
+
+// Initializes an array to contain selection arguments
+String[] mSelectionArgs = {""};
+
+</pre>
+<p>
+ Đoạn mã HTML tiếp theo cho biết cách sử dụng
+ {@link android.content.ContentResolver#query ContentResolver.query()}, bằng cách sử dụng Trình cung cấp Từ điển
+ Người dùng như một ví dụ. Truy vấn máy khách trình cung cấp tương tự như một truy vấn SQL, và nó chứa một
+ tập hợp các cột để trả về, một tập hợp các tiêu chí lựa chọn, và một thứ tự sắp xếp.
+</p>
+<p>
+ Tập hợp các cột mà truy vấn cần trả về được gọi là <strong>dự thảo</strong>
+ (biến <code>mProjection</code>).
+</p>
+<p>
+ Biểu thức để chỉ định các hàng cần truy xuất sẽ được chia thành một mệnh đề lựa chọn và
+ tham đối lựa chọn. Mệnh đề lựa chọn là sự kết hợp giữa các biểu thức lô-gic và biểu thức Boolean,
+ tên cột, và giá trị (biến <code>mSelectionClause</code>). Nếu bạn chỉ định
+ tham số thay thế được <code>?</code> thay vì một giá trị, phương pháp truy vấn sẽ truy xuất giá trị
+ từ mảng tham đối lựa chọn (biến <code>mSelectionArgs</code>).
+</p>
+<p>
+ Trong đoạn mã HTML tiếp theo, nếu người dùng không điền từ thì mệnh đề lựa chọn được đặt thành
+ <code>null</code>, và truy vấn trả về tất cả các từ trong trình cung cấp. Nếu người dùng nhập
+ một từ, mệnh đề lựa chọn được đặt thành <code>UserDictionary.Words.WORD + " = ?"</code> và
+ phần tử đầu tiên của mảng tham đối lựa chọn được đặt thành từ mà người dùng đã nhập.
+</p>
+<pre class="prettyprint">
+/*
+ * This defines a one-element String array to contain the selection argument.
+ */
+String[] mSelectionArgs = {""};
+
+// Gets a word from the UI
+mSearchString = mSearchWord.getText().toString();
+
+// Remember to insert code here to check for invalid or malicious input.
+
+// If the word is the empty string, gets everything
+if (TextUtils.isEmpty(mSearchString)) {
+ // Setting the selection clause to null will return all words
+ mSelectionClause = null;
+ mSelectionArgs[0] = "";
+
+} else {
+ // Constructs a selection clause that matches the word that the user entered.
+ mSelectionClause = UserDictionary.Words.WORD + " = ?";
+
+ // Moves the user's input string to the selection arguments.
+ mSelectionArgs[0] = mSearchString;
+
+}
+
+// Does a query against the table and returns a Cursor object
+mCursor = getContentResolver().query(
+ UserDictionary.Words.CONTENT_URI, // The content URI of the words table
+ mProjection, // The columns to return for each row
+ mSelectionClause // Either null, or the word the user entered
+ mSelectionArgs, // Either empty, or the string the user entered
+ mSortOrder); // The sort order for the returned rows
+
+// Some providers return null if an error occurs, others throw an exception
+if (null == mCursor) {
+ /*
+ * Insert code here to handle the error. Be sure not to use the cursor! You may want to
+ * call android.util.Log.e() to log this error.
+ *
+ */
+// If the Cursor is empty, the provider found no matches
+} else if (mCursor.getCount() &lt; 1) {
+
+ /*
+ * Insert code here to notify the user that the search was unsuccessful. This isn't necessarily
+ * an error. You may want to offer the user the option to insert a new row, or re-type the
+ * search term.
+ */
+
+} else {
+ // Insert code here to do something with the results
+
+}
+</pre>
+<p>
+ Truy vấn này tương tự như câu lệnh SQL:
+</p>
+<pre>
+SELECT _ID, word, locale FROM words WHERE word = &lt;userinput&gt; ORDER BY word ASC;
+</pre>
+<p>
+ Trong câu lệnh SQL này, tên cột thực tế được sử dụng thay vì các hằng số lớp hợp đồng.
+</p>
+<h4 id="Injection">Bảo vệ trước mục nhập độc hại</h4>
+<p>
+ Nếu dữ liệu được quản lý bởi trình cung cấp nội dung nằm trong một cơ sở dữ liệu SQL, việc điền dữ liệu không được tin cậy từ bên ngoài
+ vào các câu lệnh SQL thô có thể dẫn đến tiêm lỗi SQL.
+</p>
+<p>
+ Hãy xét mệnh đề lựa chọn sau:
+</p>
+<pre>
+// Constructs a selection clause by concatenating the user's input to the column name
+String mSelectionClause = "var = " + mUserInput;
+</pre>
+<p>
+ Nếu bạn làm vậy, bạn đang cho phép người dùng ghép nối SQL độc hại lên câu lệnh SQL của mình.
+ Ví dụ, người dùng có thể điền "nothing; DROP TABLE *;" cho <code>mUserInput</code>, làm vậy
+ sẽ dẫn đến mệnh đề lựa chọn <code>var = nothing; DROP TABLE *;</code>. Do
+ mệnh đề lựa chọn được coi như một câu lệnh SQL, điều này có thể khiến trình cung cấp xóa tất cả
+ bảng trong cơ sở dữ liệu SQLite cơ bản (trừ khi trình cung cấp được thiết lập để bắt những lần thử
+ <a href="http://en.wikipedia.org/wiki/SQL_injection">tiêm lỗi SQL</a>).
+</p>
+<p>
+ Để tránh vấn đề này, hãy sử dụng một mệnh đề lựa chọn mà sử dụng <code>?</code> làm tham số
+ thay thế được và một mảng các tham đối lựa chọn riêng. Khi bạn làm như vậy, mục nhập của người dùng
+ được gắn kết trực tiếp với truy vấn thay vì được giải nghĩa như một phần của câu lệnh SQL.
+ Vì nó không được coi như SQL, mục nhập của người dùng không thể tiêm lỗi SQL độc hại. Thay vì sử dụng
+ ghép nối để điền mục nhập của người dùng, hãy sử dụng mệnh đề lựa chọn này:
+</p>
+<pre>
+// Constructs a selection clause with a replaceable parameter
+String mSelectionClause = "var = ?";
+</pre>
+<p>
+ Thiết lập mảng các tham đối lựa chọn như sau:
+</p>
+<pre>
+// Defines an array to contain the selection arguments
+String[] selectionArgs = {""};
+</pre>
+<p>
+ Đặt một giá trị trong mảng các tham đối lựa chọn như sau:
+</p>
+<pre>
+// Sets the selection argument to the user's input
+selectionArgs[0] = mUserInput;
+</pre>
+<p>
+ Mệnh đề lựa chọn mà sử dụng <code>?</code> như một tham số thay thế được và một mảng
+ các tham đối lựa chọn là cách được ưu tiên để chỉ định một lựa chọn, ngay cả khi trình cung cấp không
+ được dựa trên cơ sở dữ liệu SQL.
+</p>
+<!-- Displaying the results -->
+<h3 id="DisplayResults">Hiển thị các kết quả truy vấn</h3>
+<p>
+ Phương pháp máy khách {@link android.content.ContentResolver#query ContentResolver.query()} luôn trả về
+ một {@link android.database.Cursor} chứa các cột được chỉ định bởi dự thảo của
+ truy vấn cho các hàng khớp với các tiêu chí lựa chọn của truy vấn. Một đối tượng
+ {@link android.database.Cursor} cung cấp truy cập đọc ngẫu nhiên vào các hàng và cột mà nó
+ chứa. Bằng cách sử dụng phương pháp {@link android.database.Cursor}, bạn có thể lặp lại các hàng trong
+ kết quả, xác định kiểu dữ liệu của từng cột, lấy dữ liệu ra khỏi cột, và kiểm tra các tính chất khác
+ của kết quả. Một số triển khai {@link android.database.Cursor} sẽ tự động
+ cập nhật đối tượng khi dữ liệu của trình cung cấp thay đổi, hoặc kích khởi các phương pháp trong một đối tượng quan sát
+ khi {@link android.database.Cursor} thay đổi, hoặc cả hai.
+</p>
+<p class="note">
+ <strong>Lưu ý:</strong> Một trình cung cấp có thể hạn chế truy cập vào các cột dựa trên tính chất của
+ đối tượng thực hiện truy vấn. Ví dụ, Trình cung cấp Danh bạ hạn chế truy cập đối với một số cột cho
+ các trình điều hợp đồng bộ, vì thế nó sẽ không trả chúng về một hoạt động hay dịch vụ.
+</p>
+<p>
+ Nếu không hàng nào khớp với các tiêu chí lựa chọn, trình cung cấp
+ sẽ trả về một đối tượng {@link android.database.Cursor} mà trong đó
+ {@link android.database.Cursor#getCount Cursor.getCount()} bằng 0 (con chạy trống).
+</p>
+<p>
+ Nếu xảy ra một lỗi nội bộ, các kết quả của truy vấn sẽ phụ thuộc vào trình cung cấp cụ thể. Nó có thể
+ chọn trả về <code>null</code>, hoặc nó có thể đưa ra một lỗi {@link java.lang.Exception}.
+</p>
+<p>
+ Do {@link android.database.Cursor} là một "danh sách" hàng, một cách hay để hiển thị
+ nội dung của một {@link android.database.Cursor} đó là liên kết nó với một {@link android.widget.ListView}
+ thông qua một {@link android.widget.SimpleCursorAdapter}.
+</p>
+<p>
+ Đoạn mã HTML sau tiếp tục từ đoạn mã HTML trước. Nó tạo một đối tượng
+ {@link android.widget.SimpleCursorAdapter} chứa {@link android.database.Cursor}
+ được truy xuất bởi truy vấn, và đặt đối tượng này thành trình điều hợp cho một
+ {@link android.widget.ListView}:
+</p>
+<pre class="prettyprint">
+// Defines a list of columns to retrieve from the Cursor and load into an output row
+String[] mWordListColumns =
+{
+ UserDictionary.Words.WORD, // Contract class constant containing the word column name
+ UserDictionary.Words.LOCALE // Contract class constant containing the locale column name
+};
+
+// Defines a list of View IDs that will receive the Cursor columns for each row
+int[] mWordListItems = { R.id.dictWord, R.id.locale};
+
+// Creates a new SimpleCursorAdapter
+mCursorAdapter = new SimpleCursorAdapter(
+ getApplicationContext(), // The application's Context object
+ R.layout.wordlistrow, // A layout in XML for one row in the ListView
+ mCursor, // The result from the query
+ mWordListColumns, // A string array of column names in the cursor
+ mWordListItems, // An integer array of view IDs in the row layout
+ 0); // Flags (usually none are needed)
+
+// Sets the adapter for the ListView
+mWordList.setAdapter(mCursorAdapter);
+</pre>
+<p class="note">
+ <strong>Lưu ý:</strong> Để lùi {@link android.widget.ListView} bằng một
+ {@link android.database.Cursor}, con chạy phải chứa một cột có tên <code>_ID</code>.
+ Vì điều này, truy vấn được hiện lúc trước truy xuất cột <code>_ID</code> cho
+ bảng "từ" mặc dù {@link android.widget.ListView} không hiển thị nó.
+ Hạn chế này cũng giải thích lý do tại sao phần lớn trình cung cấp đều có một cột <code>_ID</code> cho mỗi
+ bảng của nó.
+</p>
+
+ <!-- Getting data from query results -->
+<h3 id="GettingResults">Lấy dữ liệu từ các kết quả truy vấn</h3>
+<p>
+ Thay vì chỉ hiển thị các kết quả truy vấn, bạn có thể sử dụng chúng cho các tác vụ khác. Ví
+ dụ, bạn có thể truy xuất chính tả từ một từ điển người dùng, rồi sau đó tìm kiếm từ đó trong
+ các trình cung cấp khác. Để làm điều này, bạn lặp lại các hàng trong {@link android.database.Cursor}:
+</p>
+<pre class="prettyprint">
+
+// Determine the column index of the column named "word"
+int index = mCursor.getColumnIndex(UserDictionary.Words.WORD);
+
+/*
+ * Only executes if the cursor is valid. The User Dictionary Provider returns null if
+ * an internal error occurs. Other providers may throw an Exception instead of returning null.
+ */
+
+if (mCursor != null) {
+ /*
+ * Moves to the next row in the cursor. Before the first movement in the cursor, the
+ * "row pointer" is -1, and if you try to retrieve data at that position you will get an
+ * exception.
+ */
+ while (mCursor.moveToNext()) {
+
+ // Gets the value from the column.
+ newWord = mCursor.getString(index);
+
+ // Insert code here to process the retrieved word.
+
+ ...
+
+ // end of while loop
+ }
+} else {
+
+ // Insert code here to report an error if the cursor is null or the provider threw an exception.
+}
+</pre>
+<p>
+ Triển khai {@link android.database.Cursor} sẽ chứa một vài phương pháp “get" để
+ truy xuất các kiểu dữ liệu khác nhau từ đối tượng. Ví dụ, đoạn mã HTML trước
+ sử dụng {@link android.database.Cursor#getString getString()}. Chúng cũng có một phương pháp
+ {@link android.database.Cursor#getType getType()} để trả về một giá trị cho biết
+ kiểu dữ liệu của cột.
+</p>
+
+
+ <!-- Requesting permissions -->
+<h2 id="Permissions">Quyền của Trình cung cấp Nội dung</h2>
+<p>
+ Ứng dụng của một trình cung cấp có thể chỉ định các quyền mà ứng dụng khác có thể có để
+ truy cập dữ liệu của trình cung cấp đó. Những quyền này đảm bảo rằng người dùng biết một ứng dụng
+ sẽ cố gắng truy cập dữ liệu nào. Dựa trên các yêu cầu của trình cung cấp, các ứng dụng khác
+ yêu cầu quyền mà chúng cần để truy cập trình dữ liệu. Người dùng cuối thấy các quyền
+ được yêu cầu khi họ cài đặt ứng dụng.
+</p>
+<p>
+ Nếu ứng dụng của một trình cung cấp không chỉ định bất kỳ quyền nào, khi đó các ứng dụng khác không có
+ quyền truy cập dữ liệu của trình cung cấp. Tuy nhiên, các thành phần trong ứng dụng của trình cung cấp luôn có
+ đầy đủ quyền truy nhập đọc và ghi, không phụ thuộc vào các quyền được chỉ định.
+</p>
+<p>
+ Như đã lưu ý, Trình cung cấp Từ điển Người dùng sẽ yêu cầu
+ quyền <code>android.permission.READ_USER_DICTIONARY</code> để truy xuất dữ liệu từ nó.
+ Trình cung cấp có quyền <code>android.permission.WRITE_USER_DICTIONARY</code>
+ riêng để chèn, cập nhật, hoặc xóa dữ liệu.
+</p>
+<p>
+ Để nhận các quyền cần để truy cập một trình cung cấp, ứng dụng yêu cầu chúng bằng một phần tử
+<code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission&gt;</a></code>
+ trong tệp bản kê khai của nó. Khi Trình quản lý Gói Android cài đặt các ứng dụng, người dùng
+ phải phê chuẩn tất cả quyền mà ứng dụng yêu cầu. Nếu người dùng phê chuẩn tất cả quyền, khi đó
+ Trình quản lý Gói sẽ tiếp tục cài đặt; nếu người dùng không phê chuẩn chúng, Trình quản lý Gói sẽ
+ hủy bỏ việc cài đặt.
+</p>
+<p>
+ Phần tử
+<code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html">&lt;uses-permission&gt;</a></code>
+ sau yêu cầu quyền truy cập đọc vào Trình cung cấp Từ điển Người dùng:
+</p>
+<pre>
+ &lt;uses-permission android:name="android.permission.READ_USER_DICTIONARY"&gt;
+</pre>
+<p>
+ Tác động của các quyền tới việc truy cập trình cung cấp được giải thích chi tiết hơn trong
+ hướng dẫn <a href="{@docRoot}guide/topics/security/security.html">Bảo mật và Quyền</a>.
+</p>
+
+
+<!-- Inserting, Updating, and Deleting Data -->
+<h2 id="Modifications">Chèn, Cập nhật, và Xóa Dữ liệu</h2>
+<p>
+ Giống như cách bạn truy xuất dữ liệu từ một trình cung cấp, bạn cũng có thể sử dụng tương tác giữa
+ một máy khách cung cấp và {@link android.content.ContentProvider} của trình cung cấp để sửa đổi dữ liệu.
+ Bạn gọi một phương pháp {@link android.content.ContentResolver} với các tham đối được chuyển sang
+ phương pháp {@link android.content.ContentProvider} tương ứng. Trình cung cấp và
+ máy khách cung cấp sẽ tự động xử lý bảo mật và truyền thông liên tiến trình.
+</p>
+<h3 id="Inserting">Chèn dữ liệu</h3>
+<p>
+ Để chèn dữ liệu vào một trình cung cấp, bạn gọi phương pháp
+ {@link android.content.ContentResolver#insert ContentResolver.insert()}
+. Phương pháp này chèn một hàng mới vào trình cung cấp và trả về một URI nội dung cho hàng đó.
+ Đoạn mã HTML này cho biết cách chèn một từ mới vào Trình cung cấp Từ điển Người dùng:
+</p>
+<pre class="prettyprint">
+// Defines a new Uri object that receives the result of the insertion
+Uri mNewUri;
+
+...
+
+// Defines an object to contain the new values to insert
+ContentValues mNewValues = new ContentValues();
+
+/*
+ * Sets the values of each column and inserts the word. The arguments to the "put"
+ * method are "column name" and "value"
+ */
+mNewValues.put(UserDictionary.Words.APP_ID, "example.user");
+mNewValues.put(UserDictionary.Words.LOCALE, "en_US");
+mNewValues.put(UserDictionary.Words.WORD, "insert");
+mNewValues.put(UserDictionary.Words.FREQUENCY, "100");
+
+mNewUri = getContentResolver().insert(
+ UserDictionary.Word.CONTENT_URI, // the user dictionary content URI
+ mNewValues // the values to insert
+);
+</pre>
+<p>
+ Dữ liệu cho hàng mới đi vào trong một đối tượng {@link android.content.ContentValues} đơn lẻ, đối tượng này
+ có dạng tương tự như con chạy một hàng. Các cột trong đối tượng này không cần có
+ cùng kiểu dữ liệu, và nếu hoàn toàn không muốn chỉ định một giá trị, bạn có thể đặt một cột
+ thành <code>null</code> bằng cách sử dụng {@link android.content.ContentValues#putNull ContentValues.putNull()}.
+</p>
+<p>
+ Đoạn mã HTML không thêm cột <code>_ID</code> vì cột này được tự động
+ duy trì. Trình cung cấp sẽ gán một giá trị duy nhất <code>_ID</code> cho mỗi hàng được
+ thêm. Các trình cung cấp thường sử dụng giá trị này làm khóa chính của bảng.
+</p>
+<p>
+ URI nội dung được trả về trong <code>newUri</code> sẽ xác định hàng mới thêm, có
+ định dạng như sau:
+</p>
+<pre>
+content://user_dictionary/words/&lt;id_value&gt;
+</pre>
+<p>
+ <code>&lt;id_value&gt;</code> là nội dung của <code>_ID</code> cho hàng mới.
+ Hầu hết các trình cung cấp đều có thể tự động phát hiện dạng URI nội dung này rồi thực hiện thao tác được yêu cầu
+ trên hàng cụ thể đó.
+</p>
+<p>
+ Để nhận giá trị <code>_ID</code> từ {@link android.net.Uri} được trả về, hãy gọi
+ {@link android.content.ContentUris#parseId ContentUris.parseId()}.
+</p>
+<h3 id="Updating">Cập nhật dữ liệu</h3>
+<p>
+ Để cập nhật một hàng, bạn sử dụng một đối tượng {@link android.content.ContentValues} với các giá trị
+ được cập nhật giống như cách bạn làm với việc chèn, và các tiêu chí lựa chọn giống như cách bạn làm với truy vấn.
+ Phương pháp máy khách mà bạn sử dụng là
+ {@link android.content.ContentResolver#update ContentResolver.update()}. Bạn chỉ cần thêm
+ các giá trị vào đối tượng {@link android.content.ContentValues} cho các cột mà bạn đang cập nhật. Nếu bạn
+ muốn xóa các nội dung của một cột, hãy đặt giá trị thành <code>null</code>.
+</p>
+<p>
+ Đoạn mã HTML sau thay đổi tất cả hàng với cột bản địa có ngôn ngữ "en" thành cột
+ có bản địa là <code>null</code>. Giá trị trả về là số hàng đã được cập nhật:
+</p>
+<pre>
+// Defines an object to contain the updated values
+ContentValues mUpdateValues = new ContentValues();
+
+// Defines selection criteria for the rows you want to update
+String mSelectionClause = UserDictionary.Words.LOCALE + "LIKE ?";
+String[] mSelectionArgs = {"en_%"};
+
+// Defines a variable to contain the number of updated rows
+int mRowsUpdated = 0;
+
+...
+
+/*
+ * Sets the updated value and updates the selected words.
+ */
+mUpdateValues.putNull(UserDictionary.Words.LOCALE);
+
+mRowsUpdated = getContentResolver().update(
+ UserDictionary.Words.CONTENT_URI, // the user dictionary content URI
+ mUpdateValues // the columns to update
+ mSelectionClause // the column to select on
+ mSelectionArgs // the value to compare to
+);
+</pre>
+<p>
+ Bạn cũng nên thanh lọc thông tin đầu vào của người dùng khi gọi
+ {@link android.content.ContentResolver#update ContentResolver.update()}. Để tìm hiểu thêm về
+ điều này, hãy đọc phần <a href="#Injection">Bảo vệ trước mục nhập độc hại</a>.
+</p>
+<h3 id="Deleting">Xóa dữ liệu</h3>
+<p>
+ Xóa hàng tương tự như truy xuất dữ liệu hàng: bạn chỉ định các tiêu chí lựa chọn cho hàng
+ mà bạn muốn xóa và phương pháp máy khách trả về số hàng được xóa.
+ Đoạn mã HTML sau xóa các hàng có appid khớp với "user". Phương pháp sẽ trả về
+ số hàng được xóa.
+</p>
+<pre>
+
+// Defines selection criteria for the rows you want to delete
+String mSelectionClause = UserDictionary.Words.APP_ID + " LIKE ?";
+String[] mSelectionArgs = {"user"};
+
+// Defines a variable to contain the number of rows deleted
+int mRowsDeleted = 0;
+
+...
+
+// Deletes the words that match the selection criteria
+mRowsDeleted = getContentResolver().delete(
+ UserDictionary.Words.CONTENT_URI, // the user dictionary content URI
+ mSelectionClause // the column to select on
+ mSelectionArgs // the value to compare to
+);
+</pre>
+<p>
+ Bạn cũng nên thanh lọc thông tin đầu vào của người dùng khi gọi
+ {@link android.content.ContentResolver#delete ContentResolver.delete()}. Để tìm hiểu thêm về
+ điều này, hãy đọc phần <a href="#Injection">Bảo vệ trước mục nhập độc hại</a>.
+</p>
+<!-- Provider Data Types -->
+<h2 id="DataTypes">Các Kiểu Dữ liệu của Trình cung cấp</h2>
+<p>
+ Trình cung cấp nội dung có thể cung cấp nhiều kiểu dữ liệu khác nhau. Trình cung cấp Từ điển Người dùng chỉ cung cấp
+ văn bản, nhưng trình cung cấp cũng có thể cung cấp các định dạng sau:
+</p>
+ <ul>
+ <li>
+ integer
+ </li>
+ <li>
+ long integer (long)
+ </li>
+ <li>
+ floating point
+ </li>
+ <li>
+ long floating point (double)
+ </li>
+ </ul>
+<p>
+ Một kiểu dữ liệu khác mà các trình cung cấp thường sử dụng đó là Binary Large OBject (BLOB) được triển khai như một
+ mảng 64KB byte. Bạn có thể xem các kiểu dữ liệu có sẵn bằng cách xem các phương pháp "get" lớp
+ {@link android.database.Cursor}.
+</p>
+<p>
+ Kiểu dữ liệu đối với mỗi cột trong một trình cung cấp thường được liệt kê trong tài liệu của trình cung cấp đó.
+ Các kiểu dữ liệu dành cho Trình cung cấp Từ điển Người dùng được liệt kê trong tài liệu tham khảo
+ cho lớp hợp đồng {@link android.provider.UserDictionary.Words} của nó (lớp hợp đồng được
+ mô tả trong phần <a href="#ContractClasses">Các Lớp Hợp đồng</a>).
+ Bạn cũng có thể xác định kiểu dữ liệu bằng cách gọi {@link android.database.Cursor#getType
+ Cursor.getType()}.
+</p>
+<p>
+ Trình cung cấp cũng duy trì thông tin về kiểu dữ liệu MIME cho mỗi URI nội dung mà chúng định nghĩa. Bạn có thể
+ sử dụng thông tin về kiểu MIME để tìm hiểu xem ứng dụng của mình có thể xử lý dữ liệu mà
+ trình cung cấp đưa ra hay không, hoặc để chọn một kiểu xử lý dựa trên kiểu MIME. Bạn thường cần kiểu
+ MIME khi đang làm việc với một trình cung cấp chứa các cấu trúc hoặc tệp
+ dữ liệu phức tạp. Ví dụ, bảng {@link android.provider.ContactsContract.Data}
+ trong Trình cung cấp Danh bạ sử dụng các kiểu MIME để dán nhãn kiểu dữ liệu liên lạc được lưu trữ trong từng
+ hàng. Để nhận được kiểu MIME tương ứng với một URI nội dung, hãy gọi
+ {@link android.content.ContentResolver#getType ContentResolver.getType()}.
+</p>
+<p>
+ Phần <a href="#MIMETypeReference">Tham khảo Kiểu MIME</a> mô tả
+ cú pháp của cả kiểu MIME tiêu chuẩn lẫn tùy chỉnh.
+</p>
+
+
+<!-- Alternative Forms of Provider Access -->
+<h2 id="AltForms">Các Hình thức Truy cập Trình cung cấp Thay thế</h2>
+<p>
+ Có ba hình thức truy cập trình cung cấp thay thế quan trọng trong phát triển ứng dụng:
+</p>
+<ul>
+ <li>
+ <a href="#Batch">Truy cập hàng loạt</a>: Bạn có thể tạo một loạt lệnh gọi truy cập bằng các phương pháp trong
+ lớp {@link android.content.ContentProviderOperation}, rồi sau đó áp dụng chúng với
+ {@link android.content.ContentResolver#applyBatch ContentResolver.applyBatch()}.
+ </li>
+ <li>
+ Truy vấn không đồng bộ: Bạn nên thực hiện các truy vấn trong một luồng riêng. Một cách để làm điều này đó là
+ sử dụng một đối tượng {@link android.content.CursorLoader}. Các ví dụ trong
+ hướng dẫn <a href="{@docRoot}guide/components/loaders.html">Trình tải</a> sẽ minh họa
+ cách làm điều này.
+ </li>
+ <li>
+ <a href="#Intents">Truy cập dữ liệu thông qua ý định</a>: Mặc dù không thể gửi một ý định
+ trực tiếp tới một trình cung cấp, bạn có thể gửi một ý định tới ứng dụng của trình cung cấp đó,
+ đây thường là cách tốt nhất để sửa đổi dữ liệu của trình cung cấp.
+ </li>
+</ul>
+<p>
+ Truy cập hàng loạt và sửa đổi thông qua ý định được mô tả trong các phần sau.
+</p>
+<h3 id="Batch">Truy cập hàng loạt</h3>
+<p>
+ Truy cập hàng loạt vào một trình cung cấp là cách hữu ích để chèn nhiều hàng, hoặc để chèn
+ các hàng vào nhiều bảng trong cùng lệnh gọi phương pháp, hoặc nhìn chung để thực hiện một tập hợp
+ thao tác qua các ranh giới tiến trình như một giao tác (thao tác nguyên tử).
+</p>
+<p>
+ Để truy cập một trình cung cấp trong "chế độ hàng loạt",
+ bạn tạo một mảng đối tượng {@link android.content.ContentProviderOperation} rồi
+ phân phối chúng tới một trình cung cấp nội dung bằng
+ {@link android.content.ContentResolver#applyBatch ContentResolver.applyBatch()}. Bạn chuyển
+ <em>quyền</em> của trình cung cấp nội dung cho phương pháp này thay vì một URI nội dung cụ thể.
+Điều này cho phép đối tượng {@link android.content.ContentProviderOperation} trong mảng có tác dụng
+ đối với một bảng khác. Một lệnh gọi tới {@link android.content.ContentResolver#applyBatch
+ ContentResolver.applyBatch()} trả về một mảng kết quả.
+</p>
+<p>
+ Mô tả lớp hợp đồng {@link android.provider.ContactsContract.RawContacts}
+ bao gồm một đoạn mã HTML thể hiện việc chèn hàng loạt. Ứng dụng mẫu
+ <a href="{@docRoot}resources/samples/ContactManager/index.html">Trình quản lý Danh bạ</a>
+ có một ví dụ về truy cập hàng loạt trong tệp nguồn <code>ContactAdder.java</code>
+ của nó.
+</p>
+<div class="sidebox-wrapper">
+<div class="sidebox">
+<h2>Hiển thị dữ liệu bằng cách sử dụng một ứng dụng trình trợ giúp.</h2>
+<p>
+ Nếu ứng dụng của bạn <em>có</em> quyền truy cập, bạn vẫn có thể cần sử dụng một
+ ý định để hiển thị dữ liệu trong một ứng dụng khác. Ví dụ, ứng dụng Lịch chấp nhận một
+ ý định {@link android.content.Intent#ACTION_VIEW}, nhằm hiển thị một ngày hoặc sự kiện cụ thể.
+ Điều này cho phép bạn hiển thị thông tin lịch mà không phải tạo UI của chính mình.
+ Để tìm hiểu thêm về tính năng này, hãy xem
+ hướng dẫn <a href="{@docRoot}guide/topics/providers/calendar-provider.html">Trình cung cấp Lịch</a>.
+</p>
+<p>
+ Ứng dụng mà bạn gửi ý định đến không nhất thiết phải là ứng dụng
+ được liên kết với trình cung cấp. Ví dụ, bạn có thể truy xuất một liên lạc từ
+ Trình cung cấp Danh bạ, rồi gửi một ý định {@link android.content.Intent#ACTION_VIEW}
+ chứa URI nội dung cho hình ảnh liên lạc tới một trình xem ảnh.
+</p>
+</div>
+</div>
+<h3 id="Intents">Truy cập dữ liệu thông qua ý định</h3>
+<p>
+ Ý định có thể cho phép truy cập gián tiếp vào một trình cung cấp nội dung. Bạn cho phép người dùng truy cập
+ dữ liệu trong một trình cung cấp ngay cả khi ứng dụng của bạn không có quyền truy cập, hoặc bằng cách
+ nhận lại một ý định kết quả từ một ứng dụng có quyền, hoặc bằng cách kích hoạt một
+ ứng dụng có phép và cho phép người dùng được làm việc trong nó.
+</p>
+<h4>Được truy cập với các quyền tạm thời</h4>
+<p>
+ Bạn có thể truy cập dữ liệu trong một trình cung cấp nội dung, ngay cả khi bạn không có quyền
+ truy nhập phù hợp, bằng cách gửi một ý định tới một ứng dụng có quyền và
+ nhận lại một ý định kết quả chứa quyền "URI".
+ Đây là những quyền cho một URI nội dung cụ thể kéo dài tới khi hoạt động nhận chúng
+ được hoàn thành. Ứng dụng có quyền lâu dài sẽ cấp quyền tạm thời
+ bằng cách đặt một cờ trong ý định kết quả:
+</p>
+<ul>
+ <li>
+ <strong>Quyền đọc:</strong>
+ {@link android.content.Intent#FLAG_GRANT_READ_URI_PERMISSION}
+ </li>
+ <li>
+ <strong>Quyền ghi:</strong>
+ {@link android.content.Intent#FLAG_GRANT_WRITE_URI_PERMISSION}
+ </li>
+</ul>
+<p class="note">
+ <strong>Lưu ý:</strong> Những cờ này không cấp quyền truy cập đọc và ghi nói chung cho trình cung cấp
+ mà có quyền được chứa trong URI nội dung. Quyền truy cập này chỉ áp dụng cho chính URI đó.
+</p>
+<p>
+ Trình cung cấp sẽ định nghĩa quyền URI cho các URI nội dung trong bản kê khai của nó, bằng cách sử dụng thuộc tính
+<code><a href="{@docRoot}guide/topics/manifest/provider-element.html#gprmsn">android:grantUriPermission</a></code>
+ của phần tử
+<code><a href="{@docRoot}guide/topics/manifest/provider-element.html">&lt;provider&gt;</a></code>
+ cũng như phần tử con
+<code><a href="{@docRoot}guide/topics/manifest/grant-uri-permission-element.html">&lt;grant-uri-permission&gt;</a></code>
+ của phần tử
+<code><a href="{@docRoot}guide/topics/manifest/provider-element.html">&lt;provider&gt;</a></code>
+ . Cơ chế cấp quyền URI này được giải thích chi tiết hơn trong
+ hướng dẫn <a href="{@docRoot}guide/topics/security/security.html">Bảo mật và Quyền</a>,
+ trong phần "Quyền URI".
+</p>
+<p>
+ Ví dụ, bạn có thể truy xuất dữ liệu cho một liên lạc trong Trình cung cấp Danh bạ, ngay cả khi bạn không
+ có quyền {@link android.Manifest.permission#READ_CONTACTS}. Bạn có thể muốn thực hiện điều này
+ trong một ứng dụng gửi thiệp mừng điện tử tới một liên lạc vào ngày sinh nhật của người đó. Thay vì
+ yêu cầu {@link android.Manifest.permission#READ_CONTACTS}, là nơi cấp cho bạn quyền truy cập tất cả liên lạc
+ của người dùng và tất cả thông tin của họ, bạn nên cho phép người dùng kiểm soát những liên lạc
+ nào được sử dụng bởi ứng dụng của bạn. Để làm điều này, bạn sử dụng tiến trình sau:
+</p>
+<ol>
+ <li>
+ Ứng dụng của bạn gửi một ý định chứa hành động
+ {@link android.content.Intent#ACTION_PICK} và kiểu MIME "danh bạ"
+{@link android.provider.ContactsContract.RawContacts#CONTENT_ITEM_TYPE}, bằng cách sử dụng
+ phương pháp {@link android.app.Activity#startActivityForResult
+ startActivityForResult()}.
+ </li>
+ <li>
+ Vì ý định này khớp với bộ lọc ý định cho hoạt động
+ "lựa chọn" của ứng dụng Danh bạ, hoạt động sẽ đi đến tiền cảnh.
+ </li>
+ <li>
+ Trong hoạt động lựa chọn, người dùng chọn một
+ liên lạc để cập nhật. Khi điều này xảy ra, hoạt động lựa chọn sẽ gọi
+ {@link android.app.Activity#setResult setResult(resultcode, intent)}
+ để thiết lập một ý định nhằm gửi lại ứng dụng của bạn. Ý định chứa URI nội dung
+ của liên lạc mà người dùng đã chọn, và các cờ "phụ thêm"
+ {@link android.content.Intent#FLAG_GRANT_READ_URI_PERMISSION}. Những cờ này cấp quyền URI
+ cho ứng dụng của bạn để đọc dữ liệu cho liên lạc được trỏ đến bởi
+ URI nội dung. Sau đó, hoạt động lựa chọn gọi {@link android.app.Activity#finish()} để
+ trả kiểm soát về ứng dụng của bạn.
+ </li>
+ <li>
+ Hoạt động của bạn trả về tiền cảnh, và hệ thống sẽ gọi phương pháp
+ {@link android.app.Activity#onActivityResult onActivityResult()}
+ của hoạt động của bạn. Phương pháp này nhận được ý định kết quả do hoạt động lựa chọn tạo trong
+ ứng dụng Danh bạ.
+ </li>
+ <li>
+ Với URI nội dung từ ý định kết quả, bạn có thể đọc dữ liệu của liên lạc
+ từ Trình cung cấp Danh bạ, ngay cả khi bạn không yêu cầu quyền truy cập đọc lâu dài
+ vào trình cung cấp trong bản kê khai của mình. Sau đó, bạn có thể nhận thông tin ngày sinh của liên lạc
+ hoặc địa chỉ e-mail của người đó rồi gửi thiệp mừng điện tử.
+ </li>
+</ol>
+<h4>Sử dụng một ứng dụng khác</h4>
+<p>
+ Một cách đơn giản để cho phép người dùng sửa đổi dữ liệu mà bạn không có quyền truy cập đó là
+ kích hoạt một ứng dụng có quyền và cho phép người dùng làm việc ở đó.
+</p>
+<p>
+ Ví dụ, ứng dụng Lịch chấp nhận một
+ ý định {@link android.content.Intent#ACTION_INSERT}, nó cho phép bạn kích hoạt UI chèn
+ của ứng dụng. Bạn có thể chuyển dữ liệu "phụ thêm" trong ý định này mà được ứng dụng sử dụng
+ để điền trước vào UI. Vì các sự kiện định kỳ có cú pháp phức tạp, cách
+ ưu tiên để chèn sự kiện vào Trình cung cấp Lịch đó là kích hoạt ứng dụng Lịch với một
+ {@link android.content.Intent#ACTION_INSERT} rồi để người dùng chèn sự kiện tại đó.
+</p>
+<!-- Contract Classes -->
+<h2 id="ContractClasses">Các Lớp Hợp đồng</h2>
+<p>
+ Lớp hợp đồng định nghĩa các hằng số sẽ giúp ứng dụng hoạt động với các URI nội dung, tên
+ cột, hành động ý định, và các tính năng khác của một trình cung cấp nội dung. Các lớp hợp đồng không
+ được tự động đưa vào cùng một trình cung cấp; nhà phát triển của trình cung cấp phải định nghĩa chúng rồi
+ cung cấp chúng cho các nhà phát triển khác. Nhiều trình cung cấp được bao gồm cùng với nền tảng
+ Android có các lớp hợp đồng tương ứng trong gói {@link android.provider}.
+</p>
+<p>
+ Ví dụ, Trình cung cấp Từ điển Người dùng có một lớp hợp đồng
+ {@link android.provider.UserDictionary} chứa các hằng số URI nội dung và tên cột. URI nội dung
+ đối với bảng "từ" được định nghĩa trong hằng số
+ {@link android.provider.UserDictionary.Words#CONTENT_URI UserDictionary.Words.CONTENT_URI}.
+ Lớp {@link android.provider.UserDictionary.Words} cũng chứa các hằng số tên cột,
+ chúng được sử dụng trong đoạn mã HTML mẫu trong hướng dẫn này. Ví dụ, một dự thảo truy vấn có thể được
+ định nghĩa là:
+</p>
+<pre>
+String[] mProjection =
+{
+ UserDictionary.Words._ID,
+ UserDictionary.Words.WORD,
+ UserDictionary.Words.LOCALE
+};
+</pre>
+<p>
+ Một lớp hợp đồng khác là {@link android.provider.ContactsContract} dành cho Trình cung cấp Danh bạ.
+ Tài liệu tham khảo cho lớp này bao gồm các đoạn mã HTML mẫu. Một trong số các
+ lớp con của nó, {@link android.provider.ContactsContract.Intents.Insert}, là một lớp hợp đồng
+ chứa các hằng số cho ý định và dữ liệu ý định.
+</p>
+
+
+<!-- MIME Type Reference -->
+<h2 id="MIMETypeReference">Tham khảo Kiểu MIME</h2>
+<p>
+ Trình cung cấp nội dung có thể trả về các kiểu phương tiện MIME tiêu chuẩn, hoặc xâu kiểu MIME tùy chỉnh, hoặc cả hai.
+</p>
+<p>
+ Các kiểu MIME có định dạng
+</p>
+<pre>
+<em>type</em>/<em>subtype</em>
+</pre>
+<p>
+ Ví dụ, kiểu MIME thông dụng <code>text/html</code> có kiểu <code>text</code> và
+ kiểu con <code>html</code>. Nếu trình cung cấp trả về loại này cho một URI, điều đó có nghĩa rằng một
+ truy vấn đang sử dụng URI đó sẽ trả về văn bản chứa thẻ HTML.
+</p>
+<p>
+ Các xâu kiểu MIME tùy chỉnh, còn gọi là kiểu MIME "theo nhà cung cấp", có các giá trị
+ <em>kiểu</em> và <em>kiểu con</em> phức tạp hơn. Giá trị <em>kiểu</em> luôn luôn
+</p>
+<pre>
+vnd.android.cursor.<strong>dir</strong>
+</pre>
+<p>
+ áp dụng cho nhiều hàng, hoặc
+</p>
+<pre>
+vnd.android.cursor.<strong>item</strong>
+</pre>
+<p>
+ áp dụng cho một hàng.
+</p>
+<p>
+ Giá trị <em>kiểu con</em> áp dụng theo trình cung cấp. Các trình cung cấp được tích hợp trong Android thường có một kiểu con
+ đơn giản. Ví dụ, khi ứng dụng Danh bạ tạo một hàng cho một số điện thoại,
+ nó đặt kiểu MIME sau trong hàng:
+</p>
+<pre>
+vnd.android.cursor.item/phone_v2
+</pre>
+<p>
+ Để ý rằng giá trị kiểu con đơn giản là <code>phone_v2</code>.
+</p>
+<p>
+ Các nhà phát triển trình cung cấp khác có thể tạo mẫu hình kiểu con của riêng mình dựa trên quyền
+ và tên bảng của trình cung cấp. Ví dụ, xét một trình cung cấp chứa các biểu thời gian lịch tàu.
+ Quyền của trình cung cấp là <code>com.example.trains</code>, và nó chứa các bảng
+ Line1, Line2, và Line3. Để phản hồi lại URI nội dung
+</p>
+<p>
+<pre>
+content://com.example.trains/Line1
+</pre>
+<p>
+ đối với bảng Line1, trình cung cấp trả về kiểu MIME
+</p>
+<pre>
+vnd.android.cursor.<strong>dir</strong>/vnd.example.line1
+</pre>
+<p>
+ Để phản hồi lại URI nội dung
+</p>
+<pre>
+content://com.example.trains/Line2/5
+</pre>
+<p>
+ đối với hàng 5 trong bảng Line2, trình cung cấp trả về kiểu MIME
+</p>
+<pre>
+vnd.android.cursor.<strong>item</strong>/vnd.example.line2
+</pre>
+<p>
+ Hầu hết các trình cung cấp nội dung đều định nghĩa hằng số lớp hợp đồng cho các kiểu MIME mà chúng sử dụng. Ví dụ như lớp hợp đồng
+ của Trình cung cấp Danh bạ {@link android.provider.ContactsContract.RawContacts},
+ sẽ định nghĩa hằng số
+ {@link android.provider.ContactsContract.RawContacts#CONTENT_ITEM_TYPE} cho kiểu MIME của
+ một hàng liên lạc thô duy nhất.
+</p>
+<p>
+ Các URI nội dung đối với hàng duy nhất được mô tả trong phần
+ <a href="#ContentURIs">URI nội dung</a>.
+</p>
diff --git a/docs/html-intl/intl/vi/guide/topics/providers/content-provider-creating.jd b/docs/html-intl/intl/vi/guide/topics/providers/content-provider-creating.jd
new file mode 100644
index 000000000000..2e8579a1e92e
--- /dev/null
+++ b/docs/html-intl/intl/vi/guide/topics/providers/content-provider-creating.jd
@@ -0,0 +1,1214 @@
+page.title=Tạo một Trình cung cấp Nội dung
+@jd:body
+<div id="qv-wrapper">
+<div id="qv">
+
+
+<h2>Trong tài liệu này</h2>
+<ol>
+ <li>
+ <a href="#DataStorage">Thiết kế Kho lưu trữ Dữ liệu</a>
+ </li>
+ <li>
+ <a href="#ContentURI">Thiết kế URI Nội dung</a>
+ </li>
+ <li>
+ <a href="#ContentProvider">Triển khai Lớp Trình cung cấp Nội dung</a>
+ <ol>
+ <li>
+ <a href="#RequiredAccess">Phương pháp được Yêu cầu</a>
+ </li>
+ <li>
+ <a href="#Query">Triển khai phương pháp query()</a>
+ </li>
+ <li>
+ <a href="#Insert">Triển khai phương pháp insert()</a>
+ </li>
+ <li>
+ <a href="#Delete">Triển khai phương pháp delete()</a>
+ </li>
+ <li>
+ <a href="#Update">Triển khai phương pháp update()</a>
+ </li>
+ <li>
+ <a href="#OnCreate">Triển khai phương pháp onCreate()</a>
+ </li>
+ </ol>
+ </li>
+ <li>
+ <a href="#MIMETypes">Triển khai Kiểu MIME của Trình cung cấp Nội dung</a>
+ <ol>
+ <li>
+ <a href="#TableMIMETypes">Kiểu MIME cho bảng</a>
+ </li>
+ <li>
+ <a href="#FileMIMETypes">Kiểu MIME cho tệp</a>
+ </li>
+ </ol>
+ </li>
+ <li>
+ <a href="#ContractClass">Triển khai một Lớp Hợp đồng</a>
+ </li>
+ <li>
+ <a href="#Permissions">Triển khai Quyền của Trình cung cấp Nội dung</a>
+ </li>
+ <li>
+ <a href="#ProviderElement">Phần tử &lt;provider&gt;</a>
+ </li>
+ <li>
+ <a href="#Intents">Ý định và Truy cập Dữ liệu</a>
+ </li>
+</ol>
+<h2>Lớp khóa</h2>
+ <ol>
+ <li>
+ {@link android.content.ContentProvider}
+ </li>
+ <li>
+ {@link android.database.Cursor}
+ </li>
+ <li>
+ {@link android.net.Uri}
+ </li>
+ </ol>
+<h2>Các Mẫu Liên quan</h2>
+ <ol>
+ <li>
+ <a href="{@docRoot}resources/samples/NotePad/index.html">
+ Ứng dụng mẫu Note Pad
+ </a>
+ </li>
+ </ol>
+<h2>Xem thêm</h2>
+ <ol>
+ <li>
+ <a href="{@docRoot}guide/topics/providers/content-provider-basics.html">
+ Nội dung Cơ bản về Trình cung cấp Nội dung</a>
+ </li>
+ <li>
+ <a href="{@docRoot}guide/topics/providers/calendar-provider.html">
+ Trình cung cấp Lịch</a>
+ </li>
+ </ol>
+</div>
+</div>
+
+
+<p>
+ Trình cung cấp nội dung quản lý truy cập vào một kho dữ liệu tập trung. Bạn triển khai một
+ trình cung cấp thành một hoặc nhiều lớp trong một ứng dụng Android, bên cạnh các phần tử trong
+ tệp bản kê khai. Một trong các lớp của bạn triển khai một lớp con
+ {@link android.content.ContentProvider}, đây là giao diện giữa trình cung cấp của bạn và
+ các ứng dụng khác. Mặc dù mục đích của các trình cung cấp nội dung khác là cung cấp dữ liệu có sẵn cho các
+ ứng dụng khác, dĩ nhiên bạn có thể ra lệnh cho các hoạt động trong ứng dụng của mình
+ truy vấn và sửa đổi dữ liệu được quản lý bởi trình cung cấp của bạn.
+</p>
+<p>
+ Phần còn lại của chủ đề này là một danh sách cơ bản về các bước để xây dựng một trình cung cấp nội dung và một danh sách
+ các API để sử dụng.
+</p>
+
+
+<!-- Before You Start Building -->
+<h2 id="BeforeYouStart">Trước khi Bạn Bắt đầu Xây dựng</h2>
+<p>
+ Trước khi bạn bắt đầu xây dựng một trình cung cấp, hãy làm việc sau:
+</p>
+<ol>
+ <li>
+ <strong>Quyết định xem bạn có cần một trình cung cấp nội dung không</strong>. Bạn cần xây dựng một trình cung cấp
+ nội dung nếu muốn cung cấp một hoặc nhiều tính năng sau đây:
+ <ul>
+ <li>Bạn muốn cung cấp dữ liệu hoặc tệp phức tạp cho các ứng dụng khác.</li>
+ <li>Bạn muốn cho phép người dùng sao chép dữ liệu phức tạp từ ứng dụng của bạn vào các ứng dụng khác.</li>
+ <li>Bạn muốn cung cấp các gợi ý tìm kiếm tùy chỉnh bằng cách sử dụng khuôn khổ tìm kiếm.</li>
+ </ul>
+ <p>
+ Bạn <em>không</em> cần trình cung cấp phải sử dụng một cơ sở dữ liệu SQLite nếu việc sử dụng hoàn toàn
+ diễn ra trong ứng dụng của bạn.
+ </p>
+ </li>
+ <li>
+ Nếu bạn chưa làm như vậy, hãy đọc chủ đề
+ <a href="{@docRoot}guide/topics/providers/content-provider-basics.html">
+ Nội dung Cơ bản về Trình cung cấp Nội dung</a> để tìm hiểu thêm về trình cung cấp.
+ </li>
+</ol>
+<p>
+ Tiếp theo, hãy làm theo những bước sau để xây dựng trình cung cấp của bạn:
+</p>
+<ol>
+ <li>
+ Thiết kế kho lưu trữ thô cho dữ liệu của bạn. Một trình cung cấp nội dung sẽ cung cấp dữ liệu theo hai cách:
+ <dl>
+ <dt>
+ Dữ liệu tệp
+ </dt>
+ <dd>
+ Dữ liệu mà thường đến các tệp chẳng hạn như
+ ảnh, âm thanh, hoặc video. Lưu trữ các tệp ở không gian
+ riêng tư trong ứng dụng của bạn. Để hồi đáp lại một yêu cầu tệp từ một ứng dụng khác, trình cung cấp
+ của bạn có thể cung cấp một núm điều tác cho tệp.
+ </dd>
+ <dt>
+ Dữ liệu "cấu trúc"
+ </dt>
+ <dd>
+ Dữ liệu mà thường đến một cơ sở dữ liệu, mảng, hoặc cấu trúc tương tự.
+ Lưu trữ dữ liệu dưới dạng tương thích với các bảng hàng cột. Hàng
+ biểu diễn một đối tượng, chẳng hạn như một người hoặc khoản mục trong kiểm kê. Cột biểu diễn
+ một số dữ liệu cho đối tượng, chẳng hạn như tên của một người hoặc giá của một khoản mục. Một cách thường dùng để
+ lưu trữ loại dữ liệu này đó là trong cơ sở dữ liệu SQLite, nhưng bạn có thể sử dụng bất kỳ loại
+ kho lưu trữ lâu dài nào. Để tìm hiểu thêm về các loại kho lưu trữ có sẵn trong
+ hệ thống Android, hãy xem phần <a href="#DataStorage">
+ Thiết kế Kho lưu trữ Dữ liệu</a>.
+ </dd>
+ </dl>
+ </li>
+ <li>
+ Định nghĩa một triển khai cụ thể của lớp {@link android.content.ContentProvider} và
+ các phương pháp được yêu cầu của nó. Lớp này là giao diện giữa dữ liệu của bạn và phần còn lại của
+ hệ thống Android. Để biết thêm thông tin về lớp này, hãy xem phần
+ <a href="#ContentProvider">Triển khai Lớp ContentProvider</a>.
+ </li>
+ <li>
+ Định nghĩa xâu thẩm quyền của trình cung cấp, URI nội dung của nó, và các tên cột. Nếu bạn muốn
+ ứng dụng của trình cung cấp xử lý các ý định, hãy định nghĩa các hành động ý định, dữ liệu phụ thêm,
+ và cờ. Đồng thời, hãy định nghĩa các quyền mà bạn sẽ yêu cầu cho những ứng dụng muốn
+ truy cập dữ liệu của bạn. Bạn nên cân nhắc định nghĩa tất cả những giá trị này là hằng số trong một
+ lớp riêng; sau đó, bạn có thể cho hiện lớp này ra với các nhà phát triển khác. Để biết thêm
+ thông tin về URI nội dung, hãy xem
+ phần <a href="#ContentURI">Thiết kế URI Nội dung</a>.
+ Để biết thêm thông tin về ý định, hãy xem
+ phần <a href="#Intents">Ý định và Truy cập Dữ liệu</a>.
+ </li>
+ <li>
+ Thêm các nội dung tùy chọn khác, chẳng hạn như dữ liệu mẫu hoặc triển
+ khai {@link android.content.AbstractThreadedSyncAdapter} mà có thể đồng bộ hoá dữ liệu giữa
+ trình cung cấp và dữ liệu nền đám mây.
+ </li>
+</ol>
+
+
+<!-- Designing Data Storage -->
+<h2 id="DataStorage">Thiết kế Kho lưu trữ Dữ liệu</h2>
+<p>
+ Trình cung cấp nội dung là giao diện đối với dữ liệu được lưu theo một định dạng cấu trúc. Trước khi tạo
+ giao diện, bạn phải quyết định cách lưu trữ dữ liệu. Bạn có thể lưu trữ dữ liệu theo bất kỳ dạng nào
+ mà bạn muốn rồi thiết kế giao diện để đọc và ghi dữ liệu nếu cần thiết.
+</p>
+<p>
+ Có một số công nghệ lưu trữ dữ liệu có sẵn trong Android:
+</p>
+<ul>
+ <li>
+ Hệ thống Android bao gồm một API cơ sở dữ liệu SQLite mà các trình cung cấp của chính Androi sử dụng
+ để lưu trữ dữ liệu theo định hướng bảng. Lớp
+ {@link android.database.sqlite.SQLiteOpenHelper} giúp bạn tạo cơ sở dữ liệu, và lớp
+ {@link android.database.sqlite.SQLiteDatabase} là lớp cơ bản để đánh giá
+ các cơ sở dữ liệu.
+ <p>
+ Nhớ rằng bạn không phải sử dụng một cơ sở dữ liệu để triển khai kho lưu giữ của mình. Bề ngoài, một trình cung cấp
+ có dạng như là một tập hợp bảng, tương tự như một cơ sở dữ liệu quan hệ, nhưng đây
+ không phải là một yêu cầu đối với việc triển khai nội bộ của trình cung cấp.
+ </p>
+ </li>
+ <li>
+ Để lưu trữ dữ liệu tệp, Android có nhiều API định hướng tệp khác nhau.
+ Để tìm hiểu thêm về lưu trữ tệp, hãy đọc chủ đề
+ <a href="{@docRoot}guide/topics/data/data-storage.html">Kho lưu trữ Dữ liệu</a>. Nếu bạn
+ đang thiết kế một trình cung cấp dữ liệu liên quan tới phương tiện chẳng hạn như nhạc hay video, bạn có thể
+ có một trình cung cấp cho phép kết hợp dữ liệu bảng và các tệp.
+ </li>
+ <li>
+ Để làm việc với dữ liệu trên nền mạng, hãy sử dụng các lớp trong {@link java.net} và
+ {@link android.net}. Bạn cũng có thể đồng bộ hoá dữ liệu trên nền mạng với một kho lưu trữ dữ liệu cục bộ
+ chẳng hạn như một cơ sở dữ liệu, rồi cung cấp dữ liệu dưới dạng bảng hoặc tệp.
+ Ứng dụng mẫu <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">
+ Trình điều hợp Đồng bộ Mẫu</a> minh họa loại đồng bộ hoá này.
+ </li>
+</ul>
+<h3 id="DataDesign">
+ Những nội dung cần xem xét khi thiết kế dữ liệu
+</h3>
+<p>
+ Sau đây là một số mẹo để thiết kế cấu trúc dữ liệu cho trình cung cấp của bạn:
+</p>
+<ul>
+ <li>
+ Dữ liệu bảng nên luôn có một cột "khóa chính" mà trình cung cấp duy trì
+ như một giá trị số duy nhất cho mỗi hàng. Bạn có thể sử dụng giá trị này để liên kết hàng với các hàng
+ có liên quan trong các bảng khác (sử dụng nó làm "khóa ngoại"). Mặc dù bạn có thể sử dụng bất kỳ tên gọi nào
+ cho cột này, sử dụng {@link android.provider.BaseColumns#_ID BaseColumns._ID} là lựa chọn tốt nhất
+ vì việc liên kết các kết quả của một truy vấn trình cung cấp với
+ {@link android.widget.ListView} đòi hỏi một trong các cột được truy xuất phải có tên
+ <code>_ID</code>.
+ </li>
+ <li>
+ Nếu bạn muốn cung cấp các hình ảnh bitmap hoặc nội dung dữ liệu định hướng tệp rất lớn khác, hãy lưu trữ
+ dữ liệu vào một tệp rồi cung cấp nó gián tiếp thay vì lưu trữ nó trực tiếp trong một
+ bảng. Nếu làm vậy, bạn cần báo cho người dùng trình cung cấp của bạn rằng họ cần sử dụng một phương pháp tệp
+ {@link android.content.ContentResolver} để truy cập dữ liệu.
+ </li>
+ <li>
+ Sử dụng kiểu dữ liệu Binary Large OBject (BLOB) để lưu trữ dữ liệu có kích cỡ khác nhau hoặc có một
+ cấu trúc thay đổi. Ví dụ, bạn có thể sử dụng cột BLOB để lưu trữ một
+ <a href="http://code.google.com/p/protobuf">bộ đệm giao thức</a> hay
+ <a href="http://www.json.org">cấu trúc JSON</a>.
+ <p>
+ Bạn cũng có thể sử dụng một BLOB để triển khai một bảng <em>độc lập với sơ đồ</em>. Trong
+ kiểu bảng này, bạn định nghĩa một cột khóa chính, một cột kiểu MIME, và một hoặc
+ nhiều cột chung là BLOB. Ý nghĩa của dữ liệu trong cột BLOB được thể hiện
+ bởi giá trị trong cột kiểu MIME. Điều này cho phép bạn lưu trữ các kiểu hàng khác nhau trong
+ cùng bảng. Bảng "dữ liệu"
+ {@link android.provider.ContactsContract.Data} của Trình cung cấp Danh bạ là một ví dụ về bảng
+ độc lập với sơ đồ.
+ </p>
+ </li>
+</ul>
+<!-- Designing Content URIs -->
+<h2 id="ContentURI">Thiết kế URI Nội dung</h2>
+<p>
+ <strong>URI nội dung</strong> là một URI xác định dữ liệu trong một trình cung cấp. URI nội dung bao gồm
+ tên mang tính biểu tượng của toàn bộ trình cung cấp (<strong>quyền</strong> của nó) và một
+ tên trỏ đến một bảng hoặc tệp (<strong>đường dẫn</strong>). Phần id tùy chọn chỉ đến một
+ hàng riêng lẻ trong một bảng. Mọi phương thức truy cập dữ liệu
+ {@link android.content.ContentProvider} đều có một URI nội dung là một tham đối; điều này cho phép bạn
+ xác định bảng, hàng, hoặc tệp để truy cập.
+</p>
+<p>
+ Nội dung cơ bản của URI nội dung được mô tả trong chủ đề
+ <a href="{@docRoot}guide/topics/providers/content-provider-basics.html">
+ Nội dung Cơ bản về Trình cung cấp Nội dung</a>.
+</p>
+<h3>Thiết kế một thẩm quyền</h3>
+<p>
+ Một trình cung cấp thường có một thẩm quyền duy nhất, đóng vai trò là tên nội bộ Android của nó. Để
+ tránh xung đột với các trình cung cấp khác, bạn nên sử dụng quyền sở hữu miền Internet (đảo ngược)
+ làm cơ sở cho thẩm quyền của trình cung cấp của mình. Vì đề xuất này cũng đúng đối với tên gói
+ Android, bạn có thể định nghĩa thẩm quyền trình cung cấp của mình là phần mở rộng của tên
+ gói chứa trình cung cấp. Ví dụ, nếu tên gói Android là
+ <code>com.example.&lt;appname&gt;</code>, bạn nên cấp cho trình cung cấp của mình
+ thẩm quyền <code>com.example.&lt;appname&gt;.provider</code>.
+</p>
+<h3>Thiết kế một cấu trúc đường dẫn</h3>
+<p>
+ Nhà phát triển thường tạo URI nội dung từ thẩm quyền bằng cách nối các đường dẫn trỏ đến
+ các bảng riêng lẻ. Ví dụ, nếu bạn có hai bảng <em>table1</em> và
+ <em>table2</em>, bạn kết hợp thẩm quyền từ ví dụ trước để tạo ra
+ các URI nội dung
+ <code>com.example.&lt;appname&gt;.provider/table1</code> và
+ <code>com.example.&lt;appname&gt;.provider/table2</code>. Các đường dẫn
+ không bị giới hạn ở một phân đoạn duy nhất, và không cần phải có một bảng cho từng cấp của đường dẫn.
+</p>
+<h3>Xử lý ID URI nội dung</h3>
+<p>
+ Theo quy ước, các trình cung cấp cho phép truy cập một hàng đơn trong một bảng bằng cách chấp nhận một URI nội dung
+ có một giá trị ID cho hàng đó ở cuối URI. Cũng theo quy ước, các trình cung cấp sẽ so khớp
+ giá trị ID với cột <code>_ID</code> của bảng, và thực hiện truy cập yêu cầu đối với
+ hàng trùng khớp.
+</p>
+<p>
+ Quy ước này tạo điều kiện cho một kiểu mẫu thiết kế chung cho các ứng dụng truy cập một trình cung cấp. Ứng dụng
+ tiến hành truy vấn đối với trình cung cấp và hiển thị kết quả {@link android.database.Cursor}
+ trong một {@link android.widget.ListView} bằng cách sử dụng {@link android.widget.CursorAdapter}.
+ Định nghĩa {@link android.widget.CursorAdapter} yêu cầu một trong các cột trong
+ {@link android.database.Cursor} phải là <code>_ID</code>
+</p>
+<p>
+ Sau đó, người dùng chọn một trong các hàng được hiển thị từ UI để xem hoặc sửa đổi
+ dữ liệu. Ứng dụng sẽ nhận được hàng tương ứng từ {@link android.database.Cursor} làm nền cho
+ {@link android.widget.ListView}, nhận giá trị <code>_ID</code> cho hàng này, nối nó với
+ URI nội dung, và gửi yêu cầu truy cập tới trình cung cấp. Sau đó, trình cung cấp có thể thực hiện
+ truy vấn hoặc sửa đổi đối với chính xác hàng mà người dùng đã chọn.
+</p>
+<h3>Kiểu mẫu URI nội dung</h3>
+<p>
+ Để giúp bạn chọn hành động nào sẽ thực hiện cho URI nội dung đến, API của trình cung cấp sẽ bao gồm
+ lớp thuận tiện {@link android.content.UriMatcher}, nó ánh xạ "kiểu mẫu" URI nội dung với
+ các giá trị số nguyên. Bạn có thể sử dụng các giá trị số nguyên trong một câu lệnh <code>switch</code> mà chọn
+ hành động mong muốn cho URI nội dung hoặc URI mà khớp với một kiểu mẫu cụ thể.
+</p>
+<p>
+ Kiểu mẫu URI nội dung sẽ so khớp các URI nội dung bằng cách sử dụng ký tự đại diện:
+</p>
+ <ul>
+ <li>
+ <strong><code>*</code>:</strong> Khớp một xâu ký tự hợp lệ bất kỳ với chiều dài bất kỳ.
+ </li>
+ <li>
+ <strong><code>#</code>:</strong> Khớp một xâu ký tự số có chiều dài bất kỳ.
+ </li>
+ </ul>
+<p>
+ Lấy một ví dụ về thiết kế và tạo mã xử lý URI nội dung, hãy xét một trình cung cấp có
+ thẩm quyền <code>com.example.app.provider</code> mà nhận ra các URI nội dung
+ trỏ đến các bảng sau:
+</p>
+<ul>
+ <li>
+ <code>content://com.example.app.provider/table1</code>: Một bảng gọi là <code>table1</code>.
+ </li>
+ <li>
+ <code>content://com.example.app.provider/table2/dataset1</code>: Một bảng gọi là
+ <code>dataset1</code>.
+ </li>
+ <li>
+ <code>content://com.example.app.provider/table2/dataset2</code>: Một bảng gọi là
+ <code>dataset2</code>.
+ </li>
+ <li>
+ <code>content://com.example.app.provider/table3</code>: Một bảng gọi là <code>table3</code>.
+ </li>
+</ul>
+<p>
+ Trình cung cấp cũng nhận ra những URI nội dung này nếu chúng có một ID hàng được nối kèm, như
+ ví dụ <code>content://com.example.app.provider/table3/1</code> đối với hàng được nhận biết bởi
+ <code>1</code> trong <code>table3</code>.
+</p>
+<p>
+ Sẽ có thể có các kiểu mẫu URI nội dung sau:
+</p>
+<dl>
+ <dt>
+ <code>content://com.example.app.provider/*</code>
+ </dt>
+ <dd>
+ Khớp với bất kỳ URI nội dung nào trong trình cung cấp.
+ </dd>
+ <dt>
+ <code>content://com.example.app.provider/table2/*</code>:
+ </dt>
+ <dd>
+ Khớp với một URI nội dung cho các bảng <code>dataset1</code>
+ và <code>dataset2</code>, nhưng không khớp với URI nội dung cho <code>table1</code> hoặc
+ <code>table3</code>.
+ </dd>
+ <dt>
+ <code>content://com.example.app.provider/table3/#</code>: Khớp với một URI nội dung
+ cho các hàng đơn trong <code>table3</code>, chẳng hạn như
+ <code>content://com.example.app.provider/table3/6</code> đối với hàng được xác định bởi
+ <code>6</code>.
+ </dt>
+</dl>
+<p>
+ Đoạn mã HTML sau cho biết cách hoạt động của các phương pháp trong {@link android.content.UriMatcher}.
+ Đoạn mã này xử lý các URI cho toàn bộ một bảng khác với URI cho một
+ hàng đơn, bằng cách sử dụng mẫu hình URI nội dung
+ <code>content://&lt;authority&gt;/&lt;path&gt;</code> cho các bảng, và
+ <code>content://&lt;authority&gt;/&lt;path&gt;/&lt;id&gt;</code> cho các hàng đơn.
+</p>
+<p>
+ Phương pháp {@link android.content.UriMatcher#addURI(String, String, int) addURI()} ánh xạ một
+ thẩm quyền và đường dẫn tới một giá trị số nguyên. Phương pháp {@link android.content.UriMatcher#match(Uri)
+ match()} trả về giá trị số nguyên cho một URI. Câu lệnh <code>switch</code> sẽ chọn
+ giữa truy vấn toàn bộ bảng và truy vấn cho một bản ghi đơn:
+</p>
+<pre class="prettyprint">
+public class ExampleProvider extends ContentProvider {
+...
+ // Creates a UriMatcher object.
+ private static final UriMatcher sUriMatcher;
+...
+ /*
+ * The calls to addURI() go here, for all of the content URI patterns that the provider
+ * should recognize. For this snippet, only the calls for table 3 are shown.
+ */
+...
+ /*
+ * Sets the integer value for multiple rows in table 3 to 1. Notice that no wildcard is used
+ * in the path
+ */
+ sUriMatcher.addURI("com.example.app.provider", "table3", 1);
+
+ /*
+ * Sets the code for a single row to 2. In this case, the "#" wildcard is
+ * used. "content://com.example.app.provider/table3/3" matches, but
+ * "content://com.example.app.provider/table3 doesn't.
+ */
+ sUriMatcher.addURI("com.example.app.provider", "table3/#", 2);
+...
+ // Implements ContentProvider.query()
+ public Cursor query(
+ Uri uri,
+ String[] projection,
+ String selection,
+ String[] selectionArgs,
+ String sortOrder) {
+...
+ /*
+ * Choose the table to query and a sort order based on the code returned for the incoming
+ * URI. Here, too, only the statements for table 3 are shown.
+ */
+ switch (sUriMatcher.match(uri)) {
+
+
+ // If the incoming URI was for all of table3
+ case 1:
+
+ if (TextUtils.isEmpty(sortOrder)) sortOrder = "_ID ASC";
+ break;
+
+ // If the incoming URI was for a single row
+ case 2:
+
+ /*
+ * Because this URI was for a single row, the _ID value part is
+ * present. Get the last path segment from the URI; this is the _ID value.
+ * Then, append the value to the WHERE clause for the query
+ */
+ selection = selection + "_ID = " uri.getLastPathSegment();
+ break;
+
+ default:
+ ...
+ // If the URI is not recognized, you should do some error handling here.
+ }
+ // call the code to actually do the query
+ }
+</pre>
+<p>
+ Một lớp khác, {@link android.content.ContentUris}, sẽ cung cấp các phương pháp thuận tiện để làm việc
+ với phần <code>id</code> của URI nội dung. Các lớp {@link android.net.Uri} và
+ {@link android.net.Uri.Builder} bao gồm các phương pháp thuận tiện cho việc phân tích các đối tượng
+ {@link android.net.Uri} hiện có và xây dựng các đối tượng mới.
+</p>
+
+<!-- Implementing the ContentProvider class -->
+<h2 id="ContentProvider">Triển khai Lớp Trình cung cấp Nội dung</h2>
+<p>
+ Thực thể {@link android.content.ContentProvider} quản lý truy cập vào
+ một tập dữ liệu cấu trúc bằng cách xử lý yêu cầu từ các ứng dụng khác. Tất cả các dạng
+ truy cập cuối cùng đều gọi {@link android.content.ContentResolver}, sau đó nó gọi ra một phương pháp
+ cụ thể của {@link android.content.ContentProvider} để lấy quyền truy cập.
+</p>
+<h3 id="RequiredAccess">Phương pháp được yêu cầu</h3>
+<p>
+ Lớp tóm tắt {@link android.content.ContentProvider} sẽ định nghĩa sáu phương pháp tóm tắt
+ mà bạn phải triển khai như một phần lớp con cụ thể của mình. Tất cả những phương pháp này ngoại trừ
+ {@link android.content.ContentProvider#onCreate() onCreate()} đều được gọi ra bởi một ứng dụng máy khách
+ đang cố truy cập trình cung cấp nội dung của bạn:
+</p>
+<dl>
+ <dt>
+ {@link android.content.ContentProvider#query(Uri, String[], String, String[], String)
+ query()}
+ </dt>
+ <dd>
+ Truy xuất dữ liệu từ trình cung cấp của bạn. Sử dụng các tham đối để chọn bảng để
+ truy vấn, các hàng và cột để trả về, và thứ tự sắp xếp của kết quả.
+ Trả về dữ liệu như một đối tượng {@link android.database.Cursor}.
+ </dd>
+ <dt>
+ {@link android.content.ContentProvider#insert(Uri, ContentValues) insert()}
+ </dt>
+ <dd>
+ Chèn một hàng mới vào trình cung cấp của bạn. Sử dụng các tham đối để lựa chọn
+ bảng đích và nhận các giá trị cột để sử dụng. Trả về một URI nội dung cho
+ hàng mới chèn.
+ </dd>
+ <dt>
+ {@link android.content.ContentProvider#update(Uri, ContentValues, String, String[])
+ update()}
+ </dt>
+ <dd>
+ Cập nhật các hàng hiện tại trong trình cung cấp của bạn. Sử dụng các tham đối để lựa chọn bảng và hàng
+ để cập nhật và nhận các giá trị cột được cập nhật. Trả về số hàng được cập nhật.
+ </dd>
+ <dt>
+ {@link android.content.ContentProvider#delete(Uri, String, String[]) delete()}
+ </dt>
+ <dd>
+ Xóa hàng khỏi trình cung cấp của bạn. Sử dụng các tham đối để lựa chọn bảng và các hàng
+ cần xóa. Trả về số hàng được xóa.
+ </dd>
+ <dt>
+ {@link android.content.ContentProvider#getType(Uri) getType()}
+ </dt>
+ <dd>
+ Trả về kiểu MIME tương ứng với một URI nội dung. Phương pháp này được mô tả chi tiết hơn
+ trong phần <a href="#MIMETypes">Triển khai Kiểu MIME của Trình cung cấp Nội dung</a>.
+ </dd>
+ <dt>
+ {@link android.content.ContentProvider#onCreate() onCreate()}
+ </dt>
+ <dd>
+ Khởi tạo trình cung cấp của bạn. Hệ thống Android sẽ gọi ra phương pháp này ngay lập tức sau khi nó
+ tạo trình cung cấp của bạn. Để ý rằng trình cung cấp của bạn không được tạo cho đến khi đối tượng
+ {@link android.content.ContentResolver} cố truy cập nó.
+ </dd>
+</dl>
+<p>
+ Để ý rằng những phương pháp này có cùng chữ ký như các phương pháp
+ {@link android.content.ContentResolver} được đặt tên như nhau.
+</p>
+<p>
+ Việc bạn triển khai những phương pháp này nên xét tới các nội dung sau:
+</p>
+<ul>
+ <li>
+ Tất cả phương pháp này ngoại trừ {@link android.content.ContentProvider#onCreate() onCreate()}
+ đều có thể được gọi đồng thời bằng nhiều luồng, vì thế chúng phải an toàn đối với luồng. Để tìm hiểu
+ thêm về nhiều luồng, hãy xem chủ đề
+ <a href="{@docRoot}guide/components/processes-and-threads.html">
+ Tiến trình và Luồng</a>.
+ </li>
+ <li>
+ Tránh thực hiện những thao tác dài trong {@link android.content.ContentProvider#onCreate()
+ onCreate()}. Hoãn các tác vụ khởi tạo tới khi chúng thực sự cần thiết.
+ Phần <a href="#OnCreate">Triển khai phương pháp onCreate()</a>
+ sẽ bàn kỹ hơn về vấn đề này.
+ </li>
+ <li>
+ Mặc dù bạn phải triển khai những phương pháp này, mã của bạn không nhất thiết phải làm gì ngoại trừ việc
+ trả về kiểu dữ liệu kỳ vọng. Ví dụ, bạn có thể muốn ngăn những ứng dụng khác
+ chèn dữ liệu vào một số bảng. Để làm điều này, bạn có thể bỏ qua lệnh gọi tới
+ {@link android.content.ContentProvider#insert(Uri, ContentValues) insert()} và trả về
+ 0.
+ </li>
+</ul>
+<h3 id="Query">Triển khai phương pháp query()</h3>
+<p>
+ Phương pháp
+ {@link android.content.ContentProvider#query(Uri, String[], String, String[], String)
+ ContentProvider.query()} phải trả về một đối tượng {@link android.database.Cursor}, nếu không nó sẽ thất bại
+, đưa ra một lỗi {@link java.lang.Exception}. Nếu bạn đang sử dụng một cơ sở dữ liệu SQLite làm kho lưu trữ dữ liệu của mình
+, bạn có thể chỉ cần trả về {@link android.database.Cursor} được trả về bởi một trong các phương pháp
+ <code>query()</code> của lớp {@link android.database.sqlite.SQLiteDatabase}.
+ Nếu truy vấn không khớp với bất kỳ hàng nào, bạn nên trả về một thực thể {@link android.database.Cursor}
+ có phương pháp {@link android.database.Cursor#getCount()} trả về 0.
+ Bạn chỉ nên trả về <code>null</code> nếu đã xảy ra một lỗi nội bộ trong tiến trình truy vấn.
+</p>
+<p>
+ Nếu bạn không đang sử dụng một cơ sở dữ liệu SQLite làm kho lưu trữ dữ liệu của mình, hãy sử dụng một trong các lớp con cụ thể
+ của {@link android.database.Cursor}. Ví dụ, lớp {@link android.database.MatrixCursor} sẽ triển khai
+ một con chạy trong đó mỗi hàng là một mảng của {@link java.lang.Object}. Với lớp này,
+ hãy sử dụng {@link android.database.MatrixCursor#addRow(Object[]) addRow()} để thêm một hàng mới.
+</p>
+<p>
+ Nhớ rằng hệ thống Android phải có thể giao tiếp với {@link java.lang.Exception}
+ qua các ranh giới tiến trình. Android có thể làm vậy cho những trường hợp ngoại lệ sau, điều này có thể hữu ích
+ trong xử lý lỗi truy vấn:
+</p>
+<ul>
+ <li>
+ {@link java.lang.IllegalArgumentException} (Bạn có thể chọn đưa ra lỗi này nếu trình cung cấp của bạn
+ nhận một URI nội dung không hợp lệ)
+ </li>
+ <li>
+ {@link java.lang.NullPointerException}
+ </li>
+</ul>
+<h3 id="Insert">Triển khai phương pháp insert()</h3>
+<p>
+ Phương pháp {@link android.content.ContentProvider#insert(Uri, ContentValues) insert()} sẽ thêm một
+ hàng mới vào bảng phù hợp bằng cách sử dụng các giá trị trong tham đối {@link android.content.ContentValues}
+. Nếu tên cột không nằm trong tham đối {@link android.content.ContentValues}, bạn có thể
+ muốn cung cấp một giá trị mặc định cho nó hoặc trong mã trình cung cấp của bạn hoặc trong sơ đồ
+ cơ sở dữ liệu của bạn.
+</p>
+<p>
+ Phương pháp này sẽ trả về URI nội dung cho hàng mới. Để xây dựng điều này, hãy nối
+ giá trị <code>_ID</code> của hàng mới (hay khóa chính khác) với URI nội dung của bảng bằng cách sử dụng
+ {@link android.content.ContentUris#withAppendedId(Uri, long) withAppendedId()}.
+</p>
+<h3 id="Delete">Triển khai phương pháp delete()</h3>
+<p>
+ Phương pháp {@link android.content.ContentProvider#delete(Uri, String, String[]) delete()}
+ không cần phải xóa hàng thực chất khỏi kho lưu trữ dữ liệu của bạn. Nếu bạn đang sử dụng một trình điều hợp đồng bộ
+ với trình cung cấp của mình, bạn nên cân nhắc đánh dấu một hàng đã xóa
+ bằng cờ "xóa" thay vì gỡ bỏ hàng một cách hoàn toàn. Trình điều hợp đồng bộ có thể
+ kiểm tra các hàng đã xóa và gỡ bỏ chúng khỏi máy chủ trước khi xóa chúng khỏi trình cung cấp.
+</p>
+<h3 id="Update">Triển khai phương pháp update()</h3>
+<p>
+ Phương pháp {@link android.content.ContentProvider#update(Uri, ContentValues, String, String[])
+ update()} lấy cùng tham đối {@link android.content.ContentValues} được sử dụng bởi
+ {@link android.content.ContentProvider#insert(Uri, ContentValues) insert()}, và
+ cùng tham đối <code>selection</code> và <code>selectionArgs</code> được sử dụng bởi
+ {@link android.content.ContentProvider#delete(Uri, String, String[]) delete()} và
+ {@link android.content.ContentProvider#query(Uri, String[], String, String[], String)
+ ContentProvider.query()}. Điều này có thể cho phép bạn sử dụng lại mã giữa những phương pháp này.
+</p>
+<h3 id="OnCreate">Triển khai phương pháp onCreate()</h3>
+<p>
+ Hệ thống Android sẽ gọi {@link android.content.ContentProvider#onCreate()
+ onCreate()} khi nó khởi động trình cung cấp. Bạn chỉ nên thực hiện các tác vụ khởi tạo chạy nhanh
+ trong phương pháp này, và hoãn việc tạo cơ sở dữ liệu và nạp dữ liệu tới khi trình cung cấp thực sự
+ nhận được yêu cầu cho dữ liệu. Nếu bạn thực hiện các tác vụ dài trong
+ {@link android.content.ContentProvider#onCreate() onCreate()}, bạn sẽ làm chậm lại
+ quá trình khởi động của trình cung cấp. Đến lượt mình, điều này sẽ làm chậm hồi đáp từ trình cung cấp đối với các
+ ứng dụng khác.
+</p>
+<p>
+ Ví dụ, nếu bạn đang sử dụng một cơ sở dữ liệu SQLite, bạn có thể tạo
+ một đối tượng {@link android.database.sqlite.SQLiteOpenHelper} mới trong
+ {@link android.content.ContentProvider#onCreate() ContentProvider.onCreate()},
+ rồi tạo các bảng SQL lần đầu tiên khi bạn mở cơ sở dữ liệu. Để tạo điều kiện cho điều này,
+ lần đầu tiên bạn gọi {@link android.database.sqlite.SQLiteOpenHelper#getWritableDatabase
+ getWritableDatabase()}, nó sẽ tự động gọi ra phương pháp
+ {@link android.database.sqlite.SQLiteOpenHelper#onCreate(SQLiteDatabase)
+ SQLiteOpenHelper.onCreate()}.
+</p>
+<p>
+ Hai đoạn mã HTML sau minh họa tương tác giữa
+ {@link android.content.ContentProvider#onCreate() ContentProvider.onCreate()} và
+ {@link android.database.sqlite.SQLiteOpenHelper#onCreate(SQLiteDatabase)
+ SQLiteOpenHelper.onCreate()}. Đoạn mã HTML đầu tiên là triển khai
+ {@link android.content.ContentProvider#onCreate() ContentProvider.onCreate()}:
+</p>
+<pre class="prettyprint">
+public class ExampleProvider extends ContentProvider
+
+ /*
+ * Defines a handle to the database helper object. The MainDatabaseHelper class is defined
+ * in a following snippet.
+ */
+ private MainDatabaseHelper mOpenHelper;
+
+ // Defines the database name
+ private static final String DBNAME = "mydb";
+
+ // Holds the database object
+ private SQLiteDatabase db;
+
+ public boolean onCreate() {
+
+ /*
+ * Creates a new helper object. This method always returns quickly.
+ * Notice that the database itself isn't created or opened
+ * until SQLiteOpenHelper.getWritableDatabase is called
+ */
+ mOpenHelper = new MainDatabaseHelper(
+ getContext(), // the application context
+ DBNAME, // the name of the database)
+ null, // uses the default SQLite cursor
+ 1 // the version number
+ );
+
+ return true;
+ }
+
+ ...
+
+ // Implements the provider's insert method
+ public Cursor insert(Uri uri, ContentValues values) {
+ // Insert code here to determine which table to open, handle error-checking, and so forth
+
+ ...
+
+ /*
+ * Gets a writeable database. This will trigger its creation if it doesn't already exist.
+ *
+ */
+ db = mOpenHelper.getWritableDatabase();
+ }
+}
+</pre>
+<p>
+ Đoạn mã HTML tiếp theo là triển khai
+ {@link android.database.sqlite.SQLiteOpenHelper#onCreate(SQLiteDatabase)
+ SQLiteOpenHelper.onCreate()}, bao gồm một lớp trình trợ giúp:
+</p>
+<pre class="prettyprint">
+...
+// A string that defines the SQL statement for creating a table
+private static final String SQL_CREATE_MAIN = "CREATE TABLE " +
+ "main " + // Table's name
+ "(" + // The columns in the table
+ " _ID INTEGER PRIMARY KEY, " +
+ " WORD TEXT"
+ " FREQUENCY INTEGER " +
+ " LOCALE TEXT )";
+...
+/**
+ * Helper class that actually creates and manages the provider's underlying data repository.
+ */
+protected static final class MainDatabaseHelper extends SQLiteOpenHelper {
+
+ /*
+ * Instantiates an open helper for the provider's SQLite data repository
+ * Do not do database creation and upgrade here.
+ */
+ MainDatabaseHelper(Context context) {
+ super(context, DBNAME, null, 1);
+ }
+
+ /*
+ * Creates the data repository. This is called when the provider attempts to open the
+ * repository and SQLite reports that it doesn't exist.
+ */
+ public void onCreate(SQLiteDatabase db) {
+
+ // Creates the main table
+ db.execSQL(SQL_CREATE_MAIN);
+ }
+}
+</pre>
+
+
+<!-- Implementing ContentProvider MIME Types -->
+<h2 id="MIMETypes">Triển khai Kiểu MIME của Trình cung cấp Nội dung</h2>
+<p>
+ Lớp {@link android.content.ContentProvider} có hai phương pháp để trả về các kiểu MIME:
+</p>
+<dl>
+ <dt>
+ {@link android.content.ContentProvider#getType(Uri) getType()}
+ </dt>
+ <dd>
+ Một trong các phương pháp được yêu cầu mà bạn phải triển khai cho bất kỳ trình cung cấp nào.
+ </dd>
+ <dt>
+ {@link android.content.ContentProvider#getStreamTypes(Uri, String) getStreamTypes()}
+ </dt>
+ <dd>
+ Một phương pháp mà bạn được dự tính sẽ triển khai nếu trình cung cấp của bạn cung cấp tệp.
+ </dd>
+</dl>
+<h3 id="TableMIMETypes">Kiểu MIME cho bảng</h3>
+<p>
+ Phương pháp {@link android.content.ContentProvider#getType(Uri) getType()} trả về một
+ {@link java.lang.String} theo định dạng MIME mà mô tả kiểu dữ liệu được trả về bởi tham đối
+ URI nội dung. Tham đối {@link android.net.Uri} có thể là một mẫu hình thay vì một URI cụ thể;
+ trong trường hợp này, bạn nên trả về kiểu dữ liệu được liên kết với các URI nội dung mà khớp với
+ mẫu hình đó.
+</p>
+<p>
+ Đối với các kiểu dữ liệu phổ biến như văn bản, HTML, hay JPEG,
+ {@link android.content.ContentProvider#getType(Uri) getType()} sẽ trả về
+ kiểu MIME tiêu chuẩn cho dữ liệu đó. Một danh sách đầy đủ về những kiểu tiêu chuẩn này có sẵn trên trang web
+ <a href="http://www.iana.org/assignments/media-types/index.htm">IANA MIME Media Types</a>
+.
+</p>
+<p>
+ Đối với các URI nội dung mà trỏ tới một hàng hoặc các hàng của bảng dữ liệu,
+ {@link android.content.ContentProvider#getType(Uri) getType()} sẽ trả về
+ một kiểu MIME theo định dạng MIME riêng cho nhà cung cấp của Android:
+</p>
+<ul>
+ <li>
+ Bộ phận kiểu: <code>vnd</code>
+ </li>
+ <li>
+ Bộ phận kiểu con:
+ <ul>
+ <li>
+ Nếu mẫu hình URI áp dụng cho một hàng đơn: <code>android.cursor.<strong>item</strong>/</code>
+ </li>
+ <li>
+ Nếu mẫu hình URI áp dụng cho nhiều hơn một hàng: <code>android.cursor.<strong>dir</strong>/</code>
+ </li>
+ </ul>
+ </li>
+ <li>
+ Bộ phận riêng theo trình cung cấp: <code>vnd.&lt;name&gt;</code>.<code>&lt;type&gt;</code>
+ <p>
+ Bạn cung cấp <code>&lt;name&gt;</code> và <code>&lt;type&gt;</code>.
+ Giá trị <code>&lt;name&gt;</code> nên là giá trị duy nhất toàn cục,
+ và giá trị <code>&lt;type&gt;</code> nên là giá trị duy nhất đối với mẫu hình
+ URI tương ứng. Một lựa chọn hay cho <code>&lt;name&gt;</code> đó là tên công ty của bạn hoặc
+ một thành phần nào đó trong tên gói Android cho ứng dụng của bạn. Một lựa chọn hay cho
+ <code>&lt;type&gt;</code> đó là một xâu xác định bảng được liên kết với
+ URI.
+ </p>
+
+ </li>
+</ul>
+<p>
+ Ví dụ, nếu thẩm quyền của một trình cung cấp là
+ <code>com.example.app.provider</code>, và nó làm hiện ra một bảng có tên
+ <code>table1</code> thì kiểu MIME cho nhiều hàng trong <code>table1</code> là:
+</p>
+<pre>
+vnd.android.cursor.<strong>dir</strong>/vnd.com.example.provider.table1
+</pre>
+<p>
+ Đối với một hàng đơn của <code>table1</code>, kiểu MIME là:
+</p>
+<pre>
+vnd.android.cursor.<strong>item</strong>/vnd.com.example.provider.table1
+</pre>
+<h3 id="FileMIMETypes">Kiểu MIME cho tệp</h3>
+<p>
+ Nếu trình cung cấp của bạn cung cấp tệp, hãy triển khai
+ {@link android.content.ContentProvider#getStreamTypes(Uri, String) getStreamTypes()}.
+ Phương pháp này sẽ trả về một mảng {@link java.lang.String} của kiểu MIME đối với các tệp mà trình cung cấp của bạn
+ có thể trả về cho một URI nội dung cho trước. Bạn nên lọc các kiểu MIME mà mình cung cấp bằng tham đối bộ lọc
+ kiểu MIME, sao cho bạn chỉ trả về những kiểu MIME mà máy khách muốn xử lý.
+</p>
+<p>
+ Ví dụ, xét một trình cung cấp hình ảnh dưới dạng tệp có định dạng <code>.jpg</code>,
+ <code>.png</code> và <code>.gif</code>.
+ Nếu một ứng dụng gọi {@link android.content.ContentResolver#getStreamTypes(Uri, String)
+ ContentResolver.getStreamTypes()} bằng xâu bộ lọc <code>image/*</code> (
+ mà là một "hình ảnh"),
+ khi đó phương pháp {@link android.content.ContentProvider#getStreamTypes(Uri, String)
+ ContentProvider.getStreamTypes()} sẽ trả về mảng:
+</p>
+<pre>
+{ &quot;image/jpeg&quot;, &quot;image/png&quot;, &quot;image/gif&quot;}
+</pre>
+<p>
+ Nếu ứng dụng chỉ quan tâm đến các tệp <code>.jpg</code>, vậy nó có thể gọi
+ {@link android.content.ContentResolver#getStreamTypes(Uri, String)
+ ContentResolver.getStreamTypes()} bằng xâu bộ lọc <code>*\/jpeg</code>, và
+ {@link android.content.ContentProvider#getStreamTypes(Uri, String)
+ ContentProvider.getStreamTypes()} sẽ trả về:
+<pre>
+{&quot;image/jpeg&quot;}
+</pre>
+<p>
+ Nếu trình cung cấp của bạn không cung cấp bất kỳ kiểu MIME nào được yêu cầu trong xâu bộ lọc,
+ {@link android.content.ContentProvider#getStreamTypes(Uri, String) getStreamTypes()}
+ sẽ trả về <code>null</code>.
+</p>
+
+
+<!-- Implementing a Contract Class -->
+<h2 id="ContractClass">Triển khai một Lớp Hợp đồng</h2>
+<p>
+ Lớp hợp đồng là một lớp <code>public final</code> chứa các định nghĩa hằng số cho
+ URI, tên cột, kiểu MIME, và siêu dữ liệu khác liên quan tới trình cung cấp. Lớp này
+ sẽ thiết lập một hợp đồng giữa trình cung cấp và các ứng dụng khác bằng cách đảm bảo rằng trình cung cấp
+ có thể được truy cập đúng ngay cả khi có thay đổi về giá trị thực sự của URI, tên cột,
+ v.v.
+</p>
+<p>
+ Lớp hợp đồng cũng giúp các nhà phát triển vì chúng thường có tên dễ nhớ cho các hằng số của mình,
+ vì vậy các nhà phát triển ít có khả năng sử dụng các giá trị không đúng cho tên cột hay URI hơn. Do đó là một
+ lớp, nó có thể chứa tài liệu Javadoc. Các môi trường phát triển tích hợp như
+ Eclipse có thể tự động điền các tên hằng số từ lớp hợp đồng và hiển thị Javadoc cho các
+ hằng số đó.
+</p>
+<p>
+ Các nhà phát triển không thể truy cập tệp lớp của lớp hợp đồng từ ứng dụng của mình, nhưng họ có thể
+ lặng lẽ biên dịch nó vào ứng dụng của họ từ một tệp <code>.jar</code> mà bạn cung cấp.
+</p>
+<p>
+ Lớp {@link android.provider.ContactsContract} và các lớp lồng nhau của nó là các ví dụ về
+ lớp hợp đồng.
+</p>
+<h2 id="Permissions">Triển khai Quyền của Trình cung cấp Nội dung</h2>
+<p>
+ Quyền và truy cập đối với tất cả khía cạnh trong hệ thống Android được mô tả chi tiết trong
+ chủ đề <a href="{@docRoot}guide/topics/security/security.html">Bảo mật và Quyền</a>.
+ Chủ đề <a href="{@docRoot}guide/topics/data/data-storage.html">Kho lưu trữ Dữ liệu</a> cũng
+ mô tả bảo mật và các quyền có hiệu lực cho nhiều loại kho lưu trữ khác nhau.
+ Nói tóm lại, các điểm quan trọng là:
+</p>
+<ul>
+ <li>
+ Theo mặc định, các tệp dữ liệu được lưu trữ trên bộ nhớ trong của thiết bị là dữ liệu riêng tư
+ đối với ứng dụng và trình cung cấp của bạn.
+ </li>
+ <li>
+ Các cơ sở dữ liệu {@link android.database.sqlite.SQLiteDatabase} mà bạn tạo là dữ liệu riêng tư
+ đối với ứng dụng và trình cung cấp của bạn.
+ </li>
+ <li>
+ Theo mặc định, các tệp dữ liệu mà bạn lưu vào bộ nhớ ngoài là dữ liệu <em>công khai</em> và
+ <em>đọc được công khai</em>. Bạn không thể sử dụng một trình cung cấp nội dung để hạn chế truy cập vào các tệp trong
+ bộ nhớ ngoài vì các ứng dụng khác có thể sử dụng lệnh gọi API khác để đọc và ghi chúng.
+ </li>
+ <li>
+ Các lệnh gọi phương pháp để mở hoặc tạo tệp hoặc cơ sở dữ liệu SQLite trên bộ nhớ trong
+ của thiết bị của bạn có thể cấp quyền truy cập đọc và ghi cho tất cả ứng dụng khác. Nếu bạn
+ sử dụng một tệp hoặc cơ sở dữ liệu nội bộ làm kho lưu giữ của trình cung cấp của mình, và bạn cấp quyền truy cập
+ "đọc được công khai" hoặc "ghi được công khai", quyền mà bạn đặt cho trình cung cấp của mình trong
+ bản kê khai của nó sẽ không bảo vệ dữ liệu của bạn. Quyền truy cập mặc định cho các tệp và cơ sở dữ liệu trong
+ bộ nhớ trong là "riêng tư", và đối với kho lưu giữ của trình cung cấp của mình, bạn không nên thay đổi điều này.
+ </li>
+</ul>
+<p>
+ Nếu bạn muốn sử dụng các quyền của trình cung cấp nội dung để kiểm soát truy cập vào dữ liệu của mình, khi đó bạn nên
+ lưu trữ dữ liệu của mình trong các tệp nội bộ, cơ sở dữ liệu SQLite, hoặc "đám mây" (ví dụ,
+ trên một máy chủ từ xa), và bạn nên giữ các tệp và cơ sở dữ liệu riêng tư cho ứng dụng của mình.
+</p>
+<h3>Triển khai quyền</h3>
+<p>
+ Tất cả ứng dụng đều có thể đọc từ hoặc ghi vào trình cung cấp của bạn, ngay cả khi dữ liệu liên quan
+ là dữ liệu riêng tư, vì theo mặc định, trình cung cấp của bạn không được đặt quyền. Để thay đổi điều này,
+ hãy đặt quyền cho trình cung cấp của bạn trong tệp bản kê khai của bạn bằng cách sử dụng các thuộc tính hoặc phần tử
+ con của phần tử <code><a href="{@docRoot}guide/topics/manifest/provider-element.html">
+ &lt;provider&gt;</a></code>. Bạn có thể đặt quyền áp dụng cho toàn bộ trình cung cấp,
+ hoặc cho một số bảng, hoặc thậm chí cho một số bản ghi, hoặc cả ba.
+</p>
+<p>
+ Bạn định nghĩa các quyền cho trình cung cấp của bạn bằng một hoặc nhiều phần tử
+ <code><a href="{@docRoot}guide/topics/manifest/permission-element.html">
+ &lt;permission&gt;</a></code> trong tệp bản kê khai của bạn. Để
+ quyền là duy nhất cho trình cung cấp của bạn, hãy sử dụng phạm vi kiểu Java cho thuộc tính
+ <code><a href="{@docRoot}guide/topics/manifest/permission-element.html#nm">
+ android:name</a></code>. Ví dụ, đặt tên quyền đọc
+ <code>com.example.app.provider.permission.READ_PROVIDER</code>.
+
+</p>
+<p>
+ Danh sách sau liệt kê phạm vi các quyền của trình cung cấp, bắt đầu với các quyền
+ áp dụng cho toàn bộ trình cung cấp rồi mới đến các quyền chi tiết hơn.
+ Các quyền chi tiết hơn được ưu tiên so với các quyền có phạm vi rộng hơn:
+</p>
+<dl>
+ <dt>
+ Quyền đọc-ghi đơn lẻ ở cấp trình cung cấp
+ </dt>
+ <dd>
+ Một quyền kiểm soát cả quyền truy cập đọc và ghi cho toàn bộ trình cung cấp, được quy định
+ bằng thuộc tính <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#prmsn">
+ android:permission</a></code> của phần tử
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html">
+ &lt;provider&gt;</a></code>.
+ </dd>
+ <dt>
+ Quyền đọc ghi tách riêng ở cấp độ trình cung cấp
+ </dt>
+ <dd>
+ Một quyền đọc và một quyền ghi cho toàn bộ trình cung cấp. Bạn chỉ định chúng
+ bằng các thuộc tính <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#rprmsn">
+ android:readPermission</a></code> và
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#wprmsn">
+ android:writePermission</a></code> của phần tử
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html">
+ &lt;provider&gt;</a></code>. Chúng được ưu tiên so với quyền được yêu cầu bởi
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#prmsn">
+ android:permission</a></code>.
+ </dd>
+ <dt>
+ Quyền ở cấp đường dẫn
+ </dt>
+ <dd>
+ Quyền đọc, ghi, hoặc đọc/ghi cho một URI nội dung trong trình cung cấp của bạn. Bạn chỉ định
+ từng URI mà bạn muốn kiểm soát bằng một phần tử con
+ <code><a href="{@docRoot}guide/topics/manifest/path-permission-element.html">
+ &lt;path-permission&gt;</a></code> của phần tử
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html">
+ &lt;provider&gt;</a></code>. Với mỗi một URI nội dung mà bạn chỉ định, bạn có thể chỉ định một
+ quyền đọc/ghi, quyền đọc, hoặc quyền ghi, hoặc cả ba. Quyền đọc và
+ quyền ghi được ưu tiên so với quyền đọc/ghi. Đồng thời, quyền ở cấp độ đường dẫn
+ sẽ được ưu tiên so với quyền ở cấp độ trình cung cấp.
+ </dd>
+ <dt>
+ Quyền tạm thời
+ </dt>
+ <dd>
+ Là cấp độ quyền cho phép truy cập tạm thời vào một ứng dụng, ngay cả khi ứng dụng
+ không có các quyền thường được yêu cầu. Tính năng truy cập
+ tạm thời làm giảm số quyền mà một ứng dụng phải yêu cầu trong
+ bản kê khai của mình. Khi bạn dùng đến các quyền tạm thời, những ứng dụng duy nhất mà cần
+ quyền "lâu dài" cho trình cung cấp của bạn là những ứng dụng liên tục truy cập tất cả
+ dữ liệu của bạn.
+ <p>
+ Xét các quyền bạn cần để triển khai một trình cung cấp và ứng dụng e-mail khi bạn
+ muốn cho phép một ứng dụng trình xem ảnh bên ngoài hiển thị các tài liệu đính kèm dạng ảnh từ trình cung cấp
+ của bạn. Để cấp cho trình xem ảnh quyền truy cập cần thiết mà không cần yêu cầu quyền,
+ hãy thiết lập các quyền tạm thời cho URI nội dung đối với ảnh. Thiết kế ứng dụng e-mail của bạn sao cho
+ khi người dùng muốn hiển thị một ảnh, ứng dụng sẽ gửi một ý định chứa URI nội dung
+ của ảnh và cờ cho phép tới trình xem ảnh. Trình xem ảnh khi đó có thể
+ truy vấn trình cung cấp e-mail của bạn để truy xuất ảnh, ngay cả khi trình xem không
+ có quyền đọc bình thường cho trình cung cấp của bạn.
+ </p>
+ <p>
+ Để sử dụng các quyền tạm thời, hoặc đặt thuộc tính
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#gprmsn">
+ android:grantUriPermissions</a></code> của phần tử
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html">
+ &lt;provider&gt;</a></code> hoặc thêm một hoặc nhiều phần tử con
+ <code><a href="{@docRoot}guide/topics/manifest/grant-uri-permission-element.html">
+ &lt;grant-uri-permission&gt;</a></code> vào phần tử
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html">
+ &lt;provider&gt;</a></code> của bạn. Nếu bạn sử dụng các quyền tạm thời, bạn phải gọi
+ {@link android.content.Context#revokeUriPermission(Uri, int)
+ Context.revokeUriPermission()} bất cứ khi nào bạn gỡ bỏ hỗ trợ cho một URI nội dung khỏi
+ trình cung cấp của mình, và URI nội dung đó sẽ được liên kết với một quyền tạm thời.
+ </p>
+ <p>
+ Giá trị của thuộc tính sẽ xác định trình cung cấp của bạn được cho phép truy cập bao nhiêu.
+ Nếu thuộc tính được đặt thành <code>true</code>, khi đó hệ thống sẽ cấp quyền tạm thời
+ cho toàn bộ trình cung cấp của bạn, khống chế mọi quyền khác mà được yêu cầu bởi
+ quyền ở cấp độ trình cung cấp hoặc cấp độ đường dẫn của bạn.
+ </p>
+ <p>
+ Nếu cờ này được đặt thành <code>false</code>, khi đó bạn phải thêm các phần tử con
+ <code><a href="{@docRoot}guide/topics/manifest/grant-uri-permission-element.html">
+ &lt;grant-uri-permission&gt;</a></code> vào phần tử
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html">
+ &lt;provider&gt;</a></code> của mình. Mỗi phần tử con lại quy định URI nội dung hoặc
+ các URI mà truy cập tạm thời được cấp cho.
+ </p>
+ <p>
+ Để ủy quyền truy cập tạm thời cho một ứng dụng, ý định phải chứa
+ cờ {@link android.content.Intent#FLAG_GRANT_READ_URI_PERMISSION} hoặc cờ
+ {@link android.content.Intent#FLAG_GRANT_WRITE_URI_PERMISSION}, hoặc cả hai. Những quyền
+ này được đặt bằng phương pháp {@link android.content.Intent#setFlags(int) setFlags()}.
+ </p>
+ <p>
+ Nếu thuộc tính <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#gprmsn">
+ android:grantUriPermissions</a></code> không có mặt, giả sử rằng nó là
+ <code>false</code>.
+ </p>
+ </dd>
+</dl>
+
+
+
+<!-- The Provider Element -->
+<h2 id="ProviderElement">Phần tử &lt;provider&gt;</h2>
+<p>
+ Như các thành phần {@link android.app.Activity} và {@link android.app.Service},
+ một lớp con của {@link android.content.ContentProvider}
+ phải được định nghĩa trong tệp bản kê khai cho ứng dụng của nó bằng cách sử dụng phần tử
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html">
+ &lt;provider&gt;</a></code>. Hệ thống Android nhận thông tin sau từ
+ phần tử:
+<dl>
+ <dt>
+ Thẩm quyền
+ (<a href="{@docRoot}guide/topics/manifest/provider-element.html#auth">{@code
+ android:authorities}</a>)
+ </dt>
+ <dd>
+ Các tên biểu tượng nhận biết toàn bộ trình cung cấp trong hệ thống. Thuộc tính
+ này được mô tả chi tiết hơn trong phần
+ <a href="#ContentURI">Thiết kế URI Nội dung</a>.
+ </dd>
+ <dt>
+ Tên lớp của trình cung cấp
+ (<code>
+<a href="{@docRoot}guide/topics/manifest/provider-element.html#nm">android:name</a>
+ </code>)
+ </dt>
+ <dd>
+ Lớp triển khai {@link android.content.ContentProvider}. Lớp này
+ được mô tả chi tiết hơn trong phần
+ <a href="#ContentProvider">Triển khai Lớp Trình cung cấp Nội dung</a>.
+ </dd>
+ <dt>
+ Quyền
+ </dt>
+ <dd>
+ Những thuộc tính quy định quyền mà các ứng dụng khác phải có để truy cập
+ dữ liệu của trình cung cấp:
+ <ul>
+ <li>
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#gprmsn">
+ android:grantUriPermssions</a></code>: Cờ quyền tạm thời.
+ </li>
+ <li>
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#prmsn">
+ android:permission</a></code>: Quyền đọc/ghi đơn lẻ đối với toàn bộ trình cung cấp.
+ </li>
+ <li>
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#rprmsn">
+ android:readPermission</a></code>: Quyền đọc đối với toàn bộ trình cung cấp.
+ </li>
+ <li>
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#wprmsn">
+ android:writePermission</a></code>: Quyền ghi đối với toàn bộ trình cung cấp.
+ </li>
+ </ul>
+ <p>
+ Các quyền và thuộc tính tương ứng của chúng được mô tả chi tiết hơn trong
+ phần
+ <a href="#Permissions">Triển khai Quyền của Trình cung cấp Nội dung</a>.
+ </p>
+ </dd>
+ <dt>
+ Thuộc tính khởi động và kiểm soát
+ </dt>
+ <dd>
+ Những thuộc tính này xác định cách và thời điểm hệ thống Android khởi động trình cung cấp, các
+ đặc tính tiến trình của trình cung cấp, và các thiết đặt về thời gian chạy:
+ <ul>
+ <li>
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#enabled">
+ android:enabled</a></code>: Cờ cho phép hệ thống khởi động trình cung cấp.
+ </li>
+ <li>
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#exported">
+ android:exported</a></code>: Cờ cho phép các ứng dụng sử dụng trình cung cấp này.
+ </li>
+ <li>
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#init">
+ android:initOrder</a></code>: Thứ tự mà trình cung cấp nên được khởi động,
+ so với các trình cung cấp khác trong cùng tiến trình.
+ </li>
+ <li>
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#multi">
+ android:multiProcess</a></code>: Cờ cho phép hệ thống khởi động trình cung cấp
+ trong cùng tiến trình như máy khách gọi.
+ </li>
+ <li>
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#proc">
+ android:process</a></code>: Tên của tiến trình mà trình cung cấp
+ nên chạy trong đó.
+ </li>
+ <li>
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#sync">
+ android:syncable</a></code>: Cờ cho biết rằng dữ liệu của trình cung cấp sẽ được
+ đồng bộ với dữ liệu trên một máy chủ.
+ </li>
+ </ul>
+ <p>
+ Các thuộc tính được lập tài liệu theo dõi đầy đủ trong chủ đề hướng dẫn nhà phát triển đối với phần tử
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html">
+ &lt;provider&gt;</a></code>
+.
+ </p>
+ </dd>
+ <dt>
+ Các thuộc tính thông tin
+ </dt>
+ <dd>
+ Một biểu tượng tùy chọn và nhãn cho trình cung cấp:
+ <ul>
+ <li>
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#icon">
+ android:icon</a></code>: Một tài nguyên có thể vẽ chứa một biểu tượng cho trình cung cấp.
+ Biểu tượng xuất hiện bên cạnh nhãn của trình cung cấp trong danh sách ứng dụng trong
+ <em>Settings</em> &gt; <em>Apps</em> &gt; <em>All</em>.
+ </li>
+ <li>
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html#label">
+ android:label</a></code>: Một nhãn thông tin mô tả trình cung cấp hoặc dữ liệu
+ của nó, hoặc cả hai. Nhãn xuất hiện trong danh sách ứng dụng trong
+ <em>Settings</em> &gt; <em>Apps</em> &gt; <em>All</em>.
+ </li>
+ </ul>
+ <p>
+ Các thuộc tính được lập tài liệu theo dõi đầy đủ trong chủ đề hướng dẫn nhà phát triển đối với phần tử
+ <code><a href="{@docRoot}guide/topics/manifest/provider-element.html">
+ &lt;provider&gt;</a></code>.
+ </p>
+ </dd>
+</dl>
+
+<!-- Intent Access -->
+<h2 id="Intents">Ý định và Truy cập Dữ liệu</h2>
+<p>
+ Các ứng dụng có thể gián tiếp truy cập một trình cung cấp nội dung bằng một {@link android.content.Intent}.
+ Ứng dụng không gọi bất kỳ phương pháp nào của {@link android.content.ContentResolver} hoặc
+ {@link android.content.ContentProvider}. Thay vào đó, nó sẽ gửi một ý định để bắt đầu một hoạt động,
+ đây thường là một bộ phận trong ứng dụng của chính trình cung cấp. Hoạt động đích phụ trách
+ truy xuất và hiển thị dữ liệu trong UI của nó. Tùy vào hành động trong ý định, hoạt động
+ đích cũng có thể nhắc người dùng thực hiện sửa đổi dữ liệu của trình cung cấp.
+ Một ý định cũng có thể chứa dữ liệu "phụ thêm" mà hoạt động đích hiển thị
+ trong UI; khi đó người dùng có tùy chọn thay đổi dữ liệu này trước khi sử dụng nó để sửa đổi
+ dữ liệu trong trình cung cấp.
+</p>
+<p>
+
+</p>
+<p>
+ Bạn có thể muốn sử dụng truy cập ý định để giúp đảm bảo toàn vẹn dữ liệu. Trình cung cấp của bạn có thể phụ thuộc vào
+ việc chèn, cập nhật và xóa dữ liệu theo lô-gic nghiệp vụ được quy định chặt chẽ. Trong
+ trường hợp như vậy, việc cho phép các ứng dụng khác trực tiếp sửa đổi dữ liệu của bạn có thể dẫn đến dữ liệu
+ không hợp lệ. Nếu bạn muốn các nhà phát triển sử dụng truy cập ý định, hãy đảm bảo lập tài liệu theo dõi nó thật kỹ.
+ Giải thích với họ tại sao truy cập ý định sử dụng UI ứng dụng của chính bạn lại tốt hơn là cố gắng sửa đổi
+ dữ liệu bằng mã của họ.
+</p>
+<p>
+ Việc xử lý một ý định đến nhằm sửa đổi dữ liệu của trình cung cấp của bạn không khác với
+ việc xử lý các ý định khác. Bạn có thể tìm hiểu về việc sử dụng ý định bằng cách đọc chủ đề
+ <a href="{@docRoot}guide/components/intents-filters.html">Ý định và Bộ lọc Ý định</a>.
+</p>
diff --git a/docs/html-intl/intl/vi/guide/topics/providers/content-providers.jd b/docs/html-intl/intl/vi/guide/topics/providers/content-providers.jd
new file mode 100644
index 000000000000..0b0233705d87
--- /dev/null
+++ b/docs/html-intl/intl/vi/guide/topics/providers/content-providers.jd
@@ -0,0 +1,108 @@
+page.title=Trình cung cấp Nội dung
+@jd:body
+<div id="qv-wrapper">
+<div id="qv">
+
+
+<!-- In this document -->
+<h2>Chủ đề</h2>
+<ol>
+ <li>
+ <a href="{@docRoot}guide/topics/providers/content-provider-basics.html">
+ Nội dung Cơ bản về Trình cung cấp Nội dung</a>
+ </li>
+ <li>
+ <a href="{@docRoot}guide/topics/providers/content-provider-creating.html">
+ Tạo một Trình cung cấp Nội dung</a>
+ </li>
+ <li>
+ <a href="{@docRoot}guide/topics/providers/calendar-provider.html">Trình cung cấp Lịch</a>
+ </li>
+ <li>
+ <a href="{@docRoot}guide/topics/providers/contacts-provider.html">Trình cung cấp Danh bạ</a>
+ </li>
+</ol>
+
+ <!-- Related Samples -->
+<h2>Các Mẫu Liên quan</h2>
+ <ol>
+ <li>
+ <a href="{@docRoot}resources/samples/ContactManager/index.html">
+ Ứng dụng Trình quản lý Danh bạ</a>
+ </li>
+ <li>
+ <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/List2.html">
+ "Con chạy (Danh bạ)"
+ </a>
+ </li>
+ <li>
+ <a href="{@docRoot}resources/samples/ApiDemos/src/com/example/android/apis/view/List7.html">
+ "Con chạy (Điện thoại)"</a>
+ </li>
+ <li>
+ <a href="{@docRoot}resources/samples/SampleSyncAdapter/index.html">
+ Trình điều hợp Đồng bộ Mẫu</a>
+ </li>
+ </ol>
+</div>
+</div>
+<p>
+ Trình cung cấp nội dung quản lý truy cập vào một tập dữ liệu cấu trúc. Chúng gói gọn
+ dữ liệu và cung cấp các cơ chế để định nghĩa bảo mật dữ liệu. Trình cung cấp nội dung là
+ giao diện tiêu chuẩn kết nối dữ liệu trong một tiến trình với mã đang chạy trong một tiến trình khác.
+</p>
+<p>
+ Khi bạn truy cập dữ liệu trong một trình cung cấp nội dung, bạn sử dụng đối tượng
+ {@link android.content.ContentResolver} trong
+ {@link android.content.Context} của ứng dụng của bạn để giao tiếp với trình cung cấp như một máy khách.
+ Đối tượng {@link android.content.ContentResolver} giao tiếp với đối tượng trình cung cấp, một
+ thực thể của lớp triển khai {@link android.content.ContentProvider}. Đối tượng
+ trình cung cấp nhận các yêu cầu dữ liệu từ máy khách, thực hiện hành động được yêu cầu, và
+ trả về kết quả.
+</p>
+<p>
+ Bạn không cần phát triển trình cung cấp của chính mình nếu không có ý định chia sẻ dữ liệu của bạn với
+ các ứng dụng khác. Tuy nhiên, bạn cần phải có trình cung cấp của chính mình để cung cấp các gợi ý tìm kiếm tùy chỉnh
+ trong ứng dụng của chính bạn. Bạn cũng cần phải có trình cung cấp của chính mình nếu muốn sao chép và
+ dán dữ liệu hoặc tệp phức tạp từ ứng dụng của bạn sang các ứng dụng khác.
+</p>
+<p>
+ Bản thân Android bao gồm các trình cung cấp nội dung chuyên quản lý dữ liệu như âm thanh, video, hình ảnh và
+ thông tin liên lạc cá nhân. Bạn có thể thấy một số được liệt kê trong tài liệu
+ tham khảo cho gói
+ <code><a href="{@docRoot}reference/android/provider/package-summary.html">android.provider</a>
+ </code>. Với một số hạn chế, những trình cung cấp này có thể truy cập vào bất kỳ ứng dụng
+ Android nào.
+</p><p>
+ Các chủ đề sau mô tả chi tiết hơn về các trình cung cấp nội dung:
+</p>
+<dl>
+ <dt>
+ <strong><a href="{@docRoot}guide/topics/providers/content-provider-basics.html">
+ Nội dung Cơ bản về Trình cung cấp Nội dung</a></strong>
+ </dt>
+ <dd>
+ Cách truy cập dữ liệu trong một trình cung cấp nội dung khi dữ liệu được tổ chức dưới dạng bảng.
+ </dd>
+ <dt>
+ <strong><a href="{@docRoot}guide/topics/providers/content-provider-creating.html">
+ Tạo một Trình cung cấp Nội dung</a></strong>
+ </dt>
+ <dd>
+ Cách tạo trình cung cấp nội dung của chính bạn.
+ </dd>
+ <dt>
+ <strong><a href="{@docRoot}guide/topics/providers/calendar-provider.html">
+ Trình cung cấp Lịch</a></strong>
+ </dt>
+ <dd>
+ Cách truy cập Trình cung cấp Lịch mà là một bộ phận của nền tảng Android.
+ </dd>
+ <dt>
+ <strong><a href="{@docRoot}guide/topics/providers/contacts-provider.html">
+ Trình cung cấp Danh bạ</a></strong>
+ </dt>
+ <dd>
+ Cách truy cập Trình cung cấp Danh bạ mà là một bộ phận của nền tảng Android.
+ </dd>
+</dl>
diff --git a/docs/html-intl/intl/vi/guide/topics/providers/document-provider.jd b/docs/html-intl/intl/vi/guide/topics/providers/document-provider.jd
new file mode 100644
index 000000000000..30844d7c277e
--- /dev/null
+++ b/docs/html-intl/intl/vi/guide/topics/providers/document-provider.jd
@@ -0,0 +1,916 @@
+page.title=Khuôn khổ Truy cập Kho lưu trữ
+@jd:body
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>Trong tài liệu này
+ <a href="#" onclick="hideNestedItems('#toc44',this);return false;" class="header-toggle">
+ <span class="more">hiện nhiều hơn</span>
+ <span class="less" style="display:none">hiện ít hơn</span></a></h2>
+<ol id="toc44" class="hide-nested">
+ <li>
+ <a href="#overview">Tổng quan</a>
+ </li>
+ <li>
+ <a href="#flow">Dòng Điều khiển</a>
+ </li>
+ <li>
+ <a href="#client">Ghi một Ứng dụng Máy khách</a>
+ <ol>
+ <li><a href="#search">Tìm kiếm tài liệu</a></li>
+ <li><a href="#process">Kết quả tiến trình</a></li>
+ <li><a href="#metadata">Kiểm tra siêu dữ liệu tài liệu</a></li>
+ <li><a href="#open">Mở một tài liệu</a></li>
+ <li><a href="#create">Tạo một tài liệu mới</a></li>
+ <li><a href="#delete">Xóa một tài liệu</a></li>
+ <li><a href="#edit">Chỉnh sửa một tài liệu</a></li>
+ <li><a href="#permissions">Cố định các quyền</a></li>
+ </ol>
+ </li>
+ <li><a href="#custom">Ghi một Trình cung cấp Tài liệu Tùy chỉnh</a>
+ <ol>
+ <li><a href="#manifest">Bản kê khai</a></li>
+ <li><a href="#contract">Hợp đồng</a></li>
+ <li><a href="#subclass">Phân lớp con DocumentsProvider</a></li>
+ <li><a href="#security">Bảo mật</a></li>
+ </ol>
+ </li>
+
+</ol>
+<h2>Lớp khóa</h2>
+<ol>
+ <li>{@link android.provider.DocumentsProvider}</li>
+ <li>{@link android.provider.DocumentsContract}</li>
+</ol>
+
+<h2>Video</h2>
+
+<ol>
+ <li><a href="http://www.youtube.com/watch?v=zxHVeXbK1P4">
+DevBytes: Khuôn khổ Truy cập Kho lưu trữ Android 4.4: Trình cung cấp</a></li>
+ <li><a href="http://www.youtube.com/watch?v=UFj9AEz0DHQ">
+DevBytes: Khuôn khổ Truy cập Kho lưu trữ Android 4.4: Máy khách</a></li>
+</ol>
+
+
+<h2>Mã Ví dụ</h2>
+
+<ol>
+ <li><a href="{@docRoot}samples/StorageProvider/index.html">
+Trình cung cấp Lưu trữ</a></li>
+ <li><a href="{@docRoot}samples/StorageClient/index.html">
+StorageClient</a></li>
+</ol>
+
+<h2>Xem thêm</h2>
+<ol>
+ <li>
+ <a href="{@docRoot}guide/topics/providers/content-provider-basics.html">
+ Nội dung Cơ bản về Trình cung cấp Nội dung
+ </a>
+ </li>
+</ol>
+
+</div>
+</div>
+
+
+<p>Android 4.4 (API mức 19) giới thiệu Khuôn khổ Truy cập Kho lưu trữ (SAF). SAF
+ giúp người dùng đơn giản hóa việc duyệt và mở tài liệu, hình ảnh và các tệp khác
+giữa tất cả trình cung cấp lưu trữ tài liệu mà họ thích. UI tiêu chuẩn, dễ sử dụng
+cho phép người dùng duyệt tệp và truy cập hoạt động gần đây một cách nhất quán giữa các ứng dụng và trình cung cấp.</p>
+
+<p>Dịch vụ lưu trữ đám mây hoặc cục bộ có thể tham gia vào hệ sinh thái này bằng cách triển khai một
+{@link android.provider.DocumentsProvider} để gói gọn các dịch vụ của mình. Những ứng dụng
+máy khách cần truy cập vào tài liệu của một trình cung cấp có thể tích hợp với SAF chỉ bằng một vài
+dòng mã.</p>
+
+<p>SAF bao gồm:</p>
+
+<ul>
+<li><strong>Trình cung cấp tài liệu</strong>&mdash;Một trình cung cấp nội dung cho phép một
+dịch vụ lưu trữ (chẳng hạn như Google Drive) phát hiện các tệp mà nó quản lý. Trình cung cấp tài liệu được
+triển khai thành một lớp con của lớp {@link android.provider.DocumentsProvider}.
+Sơ đồ tài liệu-trình cung cấp sẽ được dựa trên một phân cấp tệp truyền thống,
+cho dù cách thức trình cung cấp tài liệu của bạn trực tiếp lưu trữ dữ liệu là hoàn toàn do bạn.
+Nền tảng Android bao gồm một vài trình cung cấp tài liệu tích hợp, chẳng hạn như
+Downloads, Images, và Videos.</li>
+
+<li><strong>Ứng dụng máy khách</strong>&mdash;Một ứng dụng tùy chỉnh có chức năng gọi ra ý định
+{@link android.content.Intent#ACTION_OPEN_DOCUMENT} và/hoặc
+{@link android.content.Intent#ACTION_CREATE_DOCUMENT} và nhận các tệp
+được trả về bởi trình cung cấp tài liệu.</li>
+
+<li><strong>Bộ chọn</strong>&mdash;Một UI hệ thống cho phép người dùng truy cập tài liệu từ tất cả
+trình cung cấp tài liệu mà thỏa mãn các tiêu chí tìm kiếm của ứng dụng máy khách.</li>
+</ul>
+
+<p>Một số tính năng được SAF cung cấp bao gồm:</p>
+<ul>
+<li>Cho phép người dùng duyệt nội dung từ tất cả trình cung cấp tài liệu, không chỉ một ứng dụng duy nhất.</li>
+<li>Giúp ứng dụng của bạn có thể có quyền truy cập lâu dài, cố định vào
+ các tài liệu được sở hữu bởi một trình cung cấp tài liệu. Thông qua truy cập này, người dùng có thể thêm, chỉnh sửa,
+ lưu và xóa tệp trên trình cung cấp.</li>
+<li>Hỗ trợ nhiều tài khoản người dùng và các phần gốc tạm thời chẳng hạn như trình cung cấp
+bộ nhớ USB, nó chỉ xuất hiện nếu ổ đĩa được cắm vào. </li>
+</ul>
+
+<h2 id ="overview">Tổng quan</h2>
+
+<p>SAF tập trung xoay quanh một trình cung cấp nội dung là một lớp con
+của lớp {@link android.provider.DocumentsProvider}. Trong một <em>trình cung cấp tài liệu</em>, dữ liệu được
+cấu trúc thành một phân cấp tệp truyền thống:</p>
+<p><img src="{@docRoot}images/providers/storage_datamodel.png" alt="data model" /></p>
+<p class="img-caption"><strong>Hình 1.</strong> Mô hình dữ liệu của trình cung cấp tài liệu. Một Phần gốc chỉ đến một Tài liệu duy nhất,
+sau đó nó bắt đầu xòe ra toàn bộ cây.</p>
+
+<p>Lưu ý điều sau đây:</p>
+<ul>
+
+<li>Mỗi một trình cung cấp tài liệu sẽ báo cáo một hoặc nhiều
+"phần gốc" là điểm bắt đầu khám phá cây tài liệu.
+Mỗi phần gốc có một {@link android.provider.DocumentsContract.Root#COLUMN_ROOT_ID} duy nhất,
+và nó trỏ đến một tài liệu (thư mục)
+biểu diễn nội dung bên dưới phần gốc đó.
+Phần gốc có thể linh hoạt theo thiết kế để hỗ trợ các trường hợp sử dụng như nhiều tài khoản,
+thiết bị lưu trữ USB tạm thời, hoặc đăng nhập/đăng xuất người dùng.</li>
+
+<li>Dưới mỗi phần gốc là một tài liệu đơn lẻ. Tài liệu đó sẽ trỏ tới 1 đến <em>N</em> tài liệu,
+mỗi tài liệu lại có thể trỏ tới 1 đến <em>N</em> tài liệu khác. </li>
+
+<li>Mỗi bộ nhớ phụ trợ phủ bề mặt
+các tệp và thư mục riêng lẻ bằng cách tham chiếu chúng bằng một
+{@link android.provider.DocumentsContract.Document#COLUMN_DOCUMENT_ID} duy nhất.
+ID của tài liệu phải là duy nhất và không thay đổi sau khi được phát hành, do chúng được sử dụng để cấp URI
+không thay đổi giữa các lần khởi động lại thiết bị.</li>
+
+
+<li>Tài liệu có thể là một tệp mở được (có một kiểu MIME cụ thể), hoặc một
+thư mục chứa các tài liệu bổ sung (có kiểu MIME
+{@link android.provider.DocumentsContract.Document#MIME_TYPE_DIR}).</li>
+
+<li>Mỗi tài liệu có thể có các khả năng khác nhau như được mô tả bởi
+{@link android.provider.DocumentsContract.Document#COLUMN_FLAGS COLUMN_FLAGS}.
+Ví dụ, {@link android.provider.DocumentsContract.Document#FLAG_SUPPORTS_WRITE},
+{@link android.provider.DocumentsContract.Document#FLAG_SUPPORTS_DELETE}, và
+{@link android.provider.DocumentsContract.Document#FLAG_SUPPORTS_THUMBNAIL}.
+{@link android.provider.DocumentsContract.Document#COLUMN_DOCUMENT_ID} cũng có thể
+có trong nhiều thư mục.</li>
+</ul>
+
+<h2 id="flow">Dòng Điều khiển</h2>
+<p>Như nêu trên, mô hình dữ liệu của trình cung cấp tài liệu được dựa trên một phân cấp
+tệp truyền thống. Tuy nhiên, bạn có thể thực tế lưu trữ dữ liệu của mình bằng bất kỳ cách nào mà mình thích, miễn
+là nó có thể được truy cập thông qua API {@link android.provider.DocumentsProvider}. Ví dụ, bạn
+có thể sử dụng kho lưu trữ đám mây dựa trên tag cho dữ liệu của mình.</p>
+
+<p>Hình 2 minh họa một ví dụ về cách mà một ứng dụng ảnh có thể sử dụng SAF
+để truy cập dữ liệu được lưu trữ:</p>
+<p><img src="{@docRoot}images/providers/storage_dataflow.png" alt="app" /></p>
+
+<p class="img-caption"><strong>Hình 2.</strong> Dòng Khuôn khổ Truy cập Kho lưu trữ</p>
+
+<p>Lưu ý điều sau đây:</p>
+<ul>
+
+<li>Trong SAF, trình cung cấp và máy khách không tương tác
+trực tiếp với nhau. Một máy khách yêu cầu quyền để tương tác
+với tệp (cụ thể là quyền đọc, chỉnh sửa, tạo hoặc xóa tệp).</li>
+
+<li>Tương tác bắt đầu khi một ứng dụng (trong ví dụ này này một ứng dụng ảnh) thể hiện ý định
+{@link android.content.Intent#ACTION_OPEN_DOCUMENT} hoặc {@link android.content.Intent#ACTION_CREATE_DOCUMENT}. Ý định có thể bao gồm các bộ lọc
+để cụ thể hơn các tiêu chí&mdash;ví dụ, "cấp cho tôi tất cả tệp mở được
+có kiểu MIME là 'image'."</li>
+
+<li>Sau khi ý định thể hiện, bộ chọn của hệ thống sẽ đi đến từng trình cung cấp được đăng ký
+và hiển thị cho người dùng xem các phần gốc nội dung khớp với tiêu chí.</li>
+
+<li>Bộ chọn cấp cho người dùng một giao diện tiêu chuẩn để truy cập tài liệu, mặc
+dù các trình cung cấp tài liệu liên quan có thể rất khác nhau. Ví dụ, hình 2
+minh họa một trình cung cấp Google Drive, một trình cung cấp USB, và một trình cung cấp đám mây.</li>
+</ul>
+
+<p>Hình 3 minh họa một bộ chọn mà trong đó một người dùng đang tìm kiếm hình ảnh đã chọn một
+tài khoản Google Drive:</p>
+
+<p><img src="{@docRoot}images/providers/storage_picker.png" width="340" alt="picker" style="border:2px solid #ddd" /></p>
+
+<p class="img-caption"><strong>Hình 3.</strong> Bộ chọn</p>
+
+<p>Khi người dùng chọn Google Drive, hình ảnh được hiển thị như minh họa trong
+hình 4. Từ điểm đó trở đi, người dùng có thể tương tác với chúng theo bất kỳ cách nào
+được hỗ trợ bởi trình cung cấp và ứng dụng máy khách.
+
+<p><img src="{@docRoot}images/providers/storage_photos.png" width="340" alt="picker" style="border:2px solid #ddd" /></p>
+
+<p class="img-caption"><strong>Hình 4.</strong> Hình ảnh</p>
+
+<h2 id="client">Ghi một Ứng dụng Máy khách</h2>
+
+<p>Trên phiên bản Android 4.3 và thấp hơn, nếu bạn muốn ứng dụng của mình truy xuất một tệp từ một ứng dụng
+khác, nó phải gọi ra một ý định chẳng hạn như {@link android.content.Intent#ACTION_PICK}
+hay {@link android.content.Intent#ACTION_GET_CONTENT}. Khi đó, người dùng phải chọn
+một ứng dụng duy nhất mà từ đó họ chọn một tệp và ứng dụng được chọn phải cung cấp một
+giao diện người dùng để người dùng duyệt và chọn từ các tệp có sẵn. </p>
+
+<p>Trên phiên bản Android 4.4 trở lên, bạn có thêm một tùy chọn là sử dụng ý định
+{@link android.content.Intent#ACTION_OPEN_DOCUMENT},
+nó hiển thị một UI bộ chọn được điều khiển bởi hệ thống, cho phép người dùng
+duyệt tất cả tệp mà các ứng dụng khác đã cung cấp. Từ UI duy nhất này, người dùng
+có thể chọn một tệp từ bất kỳ ứng dụng nào được hỗ trợ.</p>
+
+<p>{@link android.content.Intent#ACTION_OPEN_DOCUMENT} không
+nhằm mục đích thay thế cho {@link android.content.Intent#ACTION_GET_CONTENT}.
+Bạn nên sử dụng cái nào sẽ phụ thuộc vào nhu cầu của ứng dụng của bạn:</p>
+
+<ul>
+<li>Sử dụng {@link android.content.Intent#ACTION_GET_CONTENT} nếu bạn muốn ứng dụng của mình
+chỉ đơn thuần đọc/nhập dữ liệu. Bằng cách này, ứng dụng nhập một bản sao dữ liệu,
+chẳng hạn như một tệp hình ảnh.</li>
+
+<li>Sử dụng {@link android.content.Intent#ACTION_OPEN_DOCUMENT} nếu bạn muốn ứng dụng
+của mình có quyền truy cập lâu dài, cố định vào các tài liệu được sở hữu bởi một
+trình cung cấp tài liệu. Ví dụ như trường hợp một ứng dụng chỉnh sửa ảnh cho phép người dùng chỉnh sửa
+các hình ảnh được lưu trữ trong một trình cung cấp tài liệu. </li>
+
+</ul>
+
+
+<p>Phần này mô tả cách ghi các ứng dụng máy khách dựa trên
+{@link android.content.Intent#ACTION_OPEN_DOCUMENT} và
+các ý định {@link android.content.Intent#ACTION_CREATE_DOCUMENT}.</p>
+
+
+<h3 id="search">Tìm kiếm tài liệu</h3>
+
+<p>
+Đoạn mã HTML sau sử dụng {@link android.content.Intent#ACTION_OPEN_DOCUMENT}
+để tìm kiếm các trình cung cấp tài liệu mà
+chứa tệp hình ảnh:</p>
+
+<pre>private static final int READ_REQUEST_CODE = 42;
+...
+/**
+ * Fires an intent to spin up the &quot;file chooser&quot; UI and select an image.
+ */
+public void performFileSearch() {
+
+ // ACTION_OPEN_DOCUMENT is the intent to choose a file via the system's file
+ // browser.
+ Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
+
+ // Filter to only show results that can be &quot;opened&quot;, such as a
+ // file (as opposed to a list of contacts or timezones)
+ intent.addCategory(Intent.CATEGORY_OPENABLE);
+
+ // Filter to show only images, using the image MIME data type.
+ // If one wanted to search for ogg vorbis files, the type would be &quot;audio/ogg&quot;.
+ // To search for all documents available via installed storage providers,
+ // it would be &quot;*/*&quot;.
+ intent.setType(&quot;image/*&quot;);
+
+ startActivityForResult(intent, READ_REQUEST_CODE);
+}</pre>
+
+<p>Lưu ý điều sau đây:</p>
+<ul>
+<li>Khi ứng dụng thể hiện ý định {@link android.content.Intent#ACTION_OPEN_DOCUMENT}
+, nó sẽ khởi chạy một bộ chọn để hiển thị tất cả trình cung cấp tài liệu khớp với tiêu chí.</li>
+
+<li>Thêm thể loại {@link android.content.Intent#CATEGORY_OPENABLE} vào
+ý định sẽ lọc kết quả để chỉ hiển thị những tài liệu có thể mở được, chẳng hạn như tệp hình ảnh.</li>
+
+<li>Câu lệnh {@code intent.setType("image/*")} sẽ lọc thêm để
+chỉ hiển thị những tài liệu có kiểu dữ liệu MIME hình ảnh.</li>
+</ul>
+
+<h3 id="results">Kết quả Tiến trình</h3>
+
+<p>Sau khi người dùng chọn một tài liệu trong bộ chọn,
+{@link android.app.Activity#onActivityResult onActivityResult()} sẽ được gọi.
+URI tro tới tài liệu được chọn sẽ nằm trong tham số {@code resultData}
+. Trích xuất UI bằng cách sử dụng {@link android.content.Intent#getData getData()}.
+Sau khi có nó, bạn có thể sử dụng nó để truy xuất tài liệu mà người dùng muốn. Ví
+dụ:</p>
+
+<pre>&#64;Override
+public void onActivityResult(int requestCode, int resultCode,
+ Intent resultData) {
+
+ // The ACTION_OPEN_DOCUMENT intent was sent with the request code
+ // READ_REQUEST_CODE. If the request code seen here doesn't match, it's the
+ // response to some other intent, and the code below shouldn't run at all.
+
+ if (requestCode == READ_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
+ // The document selected by the user won't be returned in the intent.
+ // Instead, a URI to that document will be contained in the return intent
+ // provided to this method as a parameter.
+ // Pull that URI using resultData.getData().
+ Uri uri = null;
+ if (resultData != null) {
+ uri = resultData.getData();
+ Log.i(TAG, "Uri: " + uri.toString());
+ showImage(uri);
+ }
+ }
+}
+</pre>
+
+<h3 id="metadata">Kiểm tra siêu dữ liệu tài liệu</h3>
+
+<p>Sau khi có URI cho một tài liệu, bạn có quyền truy cập siêu dữ liệu của nó. Đoạn mã HTML
+này bắt siêu dữ liệu cho một tài liệu được quy định bởi URI, và ghi lại nó:</p>
+
+<pre>public void dumpImageMetaData(Uri uri) {
+
+ // The query, since it only applies to a single document, will only return
+ // one row. There's no need to filter, sort, or select fields, since we want
+ // all fields for one document.
+ Cursor cursor = getActivity().getContentResolver()
+ .query(uri, null, null, null, null, null);
+
+ try {
+ // moveToFirst() returns false if the cursor has 0 rows. Very handy for
+ // &quot;if there's anything to look at, look at it&quot; conditionals.
+ if (cursor != null &amp;&amp; cursor.moveToFirst()) {
+
+ // Note it's called &quot;Display Name&quot;. This is
+ // provider-specific, and might not necessarily be the file name.
+ String displayName = cursor.getString(
+ cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
+ Log.i(TAG, &quot;Display Name: &quot; + displayName);
+
+ int sizeIndex = cursor.getColumnIndex(OpenableColumns.SIZE);
+ // If the size is unknown, the value stored is null. But since an
+ // int can't be null in Java, the behavior is implementation-specific,
+ // which is just a fancy term for &quot;unpredictable&quot;. So as
+ // a rule, check if it's null before assigning to an int. This will
+ // happen often: The storage API allows for remote files, whose
+ // size might not be locally known.
+ String size = null;
+ if (!cursor.isNull(sizeIndex)) {
+ // Technically the column stores an int, but cursor.getString()
+ // will do the conversion automatically.
+ size = cursor.getString(sizeIndex);
+ } else {
+ size = &quot;Unknown&quot;;
+ }
+ Log.i(TAG, &quot;Size: &quot; + size);
+ }
+ } finally {
+ cursor.close();
+ }
+}
+</pre>
+
+<h3 id="open-client">Mở một tài liệu</h3>
+
+<p>Sau khi có URI cho một tài liệu, bạn có thể mở nó hoặc làm bất kỳ điều gì
+mà bạn muốn.</p>
+
+<h4>Bitmap</h4>
+
+<p>Sau đây là một ví dụ về cách bạn có thể mở một {@link android.graphics.Bitmap}:</p>
+
+<pre>private Bitmap getBitmapFromUri(Uri uri) throws IOException {
+ ParcelFileDescriptor parcelFileDescriptor =
+ getContentResolver().openFileDescriptor(uri, "r");
+ FileDescriptor fileDescriptor = parcelFileDescriptor.getFileDescriptor();
+ Bitmap image = BitmapFactory.decodeFileDescriptor(fileDescriptor);
+ parcelFileDescriptor.close();
+ return image;
+}
+</pre>
+
+<p>Lưu ý rằng bạn không nên thực hiện thao tác này trên luồng UI. Thực hiện điều này dưới
+nền bằng cách sử dụng {@link android.os.AsyncTask}. Sau khi mở bitmap, bạn có thể
+hiển thị nó trong một {@link android.widget.ImageView}.
+</p>
+
+<h4>Nhận một InputStream</h4>
+
+<p>Sau đây là một ví dụ về cách mà bạn có thể nhận một {@link java.io.InputStream} từ URI. Trong đoạn mã HTML
+này, các dòng tệp đang được đọc thành một xâu:</p>
+
+<pre>private String readTextFromUri(Uri uri) throws IOException {
+ InputStream inputStream = getContentResolver().openInputStream(uri);
+ BufferedReader reader = new BufferedReader(new InputStreamReader(
+ inputStream));
+ StringBuilder stringBuilder = new StringBuilder();
+ String line;
+ while ((line = reader.readLine()) != null) {
+ stringBuilder.append(line);
+ }
+ fileInputStream.close();
+ parcelFileDescriptor.close();
+ return stringBuilder.toString();
+}
+</pre>
+
+<h3 id="create">Tạo một tài liệu mới</h3>
+
+<p>Ứng dụng của bạn có thể tạo một tài liệu mới trong một trình cung cấp tài liệu bằng cách sử dụng ý định
+{@link android.content.Intent#ACTION_CREATE_DOCUMENT}
+. Để tạo một tệp, bạn cấp cho ý định của mình một kiểu MIME và tên tệp, và
+khởi chạy nó bằng một mã yêu cầu duy nhất. Phần còn lại sẽ được làm hộ bạn:</p>
+
+
+<pre>
+// Here are some examples of how you might call this method.
+// The first parameter is the MIME type, and the second parameter is the name
+// of the file you are creating:
+//
+// createFile("text/plain", "foobar.txt");
+// createFile("image/png", "mypicture.png");
+
+// Unique request code.
+private static final int WRITE_REQUEST_CODE = 43;
+...
+private void createFile(String mimeType, String fileName) {
+ Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
+
+ // Filter to only show results that can be &quot;opened&quot;, such as
+ // a file (as opposed to a list of contacts or timezones).
+ intent.addCategory(Intent.CATEGORY_OPENABLE);
+
+ // Create a file with the requested MIME type.
+ intent.setType(mimeType);
+ intent.putExtra(Intent.EXTRA_TITLE, fileName);
+ startActivityForResult(intent, WRITE_REQUEST_CODE);
+}
+</pre>
+
+<p>Sau khi tạo một tài liệu mới, bạn có thể nhận URI của tài liệu trong
+{@link android.app.Activity#onActivityResult onActivityResult()}, sao cho bạn
+có thể tiếp tục ghi nó.</p>
+
+<h3 id="delete">Xóa một tài liệu</h3>
+
+<p>Nếu bạn có URI cho một tài liệu và
+{@link android.provider.DocumentsContract.Document#COLUMN_FLAGS Document.COLUMN_FLAGS}
+của tài liệu chứa
+{@link android.provider.DocumentsContract.Document#FLAG_SUPPORTS_DELETE SUPPORTS_DELETE},
+bạn có thể xóa tài liệu đó. Ví dụ:</p>
+
+<pre>
+DocumentsContract.deleteDocument(getContentResolver(), uri);
+</pre>
+
+<h3 id="edit">Chỉnh sửa một tài liệu</h3>
+
+<p>Bạn có thể sử dụng SAF để chỉnh sửa một tài liệu văn bản ngay tại chỗ.
+Đoạn mã HTML này thể hiện
+ý định {@link android.content.Intent#ACTION_OPEN_DOCUMENT} và sử dụng
+thể loại {@link android.content.Intent#CATEGORY_OPENABLE} để chỉ hiển thị
+những tài liệu có thể mở được. Nó lọc thêm để chỉ hiển thị những tệp văn bản:</p>
+
+<pre>
+private static final int EDIT_REQUEST_CODE = 44;
+/**
+ * Open a file for writing and append some text to it.
+ */
+ private void editDocument() {
+ // ACTION_OPEN_DOCUMENT is the intent to choose a file via the system's
+ // file browser.
+ Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
+
+ // Filter to only show results that can be &quot;opened&quot;, such as a
+ // file (as opposed to a list of contacts or timezones).
+ intent.addCategory(Intent.CATEGORY_OPENABLE);
+
+ // Filter to show only text files.
+ intent.setType(&quot;text/plain&quot;);
+
+ startActivityForResult(intent, EDIT_REQUEST_CODE);
+}
+</pre>
+
+<p>Tiếp theo, từ {@link android.app.Activity#onActivityResult onActivityResult()}
+(xem <a href="#results">Kết quả tiến trình</a>) bạn có thể gọi mã để thực hiện chỉnh sửa.
+Đoạn mã HTML sau nhận được một {@link java.io.FileOutputStream}
+từ {@link android.content.ContentResolver}. Theo mặc định, nó sử dụng chế độ “ghi”.
+Cách tốt nhất là yêu cầu lượng quyền truy cập bạn cần ở mức ít nhất, vì thế đừng yêu cầu
+quyền đọc/ghi nếu bạn chỉ cần quyền ghi:</p>
+
+<pre>private void alterDocument(Uri uri) {
+ try {
+ ParcelFileDescriptor pfd = getActivity().getContentResolver().
+ openFileDescriptor(uri, "w");
+ FileOutputStream fileOutputStream =
+ new FileOutputStream(pfd.getFileDescriptor());
+ fileOutputStream.write(("Overwritten by MyCloud at " +
+ System.currentTimeMillis() + "\n").getBytes());
+ // Let the document provider know you're done by closing the stream.
+ fileOutputStream.close();
+ pfd.close();
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+}</pre>
+
+<h3 id="permissions">Cố định các quyền</h3>
+
+<p>Khi ứng dụng của bạn mở một tệp để đọc hoặc ghi, hệ thống sẽ cấp cho
+ứng dụng của bạn một quyền URI được cấp cho tệp đó. Quyền này sẽ kéo dài tới khi thiết bị của bạn khởi động lại.
+Nhưng giả sử ứng dụng của bạn là một ứng dụng chỉnh sửa hình ảnh, và bạn muốn người dùng có thể
+truy cập 5 hình ảnh cuối cùng mà họ đã chỉnh sửa, trực tiếp từ ứng dụng của bạn. Nếu thiết bị của người dùng
+đã khởi động lại, bạn sẽ phải gửi người dùng trở lại bộ chọn hệ thống để tìm
+các tệp đó, đây rõ ràng không phải là cách lý tưởng.</p>
+
+<p>Để tránh điều này xảy ra, bạn có thể cố định các quyền mà hệ thống
+cấp cho ứng dụng của bạn. Ứng dụng của bạn sẽ "nhận" cấp quyền URI có thể cố định
+mà hệ thống cung cấp một cách hiệu quả. Điều này cho phép người dùng có quyền liên tục truy cập các tệp đó
+thông qua ứng dụng của bạn, ngay cả khi thiết bị đã bị khởi động lại:</p>
+
+
+<pre>final int takeFlags = intent.getFlags()
+ &amp; (Intent.FLAG_GRANT_READ_URI_PERMISSION
+ | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
+// Check for the freshest data.
+getContentResolver().takePersistableUriPermission(uri, takeFlags);</pre>
+
+<p>Còn một bước cuối cùng. Bạn có thể đã lưu các
+URI gần đây nhất mà ứng dụng của bạn đã truy cập, nhưng chúng còn thể không còn hợp lệ&mdash;một ứng dụng khác
+có thể đã xóa hoặc sửa đổi tài liệu. Vì thế, bạn luôn nên gọi
+{@code getContentResolver().takePersistableUriPermission()} để kiểm tra
+dữ liệu mới nhất.</p>
+
+<h2 id="custom">Ghi một Trình cung cấp Tài liệu Tùy chỉnh</h2>
+
+<p>
+Nếu bạn đang phát triển một ứng dụng cung cấp dịch vụ lưu trữ cho tệp (chẳng hạn như
+một dịch vụ lưu trữ đám mây), bạn có thể cung cấp các tệp của mình thông qua
+SAF bằng cách ghi một trình cung cấp tài liệu tùy chỉnh. Phần này mô tả cách làm điều
+này.</p>
+
+
+<h3 id="manifest">Bản kê khai</h3>
+
+<p>Để triển khai một trình cung cấp tài liệu tùy chỉnh, hãy thêm nội dung sau vào bản kê khai
+của ứng dụng của bạn:</p>
+<ul>
+
+<li>Một mục tiêu API mức 19 hoặc cao hơn.</li>
+
+<li>Một phần tử <code>&lt;provider&gt;</code> khai báo trình cung cấp lưu trữ
+tùy chỉnh của bạn. </li>
+
+<li>Tên của trình cung cấp của bạn, là tên lớp của nó, bao gồm tên gói.
+Ví dụ: <code>com.example.android.storageprovider.MyCloudProvider</code>.</li>
+
+<li>Tên thẩm quyền của bạn, tức là tên gói của bạn (trong ví dụ này là
+<code>com.example.android.storageprovider</code>) cộng với kiểu của trình cung cấp nội dung
+(<code>documents</code>). Ví dụ, {@code com.example.android.storageprovider.documents}.</li>
+
+<li>Thuộc tính <code>android:exported</code> được đặt thành <code>&quot;true&quot;</code>.
+Bạn phải xuất trình cung cấp của mình để các ứng dụng khác có thể thấy nó.</li>
+
+<li>Thuộc tính <code>android:grantUriPermissions</code> được đặt thành
+<code>&quot;true&quot;</code>. Thiết đặt này cho phép hệ thống cấp cho các ứng dụng khác quyền truy cập
+vào nội dung trong trình cung cấp của bạn. Để thảo luận về cách cố định quyền được cấp cho
+một tài liệu cụ thể, hãy xem phần<a href="#permissions">Cố định các quyền</a>.</li>
+
+<li>Quyền {@code MANAGE_DOCUMENTS}. Theo mặc định, một trình cung cấp sẽ có sẵn
+đối với mọi người. Việc thêm quyền này sẽ hạn chế trình cung cấp của bạn vào hệ thống.
+Hạn chế này có ý nghĩa quan trọng đối với vấn đề bảo mật.</li>
+
+<li>Thuộc tính {@code android:enabled} được đặt thành một giá trị boolean được định nghĩa trong một tệp
+tài nguyên. Mục đích của thuộc tính này là để vô hiệu hóa trình cung cấp trên các thiết bị chạy phiên bản Android 4.3 hoặc thấp hơn.
+Ví dụ, {@code android:enabled="@bool/atLeastKitKat"}. Bên
+cạnh việc nêu thuộc tính này trong bản kê khai, bạn cần làm như sau:
+<ul>
+<li>Trong tệp tài nguyên {@code bool.xml} của bạn bên dưới {@code res/values/}, hãy thêm
+dòng sau: <pre>&lt;bool name=&quot;atLeastKitKat&quot;&gt;false&lt;/bool&gt;</pre></li>
+
+<li>Trong tệp tài nguyên {@code bool.xml} của bạn bên dưới {@code res/values-v19/}, hãy thêm
+dòng sau: <pre>&lt;bool name=&quot;atLeastKitKat&quot;&gt;true&lt;/bool&gt;</pre></li>
+</ul></li>
+
+<li>Một bộ lọc ý định chứa hành động
+{@code android.content.action.DOCUMENTS_PROVIDER}, sao cho trình cung cấp của bạn
+xuất hiện trong bộ chọn khi hệ thống tìm kiếm trình cung cấp.</li>
+
+</ul>
+<p>Sau đây là các đoạn trích từ một bản kê khai mẫu chứa một trình cung cấp:</p>
+
+<pre>&lt;manifest... &gt;
+ ...
+ &lt;uses-sdk
+ android:minSdkVersion=&quot;19&quot;
+ android:targetSdkVersion=&quot;19&quot; /&gt;
+ ....
+ &lt;provider
+ android:name=&quot;com.example.android.storageprovider.MyCloudProvider&quot;
+ android:authorities=&quot;com.example.android.storageprovider.documents&quot;
+ android:grantUriPermissions=&quot;true&quot;
+ android:exported=&quot;true&quot;
+ android:permission=&quot;android.permission.MANAGE_DOCUMENTS&quot;
+ android:enabled=&quot;&#64;bool/atLeastKitKat&quot;&gt;
+ &lt;intent-filter&gt;
+ &lt;action android:name=&quot;android.content.action.DOCUMENTS_PROVIDER&quot; /&gt;
+ &lt;/intent-filter&gt;
+ &lt;/provider&gt;
+ &lt;/application&gt;
+
+&lt;/manifest&gt;</pre>
+
+<h4 id="43">Hỗ trợ các thiết bị chạy phiên bản Android 4.3 và thấp hơn</h4>
+
+<p>Ý định
+{@link android.content.Intent#ACTION_OPEN_DOCUMENT} chỉ có sẵn
+trên các thiết bị chạy phiên bản Android 4.4 trở lên.
+Nếu bạn muốn ứng dụng của mình hỗ trợ {@link android.content.Intent#ACTION_GET_CONTENT}
+để tạo điều kiện cho các thiết bị đang chạy phiên bản Android 4.3 và thấp hơn, bạn nên
+vô hiệu hóa bộ lọc ý định {@link android.content.Intent#ACTION_GET_CONTENT} trong
+bản kê khai của bạn cho các thiết bị chạy phiên bản Android 4.4 trở lên. Một
+trình cung cấp tài liệu và {@link android.content.Intent#ACTION_GET_CONTENT} nên được xem xét
+ loại trừ lẫn nhau. Nếu bạn hỗ trợ cả hai đồng thời, ứng dụng của bạn sẽ
+xuất hiện hai lần trong UI của bộ chọn hệ thống, đưa ra hai cách khác nhau để truy cập
+dữ liệu đã lưu của bạn. Điều này có thể khiến người dùng bị nhầm lẫn.</p>
+
+<p>Sau đây là cách được khuyến cáo để vô hiệu hóa bộ lọc ý định
+{@link android.content.Intent#ACTION_GET_CONTENT} đối với các thiết bị
+chạy phiên bản Android 4.4 hoặc cao hơn:</p>
+
+<ol>
+<li>Trong tệp tài nguyên {@code bool.xml} của bạn bên dưới {@code res/values/}, hãy thêm
+dòng sau: <pre>&lt;bool name=&quot;atMostJellyBeanMR2&quot;&gt;true&lt;/bool&gt;</pre></li>
+
+<li>Trong tệp tài nguyên {@code bool.xml} của bạn bên dưới {@code res/values-v19/}, hãy thêm
+dòng sau: <pre>&lt;bool name=&quot;atMostJellyBeanMR2&quot;&gt;false&lt;/bool&gt;</pre></li>
+
+<li>Thêm một
+<a href="{@docRoot}guide/topics/manifest/activity-alias-element.html">bí danh
+hoạt động</a> để vô hiệu hóa bộ lọc ý định {@link android.content.Intent#ACTION_GET_CONTENT}
+đối với các phiên bản 4.4 (API mức 19) trở lên. Ví dụ:
+
+<pre>
+&lt;!-- This activity alias is added so that GET_CONTENT intent-filter
+ can be disabled for builds on API level 19 and higher. --&gt;
+&lt;activity-alias android:name=&quot;com.android.example.app.MyPicker&quot;
+ android:targetActivity=&quot;com.android.example.app.MyActivity&quot;
+ ...
+ android:enabled=&quot;@bool/atMostJellyBeanMR2&quot;&gt;
+ &lt;intent-filter&gt;
+ &lt;action android:name=&quot;android.intent.action.GET_CONTENT&quot; /&gt;
+ &lt;category android:name=&quot;android.intent.category.OPENABLE&quot; /&gt;
+ &lt;category android:name=&quot;android.intent.category.DEFAULT&quot; /&gt;
+ &lt;data android:mimeType=&quot;image/*&quot; /&gt;
+ &lt;data android:mimeType=&quot;video/*&quot; /&gt;
+ &lt;/intent-filter&gt;
+&lt;/activity-alias&gt;
+</pre>
+</li>
+</ol>
+<h3 id="contract">Hợp đồng</h3>
+
+<p>Thường khi bạn ghi một trình cung cấp nội dung tùy chỉnh, một trong những tác vụ đó là
+triển khai các lớp hợp đồng như được mô tả trong hướng dẫn cho nhà phát triển
+<a href="{@docRoot}guide/topics/providers/content-provider-creating.html#ContractClass">
+Trình cung cấp Nội dung</a>. Lớp hợp đồng là một lớp {@code public final} mà
+chứa các định nghĩa hằng số cho URI, tên cột, kiểu MIME và
+siêu dữ liệu khác liên quan tới trình cung cấp. SAF
+cung cấp những lớp hợp đồng này cho bạn, vì thế bạn không cần tự
+ghi:</p>
+
+<ul>
+ <li>{@link android.provider.DocumentsContract.Document}</li>
+ <li>{@link android.provider.DocumentsContract.Root}</li>
+</ul>
+
+<p>Ví dụ, sau đây là các cột bạn có thể trả về trong một con chạy khi
+trình cung cấp tài liệu của bạn được truy vấn về tài liệu hoặc phần gốc:</p>
+
+<pre>private static final String[] DEFAULT_ROOT_PROJECTION =
+ new String[]{Root.COLUMN_ROOT_ID, Root.COLUMN_MIME_TYPES,
+ Root.COLUMN_FLAGS, Root.COLUMN_ICON, Root.COLUMN_TITLE,
+ Root.COLUMN_SUMMARY, Root.COLUMN_DOCUMENT_ID,
+ Root.COLUMN_AVAILABLE_BYTES,};
+private static final String[] DEFAULT_DOCUMENT_PROJECTION = new
+ String[]{Document.COLUMN_DOCUMENT_ID, Document.COLUMN_MIME_TYPE,
+ Document.COLUMN_DISPLAY_NAME, Document.COLUMN_LAST_MODIFIED,
+ Document.COLUMN_FLAGS, Document.COLUMN_SIZE,};
+</pre>
+
+<h3 id="subclass">Phân lớp con DocumentsProvider</h3>
+
+<p>Bước tiếp theo trong khi ghi một trình cung cấp tài liệu tùy chỉnh đó là phân lớp con
+cho lớp tóm tắt {@link android.provider.DocumentsProvider}. Tối thiểu, bạn cần triển khai
+các phương pháp sau:</p>
+
+<ul>
+<li>{@link android.provider.DocumentsProvider#queryRoots queryRoots()}</li>
+
+<li>{@link android.provider.DocumentsProvider#queryChildDocuments queryChildDocuments()}</li>
+
+<li>{@link android.provider.DocumentsProvider#queryDocument queryDocument()}</li>
+
+<li>{@link android.provider.DocumentsProvider#openDocument openDocument()}</li>
+</ul>
+
+<p>Đây là những phương pháp duy nhất mà bạn được yêu cầu phải triển khai, nhưng còn
+nhiều phương pháp nữa mà bạn có thể muốn triển khai. Xem {@link android.provider.DocumentsProvider}
+để biết chi tiết.</p>
+
+<h4 id="queryRoots">Triển khai queryRoots</h4>
+
+<p>Việc bạn triển khai {@link android.provider.DocumentsProvider#queryRoots
+queryRoots()} phải trả về một {@link android.database.Cursor} trỏ về tất cả
+thư mục gốc trong trình cung cấp tài liệu của bạn, bằng cách sử dụng các cột được định nghĩa trong
+{@link android.provider.DocumentsContract.Root}.</p>
+
+<p>Trong đoạn mã HTML sau, tham số {@code projection} biểu diễn các trường cụ thể
+mà hàm gọi muốn nhận về. Đoạn mã HTML tạo một con chạy mới
+và thêm một hàng vào nó&mdash;một thư mục gốc, mức cao nhất, như
+Downloads hoặc Images. Hầu hết các trình cung cấp chỉ có một phần gốc. Bạn có thể có nhiều hơn một,
+ví dụ, trong trường hợp nhiều tài khoản người dùng. Trong trường hợp đó, chỉ cần thêm một
+hàng thứ hai vào con chạy.</p>
+
+<pre>
+&#64;Override
+public Cursor queryRoots(String[] projection) throws FileNotFoundException {
+
+ // Create a cursor with either the requested fields, or the default
+ // projection if "projection" is null.
+ final MatrixCursor result =
+ new MatrixCursor(resolveRootProjection(projection));
+
+ // If user is not logged in, return an empty root cursor. This removes our
+ // provider from the list entirely.
+ if (!isUserLoggedIn()) {
+ return result;
+ }
+
+ // It's possible to have multiple roots (e.g. for multiple accounts in the
+ // same app) -- just add multiple cursor rows.
+ // Construct one row for a root called &quot;MyCloud&quot;.
+ final MatrixCursor.RowBuilder row = result.newRow();
+ row.add(Root.COLUMN_ROOT_ID, ROOT);
+ row.add(Root.COLUMN_SUMMARY, getContext().getString(R.string.root_summary));
+
+ // FLAG_SUPPORTS_CREATE means at least one directory under the root supports
+ // creating documents. FLAG_SUPPORTS_RECENTS means your application's most
+ // recently used documents will show up in the &quot;Recents&quot; category.
+ // FLAG_SUPPORTS_SEARCH allows users to search all documents the application
+ // shares.
+ row.add(Root.COLUMN_FLAGS, Root.FLAG_SUPPORTS_CREATE |
+ Root.FLAG_SUPPORTS_RECENTS |
+ Root.FLAG_SUPPORTS_SEARCH);
+
+ // COLUMN_TITLE is the root title (e.g. Gallery, Drive).
+ row.add(Root.COLUMN_TITLE, getContext().getString(R.string.title));
+
+ // This document id cannot change once it's shared.
+ row.add(Root.COLUMN_DOCUMENT_ID, getDocIdForFile(mBaseDir));
+
+ // The child MIME types are used to filter the roots and only present to the
+ // user roots that contain the desired type somewhere in their file hierarchy.
+ row.add(Root.COLUMN_MIME_TYPES, getChildMimeTypes(mBaseDir));
+ row.add(Root.COLUMN_AVAILABLE_BYTES, mBaseDir.getFreeSpace());
+ row.add(Root.COLUMN_ICON, R.drawable.ic_launcher);
+
+ return result;
+}</pre>
+
+<h4 id="queryChildDocuments">Triển khai queryChildDocuments</h4>
+
+<p>Việc bạn triển khai
+{@link android.provider.DocumentsProvider#queryChildDocuments queryChildDocuments()}
+phải trả về một {@link android.database.Cursor} mà chỉ đến tất cả tệp trong
+thư mục được chỉ định, bằng cách sử dụng các cột được định nghĩa trong
+{@link android.provider.DocumentsContract.Document}.</p>
+
+<p>Phương pháp này được gọi khi bạn chọn một thư mục gốc ứng dụng trong UI bộ chọn.
+Nó nhận được tài liệu con của một thư mục nằm dưới phần gốc. Nó có thể được gọi ở bất kỳ mức nào trong phân cấp tệp
+, không chỉ phần gốc. Đoạn mã HTML
+này tạo một con chạy mới bằng các cột được yêu cầu, sau đó thêm thông tin về
+mọi tệp con trực tiếp trong thư mục mẹ vào con chạy.
+Tệp con có thể là một hình ảnh, một thư mục khác&mdash;bất kỳ tệp nào:</p>
+
+<pre>&#64;Override
+public Cursor queryChildDocuments(String parentDocumentId, String[] projection,
+ String sortOrder) throws FileNotFoundException {
+
+ final MatrixCursor result = new
+ MatrixCursor(resolveDocumentProjection(projection));
+ final File parent = getFileForDocId(parentDocumentId);
+ for (File file : parent.listFiles()) {
+ // Adds the file's display name, MIME type, size, and so on.
+ includeFile(result, null, file);
+ }
+ return result;
+}
+</pre>
+
+<h4 id="queryDocument">Triển khai queryDocument</h4>
+
+<p>Việc bạn triển khai
+{@link android.provider.DocumentsProvider#queryDocument queryDocument()}
+phải trả về một {@link android.database.Cursor} mà chỉ đến tệp được chỉ định,
+bằng cách sử dụng các cột được định nghĩa trong {@link android.provider.DocumentsContract.Document}.
+</p>
+
+<p>Phương pháp {@link android.provider.DocumentsProvider#queryDocument queryDocument()}
+trả về cùng thông tin đã được chuyển trong
+{@link android.provider.DocumentsProvider#queryChildDocuments queryChildDocuments()},
+nhưng là đối với một tệp cụ thể:</p>
+
+
+<pre>&#64;Override
+public Cursor queryDocument(String documentId, String[] projection) throws
+ FileNotFoundException {
+
+ // Create a cursor with the requested projection, or the default projection.
+ final MatrixCursor result = new
+ MatrixCursor(resolveDocumentProjection(projection));
+ includeFile(result, documentId, null);
+ return result;
+}
+</pre>
+
+<h4 id="openDocument">Triển khai openDocument</h4>
+
+<p>Bạn phải triển khai {@link android.provider.DocumentsProvider#openDocument
+openDocument()} để trả về một {@link android.os.ParcelFileDescriptor} biểu diễn
+tệp được chỉ định. Các ứng dụng khác có thể sử dụng {@link android.os.ParcelFileDescriptor}
+được trả về để truyền phát dữ liệu. Hệ thống gọi phương pháp này sau khi người dùng chọn một tệp
+và ứng dụng máy khách yêu cầu truy cập nó bằng cách gọi
+{@link android.content.ContentResolver#openFileDescriptor openFileDescriptor()}.
+Ví dụ:</p>
+
+<pre>&#64;Override
+public ParcelFileDescriptor openDocument(final String documentId,
+ final String mode,
+ CancellationSignal signal) throws
+ FileNotFoundException {
+ Log.v(TAG, &quot;openDocument, mode: &quot; + mode);
+ // It's OK to do network operations in this method to download the document,
+ // as long as you periodically check the CancellationSignal. If you have an
+ // extremely large file to transfer from the network, a better solution may
+ // be pipes or sockets (see ParcelFileDescriptor for helper methods).
+
+ final File file = getFileForDocId(documentId);
+
+ final boolean isWrite = (mode.indexOf('w') != -1);
+ if(isWrite) {
+ // Attach a close listener if the document is opened in write mode.
+ try {
+ Handler handler = new Handler(getContext().getMainLooper());
+ return ParcelFileDescriptor.open(file, accessMode, handler,
+ new ParcelFileDescriptor.OnCloseListener() {
+ &#64;Override
+ public void onClose(IOException e) {
+
+ // Update the file with the cloud server. The client is done
+ // writing.
+ Log.i(TAG, &quot;A file with id &quot; +
+ documentId + &quot; has been closed!
+ Time to &quot; +
+ &quot;update the server.&quot;);
+ }
+
+ });
+ } catch (IOException e) {
+ throw new FileNotFoundException(&quot;Failed to open document with id &quot;
+ + documentId + &quot; and mode &quot; + mode);
+ }
+ } else {
+ return ParcelFileDescriptor.open(file, accessMode);
+ }
+}
+</pre>
+
+<h3 id="security">Bảo mật</h3>
+
+<p>Giả sử trình cung cấp tài liệu của bạn là một dịch vụ lưu trữ đám mây được bảo vệ bằng mật khẩu
+và bạn muốn đảm bảo rằng người dùng được đăng nhập trước khi bạn bắt đầu chia sẻ tệp của họ.
+Ứng dụng của bạn nên làm gì nếu người dùng không đăng nhập? Giải pháp là trả về
+phần gốc 0 trong triển khai {@link android.provider.DocumentsProvider#queryRoots
+queryRoots()} của bạn. Cụ thể là một con chạy gốc trống:</p>
+
+<pre>
+public Cursor queryRoots(String[] projection) throws FileNotFoundException {
+...
+ // If user is not logged in, return an empty root cursor. This removes our
+ // provider from the list entirely.
+ if (!isUserLoggedIn()) {
+ return result;
+}
+</pre>
+
+<p>Bước còn lại là gọi {@code getContentResolver().notifyChange()}.
+Bạn còn nhớ {@link android.provider.DocumentsContract} chứ? Chúng ta đang sử dụng nó để tạo
+URI này. Đoạn mã HTML sau báo cho hệ thống truy vấn các phần gốc trong
+trình cung cấp tài liệu của bạn bất cứ khi nào trạng thái đăng nhập của người dùng thay đổi. Nếu người dùng không được
+đăng nhập, lệnh gọi tới {@link android.provider.DocumentsProvider#queryRoots queryRoots()} sẽ trả về một
+con chạy trống như minh họa bên trên. Điều này đảm bảo rằng tài liệu của một trình cung cấp chỉ
+có sẵn nếu người dùng đăng nhập vào trình cung cấp đó.</p>
+
+<pre>private void onLoginButtonClick() {
+ loginOrLogout();
+ getContentResolver().notifyChange(DocumentsContract
+ .buildRootsUri(AUTHORITY), null);
+}
+</pre> \ No newline at end of file
diff --git a/docs/html-intl/intl/vi/guide/topics/resources/accessing-resources.jd b/docs/html-intl/intl/vi/guide/topics/resources/accessing-resources.jd
new file mode 100644
index 000000000000..b5491dcdee2c
--- /dev/null
+++ b/docs/html-intl/intl/vi/guide/topics/resources/accessing-resources.jd
@@ -0,0 +1,337 @@
+page.title=Truy cập Tài nguyên
+parent.title=Tài nguyên Ứng dụng
+parent.link=index.html
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+ <h2>Xem nhanh</h2>
+ <ul>
+ <li>Tài nguyên có thể được tham chiếu từ mã bằng các số nguyên từ {@code R.java}, chẳng hạn như
+{@code R.drawable.myimage}</li>
+ <li>Tài nguyên có thể được tham chiếu từ các tài nguyên bằng cách sử dụng một cú pháp XML đặc biệt, ví dụ như {@code
+&#64;drawable/myimage}</li>
+ <li>Bạn cũng có thể truy cập tài nguyên ứng dụng của mình bằng các phương pháp trong
+{@link android.content.res.Resources}</li>
+ </ul>
+
+ <h2>Lớp khóa</h2>
+ <ol>
+ <li>{@link android.content.res.Resources}</li>
+ </ol>
+
+ <h2>Trong tài liệu này</h2>
+ <ol>
+ <li><a href="#ResourcesFromCode">Truy cập Tài nguyên từ Mã</a></li>
+ <li><a href="#ResourcesFromXml">Truy cập Tài nguyên từ XML</a>
+ <ol>
+ <li><a href="#ReferencesToThemeAttributes">Tham chiếu các thuộc tính kiểu</a></li>
+ </ol>
+ </li>
+ <li><a href="#PlatformResources">Truy cập Tài nguyên Nền tảng</a></li>
+ </ol>
+
+ <h2>Xem thêm</h2>
+ <ol>
+ <li><a href="providing-resources.html">Cung cấp Tài nguyên</a></li>
+ <li><a href="available-resources.html">Loại Tài nguyên</a></li>
+ </ol>
+</div>
+</div>
+
+
+
+
+<p>Sau khi cung cấp một tài nguyên trong ứng dụng của mình (đề cập trong <a href="providing-resources.html">Cung cấp Tài nguyên</a>), bạn có thể áp dụng nó bằng cách
+tham chiếu ID tài nguyên đó. Tất cả ID tài nguyên được định nghĩa trong lớp {@code R} dự án của bạn, do
+công cụ {@code aapt} tự động khởi tạo.</p>
+
+<p>Khi ứng dụng của bạn được biên dịch, {@code aapt} khởi tạo lớp {@code R}, trong đó chứa
+ID tài nguyên cho tất cả tài nguyên trong thư mục {@code
+res/} của bạn. Với mỗi loại tài nguyên, có một lớp con {@code R} (ví dụ,
+{@code R.drawable} cho tất cả tài nguyên có thể vẽ), và với mỗi tài nguyên loại đó, có một số nguyên
+tĩnh (ví dụ, {@code R.drawable.icon}). Số nguyên này là ID tài nguyên mà bạn có thể sử dụng
+để truy xuất tài nguyên của mình.</p>
+
+<p>Mặc dù lớp {@code R} là nơi các ID tài nguyên được quy định, bạn sẽ không cần
+tìm ở đó để khám phá một ID tài nguyên. Một ID tài nguyên luôn bao gồm:</p>
+<ul>
+ <li><em>Loại tài nguyên</em>: Mỗi tài nguyên được nhóm vào một "loại," chẳng hạn như {@code
+string}, {@code drawable}, và {@code layout}. Để biết thêm về các loại khác nhau, hãy xem phần <a href="available-resources.html">Loại Tài nguyên</a>.
+ </li>
+ <li><em>Tên tài nguyên</em>, là, hoặc: tên tệp,
+không bao gồm phần mở rộng; hoặc giá trị trong thuộc tính XML {@code android:name}, nếu tài nguyên
+đó là một giá trị đơn giản (chẳng hạn như một xâu).</li>
+</ul>
+
+<p>Có hai cách để bạn có thể truy cập một tài nguyên:</p>
+<ul>
+ <li><strong>Trong mã:</strong> Sử dụng một số nguyên tĩnh từ một lớp con của lớp {@code R}
+của bạn, chẳng hạn như:
+ <pre class="classic no-pretty-print">R.string.hello</pre>
+ <p>{@code string} là loại tài nguyên và {@code hello} là tên tài nguyên. Có nhiều
+API Android mà có thể truy cập các tài nguyên của bạn khi bạn cung cấp một ID tài nguyên theo định dạng này. Xem
+<a href="#ResourcesFromCode">Truy cập Tài nguyên trong Mã</a>.</p>
+ </li>
+ <li><strong>Trong XML:</strong> Sử dụng một cú pháp XML đặc biệt mà cũng tương ứng với
+ID tài nguyên được định nghĩa trong lớp {@code R} của bạn, chẳng hạn như:
+ <pre class="classic no-pretty-print">&#64;string/hello</pre>
+ <p>{@code string} là loại tài nguyên và {@code hello} là tên tài nguyên. Bạn có thể sử dụng cú pháp
+này trong một tài nguyên XML ở bất kỳ nơi nào có kỳ vọng một giá trị mà bạn cung cấp trong một tài nguyên. Xem phần <a href="#ResourcesFromXml">Truy cập Tài nguyên từ XML</a>.</p>
+ </li>
+</ul>
+
+
+
+<h2 id="ResourcesFromCode">Truy cập Tài nguyên trong Mã </h2>
+
+<p>Bạn có thể sử dụng một tài nguyên trong mã bằng cách chuyển ID tài nguyên như một tham số phương pháp. Ví
+dụ, bạn có thể đặt một {@link android.widget.ImageView} để sử dụng tài nguyên {@code res/drawable/myimage.png}
+bằng cách sử dụng {@link android.widget.ImageView#setImageResource(int) setImageResource()}:</p>
+<pre>
+ImageView imageView = (ImageView) findViewById(R.id.myimageview);
+imageView.setImageResource(<strong>R.drawable.myimage</strong>);
+</pre>
+
+<p>Bạn cũng có thể truy xuất các tài nguyên riêng lẻ bằng các phương pháp trong {@link
+android.content.res.Resources}, theo đó bạn có thể nhận được một thực thể
+bằng {@link android.content.Context#getResources()}.</p>
+
+<div class="sidebox-wrapper">
+<div class="sidebox">
+<h2>Truy cập các Tệp Gốc</h2>
+
+<p>Tuy không thường gặp, song bạn có thể cần truy cập các tệp và thư mục gốc của mình. Nếu bạn làm vậy thì việc
+lưu các tệp của bạn trong {@code res/} sẽ không có tác dụng với bạn, vì cách duy nhất để đọc một tài nguyên từ
+{@code res/} đó là bằng ID tài nguyên. Thay vào đó, bạn có thể lưu các tài nguyên của mình trong thư mục
+{@code assets/}.</p>
+<p>Các tệp lưu trong thư mục {@code assets/} <em>không</em> được cấp ID tài nguyên
+, vì thế bạn không thể tham chiếu chúng thông qua lớp {@code R} hoặc từ các tài nguyên XML. Thay vào đó, bạn có thể
+truy vấn các tệp trong thư mục {@code assets/} như một hệ thống tệp bình thường và đọc dữ liệu thô bằng cách sử dụng
+{@link android.content.res.AssetManager}.</p>
+<p>Tuy nhiên, nếu tất cả những gì bạn yêu cầu là khả năng đọc dữ liệu thô (chẳng hạn như một tệp video hoặc âm thanh),
+vậy bạn hãy lưu tệp trong thư mục {@code res/raw/} và đọc một luồng byte bằng cách sử dụng {@link
+android.content.res.Resources#openRawResource(int) openRawResource()}.</p>
+
+</div>
+</div>
+
+
+<h3>Cú pháp</h3>
+
+<p>Sau đây là cú pháp để tham chiếu một tài nguyên trong mã:</p>
+
+<pre class="classic no-pretty-print">
+[<em>&lt;package_name&gt;</em>.]R.<em>&lt;resource_type&gt;</em>.<em>&lt;resource_name&gt;</em>
+</pre>
+
+<ul>
+ <li><em>{@code &lt;package_name&gt;}</em> là tên của gói mà tài nguyên nằm trong đó (không
+bắt buộc khi tham chiếu các tài nguyên từ gói của chính bạn).</li>
+ <li><em>{@code &lt;resource_type&gt;}</em> là lớp con {@code R} cho loại tài nguyên.</li>
+ <li><em>{@code &lt;resource_name&gt;}</em> hoặc là tên tệp tài nguyên
+không có phần mở rộng hoặc là giá trị thuộc tính {@code android:name} trong phần tử XML (đối với các giá trị
+đơn giản).</li>
+</ul>
+<p>Xem phần <a href="available-resources.html">Loại Tài nguyên</a> để
+biết thêm thông tin về mỗi loại tài nguyên và cách tham chiếu chúng.</p>
+
+
+<h3>Trường hợp sử dụng</h3>
+
+<p>Có nhiều phương pháp chấp nhận một tham số ID tài nguyên và bạn có thể truy xuất tài nguyên bằng cách sử dụng
+các phương pháp trong {@link android.content.res.Resources}. Bạn có thể lấy một thực thể {@link
+android.content.res.Resources} bằng {@link android.content.Context#getResources
+Context.getResources()}.</p>
+
+
+<p>Sau đây là một số ví dụ về truy cập tài nguyên trong mã:</p>
+
+<pre>
+// Load a background for the current screen from a drawable resource
+{@link android.app.Activity#getWindow()}.{@link
+android.view.Window#setBackgroundDrawableResource(int)
+setBackgroundDrawableResource}(<strong>R.drawable.my_background_image</strong>) ;
+
+// Set the Activity title by getting a string from the Resources object, because
+// this method requires a CharSequence rather than a resource ID
+{@link android.app.Activity#getWindow()}.{@link android.view.Window#setTitle(CharSequence)
+setTitle}(getResources().{@link android.content.res.Resources#getText(int)
+getText}(<strong>R.string.main_title</strong>));
+
+// Load a custom layout for the current screen
+{@link android.app.Activity#setContentView(int)
+setContentView}(<strong>R.layout.main_screen</strong>);
+
+// Set a slide in animation by getting an Animation from the Resources object
+mFlipper.{@link android.widget.ViewAnimator#setInAnimation(Animation)
+setInAnimation}(AnimationUtils.loadAnimation(this,
+ <strong>R.anim.hyperspace_in</strong>));
+
+// Set the text on a TextView object using a resource ID
+TextView msgTextView = (TextView) findViewById(<strong>R.id.msg</strong>);
+msgTextView.{@link android.widget.TextView#setText(int)
+setText}(<strong>R.string.hello_message</strong>);
+</pre>
+
+
+<p class="caution"><strong>Chú ý:</strong> Bạn không nên sửa đổi tệp {@code
+R.java} bằng cách thủ công&mdash;nó được khởi tạo bởi công cụ {@code aapt} khi dự án của bạn được
+biên dịch. Mọi thay đổi đều bị ghi đè vào lần biên dịch tới của bạn.</p>
+
+
+
+<h2 id="ResourcesFromXml">Truy cập Tài nguyên từ XML</h2>
+
+<p>Bạn có thể định nghĩa các giá trị cho một số thuộc tính và phần tử XML bằng cách sử dụng một
+tham chiếu tới một tài nguyên hiện có. Bạn sẽ thường làm điều này khi tạo các tệp bố trí, để
+cung cấp các xâu và hình ảnh cho widget của mình.</p>
+
+<p>Ví dụ, nếu thêm một {@link android.widget.Button} vào bố trí của mình, bạn nên sử dụng
+một <a href="string-resource.html">tài nguyên xâu</a> cho văn bản nút:</p>
+
+<pre>
+&lt;Button
+ android:layout_width="fill_parent"
+ android:layout_height="wrap_content"
+ android:text="<strong>@string/submit</strong>" /&gt;
+</pre>
+
+
+<h3>Cú pháp</h3>
+
+<p>Sau đây là cú pháp để tham chiếu một tài nguyên trong một tài nguyên XML:</p>
+
+<pre class="classic no-pretty-print">
+&#64;[<em>&lt;package_name&gt;</em>:]<em>&lt;resource_type&gt;</em>/<em>&lt;resource_name&gt;</em>
+</pre>
+
+<ul>
+ <li>{@code &lt;package_name&gt;} là tên của gói mà tài nguyên nằm trong đó (không
+bắt buộc khi tham chiếu các tài nguyên từ cùng gói đó)</li>
+ <li>{@code &lt;resource_type&gt;} là lớp con
+{@code R} cho loại tài nguyên.</li>
+ <li>{@code &lt;resource_name&gt;} hoặc là tên tệp tài nguyên
+không có phần mở rộng hoặc là giá trị thuộc tính {@code android:name} trong phần tử XML (đối với các giá trị
+đơn giản).</li>
+</ul>
+
+<p>Xem phần <a href="available-resources.html">Loại Tài nguyên</a> để
+biết thêm thông tin về mỗi loại tài nguyên và cách tham chiếu chúng.</p>
+
+
+<h3>Trường hợp sử dụng</h3>
+
+<p>Trong một số trường hợp bạn phải sử dụng một tài nguyên cho một giá trị trong XML (ví dụ, để áp dụng một hình ảnh có thể vẽ
+cho một widget), nhưng bạn cũng có thể sử dụng một tài nguyên trong XML ở bất kỳ nơi nào chấp nhận một giá trị đơn giản. Ví
+dụ, nếu bạn có tệp tài nguyên sau bao gồm một <a href="more-resources.html#Color">tài nguyên màu</a> và một <a href="string-resource.html">tài nguyên xâu</a>:</p>
+
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;resources>
+ &lt;color name="opaque_red">#f00&lt;/color>
+ &lt;string name="hello">Hello!&lt;/string>
+&lt;/resources>
+</pre>
+
+<p>Bạn có thể sử dụng những tài nguyên này trong tệp bố trí sau để đặt màu văn bản và
+xâu văn bản:</p>
+
+<pre>
+&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
+&lt;EditText xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
+ android:layout_width=&quot;fill_parent&quot;
+ android:layout_height=&quot;fill_parent&quot;
+ android:textColor=&quot;<strong>&#64;color/opaque_red</strong>&quot;
+ android:text=&quot;<strong>&#64;string/hello</strong>&quot; /&gt;
+</pre>
+
+<p>Trong trường hợp này, bạn không cần quy định tên gói trong tham chiếu tài nguyên đó vì tài nguyên
+xuất phát từ gói của chính bạn. Để
+tham chiếu một tài nguyên hệ thống, bạn sẽ cần đưa vào tên gói. Ví dụ:</p>
+
+<pre>
+&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;
+&lt;EditText xmlns:android=&quot;http://schemas.android.com/apk/res/android&quot;
+ android:layout_width=&quot;fill_parent&quot;
+ android:layout_height=&quot;fill_parent&quot;
+ android:textColor=&quot;<strong>&#64;android:color/secondary_text_dark</strong>&quot;
+ android:text=&quot;&#64;string/hello&quot; /&gt;
+</pre>
+
+<p class="note"><strong>Lưu ý:</strong> Bạn nên sử dụng các tài nguyên xâu
+vào mọi lúc, để ứng dụng của bạn có thể được bản địa hóa cho các ngôn ngữ khác.
+Để biết thông tin về việc tạo các tài nguyên
+thay thế (chẳng hạn như xâu được bản địa hóa), hãy xem phần <a href="providing-resources.html#AlternativeResources">Cung cấp Tài nguyên
+Thay thế</a>. Để được hướng dẫn đầy đủ về việc bản địa hóa ứng dụng của bạn cho các ngôn ngữ khác,
+hãy xem phần <a href="localization.html">Bản địa hóa</a>.</p>
+
+<p>Bạn thậm chí có thể sử dụng tài nguyên trong XML để tạo các bí danh. Ví dụ, bạn có thể tạo một tài nguyên có thể vẽ
+là một bí danh cho một tài nguyên có thể vẽ khác:</p>
+
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@drawable/other_drawable" />
+</pre>
+
+<p>Nghe có vẻ thừa, nhưng có thể rất hữu ích khi sử dụng tài nguyên thay thế. Đọc thêm về
+<a href="providing-resources.html#AliasResources">Tạo tài nguyên bí danh</a>.</p>
+
+
+
+<h3 id="ReferencesToThemeAttributes">Tham chiếu các thuộc tính kiểu</h3>
+
+<p>Một tài nguyên thuộc tính kiểu sẽ cho phép bạn tham chiếu giá trị
+của một thuộc tính trong chủ đề đang áp dụng. Tham chiếu một thuộc tính kiểu sẽ cho phép bạn
+tùy chỉnh diện mạo của các phần tử UI bằng cách tạo kiểu cho chúng để phù hợp với các biến đổi tiêu chuẩn được cung cấp bởi
+chủ đề hiện tại, thay vì cung cấp một giá trị được mã hóa cố định. Tham chiếu một thuộc tính kiểu
+về cơ bản mà nói, là "sử dụng kiểu được định nghĩa bởi thuộc tính này, trong chủ đề hiện tại."</p>
+
+<p>Để tham chiếu một thuộc tính kiểu, cú pháp tên gần như tương tự với định dạng tài nguyên thường
+, nhưng thay vì biểu tượng @ ({@code @}), hãy sử dụng một dấu hỏi ({@code ?}), và
+phần loại tài nguyên là tùy chọn. Ví dụ:</p>
+
+<pre class="classic">
+?[<em>&lt;package_name&gt;</em>:][<em>&lt;resource_type&gt;</em>/]<em>&lt;resource_name&gt;</em>
+</pre>
+
+<p>Ví dụ, sau đây là cách bạn có thể tham chiếu một thuộc tính để đặt màu văn bản cho phù hợp với màu văn bản
+"chính" của chủ đề hệ thống:</p>
+
+<pre>
+&lt;EditText id=&quot;text&quot;
+ android:layout_width=&quot;fill_parent&quot;
+ android:layout_height=&quot;wrap_content&quot;
+ android:textColor=&quot;<strong>?android:textColorSecondary</strong>&quot;
+ android:text=&quot;&#64;string/hello_world&quot; /&gt;
+</pre>
+
+<p>Ở đây, thuộc tính {@code android:textColor} quy định tên của một thuộc tính kiểu
+trong chủ đề hiện tại. Hiện nay, Android sử dụng giá trị được áp dụng cho thuộc tính kiểu {@code android:textColorSecondary}
+làm giá trị cho {@code android:textColor} trong widget này. Vì công cụ tài nguyên
+hệ thống biết rằng một tài nguyên thuộc tính sẽ được yêu cầu trong ngữ cảnh này,
+bạn không cần nêu rõ loại (mà sẽ là
+<code>?android:attr/textColorSecondary</code>)&mdash;bạn có thể không nêu loại {@code attr}.</p>
+
+
+
+
+<h2 id="PlatformResources">Truy cập Tài nguyên Nền tảng</h2>
+
+<p>Android bao gồm nhiều tài nguyên tiêu chuẩn, chẳng hạn như kiểu, chủ đề và bố trí. Để
+truy cập các tài nguyên này, hãy xác định tham chiếu tài nguyên của bạn bằng tên gói
+<code>android</code>. Ví dụ, Android cung cấp một tài nguyên bố trí bạn có thể sử dụng cho
+các mục danh sách trong một {@link android.widget.ListAdapter}:</p>
+
+<pre>
+{@link android.app.ListActivity#setListAdapter(ListAdapter)
+setListAdapter}(new {@link
+android.widget.ArrayAdapter}&lt;String&gt;(this, <strong>android.R.layout.simple_list_item_1</strong>, myarray));
+</pre>
+
+<p>Trong ví dụ này, {@link android.R.layout#simple_list_item_1} là một tài nguyên bố trí được định nghĩa bởi
+nền tảng cho các mục trong một {@link android.widget.ListView}. Bạn có thể sử dụng điều này thay vì tạo
+bố trí riêng của mình cho các mục danh sách. Để biết thêm thông tin, hãy xem phần
+<a href="{@docRoot}guide/topics/ui/layout/listview.html">Dạng xem Danh sách</a> trong hướng dẫn cho nhà phát triển.</p>
+
diff --git a/docs/html-intl/intl/vi/guide/topics/resources/overview.jd b/docs/html-intl/intl/vi/guide/topics/resources/overview.jd
new file mode 100644
index 000000000000..7bbd72af96a7
--- /dev/null
+++ b/docs/html-intl/intl/vi/guide/topics/resources/overview.jd
@@ -0,0 +1,103 @@
+page.title=Tổng quan về Tài nguyên
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+ <h2>Chủ đề</h2>
+ <ol>
+ <li><a href="providing-resources.html">Cung cấp Tài nguyên</a></li>
+ <li><a href="accessing-resources.html">Truy cập Tài nguyên</a></li>
+ <li><a href="runtime-changes.html">Xử lý Thay đổi Thời gian chạy</a></li>
+ <li><a href="localization.html">Bản địa hóa</a></li>
+ </ol>
+
+ <h2>Tham khảo</h2>
+ <ol>
+ <li><a href="available-resources.html">Loại Tài nguyên</a></li>
+ </ol>
+</div>
+</div>
+
+
+<p>Bạn nên luôn ngoại hiện hóa các tài nguyên chẳng hạn như hình ảnh và xâu từ mã
+ứng dụng của mình, sao cho bạn có thể duy trì chúng một cách độc lập. Việc ngoại hiện hóa
+tài nguyên cũng cho phép bạn cung cấp các tài nguyên thay thế hỗ trợ những cấu hình
+thiết bị cụ thể chẳng hạn như ngôn ngữ hoặc kích cỡ màn hình khác nhau, điều này đang ngày càng trở nên
+quan trọng bởi các thiết bị dựa trên nền tảng Android ngày càng sẵn có với các cấu hình khác nhau. Để
+đảm bảo tính tương thích với các cấu hình khác nhau, bạn phải tổ chức tài nguyên trong
+thư mục {@code res/} dự án của bạn bằng cách sử dụng các thư mục con khác nhau có chức năng nhóm tài nguyên lại theo loại và
+cấu hình.</p>
+
+<div class="figure" style="width:429px">
+<img src="{@docRoot}images/resources/resource_devices_diagram1.png" height="167" alt="" />
+<p class="img-caption">
+<strong>Hình 1.</strong> Hai thiết bị khác nhau, mỗi thiết bị sử dụng bố trí mặc định
+(ứng dụng không cung cấp bố trí thay thế).</p>
+</div>
+
+<div class="figure" style="width:429px">
+<img src="{@docRoot}images/resources/resource_devices_diagram2.png" height="167" alt="" />
+<p class="img-caption">
+<strong>Hình 2.</strong> Hai thiết bị khác nhau, mỗi thiết bị sử dụng một bố trí khác nhau được cung cấp
+cho các kích cỡ màn hình khác nhau.</p>
+</div>
+
+<p>Đối với mọi loại tài nguyên, bạn có thể quy định tài nguyên <em>mặc định</em> và nhiều tài nguyên
+<em>thay thế</em> cho ứng dụng của mình:</p>
+<ul>
+ <li>Tài nguyên mặc định là những tài nguyên nên được sử dụng không phụ thuộc vào
+cấu hình thiết bị hoặc khi không có tài nguyên thay thế khớp với cấu hình
+hiện tại.</li>
+ <li>Tài nguyên thay thế là những tài nguyên mà bạn đã thiết kế để sử dụng với một cấu hình
+cụ thể. Để quy định rằng một nhóm tài nguyên áp dụng cho một cấu hình cụ thể,
+hãy nối hình dạng cấu hình phù hợp với tên thư mục.</li>
+</ul>
+
+<p>Ví dụ, trong khi bố trí UI mặc định của bạn
+được lưu trong thư mục {@code res/layout/}, bạn có thể quy định một bố trí khác sẽ
+được sử dụng khi màn hình ở hướng khổ ngang, bằng cách lưu nó trong thư mục {@code res/layout-land/}
+. Android tự động áp dụng các tài nguyên phù hợp bằng cách khớp cấu hình hiện tại
+của thiết bị với tên thư mục tài nguyên của bạn.</p>
+
+<p>Hình 1 minh họa cách hệ thống áp dụng cùng bố trí cho
+hai thiết bị khác nhau khi không có sẵn tài nguyên thay thế. Hình 2 minh họa
+cùng ứng dụng khi nó thêm một tài nguyên bố trí thay thế cho các màn hình lớn hơn.</p>
+
+<p>Các tài liệu sau trình bày hướng dẫn hoàn chỉnh về cách bạn có thể tổ chức các tài nguyên ứng dụng của mình,
+quy định tài nguyên thay thế, truy cập chúng trong ứng dụng của bạn, và nhiều điều khác:</p>
+
+<dl>
+ <dt><strong><a href="providing-resources.html">Cung cấp Tài nguyên</a></strong></dt>
+ <dd>Những kiểu tài nguyên mà bạn có thể cung cấp trong ứng dụng của mình, nơi lưu chúng, và cách tạo
+tài nguyên thay thế cho những cấu hình thiết bị cụ thể.</dd>
+ <dt><strong><a href="accessing-resources.html">Truy cập Tài nguyên</a></strong></dt>
+ <dd>Cách sử dụng tài nguyên mà bạn đã cung cấp hoặc bằng cách tham chiếu chúng từ mã ứng dụng của mình
+hoặc từ các tài nguyên XML khác.</dd>
+ <dt><strong><a href="runtime-changes.html">Xử lý Thay đổi Thời gian chạy</a></strong></dt>
+ <dd>Cách quản lý những thay đổi cấu hình mà diễn ra trong khi Hoạt động của bạn đang chạy.</dd>
+ <dt><strong><a href="localization.html">Bản địa hóa</a></strong></dt>
+ <dd>Một hướng dẫn từ dưới lên về việc bản địa hóa ứng dụng của bạn bằng cách sử dụng các tài nguyên thay thế. Trong khi đây
+chỉ là một công dụng cụ thể của tài nguyên thay thế, nó rất quan trọng để tiếp cận với nhiều
+người dùng hơn.</dd>
+ <dt><strong><a href="available-resources.html">Loại Tài nguyên</a></strong></dt>
+ <dd>Một tham chiếu về các loại tài nguyên khác nhau mà bạn có thể cung cấp, mô tả các phần tử XML,
+thuộc tính và cú pháp của chúng. Ví dụ, tham chiếu này cho bạn thấy cách tạo một tài nguyên cho
+menu ứng dụng, đối tượng vẽ được, hoạt ảnh, và hơn thế nữa.</dd>
+</dl>
+
+<!--
+<h2>Raw Assets</h2>
+
+<p>An alternative to saving files in {@code res/} is to save files in the {@code
+assets/} directory. This should only be necessary if you need direct access to original files and
+directories by name. Files saved in the {@code assets/} directory will not be given a resource
+ID, so you can't reference them through the {@code R} class or from XML resources. Instead, you can
+query data in the {@code assets/} directory like an ordinary file system, search through the
+directory and
+read raw data using {@link android.content.res.AssetManager}. For example, this can be more useful
+when dealing with textures for a game. However, if you only need to read raw data from a file
+(such as a video or audio file), then you should save files into the {@code res/raw/} directory and
+then read a stream of bytes using {@link android.content.res.Resources#openRawResource(int)}. This
+is uncommon, but if you need direct access to original files in {@code assets/}, refer to the {@link
+android.content.res.AssetManager} documentation.</p>
+-->
diff --git a/docs/html-intl/intl/vi/guide/topics/resources/providing-resources.jd b/docs/html-intl/intl/vi/guide/topics/resources/providing-resources.jd
new file mode 100644
index 000000000000..b733643e75cd
--- /dev/null
+++ b/docs/html-intl/intl/vi/guide/topics/resources/providing-resources.jd
@@ -0,0 +1,1094 @@
+page.title=Cung cấp Tài nguyên
+parent.title=Tài nguyên Ứng dụng
+parent.link=index.html
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+ <h2>Xem nhanh</h2>
+ <ul>
+ <li>Các loại tài nguyên khác nhau thuộc về các thư mục con khác nhau của {@code res/}</li>
+ <li>Tài nguyên thay thế cung cấp các tệp tài nguyên theo cấu hình cụ thể</li>
+ <li>Luôn bao gồm tài nguyên mặc định để ứng dụng của bạn không phụ thuộc vào các
+cấu hình thiết bị cụ thể</li>
+ </ul>
+ <h2>Trong tài liệu này</h2>
+ <ol>
+ <li><a href="#ResourceTypes">Nhóm các Loại Tài nguyên lại</a></li>
+ <li><a href="#AlternativeResources">Cung cấp Tài nguyên Thay thế</a>
+ <ol>
+ <li><a href="#QualifierRules">Quy tắc về tên hạn định</a></li>
+ <li><a href="#AliasResources">Tạo tài nguyên bí danh</a></li>
+ </ol>
+ </li>
+ <li><a href="#Compatibility">Cung cấp Tính tương thích giữa Thiết bị với Tài nguyên Tốt nhất</a></li>
+ <li><a href="#BestMatch">Cách Android tìm Tài nguyên Khớp Tốt nhất</a></li>
+ </ol>
+
+ <h2>Xem thêm</h2>
+ <ol>
+ <li><a href="accessing-resources.html">Truy cập Tài nguyên</a></li>
+ <li><a href="available-resources.html">Loại Tài nguyên</a></li>
+ <li><a href="{@docRoot}guide/practices/screens_support.html">Hỗ trợ Nhiều
+Màn hình</a></li>
+ </ol>
+</div>
+</div>
+
+<p>Bạn nên luôn ngoại hiện hóa các tài nguyên ứng dụng chẳng hạn như hình ảnh và xâu từ mã
+của mình, sao cho bạn có thể duy trì chúng một cách độc lập. Bạn cũng nên cung cấp tài nguyên thay thế cho
+cấu hình thiết bị cụ thể bằng cách nhóm chúng lại trong những thư mục tài nguyên đích danh. Trong
+thời gian chạy, Android sẽ sử dụng tài nguyên phù hợp dựa trên cấu hình hiện tại. Ví
+dụ, bạn có thể muốn cung cấp một bố trí UI khác phụ thuộc vào kích cỡ màn hình hoặc các xâu
+khác nhau phụ thuộc vào thiết đặt ngôn ngữ.</p>
+
+<p>Sau khi ngoại hiện hóa các tài nguyên ứng dụng của mình, bạn có thể truy cập chúng
+bằng cách sử dụng các ID tài nguyên được khởi tạo trong lớp {@code R} của dự án của bạn. Cách sử dụng
+tài nguyên trong ứng dụng của bạn được trình bày trong phần <a href="accessing-resources.html">Truy cập
+Tài nguyên</a>. Tài liệu này trình bày với bạn cách nhóm các tài nguyên lại trong dự án Android của bạn và
+cung cấp tài nguyên thay thế cho những cấu hình thiết bị cụ thể.</p>
+
+
+<h2 id="ResourceTypes">Nhóm các Loại Tài nguyên lại</h2>
+
+<p>Bạn nên đặt từng loại tài nguyên vào một thư mục con cụ thể trong thư mục
+{@code res/} dự án của mình. Ví dụ, sau đây là phân cấp tệp của một dự án đơn giản:</p>
+
+<pre class="classic no-pretty-print">
+MyProject/
+ src/ <span style="color:black">
+ MyActivity.java </span>
+ res/
+ drawable/ <span style="color:black">
+ graphic.png </span>
+ layout/ <span style="color:black">
+ main.xml
+ info.xml</span>
+ mipmap/ <span style="color:black">
+ icon.png </span>
+ values/ <span style="color:black">
+ strings.xml </span>
+</pre>
+
+<p>Như bạn có thể thấy trong ví dụ này, thư mục {@code res/} chứa tất cả tài nguyên (trong
+các thư mục con): một tài nguyên hình ảnh, hai tài nguyên bố trí, các thư mục{@code mipmap/} cho biểu tượng của trình khởi chạy
+, và một tệp tài nguyên xâu. Tên thư mục
+tài nguyên có vai trò quan trọng và được mô tả trong bảng 1.</p>
+
+<p class="note"><strong>Lưu ý:</strong> Để biết thêm thông tin về cách sử dụng thư mục mipmap, hãy xem phần
+<a href="{@docRoot}tools/projects/index.html#mipmap">Tổng quan về Quản lý Dự án</a>.</p>
+
+<p class="table-caption" id="table1"><strong>Bảng 1.</strong> Các thư mục tài nguyên
+được hỗ trợ bên trong thư mục {@code res/} của dự án.</p>
+
+<table>
+ <tr>
+ <th scope="col">Thư mục</th>
+ <th scope="col">Loại Tài nguyên</th>
+ </tr>
+
+ <tr>
+ <td><code>animator/</code></td>
+ <td>Tệp XML định nghĩa <a href="{@docRoot}guide/topics/graphics/prop-animation.html">các hoạt hình
+tính chất</a>.</td>
+ </tr>
+
+ <tr>
+ <td><code>anim/</code></td>
+ <td>Tệp XML định nghĩa <a href="{@docRoot}guide/topics/graphics/view-animation.html#tween-animation">các hoạt hình
+tween</a>. (Các hoạt hình tính chất cũng có thể được lưu trong thư mục này, nhưng
+thư mục {@code animator/} được ưu tiên cho hoạt hình tính chất để phân biệt giữa hai
+loại này.)</td>
+ </tr>
+
+ <tr>
+ <td><code>color/</code></td>
+ <td>Tệp XML định nghĩa một danh sách trạng thái các màu. Xem phần <a href="color-list-resource.html">Tài nguyên
+Danh sách Trạng thái Màu</a></td>
+ </tr>
+
+ <tr>
+ <td><code>drawable/</code></td>
+
+ <td><p>Tệp bitmap ({@code .png}, {@code .9.png}, {@code .jpg}, {@code .gif}) hoặc tệp XML
+được biên dịch thành các loại tài nguyên con vẽ được sau:</p>
+ <ul>
+ <li>Tệp bitmap</li>
+ <li>Nine-Patche (tệp bitmap có thể thay đổi kích cỡ)</li>
+ <li>Danh sách trạng thái</li>
+ <li>Hình</li>
+ <li>Nội dung vẽ được hoạt hình</li>
+ <li>Nội dung vẽ được khác</li>
+ </ul>
+ <p>Xem phần <a href="drawable-resource.html">Tài nguyên Vẽ được</a>.</p>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>mipmap/</code></td>
+ <td>Tệp vẽ được cho các mật độ biểu tượng trình khởi chạy khác nhau. Để biết thêm thông tin về việc quản lý
+ các biểu tượng trình khởi chạy bằng thư mục {@code mipmap/}, xem phần
+ <a href="{@docRoot}tools/project/index.html#mipmap">Tổng quan về Quản lý Dự án</a>.</td>
+ </tr>
+
+ <tr>
+ <td><code>layout/</code></td>
+ <td>Tệp XML định nghĩa một bố trí giao diện người dùng.
+ Xem phần <a href="layout-resource.html">Tài nguyên Bố trí</a>.</td>
+ </tr>
+
+ <tr>
+ <td><code>menu/</code></td>
+ <td>Tệp XML định nghĩa các menu ứng dụng, chẳng hạn như Menu Tùy chọn, Menu Ngữ cảnh, hoặc Menu
+Con. Xem phần <a href="menu-resource.html">Tài nguyên Menu</a>.</td>
+ </tr>
+
+ <tr>
+ <td><code>raw/</code></td>
+ <td><p>Tệp tùy ý để lưu trong dạng thô của chúng. Để mở những tài nguyên có một
+{@link java.io.InputStream} thô này, hãy gọi {@link android.content.res.Resources#openRawResource(int)
+Resources.openRawResource()} bằng ID tài nguyên, chính là {@code R.raw.<em>filename</em>}.</p>
+ <p>Tuy nhiên, nếu cần truy cập tên tệp gốc và phân cấp tệp, bạn có thể xem xét
+lưu một số tài nguyên trong thư mục {@code
+assets/} (thay vì {@code res/raw/}). Các tệp trong {@code assets/} không được cấp
+ID tài nguyên, vì thế bạn chỉ có thể đọc chúng bằng cách sử dụng {@link android.content.res.AssetManager}.</p></td>
+ </tr>
+
+ <tr>
+ <td><code>values/</code></td>
+ <td><p>Tệp XML chứa các giá trị đơn giản, chẳng hạn như xâu, số nguyên, và màu sắc.</p>
+ <p>Trong đó, tệp tài nguyên XML trong các thư mục con {@code res/} khác định nghĩa một tài nguyên đơn lẻ
+dựa trên tên tệp XML, tệp trong thư mục {@code values/} sẽ mô tả nhiều nguồn.
+Đối với tệp trong thư mục này, mỗi phần tử con của phần tử {@code &lt;resources&gt;} lại định nghĩa một tài nguyên
+duy nhất. Ví dụ, phần tử {@code &lt;string&gt;} tạo tài nguyên
+{@code R.string} và phần tử {@code &lt;color&gt;} tạo tài nguyên {@code R.color}
+.</p>
+ <p>Vì mỗi tài nguyên được định nghĩa bằng phần tử XML của chính nó, bạn có thể đặt tên tệp
+theo cách mình muốn và đặt các loại tài nguyên khác nhau vào một tệp. Tuy nhiên, để giải thích rõ, bạn có thể
+muốn đặt các loại tài nguyên duy nhất vào những tệp khác nhau. Ví dụ, sau đây là một số quy ước
+tên tệp cho các tài nguyên mà bạn có thể tạo trong thư mục này:</p>
+ <ul>
+ <li>arrays.xml cho mảng tài nguyên (<a href="more-resources.html#TypedArray">mảng có phân loại</a>).</li>
+ <li>colors.xml cho <a href="more-resources.html#Color">giá trị màu</a></li>
+ <li>dimens.xml cho <a href="more-resources.html#Dimension">giá trị kích thước</a>.</li>
+ <li>strings.xml cho <a href="string-resource.html">giá trị
+xâu</a>.</li>
+ <li>styles.xml cho <a href="style-resource.html">kiểu</a>.</li>
+ </ul>
+ <p>Xem các phần <a href="string-resource.html">Tài nguyên Xâu</a>,
+ <a href="style-resource.html">Tài nguyên Kiểu</a>, và
+ <a href="more-resources.html">các Loại Tài nguyên khác</a>.</p>
+ </td>
+ </tr>
+
+ <tr>
+ <td><code>xml/</code></td>
+ <td>Tệp XML tùy ý mà có thể được đọc vào thời gian chạy bằng cách gọi {@link
+android.content.res.Resources#getXml(int) Resources.getXML()}. Các tệp cấu hình XML khác nhau
+phải được lưu ở đây, chẳng hạn như một <a href="{@docRoot}guide/topics/search/searchable-config.html">cấu hình có thể tìm kiếm</a>.
+<!-- or preferences configuration. --></td>
+ </tr>
+</table>
+
+<p class="caution"><strong>Chú ý:</strong> Không được lưu tệp tài nguyên trực tiếp vào trong thư mục
+{@code res/}&mdash;nó sẽ gây ra lỗi với trình biên dịch.</p>
+
+<p>Để biết thêm thông tin về các loại tài nguyên, hãy xem tài liệu <a href="available-resources.html">Các Loại Tài nguyên</a>.</p>
+
+<p>Tài nguyên mà bạn lưu trong thư mục con được định nghĩa trong bảng 1 là những tài nguyên "mặc định"
+của bạn. Cụ thể, những tài nguyên này định nghĩa thiết kế và nội dung mặc định cho ứng dụng của bạn.
+Tuy nhiên, các loại thiết bị dựa trên nền tảng Android khác nhau có thể gọi các loại tài nguyên khác nhau.
+Ví dụ, nếu một thiết bị có một màn hình lớn hơn bình thường, khi đó bạn nên cung cấp
+các tài nguyên bố trí khác nhau để tận dụng diện tích màn hình tăng thêm. Hoặc, nếu một thiết bị có
+thiết đặt ngôn ngữ khác, khi đó bạn nên cung cấp các tài nguyên xâu khác để biên dịch
+văn bản trong giao diện người dùng của mình. Để cung cấp những tài nguyên khác nhau này cho các cấu hình
+thiết bị khác nhau, bạn cần cung cấp tài nguyên thay thế bên cạnh những tài nguyên
+mặc định của mình.</p>
+
+
+<h2 id="AlternativeResources">Cung cấp Tài nguyên Thay thế</h2>
+
+
+<div class="figure" style="width:429px">
+<img src="{@docRoot}images/resources/resource_devices_diagram2.png" height="167" alt="" />
+<p class="img-caption">
+<strong>Hình 1.</strong> Hai thiết bị khác nhau, mỗi thiết bị sử dụng các tài nguyên bố trí khác nhau.</p>
+</div>
+
+<p>Hầu như mọi ứng dụng đều nên cung cấp các tài nguyên thay thế để hỗ trợ những cấu hình
+thiết bị cụ thể. Ví dụ, bạn nên bao gồm các tài nguyên vẽ được thay thế cho các mật độ
+màn hình khác nhau và tài nguyên xâu thay thế cho các ngôn ngữ khác nhau. Vào thời gian chạy, Android
+sẽ phát hiện cấu hình thiết bị hiện tại và tải các tài nguyên
+tương ứng cho ứng dụng của bạn.</p>
+
+<p>Để quy định các phương án thay thế theo cấu hình cụ thể cho một tập hợp tài nguyên:</p>
+<ol>
+ <li>Tạo một thư mục mới trong {@code res/} có tên theo dạng {@code
+<em>&lt;resources_name&gt;</em>-<em>&lt;config_qualifier&gt;</em>}.
+ <ul>
+ <li><em>{@code &lt;resources_name&gt;}</em> là tên thư mục của các tài nguyên mặc định tương ứng
+(được định nghĩa trong bảng 1).</li>
+ <li><em>{@code &lt;qualifier&gt;}</em> là tên quy định một cấu hình riêng
+mà những tài nguyên này sẽ được sử dụng cho nó (được định nghĩa trong bảng 2).</li>
+ </ul>
+ <p>Bạn có thể nối nhiều hơn một <em>{@code &lt;qualifier&gt;}</em>. Tách riêng từng cái
+bằng một nét gạch.</p>
+ <p class="caution"><strong>Chú ý:</strong> Khi nối nhiều hạn định, bạn phải
+đặt chúng theo cùng thứ tự liệt kê trong bảng 2. Nếu các hạn định được xếp thứ tự
+sai, tài nguyên sẽ bị bỏ qua.</p>
+ </li>
+ <li>Lưu các tài nguyên thay thế tương ứng vào thư mục mới này. Tệp tài nguyên phải được
+đặt tên đúng như các tệp tài nguyên mặc định.</li>
+</ol>
+
+<p>Ví dụ, sau đây là một số tài nguyên mặc định và thay thế:</p>
+
+<pre class="classic no-pretty-print">
+res/
+ drawable/ <span style="color:black">
+ icon.png
+ background.png </span>
+ drawable-hdpi/ <span style="color:black">
+ icon.png
+ background.png </span>
+</pre>
+
+<p>Hạn định {@code hdpi} cho biết rằng các tài nguyên trong thư mục đó áp dụng cho những thiết bị có
+màn hình mật độ cao. Hình ảnh trong từng thư mục vẽ được này được định cỡ cho một mật độ
+màn hình cụ thể, nhưng tên tệp thì
+giống hệt. Bằng cách này, ID tài nguyên mà bạn sử dụng để tham chiếu {@code icon.png} hoặc hình ảnh {@code
+background.png} luôn như nhau, nhưng Android sẽ chọn
+phiên bản của từng tài nguyên cho khớp tốt nhất với thiết bị hiện tại, bằng cách so sánh thông tin cấu hình thiết bị
+với các hạn định về tên thư mục tài nguyên.</p>
+
+<p>Android hỗ trợ một vài hạn định cấu hình và bạn có thể
+thêm nhiều hạn định vào một tên thư mục, bằng cách tách riêng từng hạn định bằng một nét gạch. Bảng 2
+liệt kê các hạn định cấu hình hợp lệ, theo thứ tự ưu tiên&mdash;nếu bạn sử dụng nhiều
+hạn định cho một thư mục tài nguyên, bạn phải thêm chúng vào tên thư mục theo thứ tự được liệt kê trong
+bảng.</p>
+
+
+<p class="table-caption" id="table2"><strong>Bảng 2.</strong> Tên của hạn định
+cấu hình.</p>
+<table>
+ <tr>
+ <th>Cấu hình</th>
+ <th>Giá trị Hạn định</th>
+ <th>Mô tả</th>
+ </tr>
+ <tr id="MccQualifier">
+ <td>MCC và MNC</td>
+ <td>Ví dụ:<br/>
+ <code>mcc310</code><br/>
+ <code><nobr>mcc310-mnc004</nobr></code><br/>
+ <code>mcc208-mnc00</code><br/>
+ v.v.
+ </td>
+ <td>
+ <p>Mã quốc gia di động (MCC), đằng sau có thể là mã mạng di động (MNC)
+ từ thẻ SIM trong thiết bị. Ví dụ, <code>mcc310</code> ở Hoa Kỳ đối với mọi nhà mạng,
+ <code>mcc310-mnc004</code> ở Hoa Kỳ đối với Verizon, và <code>mcc208-mnc00</code> ở Pháp đối với
+ Orange.</p>
+ <p>Nếu thiết bị sử dụng một kết nối vô tuyến (điện thoại GSM), các giá trị MCC và MNC sẽ lấy
+ từ thẻ SIM.</p>
+ <p>Bạn cũng có thể sử dụng chỉ MCC (ví dụ, để đưa các tài nguyên
+pháp lý theo quốc gia cụ thể vào ứng dụng của bạn). Nếu bạn cần quy định chỉ dựa trên ngôn ngữ, hãy sử dụng hạn định
+<em>ngôn ngữ và khu vực</em> để thay thế (được trình bày ở phần tiếp theo). Nếu bạn quyết định sử dụng hạn định MCC và
+MNC, bạn nên cẩn thận và kiểm tra xem nó có hoạt động như kỳ vọng không.</p>
+ <p>Ngoài ra, cũng xem các trường cấu hình {@link
+android.content.res.Configuration#mcc}, và {@link
+android.content.res.Configuration#mnc}, tương ứng cho biết mã quốc gia di động và
+mã mạng di động hiện tại.</p>
+ </td>
+ </tr>
+ <tr id="LocaleQualifier">
+ <td>Ngôn ngữ và khu vực</td>
+ <td>Ví dụ:<br/>
+ <code>en</code><br/>
+ <code>fr</code><br/>
+ <code>en-rUS</code><br/>
+ <code>fr-rFR</code><br/>
+ <code>fr-rCA</code><br/>
+ v.v.
+ </td>
+ <td><p>Ngôn ngữ được định nghĩa bằng một mã ngôn ngữ <a href="http://www.loc.gov/standards/iso639-2/php/code_list.php">ISO
+ 639-1</a> gồm hai chữ cái, có thể theo sau là một mã khu vực
+ <a href="http://www.iso.org/iso/en/prods-services/iso3166ma/02iso-3166-code-lists/list-en1.html">ISO
+ 3166-1-alpha-2</a> dài hai chữ cái (đằng trước là "{@code r}" chữ thường).
+ </p><p>
+ Các mã <em>không</em> phân biệt chữ hoa/thường; tiền tố {@code r} được sử dụng để
+ phân biệt phần khu vực.
+ Bạn không thể chỉ quy định một khu vực.</p>
+ <p>Điều này có thể thay đổi trong suốt vòng đời
+ứng dụng của bạn nếu người dùng thay đổi ngôn ngữ của mình trong cài đặt hệ thống. Xem phần <a href="runtime-changes.html">Xử lý Thay đổi Thời gian chạy</a> để biết thông tin về
+ảnh hưởng có thể có của thay đổi này tới ứng dụng của bạn trong thời gian chạy.</p>
+ <p>Xem phần <a href="localization.html">Bản địa hóa</a> để biết hướng dẫn đầy đủ về việc bản địa hóa
+ứng dụng của bạn cho các ngôn ngữ khác.</p>
+ <p>Xem thêm trường cấu hình {@link android.content.res.Configuration#locale}, trong đó
+cho biết địa phương hiện tại.</p>
+ </td>
+ </tr>
+ <tr id="LayoutDirectionQualifier">
+ <td>Chỉ hướng Bố trí</td>
+ <td><code>ldrtl</code><br/>
+ <code>ldltr</code><br/>
+ </td>
+ <td><p>Chỉ hướng bố trí của ứng dụng của bạn. {@code ldrtl} có nghĩa là "chỉ-hướng-bố-trí-phải-qua-trái".
+ {@code ldltr} có nghĩa là "chỉ-hướng-bố-trí-trái-qua-phải" và là giá trị không biểu thị mặc định.
+ </p>
+ <p>Điều này có thể áp dụng cho bất kỳ tài nguyên nào, chẳng hạn như bố trí, nội dung vẽ được hoặc giá trị.
+ </p>
+ <p>Ví dụ, nếu bạn muốn cung cấp một bố trí cụ thể cho ngôn ngữ Ả-rập và một
+ bố trí chung nào đó cho bất kỳ ngôn ngữ “phải-qua-trái" nào khác (như chữ Ba Tư hoặc Do Thái), vậy bạn sẽ phải:
+ </p>
+<pre class="classic no-pretty-print">
+res/
+ layout/ <span style="color:black">
+ main.xml </span>(Default layout)
+ layout-ar/ <span style="color:black">
+ main.xml </span>(Specific layout for Arabic)
+ layout-ldrtl/ <span style="color:black">
+ main.xml </span>(Any "right-to-left" language, except
+ for Arabic, because the "ar" language qualifier
+ has a higher precedence.)
+</pre>
+ <p class="note"><strong>Lưu ý:</strong> Để kích hoạt các tính năng bố trí phải-qua-trái
+ cho ứng dụng của mình, bạn phải đặt <a href="{@docRoot}guide/topics/manifest/application-element.html#supportsrtl">{@code
+ supportsRtl}</a> thành {@code "true"} và đặt <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code targetSdkVersion}</a> thành 17 trở lên.</p>
+ <p><em>Được thêm trong API mức 17.</em></p>
+ </td>
+ </tr>
+ <tr id="SmallestScreenWidthQualifier">
+ <td>smallestWidth</td>
+ <td><code>sw&lt;N&gt;dp</code><br/><br/>
+ Ví dụ:<br/>
+ <code>sw320dp</code><br/>
+ <code>sw600dp</code><br/>
+ <code>sw720dp</code><br/>
+ v.v.
+ </td>
+ <td>
+ <p>Kích cỡ cơ bản của một màn hình, thể hiện bằng kích thước ngắn nhất của khu vực màn hình
+khả dụng. Cụ thể, smallestWidth của thiết bị bằng khoảng ngắn nhất giữa chiều cao và chiều rộng
+khả dụng của màn hình (bạn cũng có thể gọi là "chiều rộng nhỏ nhất có thể" cho màn hình). Bạn có thể
+sử dụng hạn định này để đảm bảo rằng, không phụ thuộc vào hướng hiện tại của màn hình, ứng dụng
+của bạn có ít nhất {@code &lt;N&gt;} dp chiều rộng khả dụng cho UI của mình.</p>
+ <p>Ví dụ, nếu bố trí của bạn yêu cầu rằng kích thước nhỏ nhất của khu vực màn hình tối thiểu
+phải luôn bằng 600 dp, vậy bạn có thể sử dụng hạn định này để tạo các tài nguyên bố trí, {@code
+res/layout-sw600dp/}. Hệ thống sẽ chỉ sử dụng những tài nguyên này khi kích thước nhỏ nhất của
+màn hình khả dụng tối thiểu bằng 600dp, không phụ thuộc vào cạnh 600dp là chiều cao hay chiều rộng
+theo nhận thức của người dùng. SmallestWidth là đặc trưng kích cỡ màn hình cố định của thiết bị; <strong>smallestWidth của
+thiết bị không thay đổi khi hướng của màn hình thay đổi</strong>.</p>
+ <p>SmallestWidth của một thiết bị sẽ xem xét cả trang trí màn hình và UI hệ thống. Ví
+dụ, nếu thiết bị có một số phần tử UI cố định trên màn hình mà chiếm mất khoảng trống dọc
+theo trục smallestWidth, hệ thống sẽ khai báo smallestWidth nhỏ hơn kích cỡ màn hình
+thực tế, bởi chúng là những điểm ảnh màn hình không khả dụng cho UI của bạn. Vì thế, giá trị mà bạn sử dụng
+nên là kích thước nhỏ nhất thực tế <em>mà bố trí của bạn yêu cầu</em> (thông thường, giá trị này bằng
+"chiều rộng nhỏ nhất" mà bố trí của bạn hỗ trợ, không phụ thuộc vào hướng hiện tại của màn hình).</p>
+ <p>Một số giá trị mà bạn có thể sử dụng ở đây đối với các kích cỡ màn hình phổ biến:</p>
+ <ul>
+ <li>320, cho các thiết bị có cấu hình màn hình như:
+ <ul>
+ <li>240x320 ldpi (thiết bị cầm tay QVGA)</li>
+ <li>320x480 mdpi (thiết bị cầm tay)</li>
+ <li>480x800 hdpi (thiết bị cầm tay mật độ cao)</li>
+ </ul>
+ </li>
+ <li>480, đối với những màn hình như 480x800 mdpi (máy tính bảng/thiết bị cầm tay).</li>
+ <li>600, đối với những màn hình như 600x1024 mdpi (máy tính bảng 7").</li>
+ <li>720, đối với những màn hình như 720x1280 mdpi (máy tính bảng 10").</li>
+ </ul>
+ <p>Khi ứng dụng của bạn cung cấp nhiều thư mục tài nguyên với những giá trị khác nhau cho
+ hạn định smallestWidth, hệ thống sẽ sử dụng hạn định gần nhất với (không vượt quá)
+smallestWidth của thiết bị. </p>
+ <p><em>Được thêm trong API mức 13.</em></p>
+ <p>Xem thêm thuộc tính <a href="{@docRoot}guide/topics/manifest/supports-screens-element.html#requiresSmallest">{@code
+android:requiresSmallestWidthDp}</a>, trong đó khai báo smallestWidth tối thiểu mà ứng dụng của bạn
+tương thích với, và trường cấu hình {@link
+android.content.res.Configuration#smallestScreenWidthDp}, trong đó lưu trữ giá trị
+smallestWidth của thiết bị.</p>
+ <p>Để biết thêm thông tin về việc thiết kế cho các màn hình khác nhau và sử dụng hạn định
+này, hãy xem hướng dẫn dành cho nhà phát triển <a href="{@docRoot}guide/practices/screens_support.html">Hỗ trợ
+Nhiều Màn hình</a>.</p>
+ </td>
+ </tr>
+ <tr id="ScreenWidthQualifier">
+ <td>Chiều rộng khả dụng</td>
+ <td><code>w&lt;N&gt;dp</code><br/><br/>
+ Ví dụ:<br/>
+ <code>w720dp</code><br/>
+ <code>w1024dp</code><br/>
+ v.v.
+ </td>
+ <td>
+ <p>Quy định một chiều rộng màn hình khả dụng tối thiểu theo đơn vị {@code dp} mà tại đó, tài nguyên
+ nên được sử dụng&mdash;được định nghĩa bởi giá trị <code>&lt;N&gt;</code>. Giá trị
+ cấu hình này sẽ thay đổi khi hướng
+ thay đổi giữa khổ ngang và dọc để khớp với chiều rộng thực tế hiện tại.</p>
+ <p>Khi ứng dụng của bạn cung cấp nhiều thư mục tài nguyên với những giá trị khác nhau
+ cho cấu hình này, hệ thống sẽ sử dụng giá trị gần nhất với (không vượt quá)
+ chiều rộng hiện tại của màn hình. Giá trị
+ ở đây xét cả trang trí trên màn hình, vì thế nếu thiết bị có một số
+ phần tử UI cố định ở cạnh trái hoặc phải của màn hình, nó
+ sẽ sử dụng một giá trị cho chiều rộng nhỏ hơn kích cỡ màn hình thực sự, dùng
+ cho những phần tử UI này và làm giảm khoảng trống khả dụng của ứng dụng.</p>
+ <p><em>Được thêm trong API mức 13.</em></p>
+ <p>Xem thêm trường cấu hình {@link android.content.res.Configuration#screenWidthDp}
+ mà chứa chiều rộng màn hình hiện tại.</p>
+ <p>Để biết thêm thông tin về việc thiết kế cho các màn hình khác nhau và sử dụng hạn định
+này, hãy xem hướng dẫn dành cho nhà phát triển <a href="{@docRoot}guide/practices/screens_support.html">Hỗ trợ
+Nhiều Màn hình</a>.</p>
+ </td>
+ </tr>
+ <tr id="ScreenHeightQualifier">
+ <td>Chiều cao khả dụng</td>
+ <td><code>h&lt;N&gt;dp</code><br/><br/>
+ Ví dụ:<br/>
+ <code>h720dp</code><br/>
+ <code>h1024dp</code><br/>
+ v.v.
+ </td>
+ <td>
+ <p>Quy định chiều cao màn hình khả dụng tối thiểu theo đơn vị "dp" mà tại đó tài nguyên
+ nên được sử dụng&mdash;được định nghĩa bởi giá trị <code>&lt;N&gt;</code>. Giá trị
+ cấu hình này sẽ thay đổi khi hướng
+ thay đổi giữa khổ ngang và dọc để khớp với chiều cao thực tế hiện tại.</p>
+ <p>Khi ứng dụng của bạn cung cấp nhiều thư mục tài nguyên với những giá trị khác nhau
+ cho cấu hình này, hệ thống sẽ sử dụng giá trị gần nhất với (không vượt quá)
+ chiều cao hiện tại của màn hình. Giá trị
+ ở đây xét cả trang trí trên màn hình, vì thế nếu thiết bị có một số
+ phần tử UI cố định trên cạnh trên hoặc dưới của màn hình, nó sẽ sử dụng
+ một giá trị cho chiều cao nhỏ hơn kích cỡ màn hình thực sự, dùng
+ cho những phần tử UI này và làm giảm khoảng trống khả dụng của ứng dụng. Trang trí
+ trên màn hình mà không cố định (chẳng hạn như thanh trạng thái của điện thoại mà có thể được
+ ẩn khi ở toàn màn hình) <em>không</em> được xét ở đây, cả
+ những trang trí trên cửa sổ như thanh tiêu đề hay thanh hành động cũng vậy, vì thế ứng dụng phải được chuẩn bị để
+ xử lý một khoảng trống nhỏ hơn mức mà chúng quy định.
+ <p><em>Được thêm trong API mức 13.</em></p>
+ <p>Xem thêm trường cấu hình {@link android.content.res.Configuration#screenHeightDp}
+ mà chứa chiều rộng màn hình hiện tại.</p>
+ <p>Để biết thêm thông tin về việc thiết kế cho các màn hình khác nhau và sử dụng hạn định
+này, hãy xem hướng dẫn dành cho nhà phát triển <a href="{@docRoot}guide/practices/screens_support.html">Hỗ trợ
+Nhiều Màn hình</a>.</p>
+ </td>
+ </tr>
+ <tr id="ScreenSizeQualifier">
+ <td>Kích cỡ màn hình</td>
+ <td>
+ <code>small</code><br/>
+ <code>normal</code><br/>
+ <code>large</code><br/>
+ <code>xlarge</code>
+ </td>
+ <td>
+ <ul class="nolist">
+ <li>{@code small}: Các màn hình có kích cỡ tương tự như màn hình
+ QVGA mật độ thấp. Kích cỡ bố trí tối thiểu đối với một màn hình nhỏ
+ bằng xấp xỉ 320x426 đơn vị dp. Các ví dụ như QVGA mật độ thấp và VGA mật độ
+ cao.</li>
+ <li>{@code normal}: Các màn hình có kích cỡ tương tự như màn hình
+ HVGA mật độ trung bình. Kích cỡ bố trí tối thiểu
+ đối với một màn hình bình thường bằng xấp xỉ 320x470 đơn vị dp. Ví dụ
+ về những màn hình như vậy là WQVGA mật độ thấp, HVGA mật độ trung bình, WVGA
+ mật độ cao.</li>
+ <li>{@code large}: Các màn hình có kích cỡ tương tự như màn hình
+ VGA mật độ trung bình.
+ Kích cỡ bố trí tối thiểu đối với một màn hình lớn bằng xấp xỉ 480x640 đơn vị dp.
+ Ví dụ như các màn hình mật độ trung bình VGA và WVGA.</li>
+ <li>{@code xlarge}: Các màn hình lớn hơn đáng kể so với màn hình
+ HVGA mật độ trung bình truyền thống. Kích cỡ bố trí tối thiểu đối với một màn hình siêu lớn
+ bằng xấp xỉ 720x960 đơn vị dp. Trong hầu hết trường hợp, những thiết bị có màn hình
+ siêu lớn sẽ quá lớn để mang trong túi và gần như là
+ thiết bị kiểu máy tính bảng. <em>Được thêm trong API mức 9.</em></li>
+ </ul>
+ <p class="note"><strong>Lưu ý:</strong> Việc sử dụng một hạn định kích cỡ không hàm ý rằng các
+tài nguyên <em>chỉ</em> áp dụng cho màn hình có kích cỡ đó. Nếu bạn không cung cấp cho các tài nguyên
+thay thế với các hạn định khớp tốt hơn với cấu hình thiết bị hiện tại, hệ thống có thể sử dụng
+bất kỳ tài nguyên nào <a href="#BestMatch">phù hợp nhất</a>.</p>
+ <p class="caution"><strong>Chú ý:</strong> Nếu tất cả tài nguyên của bạn sử dụng một hạn định kích cỡ
+<em>lớn hơn</em> màn hình hiện tại, hệ thống sẽ <strong>không</strong> sử dụng chúng và
+ứng dụng của bạn sẽ bị lỗi vào thời gian chạy (ví dụ, nếu tất cả tài nguyên bố trí được gắn thẻ hạn định {@code
+xlarge} nhưng thiết bị lại có màn hình kích cỡ bình thường).</p>
+ <p><em>Được thêm trong API mức 4.</em></p>
+
+ <p>Xem <a href="{@docRoot}guide/practices/screens_support.html">Hỗ trợ Nhiều
+Màn hình</a> để biết thêm thông tin.</p>
+ <p>Xem thêm trường cấu hình {@link android.content.res.Configuration#screenLayout},
+ở đó cho biết màn hình là màn hình nhỏ, bình thường,
+hay lớn.</p>
+ </td>
+ </tr>
+ <tr id="ScreenAspectQualifier">
+ <td>Tỷ lệ màn hình</td>
+ <td>
+ <code>long</code><br/>
+ <code>notlong</code>
+ </td>
+ <td>
+ <ul class="nolist">
+ <li>{@code long}: Màn hình dài, chẳng hạn như WQVGA, WVGA, FWVGA</li>
+ <li>{@code notlong}: Màn hình không dài, chẳng hạn như QVGA, HVGA và VGA</li>
+ </ul>
+ <p><em>Được thêm trong API mức 4.</em></p>
+ <p>Giá trị này thuần túy được dựa trên tỷ lệ khung ảnh của màn hình (màn hình "dài" sẽ rộng hơn). Nó
+không liên quan tới hướng của màn hình.</p>
+ <p>Xem thêm trường cấu hình {@link android.content.res.Configuration#screenLayout},
+ở đó cho biết màn hình có dài không.</p>
+ </td>
+ </tr>
+ <tr id="OrientationQualifier">
+ <td>Hướng của màn hình</td>
+ <td>
+ <code>port</code><br/>
+ <code>land</code> <!-- <br/>
+ <code>square</code> -->
+ </td>
+ <td>
+ <ul class="nolist">
+ <li>{@code port}: Thiết bị ở hướng đứng (thẳng đứng)</li>
+ <li>{@code land}: Thiết bị ở khổ ngang (nằm ngang)</li>
+ <!-- Square mode is currently not used. -->
+ </ul>
+ <p>Giá trị này có thể thay đổi trong suốt vòng đời ứng dụng của bạn nếu người dùng xoay
+màn hình. Xem phần <a href="runtime-changes.html">Xử lý Thay đổi Thời gian chạy</a> để biết thông tin về
+ảnh hưởng của điều này tới ứng dụng của bạn trong thời gian chạy.</p>
+ <p>Xem thêm trường cấu hình {@link android.content.res.Configuration#orientation}, trong đó
+cho biết hướng thiết bị hiện tại.</p>
+ </td>
+ </tr>
+ <tr id="UiModeQualifier">
+ <td>Chế độ UI</td>
+ <td>
+ <code>car</code><br/>
+ <code>desk</code><br/>
+ <code>television</code><br/>
+ <code>appliance</code>
+ <code>watch</code>
+ </td>
+ <td>
+ <ul class="nolist">
+ <li>{@code car}: Thiết bị đang hiển thị trong đế gắn trên ô-tô</li>
+ <li>{@code desk}: Thiết bị đang hiển thị trong đế gắn trên bàn</li>
+ <li>{@code television}: Thiết bị đang hiển thị trên một TV, mang đến một
+ trải nghiệm "10 foot" (3 mét) trong đó UI của nó nằm trên một màn hình lớn
+ cách xa người dùng, được định hướng chủ yếu quanh DPAD hoặc cách
+ tương tác không sử dụng con trỏ khác</li>
+ <li>{@code appliance}: Thiết bị đang đóng vai trò như một dụng cụ không
+ có màn hình hiển thị</li>
+ <li>{@code watch}: Thiết bị có một màn hình hiển thị và được đeo trên cổ tay</li>
+ </ul>
+ <p><em>Được thêm trong API mức 8, TV được thêm trong API 13, đồng hồ được thêm trong API 20.</em></p>
+ <p>Để biết thông tin về cách ứng dụng của bạn hồi đáp khi thiết bị được cắm vào hoặc
+ rút khỏi đế, hãy đọc <a href="{@docRoot}training/monitoring-device-state/docking-monitoring.html">Xác định
+và Theo dõi Trạng thái và Loại Đế</a>.</p>
+ <p>Giá trị này có thể thay đổi trong suốt vòng đời ứng dụng của bạn nếu người dùng đặt
+thiết bị vào đế. Bạn có thể kích hoạt hoặc vô hiệu hóa một số chế độ này bằng cách sử dụng {@link
+android.app.UiModeManager}. Xem phần <a href="runtime-changes.html">Xử lý Thay đổi Thời gian chạy</a> để
+biết thông tin về ảnh hưởng của điều này tới ứng dụng của bạn trong thời gian chạy.</p>
+ </td>
+ </tr>
+ <tr id="NightQualifier">
+ <td>Chế độ ban đêm</td>
+ <td>
+ <code>night</code><br/>
+ <code>notnight</code>
+ </td>
+ <td>
+ <ul class="nolist">
+ <li>{@code night}: Thời gian ban đêm</li>
+ <li>{@code notnight}: Thời gian ban ngày</li>
+ </ul>
+ <p><em>Được thêm trong API mức 8.</em></p>
+ <p>Giá trị này có thể thay đổi trong suốt vòng đời ứng dụng của bạn nếu chế độ ban đêm được để ở
+chế độ tự động (mặc định), trong trường hợp đó chế độ sẽ thay đổi dựa vào thời gian trong ngày. Bạn có thể kích hoạt
+hoặc vô hiệu hóa chế độ này bằng cách sử dụng {@link android.app.UiModeManager}. Xem phần <a href="runtime-changes.html">Xử lý Thay đổi Thời gian chạy</a> để biết thông tin về ảnh hưởng của điều này tới
+ứng dụng của bạn trong thời gian chạy.</p>
+ </td>
+ </tr>
+ <tr id="DensityQualifier">
+ <td>Mật độ điểm ảnh màn hình (dpi)</td>
+ <td>
+ <code>ldpi</code><br/>
+ <code>mdpi</code><br/>
+ <code>hdpi</code><br/>
+ <code>xhdpi</code><br/>
+ <code>xxhdpi</code><br/>
+ <code>xxxhdpi</code><br/>
+ <code>nodpi</code><br/>
+ <code>tvdpi</code>
+ </td>
+ <td>
+ <ul class="nolist">
+ <li>{@code ldpi}: Màn hình mật độ thấp; xấp xỉ 120dpi.</li>
+ <li>{@code mdpi}: Màn hình mật độ trung bình (trên HVGA truyền thống); xấp xỉ
+160dpi.</li>
+ <li>{@code hdpi}: Màn hình mật độ cao; xấp xỉ 240dpi.</li>
+ <li>{@code xhdpi}: Màn hình mật độ siêu cao; xấp xỉ 320dpi. <em>Được thêm trong API
+Mức 8</em></li>
+ <li>{@code xxhdpi}: Màn hình mật độ siêu siêu cao; xấp xỉ 480dpi. <em>Được thêm trong API
+Mức 16</em></li>
+ <li>{@code xxxhdpi}: Mật độ siêu siêu siêu cao sử dụng (chỉ biểu tượng trình khởi chạy, xem
+ <a href="{@docRoot}guide/practices/screens_support.html#xxxhdpi-note">ghi chú</a>
+ trong <em>Hỗ trợ Nhiều Màn hình</em>); xấp xỉ 640dpi. <em>Được thêm trong API
+Mức 18</em></li>
+ <li>{@code nodpi}: Loại này có thể được sử dụng cho tài nguyên bitmap mà bạn không muốn được định cỡ
+cho khớp với mật độ của thiết bị.</li>
+ <li>{@code tvdpi}: Màn hình trong khoảng giữa mdpi và hdpi; xấp xỉ 213dpi. Đây
+không được coi là nhóm mật độ "cơ bản". Nó được dành chủ yếu cho TV và hầu hết
+các ứng dụng không cần nó&mdash;với điều kiện các tài nguyên mdpi và hpdi đủ cho hầu hết ứng dụng
+và hệ thống sẽ định cỡ chúng cho phù hợp. Hạn định này đã được giới thiệu với API mức 13.</li>
+ </ul>
+ <p>Có tỷ lệ định cỡ 3:4:6:8:12:16 giữa sáu mật độ cơ bản (bỏ qua mật độ
+tvdpi). Vì thế, một tệp bimap 9x9 trong ldpi sẽ bằng 12x12 trong mdpi, 18x18 trong hdpi, 24x24 trong xhdpi, v.v.
+</p>
+ <p>Nếu bạn quyết định rằng tài nguyên hình ảnh của mình không đủ đẹp trên TV hoặc
+một số thiết bị khác và muốn thử tài nguyên tvdpi, hệ số định cỡ sẽ bằng 1,33*mdpi. Ví
+dụ, một hình ảnh 100px x 100px đối với màn hình mdpi sẽ bằng 133px x 133px đối với tvdpi.</p>
+ <p class="note"><strong>Lưu ý:</strong> Việc sử dụng một hạn định mật độ không hàm ý rằng các
+tài nguyên <em>chỉ</em> áp dụng cho màn hình có mật độ đó. Nếu bạn không cung cấp cho các tài nguyên
+thay thế với các hạn định khớp tốt hơn với cấu hình thiết bị hiện tại, hệ thống có thể sử dụng
+bất kỳ tài nguyên nào <a href="#BestMatch">phù hợp nhất</a>.</p>
+ <p>Xem <a href="{@docRoot}guide/practices/screens_support.html">Hỗ trợ Nhiều
+Màn hình</a> để biết thêm thông tin về cách xử lý các mật độ màn hình khác nhau và cách Android
+có thể định cỡ bitmap của mình cho vừa với mật độ hiện tại.</p>
+ </td>
+ </tr>
+ <tr id="TouchscreenQualifier">
+ <td>Loại màn hình cảm ứng</td>
+ <td>
+ <code>notouch</code><br/>
+ <code>finger</code>
+ </td>
+ <td>
+ <ul class="nolist">
+ <li>{@code notouch}: Thiết bị không có màn hình cảm ứng.</li>
+ <li>{@code finger}: Thiết bị có màn hình cảm ứng để
+ được sử dụng thông qua tương tác hướng của ngón tay của người dùng.</li>
+ </ul>
+ <p>Xem thêm trường cấu hình {@link android.content.res.Configuration#touchscreen},
+nó cho biết loại màn hình cảm ứng trên thiết bị.</p>
+ </td>
+ </tr>
+ <tr id="KeyboardAvailQualifier">
+ <td>Sự sẵn có của bàn phím</td>
+ <td>
+ <code>keysexposed</code><br/>
+ <code>keyshidden</code><br/>
+ <code>keyssoft</code>
+ </td>
+ <td>
+ <ul class="nolist">
+ <li>{@code keysexposed}: Thiết bị có sẵn một bàn phím. Nếu thiết bị có một
+bàn phím mềm được kích hoạt (có khả năng), giá trị này có thể được sử dụng khi bàn phím cứng
+<em>không</em> hiển thị trước người dùng, ngay cả khi thiết bị không có bàn phím cứng. Nếu không có
+bàn phím mềm hoặc bàn phím mềm bị vô hiệu hóa, khi đó giá trị này chỉ được sử dụng khi một bàn phím cứng được
+hiển thị.</li>
+ <li>{@code keyshidden}: Thiết bị có sẵn một bàn phím cứng nhưng nó bị
+ẩn đi <em>và </em> thiết bị <em>không</em> có bàn phím mềm được kích hoạt.</li>
+ <li>{@code keyssoft}: Thiết bị có một bàn phím mềm được kích hoạt dù nó có
+hiển thị hay không.</li>
+ </ul>
+ <p>Nếu bạn cung cấp các tài nguyên <code>keysexposed</code>, nhưng không cung cấp tài nguyên <code>keyssoft</code>
+, hệ thống sẽ sử dụng tài nguyên <code>keysexposed</code> mà không phụ thuộc vào việc có hiển thị
+bàn phím hay không, miễn là hệ thống có kích hoạt một bàn phím mềm.</p>
+ <p>Giá trị này có thể thay đổi trong vòng đời ứng dụng của bạn nếu người dùng mở một bàn phím
+cứng. Xem phần <a href="runtime-changes.html">Xử lý Thay đổi Thời gian chạy</a> để biết thông tin về
+ảnh hưởng của điều này tới ứng dụng của bạn trong thời gian chạy.</p>
+ <p>Xem thêm các trường cấu hình {@link
+android.content.res.Configuration#hardKeyboardHidden} và {@link
+android.content.res.Configuration#keyboardHidden}, theo đó tương ứng cho biết mức độ hiển thị của bàn phím
+cứng và mức độ hiển thị của bất kỳ loại bàn phím nào (bao gồm bàn phím mềm).</p>
+ </td>
+ </tr>
+ <tr id="ImeQualifier">
+ <td>Phương pháp nhập liệu văn bản chính</td>
+ <td>
+ <code>nokeys</code><br/>
+ <code>qwerty</code><br/>
+ <code>12key</code>
+ </td>
+ <td>
+ <ul class="nolist">
+ <li>{@code nokeys}: Thiết bị không có phím cứng cho việc nhập liệu văn bản.</li>
+ <li>{@code qwerty}: Thiết bị có một bàn phím qwerty cứng, dù nó có hiển thị với
+người dùng
+hay không.</li>
+ <li>{@code 12key}: Thiết bị có một bàn phím 12-phím cứng, dù nó có hiển thị với
+người dùng hay không.</li>
+ </ul>
+ <p>Xem thêm trường cấu hình {@link android.content.res.Configuration#keyboard}, trong đó
+cho biết phương pháp nhập liệu văn bản chính sẵn có.</p>
+ </td>
+ </tr>
+ <tr id="NavAvailQualifier">
+ <td>Sự sẵn có của phím điều hướng</td>
+ <td>
+ <code>navexposed</code><br/>
+ <code>navhidden</code>
+ </td>
+ <td>
+ <ul class="nolist">
+ <li>{@code navexposed}: Có sẵn phím điều hướng cho người dùng.</li>
+ <li>{@code navhidden}: Không có sẵn phím điều hướng (chẳng hạn như phía sau một nắp
+đóng).</li>
+ </ul>
+ <p>Giá trị này có thể thay đổi trong suốt vòng đời ứng dụng của bạn nếu người dùng làm hiện
+phím điều hướng. Xem phần <a href="runtime-changes.html">Xử lý Thay đổi Thời gian chạy</a> để
+biết thông tin về ảnh hưởng của điều này tới ứng dụng của bạn trong thời gian chạy.</p>
+ <p>Xem thêm trường cấu hình {@link android.content.res.Configuration#navigationHidden},
+ở đó có cho biết các phím điều hướng có bị ẩn không.</p>
+ </td>
+ </tr>
+ <tr id="NavigationQualifier">
+ <td>Phương pháp điều hướng không cảm ứng chính</td>
+ <td>
+ <code>nonav</code><br/>
+ <code>dpad</code><br/>
+ <code>trackball</code><br/>
+ <code>wheel</code>
+ </td>
+ <td>
+ <ul class="nolist">
+ <li>{@code nonav}: Thiết bị không có phương tiện điều hướng ngoài cách sử dụng
+màn hình cảm ứng.</li>
+ <li>{@code dpad}: Thiết bị có bàn điều hướng (d-pad) để điều hướng.</li>
+ <li>{@code trackball}: Thiết bị có bi xoay để điều hướng.</li>
+ <li>{@code wheel}: Thiết bị có bánh xe điều hướng để điều hướng (không phổ biến).</li>
+ </ul>
+ <p>Xem thêm trường cấu hình {@link android.content.res.Configuration#navigation}, trong đó
+cho biết loại phương pháp điều hướng sẵn có.</p>
+ </td>
+ </tr>
+<!-- DEPRECATED
+ <tr>
+ <td>Screen dimensions</td>
+ <td>Examples:<br/>
+ <code>320x240</code><br/>
+ <code>640x480</code><br/>
+ etc.
+ </td>
+ <td>
+ <p>The larger dimension must be specified first. <strong>This configuration is deprecated
+and should not be used</strong>. Instead use "screen size," "wider/taller screens," and "screen
+orientation" described above.</p>
+ </td>
+ </tr>
+-->
+ <tr id="VersionQualifier">
+ <td>Phiên bản Nền tảng (Mức API)</td>
+ <td>Ví dụ:<br/>
+ <code>v3</code><br/>
+ <code>v4</code><br/>
+ <code>v7</code><br/>
+ v.v.</td>
+ <td>
+ <p>Mức API được hỗ trợ bởi thiết bị. Ví dụ, <code>v1</code> đối với API mức
+1 (thiết bị ở phiên bản Android 1.0 hoặc cao hơn) và <code>v4</code> đối với API mức 4 (thiết bị ở phiên bản Android
+1.6 hoặc cao hơn). Xem tài liệu <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#ApiLevels">Mức API của Android</a> để biết thêm thông tin
+về những giá trị này.</p>
+ </td>
+ </tr>
+</table>
+
+
+<p class="note"><strong>Lưu ý:</strong> Một số hạn định cấu hình đã được thêm kể từ phiên bản Android
+1.0, vì thế không phải tất cả phiên bản Android đều hỗ trợ tất cả hạn định. Việc sử dụng một hạn định mới sẽ hàm ý
+thêm hạn định phiên bản nền tảng sao cho các thiết bị cũ hơn chắc chắn sẽ bỏ qua nó. Ví dụ, sử dụng
+một hạn định <code>w600dp</code> sẽ tự động bao gồm hạn định <code>v13</code>, vì
+hạn định chiều rộng khả dụng mới có trong API mức 13. Để tránh bất kỳ sự cố nào, hãy luôn đưa vào một tập hợp
+các tài nguyên mặc định (tập hợp các tài nguyên <em>không có hạn định</em>). Để biết thêm thông tin, hãy xem phần
+nói về <a href="#Compatibility">Cung cấp Tính tương thích giữa Thiết bị với Tài nguyên
+Tốt nhất</a>.</p>
+
+
+
+<h3 id="QualifierRules">Quy tắc về tên hạn định</h3>
+
+<p>Sau đây là một số quy tắc về việc sử dụng tên của hạn định cấu hình:</p>
+
+<ul>
+ <li>Bạn có thể quy định nhiều hạn định cho một tập hợp đơn lẻ các tài nguyên, được tách riêng bởi dấu gạch ngang. Ví
+dụ, <code>drawable-en-rUS-land</code> sẽ áp dụng cho các thiết bị US-English ở hướng
+khổ ngang.</li>
+ <li>Các hạn định phải theo thứ tự liệt kê trong <a href="#table2">bảng 2</a>. Ví
+dụ:
+ <ul>
+ <li>Sai: <code>drawable-hdpi-port/</code></li>
+ <li>Đúng: <code>drawable-port-hdpi/</code></li>
+ </ul>
+ </li>
+ <li>Các thư mục tài nguyên thay thế không được lồng nhau. Ví dụ, bạn không được có
+<code>res/drawable/drawable-en/</code>.</li>
+ <li>Các giá trị không phân biệt chữ hoa/thường. Trình biên dịch tài nguyên sẽ chuyển tên thư mục
+ thành chữ thường trước khi xử lý để tránh các vấn đề xảy ra trên hệ thống tệp
+ không phân biệt chữ hoa/thường. Bất kỳ việc đổi sang chữ hoa nào trong tên chỉ nhằm mục đích dễ đọc hơn.</li>
+ <li>Chỉ hỗ trợ một giá trị cho mỗi loại hạn định. Ví dụ, nếu bạn muốn sử dụng
+cùng các tệp vẽ được cho tiếng Tây Ban Nha và tiếng Pháp, bạn <em>không thể</em> đặt tên thư mục là
+<code>drawable-rES-rFR/</code>. Thay vào đó, bạn cần hai thư mục tài nguyên chẳng hạn như
+<code>drawable-rES/</code> và <code>drawable-rFR/</code>, trong đó chứa các tệp phù hợp.
+Tuy nhiên, bạn không bắt buộc thực sự phải tạo bản sao các tệp như nhau ở cả hai vị trí. Thay vào đó, bạn có thể
+tạo một bí danh tới một tài nguyên. Xem phần <a href="#AliasResources">Tạo
+tài nguyên bí danh</a> ở bên dưới.</li>
+</ul>
+
+<p>Sau khi bạn lưu tài nguyên thay thế vào các thư mục được đặt tên bằng
+những hạn định này, Android sẽ tự động áp dụng các tài nguyên trong ứng dụng của bạn dựa trên
+cấu hình thiết bị hiện tại. Cứ mỗi lần yêu cầu một tài nguyên, Android lại kiểm tra các thư mục tài nguyên
+thay thế chứa tệp tài nguyên được yêu cầu, rồi <a href="#BestMatch">tìm tài nguyên
+so khớp phù hợp nhất</a> (được trình bày ở bên dưới). Nếu không có tài nguyên thay thế khớp
+với một cấu hình thiết bị cụ thể, khi đó Android sẽ sử dụng các tài nguyên mặc định tương ứng (
+tập hợp các tài nguyên cho một loại tài nguyên cụ thể không bao gồm hạn định
+cấu hình).</p>
+
+
+
+<h3 id="AliasResources">Tạo tài nguyên bí danh</h3>
+
+<p>Khi bạn có một tài nguyên muốn sử dụng cho nhiều hơn một cấu hình
+thiết bị (nhưng không muốn cung cấp làm tài nguyên mặc định), bạn không cần đặt
+cùng tài nguyên đó vào nhiều hơn một thư mục tài nguyên thay thế. Thay vào đó, bạn có thể (trong một số trường hợp) tạo một tài nguyên
+thay thế
+đóng vai trò như một bí danh cho tài nguyên được lưu trong thư mục tài nguyên mặc định của bạn.</p>
+
+<p class="note"><strong>Lưu ý:</strong> Không phải tất cả tài nguyên đều đưa ra cơ chế mà theo đó bạn có thể
+tạo một bí danh tới một tài nguyên khác. Cụ thể, hoạt hình, menu, tài nguyên thô và các tài nguyên
+không được quy định khác trong thư mục {@code xml/} không cung cấp tính năng này.</p>
+
+<p>Ví dụ, hãy tưởng tượng bạn có một biểu tượng ứng dụng, {@code icon.png}, và cần phiên bản duy nhất của
+nó cho các bản địa khác nhau. Tuy nhiên, hai bản địa English-Canadian và French-Canadian, cần
+sử dụng cùng phiên bản. Bạn có thể giả sử rằng mình cần sao chép cùng hình ảnh
+vào thư mục tài nguyên cho cả English-Canadian và French-Canadian, nhưng điều đó
+không đúng. Thay vào đó, bạn có thể lưu hình ảnh được sử dụng cho cả hai thành {@code icon_ca.png} (bất kỳ
+tên nào khác ngoài {@code icon.png}) và đặt
+nó vào thư mục {@code res/drawable/} mặc định. Sau đó, tạo một tệp {@code icon.xml} trong {@code
+res/drawable-en-rCA/} và {@code res/drawable-fr-rCA/} tham chiếu tới tài nguyên {@code icon_ca.png}
+bằng cách sử dụng phần tử {@code &lt;bitmap&gt;}. Điều này cho phép bạn lưu trữ chỉ một phiên bản của tệp
+PNG và hai tệp XML nhỏ trỏ tới nó. (Ví dụ về tệp XML được trình bày ở bên dưới.)</p>
+
+
+<h4>Nội dung vẽ được</h4>
+
+<p>Để tạo một bí danh cho một nội dung vẽ được đang tồn tại, hãy sử dụng phần tử {@code &lt;bitmap&gt;}.
+Ví dụ:</p>
+
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;bitmap xmlns:android="http://schemas.android.com/apk/res/android"
+ android:src="@drawable/icon_ca" />
+</pre>
+
+<p>Nếu bạn lưu tệp này thành {@code icon.xml} (trong một thư mục tài nguyên thay thế chẳng hạn như
+{@code res/drawable-en-rCA/}), nó sẽ được biên dịch vào một tài nguyên mà bạn
+có thể tham chiếu như là {@code R.drawable.icon}, nhưng thực tế lại là bí danh cho tài nguyên {@code
+R.drawable.icon_ca} (được lưu trong {@code res/drawable/}).</p>
+
+
+<h4>Bố trí</h4>
+
+<p>Để tạo một bí danh cho một bố trí hiện tại, hãy sử dụng phần tử {@code &lt;include&gt;}
+, được bọc trong một {@code &lt;merge&gt;}. Ví dụ:</p>
+
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;merge>
+ &lt;include layout="@layout/main_ltr"/>
+&lt;/merge>
+</pre>
+
+<p>Nếu bạn lưu tệp này thành {@code main.xml}, nó sẽ được biên dịch thành một tài nguyên mà bạn có thể tham chiếu
+như là {@code R.layout.main}, nhưng thực tế lại là một bí danh cho tài nguyên {@code R.layout.main_ltr}
+.</p>
+
+
+<h4>Xâu và các giá trị đơn giản khác</h4>
+
+<p>Để tạo một bí danh cho một xâu hiện có, chỉ cần sử dụng ID tài nguyên của xâu
+mong muốn làm giá trị cho xâu mới. Ví dụ:</p>
+
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;resources>
+ &lt;string name="hello">Hello&lt;/string>
+ &lt;string name="hi">@string/hello&lt;/string>
+&lt;/resources>
+</pre>
+
+<p>Tài nguyên {@code R.string.hi} lúc này là một bí danh cho {@code R.string.hello}.</p>
+
+<p> <a href="{@docRoot}guide/topics/resources/more-resources.html">Các giá trị đơn giản khác</a> cũng
+hoạt động tương tự. Ví dụ, màu sắc:</p>
+
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;resources>
+ &lt;color name="yellow">#f00&lt;/color>
+ &lt;color name="highlight">@color/red&lt;/color>
+&lt;/resources>
+</pre>
+
+
+
+
+<h2 id="Compatibility">Cung cấp Tính tương thích giữa Thiết bị với Tài nguyên Tốt nhất</h2>
+
+<p>Để ứng dụng của bạn hỗ trợ nhiều cấu hình thiết bị, một điều rất quan trọng đó là
+bạn luôn cung cấp các tài nguyên mặc định cho từng loại tài nguyên mà ứng dụng của bạn sử dụng.</p>
+
+<p>Ví dụ, nếu ứng dụng của bạn hỗ trợ vài ngôn ngữ, hãy luôn bao gồm một thư mục {@code
+values/} (trong đó, xâu của bạn được lưu) <em>mà không cần</em> một <a href="#LocaleQualifier">hạn định ngôn ngữ và khu vực</a>. Nếu thay vào đó bạn đặt tất cả tệp xâu của mình
+vào các thư mục có một hạn định ngôn ngữ và khu vực, khi đó ứng dụng của bạn sẽ bị lỗi khi chạy
+trên một thiết bị được đặt ở một ngôn ngữ mà các xâu của bạn không hỗ trợ. Nhưng miễn là bạn cung cấp các tài nguyên
+{@code values/} mặc định, khi đó ứng dụng của bạn sẽ chạy bình thường (ngay cả khi người dùng không
+hiểu ngôn ngữ đó&mdash;vậy còn tốt hơn là bị lỗi).</p>
+
+<p>Tương tự, nếu bạn cung cấp các tài nguyên bố trí khác nhau dựa trên hướng của màn hình, bạn nên
+chọn một hướng làm mặc định của mình. Ví dụ, thay vì cung cấp tài nguyên bố trí trong {@code
+layout-land/} cho khổ ngang và {@code layout-port/} cho khổ dọc, hãy để một cái làm mặc định, chẳng hạn như
+{@code layout/} đối với khổ ngang và {@code layout-port/} đối với khổ dọc.</p>
+
+<p>Việc cung cấp tài nguyên mặc định quan trọng không chỉ bởi ứng dụng của bạn có thể chạy trên một
+cấu hình mà bạn chưa nghĩ đến, mà còn bởi các phiên bản Android mới đôi khi thêm
+hạn định cấu hình mà những phiên bản cũ hơn không hỗ trợ. Nếu bạn sử dụng một hạn định tài nguyên mới,
+nhưng vẫn duy trì tính tương thích về mã với các phiên bản cũ hơn của Android thì khi một phiên bản cũ hơn của
+Android chạy trên ứng dụng của bạn, nó sẽ bị lỗi nếu bạn không cung cấp tài nguyên mặc định, do nó
+không thể sử dụng tài nguyên được đặt tên bằng hạn định mới. Ví dụ, nếu <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code
+minSdkVersion}</a> của bạn được đặt bằng 4, và bạn xác định tất cả tài nguyên vẽ được của mình bằng cách sử dụng <a href="#NightQualifier">chế độ ban đêm</a> ({@code night} hoặc {@code notnight}, đã được thêm trong API
+Mức 8), khi đó một thiết bị API mức 4 sẽ không thể truy cập tài nguyên vẽ được của bạn và sẽ bị lỗi. Trong trường hợp
+này, bạn có thể muốn {@code notnight} làm tài nguyên mặc định của mình, vì thế bạn nên loại trừ hạn định
+đó sao cho tài nguyên vẽ được của bạn ở trong {@code drawable/} hoặc {@code drawable-night/}.</p>
+
+<p>Vì vậy, để mang lại khả năng tương thích với thiết bị tốt nhất, hãy luôn cung cấp tài nguyên
+mặc định cho những tài nguyên mà ứng dụng của bạn cần thực hiện đúng cách. Sau đó, hãy tạo tài nguyên
+thay thế cho các cấu hình thiết bị cụ thể bằng cách sử dụng hạn định cấu hình.</p>
+
+<p>Có một ngoại lệ đối với quy tắc này: Nếu <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code minSdkVersion}</a> của ứng dụng của bạn bằng 4 hoặc
+lớn hơn, bạn <em>không</em> cần đến tài nguyên vẽ được mặc định khi cung cấp tài nguyên
+vẽ được thay thế bằng hạn định <a href="#DensityQualifier">mật độ màn hình</a>. Kể cả khi không có
+tài nguyên vẽ được mặc định, Android cũng có thể tìm thấy kết quả khớp tốt nhất trong số các mật độ màn hình thay thế và sẽ định cỡ
+bitmap nếu cần. Tuy nhiên, để có trải nghiệm tốt nhất trên tất cả thiết bị, bạn nên
+cung cấp nội dung vẽ được thay thế cho cả ba loại mật độ.</p>
+
+
+
+<h2 id="BestMatch">Cách Android tìm Tài nguyên Khớp Tốt nhất</h2>
+
+<p>Khi bạn yêu cầu một tài nguyên mà bạn cung cấp nội dung thay thế cho nó, Android sẽ lựa chọn
+tài nguyên thay thế để sử dụng vào thời gian chạy, tùy vào cấu hình thiết bị hiện tại. Để
+diễn tả cách Android lựa chọn một tài nguyên thay thế, giả sử có các thư mục vẽ được sau,
+mỗi thư mục lại chứa các phiên bản khác nhau của cùng hình ảnh:</p>
+
+<pre class="classic no-pretty-print">
+drawable/
+drawable-en/
+drawable-fr-rCA/
+drawable-en-port/
+drawable-en-notouch-12key/
+drawable-port-ldpi/
+drawable-port-notouch-12key/
+</pre>
+
+<p>Và giả sử cấu hình thiết bị như sau:</p>
+
+<p style="margin-left:1em;">
+Bản địa = <code>en-GB</code> <br/>
+Hướng màn hình = <code>port</code> <br/>
+Mật độ điểm ảnh màn hình = <code>hdpi</code> <br/>
+Loại màn hình cảm ứng = <code>notouch</code> <br/>
+Phương pháp nhập liệu văn bản chính = <code>12key</code>
+</p>
+
+<p>Bằng cách so sánh cấu hình thiết bị với các tài nguyên thay thế sẵn có, Android sẽ lựa chọn
+nội dung vẽ được từ {@code drawable-en-port}.</p>
+
+<p>Hệ thống ra quyết định của mình về các tài nguyên nào sẽ sử dụng bằng lô-gic
+sau:</p>
+
+
+<div class="figure" style="width:371px">
+<img src="{@docRoot}images/resources/res-selection-flowchart.png" alt="" height="471" />
+<p class="img-caption"><strong>Hình 2.</strong> Lưu đồ về cách Android tìm tài nguyên
+khớp tốt nhất.</p>
+</div>
+
+
+<ol>
+ <li>Loại bỏ các tệp tài nguyên mà trái với cấu hình thiết bị.
+ <p>Thư mục <code>drawable-fr-rCA/</code> bị loại bỏ vì nó
+trái với bản địa <code>en-GB</code>.</p>
+<pre class="classic no-pretty-print">
+drawable/
+drawable-en/
+<strike>drawable-fr-rCA/</strike>
+drawable-en-port/
+drawable-en-notouch-12key/
+drawable-port-ldpi/
+drawable-port-notouch-12key/
+</pre>
+<p class="note"><strong>Ngoại lệ:</strong> Mật độ điểm ảnh màn hình là một hạn định không
+bị loại bỏ do trái ngược. Mặc dù mật độ màn hình của thiết bị là hdpi,
+<code>drawable-port-ldpi/</code> không bị loại bỏ vì mọi mật độ màn hình đều
+được coi là một kết quả khớp tại thời điểm này. Bạn có thể tham khảo thêm thông tin trong tài liệu <a href="{@docRoot}guide/practices/screens_support.html">Hỗ trợ Nhiều
+Màn hình</a>.</p></li>
+
+ <li>Chọn hạn định có mức ưu tiên cao nhất (tiếp theo) trong danh sách (<a href="#table2">bảng 2</a>).
+(Bắt đầu bằng MCC, sau đó di chuyển xuống.) </li>
+ <li>Có thư mục tài nguyên nào bao gồm hạn định này không? </li>
+ <ul>
+ <li>Nếu Không, hãy quay lại bước 2 và tìm với hạn định tiếp theo. (Trong ví dụ,
+ câu trả lời là "không" tới khi đi đến hạn định ngôn ngữ.)</li>
+ <li>Nếu Có, tiếp tục sang bước 4.</li>
+ </ul>
+ </li>
+
+ <li>Loại bỏ các thư mục tài nguyên không bao gồm hạn định này. Trong ví dụ, hệ thống
+sẽ loại bỏ tất cả thư mục không bao gồm hạn định ngôn ngữ:</li>
+<pre class="classic no-pretty-print">
+<strike>drawable/</strike>
+drawable-en/
+drawable-en-port/
+drawable-en-notouch-12key/
+<strike>drawable-port-ldpi/</strike>
+<strike>drawable-port-notouch-12key/</strike>
+</pre>
+<p class="note"><strong>Ngoại lệ:</strong> Nếu hạn định đang xét là mật độ điểm ảnh màn hình,
+Android sẽ chọn tùy chọn khớp gần nhất với mật độ màn hình của thiết bị.
+Nhìn chung, Android ưu tiên giảm kích cỡ một hình ảnh ban đầu lớn hơn thay vì tăng kích cỡ một hình ảnh ban đầu
+nhỏ hơn. Xem phần <a href="{@docRoot}guide/practices/screens_support.html">Hỗ trợ Nhiều
+Màn hình</a>.</p>
+ </li>
+
+ <li>Quay lại và lặp lại các bước 2, 3 và 4 tới khi chỉ còn lại một thư mục. Trong ví dụ, hướng
+màn hình là hạn định tiếp theo nếu có kết quả khớp.
+Vì thế, các tài nguyên không quy định hướng màn hình sẽ bị loại bỏ:
+<pre class="classic no-pretty-print">
+<strike>drawable-en/</strike>
+drawable-en-port/
+<strike>drawable-en-notouch-12key/</strike>
+</pre>
+<p>Thư mục còn lại là {@code drawable-en-port}.</p>
+ </li>
+</ol>
+
+<p>Mặc dù quy trình này được thực thi cho từng tài nguyên được yêu cầu, hệ thống sẽ tối ưu hóa hơn nữa
+một số khía cạnh. Một cách tối ưu hóa như vậy đó là sau khi biết cấu hình thiết bị, nó có thể
+loại bỏ các tài nguyên thay thế mà không thể khớp được. Ví dụ, nếu ngôn ngữ cấu hình
+là English ("en"), khi đó bất kỳ thư mục tài nguyên nào có hạn định ngôn ngữ được đặt thành
+ngôn ngữ khác English đều sẽ không được bao gồm trong tập hợp các tài nguyên được kiểm tra (mặc dù
+thư mục tài nguyên <em>không có</em> hạn định ngôn ngữ vẫn được bao gồm).</p>
+
+<p>Khi lựa chọn tài nguyên dựa trên hạn định kích cỡ màn hình, hệ thống sẽ sử dụng các tài nguyên
+được thiết kế cho màn hình nhỏ hơn màn hình hiện tại nếu không có tài nguyên nào khớp tốt hơn
+(ví dụ, một màn hình kích cỡ lớn sẽ sử dụng các tài nguyên màn hình kích cỡ bình thường nếu cần). Tuy nhiên, nếu
+những tài nguyên duy nhất sẵn có lại <em>lớn hơn</em> màn hình hiện tại, hệ thống sẽ
+<strong>không</strong> sử dụng chúng và ứng dụng của bạn sẽ bị lỗi nếu không có tài nguyên nào khác khớp với cấu hình
+thiết bị (ví dụ, nếu tất cả tài nguyên bố trí đều được gắn thẻ bằng hạn định {@code xlarge},
+nhưng thiết bị lại có một màn hình kích cỡ bình thường).</p>
+
+<p class="note"><strong>Lưu ý:</strong> <em>Mức ưu tiên</em> của hạn định (trong <a href="#table2">bảng 2</a>) quan trọng
+hơn số lượng hạn định khớp chính xác với thiết bị. Ví dụ, trong bước 4 bên trên
+lựa chọn trên danh sách bao gồm ba hạn định khớp chính xác với thiết bị (hướng, loại
+màn hình cảm ứng, và phương pháp nhập liệu), trong khi <code>drawable-en</code> chỉ có một tham số khớp
+(ngôn ngữ). Tuy nhiên, ngôn ngữ có mức ưu tiên cao hơn cả ba hạn định khác này, vì thế
+<code>drawable-port-notouch-12key</code> bị loại.</p>
+
+<p>Để tìm hiểu thêm về cách sử dụng tài nguyên trong ứng dụng của bạn, hãy tiếp tục sang phần <a href="accessing-resources.html">Truy cập Tài nguyên</a>.</p>
diff --git a/docs/html-intl/intl/vi/guide/topics/resources/runtime-changes.jd b/docs/html-intl/intl/vi/guide/topics/resources/runtime-changes.jd
new file mode 100644
index 000000000000..4a9c38ccfe60
--- /dev/null
+++ b/docs/html-intl/intl/vi/guide/topics/resources/runtime-changes.jd
@@ -0,0 +1,281 @@
+page.title=Xử lý Thay đổi Thời gian chạy
+page.tags=hoạt động,vòng đời
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+
+ <h2>Trong tài liệu này</h2>
+ <ol>
+ <li><a href="#RetainingAnObject">Giữ lại một Đối tượng trong khi Thay đổi Cấu hình</a></li>
+ <li><a href="#HandlingTheChange">Tự mình Xử lý Thay đổi Cấu hình</a>
+ </ol>
+
+ <h2>Xem thêm</h2>
+ <ol>
+ <li><a href="providing-resources.html">Cung cấp Tài nguyên</a></li>
+ <li><a href="accessing-resources.html">Truy cập Tài nguyên</a></li>
+ <li><a href="http://android-developers.blogspot.com/2009/02/faster-screen-orientation-change.html">Thay đổi
+ Hướng Màn hình Nhanh hơn</a></li>
+ </ol>
+</div>
+</div>
+
+<p>Một số cấu hình thiết bị có thể thay đổi trong thời gian chạy
+(chẳng hạn như hướng màn hình, sự sẵn có của bàn phím, và ngôn ngữ). Khi sự thay đổi như vậy diễn ra,
+Android sẽ khởi động lại việc chạy
+{@link android.app.Activity} ({@link android.app.Activity#onDestroy()} sẽ được gọi, sau đó là {@link
+android.app.Activity#onCreate(Bundle) onCreate()}). Hành vi khởi động lại được thiết kế để giúp
+ứng dụng điều chỉnh phù hợp với cấu hình mới bằng cách tự động tải lại ứng dụng của bạn bằng
+các tài nguyên thay thế khớp với cấu hình thiết bị mới.</p>
+
+<p>Để xử lý khởi động lại cho đúng, điều quan trọng là hoạt động của bạn khôi phục lại trạng thái trước đó
+của nó thông qua vòng đời <a href="{@docRoot}guide/components/activities.html#Lifecycle">Hoạt động
+thông thường</a>, trong đó Android sẽ gọi
+{@link android.app.Activity#onSaveInstanceState(Bundle) onSaveInstanceState()} trước khi nó hủy
+hoạt động của bạn sao cho bạn có thể lưu dữ liệu về trạng thái của ứng dụng. Khi đó, bạn có thể khôi phục trạng thái
+trong khi {@link android.app.Activity#onCreate(Bundle) onCreate()} hoặc {@link
+android.app.Activity#onRestoreInstanceState(Bundle) onRestoreInstanceState()}.</p>
+
+<p>Để kiểm tra xem ứng dụng của bạn có tự khởi động lại mà giữ nguyên trạng thái ứng dụng hay không,
+bạn cần gọi ra các thay đổi cấu hình (chẳng hạn như thay đổi hướng màn hình) trong khi thực hiện các
+tác vụ khác nhau trong ứng dụng của bạn. Ứng dụng của bạn sẽ có thể khởi động lại vào bất cứ lúc nào mà không bị mất
+dữ liệu của người dùng hay trạng thái để xử lý các sự kiện như thay đổi cấu hình hoặc khi người dùng nhận được
+một cuộc gọi đến rồi quay lại ứng dụng của bạn muộn hơn nhiều sau khi tiến trình
+ứng dụng của bạn có thể đã bị hủy. Để tìm hiểu về cách bạn có thể khôi phục trạng thái hoạt động của mình, hãy đọc về <a href="{@docRoot}guide/components/activities.html#Lifecycle">Vòng đời của hoạt động</a>.</p>
+
+<p>Tuy nhiên, bạn có thể gặp phải một tình huống trong đó việc khởi động lại ứng dụng của bạn và
+khôi phục phần lớn dữ liệu có thể tốn kém và tạo nên trải nghiệm người dùng kém. Trong
+tình huống như vậy, bạn có hai tùy chọn:</p>
+
+<ol type="a">
+ <li><a href="#RetainingAnObject">Giữ lại một đối tượng trong khi thay đổi cấu hình</a>
+ <p>Cho phép hoạt động của bạn khởi động lại khi cấu hình thay đổi, nhưng mang theo một
+đối tượng có trạng thái tới thực thể mới của hoạt động của bạn.</p>
+
+ </li>
+ <li><a href="#HandlingTheChange">Tự mình xử lý thay đổi cấu hình</a>
+ <p>Ngăn không cho hệ thống khởi động lại hoạt động của bạn trong những thay đổi
+cấu hình nhất định, nhưng nhận một lệnh gọi lại khi cấu hình thay đổi, sao cho bạn có thể cập nhật thủ công
+hoạt động của mình nếu cần.</p>
+ </li>
+</ol>
+
+
+<h2 id="RetainingAnObject">Giữ lại một Đối tượng trong khi Thay đổi Cấu hình</h2>
+
+<p>Nếu việc khởi động lại hoạt động của bạn yêu cầu bạn phải khôi phục nhiều tập hợp dữ liệu lớn, hãy thiết lập lại kết nối
+mạng, hoặc thực hiện các thao tác tăng cường khác, khi đó khởi động lại hoàn toàn do thay đổi cấu hình
+có thể gây ra trải nghiệm người dùng chậm chạp. Đồng thời, có thể bạn sẽ không thể hoàn toàn khôi phục được
+trạng thái hoạt động của mình với {@link android.os.Bundle} mà hệ thống lưu cho bạn bằng phương pháp gọi lại {@link
+android.app.Activity#onSaveInstanceState(Bundle) onSaveInstanceState()}&mdash;nó không
+được thiết kế để mang các đối tượng lớn (chẳng hạn như bitmap) và dữ liệu trong nó phải được nối tiếp hóa rồi
+bỏ nối tiếp hóa, điều này có thể tiêu tốn nhiều bộ nhớ và khiến việc thay đổi cấu hình diễn ra chậm. Trong một
+tình huống như vậy, bạn có thể gỡ bỏ gánh nặng khởi tạo lại hoạt động của mình bằng cách giữ lại {@link
+android.app.Fragment} khi hoạt động của bạn được khởi động lại do thay đổi cấu hình. Phân đoạn này
+có thể chứa các tham chiếu tới đối tượng có trạng thái mà bạn muốn giữ lại.</p>
+
+<p>Khi hệ thống Android tắt hoạt động của bạn do một thay đổi cấu hình, các phân đoạn
+của hoạt động mà bạn đã đánh dấu để giữ lại sẽ không bị hủy. Bạn có thể thêm các phân đoạn này vào
+hoạt động của mình để giữ lại các đối tượng có trạng thái.</p>
+
+<p>Để giữ lại các đối tượng có trạng thái trong một phân đoạn trong khi thay đổi cấu hình thời gian chạy:</p>
+
+<ol>
+ <li>Mở rộng lớp {@link android.app.Fragment} và khai báo các tham chiếu tới đối tượng
+ có trạng thái của bạn.</li>
+ <li>Gọi {@link android.app.Fragment#setRetainInstance(boolean)} khi phân đoạn được tạo.
+ </li>
+ <li>Thêm phân đoạn vào hoạt động của bạn.</li>
+ <li>Sử dụng {@link android.app.FragmentManager} để truy xuất phân đoạn khi hoạt động
+ được khởi động lại.</li>
+</ol>
+
+<p>Ví dụ, định nghĩa phân đoạn của bạn như sau:</p>
+
+<pre>
+public class RetainedFragment extends Fragment {
+
+ // data object we want to retain
+ private MyDataObject data;
+
+ // this method is only called once for this fragment
+ &#64;Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ // retain this fragment
+ setRetainInstance(true);
+ }
+
+ public void setData(MyDataObject data) {
+ this.data = data;
+ }
+
+ public MyDataObject getData() {
+ return data;
+ }
+}
+</pre>
+
+<p class="caution"><strong>Chú ý:</strong> Trong khi bạn có thể lưu trữ bất kỳ đối tượng nào, bạn
+không nên chuyển một đối tượng được gắn với {@link android.app.Activity}, chẳng hạn như {@link
+android.graphics.drawable.Drawable}, {@link android.widget.Adapter}, {@link android.view.View}
+hay bất kỳ đối tượng nào khác đi kèm với một {@link android.content.Context}. Nếu bạn làm vậy, nó sẽ
+rò rỉ tất cả dạng xem và tài nguyên của thực thể hoạt động gốc. (Rò rỉ tài nguyên
+có nghĩa là ứng dụng của bạn duy trì việc lưu giữ tài nguyên và chúng không thể được thu dọn bộ nhớ rác, vì thế
+rất nhiều bộ nhớ có thể bị mất.)</p>
+
+<p>Khi đó, hãy sử dụng {@link android.app.FragmentManager} để thêm phân đoạn vào hoạt động.
+Bạn có thể thu được đối tượng dữ liệu từ phân đoạn khi hoạt động bắt đầu lại trong khi
+thay đổi cấu hình thời gian chạy. Ví dụ, định nghĩa hoạt động của bạn như sau:</p>
+
+<pre>
+public class MyActivity extends Activity {
+
+ private RetainedFragment dataFragment;
+
+ &#64;Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main);
+
+ // find the retained fragment on activity restarts
+ FragmentManager fm = getFragmentManager();
+ dataFragment = (DataFragment) fm.findFragmentByTag(“data”);
+
+ // create the fragment and data the first time
+ if (dataFragment == null) {
+ // add the fragment
+ dataFragment = new DataFragment();
+ fm.beginTransaction().add(dataFragment, “data”).commit();
+ // load the data from the web
+ dataFragment.setData(loadMyData());
+ }
+
+ // the data is available in dataFragment.getData()
+ ...
+ }
+
+ &#64;Override
+ public void onDestroy() {
+ super.onDestroy();
+ // store the data in the fragment
+ dataFragment.setData(collectMyLoadedData());
+ }
+}
+</pre>
+
+<p>Trong ví dụ này, {@link android.app.Activity#onCreate(Bundle) onCreate()} thêm một phân đoạn
+hoặc khôi phục một tham chiếu đến nó. {@link android.app.Activity#onCreate(Bundle) onCreate()} cũng
+lưu trữ đối tượng có trạng thái bên trong thực thể phân đoạn đó.
+{@link android.app.Activity#onDestroy() onDestroy()} cập nhật đối tượng có trạng thái bên trong
+thực thể phân đoạn được giữ lại.</p>
+
+
+
+
+
+<h2 id="HandlingTheChange">Tự mình Xử lý Thay đổi Cấu hình</h2>
+
+<p>Nếu ứng dụng của bạn không cần cập nhật các tài nguyên trong một thay đổi
+cấu hình cụ thể <em>và</em> bạn có giới hạn về hiệu năng yêu cầu bạn phải
+tránh khởi động lại hoạt động, khi đó bạn có thể khai báo rằng hoạt động của bạn tự mình xử lý thay đổi cấu hình
+, làm vậy sẽ tránh cho hệ thống khởi động lại hoạt động của bạn.</p>
+
+<p class="note"><strong>Lưu ý:</strong> Việc tự mình xử lý thay đổi cấu hình có thể khiến việc
+sử dụng các tài nguyên thay thế khó khăn hơn nhiều, vì hệ thống không tự động áp dụng chúng
+cho bạn. Kỹ thuật này nên được coi là giải pháp cuối cùng khi bạn phải tránh khởi động lại do một
+thay đổi cấu hình và không được khuyến cáo đối với hầu hết ứng dụng.</p>
+
+<p>Để khai báo rằng hoạt động của bạn xử lý một thay đổi cấu hình, hãy chỉnh sửa phần tử <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code &lt;activity&gt;}</a> phù hợp trong
+tệp bản kê khai của bạn để bao gồm thuộc tính <a href="{@docRoot}guide/topics/manifest/activity-element.html#config">{@code
+android:configChanges}</a> với một giá trị có chức năng biểu diễn cấu hình mà bạn muốn
+xử lý. Các giá trị có thể được liệt kê trong tài liệu dành cho thuộc tính <a href="{@docRoot}guide/topics/manifest/activity-element.html#config">{@code
+android:configChanges}</a> (các giá trị thường được sử dụng nhất là {@code "orientation"} để
+ngăn khởi động lại khi hướng màn hình thay đổi và {@code "keyboardHidden"} để ngăn
+khởi động lại khi tính sẵn có của bàn phím thay đổi). Bạn có thể khai báo nhiều giá trị cấu hình trong
+thuộc tính bằng cách tách chúng bằng một ký tự {@code |} đường dẫn nối.</p>
+
+<p>Ví dụ, đoạn mã bản kê khai sau khai báo một hoạt động có chức năng xử lý cả
+thay đổi về hướng màn hình và thay đổi về tính sẵn có của bàn phím:</p>
+
+<pre>
+&lt;activity android:name=".MyActivity"
+ android:configChanges="orientation|keyboardHidden"
+ android:label="@string/app_name">
+</pre>
+
+<p>Lúc này, khi một trong những cấu hình này thay đổi, {@code MyActivity} không khởi động lại.
+Thay vào đó, {@code MyActivity} nhận được một lệnh gọi tới {@link
+android.app.Activity#onConfigurationChanged(Configuration) onConfigurationChanged()}. Phương pháp này
+được chuyển bởi một đối tượng {@link android.content.res.Configuration} mà quy định
+cấu hình thiết bị mới. Bằng cách đọc các trường trong {@link android.content.res.Configuration},
+bạn có thể xác định cấu hình mới và thực hiện những thay đổi phù hợp bằng cách cập nhật
+tài nguyên được sử dụng trong giao diện của bạn. Tại
+thời điểm phương pháp này được gọi, đối tượng {@link android.content.res.Resources} của hoạt động của bạn được cập nhật
+để trả về các tài nguyên dựa trên cấu hình mới, sao cho bạn có thể dễ dàng
+đặt lại các phần tử trong UI của mình mà không để hệ thống khởi động lại hoạt động của bạn.</p>
+
+<p class="caution"><strong>Chú ý:</strong> Bắt đầu với Android 3.2 (API mức 13), <strong>
+"kích cỡ màn hình" cũng thay đổi</strong> khi thiết bị chuyển giữa hướng dọc và khổ ngang
+. Vì thế, nếu bạn muốn ngăn cản việc khởi động lại vào thời gian chạy do thay đổi hướng khi phát triển
+cho API mức 13 hoặc cao hơn (như được khai báo bởi các thuộc tính <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#min">{@code minSdkVersion}</a> và <a href="{@docRoot}guide/topics/manifest/uses-sdk-element.html#target">{@code targetSdkVersion}</a>
+), bạn phải bao gồm giá trị {@code "screenSize"} bên cạnh giá trị {@code
+"orientation"}. Cụ thể, bạn phải khai báo {@code
+android:configChanges="orientation|screenSize"}. Tuy nhiên, nếu ứng dụng của bạn nhắm tới API mức
+12 hoặc thấp hơn, khi đó hoạt động của bạn luôn tự mình xử lý thay đổi cấu hình này (thay đổi
+cấu hình này không khởi động lại hoạt động của bạn, ngay cả khi đang chạy trên một thiết bị phiên bản Android 3.2 hoặc cao hơn).</p>
+
+<p>Ví dụ, việc triển khai {@link
+android.app.Activity#onConfigurationChanged(Configuration) onConfigurationChanged()} sau
+sẽ kiểm tra hướng thiết bị hiện tại:</p>
+
+<pre>
+&#64;Override
+public void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+
+ // Checks the orientation of the screen
+ if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
+ Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
+ } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
+ Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
+ }
+}
+</pre>
+
+<p>Đối tượng {@link android.content.res.Configuration} biểu diễn tất cả cấu hình
+hiện tại, không chỉ những cấu hình đã thay đổi. Trong phần lớn thời gian, bạn sẽ không quan tâm chính xác xem
+cấu hình đã thay đổi như thế nào và có thể đơn giản gán lại tất cả tài nguyên của mình với chức năng cung cấp nội dung thay thế
+cho cấu hình mà bạn đang xử lý. Ví dụ, do đối tượng {@link
+android.content.res.Resources} nay đã được cập nhật, bạn có thể đặt lại
+bất kỳ{@link android.widget.ImageView} nào với {@link android.widget.ImageView#setImageResource(int)
+setImageResource()}
+và tài nguyên phù hợp cho cấu hình mới được sử dụng (như được mô tả trong phần <a href="providing-resources.html#AlternateResources">Cung cấp Tài nguyên</a>).</p>
+
+<p>Lưu ý rằng giá trị từ các trường {@link
+android.content.res.Configuration} là những số nguyên khớp với hằng số cụ thể
+từ lớp {@link android.content.res.Configuration}. Đối với tài liệu về những hằng số
+cần sử dụng với mỗi trường, hãy tham khảo trường phù hợp trong tham chiếu {@link
+android.content.res.Configuration}.</p>
+
+<p class="note"><strong>Hãy ghi nhớ:</strong> Khi bạn khai báo hoạt động của mình để xử lý một
+thay đổi cấu hình, bạn có trách nhiệm đặt lại bất kỳ phần tử nào mà bạn cung cấp nội dung thay thế cho. Nếu bạn
+khai báo hoạt động của mình để xử lý thay đổi hướng và có những hình ảnh nên thay đổi
+giữa khổ ngang và hướng dọc, bạn phải gán lại từng tài nguyên cho từng phần tử trong khi {@link
+android.app.Activity#onConfigurationChanged(Configuration) onConfigurationChanged()}.</p>
+
+<p>Nếu bạn không cần cập nhật ứng dụng của mình dựa trên những thay đổi
+cấu hình này, thay vào đó bạn có thể <em>không</em> triển khai {@link
+android.app.Activity#onConfigurationChanged(Configuration) onConfigurationChanged()}. Trong
+trường hợp đó, tất cả tài nguyên được sử dụng trước khi thay đổi cấu hình sẽ vẫn được sử dụng
+và bạn chỉ mới tránh được việc khởi động lại hoạt động của mình. Tuy nhiên, ứng dụng của bạn cần luôn có khả năng
+tắt và khởi động lại với trạng thái trước đó của nó được giữ nguyên, vì thế bạn không nên coi
+kỹ thuật này như một cách để thoát khỏi việc giữ lại trạng thái của mình trong vòng đời của hoạt động bình thường. Không chỉ bởi
+có những thay đổi cấu hình khác mà bạn không thể ngăn không cho khởi động lại ứng dụng của mình, mà
+cả bởi vì bạn nên xử lý những sự kiện như là khi người dùng rời khỏi ứng dụng của bạn và nó bị
+hủy trước khi người dùng quay lại.</p>
+
+<p>Để biết thêm về những thay đổi cấu hình nào mà bạn có thể xử lý trong hoạt động của mình, hãy xem tài liệu <a href="{@docRoot}guide/topics/manifest/activity-element.html#config">{@code
+android:configChanges}</a> và lớp {@link android.content.res.Configuration}
+.</p>
diff --git a/docs/html-intl/intl/vi/guide/topics/ui/controls.jd b/docs/html-intl/intl/vi/guide/topics/ui/controls.jd
new file mode 100644
index 000000000000..37fe81c8c73a
--- /dev/null
+++ b/docs/html-intl/intl/vi/guide/topics/ui/controls.jd
@@ -0,0 +1,90 @@
+page.title=Điều khiển Nhập liệu
+parent.title=Giao diện Người dùng
+parent.link=index.html
+@jd:body
+
+<div class="figure" style="margin:0">
+ <img src="{@docRoot}images/ui/ui-controls.png" alt="" style="margin:0" />
+</div>
+
+<p>Điều khiển nhập liệu là những thành phần tương tác trong giao diện người dùng của ứng dụng của bạn. Android cung cấp
+nhiều kiểu điều khiển bạn có thể sử dụng trong UI của mình, chẳng hạn như nút, trường văn bản, thanh tìm kiếm,
+hộp kiểm, nút thu phóng, nút bật tắt, và nhiều kiểu khác.</p>
+
+<p>Thêm một điều khiển nhập liệu vào UI của bạn cũng đơn giản như thêm một phần tử XML vào <a href="{@docRoot}guide/topics/ui/declaring-layout.html">bố trí XML</a> của bạn. Ví dụ, đây là một bố trí
+với một trường văn bản và nút:</p>
+
+<pre style="clear:right">
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="horizontal">
+ &lt;EditText android:id="@+id/edit_message"
+ android:layout_weight="1"
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:hint="@string/edit_message" />
+ &lt;Button android:id="@+id/button_send"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/button_send"
+ android:onClick="sendMessage" />
+&lt;/LinearLayout>
+</pre>
+
+<p>Mỗi điều khiển nhập liệu hỗ trợ một tập hợp sự kiện nhập liệu cụ thể để bạn có thể xử lý các sự kiện chẳng hạn như khi
+người dùng nhập văn bản hoặc chạm vào một nút.</p>
+
+
+<h2 id="CommonControls">Điều khiển Thông dụng</h2>
+<p>Sau đây là danh sách những điều khiển thông dụng mà bạn có thể sử dụng trong ứng dụng của mình. Theo dõi các liên kết để tìm
+hiểu thêm về việc sử dụng từng điều khiển.</p>
+
+<p class="note"><strong>Lưu ý:</strong> Android cung cấp nhiều điều khiển hơn một chút so với liệt kê ở
+đây. Duyệt gói {@link android.widget} để khám phá thêm. Nếu ứng dụng của bạn yêu cầu một
+kiểu điều khiển nhập liệu cụ thể, bạn có thể xây dựng <a href="{@docRoot}guide/topics/ui/custom-components.html">các thành phần tùy chỉnh</a> của chính mình.</p>
+
+<table>
+ <tr>
+ <th scope="col">Kiểu Điều khiển</th>
+ <th scope="col">Mô tả</th>
+ <th scope="col">Lớp Liên quan</th>
+ </tr>
+ <tr>
+ <td><a href="controls/button.html">Nút</a></td>
+ <td>Nút nhấn có thể được nhấn, hoặc nhấp vào, bởi người dùng để thực hiện một hành động.</td>
+ <td>{@link android.widget.Button Button} </td>
+ </tr>
+ <tr>
+ <td><a href="controls/text.html">Trường văn bản</a></td>
+ <td>Trường văn bản có thể chỉnh sửa. Bạn có thể sử dụng widget <code>AutoCompleteTextView</code> để tạo một widget mục nhập văn bản nhằm cung cấp các gợi ý tự động hoàn thành</td>
+ <td>{@link android.widget.EditText EditText}, {@link android.widget.AutoCompleteTextView}</td>
+ </tr>
+ <tr>
+ <td><a href="controls/checkbox.html">Hộp kiểm</a></td>
+ <td>Một công tắc bật/tắt mà có thể được chuyển đổi bởi người dùng. Bạn nên sử dụng các hộp kiểm khi trình bày cho người dùng một nhóm các tùy chọn có thể chọn mà không loại trừ lẫn nhau.</td>
+ <td>{@link android.widget.CheckBox CheckBox} </td>
+ </tr>
+ <tr>
+ <td><a href="controls/radiobutton.html">Nút chọn một</a></td>
+ <td>Tương tự như hộp kiểm, chỉ khác ở chỗ chỉ có thể chọn một tùy chọn trong nhóm.</td>
+ <td>{@link android.widget.RadioGroup RadioGroup}
+ <br>{@link android.widget.RadioButton RadioButton} </td>
+ </tr>
+ <tr>
+ <td><a href="controls/togglebutton.html" style="white-space:nowrap">Nút bật tắt</a></td>
+ <td>Một nút bật/tắt có đèn chỉ báo.</td>
+ <td>{@link android.widget.ToggleButton ToggleButton} </td>
+ </tr>
+ <tr>
+ <td><a href="controls/spinner.html">Quay tròn</a></td>
+ <td>Một danh sách thả xuống cho phép người dùng chọn một giá trị từ một tập hợp.</td>
+ <td>{@link android.widget.Spinner Spinner} </td>
+ </tr>
+ <tr>
+ <td><a href="controls/pickers.html">Bộ chọn</a></td>
+ <td>Một hộp thoại cho người dùng chọn một giá trị đơn lẻ cho một tập hợp bằng cách sử dụng các nút lên/xuống hoặc thông qua cử chỉ trượt nhanh. Sử dụng một widget <code>DatePicker</code> để nhập giá trị cho ngày (tháng, ngày, năm) hoặc một widget <code>TimePicker</code> để nhập giá trị cho thời gian (giờ, phút, Sáng/Chiều tối) mà sẽ được định dạng tự động theo bản địa của người dùng.</td>
+ <td>{@link android.widget.DatePicker}, {@link android.widget.TimePicker}</td>
+ </tr>
+</table>
diff --git a/docs/html-intl/intl/vi/guide/topics/ui/declaring-layout.jd b/docs/html-intl/intl/vi/guide/topics/ui/declaring-layout.jd
new file mode 100644
index 000000000000..6add812d89f7
--- /dev/null
+++ b/docs/html-intl/intl/vi/guide/topics/ui/declaring-layout.jd
@@ -0,0 +1,492 @@
+page.title=Bố trí
+page.tags=dạng xem, nhóm dạng xem
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+ <h2>Trong tài liệu này</h2>
+<ol>
+ <li><a href="#write">Ghi XML</a></li>
+ <li><a href="#load">Nạp Tài nguyên XML</a></li>
+ <li><a href="#attributes">Thuộc tính</a>
+ <ol>
+ <li><a href="#id">ID</a></li>
+ <li><a href="#layout-params">Tham số Bố trí</a></li>
+ </ol>
+ </li>
+ <li><a href="#Position">Vị trí Bố trí</a></li>
+ <li><a href="#SizePaddingMargins">Kích cỡ, Phần đệm và Lề</a></li>
+ <li><a href="#CommonLayouts">Các Bố trí Thường gặp</a></li>
+ <li><a href="#AdapterViews">Xây dựng Bố trí bằng một Trình điều hợp</a>
+ <ol>
+ <li><a href="#FillingTheLayout">Điền dữ liệu vào một dạng xem trình điều hợp</a></li>
+ <li><a href="#HandlingUserSelections">Xử lý sự kiện nhấp</a></li>
+ </ol>
+ </li>
+</ol>
+
+ <h2>Lớp khóa</h2>
+ <ol>
+ <li>{@link android.view.View}</li>
+ <li>{@link android.view.ViewGroup}</li>
+ <li>{@link android.view.ViewGroup.LayoutParams}</li>
+ </ol>
+
+ <h2>Xem thêm</h2>
+ <ol>
+ <li><a href="{@docRoot}training/basics/firstapp/building-ui.html">Xây dựng một Giao diện Người dùng
+Đơn giản</a></li> </div>
+</div>
+
+<p>Bố trí định nghĩa cấu trúc hiển thị cho một giao diện người dùng, chẳng hạn như UI cho một <a href="{@docRoot}guide/components/activities.html">hoạt động</a> hoặc <a href="{@docRoot}guide/topics/appwidgets/index.html">widget ứng dụng</a>.
+Bạn có thể khai báo một bố trí bằng hai cách:</p>
+<ul>
+<li><strong>Khai báo phần tử UI trong XML</strong>. Android cung cấp một kho từ vựng XML
+đơn giản, tương ứng với các lớp và lớp con Dạng xem, chẳng hạn như dành cho các widget và bố trí.</li>
+<li><strong>Khởi tạo các phần tử bố trí vào thời gian chạy</strong>. Ứng dụng
+của bạn có thể tạo các đối tượng Dạng xem và Nhóm Dạng xem (và thao tác trên các tính chất của nó) theo lập trình. </li>
+</ul>
+
+<p>Khuôn khổ Android cho bạn sự linh hoạt trong khi sử dụng một hoặc cả hai phương pháp này để khai báo và quản lý UI ứng dụng của mình. Ví dụ, bạn có thể khai báo các bố trí mặc định cho ứng dụng của mình trong XML, bao gồm các phần tử màn hình mà sẽ xuất hiện trong chúng hoặc tính chất của chúng. Sau đó, bạn có thể thêm mã trong ứng dụng của mình để sửa đổi trạng thái của các đối tượng trên màn hình, bao gồm những đối tượng được khai báo trong XML, vào thời gian chạy. </p>
+
+<div class="sidebox-wrapper">
+<div class="sidebox">
+ <ul>
+ <li>Phần bổ trợ <a href="{@docRoot}tools/sdk/eclipse-adt.html">ADT
+ cho Eclipse</a> sẽ đưa ra một bản xem trước bố trí XML của bạn &mdash;
+ có tệp XML được mở, hãy chọn tab <strong>Bố trí</strong>.</li>
+ <li>Bạn cũng nên thử công cụ
+ <a href="{@docRoot}tools/debugging/debugging-ui.html#hierarchyViewer">Trình xem Phân cấp</a>,
+ để gỡ rối các bố trí &mdash; nó hé lộ các giá trị tính chất của bố trí,
+ vẽ đường viền bằng các chỉ báo phần đệm/lề, và các dạng xem được dựng đầy đủ trong khi
+ bạn gỡ rối trên trình mô phỏng hoặc thiết bị.</li>
+ <li>Công cụ <a href="{@docRoot}tools/debugging/debugging-ui.html#layoutopt">layoutopt</a> cho phép
+ bạn nhanh chóng phân tích các bố trí và phân cấp của mình xem có không hiệu quả hoặc có các vấn đề khác không.</li>
+</div>
+</div>
+
+<p>Ưu điểm của việc khai báo UI của bạn trong XML là cho phép bạn tách việc trình bày ứng dụng của mình với mã điều khiển hành vi của nó hiệu quả hơn. Mô tả UI của bạn nằm ngoài mã ứng dụng của bạn, điều này có nghĩa rằng bạn có thể sửa đổi hoặc điều hợp nó mà không phải sửa đổi mã nguồn của bạn và biên dịch lại. Ví dụ, bạn có thể tạo bố trí XML cho các hướng màn hình khác nhau, kích cỡ màn hình khác nhau, và ngôn ngữ khác nhau. Ngoài ra, việc khai báo bố trí trong XML giúp dễ dàng hơn trong việc hiển thị cấu trúc UI của bạn, vì vậy sẽ dễ gỡ lỗi sự cố hơn. Như vậy, tài liệu này tập trung vào việc hướng dẫn bạn cách khai báo bố trí của mình trong XML. Nếu bạn
+quan tâm tới việc khởi tạo các đối tượng Dạng xem vào thời gian chạy, hãy tham khảo {@link android.view.ViewGroup} và
+tài liệu tham khảo lớp {@link android.view.View}.</p>
+
+<p>Nhìn chung, kho từ vựng của XML đối với việc khai báo các phần tử UI tuân thủ chặt chẽ cấu trúc và cách đặt tên các lớp và phương pháp, trong đó các tên phần tử tương ứng với tên lớp và tên thuộc tính tương ứng với phương pháp. Trên thực tế, sự tương ứng thường trực tiếp đến mức bạn có thể đoán thuộc tính XML nào tương ứng với một phương pháp lớp, hoặc đoán xem lớp nào tương ứng với một phần tử XML cho trước. Tuy nhiên, lưu ý rằng không phải tất cả từ vựng đều giống nhau. Trong một số trường hợp, có sự khác biệt nhỏ trong việc đặt tên. Ví
+dụ, phần tử EditText có thuộc tính <code>text</code> tương ứng với
+<code>EditText.setText()</code>. </p>
+
+<p class="note"><strong>Mẹo:</strong> Tìm hiểu thêm về các kiểu bố trí trong <a href="{@docRoot}guide/topics/ui/layout-objects.html">Đối tượng Bố trí
+Thường gặp</a>. Có một tuyển tập các bài hướng dẫn về việc xây dựng các bố trí khác nhau trong hướng dẫn bài học
+<a href="{@docRoot}resources/tutorials/views/index.html">Dạng xem Hello</a>.</p>
+
+<h2 id="write">Ghi XML</h2>
+
+<p>Khi sử dụng từ vựng XML của Android, bạn có thể nhanh chóng thiết kế các bố trí UI và phần tử màn hình mà chúng chứa, giống như cách bạn tạo trang web trong HTML &mdash; bằng một loạt các phần tử lồng nhau. </p>
+
+<p>Mỗi tệp bố trí phải chứa chính xác một phần tử gốc, đó phải là một đối tượng Dạng xem hoặc Nhóm Dạng xem. Sau khi đã định nghĩa phần tử gốc, bạn có thể thêm các đối tượng hoặc widget bố trí bổ sung làm phần tử con để dần dần xây dựng một phân cấp Dạng xem định nghĩa bố trí của bạn. Ví dụ, sau đây là một bố trí XML sử dụng một {@link android.widget.LinearLayout}
+thẳng đứng để giữ một {@link android.widget.TextView} và một {@link android.widget.Button}:</p>
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical" >
+ &lt;TextView android:id="@+id/text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Hello, I am a TextView" />
+ &lt;Button android:id="@+id/button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="Hello, I am a Button" />
+&lt;/LinearLayout>
+</pre>
+
+<p>Sau khi bạn đã khai báo bố trí của mình trong XML, hãy lưu tệp với phần mở rộng <code>.xml</code>,
+trong thư mục dự án <code>res/layout/</code> Android của bạn để biên dịch cho phù hợp. </p>
+
+<p>Thông tin về cú pháp đối với tệp XML bố trí có sẵn trong tài liệu <a href="{@docRoot}guide/topics/resources/layout-resource.html">Tài nguyên Bố trí</a>.</p>
+
+<h2 id="load">Nạp Tài nguyên XML</h2>
+
+<p>Khi bạn biên dịch ứng dụng của mình, từng tệp bố trí XML được biên dịch thành một tài nguyên
+{@link android.view.View}. Bạn nên nạp tài nguyên bố trí từ mã ứng dụng của mình, trong triển khai gọi lại
+{@link android.app.Activity#onCreate(android.os.Bundle) Activity.onCreate()} của bạn.
+Làm vậy bằng cách gọi <code>{@link android.app.Activity#setContentView(int) setContentView()}</code>,
+chuyển cho nó tham chiếu tới tài nguyên bố trí của bạn dưới hình thức:
+<code>R.layout.<em>layout_file_name</em></code>.
+Ví dụ, nếu bố trí XML của bạn được lưu thành <code>main_layout.xml</code>, bạn sẽ nạp nó
+cho Hoạt động của mình như sau:</p>
+<pre>
+public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.main_layout);
+}
+</pre>
+
+<p>Phương pháp gọi lại <code>onCreate()</code> trong Hoạt động của bạn được gọi bởi khuôn khổ Android khi
+Hoạt động của bạn được khởi chạy (xem phần thảo luận về vòng đời, trong tài liệu
+<a href="{@docRoot}guide/components/activities.html#Lifecycle">Hoạt động</a>
+).</p>
+
+
+<h2 id="attributes">Thuộc tính</h2>
+
+<p>Mọi đối tượng Dạng xem và Nhóm Dạng xem đều hỗ trợ các phiên bản thuộc tính XML của chính mình.
+Một số thuộc tính áp dụng riêng cho đối tượng Dạng xem (ví dụ, TextView hỗ trợ thuộc tính <code>textSize</code>
+), nhưng những thuộc tính này cũng được kế thừa bởi bất kỳ đối tượng Dạng xem nào mà có thể mở rộng lớp này.
+Một số được áp dụng chung cho tất cả đối tượng Dạng xem vì chúng được kế thừa từ lớp Dạng xem gốc (như
+thuộc tính <code>id</code>). Và những thuộc tính còn lại được coi là "tham số bố trí," đó là những thuộc tính
+mô tả một số hướng bố trí nhất định của đối tượng Dạng xem, như được định nghĩa bởi đối tượng Nhóm Dạng xem
+mẹ của đối tượng đó.</p>
+
+<h3 id="id">ID</h3>
+
+<p>Bất kỳ đối tượng Dạng xem nào cũng có một ID số nguyên được liên kết với nó để nhận biết duy nhất Dạng xem trong cây.
+Khi ứng dụng được biên dịch, ID này được tham chiếu như một số nguyên, nhưng ID thường
+được gán trong tệp XML bố trí như một xâu, trong thuộc tính <code>id</code>.
+Đây là thuộc tính XML chung cho tất cả đối tượng Dạng xem
+(được định nghĩa theo lớp {@link android.view.View}) và bạn sẽ rất hay sử dụng nó.
+Cú pháp đối với một ID bên trong một tag XML là:</p>
+<pre>android:id="&#64;+id/my_button"</pre>
+
+<p>Biểu tượng "a móc" (@) ở đầu xâu thể hiện rằng trình phân tích XML nên phân tích và mở rộng phần còn lại
+của xâu ID và nhận biết nó như một tài nguyên ID. Biểu tượng dấu cộng (+) có nghĩa rằng đây là một tên tài nguyên mới mà phải
+được tạo và thêm vào tài nguyên của chúng ta (trong tệp <code>R.java</code>). Có nhiều tài nguyên ID khác
+được cung cấp bởi khuôn khổ Android. Khi tham chiếu một ID tài nguyên Android, bạn không cần biểu tượng dấu cộng,
+nhưng phải thêm vùng tên gói <code>android</code>, như sau:</p>
+<pre>android:id="&#64;android:id/empty"</pre>
+<p>Khi đã có vùng tên gói <code>android</code>, giờ chúng ta đang tham chiếu một ID từ lớp tài nguyên <code>android.R</code>
+, thay vì lớp tài nguyên cục bộ.</p>
+
+<p>Để tạo các dạng xem và tham chiếu chúng từ ứng dụng, một mô thức thường thấy đó là:</p>
+<ol>
+ <li>Định nghĩa một dạng xem/widget trong tệp bố trí và gán cho nó một ID duy nhất:
+<pre>
+&lt;Button android:id="&#64;+id/my_button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="&#64;string/my_button_text"/>
+</pre>
+ </li>
+ <li>Sau đó, tạo một thực thể của đối tượng dạng xem và chụp nó từ bố trí
+(thường trong phương pháp <code>{@link android.app.Activity#onCreate(Bundle) onCreate()}</code>):
+<pre>
+Button myButton = (Button) findViewById(R.id.my_button);
+</pre>
+ </li>
+</ol>
+<p>Định nghĩa các ID cho đối tượng dạng xem là việc quan trọng khi tạo một {@link android.widget.RelativeLayout}.
+Trong một bố trí tương đối, các dạng xem đồng hạng có thể định nghĩa bố trí của nó so với dạng xem đồng hạng kia,
+dạng xem mà được tham chiếu bởi ID duy nhất.</p>
+<p>Một ID không cần phải là duy nhất trong toàn bộ cây, nhưng nên là
+duy nhất trong bộ phận của cây mà bạn đang tìm kiếm (thường là toàn bộ cây, vì thế tốt nhất là
+ID nên hoàn toàn duy nhất khi có thể).</p>
+
+
+<h3 id="layout-params">Tham số Bố trí</h3>
+
+<p>Các thuộc tính bố trí XML <code>layout_<em>something</em></code> sẽ định nghĩa
+các tham số bố trí cho Dạng xem phù hợp với Nhóm Dạng xem mà nó nằm trong đó.</p>
+
+<p>Mọi lớp Nhóm Dạng xem đều triển khai một lớp lồng nhau có chức năng mở rộng {@link
+android.view.ViewGroup.LayoutParams}. Lớp con này
+chứa các kiểu tính chất mà định nghĩa kích cỡ và vị trí của từng dạng xem con cho
+phù hợp với nhóm dạng xem. Như bạn có thể thấy trong hình 1, nhóm dạng xem
+mẹ sẽ định nghĩa các tham số bố trí cho từng dạng xem con (bao gồm nhóm dạng xem con).</p>
+
+<img src="{@docRoot}images/layoutparams.png" alt="" />
+<p class="img-caption"><strong>Hình 1.</strong> Trực quan hóa một phân cấp dạng xem với các tham số
+bố trí được liên kết với từng dạng xem.</p>
+
+<p>Để ý rằng mọi lớp con LayoutParams đều có cú pháp riêng của mình cho các giá trị
+thiết đặt. Mỗi phần tử con phải định nghĩa LayoutParams cho phù hợp với phần tử mẹ của nó,
+mặc dù cũng có thể định nghĩa LayoutParams khác cho phần tử con của chính nó. </p>
+
+<p>Tất cả nhóm dạng xem đều có chiều rộng và chiều cao (<code>layout_width</code> và
+<code>layout_height</code>), và mỗi dạng xem đều phải định nghĩa chúng. Nhiều
+LayoutParams cũng có lề và viền tùy chọn. <p>
+
+<p>Bạn có thể chỉ định chiều rộng và chiều cao bằng các số đo chính xác, mặc dù có thể
+bạn sẽ không muốn làm điều này thường xuyên. Bạn sẽ thường sử dụng một trong những hằng số này để
+đặt chiều rộng hoặc chiều cao: </p>
+
+<ul>
+ <li><var>wrap_content</var> cho biết dạng xem của bạn tự định cỡ theo kích thước
+mà nội dung của nó yêu cầu.</li>
+ <li><var>match_parent</var> (được đặt tên <var>fill_parent</var> trước API Mức 8)
+cho biết dạng xem của bạn có thể phóng lớn khi nhóm dạng xem mẹ của nó cho phép.</li>
+</ul>
+
+<p>Nhìn chung, việc chỉ định một chiều rộng và chiều cao bố trí bằng cách sử dụng các đơn vị tuyệt đối như
+điểm ảnh là điều không được khuyến cáo. Thay vào đó, sử dụng các số đo tương đối như
+số đơn vị điểm ảnh độc lập với mật độ (<var>dp</var>), <var>wrap_content</var>, hoặc
+<var>match_parent</var>, là một phương pháp tốt hơn, vì nó giúp đảm bảo rằng
+ứng dụng của bạn sẽ hiển thị phù hợp giữa nhiều loại kích cỡ màn hình thiết bị khác nhau.
+Các kiểu số đo được chấp nhận được định nghĩa trong tài liệu
+<a href="{@docRoot}guide/topics/resources/available-resources.html#dimension">
+Tài nguyên Có sẵn</a>.</p>
+
+
+<h2 id="Position">Vị trí Bố trí</h2>
+ <p>
+ Hình học của một dạng xem là hình chữ nhật. Dạng xem có một vị trí,
+ được biểu diễn thành một cặp tọa độ <em>trái</em> và <em>trên</em> và
+ hai kích thước, được biểu diễn thành chiều rộng và chiều cao. Đơn vị của vị trí
+ và kích thước là điểm ảnh.
+ </p>
+
+ <p>
+ Có thể truy xuất vị trí của một dạng xem bằng cách gọi ra các phương pháp
+ {@link android.view.View#getLeft()} và {@link android.view.View#getTop()}. Phương pháp đầu trả về tọa độ trái, hay X,
+ của hình chữ nhật biểu diễn dạng xem. Phương pháp sau trả về tọa độ trên, hay Y,
+ của hình chữ nhật biểu diễn dạng xem. Những phương pháp này
+ đều trả về vị trí của dạng xem so với dạng xem mẹ của nó. Ví dụ,
+ khi <code>getLeft()</code> trả về 20, điều đó có nghĩa là dạng xem nằm ở 20 điểm ảnh về
+ bên phải của cạnh trái của dạng xem mẹ trực tiếp của nó.
+ </p>
+
+ <p>
+ Ngoài ra, một vài phương pháp thuận tiện được đưa ra để tránh những tính toán
+ không cần thiết, cụ thể là {@link android.view.View#getRight()} và {@link android.view.View#getBottom()}.
+ Những phương pháp này trả về tọa độ của cạnh phải và cạnh đáy của hình chữ nhật
+ biểu diễn dạng xem. Ví dụ, việc gọi {@link android.view.View#getRight()}
+ tương tự như tính toán sau: <code>getLeft() + getWidth()</code>.
+ </p>
+
+
+<h2 id="SizePaddingMargins">Kích cỡ, Phần đệm và Lề</h2>
+ <p>
+ Kích cỡ của một dạng xem được biểu diễn bằng chiều rộng và chiều cao. Thực ra một dạng xem
+ sẽ có hai cặp giá trị chiều rộng và chiều cao.
+ </p>
+
+ <p>
+ Cặp thứ nhất được gọi là <em>chiều rộng đo được</em> và
+ <em>chiều cao đo được</em>. Những kích thước này xác định một dạng xem muốn phóng lớn bao nhiêu
+ trong dạng xem mẹ của nó. Các
+ kích thước đo được có thể thu được bằng cách gọi {@link android.view.View#getMeasuredWidth()}
+ và {@link android.view.View#getMeasuredHeight()}.
+ </p>
+
+ <p>
+ Cặp thứ hai đơn thuần là <em>chiều rộng</em> và <em>chiều cao</em>, hoặc
+ đôi khi gọi là <em>chiều rộng vẽ</em> và <em>chiều cao vẽ</em>. Những
+ kích thước này xác định kích cỡ thực sự của dạng xem trên màn hình, tại thời điểm vẽ và
+ sau khi bố trí. Những giá trị này có thể nhưng không nhất thiết phải khác với
+ chiều rộng và chiều cao đo được. Chiều rộng và chiều cao này có thể lấy được bằng cách gọi
+ {@link android.view.View#getWidth()} và {@link android.view.View#getHeight()}.
+ </p>
+
+ <p>
+ Để đo các kích thước của nó, dạng xem cần xét tới phần đệm của nó. Phần đệm
+ được biểu diễn bằng số điểm ảnh của phần bên trái, bên trên, bên phải và bên dưới của dạng xem.
+ Phần đệm có thể được sử dụng để bù trừ nội dung của dạng xem bằng một số điểm ảnh
+ cụ thể. Ví dụ, phần đệm bên trái bằng 2 sẽ đẩy nội dung của dạng xem đi
+ 2 điểm ảnh về bên phải của cạnh bên trái. Phần đệm có thể được đặt bằng cách sử dụng phương pháp
+ {@link android.view.View#setPadding(int, int, int, int)} và được truy vấn bằng cách gọi
+ {@link android.view.View#getPaddingLeft()}, {@link android.view.View#getPaddingTop()},
+ {@link android.view.View#getPaddingRight()} và {@link android.view.View#getPaddingBottom()}.
+ </p>
+
+ <p>
+ Mặc dù dạng xem có thể xác định phần đệm, nó không có bất kỳ sự hỗ trợ nào cho
+ lề. Tuy nhiên, các nhóm dạng xem lại cung cấp sự hỗ trợ như vậy. Tham khảo
+ {@link android.view.ViewGroup} và
+ {@link android.view.ViewGroup.MarginLayoutParams} để biết thêm thông tin.
+ </p>
+
+ <p>Để biết thêm thông tin về kích thước, xem
+ <a href="{@docRoot}guide/topics/resources/more-resources.html#Dimension">Giá trị Kích thước</a>.
+ </p>
+
+
+
+
+
+
+<style type="text/css">
+div.layout {
+ float:left;
+ width:200px;
+ margin:0 0 20px 20px;
+}
+div.layout.first {
+ margin-left:0;
+ clear:left;
+}
+</style>
+
+
+
+
+<h2 id="CommonLayouts">Các Bố trí Thường gặp</h2>
+
+<p>Mỗi lớp con của lớp {@link android.view.ViewGroup} cung cấp một cách duy nhất để hiển thị
+các dạng xem mà bạn lồng trong nó. Dưới đây là một số kiểu bố trí phổ biến hơn mà được tích hợp
+trong nền tảng Android.</p>
+
+<p class="note"><strong>Lưu ý:</strong> Mặc dù bạn có thể lồng một hoặc nhiều bố trí với một
+bố trí khác để đạt được thiết kế UI của mình, bạn nên cố gắng duy trì phân cấp bố trí của mình ở mức nông nhất
+có thể. Bố trí của bạn sẽ vẽ nhanh hơn nếu nó có ít bố trí lồng nhau hơn (phân cấp dạng xem rộng
+sẽ tốt hơn phân cấp dạng xem sâu).</p>
+
+<!--
+<h2 id="framelayout">FrameLayout</h2>
+<p>{@link android.widget.FrameLayout FrameLayout} is the simplest type of layout
+object. It's basically a blank space on your screen that you can
+later fill with a single object &mdash; for example, a picture that you'll swap in and out.
+All child elements of the FrameLayout are pinned to the top left corner of the screen; you cannot
+specify a different location for a child view. Subsequent child views will simply be drawn over
+previous ones,
+partially or totally obscuring them (unless the newer object is transparent).
+</p>
+-->
+
+
+<div class="layout first">
+ <h4><a href="layout/linear.html">Bố trí Tuyến tính</a></h4>
+ <a href="layout/linear.html"><img src="{@docRoot}images/ui/linearlayout-small.png" alt="" /></a>
+ <p>Một bố trí có chức năng sắp xếp tổ chức các bố trí con của nó thành một hàng ngang hoặc thẳng đứng. Nó
+ sẽ tạo một thanh cuộn nếu chiều dài của cửa sổ vượt quá chiều dài của màn hình.</p>
+</div>
+
+<div class="layout">
+ <h4><a href="layout/relative.html">Bố trí Tương đối</a></h4>
+ <a href="layout/relative.html"><img src="{@docRoot}images/ui/relativelayout-small.png" alt="" /></a>
+ <p>Cho phép bạn chỉ định vị trí của các đối tượng con so với nhau (đối tượng con A về phía
+bên trái của đối tượng con B) hoặc so với đối tượng mẹ (được căn theo bên trên đối tượng mẹ).</p>
+</div>
+
+<div class="layout">
+ <h4><a href="{@docRoot}guide/webapps/webview.html">Dạng xem Web</a></h4>
+ <a href="{@docRoot}guide/webapps/webview.html"><img src="{@docRoot}images/ui/webview-small.png" alt="" /></a>
+ <p>Hiển thị trang web.</p>
+</div>
+
+
+
+
+<h2 id="AdapterViews" style="clear:left">Xây dựng Bố trí bằng một Trình điều hợp</h2>
+
+<p>Khi nội dung cho bố trí của bạn động hoặc chưa được xác định trước, bạn có thể sử dụng một bố trí có chức năng
+tạo lớp con {@link android.widget.AdapterView} để đưa vào bố trí có dạng xem vào thời gian chạy. Một
+lớp con của lớp {@link android.widget.AdapterView} sẽ sử dụng một {@link android.widget.Adapter} để
+gắn kết dữ liệu với bố trí của nó. {@link android.widget.Adapter} đóng vai trò trung gian giữa nguồn
+dữ liệu và bố trí {@link android.widget.AdapterView} &mdash;{@link android.widget.Adapter}
+sẽ truy xuất dữ liệu (từ một nguồn chẳng hạn như một mảng hoặc truy vấn cơ sở dữ liệu) và chuyển từng mục nhập
+thành một dạng xem có thể thêm vào bố trí {@link android.widget.AdapterView}.</p>
+
+<p>Các bố trí phổ biến được hỗ trợ bởi trình điều hợp bao gồm:</p>
+
+<div class="layout first">
+ <h4><a href="layout/listview.html">Dạng xem Danh sách</a></h4>
+ <a href="layout/listview.html"><img src="{@docRoot}images/ui/listview-small.png" alt="" /></a>
+ <p>Hiển thị một danh sách cột cuộn đơn.</p>
+</div>
+
+<div class="layout">
+ <h4><a href="layout/gridview.html">Dạng xem Lưới</a></h4>
+ <a href="layout/gridview.html"><img src="{@docRoot}images/ui/gridview-small.png" alt="" /></a>
+ <p>Hiển thị một lưới cuộn gồm nhiều hàng và cột.</p>
+</div>
+
+
+
+<h3 id="FillingTheLayout" style="clear:left">Điền dữ liệu vào một dạng xem trình điều hợp</h3>
+
+<p>Bạn có thể đưa vào một {@link android.widget.AdapterView} chẳng hạn như {@link android.widget.ListView} hoặc
+{@link android.widget.GridView} bằng cách gắn kết thực thể {@link android.widget.AdapterView} với một
+{@link android.widget.Adapter}, nó truy xuất dữ liệu từ một nguồn bên ngoài và tạo một {@link
+android.view.View} để biểu diễn từng mục nhập dữ liệu.</p>
+
+<p>Android cung cấp một vài lớp con của {@link android.widget.Adapter} rất hữu ích cho việc
+truy xuất các kiểu dữ liệu khác nhau và xây dựng dạng xem cho một {@link android.widget.AdapterView}. Hai
+trình điều hợp phổ biến nhất là:</p>
+
+<dl>
+ <dt>{@link android.widget.ArrayAdapter}</dt>
+ <dd>Sử dụng trình điều hợp này khi nguồn dữ liệu của bạn là một mảng. Theo mặc định, {@link
+android.widget.ArrayAdapter} tạo một dạng xem cho mỗi mục mảng bằng cách gọi {@link
+java.lang.Object#toString()} trên từng mục và đặt nội dung trong một {@link
+android.widget.TextView}.
+ <p>Ví dụ, nếu bạn có một mảng xâu mà bạn muốn hiển thị trong một {@link
+android.widget.ListView}, hãy khởi tạo một {@link android.widget.ArrayAdapter} mới bằng cách sử dụng
+hàm dựng để chỉ định bố trí cho từng xâu và mảng xâu:</p>
+<pre>
+ArrayAdapter&lt;String> adapter = new ArrayAdapter&lt;String>(this,
+ android.R.layout.simple_list_item_1, myStringArray);
+</pre>
+<p>Các tham đối cho hàm dựng này là:</p>
+<ul>
+ <li>Ứng dụng của bạn {@link android.content.Context}</li>
+ <li>Bố trí chứa một {@link android.widget.TextView} cho mỗi xâu trong mảng</li>
+ <li>Mảng xâu</li>
+</ul>
+<p>Sau đó chỉ cần gọi
+{@link android.widget.ListView#setAdapter setAdapter()} trên {@link android.widget.ListView} của bạn:</p>
+<pre>
+ListView listView = (ListView) findViewById(R.id.listview);
+listView.setAdapter(adapter);
+</pre>
+
+ <p>Để tùy chỉnh diện mạo của từng mục, bạn có thể khống chế phương pháp {@link
+java.lang.Object#toString()} cho các đối tượng trong mảng của mình. Hoặc, để tạo một dạng xem cho từng
+mục không phải là một {@link android.widget.TextView} (ví dụ, nếu bạn muốn một
+{@link android.widget.ImageView} cho từng mục mảng), hãy mở rộng lớp {@link
+android.widget.ArrayAdapter} và khống chế {@link android.widget.ArrayAdapter#getView
+getView()} để trả về kiểu dạng xem mà bạn muốn cho từng mục.</p>
+
+</dd>
+
+ <dt>{@link android.widget.SimpleCursorAdapter}</dt>
+ <dd>Sử dụng trình điều hợp này khi dữ liệu của bạn đến từ một {@link android.database.Cursor}. Khi
+sử dụng {@link android.widget.SimpleCursorAdapter}, bạn phải chỉ định một bố trí để sử dụng cho từng
+hàng trong {@link android.database.Cursor} và những cột nào trong {@link android.database.Cursor}
+nên được chèn vào dạng xem nào của bố trí. Ví dụ, nếu bạn muốn tạo một danh sách
+tên người và số điện thoại, bạn có thể thực hiện một truy vấn mà trả về một {@link
+android.database.Cursor} chứa một hàng cho từng người và nhiều cột cho các tên và
+số điện thoại. Sau đó, bạn tạo một mảng xâu chỉ định những cột nào từ {@link
+android.database.Cursor} mà bạn muốn trong bố trí cho từng kết quả và một mảng số nguyên chỉ định các
+dạng xem tương ứng mà từng cột sẽ được đặt vào:</p>
+<pre>
+String[] fromColumns = {ContactsContract.Data.DISPLAY_NAME,
+ ContactsContract.CommonDataKinds.Phone.NUMBER};
+int[] toViews = {R.id.display_name, R.id.phone_number};
+</pre>
+<p>Khi bạn khởi tạo {@link android.widget.SimpleCursorAdapter}, hãy chuyển bố trí cần sử dụng cho
+từng kết quả, {@link android.database.Cursor} chứa các kết quả, và hai mảng sau:</p>
+<pre>
+SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,
+ R.layout.person_name_and_number, cursor, fromColumns, toViews, 0);
+ListView listView = getListView();
+listView.setAdapter(adapter);
+</pre>
+<p>Sau đó, {@link android.widget.SimpleCursorAdapter} tạo một dạng xem cho từng hàng trong
+{@link android.database.Cursor} sử dụng bố trí được cung cấp bằng cách chèn từng mục {@code
+fromColumns} vào dạng xem {@code toViews} tương ứng.</p>.</dd>
+</dl>
+
+
+<p>Trong vòng đời ứng dụng của bạn, nếu bạn thay đổi dữ liệu liên quan được đọc bởi
+trình điều hợp của mình, bạn nên gọi {@link android.widget.ArrayAdapter#notifyDataSetChanged()}. Nó sẽ
+thông báo với dạng xem đính kèm rằng dữ liệu đã được thay đổi và dạng xem nên tự làm mới.</p>
+
+
+
+<h3 id="HandlingUserSelections">Xử lý sự kiện nhấp</h3>
+
+<p>Bạn có thể phản hồi các sự kiện nhấp trên từng mục trong một {@link android.widget.AdapterView} bằng cách
+triển khai giao diện {@link android.widget.AdapterView.OnItemClickListener}. Ví dụ:</p>
+
+<pre>
+// Create a message handling object as an anonymous class.
+private OnItemClickListener mMessageClickedHandler = new OnItemClickListener() {
+ public void onItemClick(AdapterView parent, View v, int position, long id) {
+ // Do something in response to the click
+ }
+};
+
+listView.setOnItemClickListener(mMessageClickedHandler);
+</pre>
+
+
+
diff --git a/docs/html-intl/intl/vi/guide/topics/ui/dialogs.jd b/docs/html-intl/intl/vi/guide/topics/ui/dialogs.jd
new file mode 100644
index 000000000000..1fa45508ef0c
--- /dev/null
+++ b/docs/html-intl/intl/vi/guide/topics/ui/dialogs.jd
@@ -0,0 +1,798 @@
+page.title=Hộp thoại
+page.tags=alertdialog,dialogfragment
+
+@jd:body
+
+
+
+<div id="qv-wrapper">
+ <div id="qv">
+ <h2>Trong tài liệu này</h2>
+<ol>
+ <li><a href="#DialogFragment">Tạo một Phân đoạn Hộp thoại</a></li>
+ <li><a href="#AlertDialog">Xây dựng một Hộp thoại Cảnh báo</a>
+ <ol>
+ <li><a href="#AddingButtons">Thêm nút</a></li>
+ <li><a href="#AddingAList">Thêm một danh sách</a></li>
+ <li><a href="#CustomLayout">Tạo một Bố trí Tùy chỉnh</a></li>
+ </ol>
+ </li>
+ <li><a href="#PassingEvents">Chuyển Sự kiện lại Máy chủ của Hộp thoại</a></li>
+ <li><a href="#ShowingADialog">Hiển thị một Hộp thoại</a></li>
+ <li><a href="#FullscreenDialog">Hiển thị một Hộp thoại Toàn màn hình hoặc dạng một Phân đoạn Nhúng</a>
+ <ol>
+ <li><a href="#ActivityAsDialog">Hiển thị một hoạt động dưới dạng một hộp thoại trên màn hình lớn</a></li>
+ </ol>
+ </li>
+ <li><a href="#DismissingADialog">Bỏ một Hộp thoại</a></li>
+</ol>
+
+ <h2>Lớp khóa</h2>
+ <ol>
+ <li>{@link android.app.DialogFragment}</li>
+ <li>{@link android.app.AlertDialog}</li>
+ </ol>
+
+ <h2>Xem thêm</h2>
+ <ol>
+ <li><a href="{@docRoot}design/building-blocks/dialogs.html">Hướng dẫn thiết kế hộp thoại</a></li>
+ <li><a href="{@docRoot}guide/topics/ui/controls/pickers.html">Bộ chọn</a> (Hộp thoại Ngày/Giờ)</li>
+ </ol>
+ </div>
+</div>
+
+<p>Hộp thoại là một cửa sổ nhỏ có chức năng nhắc người dùng
+đưa ra một quyết định hoặc nhập thông tin bổ sung. Hộp thoại không lấp kín màn hình và
+thường được sử dụng cho các sự kiện mô thái yêu cầu người dùng phải thực hiện một hành động trước khi có thể đi tiếp.</p>
+
+<div class="note design">
+<p><strong>Thiết kế Hộp thoại</strong></p>
+ <p>Để biết thông tin về cách thiết kế hộp thoại của bạn, bao gồm các đề xuất
+ về ngôn ngữ, hãy đọc hướng dẫn thiết kế <a href="{@docRoot}design/building-blocks/dialogs.html">Hộp thoại</a>.</p>
+</div>
+
+<img src="{@docRoot}images/ui/dialogs.png" />
+
+<p>Lớp {@link android.app.Dialog} là lớp cơ sở cho hộp thoại, nhưng bạn
+nên tránh khởi tạo {@link android.app.Dialog} một cách trực tiếp.
+Thay vào đó, hãy sử dụng một trong các lớp con sau:</p>
+<dl>
+ <dt>{@link android.app.AlertDialog}</dt>
+ <dd>Hộp thoại có thể hiển thị một tiêu đề, tối đa ba nút, một danh sách
+ các mục có thể chọn, hoặc một bố trí tùy chỉnh.</dd>
+ <dt>{@link android.app.DatePickerDialog} hoặc {@link android.app.TimePickerDialog}</dt>
+ <dd>Hộp thoại với một UI được xác định trước, cho phép người dùng chọn ngày hoặc giờ.</dd>
+</dl>
+
+<div class="sidebox">
+<h2>Tránh ProgressDialog</h2>
+<p>Android có một lớp hộp thoại khác gọi là
+{@link android.app.ProgressDialog}, nó hiển thị một hộp thoại với một thanh tiến độ. Tuy nhiên, nếu bạn
+cần chỉ báo tiến độ tải hoặc chưa xác định, thay vào đó, bạn nên tuân theo hướng dẫn
+thiết kế dành cho <a href="{@docRoot}design/building-blocks/progress.html">Tiến độ &amp;
+Hoạt động</a> và sử dụng một {@link android.widget.ProgressBar} trong bố trí của mình.</p>
+</div>
+
+<p>Những lớp này định nghĩa kiểu và cấu trúc cho hộp thoại của bạn, nhưng bạn nên
+sử dụng một {@link android.support.v4.app.DialogFragment} làm bộ chứa cho hộp thoại của mình.
+Lớp {@link android.support.v4.app.DialogFragment} sẽ cung cấp tất cả điều khiển mà
+bạn cần để tạo hộp thoại của mình và quản lý diện mạo của hộp thoại, thay vì gọi ra các phương pháp
+trên đối tượng {@link android.app.Dialog}.</p>
+
+<p>Việc sử dụng {@link android.support.v4.app.DialogFragment} để quản lý hộp thoại
+sẽ đảm bảo rằng nó xử lý đúng các sự kiện vòng đời
+chẳng hạn như khi người dùng nhấn nút <em>Quay lại</em> hoặc xoay màn hình. Lớp {@link
+android.support.v4.app.DialogFragment} cũng cho phép bạn sử dụng lại UI của hộp thoại như một
+thành phần có thể nhúng trong một UI rộng hơn, giống như một {@link
+android.support.v4.app.Fragment} truyền thống (chẳng hạn như khi bạn muốn UI hộp thoại xuất hiện khác đi
+trên các màn hình lớn và nhỏ).</p>
+
+<p>Các phần sau trong hướng dẫn này mô tả cách sử dụng {@link
+android.support.v4.app.DialogFragment} kết hợp với một đối tượng {@link android.app.AlertDialog}
+. Nếu muốn tạo một bộ chọn ngày hoặc giờ, thay vào đó, bạn nên đọc hướng dẫn
+<a href="{@docRoot}guide/topics/ui/controls/pickers.html">Bộ chọn</a>.</p>
+
+<p class="note"><strong>Lưu ý:</strong>
+Vì lớp {@link android.app.DialogFragment} ban đầu được bổ sung cùng với
+Android 3.0 (API mức 11), tài liệu này mô tả cách sử dụng lớp {@link
+android.support.v4.app.DialogFragment} được cung cấp kèm <a href="{@docRoot}tools/support-library/index.html">Thư viện Hỗ trợ</a>. Bằng cách thêm thư viện này
+vào ứng dụng của mình, bạn có thể sử dụng {@link android.support.v4.app.DialogFragment} và nhiều loại
+API khác trên các thiết bị chạy Android 1.6 hoặc cao hơn. Nếu phiên bản tối thiểu mà ứng dụng của bạn hỗ trợ
+là API mức 11 hoặc cao hơn, khi đó bạn có thể sử dụng phiên bản khuôn khổ của {@link
+android.app.DialogFragment}, nhưng hãy chú ý rằng các liên kết trong tài liệu này dành cho các API
+thư viện hỗ trợ. Khi sử dụng thư viện hỗ trợ,
+hãy nhớ rằng bạn nhập lớp <code>android.support.v4.app.DialogFragment</code>
+chứ <em>không phải</em> <code>android.app.DialogFragment</code>.</p>
+
+
+<h2 id="DialogFragment">Tạo một Phân đoạn Hộp thoại</h2>
+
+<p>Bạn có thể hoàn thành nhiều loại thiết kế hộp thoại&mdash;bao gồm
+bố trí tùy chỉnh và những bố trí được mô tả trong hướng dẫn thiết kế <a href="{@docRoot}design/building-blocks/dialogs.html">Hộp thoại</a>
+&mdash;bằng cách mở rộng
+{@link android.support.v4.app.DialogFragment} và tạo một {@link android.app.AlertDialog}
+trong phương pháp gọi lại {@link android.support.v4.app.DialogFragment#onCreateDialog
+onCreateDialog()}.</p>
+
+<p>Ví dụ, sau đây là một {@link android.app.AlertDialog} cơ bản được quản lý bên trong
+một {@link android.support.v4.app.DialogFragment}:</p>
+
+<pre>
+public class FireMissilesDialogFragment extends DialogFragment {
+ &#64;Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ // Use the Builder class for convenient dialog construction
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ builder.setMessage(R.string.dialog_fire_missiles)
+ .setPositiveButton(R.string.fire, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ // FIRE ZE MISSILES!
+ }
+ })
+ .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ // User cancelled the dialog
+ }
+ });
+ // Create the AlertDialog object and return it
+ return builder.create();
+ }
+}
+</pre>
+
+<div class="figure" style="width:290px;margin:0 0 0 20px">
+<img src="{@docRoot}images/ui/dialog_buttons.png" alt="" />
+<p class="img-caption"><strong>Hình 1.</strong>
+Hộp thoại với một thông báo và hai nút hành động.</p>
+</div>
+
+<p>Lúc này, khi bạn tạo một thực thể thuộc lớp này và gọi {@link
+android.support.v4.app.DialogFragment#show show()} trên đối tượng đó, hộp thoại sẽ xuất hiện
+như minh họa trong hình 1.</p>
+
+<p>Phần tiếp theo mô tả thêm về việc sử dụng các API {@link android.app.AlertDialog.Builder}
+để tạo hộp thoại.</p>
+
+<p>Tùy vào độ phức tạp của hộp thoại của bạn, bạn có thể triển khai nhiều loại phương pháp gọi lại khác
+trong {@link android.support.v4.app.DialogFragment}, bao gồm tất cả
+<a href="{@docRoot}guide/components/fragments.html#Lifecycle">phương pháp vòng đời phân đoạn</a> cơ bản.
+
+
+
+
+
+<h2 id="AlertDialog">Xây dựng một Hộp thoại Cảnh báo</h2>
+
+
+<p>Lớp {@link android.app.AlertDialog} cho phép bạn xây dựng nhiều loại thiết kế hộp thoại và
+thường là lớp hộp thoại duy nhất mà bạn sẽ cần.
+Như được minh họa trong hình 2, có ba vùng trên một hộp thoại cảnh báo:</p>
+
+<div class="figure" style="width:311px;margin-top:0">
+<img src="{@docRoot}images/ui/dialogs_regions.png" alt="" style="margin-bottom:0" />
+<p class="img-caption"><strong>Hình 2.</strong> Bố trí của một hộp thoại.</p>
+</div>
+
+<ol>
+<li><b>Tiêu đề</b>
+ <p>Tiêu đề không bắt buộc và chỉ nên được sử dụng khi vùng nội dung
+ bị chiếm bởi một thông báo chi tiết, một danh sách, hay một bố trí tùy chỉnh. Nếu bạn cần nêu
+ một thông báo hoặc câu hỏi đơn giản (chẳng hạn như hộp thoại trong hình 1), bạn không cần tiêu đề.</li>
+<li><b>Vùng nội dung</b>
+ <p>Vùng này có thể hiển thị một thông báo, danh sách, hay bố trí tùy chỉnh khác.</p></li>
+<li><b>Nút hành động</b>
+ <p>Sẽ không có quá ba nút hành động trong một hộp thoại.</p></li>
+</ol>
+
+<p>Lớp {@link android.app.AlertDialog.Builder}
+cung cấp các API cho phép bạn tạo một {@link android.app.AlertDialog}
+với những kiểu nội dung này, bao gồm một bố trí tùy chỉnh.</p>
+
+<p>Để xây dựng một {@link android.app.AlertDialog}:</p>
+
+<pre>
+<b>// 1. Instantiate an {@link android.app.AlertDialog.Builder} with its constructor</b>
+AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+
+<b>// 2. Chain together various setter methods to set the dialog characteristics</b>
+builder.setMessage(R.string.dialog_message)
+ .setTitle(R.string.dialog_title);
+
+<b>// 3. Get the {@link android.app.AlertDialog} from {@link android.app.AlertDialog.Builder#create()}</b>
+AlertDialog dialog = builder.create();
+</pre>
+
+<p>Các chủ đề sau cho biết cách định nghĩa các thuộc tính hộp thoại khác nhau bằng cách
+sử dụng lớp {@link android.app.AlertDialog.Builder}.</p>
+
+
+
+
+<h3 id="AddingButtons">Thêm nút</h3>
+
+<p>Để thêm các nút hành động như trong hình 2,
+hãy gọi các phương pháp {@link android.app.AlertDialog.Builder#setPositiveButton setPositiveButton()} và
+{@link android.app.AlertDialog.Builder#setNegativeButton setNegativeButton()}:</p>
+
+<pre style="clear:right">
+AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+// Add the buttons
+builder.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ // User clicked OK button
+ }
+ });
+builder.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ // User cancelled the dialog
+ }
+ });
+// Set other dialog properties
+...
+
+// Create the AlertDialog
+AlertDialog dialog = builder.create();
+</pre>
+
+<p>Các phương pháp <code>set...Button()</code> yêu cầu một tiêu đề cho nút (được cung cấp
+bởi một <a href="{@docRoot}guide/topics/resources/string-resource.html">tài nguyên xâu</a>) và một
+{@link android.content.DialogInterface.OnClickListener} có chức năng định nghĩa hành động sẽ tiến hành
+khi người dùng nhấn nút.</p>
+
+<p>Có ba nút hành động khác nhau mà bạn có thể thêm:</p>
+<dl>
+ <dt>Tích cực</dt>
+ <dd>Bạn nên sử dụng nút này để chấp nhận và tiếp tục với hành động (hành động "OK").</dd>
+ <dt>Tiêu cực</dt>
+ <dd>Bạn nên sử dụng nút này để hủy bỏ hành động.</dd>
+ <dt>Trung lập</dt>
+ <dd>Bạn nên sử dụng nút này khi người dùng có thể không muốn tiếp tục với hành động,
+ nhưng không hẳn muốn hủy bỏ. Nó nằm ở giữa nút
+ tích cực và tiêu cực. Ví dụ, hành động có thể là "Nhắc tôi sau."</dd>
+</dl>
+
+<p>Bạn chỉ có thể thêm một nút mỗi loại vào một {@link
+android.app.AlertDialog}. Nghĩa là, bạn không thể có nhiều hơn một nút "tích cực".</p>
+
+
+
+<div class="figure" style="width:290px;margin:0 0 0 40px">
+<img src="{@docRoot}images/ui/dialog_list.png" alt="" />
+<p class="img-caption"><strong>Hình 3.</strong>
+Hộp thoại có tiêu đề và danh sách.</p>
+</div>
+
+<h3 id="AddingAList">Thêm một danh sách</h3>
+
+<p>Có ba loại danh sách có sẵn với các API {@link android.app.AlertDialog}:</p>
+<ul>
+<li>Danh sách một lựa chọn truyền thống</li>
+<li>Danh sách một lựa chọn cố định (nút chọn một)</li>
+<li>Danh sách nhiều lựa chọn cố định (hộp kiểm)</li>
+</ul>
+
+<p>Để tạo danh sách một lựa chọn như danh sách trong hình 3,
+hãy sử dụng phương pháp {@link android.app.AlertDialog.Builder#setItems setItems()}:</p>
+
+<pre style="clear:right">
+&#64;Override
+public Dialog onCreateDialog(Bundle savedInstanceState) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ builder.setTitle(R.string.pick_color)
+ .setItems(R.array.colors_array, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int which) {
+ // The 'which' argument contains the index position
+ // of the selected item
+ }
+ });
+ return builder.create();
+}
+</pre>
+
+<p>Vì danh sách xuất hiện trong vùng nội dung của hộp thoại,
+hộp thoại không thể hiển thị cả thông báo và danh sách và bạn nên đặt một tiêu đề cho hộp thoại
+bằng {@link android.app.AlertDialog.Builder#setTitle setTitle()}.
+Để chỉ định các mục cho danh sách, hãy gọi {@link
+android.app.AlertDialog.Builder#setItems setItems()}, chuyển một mảng.
+Hoặc, bạn có thể chỉ định một danh sách bằng cách sử dụng {@link
+android.app.AlertDialog.Builder#setAdapter setAdapter()}. Điều này cho phép bạn hỗ trợ danh sách
+bằng dữ liệu động (chẳng hạn như từ một cơ sở dữ liệu) bằng cách sử dụng {@link android.widget.ListAdapter}.</p>
+
+<p>Nếu bạn chọn hỗ trợ danh sách của mình bằng một {@link android.widget.ListAdapter},
+hãy luôn sử dụng {@link android.support.v4.content.Loader} sao cho nội dung tải
+không đồng bộ. Điều này được mô tả thêm trong hướng dẫn
+<a href="{@docRoot}guide/topics/ui/declaring-layout.html#AdapterViews">Xây dựng Bố trí
+bằng một Trình điều hợp</a> và <a href="{@docRoot}guide/components/loaders.html">Trình tải</a>
+.</p>
+
+<p class="note"><strong>Lưu ý:</strong> Theo mặc định, chạm vào một mục danh sách sẽ bỏ hộp thoại,
+trừ khi bạn đang sử dụng một trong các danh sách lựa chọn cố định sau.</p>
+
+<div class="figure" style="width:290px;margin:-30px 0 0 40px">
+<img src="{@docRoot}images/ui/dialog_checkboxes.png" />
+<p class="img-caption"><strong>Hình 4.</strong>
+Danh sách nhiều mục lựa chọn.</p>
+</div>
+
+
+<h4 id="Checkboxes">Thêm một danh sách nhiều lựa chọn hoặc một lựa chọn cố định</h4>
+
+<p>Để thêm một danh sách nhiều lựa chọn (hộp kiểm) hoặc
+một lựa chọn (nút chọn một), hãy sử dụng các phương pháp
+{@link android.app.AlertDialog.Builder#setMultiChoiceItems(Cursor,String,String,
+DialogInterface.OnMultiChoiceClickListener) setMultiChoiceItems()} hoặc
+{@link android.app.AlertDialog.Builder#setSingleChoiceItems(int,int,DialogInterface.OnClickListener)
+setSingleChoiceItems()} tương ứng.</p>
+
+<p>Ví dụ, sau đây là cách bạn có thể tạo một danh sách nhiều lựa chọn như
+danh sách được minh họa trong hình 4 giúp lưu các mục
+được chọn trong một {@link java.util.ArrayList}:</p>
+
+<pre style="clear:right">
+&#64;Override
+public Dialog onCreateDialog(Bundle savedInstanceState) {
+ mSelectedItems = new ArrayList(); // Where we track the selected items
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ // Set the dialog title
+ builder.setTitle(R.string.pick_toppings)
+ // Specify the list array, the items to be selected by default (null for none),
+ // and the listener through which to receive callbacks when items are selected
+ .setMultiChoiceItems(R.array.toppings, null,
+ new DialogInterface.OnMultiChoiceClickListener() {
+ &#64;Override
+ public void onClick(DialogInterface dialog, int which,
+ boolean isChecked) {
+ if (isChecked) {
+ // If the user checked the item, add it to the selected items
+ mSelectedItems.add(which);
+ } else if (mSelectedItems.contains(which)) {
+ // Else, if the item is already in the array, remove it
+ mSelectedItems.remove(Integer.valueOf(which));
+ }
+ }
+ })
+ // Set the action buttons
+ .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
+ &#64;Override
+ public void onClick(DialogInterface dialog, int id) {
+ // User clicked OK, so save the mSelectedItems results somewhere
+ // or return them to the component that opened the dialog
+ ...
+ }
+ })
+ .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
+ &#64;Override
+ public void onClick(DialogInterface dialog, int id) {
+ ...
+ }
+ });
+
+ return builder.create();
+}
+</pre>
+
+<p>Mặc dù cả danh sách truyền thống và danh sách có nút chọn một
+đều cung cấp hành động "một lựa chọn", bạn nên sử dụng {@link
+android.app.AlertDialog.Builder#setSingleChoiceItems(int,int,DialogInterface.OnClickListener)
+setSingleChoiceItems()} nếu bạn muốn cố định lựa chọn của người dùng.
+Cụ thể, nếu việc mở hộp thoại lại sau này báo hiệu lựa chọn hiện tại của người dùng, khi đó
+bạn hãy tạo một danh sách với các nút chọn một.</p>
+
+
+
+
+
+<h3 id="CustomLayout">Tạo một Bố trí Tùy chỉnh</h3>
+
+<div class="figure" style="width:290px;margin:-30px 0 0 40px">
+<img src="{@docRoot}images/ui/dialog_custom.png" alt="" />
+<p class="img-caption"><strong>Hình 5.</strong> Một bố trí hộp thoại tùy chỉnh.</p>
+</div>
+
+<p>Nếu bạn muốn một bố trí tùy chỉnh trong một hộp thoại, hãy tạo một bố trí và thêm nó vào một
+{@link android.app.AlertDialog} bằng cách gọi {@link
+android.app.AlertDialog.Builder#setView setView()} trên đối tượng {@link
+android.app.AlertDialog.Builder} của bạn.</p>
+
+<p>Theo mặc định, bố trí tùy chỉnh sẽ lấp đầy cửa sổ hộp thoại, nhưng bạn vẫn có thể
+sử dụng các phương pháp {@link android.app.AlertDialog.Builder} để thêm nút và tiêu đề.</p>
+
+<p>Ví dụ, sau đây là tệp bố trí cho hộp thoại trong Hình 5:</p>
+
+<p style="clear:right" class="code-caption">res/layout/dialog_signin.xml</p>
+<pre>
+&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:orientation="vertical"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content">
+ &lt;ImageView
+ android:src="@drawable/header_logo"
+ android:layout_width="match_parent"
+ android:layout_height="64dp"
+ android:scaleType="center"
+ android:background="#FFFFBB33"
+ android:contentDescription="@string/app_name" />
+ &lt;EditText
+ android:id="@+id/username"
+ android:inputType="textEmailAddress"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="16dp"
+ android:layout_marginLeft="4dp"
+ android:layout_marginRight="4dp"
+ android:layout_marginBottom="4dp"
+ android:hint="@string/username" />
+ &lt;EditText
+ android:id="@+id/password"
+ android:inputType="textPassword"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="4dp"
+ android:layout_marginLeft="4dp"
+ android:layout_marginRight="4dp"
+ android:layout_marginBottom="16dp"
+ android:fontFamily="sans-serif"
+ android:hint="@string/password"/>
+&lt;/LinearLayout>
+</pre>
+
+<p class="note"><strong>Mẹo:</strong> Theo mặc định, khi bạn đặt một phần tử {@link android.widget.EditText}
+để sử dụng kiểu đầu vào {@code "textPassword"}, họ phông được đặt thành đơn cách, vì thế
+bạn nên đổi họ phông thành {@code "sans-serif"} sao cho cả hai trường văn bản đều sử dụng
+một kiểu phông thống nhất.</p>
+
+<p>Để bung bố trí ra trong {@link android.support.v4.app.DialogFragment} của bạn,
+hãy lấy một {@link android.view.LayoutInflater} với
+{@link android.app.Activity#getLayoutInflater()} và gọi
+{@link android.view.LayoutInflater#inflate inflate()}, trong đó tham số đầu tiên
+là ID tài nguyên bố trí và tham số thứ hai là một dạng xem mẹ cho bố trí.
+Khi đó, bạn có thể gọi {@link android.app.AlertDialog#setView setView()}
+để đặt bố trí vào một hộp thoại.</p>
+
+<pre>
+&#64;Override
+public Dialog onCreateDialog(Bundle savedInstanceState) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ // Get the layout inflater
+ LayoutInflater inflater = getActivity().getLayoutInflater();
+
+ // Inflate and set the layout for the dialog
+ // Pass null as the parent view because its going in the dialog layout
+ builder.setView(inflater.inflate(R.layout.dialog_signin, null))
+ // Add action buttons
+ .setPositiveButton(R.string.signin, new DialogInterface.OnClickListener() {
+ &#64;Override
+ public void onClick(DialogInterface dialog, int id) {
+ // sign in the user ...
+ }
+ })
+ .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ LoginDialogFragment.this.getDialog().cancel();
+ }
+ });
+ return builder.create();
+}
+</pre>
+
+<div class="note">
+<p><strong>Mẹo:</strong> Nếu bạn muốn một hộp thoại tùy chỉnh,
+thay vào đó, bạn có thể hiển thị {@link android.app.Activity} như là một hộp thoại
+thay vì sử dụng các API {@link android.app.Dialog}. Chỉ cần tạo một hoạt động và đặt chủ đề của nó thành
+{@link android.R.style#Theme_Holo_Dialog Theme.Holo.Dialog}
+trong phần tử bản kê khai <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code
+&lt;activity&gt;}</a>:</p>
+
+<pre>
+&lt;activity android:theme="&#64;android:style/Theme.Holo.Dialog" >
+</pre>
+<p>Vậy là xong. Lúc này, hoạt động sẽ hiển thị một cửa sổ hộp thoại thay vì toàn màn hình.</p>
+</div>
+
+
+
+<h2 id="PassingEvents">Chuyển Sự kiện lại Máy chủ của Hộp thoại</h2>
+
+<p>Khi người dùng chạm vào một trong các nút hành động của hộp thoại hoặc chọn một mục từ danh sách của hộp thoại,
+{@link android.support.v4.app.DialogFragment} của bạn có thể tự thực hiện hành động
+cần thiết, nhưng thường thì bạn sẽ muốn chuyển sự kiện tới hoạt động hoặc phân đoạn
+đã mở hộp thoại. Để làm điều này, hãy định nghĩa một giao diện bằng một phương pháp cho mỗi loại sự kiện nhấp.
+Sau đó, triển khai giao diện đó trong thành phần chủ mà sẽ
+nhận sự kiện hành động từ hộp thoại.</p>
+
+<p>Ví dụ, sau đây là một {@link android.support.v4.app.DialogFragment} có chức năng định nghĩa một
+giao diện mà thông qua đó, nó sẽ chuyển các sự kiện lại cho hoạt động chủ:</p>
+
+<pre>
+public class NoticeDialogFragment extends DialogFragment {
+
+ /* The activity that creates an instance of this dialog fragment must
+ * implement this interface in order to receive event callbacks.
+ * Each method passes the DialogFragment in case the host needs to query it. */
+ public interface NoticeDialogListener {
+ public void onDialogPositiveClick(DialogFragment dialog);
+ public void onDialogNegativeClick(DialogFragment dialog);
+ }
+
+ // Use this instance of the interface to deliver action events
+ NoticeDialogListener mListener;
+
+ // Override the Fragment.onAttach() method to instantiate the NoticeDialogListener
+ &#64;Override
+ public void onAttach(Activity activity) {
+ super.onAttach(activity);
+ // Verify that the host activity implements the callback interface
+ try {
+ // Instantiate the NoticeDialogListener so we can send events to the host
+ mListener = (NoticeDialogListener) activity;
+ } catch (ClassCastException e) {
+ // The activity doesn't implement the interface, throw exception
+ throw new ClassCastException(activity.toString()
+ + " must implement NoticeDialogListener");
+ }
+ }
+ ...
+}
+</pre>
+
+<p>Hoạt động lưu giữ hộp thoại sẽ tạo một thực thể của hộp thoại
+bằng hàm dựng của phân đoạn hộp thoại và nhận sự kiện
+của hộp thoại thông qua triển khai giao diện {@code NoticeDialogListener}:</p>
+
+<pre>
+public class MainActivity extends FragmentActivity
+ implements NoticeDialogFragment.NoticeDialogListener{
+ ...
+
+ public void showNoticeDialog() {
+ // Create an instance of the dialog fragment and show it
+ DialogFragment dialog = new NoticeDialogFragment();
+ dialog.show(getSupportFragmentManager(), "NoticeDialogFragment");
+ }
+
+ // The dialog fragment receives a reference to this Activity through the
+ // Fragment.onAttach() callback, which it uses to call the following methods
+ // defined by the NoticeDialogFragment.NoticeDialogListener interface
+ &#64;Override
+ public void onDialogPositiveClick(DialogFragment dialog) {
+ // User touched the dialog's positive button
+ ...
+ }
+
+ &#64;Override
+ public void onDialogNegativeClick(DialogFragment dialog) {
+ // User touched the dialog's negative button
+ ...
+ }
+}
+</pre>
+
+<p>Vì hoạt động chủ sẽ triển khai {@code NoticeDialogListener}&mdash;, được
+thực thi bởi phương pháp gọi lại {@link android.support.v4.app.Fragment#onAttach onAttach()}
+minh họa bên trên,&mdash;phân đoạn hộp thoại có thể sử dụng các phương pháp gọi lại
+giao diện để chuyển các sự kiện nhấp cho hoạt động:</p>
+
+<pre>
+public class NoticeDialogFragment extends DialogFragment {
+ ...
+
+ &#64;Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ // Build the dialog and set up the button click handlers
+ AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
+ builder.setMessage(R.string.dialog_fire_missiles)
+ .setPositiveButton(R.string.fire, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ // Send the positive button event back to the host activity
+ mListener.onDialogPositiveClick(NoticeDialogFragment.this);
+ }
+ })
+ .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
+ public void onClick(DialogInterface dialog, int id) {
+ // Send the negative button event back to the host activity
+ mListener.onDialogNegativeClick(NoticeDialogFragment.this);
+ }
+ });
+ return builder.create();
+ }
+}
+</pre>
+
+
+
+<h2 id="ShowingADialog">Hiển thị một Hộp thoại</h2>
+
+<p>Khi bạn muốn hiển thị hộp thoại của mình, hãy tạo một thực thể {@link
+android.support.v4.app.DialogFragment} của bạn và gọi {@link android.support.v4.app.DialogFragment#show
+show()}, chuyển {@link android.support.v4.app.FragmentManager} và một tên tag
+cho phân đoạn hộp thoại.</p>
+
+<p>Bạn có thể nhận được {@link android.support.v4.app.FragmentManager} bằng cách gọi
+{@link android.support.v4.app.FragmentActivity#getSupportFragmentManager()} từ
+{@link android.support.v4.app.FragmentActivity} hoặc {@link
+android.support.v4.app.Fragment#getFragmentManager()} từ một {@link
+android.support.v4.app.Fragment}. Ví dụ:</p>
+
+<pre>
+public void confirmFireMissiles() {
+ DialogFragment newFragment = new FireMissilesDialogFragment();
+ newFragment.show(getSupportFragmentManager(), "missiles");
+}
+</pre>
+
+<p>Tham đối thứ hai, {@code "missiles"}, là một tên tag duy nhất mà hệ thống sử dụng để lưu
+và khôi phục trạng thái của phân đoạn khi cần thiết. Tag cũng cho phép bạn nhận một điều khiển (handle) cho
+phân đoạn bằng cách gọi {@link android.support.v4.app.FragmentManager#findFragmentByTag
+findFragmentByTag()}.</p>
+
+
+
+
+<h2 id="FullscreenDialog">Hiển thị một Hộp thoại Toàn màn hình hoặc dạng một Phân đoạn Nhúng</h2>
+
+<p>Bạn có thể có một thiết kế UI mà trong đó bạn muốn một phần UI xuất hiện như một hộp thoại trong một số
+tình huống, nhưng ở dưới dạng toàn màn hình hoặc phân đoạn nhúng trong trường hợp khác (có thể phụ thuộc
+vào thiết bị là màn hình lớn hay nhỏ). Lớp {@link android.support.v4.app.DialogFragment}
+cung cấp cho bạn sự linh hoạt này vì nó vẫn có thể đóng vai trò như một {@link
+android.support.v4.app.Fragment} nhúng được.</p>
+
+<p>Tuy nhiên, bạn không thể sử dụng {@link android.app.AlertDialog.Builder AlertDialog.Builder}
+hay các đối tượng {@link android.app.Dialog} khác để xây dựng hộp thoại trong trường hợp này. Nếu
+bạn muốn {@link android.support.v4.app.DialogFragment} có thể
+nhúng được, bạn phải định nghĩa UI của hộp thoại trong một bố trí, rồi tải bố trí đó trong lệnh gọi lại
+{@link android.support.v4.app.DialogFragment#onCreateView
+onCreateView()}.</p>
+
+<p>Sau đây là một ví dụ {@link android.support.v4.app.DialogFragment} có thể xuất hiện như một
+hộp thoại hoặc phân đoạn nhúng được (sử dụng một bố trí có tên gọi <code>purchase_items.xml</code>):</p>
+
+<pre>
+public class CustomDialogFragment extends DialogFragment {
+ /** The system calls this to get the DialogFragment's layout, regardless
+ of whether it's being displayed as a dialog or an embedded fragment. */
+ &#64;Override
+ public View onCreateView(LayoutInflater inflater, ViewGroup container,
+ Bundle savedInstanceState) {
+ // Inflate the layout to use as dialog or embedded fragment
+ return inflater.inflate(R.layout.purchase_items, container, false);
+ }
+
+ /** The system calls this only when creating the layout in a dialog. */
+ &#64;Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ // The only reason you might override this method when using onCreateView() is
+ // to modify any dialog characteristics. For example, the dialog includes a
+ // title by default, but your custom layout might not need it. So here you can
+ // remove the dialog title, but you must call the superclass to get the Dialog.
+ Dialog dialog = super.onCreateDialog(savedInstanceState);
+ dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
+ return dialog;
+ }
+}
+</pre>
+
+<p>Và sau đây là một số mã quyết định xem hiển thị phân đoạn như một hộp thoại
+hay UI toàn màn hình, dựa vào kích cỡ màn hình:</p>
+
+<pre>
+public void showDialog() {
+ FragmentManager fragmentManager = getSupportFragmentManager();
+ CustomDialogFragment newFragment = new CustomDialogFragment();
+
+ if (mIsLargeLayout) {
+ // The device is using a large layout, so show the fragment as a dialog
+ newFragment.show(fragmentManager, "dialog");
+ } else {
+ // The device is smaller, so show the fragment fullscreen
+ FragmentTransaction transaction = fragmentManager.beginTransaction();
+ // For a little polish, specify a transition animation
+ transaction.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_OPEN);
+ // To make it fullscreen, use the 'content' root view as the container
+ // for the fragment, which is always the root view for the activity
+ transaction.add(android.R.id.content, newFragment)
+ .addToBackStack(null).commit();
+ }
+}
+</pre>
+
+<p>Để biết thêm thông tin về việc thực hiện các giao tác phân đoạn, hãy xem hướng dẫn
+<a href="{@docRoot}guide/components/fragments.html">Phân đoạn</a>.</p>
+
+<p>Trong ví dụ này, boolean <code>mIsLargeLayout</code> chỉ định liệu thiết bị hiện tại
+có nên sử dụng thiết kế bố trí lớn của ứng dụng (và vì thế, nó hiển thị phân đoạn này như một hộp thoại thay vì
+toàn màn hình) hay không. Cách tốt nhất để đặt loại boolean này đó là khai báo một
+<a href="{@docRoot}guide/topics/resources/more-resources.html#Bool">giá trị tài nguyên bool</a>
+bằng một giá trị <a href="{@docRoot}guide/topics/resources/providing-resources.html#AlternativeResources">tài nguyên thay thế</a> cho các kích cỡ màn hình khác nhau. Ví dụ, sau đây là hai
+phiên bản của tài nguyên bool cho các kích cỡ màn hình khác nhau:</p>
+
+<p class="code-caption">res/values/bools.xml</p>
+<pre>
+&lt;!-- Default boolean values -->
+&lt;resources>
+ &lt;bool name="large_layout">false&lt;/bool>
+&lt;/resources>
+</pre>
+
+<p class="code-caption">res/values-large/bools.xml</p>
+<pre>
+&lt;!-- Large screen boolean values -->
+&lt;resources>
+ &lt;bool name="large_layout">true&lt;/bool>
+&lt;/resources>
+</pre>
+
+<p>Khi đó, bạn có thể khởi tạo giá trị {@code mIsLargeLayout} trong phương pháp
+{@link android.app.Activity#onCreate onCreate()} của hoạt động:</p>
+
+<pre>
+boolean mIsLargeLayout;
+
+&#64;Override
+public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ setContentView(R.layout.activity_main);
+
+ mIsLargeLayout = getResources().getBoolean(R.bool.large_layout);
+}
+</pre>
+
+
+
+<h3 id="ActivityAsDialog">Hiển thị một hoạt động dưới dạng một hộp thoại trên màn hình lớn</h3>
+
+<p>Thay vì hiển thị một hộp thoại thành UI toàn màn hình trên các màn hình nhỏ, bạn có thể đạt được
+kết quả tương tự bằng cách hiển thị một {@link android.app.Activity} thành một hộp thoại trên
+màn hình lớn. Phương pháp mà bạn chọn phụ thuộc vào thiết kế ứng dụng của bạn, nhưng
+việc hiển thị một hoạt động thành một hộp thoại thường có ích khi ứng dụng của bạn đã được thiết kế cho màn hình
+nhỏ và bạn muốn cải thiện trải nghiệm trên máy tính bảng bằng cách hiển thị một hoạt động có vòng đời ngắn
+thành một hộp thoại.</p>
+
+<p>Để hiển thị một hoạt động thành một hộp thoại chỉ khi trên màn hình lớn,
+hãy áp dụng chủ đề {@link android.R.style#Theme_Holo_DialogWhenLarge Theme.Holo.DialogWhenLarge}
+cho phần tử bản kê khai <a href="{@docRoot}guide/topics/manifest/activity-element.html">{@code
+&lt;activity&gt;}</a>:</p>
+
+<pre>
+&lt;activity android:theme="&#64;android:style/Theme.Holo.DialogWhenLarge" >
+</pre>
+
+<p>Để biết thêm thông tin về việc tạo kiểu cho các hoạt động của bạn bằng chủ đề, hãy xem hướng dẫn <a href="{@docRoot}guide/topics/ui/themes.html">Kiểu và Chủ đề</a>.</p>
+
+
+
+<h2 id="DismissingADialog">Bỏ một Hộp thoại</h2>
+
+<p>Khi người dùng chạm vào bất kỳ nút hành động nào được tạo bằng
+{@link android.app.AlertDialog.Builder}, hệ thống sẽ bỏ hộp thoại cho bạn.</p>
+
+<p>Hệ thống cũng bỏ hộp thoại khi người dùng chạm vào một mục trong một danh sách hộp thoại, trừ
+khi danh sách sử dụng nút chọn một hoặc hộp kiểm. Nếu không, bạn có thể bỏ thủ công hộp thoại của mình
+bằng cách gọi {@link android.support.v4.app.DialogFragment#dismiss()} trên {@link
+android.support.v4.app.DialogFragment} của bạn.</p>
+
+<p>Trong trường hợp bạn cần thực hiện các
+hành động nhất định khi hộp thoại biến mất, bạn có thể triển khai phương pháp {@link
+android.support.v4.app.DialogFragment#onDismiss onDismiss()} trong {@link
+android.support.v4.app.DialogFragment} của mình.</p>
+
+<p>Bạn cũng có thể <em>hủy bỏ</em> một hộp thoại. Đây là một sự kiện đặc biệt chỉ báo người dùng
+chủ ý rời khỏi hộp thoại mà không hoàn thành tác vụ. Điều này xảy ra nếu người dùng nhấn nút
+<em>Quay lại</em>, chạm vào màn hình ngoài vùng hộp thoại,
+hoặc nếu bạn công khai gọi {@link android.app.Dialog#cancel()} trên {@link
+android.app.Dialog} (chẳng hạn như khi hồi đáp lại một nút "Hủy bỏ" trong hộp thoại).</p>
+
+<p>Như nêu trong ví dụ bên trên, bạn có thể hồi đáp lại sự kiện hủy bỏ này bằng cách triển khai
+{@link android.support.v4.app.DialogFragment#onCancel onCancel()} trong lớp {@link
+android.support.v4.app.DialogFragment} của mình.</p>
+
+<p class="note"><strong>Lưu ý:</strong> Hệ thống sẽ gọi
+{@link android.support.v4.app.DialogFragment#onDismiss onDismiss()} trên mỗi sự kiện mà
+gọi ra lệnh gọi lại {@link android.support.v4.app.DialogFragment#onCancel onCancel()}. Tuy nhiên,
+nếu bạn gọi {@link android.app.Dialog#dismiss Dialog.dismiss()} hoặc {@link
+android.support.v4.app.DialogFragment#dismiss DialogFragment.dismiss()},
+hệ thống sẽ gọi {@link android.support.v4.app.DialogFragment#onDismiss onDismiss()} <em>chứ
+không phải</em> {@link android.support.v4.app.DialogFragment#onCancel onCancel()}. Vì thế, nhìn chung bạn nên
+gọi {@link android.support.v4.app.DialogFragment#dismiss dismiss()} khi người dùng nhấn nút
+<em>tích cực</em> trong hộp thoại của bạn để xóa hộp thoại khỏi dạng xem.</p>
+
+
diff --git a/docs/html-intl/intl/vi/guide/topics/ui/menus.jd b/docs/html-intl/intl/vi/guide/topics/ui/menus.jd
new file mode 100644
index 000000000000..8e9e1c412c5a
--- /dev/null
+++ b/docs/html-intl/intl/vi/guide/topics/ui/menus.jd
@@ -0,0 +1,1031 @@
+page.title=Menu
+parent.title=Giao diện Người dùng
+parent.link=index.html
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+ <h2>Trong tài liệu này</h2>
+<ol>
+ <li><a href="#xml">Định nghĩa một Menu trong XML</a></li>
+ <li><a href="#options-menu">Tạo một Menu Tùy chọn</a>
+ <ol>
+ <li><a href="#RespondingOptionsMenu">Xử lý sự kiện nhấp</a></li>
+ <li><a href="#ChangingTheMenu">Thay đổi các mục menu vào thời gian chạy</a></li>
+ </ol>
+ </li>
+ <li><a href="#context-menu">Tạo một Menu Ngữ cảnh</a>
+ <ol>
+ <li><a href="#FloatingContextMenu">Tạo một menu ngữ cảnh nổi</a></li>
+ <li><a href="#CAB">Sử dụng chế độ hành động theo ngữ cảnh</a></li>
+ </ol>
+ </li>
+ <li><a href="#PopupMenu">Tạo một Menu Bật lên</a>
+ <ol>
+ <li><a href="#PopupEvents">Xử lý sự kiện nhấp</a></li>
+ </ol>
+ </li>
+ <li><a href="#groups">Tạo Nhóm Menu</a>
+ <ol>
+ <li><a href="#checkable">Sử dụng mục menu có thể chọn</a></li>
+ </ol>
+ </li>
+ <li><a href="#intents">Thêm Mục Menu dựa trên Ý định</a>
+ <ol>
+ <li><a href="#AllowingToAdd">Cho phép hoạt động của bạn được thêm vào các menu khác</a></li>
+ </ol>
+ </li>
+</ol>
+
+ <h2>Lớp khóa</h2>
+ <ol>
+ <li>{@link android.view.Menu}</li>
+ <li>{@link android.view.MenuItem}</li>
+ <li>{@link android.view.ContextMenu}</li>
+ <li>{@link android.view.ActionMode}</li>
+ </ol>
+
+ <h2>Xem thêm</h2>
+ <ol>
+ <li><a href="{@docRoot}guide/topics/ui/actionbar.html">Thanh Hành động</a></li>
+ <li><a href="{@docRoot}guide/topics/resources/menu-resource.html">Tài nguyên Menu</a></li>
+ <li><a href="http://android-developers.blogspot.com/2012/01/say-goodbye-to-menu-button.html">Nói
+Tạm biệt với Nút Menu</a></li>
+ </ol>
+</div>
+</div>
+
+<p>Menu là một thành phần giao diện người dùng phổ biến trong nhiều loại ứng dụng. Để cung cấp một
+trải nghiệm người dùng quen thuộc và nhất quán, bạn nên sử dụng các API {@link android.view.Menu} để trình bày
+hành động người dùng và các tùy chọn khác trong hoạt động của mình.</p>
+
+<p>Bắt đầu với Android 3.0 (API mức 11), các thiết bị dựa trên nền tảng Android không còn phải
+cung cấp một nút <em>Menu</em> chuyên dụng nữa. Với sự thay đổi này, các ứng dụng Android cần tránh khỏi
+sự phụ thuộc vào bảng điều khiển menu 6 mục truyền thống này mà thay vào đó cung cấp một thanh hành động để trình bày
+các hành động người dùng thông dụng.</p>
+
+<p>Mặc dù thiết kế và trải nghiệm người dùng đối với một số mục menu đã thay đổi, ngữ nghĩa để định nghĩa
+tập hợp hành động và tùy chọn thì vẫn dựa trên các API {@link android.view.Menu}. Hướng dẫn
+này trình bày cách tạo ba loại menu hay trình bày hành động cơ bản trên tất cả
+phiên bản Android:</p>
+
+<dl>
+ <dt><strong>Menu tùy chọn và thanh hành động</strong></dt>
+ <dd><a href="#options-menu">Menu tùy chọn</a> là tập hợp các mục menu cơ bản cho một
+hoạt động. Đó là nơi bạn nên đặt các hành động có tác động chung tới ứng dụng, chẳng hạn như
+"Tìm kiếm," "Soạn e-mail" và "Cài đặt."
+ <p>Nếu bạn đang phát triển cho phiên bản Android 2.3 hoặc thấp hơn, người dùng có thể
+hiện bảng điều khiển menu tùy chọn bằng cách nhấn nút <em>Menu</em>.</p>
+ <p>Trên phiên bản Android 3.0 trở lên, các mục từ menu tùy chọn được trình bày bởi <a href="{@docRoot}guide/topics/ui/actionbar.html">thanh hành động</a>, là sự kết hợp giữa các mục hành động
+trên màn hình và các tùy chọn tràn. Bắt đầu với phiên bản Android 3.0, nút <em>Menu</em> bị bỏ đi (một số
+thiết bị
+không có), vì thế bạn nên chuyển sang sử dụng thanh hành động để cho phép truy cập vào hành động và
+các tùy chọn khác.</p>
+ <p>Xem phần về <a href="#options-menu">Tạo một Menu Tùy chọn</a>.</p>
+ </dd>
+
+ <dt><strong>Menu ngữ cảnh và chế độ hành động theo ngữ cảnh</strong></dt>
+
+ <dd>Menu ngữ cảnh là một <a href="#FloatingContextMenu">menu nổi</a> xuất hiện khi
+người dùng thực hiện nhấp giữ trên một phần tử. Nó cung cấp các hành động ảnh hưởng tới nội dung hoặc
+khung ngữ cảnh được chọn.
+ <p>Khi phát triển cho phiên bản Android 3.0 trở lên, thay vào đó, bạn nên sử dụng <a href="#CAB">chế độ hành động theo ngữ cảnh</a> để kích hoạt các hành động trên nội dung được chọn. Chế độ này hiển thị
+các mục hành động ảnh hưởng tới nội dung được chọn trong một thanh ở trên cùng của màn hình và cho phép người dùng
+chọn nhiều mục.</p>
+ <p>Xem phần nói về <a href="#context-menu">Tạo Menu Ngữ cảnh</a>.</p>
+</dd>
+
+ <dt><strong>Menu bật lên</strong></dt>
+ <dd>Menu bật lên sẽ hiển thị danh sách các mục trong một danh sách thẳng đứng được neo vào dạng xem
+đã gọi ra menu. Nên cung cấp một phần tràn gồm các hành động liên quan tới nội dung cụ thể hoặc
+nhằm cung cấp các tùy chọn cho phần thứ hai của một lệnh. Các hành động trong một menu bật lên
+<strong>không</strong> nên trực tiếp ảnh hưởng tới nội dung tương ứng&mdash;đó là việc của hành động ngữ cảnh
+. Thay vào đó, menu bật lên áp dụng cho các hành động mở rộng liên quan tới các vùng nội dung trong hoạt động
+của bạn.
+ <p>Xem phần về <a href="#PopupMenu">Tạo một Menu Bật lên</a>.</p>
+</dd>
+</dl>
+
+
+
+<h2 id="xml">Định nghĩa một Menu trong XML</h2>
+
+<p>Đối với tất cả các loại menu, Android cung cấp một định dạng XML chuẩn để định nghĩa các mục menu.
+Thay vì xây dựng một menu trong mã của hoạt động của bạn, bạn nên định nghĩa một menu và tất cả các mục của nó trong một
+<a href="{@docRoot}guide/topics/resources/menu-resource.html">tài nguyên menu</a> XML. Khi đó, bạn có thể
+bung tài nguyên menu (tải nó như một đối tượng {@link android.view.Menu}) trong hoạt động hoặc
+phân đoạn của mình.</p>
+
+<p>Sử dụng một tài nguyên menu là một cách làm hay vì một vài lý do:</p>
+<ul>
+ <li>Nó dễ trực quan hóa cấu trúc menu trong XML hơn.</li>
+ <li>Nó tách riêng nội dung cho menu với mã hành vi của ứng dụng của bạn.</li>
+ <li>Nó cho phép bạn tạo các cấu hình menu phái sinh cho các phiên bản nền tảng,
+kích cỡ màn hình khác nhau và các cấu hình khác bằng cách tận dụng khuôn khổ <a href="{@docRoot}guide/topics/resources/index.html">tài nguyên ứng dụng</a>.</li>
+</ul>
+
+<p>Để định nghĩa menu, hãy tạo một tệp XML bên trong thư mục <code>res/menu/</code>
+dự án của bạn và xây dựng menu với các phần tử sau:</p>
+<dl>
+ <dt><code>&lt;menu></code></dt>
+ <dd>Định nghĩa một {@link android.view.Menu}, đó là một bộ chứa các mục menu. Phần tử
+<code>&lt;menu></code> phải là một nút gốc cho tệp và có thể giữ một hoặc nhiều phần tử
+<code>&lt;item></code> và <code>&lt;group></code>.</dd>
+
+ <dt><code>&lt;item></code></dt>
+ <dd>Tạo một {@link android.view.MenuItem}, nó biểu diễn một mục đơn trong một menu. Phần tử
+này có thể chứa một phần tử <code>&lt;menu></code> được lồng nhau để tạo một menu con.</dd>
+
+ <dt><code>&lt;group></code></dt>
+ <dd>Một bộ chứa tùy chọn, vô hình cho các phần tử {@code &lt;item&gt;}. Nó cho phép bạn
+phân loại các mục menu sao cho chúng chia sẻ các tính chất như trạng thái hiện hoạt và khả năng hiển thị. Để biết thêm
+thông tin, hãy xem phần nói về <a href="#groups">Tạo Nhóm Menu</a>.</dd>
+</dl>
+
+
+<p>Sau đây là một menu ví dụ có tên là <code>game_menu.xml</code>:</p>
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
+&lt;menu xmlns:android="http://schemas.android.com/apk/res/android"&gt;
+ &lt;item android:id="@+id/new_game"
+ android:icon="@drawable/ic_new_game"
+ android:title="@string/new_game"
+ android:showAsAction="ifRoom"/&gt;
+ &lt;item android:id="@+id/help"
+ android:icon="@drawable/ic_help"
+ android:title="@string/help" /&gt;
+&lt;/menu&gt;
+</pre>
+
+<p>Phần tử <code>&lt;item></code> hỗ trợ một vài thuộc tính bạn có thể sử dụng để định nghĩa biểu hiện bên ngoài
+và hành vi của một mục. Các mục trong menu trên bao gồm những thuộc tính sau:</p>
+
+<dl>
+ <dt>{@code android:id}</dt>
+ <dd>Một ID tài nguyên duy nhất đối với mục, nó cho phép ứng dụng có thể nhận ra mục đó
+khi người dùng chọn nó.</dd>
+ <dt>{@code android:icon}</dt>
+ <dd>Một tham chiếu tới một nội dung vẽ được để dùng làm biểu tượng của mục.</dd>
+ <dt>{@code android:title}</dt>
+ <dd>Một tham chiếu tới một xâu để dùng làm tiêu đề của mục.</dd>
+ <dt>{@code android:showAsAction}</dt>
+ <dd>Quy định thời điểm và cách thức mục này nên xuất hiện như một mục hành động trong <a href="{@docRoot}guide/topics/ui/actionbar.html">thanh hành động</a>.</dd>
+</dl>
+
+<p>Đây là những thuộc tính quan trọng nhất bạn nên sử dụng, nhưng còn nhiều thuộc tính sẵn có khác.
+Để biết thông tin về tất cả thuộc tính được hỗ trợ, hãy xem tài liệu <a href="{@docRoot}guide/topics/resources/menu-resource.html">Tài nguyên Menu</a>.</p>
+
+<p>Bạn có thể thêm một menu con vào một mục trong bất kỳ menu nào (ngoại trừ menu con) bằng cách thêm một phần tử {@code &lt;menu&gt;}
+làm con của {@code &lt;item&gt;}. Các menu con thường hữu ích khi ứng dụng của bạn có nhiều
+chức năng mà có thể được tổ chức thành các chủ đề, như các mục trong thanh menu của một ứng dụng PC (Tệp,
+Chỉnh sửa, Dạng xem, v.v.). Ví dụ:</p>
+
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
+&lt;menu xmlns:android="http://schemas.android.com/apk/res/android"&gt;
+ &lt;item android:id="@+id/file"
+ android:title="@string/file" &gt;
+ &lt;!-- "file" submenu --&gt;
+ &lt;menu&gt;
+ &lt;item android:id="@+id/create_new"
+ android:title="@string/create_new" /&gt;
+ &lt;item android:id="@+id/open"
+ android:title="@string/open" /&gt;
+ &lt;/menu&gt;
+ &lt;/item&gt;
+&lt;/menu&gt;
+</pre>
+
+<p>Để sử dụng menu trong hoạt động của mình, bạn cần bung tài nguyên menu (chuyển tài nguyên XML
+thành một đối tượng có thể lập trình) bằng cách sử dụng {@link android.view.MenuInflater#inflate(int,Menu)
+MenuInflater.inflate()}. Trong những phần sau, bạn sẽ biết cách bung một menu đối với mỗi
+loại menu.</p>
+
+
+
+<h2 id="options-menu">Tạo một Menu Tùy chọn</h2>
+
+<div class="figure" style="width:200px;margin:0">
+ <img src="{@docRoot}images/options_menu.png" height="333" alt="" />
+ <p class="img-caption"><strong>Hình 1.</strong> Các menu tùy chọn trong
+Trình duyệt, trên Android 2.3.</p>
+</div>
+
+<p>Menu tùy chọn là nơi bạn nên đưa vào hành động và các tùy chọn khác liên quan tới
+ngữ cảnh hoạt động hiện tại, chẳng hạn như "Tìm kiếm," "Soạn e-mail," và "Cài đặt."</p>
+
+<p>Nơi mà các mục trong menu tùy chọn của bạn xuất hiện trên màn hình sẽ phụ thuộc vào phiên bản mà bạn
+phát triển ứng dụng của mình cho:</p>
+
+<ul>
+ <li>Nếu bạn phát triển ứng dụng của mình cho phiên bản <strong>Android 2.3.x (API mức 10) hoặc
+thấp hơn</strong>, nội dung của menu tùy chọn sẽ xuất hiện ở dưới cùng màn hình khi người dùng
+nhấn nút <em>Menu</em> như minh họa trong hình 1. Khi được mở, phần hiển thị đầu tiên là
+menu biểu tượng
+với tối đa sáu mục menu. Nếu menu của bạn bao gồm nhiều hơn sáu mục, Android sẽ đặt
+mục thứ sáu và phần còn lại vào một menu tràn mà người dùng có thể mở bằng cách chọn
+<em>Thêm nữa</em>.</li>
+
+ <li>Nếu bạn phát triển ứng dụng của mình cho phiên bản <strong>Android 3.0 (API mức 11) và
+cao hơn</strong>, các mục từ menu tùy chọn sẵn ở trong <a href="{@docRoot}guide/topics/ui/actionbar.html">thanh hành động</a>. Theo mặc định, hệ thống
+đặt tất cả các mục trong phần tràn hành động mà người dùng có thể hiện bằng biểu tượng tràn hành động phía
+bên phải của thanh hành động (hoặc bằng cách nhấn nút <em>Menu</em> của thiết bị nếu có). Để
+kích hoạt
+truy cập nhanh vào các hành động quan trọng, bạn có thể đưa lên một vài mục xuất hiện trong thanh hành động bằng cách thêm
+{@code android:showAsAction="ifRoom"} vào phần tử {@code &lt;item&gt;} tương ứng (xem hình
+2). <p>Để biết thêm thông tin về các mục hành động và hành vi khác của thanh hành động, hãy xem hướng dẫn <a href="{@docRoot}guide/topics/ui/actionbar.html">Thanh Hành động</a>. </p>
+<p class="note"><strong>Lưu ý:</strong> Ngay cả khi bạn <em>không</em> đang phát triển cho phiên bản Android 3.0 hoặc
+cao hơn, bạn có thể xây dựng bố trí thanh hành động của chính mình cho hiệu ứng tương tự. Để xem ví dụ về cách bạn có thể hỗ trợ các phiên bản cao hơn
+của Android bằng một thanh hành động, hãy xem mẫu <a href="{@docRoot}resources/samples/ActionBarCompat/index.html">Tương thích với Thanh Hành động</a>
+.</p>
+</li>
+</ul>
+
+<img src="{@docRoot}images/ui/actionbar.png" alt="" />
+<p class="img-caption"><strong>Hình 2.</strong> Thanh hành động từ ứng dụng <a href="{@docRoot}resources/samples/HoneycombGallery/index.html">Honeycomb Gallery</a>, hiển thị
+các tab điều hướng và một mục hành động máy ảnh (cộng với nút tràn hành động).</p>
+
+<p>Bạn có thể khai báo các mục cho menu tùy chọn từ lớp con {@link android.app.Activity}
+của bạn hoặc một lớp con {@link android.app.Fragment}. Nếu cả hoạt động của bạn và (các) phân đoạn
+đều khai báo các mục cho menu tùy chọn, chúng sẽ được kết hợp lại trong UI. Các mục của hoạt động xuất hiện
+trước, sau đó là các mục của từng phân đoạn theo thứ tự phân đoạn được thêm vào
+hoạt động. Nếu cần, bạn có thể sắp xếp lại các mục menu bằng thuộc tính {@code android:orderInCategory}
+trong mỗi {@code &lt;item&gt;} mà bạn cần di chuyển.</p>
+
+<p>Để quy định menu tùy chọn cho một hoạt động, hãy khống chế {@link
+android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()} (các phân đoạn cung cấp
+phương pháp gọi lại {@link android.app.Fragment#onCreateOptionsMenu onCreateOptionsMenu()} của chính mình). Trong
+phương pháp này, bạn có thể bung tài nguyên menu của mình (<a href="#xml">được định nghĩa trong XML</a>) vào {@link
+android.view.Menu} được cung cấp trong phương pháp gọi lại. Ví dụ:</p>
+
+<pre>
+&#64;Override
+public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater inflater = {@link android.app.Activity#getMenuInflater()};
+ inflater.inflate(R.menu.game_menu, menu);
+ return true;
+}
+</pre>
+
+<p>Bạn cũng có thể thêm các mục menu bằng cách sử dụng {@link android.view.Menu#add(int,int,int,int)
+add()} và truy xuất các mục bằng {@link android.view.Menu#findItem findItem()} để xem lại
+tính chất của chúng bằng các API {@link android.view.MenuItem}.</p>
+
+<p>Nếu bạn phát triển ứng dụng của mình cho phiên bản Android 2.3.x và thấp hơn, hệ thống gọi {@link
+android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()} để tạo menu tùy chọn
+khi người dùng mở menu lần đầu tiên. Nếu bạn phát triển cho phiên bản Android 3.0 vào cao hơn,
+hệ thống sẽ gọi {@link android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()} khi
+bắt đầu hoạt động để hiển thị các mục cho thanh hành động.</p>
+
+
+
+<h3 id="RespondingOptionsMenu">Xử lý sự kiện nhấp</h3>
+
+<p>Khi người dùng chọn một mục từ menu tùy chọn (bao gồm các mục hành động trong thanh hành động),
+hệ thống sẽ gọi phương pháp {@link android.app.Activity#onOptionsItemSelected(MenuItem)
+onOptionsItemSelected()} của hoạt động của bạn. Phương pháp này thông qua {@link android.view.MenuItem} được chọn. Bạn
+có thể nhận biết mục bằng cách gọi {@link android.view.MenuItem#getItemId()}, nó trả về ID duy nhất
+cho mục menu (được định nghĩa bởi thuộc tính {@code android:id} trong tài nguyên menu hoặc bằng một
+số nguyên được cấp cho phương pháp {@link android.view.Menu#add(int,int,int,int) add()}). Bạn có thể khớp
+ID này với các mục menu đã biết để thực hiện hành động phù hợp. Ví dụ:</p>
+
+<pre>
+&#64;Override
+public boolean onOptionsItemSelected(MenuItem item) {
+ // Handle item selection
+ switch (item.getItemId()) {
+ case R.id.new_game:
+ newGame();
+ return true;
+ case R.id.help:
+ showHelp();
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
+ }
+}
+</pre>
+
+<p>Khi bạn xử lý thành công một mục menu, trả về {@code true}. Nếu không xử lý được
+mục menu, bạn nên gọi triển khai siêu lớp của {@link
+android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()} (triển khai
+mặc định trả về sai).</p>
+
+<p>Nếu hoạt động của bạn bao gồm các phân đoạn, trước tiên hệ thống sẽ gọi {@link
+android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()} cho hoạt động, rồi mới
+cho từng phân đoạn (theo thứ tự thêm phân đoạn) tới khi trả về
+{@code true} hoặc tất cả phân đoạn đều được gọi.</p>
+
+<p class="note"><strong>Mẹo:</strong> Android 3.0 thêm khả năng cho phép bạn định nghĩa hành vi
+khi nhấp đối với một mục menu trong XML, bằng cách sử dụng thuộc tính {@code android:onClick}. Giá trị cho
+thuộc tính phải là tên của một phương pháp được định nghĩa bởi hoạt động sử dụng menu. Phương pháp
+phải công khai và chấp nhận một tham số {@link android.view.MenuItem} đơn&mdash;khi hệ thống
+gọi phương pháp này, nó thông qua mục menu được chọn. Để biết thêm thông tin và ví dụ, hãy xem tài liệu <a href="{@docRoot}guide/topics/resources/menu-resource.html">Tài nguyên Menu</a>.</p>
+
+<p class="note"><strong>Mẹo:</strong> Nếu ứng dụng của bạn chứa nhiều hoạt động và
+một số chúng cung cấp menu tùy chọn tương tự, hãy xem xét tạo
+ một hoạt động chỉ triển khai các phương pháp {@link android.app.Activity#onCreateOptionsMenu(Menu)
+onCreateOptionsMenu()} và {@link android.app.Activity#onOptionsItemSelected(MenuItem)
+onOptionsItemSelected()}. Sau đó, mở rộng lớp này đối với mỗi hoạt động cần chia sẻ
+menu tùy chọn tương tự. Bằng cách này, bạn có thể quản lý một bộ mã để xử lý các hành động
+menu và từng lớp hậu duệ kế thừa các hành vi menu.
+Nếu bạn muốn thêm các mục menu vào một trong các hoạt động hậu duệ,
+hãy khống chế {@link android.app.Activity#onCreateOptionsMenu(Menu)
+onCreateOptionsMenu()} trong hoạt động đó. Gọi {@code super.onCreateOptionsMenu(menu)} sao cho
+các mục menu gốc được tạo, sau đó thêm các mục menu mới bằng {@link
+android.view.Menu#add(int,int,int,int) menu.add()}. Bạn cũng có thể khống chế hành vi
+của siêu lớp đối với các mục menu riêng lẻ.</p>
+
+
+<h3 id="ChangingTheMenu">Thay đổi các mục menu vào thời gian chạy</h3>
+
+<p>Sau khi hệ thống gọi {@link android.app.Activity#onCreateOptionsMenu(Menu)
+onCreateOptionsMenu()}, nó sẽ giữ lại một thực thể của {@link android.view.Menu} mà bạn đưa vào và
+sẽ không gọi lại {@link android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()}
+trừ khi menu bị vô hiệu hóa vì lý do nào đó. Tuy nhiên, bạn chỉ nên sử dụng {@link
+android.app.Activity#onCreateOptionsMenu(Menu) onCreateOptionsMenu()} để tạo trạng thái menu
+ban đầu chứ không phải để thực hiện thay đổi trong vòng đời của hoạt động.</p>
+
+<p>Nếu bạn muốn sửa đổi menu tùy chọn dựa trên
+các sự kiện xảy ra trong vòng đời của hoạt động, bạn có thể làm vậy trong phương pháp
+ {@link android.app.Activity#onPrepareOptionsMenu(Menu) onPrepareOptionsMenu()}. Phương pháp
+này chuyển cho bạn đối tượng {@link android.view.Menu} như hiện đang có để bạn có thể sửa đổi nó,
+chẳng hạn như thêm, xóa bỏ, hoặc vô hiệu hóa các mục. (Phân đoạn cũng cung cấp lệnh gọi lại {@link
+android.app.Fragment#onPrepareOptionsMenu onPrepareOptionsMenu()}.)</p>
+
+<p>Trên phiên bản Android 2.3.x và thấp hơn, hệ thống gọi {@link
+android.app.Activity#onPrepareOptionsMenu(Menu)
+onPrepareOptionsMenu()} mỗi lần người dùng mở menu tùy chọn (nhấn nút <em>Menu</em>
+).</p>
+
+<p>Trên phiên bản Android 3.0 trở lên, menu tùy chọn được coi như luôn mở khi các mục menu được
+trình bày trong thanh hành động. Khi một sự kiện xảy ra và bạn muốn thực hiện một cập nhật menu, bạn phải
+gọi {@link android.app.Activity#invalidateOptionsMenu invalidateOptionsMenu()} để yêu cầu
+hệ thống gọi {@link android.app.Activity#onPrepareOptionsMenu(Menu) onPrepareOptionsMenu()}.</p>
+
+<p class="note"><strong>Lưu ý:</strong>
+Bạn không nên thay đổi các mục trong menu tùy chọn dựa trên {@link android.view.View} đang
+trong tiêu điểm. Khi ở chế độ cảm ứng (khi người dùng không sử dụng bi xoay hay d-pad), các dạng xem
+không thể lấy tiêu điểm, vì thế bạn không nên sử dụng tiêu điểm làm cơ sở để sửa đổi
+các mục trong menu tùy chọn. Nếu bạn muốn cung cấp các mục menu nhạy cảm với ngữ cảnh cho một {@link
+android.view.View}, hãy sử dụng một <a href="#context-menu">Menu Ngữ cảnh</a>.</p>
+
+
+
+
+<h2 id="context-menu">Tạo một Menu Ngữ cảnh</h2>
+
+<div class="figure" style="width:420px;margin-top:-1em">
+ <img src="{@docRoot}images/ui/menu-context.png" alt="" />
+ <p class="img-caption"><strong>Hình 3.</strong> Ảnh chụp màn hình một menu ngữ cảnh nổi (trái)
+và thanh hành động ngữ cảnh (phải).</p>
+</div>
+
+<p>Menu ngữ cảnh sẽ đưa ra các hành động ảnh hưởng tới một mục hoặc khung ngữ cảnh cụ thể trong UI. Bạn
+có thể cung cấp một menu ngữ cảnh cho bất kỳ dạng xem nào, nhưng chúng thường được sử dụng nhiều nhất cho các mục trong một {@link
+android.widget.ListView}, {@link android.widget.GridView}, hoặc các bộ sưu tập dạng xem khác mà
+người dùng có thể thực hiện hành động trực tiếp trên mỗi mục.</p>
+
+<p>Có hai cách để cung cấp các hành động ngữ cảnh:</p>
+<ul>
+ <li>Trong một <a href="#FloatingContextMenu">menu ngữ cảnh nổi</a>. Menu xuất hiện như một
+danh sách nổi gồm nhiều mục menu (tương tự như một hộp thoại) khi người dùng thực hiện nhấp giữ (nhấn và
+giữ) trên một dạng xem có khai báo hỗ trợ menu ngữ cảnh. Người dùng có thể thực hiện hành động
+ngữ cảnh trên một mục vào một thời điểm.</li>
+
+ <li>Trong <a href="#CAB">chế độ hành động theo ngữ cảnh</a>. Chế độ này là một hệ thống triển khai
+{@link android.view.ActionMode} có chức năng hiển thị một <em>thanh hành động ngữ cảnh</em> ở bên trên
+màn hình với các mục hành động ảnh hưởng tới (các) mục được chọn. Khi chế độ này hiện hoạt, người dùng
+có thể thực hiện một hành động trên nhiều mục ngay lập tức (nếu ứng dụng của bạn cho phép).</li>
+</ul>
+
+<p class="note"><strong>Lưu ý:</strong> Chế độ hành động theo ngữ cảnh sẵn có trên phiên bản Android 3.0 (API
+mức 11) và cao hơn và là kỹ thuật được ưu tiên cho việc hiển thị các hành động theo ngữ cảnh khi
+sẵn có. Nếu ứng dụng của bạn hỗ trợ các phiên bản thấp hơn 3.0, vậy bạn nên quay lại menu ngữ cảnh
+nổi trên những thiết bị đó.</p>
+
+
+<h3 id="FloatingContextMenu">Tạo một menu ngữ cảnh nổi</h3>
+
+<p>Để cung cấp một menu ngữ cảnh nổi:</p>
+<ol>
+ <li>Đăng ký {@link android.view.View} mà menu ngữ cảnh nên được liên kết với bằng cách
+gọi {@link android.app.Activity#registerForContextMenu(View) registerForContextMenu()} và chuyển
+cho nó {@link android.view.View}.
+ <p>Nếu hoạt động của bạn sử dụng một {@link android.widget.ListView} hoặc {@link android.widget.GridView} và
+bạn muốn từng mục cung cấp cùng menu ngữ cảnh, hãy đăng ký tất cả mục cho một menu ngữ cảnh bằng cách
+chuyển {@link android.widget.ListView} hoặc {@link android.widget.GridView} cho {@link
+android.app.Activity#registerForContextMenu(View) registerForContextMenu()}.</p>
+</li>
+
+ <li>Triển khai phương pháp {@link
+android.view.View.OnCreateContextMenuListener#onCreateContextMenu onCreateContextMenu()}
+trong {@link android.app.Activity} hoặc {@link android.app.Fragment} của bạn.
+ <p>Khi dạng xem được đăng ký nhận được một sự kiện nhấp giữ, hệ thống sẽ gọi phương pháp {@link
+android.view.View.OnCreateContextMenuListener#onCreateContextMenu onCreateContextMenu()}
+của bạn. Đây là nơi bạn định nghĩa các mục menu, thường bằng cách bung một tài nguyên menu. Ví
+dụ:</p>
+<pre>
+&#64;Override
+public void onCreateContextMenu(ContextMenu menu, View v,
+ ContextMenuInfo menuInfo) {
+ super.onCreateContextMenu(menu, v, menuInfo);
+ MenuInflater inflater = getMenuInflater();
+ inflater.inflate(R.menu.context_menu, menu);
+}
+</pre>
+
+<p>{@link android.view.MenuInflater} cho phép bạn bung menu ngữ cảnh từ một <a href="{@docRoot}guide/topics/resources/menu-resource.html">tài nguyên menu</a>. Các tham số của phương pháp gọi lại
+bao gồm {@link android.view.View}
+mà người dùng đã chọn và một đối tượng {@link android.view.ContextMenu.ContextMenuInfo} cung cấp
+thông tin bổ sung về mục được chọn. Nếu hoạt động của bạn có một vài dạng xem mà mỗi dạng cung cấp
+một menu ngữ cảnh khác nhau, bạn có thể sử dụng những tham số này để xác định menu ngữ cảnh nào cần
+bung.</p>
+</li>
+
+<li>Triển khai {@link android.app.Activity#onContextItemSelected(MenuItem)
+onContextItemSelected()}.
+ <p>Khi người dùng chọn một mục menu, hệ thống sẽ gọi phương pháp này để bạn có thể thực hiện
+hành động phù hợp. Ví dụ:</p>
+
+<pre>
+&#64;Override
+public boolean onContextItemSelected(MenuItem item) {
+ AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
+ switch (item.getItemId()) {
+ case R.id.edit:
+ editNote(info.id);
+ return true;
+ case R.id.delete:
+ deleteNote(info.id);
+ return true;
+ default:
+ return super.onContextItemSelected(item);
+ }
+}
+</pre>
+
+<p>Phương pháp {@link android.view.MenuItem#getItemId()} sẽ truy vấn ID cho
+mục menu được chọn, bạn nên gán mục này cho từng mục menu trong XML bằng cách sử dụng thuộc tính {@code
+android:id} như trình bày trong phần về <a href="#xml">Định nghĩa một Menu trong
+XML</a>.</p>
+
+<p>Khi bạn xử lý thành công một mục menu, trả về {@code true}. Nếu bạn không xử lý mục menu,
+bạn nên chuyển mục menu đó tới triển khai siêu lớp. Nếu hoạt động của bạn bao gồm nhiều phân đoạn,
+hoạt động sẽ nhận được lệnh gọi lại này trước. Bằng cách gọi siêu lớp khi chưa được xử lý, hệ thống
+sẽ chuyển sự kiện tới phương pháp gọi lại tương ứng trong từng phân đoạn, lần lượt (theo thứ tự
+thêm phân đoạn) tới khi {@code true} hoặc {@code false} được trả về. (Triển khai
+mặc định cho {@link android.app.Activity} và {@code android.app.Fragment} sẽ trả về {@code
+false}, vì thế bạn nên luôn gọi siêu lớp khi chưa được xử lý.)</p>
+</li>
+</ol>
+
+
+<h3 id="CAB">Sử dụng chế độ hành động theo ngữ cảnh</h3>
+
+<p>Chế độ hành động theo ngữ cảnh là một triển khai hệ thống {@link android.view.ActionMode}
+tập trung vào tương tác người dùng hướng tới việc thực hiện các hành động theo ngữ cảnh. Khi một
+người dùng kích hoạt chế độ này bằng cách chọn một mục, một <em>thanh hành động ngữ cảnh</em> sẽ xuất hiện bên trên
+màn hình để trình bày các hành động mà người dùng có thể thực hiện trên (các) mục đang được chọn. Trong khi
+chế độ này được kích hoạt, người dùng có thể chọn nhiều mục (nếu bạn cho phép), bỏ chọn mục, và tiếp tục
+điều hướng trong hoạt động (miễn là bạn sẵn lòng cho phép). Chế độ hành động bị vô hiệu hóa
+và thanh hành động ngữ cảnh biến mất khi người dùng bỏ chọn tất cả các mục, nhấn nút QUAY LẠI,
+hoặc chọn hành động <em>Xong</em> ở phía bên trái của thanh.</p>
+
+<p class="note"><strong>Lưu ý:</strong> Thanh hành động ngữ cảnh không nhất thiết
+phải được liên kết với <a href="{@docRoot}guide/topics/ui/actionbar.html">thanh hành động</a>. Chúng vận hành
+độc lập, mặc dù thanh hành động ngữ cảnh đè lên vị trí của thanh hành động
+về mặt hiển thị.</p>
+
+<p>Nếu bạn đang phát triển cho phiên bản Android 3.0 (API mức 11) hoặc cao hơn, bạn
+nên sử dụng chế độ hành động theo ngữ cảnh để trình bày các hành động ngữ cảnh, thay vì sử dụng <a href="#FloatingContextMenu">menu ngữ cảnh nổi</a>.</p>
+
+<p>Đối với các dạng xem cung cấp hành động ngữ cảnh, bạn nên thường xuyên gọi ra chế độ hành động theo ngữ cảnh
+khi xảy ra một trong hai sự kiện sau (hoặc cả hai):</p>
+<ul>
+ <li>Người dùng thực hiện nhấp giữ trên dạng xem.</li>
+ <li>Người dùng chọn một hộp kiểm hoặc một thành phần UI tương tự trong dạng xem.</li>
+</ul>
+
+<p>Cách ứng dụng của bạn gọi ra chế độ hành động theo ngữ cảnh và định nghĩa hành vi cho từng
+hành động phụ thuộc vào thiết kế của bạn. Cơ bản có hai thiết kế:</p>
+<ul>
+ <li>Đối với các hành động ngữ cảnh trên các dạng xem riêng lẻ, tùy ý.</li>
+ <li>Đối với các hành động ngữ cảnh hàng loạt trên các nhóm mục trong một {@link
+android.widget.ListView} hoặc {@link android.widget.GridView} (cho phép người dùng chọn nhiều
+mục và thực hiện một hành động trên tất cả).</li>
+</ul>
+
+<p>Các phần sau mô tả phần thiết lập cần thiết đối với từng kịch bản.</p>
+
+
+<h4 id="CABforViews">Kích hoạt chế độ hành động theo ngữ cảnh cho các dạng xem riêng lẻ</h4>
+
+<p>Nếu muốn gọi ra chế độ hành động theo ngữ cảnh chỉ khi người dùng chọn các dạng xem
+cụ thể, bạn nên:</p>
+<ol>
+ <li>Triển khai giao diện {@link android.view.ActionMode.Callback}. Trong các phương pháp gọi lại của giao diện, bạn
+có thể quy định các hành động cho thanh hành động ngữ cảnh, hồi đáp các sự kiện nhấp trên mục hành động, và
+xử lý các sự kiện vòng đời khác đối với chế độ hành động.</li>
+ <li>Gọi {@link android.app.Activity#startActionMode startActionMode()} khi bạn muốn hiển thị
+thanh (chẳng hạn như khi người dùng nhấp giữ dạng xem).</li>
+</ol>
+
+<p>Ví dụ:</p>
+
+<ol>
+ <li>Triển khai giao diện {@link android.view.ActionMode.Callback ActionMode.Callback}:
+<pre>
+private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
+
+ // Called when the action mode is created; startActionMode() was called
+ &#64;Override
+ public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+ // Inflate a menu resource providing context menu items
+ MenuInflater inflater = mode.getMenuInflater();
+ inflater.inflate(R.menu.context_menu, menu);
+ return true;
+ }
+
+ // Called each time the action mode is shown. Always called after onCreateActionMode, but
+ // may be called multiple times if the mode is invalidated.
+ &#64;Override
+ public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+ return false; // Return false if nothing is done
+ }
+
+ // Called when the user selects a contextual menu item
+ &#64;Override
+ public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.menu_share:
+ shareCurrentItem();
+ mode.finish(); // Action picked, so close the CAB
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ // Called when the user exits the action mode
+ &#64;Override
+ public void onDestroyActionMode(ActionMode mode) {
+ mActionMode = null;
+ }
+};
+</pre>
+
+<p>Lưu ý rằng những phương pháp gọi lại sự kiện này hầu như giống với các phương pháp gọi lại đối với <a href="#options-menu">menu tùy chọn</a>, khác ở chỗ từng phương pháp cũng chuyển đối tượng {@link
+android.view.ActionMode} được liên kết với sự kiện đó. Bạn có thể sử dụng các API {@link
+android.view.ActionMode} để thực hiện những thay đổi khác nhau với CAB, chẳng hạn như sửa đổi tiêu đề và
+phụ đề bằng {@link android.view.ActionMode#setTitle setTitle()} và {@link
+android.view.ActionMode#setSubtitle setSubtitle()} (hữu ích khi muốn cho biết có bao nhiêu mục
+được chọn).</p>
+
+<p>Cũng lưu ý rằng các bộ mẫu trên sẽ đặt biến {@code mActionMode} là rỗng khi
+chế độ hành động bị hủy. Ở bước tiếp theo, bạn sẽ thấy cách nó được khởi tạo và việc lưu
+biến thành viên trong hoạt động hoặc phân đoạn của bạn có thể hữu ích như thế nào.</p>
+</li>
+
+ <li>Gọi {@link android.app.Activity#startActionMode startActionMode()} để kích hoạt chế độ hành động theo ngữ cảnh
+khi phù hợp, chẳng hạn như để hồi đáp lại một sự kiện nhấp giữ trên một {@link
+android.view.View}:</p>
+
+<pre>
+someView.setOnLongClickListener(new View.OnLongClickListener() {
+ // Called when the user long-clicks on someView
+ public boolean onLongClick(View view) {
+ if (mActionMode != null) {
+ return false;
+ }
+
+ // Start the CAB using the ActionMode.Callback defined above
+ mActionMode = getActivity().startActionMode(mActionModeCallback);
+ view.setSelected(true);
+ return true;
+ }
+});
+</pre>
+
+<p>Khi bạn gọi {@link android.app.Activity#startActionMode startActionMode()}, hệ thống sẽ trả về
+{@link android.view.ActionMode} được tạo. Bằng cách lưu điều này trong một biến thành viên, bạn có thể
+thực hiện thay đổi thanh hành động theo ngữ cảnh để hồi đáp những sự kiện khác. Trong mẫu trên,
+{@link android.view.ActionMode} được sử dụng để đảm bảo rằng thực thể {@link android.view.ActionMode} không
+được tạo lại nếu nó đã hiện hoạt, bằng cách kiểm tra xem thành viên có rỗng không trước khi khởi động
+chế độ hành động.</p>
+</li>
+</ol>
+
+
+
+<h4 id="CABforListView">Kích hoạt hành động theo ngữ cảnh hàng loạt trong ListView hoặc GridView</h4>
+
+<p>Nếu bạn có một bộ sưu tập các mục trong một {@link android.widget.ListView} hoặc {@link
+android.widget.GridView} (hoặc một phần mở rộng khác của {@link android.widget.AbsListView}) và muốn
+cho phép người dùng thực hiện các hành động hàng loạt, bạn nên:</p>
+
+<ul>
+ <li>Triển khai giao diện {@link android.widget.AbsListView.MultiChoiceModeListener} và đặt nó
+cho nhóm dạng xem bằng {@link android.widget.AbsListView#setMultiChoiceModeListener
+setMultiChoiceModeListener()}. Trong các phương pháp gọi lại của trình nghe, bạn có thể quy định các hành động
+cho thanh hành động theo ngữ cảnh, hồi đáp các sự kiện nhấp trên các mục hành động, và xử lý các phương pháp gọi lại khác
+được kế thừa từ giao diện {@link android.view.ActionMode.Callback}.</li>
+
+ <li>Gọi {@link android.widget.AbsListView#setChoiceMode setChoiceMode()} bằng tham đối {@link
+android.widget.AbsListView#CHOICE_MODE_MULTIPLE_MODAL}.</li>
+</ul>
+
+<p>Ví dụ:</p>
+
+<pre>
+ListView listView = getListView();
+listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE_MODAL);
+listView.setMultiChoiceModeListener(new MultiChoiceModeListener() {
+
+ &#64;Override
+ public void onItemCheckedStateChanged(ActionMode mode, int position,
+ long id, boolean checked) {
+ // Here you can do something when items are selected/de-selected,
+ // such as update the title in the CAB
+ }
+
+ &#64;Override
+ public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+ // Respond to clicks on the actions in the CAB
+ switch (item.getItemId()) {
+ case R.id.menu_delete:
+ deleteSelectedItems();
+ mode.finish(); // Action picked, so close the CAB
+ return true;
+ default:
+ return false;
+ }
+ }
+
+ &#64;Override
+ public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+ // Inflate the menu for the CAB
+ MenuInflater inflater = mode.getMenuInflater();
+ inflater.inflate(R.menu.context, menu);
+ return true;
+ }
+
+ &#64;Override
+ public void onDestroyActionMode(ActionMode mode) {
+ // Here you can make any necessary updates to the activity when
+ // the CAB is removed. By default, selected items are deselected/unchecked.
+ }
+
+ &#64;Override
+ public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+ // Here you can perform updates to the CAB due to
+ // an {@link android.view.ActionMode#invalidate} request
+ return false;
+ }
+});
+</pre>
+
+<p>Vậy là xong. Lúc này, khi người dùng chọn một mục bằng nhấp giữ, hệ thống sẽ gọi phương pháp {@link
+android.widget.AbsListView.MultiChoiceModeListener#onCreateActionMode onCreateActionMode()}
+và hiển thị thanh hành động theo ngữ cảnh với các hành động được quy định. Trong khi thanh hành động theo ngữ cảnh
+hiển thị, người dùng có thể chọn thêm mục.</p>
+
+<p>Trong một số trường hợp mà các hành động ngữ cảnh cung cấp các mục hành động chung, bạn có thể muốn
+thêm một hộp kiểm hoặc một phần tử UI tương tự để cho phép người dùng chọn các mục, vì
+họ có thể không phát hiện được hành vi nhấp giữ. Khi một người dùng chọn hộp kiểm, bạn
+có thể gọi ra chế độ hành động theo ngữ cảnh bằng cách thiết đặt mục danh sách tương ứng về trạng thái
+đã chọn bằng {@link android.widget.AbsListView#setItemChecked setItemChecked()}.</p>
+
+
+
+
+<h2 id="PopupMenu">Tạo một Menu Bật lên</h2>
+
+<div class="figure" style="width:220px">
+<img src="{@docRoot}images/ui/popupmenu.png" alt="" />
+<p><strong>Hình 4.</strong> Menu bật lên trong ứng dụng Gmail, được neo vào nút tràn
+ở trên cùng bên phải.</p>
+</div>
+
+<p>{@link android.widget.PopupMenu} là một menu mô thái được neo vào một {@link android.view.View}.
+Nó xuất hiện bên dưới dạng xem dấu neo nếu có khoảng trống, hoặc bên trên dạng xem nếu không. Nó có ích cho việc:</p>
+<ul>
+ <li>Cung cấp một menu kiểu tràn cho các hành động mà <em>liên quan tới</em> nội dung cụ thể (chẳng hạn như tiêu đề e-mail
+của Gmail như minh họa trong hình 4).
+ <p class="note"><strong>Lưu ý:</strong> Nó không giống như một menu ngữ cảnh, vốn thường
+áp dụng cho các hành động mà <em>ảnh hưởng</em> tới nội dung được chọn. Đối với những hành động ảnh hưởng tới nội dung
+được chọn, hãy sử dụng <a href="#CAB">chế độ hành động theo ngữ cảnh</a> hoặc <a href="#FloatingContextMenu">menu ngữ cảnh nổi</a>.</p></li>
+ <li>Cung cấp một phần thứ hai của câu lệnh (chẳng hạn như một nút được đánh dấu "Thêm"
+có chức năng tạo ra một menu bật lên với các tùy chọn "Thêm" khác nhau).</li>
+ <li>Cung cấp một danh sách thả xuống tương tự như {@link android.widget.Spinner}, nó không giữ lại một
+lựa chọn liên tục.</li>
+</ul>
+
+
+<p class="note"><strong>Lưu ý:</strong> {@link android.widget.PopupMenu} sẵn có với API
+mức 11 trở lên.</p>
+
+<p>Nếu bạn định nghĩa <a href="#xml">menu của mình trong XML</a>, sau đây là cách bạn có thể hiển thị menu bật lên:</p>
+<ol>
+ <li>Khởi tạo một {@link android.widget.PopupMenu} bằng hàm dựng của nó, có chức năng đưa
+ứng dụng hiện tại {@link android.content.Context} và {@link android.view.View} tới menu
+mà sẽ được neo.</li>
+ <li>Sử dụng {@link android.view.MenuInflater} để bung tài nguyên menu của bạn vào đối tượng {@link
+android.view.Menu} được trả về bởi {@link
+android.widget.PopupMenu#getMenu() PopupMenu.getMenu()}. Trên API mức 14 trở lên, bạn có thể sử dụng
+{@link android.widget.PopupMenu#inflate PopupMenu.inflate()} thay thế.</li>
+ <li>Gọi {@link android.widget.PopupMenu#show() PopupMenu.show()}.</li>
+</ol>
+
+<p>Ví dụ, sau đây là một nút với thuộc tính {@link android.R.attr#onClick android:onClick} có chức năng
+hiển thị một menu bật lên:</p>
+
+<pre>
+&lt;ImageButton
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:src="@drawable/ic_overflow_holo_dark"
+ android:contentDescription="@string/descr_overflow_button"
+ android:onClick="showPopup" />
+</pre>
+
+<p>Khi đó, hoạt động có thể hiển thị menu bật lên như sau:</p>
+
+<pre>
+public void showPopup(View v) {
+ PopupMenu popup = new PopupMenu(this, v);
+ MenuInflater inflater = popup.getMenuInflater();
+ inflater.inflate(R.menu.actions, popup.getMenu());
+ popup.show();
+}
+</pre>
+
+<p>Trong API mức 14 trở lên, bạn có thể kết hợp hai dòng có chức năng bung menu bằng {@link
+android.widget.PopupMenu#inflate PopupMenu.inflate()}.</p>
+
+<p>Menu bị bỏ qua khi người dùng chọn một mục hoặc chạm vào bên ngoài vùng
+menu. Bạn có thể lắng nghe báo hiệu sự kiện bỏ bằng cách sử dụng {@link
+android.widget.PopupMenu.OnDismissListener}.</p>
+
+<h3 id="PopupEvents">Xử lý sự kiện nhấp</h3>
+
+<p>Để thực hiện một
+hành động khi người dùng chọn một mục menu, bạn phải triển khai giao diện {@link
+android.widget.PopupMenu.OnMenuItemClickListener} và đăng ký nó với {@link
+android.widget.PopupMenu} của mình bằng cách gọi {@link android.widget.PopupMenu#setOnMenuItemClickListener
+setOnMenuItemclickListener()}. Khi người dùng chọn một mục, hệ thống sẽ gọi lệnh gọi lại {@link
+android.widget.PopupMenu.OnMenuItemClickListener#onMenuItemClick onMenuItemClick()} trong
+giao diện của bạn.</p>
+
+<p>Ví dụ:</p>
+
+<pre>
+public void showMenu(View v) {
+ PopupMenu popup = new PopupMenu(this, v);
+
+ // This activity implements OnMenuItemClickListener
+ popup.setOnMenuItemClickListener(this);
+ popup.inflate(R.menu.actions);
+ popup.show();
+}
+
+&#64;Override
+public boolean onMenuItemClick(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.archive:
+ archive(item);
+ return true;
+ case R.id.delete:
+ delete(item);
+ return true;
+ default:
+ return false;
+ }
+}
+</pre>
+
+
+<h2 id="groups">Tạo Nhóm Menu</h2>
+
+<p>Nhóm menu là một tập hợp các mục menu chia sẻ những đặc điểm nhất định. Với một nhóm, bạn có thể
+:</p>
+<ul>
+ <li>Hiển thị hoặc ẩn tất cả các mục bằng {@link android.view.Menu#setGroupVisible(int,boolean)
+setGroupVisible()}</li>
+ <li>Kích hoạt hoặc vô hiệu hóa tất cả các mục bằng {@link android.view.Menu#setGroupEnabled(int,boolean)
+setGroupEnabled()}</li>
+ <li>Quy định xem tất cả các mục có thể chọn hay không bằng {@link
+android.view.Menu#setGroupCheckable(int,boolean,boolean) setGroupCheckable()}</li>
+</ul>
+
+<p>Bạn có thể tạo một nhóm bằng cách lồng các phần tử {@code &lt;item&gt;} bên trong một phần tử {@code &lt;group&gt;}
+vào tài nguyên menu của bạn hoặc bằng cách quy định một ID nhóm bằng phương pháp {@link
+android.view.Menu#add(int,int,int,int) add()}.</p>
+
+<p>Sau đây là một ví dụ về tài nguyên menu bao gồm một nhóm:</p>
+
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
+&lt;menu xmlns:android="http://schemas.android.com/apk/res/android"&gt;
+ &lt;item android:id="@+id/menu_save"
+ android:icon="@drawable/menu_save"
+ android:title="@string/menu_save" /&gt;
+ &lt;!-- menu group --&gt;
+ &lt;group android:id="@+id/group_delete"&gt;
+ &lt;item android:id="@+id/menu_archive"
+ android:title="@string/menu_archive" /&gt;
+ &lt;item android:id="@+id/menu_delete"
+ android:title="@string/menu_delete" /&gt;
+ &lt;/group&gt;
+&lt;/menu&gt;
+</pre>
+
+<p>Các mục nằm trong nhóm xuất hiện ở cùng cấp như mục đầu tiên&mdash;tất cả ba mục
+trong menu đều là các mục đồng cấp. Tuy nhiên, bạn có thể sửa đổi các đặc điểm của hai
+mục trong nhóm bằng cách tham chiếu ID nhóm và sử dụng các phương pháp được liệt kê bên trên. Hệ thống cũng sẽ
+không bao giờ tách riêng các mục đã ghép nhóm. Ví dụ, nếu bạn khai báo {@code
+android:showAsAction="ifRoom"} cho từng mục, chúng sẽ hoặc đều xuất hiện trong thanh hành động
+hoặc đều xuất hiện trong phần tràn hành động.</p>
+
+
+<h3 id="checkable">Sử dụng mục menu có thể chọn</h3>
+
+<div class="figure" style="width:200px">
+ <img src="{@docRoot}images/radio_buttons.png" height="333" alt="" />
+ <p class="img-caption"><strong>Hình 5.</strong> Ảnh chụp màn hình một menu con với các mục
+có thể chọn.</p>
+</div>
+
+<p>Một mục có thể có ích như một giao diện để bật và tắt các tùy chọn, bằng cách sử dụng một hộp kiểm cho
+các tùy chọn độc lập, hoặc nút chọn một cho các nhóm
+tùy chọn loại trừ lẫn nhau. Hình 5 minh họa một menu con với các mục có thể chọn bằng các nút
+ chọn một.</p>
+
+<p class="note"><strong>Lưu ý:</strong> Các mục menu trong Menu Biểu tượng (từ menu tùy chọn) không thể
+hiển thị một hộp kiểm hay nút chọn một. Nếu bạn chọn đặt các mục trong Menu Biểu tượng là có thể chọn,
+bạn phải chỉ định trạng thái được chọn bằng cách tráo đổi biểu tượng và/hoặc văn bản
+mỗi lần trạng thái thay đổi một cách thủ công.</p>
+
+<p>Bạn có thể định nghĩa hành vi có thể chọn cho các mục menu riêng lẻ bằng cách sử dụng thuộc tính {@code
+android:checkable} trong phần tử {@code &lt;item&gt;}, hoặc cho toàn bộ nhóm với
+thuộc tính {@code android:checkableBehavior} trong phần tử {@code &lt;group&gt;}. Ví
+dụ, tất cả các mục trong nhóm menu này có thể chọn bằng một nút chọn một:</p>
+
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?&gt;
+&lt;menu xmlns:android="http://schemas.android.com/apk/res/android"&gt;
+ &lt;group android:checkableBehavior="single"&gt;
+ &lt;item android:id="@+id/red"
+ android:title="@string/red" /&gt;
+ &lt;item android:id="@+id/blue"
+ android:title="@string/blue" /&gt;
+ &lt;/group&gt;
+&lt;/menu&gt;
+</pre>
+
+<p>Thuộc tính {@code android:checkableBehavior} chấp nhận hoặc:
+<dl>
+ <dt>{@code single}</dt>
+ <dd>Chỉ chọn được một mục từ nhóm (nút chọn một)</dd>
+ <dt>{@code all}</dt>
+ <dd>Có thể chọn được tất cả các mục (hộp kiểm)</dd>
+ <dt>{@code none}</dt>
+ <dd>Không chọn được mục nào</dd>
+</dl>
+
+<p>Bạn có thể áp dụng một trạng thái được chọn mặc định cho một mục bằng cách sử dụng thuộc tính {@code android:checked} trong
+phần tử {@code &lt;item&gt;} và thay đổi nó trong mã bằng phương pháp {@link
+android.view.MenuItem#setChecked(boolean) setChecked()}.</p>
+
+<p>Khi chọn một mục có thể chọn, hệ thống sẽ gọi phương pháp gọi lại mục được chọn tương ứng
+(chẳng hạn như {@link android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()}). Chính
+ở đây bạn phải đặt trạng thái của hộp kiểm, vì hộp kiểm hay nút chọn một đều không
+tự động thay đổi trạng thái của nó. Bạn có thể truy vấn trạng thái hiện tại của mục (như trước khi
+người dùng chọn) bằng {@link android.view.MenuItem#isChecked()} và sau đó đặt trạng thái được chọn bằng
+{@link android.view.MenuItem#setChecked(boolean) setChecked()}. Ví dụ:</p>
+
+<pre>
+&#64;Override
+public boolean onOptionsItemSelected(MenuItem item) {
+ switch (item.getItemId()) {
+ case R.id.vibrate:
+ case R.id.dont_vibrate:
+ if (item.isChecked()) item.setChecked(false);
+ else item.setChecked(true);
+ return true;
+ default:
+ return super.onOptionsItemSelected(item);
+ }
+}
+</pre>
+
+<p>Nếu bạn không đặt trạng thái được chọn bằng cách này, khi đó trạng thái hiển thị của mục (hộp kiểm hoặc
+nút chọn một) sẽ không
+thay đổi khi người dùng chọn nó. Khi bạn đặt trạng thái, hoạt động sẽ giữ nguyên trạng thái được chọn
+của mục đó để khi người dùng mở menu sau, trạng thái được chọn mà bạn đặt
+sẽ được hiển thị.</p>
+
+<p class="note"><strong>Lưu ý:</strong>
+Các mục menu có thể chọn được chỉ định sử dụng trên mỗi phiên và không được lưu sau khi
+ứng dụng bị hủy. Nếu bạn có các cài đặt ứng dụng mà bạn muốn lưu cho người dùng,
+bạn nên lưu trữ dữ liệu bằng cách sử dụng <a href="{@docRoot}guide/topics/data/data-storage.html#pref">Tùy chọn dùng chung</a>.</p>
+
+
+
+<h2 id="intents">Thêm Mục Menu dựa trên Ý định</h2>
+
+<p>Đôi khi bạn sẽ muốn một mục menu khởi chạy một hoạt động bằng cách sử dụng một {@link android.content.Intent}
+(dù đó là một hoạt động trong ứng dụng của bạn hay một ứng dụng khác). Khi bạn biết ý định mà mình
+muốn sử dụng và có một mục menu cụ thể sẽ khởi tạo ý định, bạn có thể thực thi ý định
+bằng {@link android.app.Activity#startActivity(Intent) startActivity()} trong phương pháp gọi lại
+phù hợp theo mục được chọn (chẳng hạn như lệnh gọi lại {@link
+android.app.Activity#onOptionsItemSelected(MenuItem) onOptionsItemSelected()}).</p>
+
+<p>Tuy nhiên, nếu bạn không chắc chắn rằng thiết bị của người dùng
+chứa một ứng dụng xử lý ý định đó thì việc thêm một mục menu gọi nó ra có thể dẫn đến
+mục menu không hoạt động, do ý định có thể không phân giải thành một
+hoạt động. Để giải quyết điều này, Android cho phép bạn linh hoạt thêm các mục menu vào menu của mình
+khi Android tìm các hoạt động trên thiết bị để xử lý ý định của bạn.</p>
+
+<p>Để thêm các mục menu dựa trên các hoạt động sẵn có mà chấp nhận ý định:</p>
+<ol>
+ <li>Định nghĩa một
+ý định bằng thể loại {@link android.content.Intent#CATEGORY_ALTERNATIVE} và/hoặc
+{@link android.content.Intent#CATEGORY_SELECTED_ALTERNATIVE}, cộng với bất kỳ yêu cầu nào khác.</li>
+ <li>Gọi {@link
+android.view.Menu#addIntentOptions(int,int,int,ComponentName,Intent[],Intent,int,MenuItem[])
+Menu.addIntentOptions()}. Sau đó, Android tìm kiếm bất kỳ ứng dụng nào có thể thực hiện ý định
+và thêm chúng vào menu của bạn.</li>
+</ol>
+
+<p>Nếu không có ứng dụng được cài đặt
+mà thỏa mãn ý định thì không có mục menu nào được thêm vào.</p>
+
+<p class="note"><strong>Lưu ý:</strong>
+{@link android.content.Intent#CATEGORY_SELECTED_ALTERNATIVE} được sử dụng để xử lý
+phần tử đang được chọn trên màn hình. Vì vậy, nó chỉ nên được sử dụng khi tạo một Menu trong {@link
+android.app.Activity#onCreateContextMenu(ContextMenu,View,ContextMenuInfo)
+onCreateContextMenu()}.</p>
+
+<p>Ví dụ:</p>
+
+<pre>
+&#64;Override
+public boolean onCreateOptionsMenu(Menu menu){
+ super.onCreateOptionsMenu(menu);
+
+ // Create an Intent that describes the requirements to fulfill, to be included
+ // in our menu. The offering app must include a category value of Intent.CATEGORY_ALTERNATIVE.
+ Intent intent = new Intent(null, dataUri);
+ intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
+
+ // Search and populate the menu with acceptable offering applications.
+ menu.addIntentOptions(
+ R.id.intent_group, // Menu group to which new items will be added
+ 0, // Unique item ID (none)
+ 0, // Order for the items (none)
+ this.getComponentName(), // The current activity name
+ null, // Specific items to place first (none)
+ intent, // Intent created above that describes our requirements
+ 0, // Additional flags to control items (none)
+ null); // Array of MenuItems that correlate to specific items (none)
+
+ return true;
+}</pre>
+
+<p>Đối với mỗi hoạt động được tìm thấy mà cung cấp một bộ lọc ý định khớp với ý định được định nghĩa, một mục menu
+được thêm, bằng cách sử dụng giá trị trong <code>android:label</code> của bộ lọc ý định làm
+tiêu đề của mục menu và biểu tượng của ứng dụng làm biểu tượng của mục menu. Phương pháp
+{@link android.view.Menu#addIntentOptions(int,int,int,ComponentName,Intent[],Intent,int,MenuItem[])
+addIntentOptions()} trả về số mục menu được thêm.</p>
+
+<p class="note"><strong>Lưu ý:</strong> Khi bạn gọi {@link
+android.view.Menu#addIntentOptions(int,int,int,ComponentName,Intent[],Intent,int,MenuItem[])
+addIntentOptions()}, nó sẽ khống chế bất kỳ và tất cả các mục menu theo nhóm menu được quy định trong tham đối
+đầu tiên.</p>
+
+
+<h3 id="AllowingToAdd">Cho phép hoạt động của bạn được thêm vào các menu khác</h3>
+
+<p>Bạn cũng có thể cung cấp các dịch vụ của hoạt động của mình cho các ứng dụng khác, vì vậy ứng dụng của bạn
+có thể nằm trong menu của các ứng dụng khác (đảo ngược vai trò nêu trên).</p>
+
+<p>Để được nằm trong menu của ứng dụng khác, bạn cần định nghĩa một bộ lọc
+ý định như bình thường, nhưng đảm bảo thêm các giá trị {@link android.content.Intent#CATEGORY_ALTERNATIVE}
+và/hoặc {@link android.content.Intent#CATEGORY_SELECTED_ALTERNATIVE} cho thể loại
+bộ lọc ý định. Ví dụ:</p>
+<pre>
+&lt;intent-filter label="&#64;string/resize_image">
+ ...
+ &lt;category android:name="android.intent.category.ALTERNATIVE" />
+ &lt;category android:name="android.intent.category.SELECTED_ALTERNATIVE" />
+ ...
+&lt;/intent-filter>
+</pre>
+
+<p>Tìm hiểu thêm về việc ghi các bộ lọc ý định trong tài liệu
+<a href="/guide/components/intents-filters.html">Ý định và Bộ lọc Ý định</a>.</p>
+
+<p>Để tham khảo một ứng dụng mẫu sử dụng kỹ thuật này, hãy xem mã mẫu
+<a href="{@docRoot}resources/samples/NotePad/src/com/example/android/notepad/NoteEditor.html">Note
+Pad</a>.</p>
diff --git a/docs/html-intl/intl/vi/guide/topics/ui/notifiers/notifications.jd b/docs/html-intl/intl/vi/guide/topics/ui/notifiers/notifications.jd
new file mode 100644
index 000000000000..5890cb331b96
--- /dev/null
+++ b/docs/html-intl/intl/vi/guide/topics/ui/notifiers/notifications.jd
@@ -0,0 +1,979 @@
+page.title=Thông báo
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+<h2>Trong tài liệu này</h2>
+<ol>
+ <li><a href="#Design">Cân nhắc Thiết kế</a></li>
+ <li><a href="#CreateNotification">Tạo một Thông báo</a>
+ <ol>
+ <li><a href="#Required">Nội dung thông báo được yêu cầu</a></li>
+ <li><a href="#Optional">Nội dung và cài đặt thông báo tùy chọn</a></li>
+ <li><a href="#Actions">Hành động thông báo</a></li>
+ <li><a href="#Priority">Mức ưu tiên của thông báo</a></li>
+ <li><a href="#SimpleNotification">Tạo một thông báo đơn giản</a></li>
+ <li><a href="#ApplyStyle">Áp dụng bố trí mở rộng cho một thông báo</a></li>
+ <li><a href="#Compatibility">Xử lý tính tương thích</a></li>
+ </ol>
+ </li>
+ <li><a href="#Managing">Quản lý Thông báo</a>
+ <ol>
+ <li><a href="#Updating">Cập nhật thông báo</a></li>
+ <li><a href="#Removing">Loại bỏ thông báo</a></li>
+ </ol>
+ </li>
+ <li><a href="#NotificationResponse">Giữ lại Điều hướng khi Bắt đầu một Hoạt động</a>
+ <ol>
+ <li><a href="#DirectEntry">Thiết đặt một PendingIntent cho hoạt động thường xuyên</a></li>
+ <li><a href="#ExtendedNotification">Thiết đặt một PendingIntent cho hoạt động đặc biệt</a></li>
+ </ol>
+ </li>
+ <li><a href="#Progress">Hiển thị Tiến độ trong một Thông báo</a>
+ <ol>
+ <li><a href="#FixedProgress">Hiển thị một chỉ báo tiến độ thời lượng cố định</a></li>
+ <li><a href="#ActivityIndicator">Hiển thị một chỉ báo hoạt động liên tục</a></li>
+ </ol>
+ </li>
+ <li><a href="#metadata">Siêu dữ liệu Thông báo</a></li>
+ <li><a href="#Heads-up">Thông báo Cảnh báo</a></li>
+ <li><a href="#lockscreenNotification">Thông báo Màn hình Khóa</a></li>
+ <ol>
+ <li><a href="#visibility">Thiết đặt Khả năng Hiển thị</a></li>
+ <li><a href="#controllingMedia">Điều khiển Phát lại Phương tiện trên Màn hình Khóa</a></li>
+ </ol>
+ <li><a href="#CustomNotification">Bố trí Thông báo Tùy chỉnh</a></li>
+</ol>
+
+ <h2>Lớp khóa</h2>
+ <ol>
+ <li>{@link android.app.NotificationManager}</li>
+ <li>{@link android.support.v4.app.NotificationCompat}</li>
+ </ol>
+ <h2>Video</h2>
+ <ol>
+ <li>
+ <a href="http://www.youtube.com/watch?v=Yc8YrVc47TI&amp;feature=player_detailpage#t=1672s">
+ Thông báo trong 4.1</a>
+ </li>
+ </ol>
+<h2>Xem thêm</h2>
+<ol>
+ <li>
+ <a href="{@docRoot}design/patterns/notifications.html">Thiết kế Android: Thông báo</a>
+ </li>
+</ol>
+</div>
+</div>
+<p>
+ Thông báo là một thông điệp bạn có thể hiển thị với người dùng bên ngoài
+ UI bình thường của ứng dụng của bạn. Khi bạn yêu cầu hệ thống phát hành một thông báo, trước tiên nó xuất hiện như một biểu tượng trong
+ <strong>khu vực thông báo</strong>. Để xem chi tiết thông báo, người dùng mở
+ <strong>ngăn kéo thông báo</strong>. Cả khu vực thông báo và ngăn kéo thông báo đều
+ là các khu vực do hệ thống kiểm soát mà người dùng có thể xem vào bất cứ lúc nào.
+</p>
+<img id="figure1" src="{@docRoot}images/ui/notifications/notification_area.png" height="" alt="" />
+<p class="img-caption">
+ <strong>Hình 1.</strong> Thông báo trong khu vực thông báo.
+</p>
+<img id="figure2" src="{@docRoot}images/ui/notifications/notification_drawer.png" width="280px" alt="" />
+<p class="img-caption">
+ <strong>Hình 2.</strong> Thông báo trong ngăn kéo thông báo.
+</p>
+
+<p class="note"><strong>Lưu ý:</strong> Ngoại trừ phần được lưu ý, hướng dẫn này nhắc đến
+lớp {@link android.support.v4.app.NotificationCompat.Builder NotificationCompat.Builder}
+trong phiên bản 4 của <a href="{@docRoot}tools/support-library/index.html">Thư viện Hỗ trợ</a>.
+Lớp {@link android.app.Notification.Builder Notification.Builder} đã được thêm vào trong Android
+3.0 (API mức 11).</p>
+
+<h2 id="Design">Cân nhắc Thiết kế</h2>
+
+<p>Là một phần quan trọng của giao diện người dùng Android, thông báo có các hướng dẫn thiết kế của riêng mình.
+Những thay đổi thiết kế cơ bản được giới thiệu trong Android 5.0 (API mức 21) đặc biệt
+quan trọng và bạn nên xem phần đào tạo về <a href="{@docRoot}training/material/index.html">Thiết kế Material</a>
+để biết thêm thông tin. Để tìm hiểu cách thiết kế thông báo và tương tác của chúng, hãy đọc hướng dẫn thiết kế
+<a href="{@docRoot}design/patterns/notifications.html">Thông báo</a>.</p>
+
+<h2 id="CreateNotification">Tạo một Thông báo</h2>
+
+<p>Bạn quy định thông tin UI và các hành động cho một thông báo trong một đối tượng
+{@link android.support.v4.app.NotificationCompat.Builder NotificationCompat.Builder}.
+Để tạo chính thông báo, bạn gọi
+{@link android.support.v4.app.NotificationCompat.Builder#build NotificationCompat.Builder.build()},
+nó sẽ trả về một đối tượng {@link android.app.Notification} chứa những đặc tả của bạn. Để phát hành
+thông báo, bạn chuyển đối tượng {@link android.app.Notification} tới hệ thống bằng cách gọi
+{@link android.app.NotificationManager#notify NotificationManager.notify()}.</p>
+
+<h3 id="Required">Nội dung thông báo được yêu cầu</h3>
+<p>
+ Một đối tượng {@link android.app.Notification} <em>phải</em> chứa những điều sau:
+</p>
+<ul>
+ <li>
+ Một biểu tượng nhỏ được đặt bởi
+ {@link android.support.v4.app.NotificationCompat.Builder#setSmallIcon setSmallIcon()}
+ </li>
+ <li>
+ Một tiêu đề được đặt bởi
+ {@link android.support.v4.app.NotificationCompat.Builder#setContentTitle setContentTitle()}
+ </li>
+ <li>
+ Văn bản chi tiết được đặt bởi
+ {@link android.support.v4.app.NotificationCompat.Builder#setContentText setContentText()}
+ </li>
+</ul>
+<h3 id="Optional">Nội dung và cài đặt thông báo tùy chọn</h3>
+<p>
+ Tất cả cài đặt và nội dung thông báo khác đều mang tính tùy chọn. Để tìm hiểu thêm về chúng,
+ hãy xem tài liệu tham khảo cho {@link android.support.v4.app.NotificationCompat.Builder}.
+</p>
+<!-- ------------------------------------------------------------------------------------------ -->
+<h3 id="Actions">Hành động thông báo</h3>
+<p>
+ Mặc dù chúng mang tính tùy chọn, bạn nên thêm ít nhất một hành động vào thông báo của mình.
+ Một hành động cho phép người dùng đi trực tiếp từ thông báo tới một
+ {@link android.app.Activity} trong ứng dụng của bạn, nơi mà họ có thể xem thêm một hoặc nhiều sự kiện
+ hoặc làm việc thêm.
+</p>
+<p>
+ Một thông báo có thể cung cấp nhiều hành động. Bạn nên luôn định nghĩa hành động mà được
+ kích khởi khi người dùng nhấp vào thông báo; thường thì hành động này mở ra một
+ {@link android.app.Activity} trong ứng dụng của bạn. Bạn cũng có thể thêm các nút vào thông báo
+ để thực hiện những hành động bổ sung chẳng hạn như báo lại báo thức hay hồi đáp ngay lập tức một tin nhắn
+ văn bản; tính năng này sẵn có từ phiên bản Android 4.1. Nếu sử dụng các nút hành động bổ sung, bạn
+ cũng phải cung cấp tính năng của chúng trong một {@link android.app.Activity} trong ứng dụng của bạn; xem
+ phần <a href="#Compatibility">Xử lý tính tương thích</a> để biết thêm chi tiết.
+</p>
+<p>
+ Bên trong một {@link android.app.Notification}, bản thân hành động được định nghĩa bởi một
+ {@link android.app.PendingIntent} chứa một
+ {@link android.content.Intent} có chức năng bắt đầu
+ một {@link android.app.Activity} trong ứng dụng của bạn. Để liên kết
+ {@link android.app.PendingIntent} với một cử chỉ, hãy gọi phương pháp
+ {@link android.support.v4.app.NotificationCompat.Builder} phù hợp. Ví dụ, nếu bạn muốn bắt đầu
+ {@link android.app.Activity} khi người dùng nhấp vào văn bản thông báo trong
+ ngăn kéo thông báo, bạn hãy thêm {@link android.app.PendingIntent} bằng cách gọi
+ {@link android.support.v4.app.NotificationCompat.Builder#setContentIntent setContentIntent()}.
+</p>
+<p>
+ Bắt đầu một {@link android.app.Activity} khi người dùng nhấp vào thông báo là kịch bản
+ hành động phổ biến nhất. Bạn cũng có thể bắt đầu một {@link android.app.Activity} khi người dùng
+ bỏ một thông báo. Trong phiên bản Android 4.1 và sau đó, bạn có thể bắt đầu một
+ {@link android.app.Activity} từ một nút hành động. Để tìm hiểu thêm, hãy đọc hướng dẫn tham khảo cho
+ {@link android.support.v4.app.NotificationCompat.Builder}.
+</p>
+<!-- ------------------------------------------------------------------------------------------ -->
+<h3 id="Priority">Mức ưu tiên của thông báo</h3>
+<p>
+ Nếu muốn, bạn có thể đặt mức ưu tiên của một thông báo. Mức ưu tiên đóng vai trò
+ như một gợi ý cho UI của thiết bị về cách thông báo sẽ được hiển thị.
+ Để đặt mức ưu tiên của một thông báo, hãy gọi {@link
+ android.support.v4.app.NotificationCompat.Builder#setPriority(int)
+ NotificationCompat.Builder.setPriority()} và chuyển trong một trong các hằng số mức ưu tiên {@link
+ android.support.v4.app.NotificationCompat}. Có năm mức ưu tiên,
+ dao động từ {@link
+ android.support.v4.app.NotificationCompat#PRIORITY_MIN} (-2) đến {@link
+ android.support.v4.app.NotificationCompat#PRIORITY_MAX} (2); nếu không được đặt,
+ mức ưu tiên mặc định thành {@link
+ android.support.v4.app.NotificationCompat#PRIORITY_DEFAULT} (0).
+</p>
+<p> Để biết thông tin về việc đặt một mức ưu tiên phù hợp, hãy xem phần "Đặt
+ và quản lý mức ưu tiên của thông báo cho đúng" trong hướng dẫn Thiết kế <a href="{@docRoot}design/patterns/notifications.html">Thông báo</a>
+.
+</p>
+<!-- ------------------------------------------------------------------------------------------ -->
+<h3 id="SimpleNotification">Tạo một thông báo đơn giản</h3>
+<p>
+ Đoạn mã HTML sau minh họa một thông báo đơn giản, trong đó quy định một hoạt động sẽ mở khi
+ người dùng nhấp vào thông báo. Để ý rằng đoạn mã này sẽ tạo một đối tượng
+ {@link android.support.v4.app.TaskStackBuilder} và sử dụng nó để tạo
+ {@link android.app.PendingIntent} cho hành động. Kiểu mẫu này được giải thích chi tiết hơn
+ trong phần <a href="#NotificationResponse">
+ Giữ lại Điều hướng khi Bắt đầu một Hoạt động</a>:
+</p>
+<pre>
+NotificationCompat.Builder mBuilder =
+ new NotificationCompat.Builder(this)
+ .setSmallIcon(R.drawable.notification_icon)
+ .setContentTitle("My notification")
+ .setContentText("Hello World!");
+// Creates an explicit intent for an Activity in your app
+Intent resultIntent = new Intent(this, ResultActivity.class);
+
+// The stack builder object will contain an artificial back stack for the
+// started Activity.
+// This ensures that navigating backward from the Activity leads out of
+// your application to the Home screen.
+TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
+// Adds the back stack for the Intent (but not the Intent itself)
+stackBuilder.addParentStack(ResultActivity.class);
+// Adds the Intent that starts the Activity to the top of the stack
+stackBuilder.addNextIntent(resultIntent);
+PendingIntent resultPendingIntent =
+ stackBuilder.getPendingIntent(
+ 0,
+ PendingIntent.FLAG_UPDATE_CURRENT
+ );
+mBuilder.setContentIntent(resultPendingIntent);
+NotificationManager mNotificationManager =
+ (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+// mId allows you to update the notification later on.
+mNotificationManager.notify(mId, mBuilder.build());
+</pre>
+<p>Vậy là xong. Người dùng của bạn hiện đã được thông báo.</p>
+<!-- ------------------------------------------------------------------------------------------ -->
+<h3 id="ApplyStyle">Áp dụng bố trí mở rộng cho một thông báo</h3>
+<p>
+ Để có một thông báo xuất hiện trong một dạng xem mở rộng, trước tiên hãy tạo một đối tượng
+ {@link android.support.v4.app.NotificationCompat.Builder} với các tùy chọn dạng xem thông thường
+ mà bạn muốn. Tiếp theo, hãy gọi {@link android.support.v4.app.NotificationCompat.Builder#setStyle
+ Builder.setStyle()} với một đối tượng bố trí mở rộng làm tham đối.
+</p>
+<p>
+ Ghi nhớ rằng các thông báo mở rộng không sẵn có trên các nền tảng trước Android 4.1. Để
+ tìm hiểu về cách xử lý thông báo đối với nền tảng phiên bản Android 4.1 và trước đó, hãy đọc
+ phần <a href="#Compatibility">Xử lý tính tương thích</a>.
+</p>
+<p>
+ Ví dụ, đoạn mã HTML sau minh họa cách thay đổi thông báo được tạo
+ trong đoạn mã HTML trước để sử dụng bố trí mở rộng:
+</p>
+<pre>
+NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
+ .setSmallIcon(R.drawable.notification_icon)
+ .setContentTitle("Event tracker")
+ .setContentText("Events received")
+NotificationCompat.InboxStyle inboxStyle =
+ new NotificationCompat.InboxStyle();
+String[] events = new String[6];
+// Sets a title for the Inbox in expanded layout
+inboxStyle.setBigContentTitle("Event tracker details:");
+...
+// Moves events into the expanded layout
+for (int i=0; i &lt; events.length; i++) {
+
+ inboxStyle.addLine(events[i]);
+}
+// Moves the expanded layout object into the notification object.
+mBuilder.setStyle(inBoxStyle);
+...
+// Issue the notification here.
+</pre>
+
+<h3 id="Compatibility">Xử lý tính tương thích</h3>
+
+<p>
+ Không phải tất cả tính năng thông báo đều sẵn có đối với một phiên bản cụ thể, mặc dù
+ các phương pháp đặt chúng đều nằm trong lớp thư viện hỗ trợ
+ {@link android.support.v4.app.NotificationCompat.Builder NotificationCompat.Builder}.
+ Ví dụ, nút hành động phụ thuộc vào thông báo mở rộng chỉ xuất hiện trên phiên bản Android
+ 4.1 trở lên, bởi bản thân thông báo mở rộng chỉ sẵn có trên phiên bản
+ Android 4.1 trở lên.
+</p>
+<p>
+ Để đảm bảo tính tương thích tốt nhất, hãy tạo thông báo bằng
+ {@link android.support.v4.app.NotificationCompat NotificationCompat} và các lớp con của nó,
+ đặc biệt là {@link android.support.v4.app.NotificationCompat.Builder
+ NotificationCompat.Builder}. Bên cạnh đó, hãy tuân theo tiến trình sau khi bạn triển khai một thông báo:
+</p>
+<ol>
+ <li>
+ Cung cấp tất cả tính năng thông báo cho tất cả người dùng, không phụ thuộc vào phiên bản
+ mà họ đang sử dụng. Để làm vậy, hãy xác minh rằng tất cả tính năng đều sẵn có từ một
+ {@link android.app.Activity} trong ứng dụng của bạn. Bạn có thể muốn thêm một
+ {@link android.app.Activity} mới để làm điều này.
+ <p>
+ Ví dụ, nếu bạn muốn sử dụng
+ {@link android.support.v4.app.NotificationCompat.Builder#addAction addAction()} để
+ cung cấp khả năng điều khiển dừng và bắt đầu phát lại phương tiện, trước tiên hãy triển khai khả năng
+ điều khiển này trong một {@link android.app.Activity} trong ứng dụng của bạn.
+ </p>
+ </li>
+ <li>
+ Đảm bảo rằng tất cả người dùng đều có thể tiếp cận với tính năng trong {@link android.app.Activity},
+ bằng cách cho nó khởi động khi người dùng nhấp vào thông báo. Để làm điều này,
+ hãy tạo một {@link android.app.PendingIntent}
+ cho {@link android.app.Activity}. Gọi
+ {@link android.support.v4.app.NotificationCompat.Builder#setContentIntent
+ setContentIntent()} để thêm {@link android.app.PendingIntent} vào thông báo.
+ </li>
+ <li>
+ Bây giờ, hãy thêm các tính năng thông báo mở rộng mà bạn muốn sử dụng vào thông báo. Ghi nhớ
+ rằng bất kỳ tính năng nào mà bạn thêm cũng phải sẵn có trong {@link android.app.Activity}
+ mà bắt đầu khi người dùng nhấp vào thông báo.
+ </li>
+</ol>
+
+
+<!-- ------------------------------------------------------------------------------------------ -->
+<!-- ------------------------------------------------------------------------------------------ -->
+<h2 id="Managing">Quản lý Thông báo</h2>
+<p>
+ Khi cần phát hành một thông báo nhiều lần cho cùng loại sự kiện, bạn
+ nên tránh tạo một thông báo hoàn toàn mới. Thay vào đó, bạn nên cân nhắc cập nhật
+ một thông báo trước đó, hoặc bằng cách thay đổi một vài giá trị hoặc bằng cách thêm vào nó, hoặc cả hai.
+</p>
+<p>
+ Ví dụ, Gmail thông báo với người dùng rằng e-mail mới đã đến bằng cách tăng số đếm
+ tin nhắn chưa đọc và bằng cách thêm một phần tóm tắt từng e-mail vào thông báo. Đây được gọi là
+ "xếp chồng" thông báo; nó được mô tả chi tiết hơn trong phần hướng dẫn Thiết kế
+ <a href="{@docRoot}design/patterns/notifications.html">Thông báo</a>.
+</p>
+<p class="note">
+ <strong>Lưu ý:</strong> Tính năng Gmail này yêu cầu bố trí mở rộng "hộp thư đến", đó là
+ một phần của tính năng thông báo mở rộng sẵn có bắt đầu từ Android 4.1.
+</p>
+<p>
+ Phần sau mô tả cách cập nhật thông báo và cả cách loại bỏ chúng.
+</p>
+<h3 id="Updating">Cập nhật thông báo</h3>
+<p>
+ Để thiết lập một thông báo để nó có thể được cập nhật, hãy phát hành nó cùng một ID thông báo bằng cách gọi
+ {@link android.app.NotificationManager#notify(int, android.app.Notification) NotificationManager.notify()}.
+ Để cập nhật thông báo sau khi bạn đã phát hành
+ nó, hãy cập nhật hoặc tạo một đối tượng {@link android.support.v4.app.NotificationCompat.Builder},
+ xây dựng một đối tượng {@link android.app.Notification} từ nó, và phát hành
+ {@link android.app.Notification} với cùng ID mà bạn đã sử dụng trước đó. Nếu
+ thông báo trước đó vẫn hiển thị, hệ thống sẽ cập nhật nó từ nội dung của
+ đối tượng {@link android.app.Notification}. Nếu thông báo trước đó đã bị bỏ đi, một
+ thông báo mới sẽ được tạo thay thế.
+</p>
+<p>
+ Đoạn mã HTML sau minh họa một thông báo được cập nhật để phản ánh
+ số sự kiện đã xảy ra. Nó xếp chồng thông báo, hiển thị một tóm tắt:
+</p>
+<pre>
+mNotificationManager =
+ (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+// Sets an ID for the notification, so it can be updated
+int notifyID = 1;
+mNotifyBuilder = new NotificationCompat.Builder(this)
+ .setContentTitle("New Message")
+ .setContentText("You've received new messages.")
+ .setSmallIcon(R.drawable.ic_notify_status)
+numMessages = 0;
+// Start of a loop that processes data and then notifies the user
+...
+ mNotifyBuilder.setContentText(currentText)
+ .setNumber(++numMessages);
+ // Because the ID remains unchanged, the existing notification is
+ // updated.
+ mNotificationManager.notify(
+ notifyID,
+ mNotifyBuilder.build());
+...
+</pre>
+
+<!-- ------------------------------------------------------------------------------------------ -->
+<h3 id="Removing">Loại bỏ thông báo</h3>
+<p>
+ Thông báo vẫn hiển thị cho tới khi xảy ra một trong những điều sau:
+</p>
+<ul>
+ <li>
+ Người dùng bỏ từng thông báo một hoặc bỏ tất cả bằng cách sử dụng "Xóa Tất cả" (nếu
+ thông báo có thể xóa được).
+ </li>
+ <li>
+ Người dùng nhấp vào thông báo và bạn đã gọi
+ {@link android.support.v4.app.NotificationCompat.Builder#setAutoCancel setAutoCancel()} khi
+ tạo thông báo.
+ </li>
+ <li>
+ Bạn gọi {@link android.app.NotificationManager#cancel(int) cancel()} cho một ID thông báo
+ cụ thể. Phương pháp này cũng xóa các thông báo đang diễn ra.
+ </li>
+ <li>
+ Bạn gọi {@link android.app.NotificationManager#cancelAll() cancelAll()}, nó sẽ xóa
+ tất cả thông báo mà bạn đã phát hành trước đó.
+ </li>
+</ul>
+<!-- ------------------------------------------------------------------------------------------ -->
+<!-- ------------------------------------------------------------------------------------------ -->
+<h2 id="NotificationResponse">Giữ lại Điều hướng khi Bắt đầu một Hoạt động</h2>
+<p>
+ Khi bạn bắt đầu một {@link android.app.Activity} từ một thông báo, bạn phải giữ lại trải nghiệm điều hướng kỳ vọng
+ của người dùng. Nhấp vào <i>Quay lại</i> sẽ đưa người dùng quay lại thông qua
+ tiến trình làm việc bình thường của ứng dụng về màn hình Trang chủ, và nhấp vào <i>Gần đây</i> sẽ hiển thị
+ {@link android.app.Activity} như một tác vụ riêng. Để giữ lại trải nghiệm điều hướng, bạn
+ nên bắt đầu {@link android.app.Activity} trong một tác vụ mới. Cách bạn thiết lập
+ {@link android.app.PendingIntent} để cấp cho bạn một tác vụ mới sẽ phụ thuộc vào tính chất của
+ {@link android.app.Activity} mà bạn đang bắt đầu. Có hai tình huống thông thường:
+</p>
+<dl>
+ <dt>
+ Hoạt động thường xuyên
+ </dt>
+ <dd>
+ Bạn đang bắt đầu một {@link android.app.Activity} là một phần của tiến trình công việc
+ bình thường của ứng dụng. Trong tình huống này, hãy thiết lập {@link android.app.PendingIntent} để
+ bắt đầu một tác vụ mới, và cung cấp {@link android.app.PendingIntent} với một ngăn xếp
+ có chức năng tái tạo lại hành vi thông thường <i>Quay lại</i> của ứng dụng.
+ <p>
+ Thông báo từ ứng dụng Gmail thể hiện điều này. Khi bạn nhấp vào một thông báo
+ cho một thư e-mail đơn lẻ, bạn sẽ thấy chính thư đó. Chạm vào <b>Quay lại</b> sẽ đưa bạn
+ ngược lại qua Gmail về màn hình Trang chủ, giống như thể bạn đã vào Gmail từ
+ màn hình Trang chủ chứ không phải vào từ một thông báo.
+ </p>
+ <p>
+ Điều này xảy ra mà không phụ thuộc vào ứng dụng bạn đang ở trong khi chạm vào
+ thông báo. Ví dụ, nếu bạn đang vào Gmail để soạn thư, và bạn nhấp vào một
+ thông báo cho một e-mail đơn lẻ, bạn sẽ đến e-mail đó ngay lập tức. Chạm vào <i>Quay lại</i>
+ sẽ đưa bạn về hộp thư đến rồi tới màn hình Trang chủ, thay vì đưa bạn tới
+ thư mà bạn đang soạn.
+ </p>
+ </dd>
+ <dt>
+ Hoạt động đặc biệt
+ </dt>
+ <dd>
+ Người dùng chỉ thấy {@link android.app.Activity} này nếu nó được bắt đầu từ một thông báo.
+ Nghĩa là, {@link android.app.Activity} mở rộng thông báo bằng cách cung cấp
+ thông tin mà sẽ khó hiển thị trong chính thông báo đó. Đối với tình huống này,
+ hãy thiết lập {@link android.app.PendingIntent} để bắt đầu một tác vụ mới. Tuy nhiên, không cần tạo
+ một ngăn xếp vì {@link android.app.Activity} được bắt đầu không phải là một phần trong
+ tiến trình hoạt động của ứng dụng. Nhấp vào <i>Quay lại</i> sẽ vẫn đưa người dùng đến
+ màn hình Trang chủ.
+ </dd>
+</dl>
+<!-- ------------------------------------------------------------------------------------------ -->
+<h3 id="DirectEntry">Thiết đặt một PendingIntent cho hoạt động thường xuyên</h3>
+<p>
+ Để thiết lập {@link android.app.PendingIntent} để bắt đầu một mục nhập trực tiếp
+ {@link android.app.Activity}, hãy làm theo những bước sau:
+</p>
+<ol>
+ <li>
+ Định nghĩa phân cấp {@link android.app.Activity} của ứng dụng của bạn trong bản kê khai.
+ <ol style="list-style-type: lower-alpha;">
+ <li>
+ Thêm hỗ trợ cho phiên bản Android 4.0.3 và trước đó. Để làm điều này, hãy quy định mẹ của
+ {@link android.app.Activity} mà bạn đang bắt đầu bằng cách thêm phần tử
+<code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html">&lt;meta-data&gt;</a></code>
+ làm con của
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>.
+ <p>
+ Đối với phần tử này, hãy đặt
+<code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html#nm">android:name</a>="android.support.PARENT_ACTIVITY"</code>.
+ Đặt
+<code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html#val">android:value</a>="&lt;parent_activity_name&gt;"</code>
+ trong đó <code>&lt;parent_activity_name&gt;</code> là giá trị của
+<code><a href="{@docRoot}guide/topics/manifest/meta-data-element.html#nm">android:name</a></code>
+ đối với phần tử
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
+ mẹ. Xem ví dụ trong XML sau.
+ </p>
+ </li>
+ <li>
+ Cũng thêm hỗ trợ cho phiên bản Android 4.1 và sau đó. Để làm điều này, hãy thêm thuộc tính
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#parent">android:parentActivityName</a></code>
+ vào phần tử
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
+ của {@link android.app.Activity} mà bạn đang bắt đầu.
+ </li>
+ </ol>
+ <p>
+ XML cuối cùng sẽ trông như sau:
+ </p>
+<pre>
+&lt;activity
+ android:name=".MainActivity"
+ android:label="&#64;string/app_name" &gt;
+ &lt;intent-filter&gt;
+ &lt;action android:name="android.intent.action.MAIN" /&gt;
+ &lt;category android:name="android.intent.category.LAUNCHER" /&gt;
+ &lt;/intent-filter&gt;
+&lt;/activity&gt;
+&lt;activity
+ android:name=".ResultActivity"
+ android:parentActivityName=".MainActivity"&gt;
+ &lt;meta-data
+ android:name="android.support.PARENT_ACTIVITY"
+ android:value=".MainActivity"/&gt;
+&lt;/activity&gt;
+</pre>
+ </li>
+ <li>
+ Tạo một ngăn xếp dựa trên {@link android.content.Intent} mà bắt đầu
+ {@link android.app.Activity}:
+ <ol style="list-style-type: lower-alpha;">
+ <li>
+ Tạo {@link android.content.Intent} để bắt đầu {@link android.app.Activity}.
+ </li>
+ <li>
+ Tạo một bộ dựng chồng bằng cách gọi {@link android.app.TaskStackBuilder#create
+ TaskStackBuilder.create()}.
+ </li>
+ <li>
+ Thêm ngăn xếp vào bộ dựng ngăn xếp bằng cách gọi
+ {@link android.support.v4.app.TaskStackBuilder#addParentStack addParentStack()}.
+ Đối với mỗi {@link android.app.Activity} trong phân cấp mà bạn đã định nghĩa trong
+ bản kê khai, ngăn xếp chứa một đối tượng {@link android.content.Intent} mà
+ sẽ khởi động {@link android.app.Activity}. Phương pháp này cũng thêm cờ có chức năng bắt đầu
+ chồng trong một tác vụ mới.
+ <p class="note">
+ <strong>Lưu ý:</strong> Mặc dù tham đối đến
+ {@link android.support.v4.app.TaskStackBuilder#addParentStack addParentStack()}
+ là một tham chiếu tới {@link android.app.Activity} được bắt đầu, phương pháp gọi
+ không thêm {@link android.content.Intent} có chức năng bắt đầu
+ {@link android.app.Activity}. Thay vào đó, nó được xử lý ở bước tiếp theo.
+ </p>
+ </li>
+ <li>
+ Thêm {@link android.content.Intent} có chức năng bắt đầu {@link android.app.Activity}
+ từ thông báo bằng cách gọi
+ {@link android.support.v4.app.TaskStackBuilder#addNextIntent addNextIntent()}.
+ Chuyển {@link android.content.Intent} mà bạn đã tạo ở bước đầu tiên làm
+ tham đối tới
+ {@link android.support.v4.app.TaskStackBuilder#addNextIntent addNextIntent()}.
+ </li>
+ <li>
+ Nếu bạn cần, hãy thêm các tham đối tới các đối tượng {@link android.content.Intent} trên chồng
+ bằng cách gọi {@link android.support.v4.app.TaskStackBuilder#editIntentAt
+ TaskStackBuilder.editIntentAt()}. Đôi khi cần phải đảm bảo rằng
+ {@link android.app.Activity} mục tiêu sẽ hiển thị dữ liệu có ý nghĩa khi người dùng điều hướng
+ tới nó bằng cách sử dụng <i>Quay lại</i>.
+ </li>
+ <li>
+ Nhận một {@link android.app.PendingIntent} cho ngăn xếp này bằng cách gọi
+ {@link android.support.v4.app.TaskStackBuilder#getPendingIntent getPendingIntent()}.
+ Sau đó, bạn có thể sử dụng {@link android.app.PendingIntent} này làm tham đối tới
+ {@link android.support.v4.app.NotificationCompat.Builder#setContentIntent
+ setContentIntent()}.
+ </li>
+ </ol>
+ </li>
+</ol>
+<p>
+ Đoạn mã HTML sau minh họa tiến trình:
+</p>
+<pre>
+...
+Intent resultIntent = new Intent(this, ResultActivity.class);
+TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
+// Adds the back stack
+stackBuilder.addParentStack(ResultActivity.class);
+// Adds the Intent to the top of the stack
+stackBuilder.addNextIntent(resultIntent);
+// Gets a PendingIntent containing the entire back stack
+PendingIntent resultPendingIntent =
+ stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
+...
+NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
+builder.setContentIntent(resultPendingIntent);
+NotificationManager mNotificationManager =
+ (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+mNotificationManager.notify(id, builder.build());
+</pre>
+<!-- ------------------------------------------------------------------------------------------ -->
+<h3 id="ExtendedNotification">Thiết đặt một PendingIntent cho hoạt động đặc biệt</h3>
+<p>
+ Phần sau mô tả cách thiết lập một
+ {@link android.app.PendingIntent} cho hoạt động đặc biệt.
+</p>
+<p>
+ Một {@link android.app.Activity} đặc biệt không cần ngăn xếp, vì thế bạn không phải
+ định nghĩa phân cấp {@link android.app.Activity} của nó trong bản kê khai, và bạn không phải
+ gọi
+ {@link android.support.v4.app.TaskStackBuilder#addParentStack addParentStack()} để xây dựng một
+ ngăn xếp. Thay vào đó, hãy sử dụng bản kê khai để thiết lập các tùy chọn tác vụ {@link android.app.Activity},
+ và tạo {@link android.app.PendingIntent} bằng cách gọi
+ {@link android.app.PendingIntent#getActivity getActivity()}:
+</p>
+<ol>
+ <li>
+ Trong bản kê khai của mình, hãy thêm các thuộc tính sau vào phần tử
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html">&lt;activity&gt;</a></code>
+ cho {@link android.app.Activity}
+ <dl>
+ <dt>
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#nm">android:name</a>="<i>activityclass</i>"</code>
+ </dt>
+ <dd>
+ Tên lớp được xác định đầy đủ của hoạt động.
+ </dd>
+ <dt>
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#aff">android:taskAffinity</a>=""</code>
+ </dt>
+ <dd>
+ Kết hợp với cờ
+ {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_NEW_TASK}
+ mà bạn đặt trong mã, điều này đảm bảo rằng {@link android.app.Activity} này không
+ đi đến tác vụ mặc định của ứng dụng. Bất kỳ tác vụ hiện tại nào mà có
+ bố trí mặc định của ứng dụng đều không bị ảnh hưởng.
+ </dd>
+ <dt>
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html#exclude">android:excludeFromRecents</a>="true"</code>
+ </dt>
+ <dd>
+ Loại bỏ tác vụ mới khỏi <i>Gần đây</i>, sao cho người dùng không thể vô tình
+ điều hướng quay lại nó.
+ </dd>
+ </dl>
+ <p>
+ Đoạn mã HTML này thể hiện phần tử:
+ </p>
+<pre>
+&lt;activity
+ android:name=".ResultActivity"
+...
+ android:launchMode="singleTask"
+ android:taskAffinity=""
+ android:excludeFromRecents="true"&gt;
+&lt;/activity&gt;
+...
+</pre>
+ </li>
+ <li>
+ Xây dựng và phát hành thông báo:
+ <ol style="list-style-type: lower-alpha;">
+ <li>
+ Tạo một {@link android.content.Intent} có chức năng bắt đầu
+ {@link android.app.Activity}.
+ </li>
+ <li>
+ Đặt {@link android.app.Activity} để bắt đầu trong một tác vụ mới, trống bằng cách gọi
+ {@link android.content.Intent#setFlags setFlags()} với các cờ
+ {@link android.content.Intent#FLAG_ACTIVITY_NEW_TASK FLAG_ACTIVITY_NEW_TASK}
+ và
+ {@link android.content.Intent#FLAG_ACTIVITY_CLEAR_TASK FLAG_ACTIVITY_CLEAR_TASK}.
+ </li>
+ <li>
+ Đặt bất kỳ tùy chọn nào khác mà bạn cần cho {@link android.content.Intent}.
+ </li>
+ <li>
+ Tạo một {@link android.app.PendingIntent} từ {@link android.content.Intent}
+ bằng cách gọi {@link android.app.PendingIntent#getActivity getActivity()}.
+ Sau đó, bạn có thể sử dụng {@link android.app.PendingIntent} này làm tham đối tới
+ {@link android.support.v4.app.NotificationCompat.Builder#setContentIntent
+ setContentIntent()}.
+ </li>
+ </ol>
+ <p>
+ Đoạn mã HTML sau minh họa tiến trình:
+ </p>
+<pre>
+// Instantiate a Builder object.
+NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
+// Creates an Intent for the Activity
+Intent notifyIntent =
+ new Intent(this, ResultActivity.class);
+// Sets the Activity to start in a new, empty task
+notifyIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
+ | Intent.FLAG_ACTIVITY_CLEAR_TASK);
+// Creates the PendingIntent
+PendingIntent notifyPendingIntent =
+ PendingIntent.getActivity(
+ this,
+ 0,
+ notifyIntent,
+ PendingIntent.FLAG_UPDATE_CURRENT
+);
+
+// Puts the PendingIntent into the notification builder
+builder.setContentIntent(notifyPendingIntent);
+// Notifications are issued by sending them to the
+// NotificationManager system service.
+NotificationManager mNotificationManager =
+ (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+// Builds an anonymous Notification object from the builder, and
+// passes it to the NotificationManager
+mNotificationManager.notify(id, builder.build());
+</pre>
+ </li>
+</ol>
+<!-- ------------------------------------------------------------------------------------------ -->
+<!-- ------------------------------------------------------------------------------------------ -->
+<h2 id="Progress">Hiển thị Tiến độ trong một Thông báo</h2>
+<p>
+ Thông báo có thể bao gồm một chỉ báo tiến độ dạng hoạt ảnh để cho người dùng thấy trạng thái
+ của một thao tác đang diễn ra. Nếu bạn có thể ước lượng thao tác mất bao lâu và nó được
+ được hoàn thành bao nhiêu vào bất cứ lúc nào, hãy sử dụng hình thức "xác định" của chỉ báo
+ (thanh tiến độ). Nếu bạn không thể ước lượng thời lượng của thao tác, hãy sử dụng hình thức
+ "không xác định" của chỉ báo (chỉ báo hoạt động).
+</p>
+<p>
+ Chỉ báo tiến độ được hiển thị bằng triển khai lớp
+ {@link android.widget.ProgressBar} của nền tảng.
+</p>
+<p>
+ Để sử dụng chỉ báo tiến độ trên các nền tảng bắt đầu từ Android 4.0, hãy gọi
+ {@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress()}. Đối
+ với các phiên bản trước đây, bạn phải tạo bố trí thông báo tùy chỉnh của chính mình
+ trong đó chứa một dạng xem {@link android.widget.ProgressBar}.
+</p>
+<p>
+ Phần sau đây mô tả cách hiển thị tiến độ trong một thông báo bằng cách sử dụng
+ {@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress()}.
+</p>
+<!-- ------------------------------------------------------------------------------------------ -->
+<h3 id="FixedProgress">Hiển thị một chỉ báo tiến độ thời lượng cố định</h3>
+<p>
+ Để hiển thị một thanh tiến độ xác định, hãy thêm thanh vào thông báo của bạn bằng cách gọi
+ {@link android.support.v4.app.NotificationCompat.Builder#setProgress
+ setProgress(max, progress, false)} rồi phát hành thông báo. Khi thông báo của bạn tiến hành,
+ tăng dần<code>progress</code>, và cập nhật thông báo. Khi kết thúc thao tác,
+ <code>progress</code> sẽ bằng <code>max</code>. Một cách thông thường để gọi
+ {@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress()}
+ đó là đặt <code>max</code> thành 100 rồi tăng dần <code>progress</code> dưới dạng giá trị
+ "phần trăm hoàn thành" cho thao tác.
+</p>
+<p>
+ Bạn có thể hoặc để thanh tiến độ hiển thị khi nào thì thao tác hoàn thành, hoặc loại bỏ nó. Dù
+ trong trường hợp nào hãy nhớ cập nhật văn bản thông báo để hiển thị thao tác hoàn tất.
+ Để loại bỏ thanh tiến độ, hãy gọi
+ {@link android.support.v4.app.NotificationCompat.Builder#setProgress
+ setProgress(0, 0, false)}. Ví dụ:
+</p>
+<pre>
+...
+mNotifyManager =
+ (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
+mBuilder = new NotificationCompat.Builder(this);
+mBuilder.setContentTitle("Picture Download")
+ .setContentText("Download in progress")
+ .setSmallIcon(R.drawable.ic_notification);
+// Start a lengthy operation in a background thread
+new Thread(
+ new Runnable() {
+ &#64;Override
+ public void run() {
+ int incr;
+ // Do the "lengthy" operation 20 times
+ for (incr = 0; incr &lt;= 100; incr+=5) {
+ // Sets the progress indicator to a max value, the
+ // current completion percentage, and "determinate"
+ // state
+ mBuilder.setProgress(100, incr, false);
+ // Displays the progress bar for the first time.
+ mNotifyManager.notify(0, mBuilder.build());
+ // Sleeps the thread, simulating an operation
+ // that takes time
+ try {
+ // Sleep for 5 seconds
+ Thread.sleep(5*1000);
+ } catch (InterruptedException e) {
+ Log.d(TAG, "sleep failure");
+ }
+ }
+ // When the loop is finished, updates the notification
+ mBuilder.setContentText("Download complete")
+ // Removes the progress bar
+ .setProgress(0,0,false);
+ mNotifyManager.notify(ID, mBuilder.build());
+ }
+ }
+// Starts the thread by calling the run() method in its Runnable
+).start();
+</pre>
+
+<!-- ------------------------------------------------------------------------------------------ -->
+<h3 id="ActivityIndicator">Hiển thị một chỉ báo hoạt động liên tục</h3>
+<p>
+ Để hiển thị một chỉ báo hoạt động không xác định, hãy thêm nó vào thông báo của bạn bằng
+ {@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress(0, 0, true)}
+ (hai tham đối đầu tiên bị bỏ qua), và phát hành thông báo. Kết quả là một chỉ báo
+ mà có cùng kiểu như một thanh tiến độ, khác ở chỗ hoạt ảnh của nó đang diễn ra.
+</p>
+<p>
+ Phát hành thông báo khi bắt đầu thao tác. Hoạt ảnh sẽ chạy tới khi bạn
+ sửa đổi thông báo của mình. Khi thao tác hoàn thành, hãy gọi
+ {@link android.support.v4.app.NotificationCompat.Builder#setProgress setProgress(0, 0, false)}
+ và rồi cập nhật thông báo để loại bỏ chỉ báo hoạt động.
+ Luôn làm điều này; nếu không, hoạt ảnh sẽ chạy ngay cả khi thao tác đã hoàn thành. Đồng thời
+ hãy nhớ thay đổi văn bản thông báo để biểu thị thao tác hoàn tất.
+</p>
+<p>
+ Để xem chỉ báo hoạt động vận hành như thế nào, hãy tham khảo đoạn mã HTML trước. Định vị các dòng sau:
+</p>
+<pre>
+// Sets the progress indicator to a max value, the current completion
+// percentage, and "determinate" state
+mBuilder.setProgress(100, incr, false);
+// Issues the notification
+mNotifyManager.notify(0, mBuilder.build());
+</pre>
+<p>
+ Thay thế các dòng bạn đã tìm thấy bằng các dòng sau:
+</p>
+<pre>
+ // Sets an activity indicator for an operation of indeterminate length
+mBuilder.setProgress(0, 0, true);
+// Issues the notification
+mNotifyManager.notify(0, mBuilder.build());
+</pre>
+
+<h2 id="metadata">Siêu dữ liệu Thông báo</h2>
+
+<p>Thông báo có thể được sắp xếp theo siêu dữ liệu mà bạn gán cho bằng các
+phương pháp {@link android.support.v4.app.NotificationCompat.Builder} sau:</p>
+
+<ul>
+ <li>{@link android.support.v4.app.NotificationCompat.Builder#setCategory(java.lang.String) setCategory()}
+ thông báo hệ thống cách xử lý thông báo ứng dụng của bạn khi thiết bị đang trong chế độ Ưu tiên
+ (ví dụ, nếu thông báo của bạn biểu diễn một cuộc gọi đến, tin nhắn tức thời hoặc báo thức).</li>
+ <li>{@link android.support.v4.app.NotificationCompat.Builder#setPriority(int) setPriority()} khiến
+ thông báo với trường mức ưu tiên được đặt thành {@code PRIORITY_MAX} hoặc {@code PRIORITY_HIGH} xuất hiện
+ trong một cửa sổ nổi nhỏ nếu thông báo cũng có âm thanh hoặc rung.</li>
+ <li>{@link android.support.v4.app.NotificationCompat.Builder#addPerson(java.lang.String) addPerson()}
+ cho phép bạn thêm một danh sách người vào thông báo. Ứng dụng của bạn có thể sử dụng tín hiệu này cho
+ hệ thống mà nó sẽ nhóm cùng với thông báo từ những người được quy định, hoặc xếp hạng thông báo
+ từ những người này là quan trọng hơn.</li>
+</ul>
+
+<div class="figure" style="width:230px">
+ <img src="{@docRoot}images/ui/notifications/heads-up.png" alt="" width="" height="" id="figure3" />
+ <p class="img-caption">
+ <strong>Hình 3.</strong> Hoạt động toàn màn hình thể hiện một thông báo cảnh báo
+ </p>
+</div>
+
+<h2 id="Heads-up">Thông báo Cảnh báo</h2>
+
+<p>Với Android 5.0 (API mức 21), thông báo có thể xuất hiện trong một cửa sổ nổi nhỏ
+(còn gọi là <em>thông báo cảnh báo</em>) khi thiết bị hiện hoạt
+(tức là thiết bị được mở khóa và màn hình của nó đang bật). Những thông báo
+này có vẻ tương tự như dạng rút gọn thông báo của bạn, chỉ khác là
+thông báo cảnh báo cũng hiển thị các nút hành động. Người dùng có thể hành động trên đó, hoặc bỏ,
+một thông báo cảnh báo mà không phải rời khỏi ứng dụng hiện tại.</p>
+
+<p>Các ví dụ về điều kiện có thể kích khởi thông báo cảnh báo bao gồm:</p>
+
+<ul>
+ <li>Hoạt động của người dùng đang trong chế độ toàn màn hình (ứng dụng sử dụng
+{@link android.app.Notification#fullScreenIntent}), hoặc</li>
+ <li>Thông báo có mức ưu tiên cao và sử dụng nhạc chuông hoặc
+ rung</li>
+</ul>
+
+<h2 id="lockscreenNotification">Thông báo Màn hình Khóa</h2>
+
+<p>Với việc phát hành Android 5.0 (API mức 21), giờ đây thông báo có thể xuất hiện trên màn hình
+khóa. Ứng dụng của bạn có thể sử dụng tính năng này để cung cấp các chức năng điều khiển phát lại phương tiện và các hành động
+thông dụng khác. Người dùng có thể chọn thông qua Cài đặt để xem có hiển thị thông báo trên màn hình khóa không, và
+bạn có thể chỉ định xem thông báo từ ứng dụng của mình có hiển thị trên màn hình khóa không.</p>
+
+<h3 id="visibility">Thiết đặt Khả năng Hiển thị</h3>
+
+<p>Ứng dụng của bạn có thể điều khiển mức chi tiết có thể nhìn thấy được trong thông báo được hiển thị trên một
+màn hình khóa bảo mật. Bạn gọi {@link android.support.v4.app.NotificationCompat.Builder#setVisibility(int) setVisibility()}
+và quy định một trong những giá trị sau:</p>
+
+<ul>
+ <li>{@link android.support.v4.app.NotificationCompat#VISIBILITY_PUBLIC} hiển thị đầy đủ nội dung của
+ thông báo.</li>
+ <li>{@link android.support.v4.app.NotificationCompat#VISIBILITY_SECRET} không hiển thị bất kỳ phần nào của
+ thông báo này trên màn hình khóa.</li>
+ <li>{@link android.support.v4.app.NotificationCompat#VISIBILITY_PRIVATE} hiển thị thông tin cơ bản,
+ chẳng hạn như biểu tượng và tiêu đề nội dung của thông báo, nhưng ẩn nội dung đầy đủ của thông báo.</li>
+</ul>
+
+<p>Khi {@link android.support.v4.app.NotificationCompat#VISIBILITY_PRIVATE} được đặt, bạn cũng có thể
+cung cấp một phiên bản thay thế cho nội dung thông báo, trong đó ẩn một số chi tiết nhất định. Ví dụ,
+một ứng dụng SMS có thể hiển thị một thông báo hiển thị <em>Bạn có 3 tin nhắn văn bản mới</em>, nhưng ẩn
+nội dung của tin nhắn và người gửi. Để cung cấp thông báo thay thế này, trước tiên hãy tạo thông báo
+thay thế bằng cách sử dụng {@link android.support.v4.app.NotificationCompat.Builder}. Khi bạn tạo
+đối tượng thông báo riêng tư, hãy đính kèm thông báo thay thế cho nó thông qua phương pháp
+{@link android.support.v4.app.NotificationCompat.Builder#setPublicVersion(android.app.Notification) setPublicVersion()}
+.</p>
+
+<h3 id="controllingMedia">Điều khiển Phát lại Phương tiện trên Màn hình Khóa</h3>
+
+<p>Trong Android 5.0 (API mức 21) màn hình khóa không còn hiển thị điều khiển phương tiện
+dựa trên {@link android.media.RemoteControlClient}, điều mà nay đã bị bỏ đi. Thay vào đó, hãy sử dụng mẫu
+{@link android.app.Notification.MediaStyle} với phương pháp
+{@link android.app.Notification.Builder#addAction(android.app.Notification.Action) addAction()}
+, có chức năng chuyển hành động thành các biểu tượng có thể nhấp.</p>
+
+<p class="note"><strong>Lưu ý:</strong> Mẫu và phương pháp {@link android.app.Notification.Builder#addAction(android.app.Notification.Action) addAction()}
+không nằm trong thư viện hỗ trợ, vì thế những tính năng này chỉ chạy trong phiên bản Android 5.0 trở lên
+.</p>
+
+<p>Để hiển thị điều khiển phát lại phương tiện trên màn hình khóa trong Android 5.0, hãy đặt mức độ nhìn thấy
+thành {@link android.support.v4.app.NotificationCompat#VISIBILITY_PUBLIC}, như mô tả bên trên. Sau đó thêm
+các hành động và đặt mẫu {@link android.app.Notification.MediaStyle}, như được mô tả trong
+đoạn mã mẫu sau:</p>
+
+<pre>
+Notification notification = new Notification.Builder(context)
+ // Show controls on lock screen even when user hides sensitive content.
+ .setVisibility(Notification.VISIBILITY_PUBLIC)
+ .setSmallIcon(R.drawable.ic_stat_player)
+ // Add media control buttons that invoke intents in your media service
+ .addAction(R.drawable.ic_prev, "Previous", prevPendingIntent) // #0
+ .addAction(R.drawable.ic_pause, "Pause", pausePendingIntent) // #1
+ .addAction(R.drawable.ic_next, "Next", nextPendingIntent) // #2
+ // Apply the media style template
+ .setStyle(new Notification.MediaStyle()
+ .setShowActionsInCompactView(1 /* #1: pause button */)
+ .setMediaSession(mMediaSession.getSessionToken())
+ .setContentTitle("Wonderful music")
+ .setContentText("My Awesome Band")
+ .setLargeIcon(albumArtBitmap)
+ .build();
+</pre>
+
+<p class="note"><strong>Lưu ý:</strong> Việc rút bỏ {@link android.media.RemoteControlClient}
+còn có nhiều ý nghĩa khác đối với việc điều khiển phương tiện. Xem phần
+<a href="{@docRoot}about/versions/android-5.0.html#MediaPlaybackControl">Điều khiển Phát lại Phương tiện</a>
+để biết thêm thông tin về các API mới đối với quản lý phiên phương tiện và điều khiển phát lại này.</p>
+
+
+<!-- ------------------------------------------------------------------------------------------ -->
+<h2 id="CustomNotification">Bố trí Thông báo Tùy chỉnh</h2>
+<p>
+ Khuôn khổ thông báo cho phép bạn định nghĩa một bố trí thông báo tùy chỉnh, nó
+ định nghĩa hình thức của thông báo trong một đối tượng {@link android.widget.RemoteViews}.
+ Thông báo có bố trí tùy chỉnh tương tự như thông báo thường, nhưng chúng được dựa trên
+ {@link android.widget.RemoteViews} được định nghĩa trong một tệp bố trí XML.
+</p>
+<p>
+ Chiều cao sẵn có cho bố trí thông báo tùy chỉnh phụ thuộc vào dạng xem thông báo. Bố trí dạng xem bình thường
+ được giới hạn ở 64 dp, và bố trí dạng xem mở rộng được giới hạn ở 256 dp.
+</p>
+<p>
+ Để định nghĩa một bố trí thông báo tùy chỉnh, hãy bắt đầu bằng việc khởi tạo đối tượng
+ {@link android.widget.RemoteViews} để bung một tệp bố trí XML. Sau đó,
+ thay vì gọi các phương pháp như
+ {@link android.support.v4.app.NotificationCompat.Builder#setContentTitle setContentTitle()},
+ hãy gọi {@link android.support.v4.app.NotificationCompat.Builder#setContent setContent()}. Để đặt
+ chi tiết nội dung trong thông báo tùy chỉnh, hãy sử dụng các phương pháp
+ {@link android.widget.RemoteViews} để đặt giá trị của các tập con của dạng xem:
+</p>
+<ol>
+ <li>
+ Tạo một bố trí XML cho thông báo trong một tệp riêng. Bạn có thể sử dụng bất kỳ tên tệp nào
+ mà bạn muốn, nhưng phải sử dụng phần mở rộng <code>.xml</code>
+ </li>
+ <li>
+ Trong ứng dụng của bạn, hãy sử dụng các phương pháp {@link android.widget.RemoteViews} để định nghĩa các biểu tượng và văn bản
+ của thông báo của bạn. Đặt đối tượng {@link android.widget.RemoteViews} này vào
+ {@link android.support.v4.app.NotificationCompat.Builder} của bạn bằng cách gọi
+ {@link android.support.v4.app.NotificationCompat.Builder#setContent setContent()}. Tránh
+ đặt một {@link android.graphics.drawable.Drawable} nền trên đối tượng
+ {@link android.widget.RemoteViews} của bạn, vì màu văn bản của bạn có thể không đọc được.
+ </li>
+</ol>
+<p>
+ Lớp {@link android.widget.RemoteViews} cũng bao gồm các phương pháp mà bạn có thể sử dụng để dễ dạng
+ thêm một {@link android.widget.Chronometer} hoặc {@link android.widget.ProgressBar}
+ vào bố trí thông báo của bạn. Để biết thêm thông tin về việc tạo bố trí tùy chỉnh cho thông báo
+ của mình, hãy tham khảo tài liệu tham khảo {@link android.widget.RemoteViews}.
+</p>
+<p class="caution">
+ <strong>Chú ý:</strong> Khi bạn sử dụng một bố trí thông báo tùy chỉnh, hãy đặc biệt cẩn thận
+ để đảm bảo rằng bố trí tùy chỉnh của bạn có tác dụng với các hướng và độ phân giải thiết bị khác nhau. Trong khi
+ lời khuyên này áp dụng cho tất cả bố trí Dạng xem, nó đặc biệt quan trọng đối với thông báo
+ vì khoảng trống trong ngăn kéo thông báo rất hạn chế. Không được tạo bố trí tùy chỉnh của bạn quá
+ phức tạp và đảm bảo kiểm tra nó trong các cấu hình khác nhau.
+</p>
+<!-- ------------------------------------------------------------------------------------------ -->
+<h4>Sử dụng các tài nguyên kiểu cho văn bản thông báo tùy chỉnh</h4>
+<p>
+ Luôn sử dụng tài nguyên kiểu cho văn bản của một thông báo tùy chỉnh. Màu nền của thông báo
+ có thể thay đổi giữa các thiết bị và phiên bản khác nhau, và việc sử dụng tài nguyên kiểu
+ sẽ giúp bạn khắc phục điều này. Bắt đầu từ Android 2.3, hệ thống đã định nghĩa kiểu cho
+ văn bản bố trí thông báo chuẩn. Nếu bạn sử dụng cùng kiểu trong các ứng dụng nhắm đến phiên bản Android
+ 2.3 hoặc cao hơn, bạn sẽ phải đảm bảo rằng văn bản của bạn nhìn thấy được trên nền hiển thị.
+</p>
diff --git a/docs/html-intl/intl/vi/guide/topics/ui/overview.jd b/docs/html-intl/intl/vi/guide/topics/ui/overview.jd
new file mode 100644
index 000000000000..7bd45527c7b4
--- /dev/null
+++ b/docs/html-intl/intl/vi/guide/topics/ui/overview.jd
@@ -0,0 +1,71 @@
+page.title=Tổng quan về UI
+@jd:body
+
+
+<p>Tất cả phần tử giao diện người dùng trong một ứng dụng Android đều được xây dựng bằng cách sử dụng các đối tượng {@link android.view.View} và
+{@link android.view.ViewGroup}. {@link android.view.View} là một đối tượng có chức năng vẽ
+thứ gì đó trên màn hình mà người dùng có thể tương tác với. {@link android.view.ViewGroup} là một đối tượng
+có chức năng giữ các đối tượng {@link android.view.View} (và {@link android.view.ViewGroup}) khác
+để định nghĩa bố trí của giao diện.</p>
+
+<p>Android cung cấp một bộ sưu tập cả lớp con {@link android.view.View} và {@link
+android.view.ViewGroup} cung cấp cho bạn các cách điều khiển nhập liệu thông dụng (chẳng hạn như nút và
+trường văn bản) và các mô hình bố trí khác nhau (chẳng hạn như bố trí tuyến tính hoặc tương đối).</p>
+
+
+<h2 id="Layout">Bố trí Giao diện Người dùng</h2>
+
+<p>Giao diện người dùng của từng thành phần trong ứng dụng của bạn được định nghĩa bằng cách sử dụng một phân cấp của các đối tượng {@link
+android.view.View} và {@link android.view.ViewGroup} như minh họa trong hình 1. Mỗi nhóm dạng xem
+là một bộ chứa vô hình có chức năng tổ chức các dạng xem con, trong khi dạng xem con có thể là
+điều khiển nhập liệu hoặc các widget khác để
+vẽ một phần nào đó của UI. Cây phân cấp này có thể đơn giản hoặc phức tạp như nhu cầu
+của bạn (nhưng đơn giản sẽ tốt cho hiệu năng).</p>
+
+<img src="{@docRoot}images/viewgroup.png" alt="" />
+<p class="img-caption"><strong>Hình 1.</strong> Minh họa một phân cấp dạng xem có chức năng định nghĩa một
+bố trí UI.</p>
+
+<p>Để khai báo bố trí của mình, bạn có thể khởi tạo các đối tượng {@link android.view.View} trong mã và bắt đầu
+xây dựng một cây, nhưng cách dễ nhất và hiệu quả nhất để định nghĩa bố trí của bạn đó là bằng một tệp XML.
+XML cung cấp một cấu trúc mà người dùng có thể đọc được cho bố trí, tương tự như HTML.</p>
+
+<p>Tên của phần tử XML đối với một dạng xem tương ứng với lớp Android mà nó biểu diễn. Vì thế một phần tử
+<code>&lt;TextView&gt;</code> tạo ra một widget {@link android.widget.TextView} trong UI của bạn,
+và một phần tử <code>&lt;LinearLayout&gt;</code> tạo ra một nhóm dạng xem {@link android.widget.LinearLayout}
+. </p>
+
+<p>Ví dụ, một bố trí thẳng đứng đơn giản với dạng xem văn bản và nút trông như sau:</p>
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical" >
+ &lt;TextView android:id="@+id/text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="I am a TextView" />
+ &lt;Button android:id="@+id/button"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="I am a Button" />
+&lt;/LinearLayout>
+</pre>
+
+<p>Khi bạn tải một tài nguyên bố trí trong ứng dụng của mình, Android khởi tạo từng nút của bố trí vào một
+đối tượng thời gian chạy mà bạn có thể sử dụng để định nghĩa các hành vi bổ sung, truy vấn trạng thái của đối tượng hoặc sửa đổi
+bố trí.</p>
+
+<p>Để xem hướng dẫn đầy đủ về tạo bố trí UI, hãy xem phần <a href="declaring-layout.html">Bố trí
+XML</a>.
+
+
+<h2 id="UIComponents">Thành phần Giao diện Người dùng</h2>
+
+<p>Bạn không phải xây dựng tất cả UI của mình bằng cách sử dụng các đối tượng {@link android.view.View} và {@link
+android.view.ViewGroup}. Android cung cấp một vài thành phần ứng dụng đưa ra một
+bố trí UI chuẩn mà bạn chỉ cần định nghĩa nội dung cho nó. Mỗi thành phần UI như vậy
+đều có một bộ API duy nhất được mô tả trong các tài liệu tương ứng, chẳng hạn như <a href="{@docRoot}guide/topics/ui/actionbar.html">Thanh Hành động</a>, <a href="{@docRoot}guide/topics/ui/dialogs.html">Hộp thoại</a> và <a href="{@docRoot}guide/topics/ui/notifiers/notifications.html">Thông báo Trạng thái</a>.</p>
+
+
diff --git a/docs/html-intl/intl/vi/guide/topics/ui/settings.jd b/docs/html-intl/intl/vi/guide/topics/ui/settings.jd
new file mode 100644
index 000000000000..8e19b979d0ac
--- /dev/null
+++ b/docs/html-intl/intl/vi/guide/topics/ui/settings.jd
@@ -0,0 +1,1202 @@
+page.title=Thiết đặt
+page.tags=preference,preferenceactivity,preferencefragment
+
+@jd:body
+
+
+<div id="qv-wrapper">
+<div id="qv">
+
+<h2>Trong tài liệu này</h2>
+<ol>
+ <li><a href="#Overview">Tổng quan</a>
+ <ol>
+ <li><a href="#SettingTypes">Tùy chọn</a></li>
+ </ol>
+ </li>
+ <li><a href="#DefiningPrefs">Định nghĩa Tùy chọn trong XML</a>
+ <ol>
+ <li><a href="#Groups">Tạo nhóm thiết đặt</a></li>
+ <li><a href="#Intents">Sử dụng ý định</a></li>
+ </ol>
+ </li>
+ <li><a href="#Activity">Tạo một Hoạt động Tùy chọn</a></li>
+ <li><a href="#Fragment">Sử dụng Phân đoạn Tùy chọn</a></li>
+ <li><a href="#Defaults">Thiết đặt Giá trị Mặc định</a></li>
+ <li><a href="#PreferenceHeaders">Sử dụng Tiêu đề Tùy chọn</a>
+ <ol>
+ <li><a href="#CreateHeaders">Tạo tệp tiêu đề</a></li>
+ <li><a href="#DisplayHeaders">Hiển thị tiêu đề</a></li>
+ <li><a href="#BackCompatHeaders">Hỗ trợ các phiên bản cũ hơn với tiêu đề tùy chọn</a></li>
+ </ol>
+ </li>
+ <li><a href="#ReadingPrefs">Đọc Tùy chọn</a>
+ <ol>
+ <li><a href="#Listening">Theo dõi thay đổi tùy chọn</a></li>
+ </ol>
+ </li>
+ <li><a href="#NetworkUsage">Quản lý Sử dụng Mạng</a></li>
+ <li><a href="#Custom">Xây dựng một Thiết đặt Tùy chỉnh</a>
+ <ol>
+ <li><a href="#CustomSelected">Quy định một giao diện người dùng</a></li>
+ <li><a href="#CustomSave">Lưu giá trị của thiết đặt</a></li>
+ <li><a href="#CustomInitialize">Khởi tạo giá trị hiện tại</a></li>
+ <li><a href="#CustomDefault">Cung cấp một giá trị mặc định</a></li>
+ <li><a href="#CustomSaveState">Lưu và khôi phục trạng thái của Tùy chọn</a></li>
+ </ol>
+ </li>
+</ol>
+
+<h2>Lớp khóa</h2>
+<ol>
+ <li>{@link android.preference.Preference}</li>
+ <li>{@link android.preference.PreferenceActivity}</li>
+ <li>{@link android.preference.PreferenceFragment}</li>
+</ol>
+
+
+<h2>Xem thêm</h2>
+<ol>
+ <li><a href="{@docRoot}design/patterns/settings.html">Hướng dẫn thiết kế Thiết đặt</a></li>
+</ol>
+</div>
+</div>
+
+
+
+
+<p>Ứng dụng thường bao gồm những thiết đặt cho phép người dùng sửa đổi các tính năng và hành vi của ứng dụng. Ví
+dụ, một số ứng dụng cho phép người dùng quy định xem thông báo có được kích hoạt hay không hoặc quy định tần suất
+ứng dụng sẽ đồng bộ dữ liệu với đám mây.</p>
+
+<p>Nếu muốn cung cấp thiết đặt cho ứng dụng của mình, bạn nên sử dụng
+các API {@link android.preference.Preference} của Android để xây dựng một giao diện phù hợp với
+trải nghiệm người dùng trong các ứng dụng Android khác (bao gồm thiết đặt hệ thống). Tài liệu này mô tả
+cách xây dựng thiết đặt ứng dụng của bạn bằng cách sử dụng các API {@link android.preference.Preference}.</p>
+
+<div class="note design">
+<p><strong>Thiết kế Thiết đặt</strong></p>
+ <p>Để biết thông tin về cách thiết kế thiết đặt của bạn, hãy đọc hướng dẫn thiết kế <a href="{@docRoot}design/patterns/settings.html">Thiết đặt</a>.</p>
+</div>
+
+
+<img src="{@docRoot}images/ui/settings/settings.png" alt="" width="435" />
+<p class="img-caption"><strong>Hình 1.</strong> Ảnh chụp màn hình từ thiết đặt của ứng dụng
+Messaging trên Android. Chọn một mục được định nghĩa bởi một {@link android.preference.Preference}
+sẽ mở ra một giao diện để thay đổi thiết đặt.</p>
+
+
+
+
+<h2 id="Overview">Tổng quan</h2>
+
+<p>Thay vì sử dụng các đối tượng {@link android.view.View} để xây dựng giao diện người dùng, thiết đặt được
+xây dựng bằng cách sử dụng các lớp con khác nhau của lớp {@link android.preference.Preference} mà bạn
+khai báo trong một tệp XML.</p>
+
+<p>Đối tượng {@link android.preference.Preference} là một khối dựng cho một thiết đặt
+đơn lẻ. Mỗi {@link android.preference.Preference} xuất hiện như một mục trong một danh sách và cung cấp
+UI phù hợp để người dùng sửa đổi thiết đặt. Ví dụ, một {@link
+android.preference.CheckBoxPreference} tạo một mục danh sách hiển thị một hộp kiểm, và một {@link
+android.preference.ListPreference} tạo một mục mở ra một hộp thoại với danh sách lựa chọn.</p>
+
+<p>Mỗi {@link android.preference.Preference} mà bạn thêm có một cặp khóa-giá trị tương ứng mà
+hệ thống sử dụng để lưu thiết đặt trong một tệp {@link android.content.SharedPreferences}
+mặc định cho thiết đặt của ứng dụng của bạn. Khi người dùng thay đổi một thiết đặt, hệ thống sẽ cập nhật giá trị
+tương ứng trong tệp {@link android.content.SharedPreferences} cho bạn. Lần duy nhất mà bạn nên
+trực tiếp tương tác với tệp {@link android.content.SharedPreferences} được liên kết đó là khi bạn
+cần đọc giá trị để xác định xem hành vi ứng dụng của mình có được dựa trên thiết đặt của người dùng không.</p>
+
+<p>Giá trị được lưu trong {@link android.content.SharedPreferences} cho từng thiết đặt có thể là một trong các kiểu dữ liệu
+sau:</p>
+
+<ul>
+ <li>Boolean</li>
+ <li>Float</li>
+ <li>Int</li>
+ <li>Long</li>
+ <li>String</li>
+ <li>String {@link java.util.Set}</li>
+</ul>
+
+<p>Vì thiết đặt của ứng dụng của bạn được xây dựng bằng cách sử dụng các đối tượng {@link android.preference.Preference}
+thay vì đối tượng
+{@link android.view.View}, bạn nên sử dụng một lớp con {@link android.app.Activity} hoặc
+{@link android.app.Fragment} chuyên dụng để hiển thị thiết đặt danh sách:</p>
+
+<ul>
+ <li>Nếu ứng dụng của bạn hỗ trợ các phiên bản Android cũ hơn 3.0 (API mức 10 và thấp hơn), bạn phải
+xây dựng hoạt động như một phần mở rộng của lớp {@link android.preference.PreferenceActivity}.</li>
+ <li>Trên phiên bản Android 3.0 trở lên, thay vào đó, bạn nên sử dụng một {@link android.app.Activity}
+truyền thống nơi lưu giữ {@link android.preference.PreferenceFragment} để hiển thị thiết đặt ứng dụng của bạn.
+Tuy nhiên, bạn cũng có thể sử dụng {@link android.preference.PreferenceActivity} để tạo một bố trí hai bảng
+cho màn hình lớn khi bạn có nhiều nhóm thiết đặt.</li>
+</ul>
+
+<p>Cách thiết đặt {@link android.preference.PreferenceActivity} của bạn và các thực thể của {@link
+android.preference.PreferenceFragment} được trình bày trong các phần về <a href="#Activity">Tạo một Hoạt động Tùy chọn</a> và <a href="#Fragment">Sử dụng
+Phân đoạn Tùy chọn</a>.</p>
+
+
+<h3 id="SettingTypes">Tùy chọn</h3>
+
+<p>Mọi thiết đặt cho ứng dụng của bạn đều được biểu diễn bởi một lớp con cụ thể của lớp {@link
+android.preference.Preference}. Mỗi lớp con lại bao gồm một tập hợp các tính chất cốt lõi cho phép bạn
+quy định những thứ như tiêu đề cho thiết đặt và giá trị mặc định. Mỗi lớp con cũng cung cấp
+các tính chất và giao diện người dùng chuyên dụng của chính nó. Ví dụ, hình 1 mình họa một ảnh chụp màn hình từ thiết đặt của ứng dụng
+Messaging. Mỗi mục danh sách trong màn hình thiết đặt được hỗ trợ bởi một đối tượng {@link
+android.preference.Preference} khác nhau.</p>
+
+<p>Sau đây là một số tùy chọn phổ biến nhất:</p>
+
+<dl>
+ <dt>{@link android.preference.CheckBoxPreference}</dt>
+ <dd>Hiển thị một mục kèm một hộp kiểm cho thiết đặt hoặc được kích hoạt hoặc bị vô hiệu hóa. Giá trị
+được lưu là một boolean (<code>true</code> nếu nó được chọn).</dd>
+
+ <dt>{@link android.preference.ListPreference}</dt>
+ <dd>Mở một hộp thoại kèm danh sách nút chọn một. Giá trị được lưu
+có thể là bất kỳ loại giá trị được hỗ trợ nào (liệt kê bên trên).</dd>
+
+ <dt>{@link android.preference.EditTextPreference}</dt>
+ <dd>Mở một hộp thoại kèm một widget {@link android.widget.EditText}. Giá trị được lưu là một {@link
+java.lang.String}.</dd>
+</dl>
+
+<p>Xem lớp {@link android.preference.Preference} để biết danh sách tất cả các lớp con khác và tính chất
+tương ứng của chúng.</p>
+
+<p>Dĩ nhiên, các lớp tích hợp không đáp ứng mọi nhu cầu và ứng dụng của bạn có thể yêu cầu
+lớp con chuyên dụng hơn. Ví dụ, nền tảng này hiện chưa cung cấp một lớp {@link
+android.preference.Preference} cho việc chọn một số hay ngày. Vì thế, bạn có thể cần phải định nghĩa
+lớp con {@link android.preference.Preference} của chính mình. Để được trợ giúp khi làm vậy, hãy xem phần về <a href="#Custom">Xây dựng Thiết đặt Tùy chỉnh</a>.</p>
+
+
+
+<h2 id="DefiningPrefs">Định nghĩa Tùy chọn trong XML</h2>
+
+<p>Mặc dù bạn có thể khởi tạo các đối tượng {@link android.preference.Preference} mới vào thời gian chạy, bạn
+nên định nghĩa danh sách các thiết đặt của mình trong XML kèm một phân cấp của các đối tượng {@link android.preference.Preference}
+. Việc sử dụng một tệp XML để định nghĩa bộ sưu tập thiết đặt của bạn sẽ được ưu tiên vì tệp
+cung cấp một cấu trúc dễ đọc, cập nhật đơn giản. Bên cạnh đó, các thiết đặt ứng dụng của bạn thường được
+xác định trước, mặc dù bạn vẫn có thể sửa đổi bộ sưu tập vào thời gian chạy.</p>
+
+<p>Mỗi lớp con {@link android.preference.Preference} có thể được khai báo bằng một phần tử XML mà
+khớp với tên lớp đó, chẳng hạn như {@code &lt;CheckBoxPreference&gt;}.</p>
+
+<p>Bạn phải lưu tệp XML trong thư mục {@code res/xml/}. Mặc dù bạn có thể đặt tên tệp là
+bất cứ thứ gì mình muốn, nó thường được đặt tên là{@code preferences.xml}. Bạn thường chỉ cần một tệp,
+bởi các nhánh trong phân cấp (mà mở danh sách thiết đặt của riêng chúng) sẽ được khai báo bằng cách sử dụng các thực thể
+lồng nhau của {@link android.preference.PreferenceScreen}.</p>
+
+<p class="note"><strong>Lưu ý:</strong> Nếu bạn muốn tạo một bố trí đa bảng cho thiết đặt
+của mình, vậy bạn nên tách riêng các tệp XML cho từng phân đoạn.</p>
+
+<p>Node gốc cho tệp XML phải là một phần tử {@link android.preference.PreferenceScreen
+&lt;PreferenceScreen&gt;}. Trong phần tử này là nơi bạn thêm từng {@link
+android.preference.Preference}. Từng phần tử con mà bạn thêm vào trong phần tử
+{@link android.preference.PreferenceScreen &lt;PreferenceScreen&gt;} sẽ xuất hiện như một mục
+đơn lẻ trong danh sách thiết đặt.</p>
+
+<p>Ví dụ:</p>
+
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+ &lt;CheckBoxPreference
+ android:key="pref_sync"
+ android:title="@string/pref_sync"
+ android:summary="@string/pref_sync_summ"
+ android:defaultValue="true" />
+ &lt;ListPreference
+ android:dependency="pref_sync"
+ android:key="pref_syncConnectionType"
+ android:title="@string/pref_syncConnectionType"
+ android:dialogTitle="@string/pref_syncConnectionType"
+ android:entries="@array/pref_syncConnectionTypes_entries"
+ android:entryValues="@array/pref_syncConnectionTypes_values"
+ android:defaultValue="@string/pref_syncConnectionTypes_default" />
+&lt;/PreferenceScreen>
+</pre>
+
+<p>Trong ví dụ này, có một {@link android.preference.CheckBoxPreference} và một {@link
+android.preference.ListPreference}. Cả hai mục đều bao gồm ba thuộc tính sau:</p>
+
+<dl>
+ <dt>{@code android:key}</dt>
+ <dd>Thuộc tính này được yêu cầu cho các tùy chọn duy trì một giá trị dữ liệu. Nó quy định khóa
+(xâu) duy nhất mà hệ thống sử dụng khi lưu giá trị của thiết đặt này trong {@link
+android.content.SharedPreferences}.
+ <p>Các thực thể duy nhất mà thuộc tính này không <em>được yêu cầu</em> là khi tùy chọn là một
+{@link android.preference.PreferenceCategory} hoặc {@link android.preference.PreferenceScreen}, hoặc
+tùy chọn quy định một {@link android.content.Intent} để gọi ra (bằng phần tử <a href="#Intents">{@code &lt;intent&gt;}</a>) hoặc {@link android.app.Fragment} để hiển thị (bằng thuộc tính <a href="{@docRoot}reference/android/preference/Preference.html#attr_android:fragment">{@code
+android:fragment}</a>).</p>
+ </dd>
+ <dt>{@code android:title}</dt>
+ <dd>Thuộc tính này cung cấp một tên hiển thị với người dùng cho thiết đặt.</dd>
+ <dt>{@code android:defaultValue}</dt>
+ <dd>Nó quy định giá trị ban đầu mà hệ thống nên đặt trong tệp {@link
+android.content.SharedPreferences}. Bạn nên cung cấp một giá trị mặc định cho tất cả
+thiết đặt.</dd>
+</dl>
+
+<p>Để biết thông tin về tất cả thuộc tính được hỗ trợ khác, hãy xem tài liệu {@link
+android.preference.Preference} (và lớp con tương ứng).</p>
+
+
+<div class="figure" style="width:300px">
+ <img src="{@docRoot}images/ui/settings/settings-titles.png" alt="" />
+ <p class="img-caption"><strong>Hình 2.</strong> Thiết đặt thể loại
+ có tiêu đề. <br/><b>1.</b> Thể loại được quy định bởi phần tử {@link
+android.preference.PreferenceCategory &lt;PreferenceCategory&gt;}. <br/><b>2.</b> Tiêu đề
+được quy định bằng thuộc tính {@code android:title}.</p>
+</div>
+
+
+<p>Khi danh sách thiết đặt của bạn vượt quá khoảng 10 mục, bạn có thể muốn thêm tiêu đề để
+định nghĩa các nhóm thiết đặt hoặc hiển thị các nhóm đó trong một
+màn hình riêng. Những tùy chọn này được mô tả trong các phần sau.</p>
+
+
+<h3 id="Groups">Tạo nhóm thiết đặt</h3>
+
+<p>Nếu bạn trình bày một danh sách từ 10 thiết đặt trở lên, người dùng
+có thể gặp khó khăn trong việc dò tìm, hiểu và xử lý chúng. Bạn có thể khắc phục điều này bằng cách
+chia một số hoặc tất cả thiết đặt thành các nhóm, qua đó biến một danh sách dài thành nhiều
+danh sách ngắn hơn. Một nhóm các thiết đặt có liên quan có thể được trình bày bằng một trong hai cách:</p>
+
+<ul>
+ <li><a href="#Titles">Sử dụng tiêu đề</a></li>
+ <li><a href="#Subscreens">Sử dụng màn hình con</a></li>
+</ul>
+
+<p>Bạn có thể sử dụng một hoặc cả hai kỹ thuật tạo nhóm này để sắp xếp các thiết đặt cho ứng dụng của mình. Khi
+quyết định sử dụng cái nào và làm thế nào để chia các thiết đặt của mình, bạn nên tuân theo các hướng dẫn trong tài liệu hướng dẫn
+<a href="{@docRoot}design/patterns/settings.html">Thiết đặt</a> của Thiết kế Android.</p>
+
+
+<h4 id="Titles">Sử dụng tiêu đề</h4>
+
+<p>Nếu bạn muốn cung cấp các thanh chia có tiêu đề giữa các nhóm thiết đặt (như minh họa trong hình 2),
+hãy đặt từng nhóm đối tượng {@link android.preference.Preference} vào bên trong một {@link
+android.preference.PreferenceCategory}.</p>
+
+<p>Ví dụ:</p>
+
+<pre>
+&lt;PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+ &lt;PreferenceCategory
+ android:title="&#64;string/pref_sms_storage_title"
+ android:key="pref_key_storage_settings">
+ &lt;CheckBoxPreference
+ android:key="pref_key_auto_delete"
+ android:summary="&#64;string/pref_summary_auto_delete"
+ android:title="&#64;string/pref_title_auto_delete"
+ android:defaultValue="false"... />
+ &lt;Preference
+ android:key="pref_key_sms_delete_limit"
+ android:dependency="pref_key_auto_delete"
+ android:summary="&#64;string/pref_summary_delete_limit"
+ android:title="&#64;string/pref_title_sms_delete"... />
+ &lt;Preference
+ android:key="pref_key_mms_delete_limit"
+ android:dependency="pref_key_auto_delete"
+ android:summary="&#64;string/pref_summary_delete_limit"
+ android:title="&#64;string/pref_title_mms_delete" ... />
+ &lt;/PreferenceCategory>
+ ...
+&lt;/PreferenceScreen>
+</pre>
+
+
+<h4 id="Subscreens">Sử dụng màn hình con</h4>
+
+<p>Nếu bạn muốn đặt các nhóm thiết đặt vào một màn hình con (như minh họa trong hình 3), hãy đặt nhóm
+các đối tượng {@link android.preference.Preference} vào bên trong một {@link
+android.preference.PreferenceScreen}.</p>
+
+<img src="{@docRoot}images/ui/settings/settings-subscreen.png" alt="" />
+<p class="img-caption"><strong>Hình 3.</strong> Màn hình con thiết đặt. Phần tử {@code
+&lt;PreferenceScreen&gt;} sẽ tạo
+một mục mà, khi được chọn, nó sẽ mở ra một danh sách riêng để hiển thị các thiết đặt lồng nhau.</p>
+
+<p>Ví dụ:</p>
+
+<pre>
+&lt;PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+ &lt;!-- opens a subscreen of settings -->
+ &lt;PreferenceScreen
+ android:key="button_voicemail_category_key"
+ android:title="&#64;string/voicemail"
+ android:persistent="false">
+ &lt;ListPreference
+ android:key="button_voicemail_provider_key"
+ android:title="&#64;string/voicemail_provider" ... />
+ &lt;!-- opens another nested subscreen -->
+ &lt;PreferenceScreen
+ android:key="button_voicemail_setting_key"
+ android:title="&#64;string/voicemail_settings"
+ android:persistent="false">
+ ...
+ &lt;/PreferenceScreen>
+ &lt;RingtonePreference
+ android:key="button_voicemail_ringtone_key"
+ android:title="&#64;string/voicemail_ringtone_title"
+ android:ringtoneType="notification" ... />
+ ...
+ &lt;/PreferenceScreen>
+ ...
+&lt;/PreferenceScreen>
+</pre>
+
+
+<h3 id="Intents">Sử dụng ý định</h3>
+
+<p>Trong một số trường hợp, bạn có thể muốn một mục tùy chọn mở một hoạt động khác thay vì một
+màn hình thiết đặt, chẳng hạn như một trình duyệt web để xem một trang web. Để gọi ra một {@link
+android.content.Intent} khi người dùng chọn một mục tùy chọn, hãy thêm một phần tử {@code &lt;intent&gt;}
+làm con của phần tử {@code &lt;Preference&gt;} tương ứng.</p>
+
+<p>Ví dụ, sau đây là cách bạn có thể sử dụng một mục tùy chọn để mở một trang web:</p>
+
+<pre>
+&lt;Preference android:title="@string/prefs_web_page" >
+ &lt;intent android:action="android.intent.action.VIEW"
+ android:data="http://www.example.com" />
+&lt;/Preference>
+</pre>
+
+<p>Bạn có thể tạo cả ý định biểu thị và không biểu thị bằng cách sử dụng các thuộc tính sau:</p>
+
+<dl>
+ <dt>{@code android:action}</dt>
+ <dd>Hành động cần gán, theo mỗi phương pháp {@link android.content.Intent#setAction setAction()}
+.</dd>
+ <dt>{@code android:data}</dt>
+ <dd>Dữ liệu cần gán, theo mỗi phương pháp {@link android.content.Intent#setData setData()}.</dd>
+ <dt>{@code android:mimeType}</dt>
+ <dd>Kiểu MIME cần gán, theo mỗi phương pháp {@link android.content.Intent#setType setType()}
+.</dd>
+ <dt>{@code android:targetClass}</dt>
+ <dd>Phần lớp của tên thành phần, theo mỗi phương pháp {@link android.content.Intent#setComponent
+setComponent()}.</dd>
+ <dt>{@code android:targetPackage}</dt>
+ <dd>Phần gói của tên thành phần, theo mỗi phương pháp {@link
+android.content.Intent#setComponent setComponent()}.</dd>
+</dl>
+
+
+
+<h2 id="Activity">Tạo một Hoạt động Tùy chọn</h2>
+
+<p>Để hiển thị thiết đặt của bạn trong một hoạt động, hãy mở rộng lớp {@link
+android.preference.PreferenceActivity}. Đây là phần mở rộng của lớp {@link
+android.app.Activity} truyền thống mà hiển thị một danh sách các thiết đặt dựa trên một phân cấp của các đối tượng {@link
+android.preference.Preference}. {@link android.preference.PreferenceActivity}
+sẽ tự động duy trì các thiết đặt liên kết với từng {@link
+android.preference.Preference} khi người dùng thực hiện một thay đổi.</p>
+
+<p class="note"><strong>Lưu ý:</strong> Nếu bạn đang phát triển ứng dụng của mình cho phiên bản Android 3.0 và
+cao hơn, thay vào đó bạn nên sử dụng {@link android.preference.PreferenceFragment}. Đi đến phần
+tiếp theo về <a href="#Fragment">Sử dụng Phân đoạn Tùy chọn</a>.</p>
+
+<p>Điều quan trọng nhất cần nhớ đó là bạn không được tải một bố trí dạng xem trong khi gọi lại {@link
+android.preference.PreferenceActivity#onCreate onCreate()}. Thay vào đó, bạn hãy gọi {@link
+android.preference.PreferenceActivity#addPreferencesFromResource addPreferencesFromResource()} để
+thêm tùy chọn mà bạn đã khai báo trong một tệp XML vào hoạt động. Ví dụ, sau đây là đoạn mã tối thiểu
+cần thiết cho một {@link android.preference.PreferenceActivity} chức năng:</p>
+
+<pre>
+public class SettingsActivity extends PreferenceActivity {
+ &#64;Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ addPreferencesFromResource(R.xml.preferences);
+ }
+}
+</pre>
+
+<p>Đây là đoạn mã vừa đủ cho một số ứng dụng bởi ngay khi người dùng sửa đổi một tùy chọn,
+hệ thống sẽ lưu thay đổi đối với tệp {@link android.content.SharedPreferences} mặc định mà các
+thành phần ứng dụng khác của bạn có thể đọc khi bạn cần kiểm tra thiết đặt của người dùng. Tuy nhiên,
+nhiều ứng dụng lại yêu cầu thêm mã để theo dõi những thay đổi xảy ra với các tùy chọn đó.
+Để biết thông tin về việc theo dõi thay đổi trong tệp {@link android.content.SharedPreferences},
+hãy xem phần về <a href="#ReadingPrefs">Đọc Tùy chọn</a>.</p>
+
+
+
+
+<h2 id="Fragment">Sử dụng Phân đoạn Tùy chọn</h2>
+
+<p>Nếu bạn đang phát triển cho phiên bản Android 3.0 (API mức 11) trở lên, bạn nên sử dụng một {@link
+android.preference.PreferenceFragment} để hiển thị danh sách các đối tượng {@link android.preference.Preference}
+của bạn. Bạn có thể thêm một {@link android.preference.PreferenceFragment} vào bất kỳ hoạt động nào&mdash;bạn không cần
+sử dụng {@link android.preference.PreferenceActivity}.</p>
+
+<p><a href="{@docRoot}guide/components/fragments.html">Phân đoạn</a> cung cấp một kiến trúc
+linh hoạt hơn cho ứng dụng của bạn, so với việc sử dụng chỉ các hoạt động, dù loại hoạt động
+mà bạn đang xây dựng là gì. Như vậy, chúng tôi gợi ý bạn sử dụng {@link
+android.preference.PreferenceFragment} để kiểm soát hiển thị các thiết đặt của mình thay cho {@link
+android.preference.PreferenceActivity} khi có thể.</p>
+
+<p>Việc triển khai {@link android.preference.PreferenceFragment} có thể chỉ đơn giản như
+định nghĩa phương pháp {@link android.preference.PreferenceFragment#onCreate onCreate()} để tải một
+tệp tùy chọn bằng {@link android.preference.PreferenceFragment#addPreferencesFromResource
+addPreferencesFromResource()}. Ví dụ:</p>
+
+<pre>
+public static class SettingsFragment extends PreferenceFragment {
+ &#64;Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Load the preferences from an XML resource
+ addPreferencesFromResource(R.xml.preferences);
+ }
+ ...
+}
+</pre>
+
+<p>Khi đó, bạn có thể thêm phân đoạn này vào một {@link android.app.Activity} giống như cách mà bạn sẽ làm với bất kỳ
+{@link android.app.Fragment} nào khác. Ví dụ:</p>
+
+<pre>
+public class SettingsActivity extends Activity {
+ &#64;Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ // Display the fragment as the main content.
+ getFragmentManager().beginTransaction()
+ .replace(android.R.id.content, new SettingsFragment())
+ .commit();
+ }
+}
+</pre>
+
+<p class="note"><strong>Lưu ý:</strong> {@link android.preference.PreferenceFragment} không có một
+đối tượng {@link android.content.Context} của chính nó. Nếu bạn cần một đối tượng {@link android.content.Context}
+, bạn có thể gọi {@link android.app.Fragment#getActivity()}. Tuy nhiên, hãy chắc chắn là chỉ gọi
+{@link android.app.Fragment#getActivity()} khi phân đoạn đó được gắn kèm với một hoạt động. Khi
+phân đoạn chưa được gắn kèm, hoặc bị bỏ gắn kèm trong khi kết thúc vòng đời của nó, {@link
+android.app.Fragment#getActivity()} sẽ trả về rỗng.</p>
+
+
+<h2 id="Defaults">Thiết đặt Giá trị Mặc định</h2>
+
+<p>Tùy chọn mà bạn tạo có thể định nghĩa một số hành vi quan trọng cho ứng dụng của bạn, vì thế
+bạn cần phải khởi tạo tệp {@link android.content.SharedPreferences} kèm theo với các
+giá trị mặc định cho từng {@link android.preference.Preference} khi người dùng lần đầu mở
+ứng dụng của bạn.</p>
+
+<p>Điều đầu tiên bạn phải làm đó là quy định một giá trị mặc định cho từng đối tượng {@link
+android.preference.Preference}
+trong tệp XML của bạn bằng cách sử dụng thuộc tính {@code android:defaultValue}. Giá trị đó có thể là bất kỳ kiểu
+dữ liệu nào mà phù hợp với đối tượng {@link android.preference.Preference} tương ứng. Ví
+dụ:</p>
+
+<pre>
+&lt;!-- default value is a boolean -->
+&lt;CheckBoxPreference
+ android:defaultValue="true"
+ ... />
+
+&lt;!-- default value is a string -->
+&lt;ListPreference
+ android:defaultValue="@string/pref_syncConnectionTypes_default"
+ ... />
+</pre>
+
+<p>Khi đó, từ phương pháp {@link android.app.Activity#onCreate onCreate()} trong hoạt động chính
+&mdash;của ứng dụng của bạn và trong bất kỳ hoạt động nào khác mà thông qua đó người dùng có thể vào ứng dụng của bạn lần
+đầu tiên&mdash;hãy gọi {@link android.preference.PreferenceManager#setDefaultValues
+setDefaultValues()}:</p>
+
+<pre>
+PreferenceManager.setDefaultValues(this, R.xml.advanced_preferences, false);
+</pre>
+
+<p>Việc gọi này trong khi {@link android.app.Activity#onCreate onCreate()} sẽ đảm bảo rằng
+ứng dụng của bạn được khởi tạo phù hợp với các thiết đặt mặc định mà ứng dụng của bạn có thể cần
+đọc để xác định một số hành vi (chẳng hạn như có tải xuống dữ liệu trong khi đang trên
+mạng di động hay không).</p>
+
+<p>Phương pháp này dùng ba tham đối:</p>
+<ul>
+ <li>{@link android.content.Context} ứng dụng của bạn.</li>
+ <li>ID tài nguyên cho tệp XML tùy chọn mà bạn muốn đặt các giá trị mặc định cho.</li>
+ <li>Một boolean cho biết các giá trị mặc định có nên được đặt nhiều hơn một lần hay không.
+<p>Khi tham đối này là <code>false</code>, hệ thống sẽ đặt các giá trị mặc định chỉ khi phương pháp này chưa từng được
+gọi trước đây (hoặc {@link android.preference.PreferenceManager#KEY_HAS_SET_DEFAULT_VALUES}
+trong tệp tùy chọn được chia sẻ giá trị mặc định là sai).</p></li>
+</ul>
+
+<p>Miễn là bạn đặt tham đối thứ ba này thành <code>false</code>, bạn có thể gọi phương pháp này một cách an toàn
+mỗi khi hoạt động của bạn bắt đầu mà không khống chế các tùy chọn đã lưu của người dùng bằng cách đặt lại chúng thành
+mặc định. Tuy nhiên, nếu bạn đặt nó thành <code>true</code>, bạn sẽ khống chế mọi giá trị
+trước đó bằng các giá trị mặc định.</p>
+
+
+
+<h2 id="PreferenceHeaders">Sử dụng Tiêu đề Tùy chọn</h2>
+
+<p>Trong vài trường hợp hiếm gặp, bạn có thể muốn thiết kế các thiết đặt của mình sao cho màn hình thứ nhất
+chỉ hiển thị một danh sách <a href="#Subscreens">các màn hình con</a> (chẳng hạn như trong ứng dụng Thiết đặt của hệ thống,
+như minh họa trong các hình 4 và 5). Khi phát triển thiết kế như vậy cho phiên bản Android 3.0 trở lên, bạn
+nên sử dụng tính năng "tiêu đề" mới trong Android 3.0, thay vì xây dựng màn hình con với các phần tử
+{@link android.preference.PreferenceScreen} lồng nhau.</p>
+
+<p>Để xây dựng thiết đặt có tiêu đề của mình, bạn cần:</p>
+<ol>
+ <li>Tách riêng từng nhóm thiết đặt thành các thực thể riêng của {@link
+android.preference.PreferenceFragment}. Cụ thể, mỗi nhóm thiết đặt cần một tệp XML
+riêng.</li>
+ <li>Tạo một tệp tiêu đề XML liệt kê từng nhóm thiết đặt và khai báo phân đoạn nào
+chứa danh sách thiết đặt tương ứng.</li>
+ <li>Mở rộng lớp {@link android.preference.PreferenceActivity} để lưu trữ các thiết đặt của bạn.</li>
+ <li>Triển khai lệnh gọi lại {@link
+android.preference.PreferenceActivity#onBuildHeaders onBuildHeaders()} để quy định
+tệp tiêu đề.</li>
+</ol>
+
+<p>Một lợi ích tuyệt vời đối với việc sử dụng thiết kế này đó là {@link android.preference.PreferenceActivity}
+tự động trình bày bố trí hai bảng như minh họa trong hình 4 khi chạy trên màn hình lớn.</p>
+
+<p>Ngay cả khi ứng dụng của bạn hỗ trợ các phiên bản Android cũ hơn 3.0, bạn có thể xây dựng ứng dụng
+của mình để sử dụng {@link android.preference.PreferenceFragment} cho một trình chiếu hai bảng trên
+các thiết bị mới hơn, trong khi vẫn hỗ trợ phân cấp đa màn hình truyền thống trên các thiết bị
+cũ hơn (xem phần nói về <a href="#BackCompatHeaders">Hỗ trợ các phiên bản cũ hơn
+với tiêu đề tùy chọn</a>).</p>
+
+<img src="{@docRoot}images/ui/settings/settings-headers-tablet.png" alt="" />
+<p class="img-caption"><strong>Hình 4.</strong> Bố trí có hai bảng với tiêu đề. <br/><b>1.</b>
+Tiêu đề được định nghĩa trong một tệp tiêu đề XML. <br/><b>2.</b> Mỗi nhóm thiết đặt được định nghĩa bởi một
+{@link android.preference.PreferenceFragment}, được quy định bởi một phần tử {@code &lt;header&gt;} trong tệp tiêu đề
+.</p>
+
+<img src="{@docRoot}images/ui/settings/settings-headers-handset.png" alt="" />
+<p class="img-caption"><strong>Hình 5.</strong> Thiết bị cầm tay với các tiêu đề thiết đặt. Khi một
+mục được chọn, {@link android.preference.PreferenceFragment} được liên kết sẽ thay thế
+tiêu đề.</p>
+
+
+<h3 id="CreateHeaders" style="clear:left">Tạo tệp tiêu đề</h3>
+
+<p>Mỗi nhóm thiết đặt trong danh sách tiêu đề của bạn được quy định bởi một phần tử {@code &lt;header&gt;}
+đơn lẻ bên trong một phần tử {@code &lt;preference-headers&gt;} gốc. Ví dụ:</p>
+
+<pre>
+&lt;?xml version="1.0" encoding="utf-8"?>
+&lt;preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
+ &lt;header
+ android:fragment="com.example.prefs.SettingsActivity$SettingsFragmentOne"
+ android:title="@string/prefs_category_one"
+ android:summary="@string/prefs_summ_category_one" />
+ &lt;header
+ android:fragment="com.example.prefs.SettingsActivity$SettingsFragmentTwo"
+ android:title="@string/prefs_category_two"
+ android:summary="@string/prefs_summ_category_two" >
+ &lt;!-- key/value pairs can be included as arguments for the fragment. -->
+ &lt;extra android:name="someKey" android:value="someHeaderValue" />
+ &lt;/header>
+&lt;/preference-headers>
+</pre>
+
+<p>Với thuộc tính {@code android:fragment}, mỗi tiêu đề sẽ khai báo một thực thể của {@link
+android.preference.PreferenceFragment} mà sẽ mở khi người dùng chọn tiêu đề đó.</p>
+
+<p>Phần tử {@code &lt;extras&gt;} cho phép bạn chuyển các cặp khóa-giá trị sang phân đoạn trong một {@link
+android.os.Bundle}. Phân đoạn có thể truy xuất các tham đối bằng cách gọi {@link
+android.app.Fragment#getArguments()}. Bạn có thể chuyển các tham đối tới phân đoạn vì nhiều
+lý do khác nhau, nhưng một lý do chính đáng đó là để sử dụng lại cùng lớp con của {@link
+android.preference.PreferenceFragment} cho mỗi nhóm và sử dụng tham đối để quy định
+tệp XML tùy chọn nào mà phân đoạn cần tải.</p>
+
+<p>Ví dụ, sau đây là một phân đoạn mà có thể được tái sử dụng cho nhiều nhóm thiết đặt, khi từng
+tiêu đề định nghĩa một tham đối {@code &lt;extra&gt;} với khóa {@code "settings"}:</p>
+
+<pre>
+public static class SettingsFragment extends PreferenceFragment {
+ &#64;Override
+ public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ String settings = getArguments().getString("settings");
+ if ("notifications".equals(settings)) {
+ addPreferencesFromResource(R.xml.settings_wifi);
+ } else if ("sync".equals(settings)) {
+ addPreferencesFromResource(R.xml.settings_sync);
+ }
+ }
+}
+</pre>
+
+
+
+<h3 id="DisplayHeaders">Hiển thị tiêu đề</h3>
+
+<p>Để hiển thị tiêu đề tùy chọn, bạn phải triển khai phương pháp gọi lại {@link
+android.preference.PreferenceActivity#onBuildHeaders onBuildHeaders()} và gọi
+{@link android.preference.PreferenceActivity#loadHeadersFromResource
+loadHeadersFromResource()}. Ví dụ:</p>
+
+<pre>
+public class SettingsActivity extends PreferenceActivity {
+ &#64;Override
+ public void onBuildHeaders(List&lt;Header> target) {
+ loadHeadersFromResource(R.xml.preference_headers, target);
+ }
+}
+</pre>
+
+<p>Khi người dùng chọn một mục từ danh sách tiêu đề, hệ thống sẽ mở {@link
+android.preference.PreferenceFragment} kèm theo.</p>
+
+<p class="note"><strong>Lưu ý:</strong> Khi sử dụng tiêu đề tùy chọn, lớp con {@link
+android.preference.PreferenceActivity} của bạn không cần triển khai phương pháp {@link
+android.preference.PreferenceActivity#onCreate onCreate()}, vì tác vụ cần thiết duy nhất
+cho hoạt động đó là tải tiêu đề.</p>
+
+
+<h3 id="BackCompatHeaders">Hỗ trợ các phiên bản cũ hơn với tiêu đề tùy chọn</h3>
+
+<p>Nếu ứng dụng của bạn hỗ trợ các phiên bản Android cũ hơn 3.0, bạn vẫn có thể sử dụng tiêu đề để
+cung cấp một bố trí hai bảng khi chạy trên Android 3.0 trở lên. Tất cả những việc bạn cần làm đó là tạo một
+tệp XML tùy chọn bổ sung có sử dụng phần tử cơ bản {@link android.preference.Preference
+&lt;Preference&gt;} đóng vai trò như mục tiêu đề (để dùng cho các phiên bản Android
+cũ hơn).</p>
+
+<p>Tuy nhiên, thay vì mở một {@link android.preference.PreferenceScreen} mới, từng phần tử {@link
+android.preference.Preference &lt;Preference&gt;} sẽ gửi một {@link android.content.Intent} tới
+{@link android.preference.PreferenceActivity} mà quy định tệp XML tùy chọn cần
+tải.</p>
+
+<p>Ví dụ, sau đây là một tệp XML cho các tiêu đề tùy chọn được sử dụng trên Android 3.0
+trở lên ({@code res/xml/preference_headers.xml}):</p>
+
+<pre>
+&lt;preference-headers xmlns:android="http://schemas.android.com/apk/res/android">
+ &lt;header
+ android:fragment="com.example.prefs.SettingsFragmentOne"
+ android:title="@string/prefs_category_one"
+ android:summary="@string/prefs_summ_category_one" />
+ &lt;header
+ android:fragment="com.example.prefs.SettingsFragmentTwo"
+ android:title="@string/prefs_category_two"
+ android:summary="@string/prefs_summ_category_two" />
+&lt;/preference-headers>
+</pre>
+
+<p>Và sau đây là một tệp tùy chọn cung cấp cùng các tiêu đề cho các phiên bản cũ hơn
+Android 3.0 ({@code res/xml/preference_headers_legacy.xml}):</p>
+
+<pre>
+&lt;PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android">
+ &lt;Preference
+ android:title="@string/prefs_category_one"
+ android:summary="@string/prefs_summ_category_one" >
+ &lt;intent
+ android:targetPackage="com.example.prefs"
+ android:targetClass="com.example.prefs.SettingsActivity"
+ android:action="com.example.prefs.PREFS_ONE" />
+ &lt;/Preference>
+ &lt;Preference
+ android:title="@string/prefs_category_two"
+ android:summary="@string/prefs_summ_category_two" >
+ &lt;intent
+ android:targetPackage="com.example.prefs"
+ android:targetClass="com.example.prefs.SettingsActivity"
+ android:action="com.example.prefs.PREFS_TWO" />
+ &lt;/Preference>
+&lt;/PreferenceScreen>
+</pre>
+
+<p>Vì hỗ trợ dành cho {@code &lt;preference-headers&gt;} đã được thêm trong Android 3.0, hệ thống sẽ gọi
+{@link android.preference.PreferenceActivity#onBuildHeaders onBuildHeaders()} trong {@link
+android.preference.PreferenceActivity} của bạn chỉ khi đang chạy trên phiên bản Androd 3.0 hoặc cao hơn. Để tải
+tệp tiêu đề "kế thừa" ({@code preference_headers_legacy.xml}), bạn phải kiểm tra phiên bản Android
+và, nếu phiên bản cũ hơn Android 3.0 ({@link
+android.os.Build.VERSION_CODES#HONEYCOMB}), hãy gọi {@link
+android.preference.PreferenceActivity#addPreferencesFromResource addPreferencesFromResource()} để
+tải tệp tiêu đề kế thừa. Ví dụ:</p>
+
+<pre>
+&#64;Override
+public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ ...
+
+ if (Build.VERSION.SDK_INT &lt; Build.VERSION_CODES.HONEYCOMB) {
+ // Load the legacy preferences headers
+ addPreferencesFromResource(R.xml.preference_headers_legacy);
+ }
+}
+
+// Called only on Honeycomb and later
+&#64;Override
+public void onBuildHeaders(List&lt;Header> target) {
+ loadHeadersFromResource(R.xml.preference_headers, target);
+}
+</pre>
+
+<p>Việc duy nhất còn lại cần làm đó là xử lý {@link android.content.Intent} mà được chuyển vào
+hoạt động để nhận biết tệp tùy chọn nào cần tải. Vì vậy, hãy truy xuất hành động của ý định và so sánh nó với
+các xâu hành động đã biết mà bạn đã sử dụng trong tag {@code &lt;intent&gt;} của XML tùy chọn:</p>
+
+<pre>
+final static String ACTION_PREFS_ONE = "com.example.prefs.PREFS_ONE";
+...
+
+&#64;Override
+public void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+
+ String action = getIntent().getAction();
+ if (action != null &amp;&amp; action.equals(ACTION_PREFS_ONE)) {
+ addPreferencesFromResource(R.xml.preferences);
+ }
+ ...
+
+ else if (Build.VERSION.SDK_INT &lt; Build.VERSION_CODES.HONEYCOMB) {
+ // Load the legacy preferences headers
+ addPreferencesFromResource(R.xml.preference_headers_legacy);
+ }
+}
+</pre>
+
+<p>Lưu ý rằng các lệnh gọi liên tiếp đến {@link
+android.preference.PreferenceActivity#addPreferencesFromResource addPreferencesFromResource()} sẽ
+xếp chồng tất cả tùy chọn trong một danh sách duy nhất, vì thế hãy chắc chắn rằng nó chỉ được gọi một lần bằng cách liên kết các
+điều kiện với mệnh đề else-if.</p>
+
+
+
+
+
+<h2 id="ReadingPrefs">Đọc Tùy chọn</h2>
+
+<p>Theo mặc định, tất cả tùy chọn của ứng dụng của bạn đều được lưu vào một tệp có thể truy cập từ bất kỳ nơi nào
+trong ứng dụng của bạn bằng cách gọi phương pháp tĩnh {@link
+android.preference.PreferenceManager#getDefaultSharedPreferences
+PreferenceManager.getDefaultSharedPreferences()}. Điều này sẽ trả về đối tượng {@link
+android.content.SharedPreferences} chứa tất cả cặp khóa-giá trị liên kết
+với các đối tượng {@link android.preference.Preference} được sử dụng trong {@link
+android.preference.PreferenceActivity}.</p>
+
+<p>Ví dụ, sau đây là cách bạn có thể đọc một trong các giá trị tùy chọn từ bất kỳ hoạt động nào khác trong ứng dụng
+của mình:</p>
+
+<pre>
+SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
+String syncConnPref = sharedPref.getString(SettingsActivity.KEY_PREF_SYNC_CONN, "");
+</pre>
+
+
+
+<h3 id="Listening">Theo dõi thay đổi tùy chọn</h3>
+
+<p>Có một vài lý do khiến bạn có thể muốn được thông báo càng sớm càng tốt nếu người dùng thay đổi một trong các
+tùy chọn. Để nhận một phương pháp gọi lại khi thay đổi xảy ra với bất kỳ tùy chọn nào,
+hãy triển khai giao diện {@link android.content.SharedPreferences.OnSharedPreferenceChangeListener
+SharedPreference.OnSharedPreferenceChangeListener} và đăng ký đối tượng theo dõi cho đối tượng
+{@link android.content.SharedPreferences} bằng cách gọi {@link
+android.content.SharedPreferences#registerOnSharedPreferenceChangeListener
+registerOnSharedPreferenceChangeListener()}.</p>
+
+<p>Giao diện này chỉ có một phương pháp gọi lại, {@link
+android.content.SharedPreferences.OnSharedPreferenceChangeListener#onSharedPreferenceChanged
+onSharedPreferenceChanged()}, và bạn có thể thấy đây là cách dễ nhất để triển khai giao diện như một phần
+hoạt động của mình. Ví dụ:</p>
+
+<pre>
+public class SettingsActivity extends PreferenceActivity
+ implements OnSharedPreferenceChangeListener {
+ public static final String KEY_PREF_SYNC_CONN = "pref_syncConnectionType";
+ ...
+
+ public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
+ String key) {
+ if (key.equals(KEY_PREF_SYNC_CONN)) {
+ Preference connectionPref = findPreference(key);
+ // Set summary to be the user-description for the selected value
+ connectionPref.setSummary(sharedPreferences.getString(key, ""));
+ }
+ }
+}
+</pre>
+
+<p>Trong ví dụ này, phương pháp sẽ kiểm tra xem thiết đặt bị thay đổi có áp dụng cho một khóa tùy chọn đã biết không. Nó
+sẽ gọi {@link android.preference.PreferenceActivity#findPreference findPreference()} để nhận đối tượng
+{@link android.preference.Preference} đã bị thay đổi để nó có thể sửa đổi tóm tắt
+của mục đó thành mô tả lựa chọn của người dùng. Cụ thể, khi thiết đặt là một {@link
+android.preference.ListPreference} hoặc thiết đặt nhiều lựa chọn khác, bạn nên gọi {@link
+android.preference.Preference#setSummary setSummary()} khi thiết đặt thay đổi để hiển thị
+trạng thái hiện tại (chẳng hạn như thiết đặt Ngủ như minh họa trong hình 5).</p>
+
+<p class="note"><strong>Lưu ý:</strong> Như đã mô tả trong tài liệu Thiết kế Android về <a href="{@docRoot}design/patterns/settings.html">Thiết đặt</a>, chúng tôi khuyên bạn nên cập nhật
+tóm tắt cho {@link android.preference.ListPreference} mỗi khi người dùng thay đổi tùy chọn để
+mô tả thiết đặt hiện tại.</p>
+
+<p>Để quản lý vòng đời trong hoạt động cho phù hợp, chúng tôi khuyên rằng bạn nên đăng ký và bỏ đăng ký
+{@link android.content.SharedPreferences.OnSharedPreferenceChangeListener} của mình tương ứng trong {@link
+android.app.Activity#onResume} và các lệnh gọi lại {@link android.app.Activity#onPause}:</p>
+
+<pre>
+&#64;Override
+protected void onResume() {
+ super.onResume();
+ getPreferenceScreen().getSharedPreferences()
+ .registerOnSharedPreferenceChangeListener(this);
+}
+
+&#64;Override
+protected void onPause() {
+ super.onPause();
+ getPreferenceScreen().getSharedPreferences()
+ .unregisterOnSharedPreferenceChangeListener(this);
+}
+</pre>
+
+<p class="caution"><strong>Chú ý:</strong> Khi bạn gọi {@link
+android.content.SharedPreferences#registerOnSharedPreferenceChangeListener
+registerOnSharedPreferenceChangeListener()}, trình quản lý tùy chọn hiện
+không lưu trữ một tham chiếu mạnh tới đối tượng theo dõi. Bạn phải lưu trữ một tham chiếu
+mạnh tới đối tượng theo dõi, nếu không nó sẽ dễ bị thu thập thông tin rác. Chúng tôi
+khuyên bạn nên giữ một tham chiếu tới đối tượng theo dõi trong dữ liệu thực thể của một đối tượng
+mà sẽ tồn tại miễn là bạn còn cần đối tượng theo dõi đó.</p>
+
+<p>Ví dụ, trong đoạn mã sau, hàm gọi không giữ tham chiếu tới
+đối tượng theo dõi. Kết quả là đối tượng theo dõi sẽ bị thu thập thông tin rác,
+và nó sẽ bị lỗi tại một thời điểm không xác định trong tương lai:</p>
+
+<pre>
+prefs.registerOnSharedPreferenceChangeListener(
+ // Bad! The listener is subject to garbage collection!
+ new SharedPreferences.OnSharedPreferenceChangeListener() {
+ public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
+ // listener implementation
+ }
+});
+</pre>
+
+<p>Thay vào đó, hãy lưu một tham chiếu tới đối tượng theo dõi trong một trường dữ liệu thực thể của một
+đối tượng mà sẽ tồn tại miễn là còn cần đối tượng theo dõi đó:</p>
+
+<pre>
+SharedPreferences.OnSharedPreferenceChangeListener listener =
+ new SharedPreferences.OnSharedPreferenceChangeListener() {
+ public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
+ // listener implementation
+ }
+};
+prefs.registerOnSharedPreferenceChangeListener(listener);
+</pre>
+
+<h2 id="NetworkUsage">Quản lý Sử dụng Mạng</h2>
+
+
+<p>Bắt đầu với Android 4.0, ứng dụng Thiết đặt của hệ thống sẽ cho phép người dùng xem
+ứng dụng của họ đang sử dụng bao nhiêu dữ liệu mạng khi đang ở tiền cảnh và dưới nền. Khi đó, người dùng có thể
+vô hiệu hóa việc sử dụng dữ liệu chạy ngầm cho từng ứng dụng. Để tránh việc người dùng vô hiệu hóa truy cập dữ liệu
+của ứng dụng của bạn từ dưới nền, bạn nên sử dụng kết nối dữ liệu một cách hiệu quả và cho phép
+người dùng tinh chỉnh mức sử dụng dữ liệu cho ứng dụng của bạn thông qua thiết đặt ứng dụng.<p>
+
+<p>Ví dụ, bạn có thể cho phép người dùng kiểm soát tần suất ứng dụng của bạn đồng bộ dữ liệu, ứng dụng của bạn
+chỉ được thực hiện tải lên/tải xuống khi trên Wi-Fi, ứng dụng của bạn sử dụng dữ liệu trong khi đang chuyển vùng dữ liệu, v.v... hay không. Với
+những kiểm soát này, người dùng sẽ ít có khả năng vô hiệu hóa truy cập dữ liệu của ứng dụng của bạn
+hơn nhiều khi họ đạt gần mức giới hạn đặt ra trong Thiết đặt hệ thống, vì thay vào đó, họ có thể kiểm soát chính xác
+lượng dữ liệu mà ứng dụng của bạn sử dụng.</p>
+
+<p>Sau khi bạn đã thêm các tùy chọn cần thiết trong {@link android.preference.PreferenceActivity}
+của mình để kiểm soát các thói quen dữ liệu của ứng dụng của bạn, bạn nên thêm một bộ lọc ý định cho {@link
+android.content.Intent#ACTION_MANAGE_NETWORK_USAGE} trong tệp bản kê khai của mình. Ví dụ:</p>
+
+<pre>
+&lt;activity android:name="SettingsActivity" ... >
+ &lt;intent-filter>
+ &lt;action android:name="android.intent.action.MANAGE_NETWORK_USAGE" />
+ &lt;category android:name="android.intent.category.DEFAULT" />
+ &lt;/intent-filter>
+&lt;/activity>
+</pre>
+
+<p>Bộ lọc ý định này cho hệ thống biết rằng đây là hoạt động kiểm soát mức sử dụng dữ liệu
+của ứng dụng của bạn. Vì thế, khi người dùng kiểm tra lượng dữ liệu mà ứng dụng của bạn đang dùng từ ứng dụng
+Thiết đặt của hệ thống, sẽ có một nút <em>Xem thiết đặt ứng dụng</em> khởi chạy
+{@link android.preference.PreferenceActivity} của bạn, vì thế người dùng có thể tinh chỉnh lượng dữ liệu mà ứng dụng của bạn
+dùng.</p>
+
+
+
+
+
+
+
+<h2 id="Custom">Xây dựng một Thiết đặt Tùy chỉnh</h2>
+
+<p>Khuôn khổ Android bao gồm nhiều lớp con {@link android.preference.Preference} mà
+cho phép bạn xây dựng một UI cho một vài loại thiết đặt khác nhau.
+Tuy nhiên, bạn có thể khám phá thiết đặt mình cần mà chưa có giải pháp tích hợp sẵn, chẳng hạn như một
+bộ chọn số hay bộ chọn ngày. Trong trường hợp như vậy, bạn sẽ cần tạo một tùy chọn tùy chỉnh bằng cách mở rộng
+lớp {@link android.preference.Preference} hoặc một trong các lớp con khác.</p>
+
+<p>Khi bạn mở rộng lớp {@link android.preference.Preference}, có một vài điều quan trọng
+mà bạn cần làm:</p>
+
+<ul>
+ <li>Quy định giao diện người dùng sẽ xuất hiện khi người dùng chọn thiết đặt.</li>
+ <li>Lưu giá trị của thiết đặt khi phù hợp.</li>
+ <li>Khởi tạo {@link android.preference.Preference} bằng giá trị hiện tại (hoặc mặc định)
+khi xét tới dạng xem.</li>
+ <li>Cung cấp giá trị mặc định khi hệ thống yêu cầu.</li>
+ <li>Nếu {@link android.preference.Preference} cung cấp UI của chính mình (chẳng hạn như một hộp thoại), hãy lưu
+và khôi phục trạng thái để xử lý các thay đổi trong vòng đời (chẳng hạn như khi người dùng xoay màn hình).</li>
+</ul>
+
+<p>Các phần sau mô tả cách hoàn thành từng tác vụ này.</p>
+
+
+
+<h3 id="CustomSelected">Quy định một giao diện người dùng</h3>
+
+ <p>Nếu bạn trực tiếp mở rộng lớp {@link android.preference.Preference}, bạn cần triển khai
+{@link android.preference.Preference#onClick()} để định nghĩa hành động xảy ra khi người dùng
+chọn mục. Tuy nhiên, hầu hết các thiết đặt tùy chỉnh sẽ mở rộng {@link android.preference.DialogPreference} để
+hiển thị một hộp thoại, điều này làm đơn giản hóa quy trình. Khi bạn mở rộng {@link
+android.preference.DialogPreference}, bạn phải gọi {@link
+android.preference.DialogPreference#setDialogLayoutResource setDialogLayoutResourcs()} trong khi đang ở trong
+hàm dựng lớp để quy định bố trí cho hộp thoại.</p>
+
+ <p>Ví dụ, sau đây là hàm dựng cho một {@link
+android.preference.DialogPreference} tùy chỉnh mà khai báo bố trí và quy định văn bản cho
+các nút hộp thoại tích cực và tiêu cực mặc định:</p>
+
+<pre>
+public class NumberPickerPreference extends DialogPreference {
+ public NumberPickerPreference(Context context, AttributeSet attrs) {
+ super(context, attrs);
+
+ setDialogLayoutResource(R.layout.numberpicker_dialog);
+ setPositiveButtonText(android.R.string.ok);
+ setNegativeButtonText(android.R.string.cancel);
+
+ setDialogIcon(null);
+ }
+ ...
+}
+</pre>
+
+
+
+<h3 id="CustomSave">Lưu giá trị của thiết đặt</h3>
+
+<p>Bạn có thể lưu một giá trị cho thiết đặt vào bất cứ lúc nào bằng cách gọi một trong các phương pháp của lớp {@link
+android.preference.Preference}, {@code persist*()}, chẳng hạn như {@link
+android.preference.Preference#persistInt persistInt()} nếu giá trị của thiết đặt là một số nguyên hoặc
+{@link android.preference.Preference#persistBoolean persistBoolean()} để lưu một boolean.</p>
+
+<p class="note"><strong>Lưu ý:</strong> Mỗi {@link android.preference.Preference} chỉ có thể lưu một
+kiểu dữ liệu, vì thế bạn phải sử dụng phương pháp {@code persist*()} phù hợp cho kiểu dữ liệu được sử dụng bởi
+{@link android.preference.Preference} tùy chỉnh của mình.</p>
+
+<p>Thời điểm bạn chọn duy trì thiết đặt có thể phụ thuộc vào lớp {@link
+android.preference.Preference} nào mà bạn mở rộng. Nếu mở rộng {@link
+android.preference.DialogPreference}, khi đó bạn nên duy trì giá trị đó chỉ khi hộp thoại
+đóng lại do kết quả tích cực (người dùng chọn nút "OK").</p>
+
+<p>Khi {@link android.preference.DialogPreference} đóng lại, hệ thống sẽ gọi phương pháp {@link
+android.preference.DialogPreference#onDialogClosed onDialogClosed()}. Phương pháp bao gồm một
+tham đối boolean quy định xem người dùng có trả về kết quả "tích cực" hay không&mdash;nếu kết quả là
+<code>true</code>, khi đó, người dùng đã chọn nút tích cực và bạn nên lưu giá trị mới này. Ví
+dụ:</p>
+
+<pre>
+&#64;Override
+protected void onDialogClosed(boolean positiveResult) {
+ // When the user selects "OK", persist the new value
+ if (positiveResult) {
+ persistInt(mNewValue);
+ }
+}
+</pre>
+
+<p>Trong ví dụ này, <code>mNewValue</code> là một thành viên lớp lưu giữ giá trị
+hiện tại của thiết đặt. Việc gọi {@link android.preference.Preference#persistInt persistInt()} sẽ lưu giá trị vào
+tệp {@link android.content.SharedPreferences} (tự động sử dụng khóa mà
+được quy định trong tệp XML cho {@link android.preference.Preference} này).</p>
+
+
+<h3 id="CustomInitialize">Khởi tạo giá trị hiện tại</h3>
+
+<p>Khi hệ thống thêm {@link android.preference.Preference} của bạn vào màn hình, nó
+gọi {@link android.preference.Preference#onSetInitialValue onSetInitialValue()} để thông báo
+với bạn xem thiết đặt có giá trị được duy trì hay không. Nếu không có giá trị được duy trì, lệnh gọi này sẽ cung cấp
+cho bạn giá trị mặc định.</p>
+
+<p>Phương pháp {@link android.preference.Preference#onSetInitialValue onSetInitialValue()} chuyển một
+boolean, <code>restorePersistedValue</code>, để cho biết liệu giá trị đã được duy trì
+cho thiết đặt hay không. Nếu nó là <code>true</code>, khi đó bạn nên truy xuất giá trị được duy trì bằng cách gọi
+một trong các phương pháp của lớp {@link
+android.preference.Preference}, {@code getPersisted*()}, chẳng hạn như {@link
+android.preference.Preference#getPersistedInt getPersistedInt()} đối với một giá trị số nguyên. Bạn sẽ
+thường muốn truy xuất giá trị được duy trì sao cho bạn có thể cập nhật UI cho phù hợp để phản ánh
+giá trị đã lưu trước đó.</p>
+
+<p>Nếu <code>restorePersistedValue</code> là <code>false</code>, vậy bạn
+nên sử dụng giá trị mặc định được chuyển trong tham đối thứ hai.</p>
+
+<pre>
+&#64;Override
+protected void onSetInitialValue(boolean restorePersistedValue, Object defaultValue) {
+ if (restorePersistedValue) {
+ // Restore existing state
+ mCurrentValue = this.getPersistedInt(DEFAULT_VALUE);
+ } else {
+ // Set default state from the XML attribute
+ mCurrentValue = (Integer) defaultValue;
+ persistInt(mCurrentValue);
+ }
+}
+</pre>
+
+<p>Mỗi phương pháp {@code getPersisted*()} sẽ lấy một tham đối quy định
+giá trị mặc định sẽ sử dụng trong trường hợp thực sự không có giá trị được duy trì hoặc khóa không tồn tại. Trong
+ví dụ trên, một hằng số cục bộ được sử dụng để quy định giá trị mặc định trong trường hợp {@link
+android.preference.Preference#getPersistedInt getPersistedInt()} không thể trả về một giá trị được duy trì.</p>
+
+<p class="caution"><strong>Chú ý:</strong> Bạn <strong>không thể</strong> sử dụng
+<code>defaultValue</code> làm giá trị mặc định trong phương pháp {@code getPersisted*()}, bởi
+giá trị của nó luôn rỗng khi <code>restorePersistedValue</code> là <code>true</code>.</p>
+
+
+<h3 id="CustomDefault">Cung cấp một giá trị mặc định</h3>
+
+<p>Nếu trường hợp lớp {@link android.preference.Preference} của bạn quy định một giá trị mặc định
+(với thuộc tính {@code android:defaultValue}), khi đó hệ thống
+sẽ gọi {@link android.preference.Preference#onGetDefaultValue
+onGetDefaultValue()} khi nó khởi tạo đối tượng để truy xuất giá trị. Bạn phải
+triển khai phương pháp này để hệ thống lưu giá trị mặc định trong {@link
+android.content.SharedPreferences}. Ví dụ:</p>
+
+<pre>
+&#64;Override
+protected Object onGetDefaultValue(TypedArray a, int index) {
+ return a.getInteger(index, DEFAULT_VALUE);
+}
+</pre>
+
+<p>Các tham đối của phương pháp cung cấp mọi thứ bạn cần: mảng thuộc tính và vị trí chỉ mục
+của {@code android:defaultValue} mà bạn phải truy xuất. Lý do bạn phải triển khai
+phương pháp này nhằm trích xuất giá trị mặc định từ thuộc tính đó là bởi bạn phải quy định
+một giá trị mặc định cục bộ cho thuộc tính trong trường hợp giá trị không được định nghĩa.</p>
+
+
+
+<h3 id="CustomSaveState">Lưu và khôi phục trạng thái của Tùy chọn</h3>
+
+<p>Giống như {@link android.view.View} trong một bố trí, lớp con {@link android.preference.Preference}
+của bạn chịu trách nhiệm lưu và khôi phục trạng thái của nó trong trường hợp hoạt động hoặc phân đoạn
+được khởi động lại (chẳng hạn như khi người dùng xoay màn hình). Để lưu và khôi phục
+trạng thái của lớp {@link android.preference.Preference} của bạn cho đúng, bạn phải triển khai các
+phương pháp gọi lại vòng đời {@link android.preference.Preference#onSaveInstanceState
+onSaveInstanceState()} và {@link
+android.preference.Preference#onRestoreInstanceState onRestoreInstanceState()}.</p>
+
+<p>Trạng thái của {@link android.preference.Preference} của bạn được định nghĩa bởi một đối tượng mà triển khai
+giao diện {@link android.os.Parcelable}. Khuôn khổ Android sẽ cung cấp một đối tượng như vậy cho bạn
+như một điểm bắt đầu để định nghĩa đối tượng trạng thái của bạn: lớp {@link
+android.preference.Preference.BaseSavedState}.</p>
+
+<p>Để định nghĩa cách thức lớp {@link android.preference.Preference} của bạn lưu trạng thái của nó
+hãy mở rộng lớp {@link android.preference.Preference.BaseSavedState}. Bạn cần khống chế chỉ
+ một vài phương pháp và định nghĩa đối tượng {@link android.preference.Preference.BaseSavedState#CREATOR}
+.</p>
+
+<p>Đối với hầu hết ứng dụng, bạn có thể sao chép triển khai sau và chỉ cần thay đổi các dòng
+xử lý {@code value} nếu lớp con {@link android.preference.Preference} của bạn lưu một kiểu
+dữ liệu khác số nguyên.</p>
+
+<pre>
+private static class SavedState extends BaseSavedState {
+ // Member that holds the setting's value
+ // Change this data type to match the type saved by your Preference
+ int value;
+
+ public SavedState(Parcelable superState) {
+ super(superState);
+ }
+
+ public SavedState(Parcel source) {
+ super(source);
+ // Get the current preference's value
+ value = source.readInt(); // Change this to read the appropriate data type
+ }
+
+ &#64;Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ // Write the preference's value
+ dest.writeInt(value); // Change this to write the appropriate data type
+ }
+
+ // Standard creator object using an instance of this class
+ public static final Parcelable.Creator&lt;SavedState> CREATOR =
+ new Parcelable.Creator&lt;SavedState>() {
+
+ public SavedState createFromParcel(Parcel in) {
+ return new SavedState(in);
+ }
+
+ public SavedState[] newArray(int size) {
+ return new SavedState[size];
+ }
+ };
+}
+</pre>
+
+<p>Với triển khai {@link android.preference.Preference.BaseSavedState} bên trên được thêm
+vào ứng dụng của bạn (thường dưới dạng một lớp con của lớp con {@link android.preference.Preference} của bạn), khi đó
+bạn cần triển khai các phương pháp {@link android.preference.Preference#onSaveInstanceState
+onSaveInstanceState()} và {@link
+android.preference.Preference#onRestoreInstanceState onRestoreInstanceState()} cho lớp con
+{@link android.preference.Preference} của mình.</p>
+
+<p>Ví dụ:</p>
+
+<pre>
+&#64;Override
+protected Parcelable onSaveInstanceState() {
+ final Parcelable superState = super.onSaveInstanceState();
+ // Check whether this Preference is persistent (continually saved)
+ if (isPersistent()) {
+ // No need to save instance state since it's persistent,
+ // use superclass state
+ return superState;
+ }
+
+ // Create instance of custom BaseSavedState
+ final SavedState myState = new SavedState(superState);
+ // Set the state's value with the class member that holds current
+ // setting value
+ myState.value = mNewValue;
+ return myState;
+}
+
+&#64;Override
+protected void onRestoreInstanceState(Parcelable state) {
+ // Check whether we saved the state in onSaveInstanceState
+ if (state == null || !state.getClass().equals(SavedState.class)) {
+ // Didn't save the state, so call superclass
+ super.onRestoreInstanceState(state);
+ return;
+ }
+
+ // Cast state to custom BaseSavedState and pass to superclass
+ SavedState myState = (SavedState) state;
+ super.onRestoreInstanceState(myState.getSuperState());
+
+ // Set this Preference's widget to reflect the restored state
+ mNumberPicker.setValue(myState.value);
+}
+</pre>
+
diff --git a/docs/html-intl/intl/vi/guide/topics/ui/ui-events.jd b/docs/html-intl/intl/vi/guide/topics/ui/ui-events.jd
new file mode 100644
index 000000000000..b4d1635d1caa
--- /dev/null
+++ b/docs/html-intl/intl/vi/guide/topics/ui/ui-events.jd
@@ -0,0 +1,291 @@
+page.title=Sự kiện Nhập liệu
+parent.title=Giao diện Người dùng
+parent.link=index.html
+@jd:body
+
+<div id="qv-wrapper">
+<div id="qv">
+ <h2>Trong tài liệu này</h2>
+ <ol>
+ <li><a href="#EventListeners">Đối tượng theo dõi Sự kiện</a></li>
+ <li><a href="#EventHandlers">Bộ xử lý Sự kiện</a></li>
+ <li><a href="#TouchMode">Chế độ Cảm ứng</a></li>
+ <li><a href="#HandlingFocus">Xử lý Tiêu điểm</a></li>
+ </ol>
+
+</div>
+</div>
+
+<p>Trên Android, có nhiều cách để can thiệp vào các sự kiện từ tương tác của một người dùng với ứng dụng của bạn.
+Khi xem xét các sự kiện trong giao diện người dùng của bạn, cách tiếp cận là chụp lại sự kiện từ
+đối tượng Dạng xem cụ thể mà người dùng tương tác với. Lớp Dạng xem sẽ cung cấp phương thức để làm việc này.</p>
+
+<p>Trong các lớp Dạng xem khác nhau mà bạn sẽ sử dụng để soạn bố trí của mình, bạn có thể thấy một vài phương pháp gọi lại
+công khai dường như hữu ích đối với sự kiện UI. Những phương pháp này được khuôn khổ Android gọi khi
+xảy ra hành động tương ứng trên đối tượng đó. Ví dụ, khi một Dạng xem (chẳng hạn như một Nút) được chạm vào,
+phương pháp <code>onTouchEvent()</code> được gọi trên đối tượng đó. Tuy nhiên, để can thiệp vào điều này, bạn phải mở rộng
+lớp và khống chế phương pháp đó. Tuy nhiên, việc mở rộng mọi đối tượng Dạng xem
+để xử lý một sự kiện như vậy sẽ là không thực tế. Đây là lý do tại sao lớp Dạng xem cũng chứa
+một tập hợp giao diện lồng nhau cùng các phương pháp gọi lại mà bạn có thể định nghĩa dễ dàng hơn nhiều. Những giao diện này,
+được gọi là <a href="#EventListeners">đối tượng theo dõi sự kiện</a>, là tấm vé để bạn chụp lại tương tác giữa người dùng với UI của bạn.</p>
+
+<p>Trong khi các đối tượng theo dõi sự kiện sẽ thường được sử dụng để theo dõi tương tác của người dùng, có thể
+có lúc bạn muốn mở rộng một lớp Dạng xem để xây dựng một thành phần tùy chỉnh.
+Có thể là bạn muốn mở rộng lớp {@link android.widget.Button}
+để khiến cái gì đó trông ấn tượng hơn. Trong trường hợp này, bạn sẽ có thể định nghĩa các hành vi sự kiện mặc định cho lớp
+của mình bằng cách sử dụng <a href="#EventHandlers">bộ xử lý sự kiện</a> của lớp.</p>
+
+
+<h2 id="EventListeners">Đối tượng theo dõi Sự kiện</h2>
+
+<p>Đối tượng theo dõi sự kiện là một giao diện trong lớp {@link android.view.View} chứa một phương pháp gọi lại
+đơn lẻ. Những phương pháp này sẽ được khuôn khổ Android gọi khi Dạng xem mà đối tượng theo dõi đã
+được đăng ký với bị kích khởi bởi tương tác giữa người dùng với mục trong UI.</p>
+
+<p>Trong giao diện của đối tượng theo dõi sự kiện là những phương pháp gọi lại sau:</p>
+
+<dl>
+ <dt><code>onClick()</code></dt>
+ <dd>Từ {@link android.view.View.OnClickListener}.
+ Phương pháp này được gọi khi người dùng chạm vào mục
+ (khi ở chế độ cảm ứng), hoặc lấy tiêu điểm vào một mục bằng phím điều hướng hoặc bi xoay và
+ nhấn phím "enter" phù hợp hoặc nhấn bi xoay.</dd>
+ <dt><code>onLongClick()</code></dt>
+ <dd>Từ {@link android.view.View.OnLongClickListener}.
+ Phương pháp này được gọi khi người gọi chạm và giữ mục (khi ở chế độ cảm ứng), hoặc
+ lấy tiêu điểm vào một mục bằng phím điều hướng hoặc bi xoay và
+ nhấn và giữ phím "enter" phù hợp hoặc nhấn và giữ bi xoay (trong một giây).</dd>
+ <dt><code>onFocusChange()</code></dt>
+ <dd>Từ {@link android.view.View.OnFocusChangeListener}.
+ Phương pháp này được gọi khi người dùng điều hướng lên hoặc ra khỏi một mục bằng cách sử dụng các phím điều hướng hoặc bi xoay.</dd>
+ <dt><code>onKey()</code></dt>
+ <dd>Từ {@link android.view.View.OnKeyListener}.
+ Phương pháp này được gọi khi người dùng được lấy tiêu điểm vào một mục và nhấn hoặc nhả phím cứng trên thiết bị.</dd>
+ <dt><code>onTouch()</code></dt>
+ <dd>Từ {@link android.view.View.OnTouchListener}.
+ Phương pháp này được gọi khi người dùng thực hiện một hành động được coi như một sự kiện chạm, bao gồm nhấn, nhả,
+ hoặc bất kỳ động tác chuyển động nào trên màn hình (trong đường biên của mục đó).</dd>
+ <dt><code>onCreateContextMenu()</code></dt>
+ <dd>Từ {@link android.view.View.OnCreateContextMenuListener}.
+ Phương pháp này được gọi khi một Menu Ngữ cảnh đang được xây dựng (kết quả của một sự kiện "nhấp giữ" kéo dài). Xem phần thảo luận về
+ menu ngữ cảnh trong hướng dẫn dành cho nhà phát triển <a href="{@docRoot}guide/topics/ui/menus.html#context-menu">Menu</a>
+.</dd>
+</dl>
+
+<p>Những phương pháp này là phương pháp duy nhất nằm trong giao diện tương ứng của chúng. Để định nghĩa một trong những phương pháp này
+và xử lý sự kiện của bạn, hãy triển khai giao diện lồng nhau trong Hoạt động của bạn hoặc định nghĩa nó thành một lớp vô danh.
+Sau đó, chuyển một thực thể triển khai của bạn
+tới phương pháp <code>View.set...Listener()</code> tương ứng. (Ví dụ, gọi
+<code>{@link android.view.View#setOnClickListener(View.OnClickListener) setOnClickListener()}</code>
+và chuyển cho nó triển khai {@link android.view.View.OnClickListener OnClickListener} của bạn.)</p>
+
+<p>Ví dụ bên dưới cho biết cách đăng ký một đối tượng theo dõi khi nhấp cho một Nút. </p>
+
+<pre>
+// Create an anonymous implementation of OnClickListener
+private OnClickListener mCorkyListener = new OnClickListener() {
+ public void onClick(View v) {
+ // do something when the button is clicked
+ }
+};
+
+protected void onCreate(Bundle savedValues) {
+ ...
+ // Capture our button from layout
+ Button button = (Button)findViewById(R.id.corky);
+ // Register the onClick listener with the implementation above
+ button.setOnClickListener(mCorkyListener);
+ ...
+}
+</pre>
+
+<p>Bạn cũng có thể thấy tiện hơn khi triển khai OnClickListener như một phần trong Hoạt động của mình.
+Làm vậy sẽ tránh phải tải lớp bổ sung và phân bổ đối tượng. Ví dụ:</p>
+<pre>
+public class ExampleActivity extends Activity implements OnClickListener {
+ protected void onCreate(Bundle savedValues) {
+ ...
+ Button button = (Button)findViewById(R.id.corky);
+ button.setOnClickListener(this);
+ }
+
+ // Implement the OnClickListener callback
+ public void onClick(View v) {
+ // do something when the button is clicked
+ }
+ ...
+}
+</pre>
+
+<p>Lưu ý rằng phương pháp gọi lại <code>onClick()</code> trong ví dụ trên không có giá trị
+trả về, nhưng một số phương pháp đối tượng theo dõi sự kiện khác phải trả về một boolean. Lý do
+này phụ thuộc vào sự kiện. Với số ít sự kiện thực hiện như vậy, sau đây là lý do:</p>
+<ul>
+ <li><code>{@link android.view.View.OnLongClickListener#onLongClick(View) onLongClick()}</code> -
+ Trả về một boolean cho biết bạn đã xử lý sự kiện và sự kiện không nên được tiếp tục hay không.
+ Cụ thể, trả về <em>true</em> để cho biết rằng bạn đã xử lý sự kiện và nó nên dừng ở đây;
+ trả về <em>false</em> nếu bạn chưa xử lý nó và/hoặc sự kiện sẽ tiếp tục đối với bất kỳ
+ đối tượng theo dõi khi nhấp nào khác.</li>
+ <li><code>{@link android.view.View.OnKeyListener#onKey(View,int,KeyEvent) onKey()}</code> -
+ Trả về một boolean cho biết bạn đã xử lý sự kiện và sự kiện không nên được tiếp tục hay không.
+ Cụ thể, trả về <em>true</em> sẽ cho biết rằng bạn đã xử lý sự kiện và nó nên dừng ở đây;
+ trả về <em>false</em> nếu bạn chưa xử lý nó và/hoặc sự kiện sẽ tiếp tục đối với bất kỳ
+ đối tượng theo dõi trên phím nào khác.</li>
+ <li><code>{@link android.view.View.OnTouchListener#onTouch(View,MotionEvent) onTouch()}</code> -
+ Trả về một boolean cho biết đối tượng theo dõi của bạn có xử lý sự kiện này hay không. Điều quan trọng đó là
+ sự kiện này có thể có nhiều hành động nối tiếp nhau. Vì vậy, nếu bạn trả về <em>false</em> khi
+ nhận được sự kiện hành động hướng xuống, bạn sẽ cho biết rằng mình chưa xử lý sự kiện và cũng
+ không quan tâm tới các hành động sau đó từ sự kiện này. Vì thế, bạn sẽ không bị gọi vì bất kỳ hành động nào khác
+ trong sự kiện, chẳng hạn như một cử chỉ ngón tay, hay sự kiện hành động cho sự kiện hướng lên.</li>
+</ul>
+
+<p>Ghi nhớ rằng các sự kiện phím cứng luôn được chuyển tới Dạng xem đang được lấy tiêu điểm. Chúng được chuyển bắt đầu từ trên cùng
+của phân cấp Dạng xem, rồi xuống dưới, tới khi chúng đến đích phù hợp. Nếu Dạng xem của bạn (hoặc con của Dạng xem)
+hiện có tiêu điểm, khi đó bạn có thể thấy hành trình của sự kiện qua phương pháp <code>{@link android.view.View#dispatchKeyEvent(KeyEvent)
+dispatchKeyEvent()}</code>. Một cách khác để chụp lại các sự kiện phím bấm thông qua Dạng xem của mình, bạn cũng có thể nhận
+tất cả sự kiện bên trong Hoạt động của mình bằng <code>{@link android.app.Activity#onKeyDown(int,KeyEvent) onKeyDown()}</code>
+và <code>{@link android.app.Activity#onKeyUp(int,KeyEvent) onKeyUp()}</code>.</p>
+
+<p>Đồng thời, khi nghĩ tới nhập liệu văn bản cho ứng dụng của bạn, hãy nhớ rằng nhiều thiết bị chỉ có các phương pháp
+nhập liệu mềm. Những phương pháp như vậy không bắt buộc phải dựa trên phím bấm; một số có thể sử dụng nhập liệu bằng giọng nói, viết tay, v.v. Ngay cả khi
+một phương pháp nhập liệu trình bày một giao diện như bàn phím, nó sẽ thường <strong>không</strong> kích khởi họ sự kiện
+<code>{@link android.app.Activity#onKeyDown(int,KeyEvent) onKeyDown()}</code>. Bạn không nên
+xây dựng UI yêu cầu kiểm soát các thao tác nhấn phím cụ thể trừ khi muốn giới hạn ứng dụng của bạn ở một số thiết bị
+có bàn phím cứng. Cụ thể, không được dựa vào những phương pháp này để xác thực nhập liệu khi người dùng nhấn phím
+quay lại; thay vào đó, hãy sử dụng các hành động như {@link android.view.inputmethod.EditorInfo#IME_ACTION_DONE} để báo hiệu với
+phương pháp nhập liệu bạn kỳ vọng ứng dụng của mình sẽ phản ứng như thế nào để nó có thể thay đổi UI của mình cho có nghĩa. Tránh các giả định
+về cách thức hoạt động của một phương pháp nhập liệu mềm và chỉ tin tưởng để nó cung cấp văn bản đã có định dạng cho ứng dụng của mình.</p>
+
+<p class="note"><strong>Lưu ý:</strong> Android sẽ gọi bộ xử lý sự kiện trước rồi mới tới bộ xử lý
+mặc định phù hợp từ định nghĩa lớp. Như thế, việc trả về <em>true</em> từ những đối tượng theo dõi sự kiện này sẽ dừng
+việc lan truyền sự kiện tới đối tượng theo dõi sự kiện khác và cũng sẽ chặn phương pháp gọi lại tới
+bộ xử lý sự kiện mặc định trong Dạng xem. Vì thế, hãy chắc chắn rằng bạn muốn chấm dứt sự kiện khi trả về <em>true</em>.</p>
+
+
+<h2 id="EventHandlers">Bộ xử lý Sự kiện</h2>
+
+<p>Nếu bạn đang xây dựng một thành phần tùy chỉnh từ Dạng xem, khi đó bạn sẽ có thể định nghĩa một vài phương pháp gọi lại
+được sử dụng như bộ xử lý sự kiện mặc định.
+Trong tài liệu về <a href="{@docRoot}guide/topics/ui/custom-components.html">Thành phần
+Tùy chỉnh</a>, bạn sẽ tìm hiểu về một số phương pháp gọi lại phổ biến được sử dụng để xử lý sự kiện,
+bao gồm:</p>
+<ul>
+ <li><code>{@link android.view.View#onKeyDown}</code> - Được gọi khi xảy ra một sự kiện phím bấm mới.</li>
+ <li><code>{@link android.view.View#onKeyUp}</code> - Được gọi khi xảy ra một sự kiện phím bấm hướng lên.</li>
+ <li><code>{@link android.view.View#onTrackballEvent}</code> - Được gọi khi xảy ra một sự kiện chuyển động bi xoay.</li>
+ <li><code>{@link android.view.View#onTouchEvent}</code> - Được gọi khi xảy ra một sự kiện chuyển động màn hình cảm ứng.</li>
+ <li><code>{@link android.view.View#onFocusChanged}</code> - Được gọi khi dạng xem có hoặc mất tiêu điểm.</li>
+</ul>
+<p>Có một số phương pháp khác mà bạn cần lưu ý, chúng không thuộc lớp Dạng xem,
+nhưng có thể tác động trực tiếp tới cách bạn có thể xử lý sự kiện. Vì thế, khi quản lý các sự kiện phức tạp hơn bên trong
+một bố trí, hãy xét những phương pháp khác sau:</p>
+<ul>
+ <li><code>{@link android.app.Activity#dispatchTouchEvent(MotionEvent)
+ Activity.dispatchTouchEvent(MotionEvent)}</code> - Phương pháp này cho phép {@link
+ android.app.Activity} của bạn can thiệp vào tất cả sự kiện chạm trước khi chúng được phân phối tới cửa sổ.</li>
+ <li><code>{@link android.view.ViewGroup#onInterceptTouchEvent(MotionEvent)
+ ViewGroup.onInterceptTouchEvent(MotionEvent)}</code> - Phương pháp này cho phép một {@link
+ android.view.ViewGroup} xem sự kiện khi chúng được phân phối tới Dạng xem con.</li>
+ <li><code>{@link android.view.ViewParent#requestDisallowInterceptTouchEvent(boolean)
+ ViewParent.requestDisallowInterceptTouchEvent(boolean)}</code> - Gọi phương pháp
+ này trên Dạng xem mẹ để cho biết rằng nó sẽ không can thiệp vào các sự kiện chạm bằng <code>{@link
+ android.view.ViewGroup#onInterceptTouchEvent(MotionEvent)}</code>.</li>
+</ul>
+
+<h2 id="TouchMode">Chế độ Cảm ứng</h2>
+<p>
+Khi một người dùng đang điều hướng trong một giao diện người dùng bằng phím hướng hoặc bi xoay, cần
+lấy tiêu điểm tới các mục có thể hành động (như nút) sao cho người dùng có thể thấy
+mục nào sẽ chấp nhận nhập liệu. Tuy nhiên, nếu thiết bị có khả năng cảm ứng, và người dùng
+bắt đầu tương tác với giao diện bằng cách chạm vào nó, khi đó không còn cần
+tô sáng mục hay lấy tiêu điểm tới một Dạng xem cụ thể nữa. Do đó, có một chế độ cho
+tương tác có tên là "chế độ cảm ứng."
+</p>
+<p>
+Đối với thiết bị có khả năng cảm ứng, sau khi người dùng chạm vào màn hình, thiết bị
+sẽ vào chế độ cảm ứng. Từ điểm này trở đi, chỉ những Dạng xem mà
+{@link android.view.View#isFocusableInTouchMode} là đúng mới có thể lấy tiêu điểm, chẳng hạn như chế độ xem các widget chỉnh sửa văn bản.
+Các Dạng xem chạm được, chẳng hạn như nút, sẽ không lấy được tiêu điểm khi chạm; chúng sẽ chỉ đơn giản
+khởi chạy đối tượng theo dõi khi nhấp của mình khi được nhấn.
+</p>
+<p>
+Bất cứ khi nào một người dùng nhấn phím hướng hoặc cuộn bằng bi xoay, thiết bị sẽ
+thoát chế độ cảm ứng, và tìm một dạng xem để lấy tiêu điểm. Lúc này, người dùng có thể tiếp tục tương tác
+với giao diện người dùng mà không chạm vào màn hình.
+</p>
+<p>
+Trạng thái chế độ cảm ứng sẽ được duy trì trên toàn bộ hệ thống (tất cả cửa sổ và hoạt động).
+Để truy vấn trạng thái hiện tại, bạn có thể gọi
+{@link android.view.View#isInTouchMode} để xem liệu thiết bị có đang ở trong chế độ cảm ứng hay không.
+</p>
+
+
+<h2 id="HandlingFocus">Xử lý Tiêu điểm</h2>
+
+<p>Khuôn khổ sẽ xử lý chuyển động của tiêu điểm thường xuyên hồi đáp lại nhập liệu của người dùng.
+Việc này bao gồm thay đổi tiêu điểm khi Dạng xem bị loại bỏ hoặc ẩn đi, hoặc khi Dạng xem
+mới có sẵn. Dạng xem thể hiện sự sẵn sàng lấy tiêu điểm của chúng
+thông qua phương pháp <code>{@link android.view.View#isFocusable()}</code>. Để thay đổi việc liệu một Dạng xem có thể lấy
+tiêu điểm hay không, hãy gọi <code>{@link android.view.View#setFocusable(boolean) setFocusable()}</code>. Khi ở trong chế độ cảm ứng,
+bạn có thể truy vấn xem Dạng xem có cho phép lấy tiêu điểm bằng <code>{@link android.view.View#isFocusableInTouchMode()}</code> hay không.
+Bạn có thể thay đổi điều này bằng <code>{@link android.view.View#setFocusableInTouchMode(boolean) setFocusableInTouchMode()}</code>.
+</p>
+
+<p>Chuyển động tiêu điểm được dựa trên một giải thuật tìm kiếm đối tượng gần nhất theo
+một hướng cho trước. Trong các trường hợp hiếm gặp, giải thuật mặc định có thể không khớp với
+hành vi theo ý định của nhà phát triển. Trong những tình huống này, bạn có thể cung cấp
+các khống chế rõ ràng với các thuộc tính XML sau trong tệp bố trí:
+<var>nextFocusDown</var>, <var>nextFocusLeft</var>, <var>nextFocusRight</var>, và
+<var>nextFocusUp</var>. Thêm một trong những thuộc tính này vào Dạng xem mà <em>từ</em> đó
+tiêu điểm đang rời khỏi. Định nghĩa giá trị của thuộc tính là id của Dạng xem
+<em>mà</em> cần được lấy tiêu điểm. Ví dụ:</p>
+<pre>
+&lt;LinearLayout
+ android:orientation="vertical"
+ ... >
+ &lt;Button android:id="@+id/top"
+ android:nextFocusUp="@+id/bottom"
+ ... />
+ &lt;Button android:id="@+id/bottom"
+ android:nextFocusDown="@+id/top"
+ ... />
+&lt;/LinearLayout>
+</pre>
+
+<p>Thông thưởng, trong bố trí thẳng đứng này, việc điều hướng lên từ Nút đầu tiên sẽ không
+đi tới đâu hết và việc điều hướng xuống từ Nút thứ hai cũng vậy. Giờ thì khi Nút trên cùng
+đã định nghĩa Nút dưới cùng là <var>nextFocusUp</var> (và ngược lại), tiêu điểm điều hướng sẽ
+luân chuyển từ trên-xuống-dưới và dưới-lên-trên.</p>
+
+<p>Nếu bạn muốn khai báo một Dạng xem là có thể lấy tiêu điểm trong UI của mình (thông thường thì không),
+hãy thêm thuộc tính XML <code>android:focusable</code> vào Dạng xem, trong khai báo bố trí của bạn.
+Đặt giá trị <var>true</var>. Bạn cũng có thể khai báo một Dạng xem
+là có thể lấy tiêu điểm trong khi ở Chế độ Cảm ứng bằng <code>android:focusableInTouchMode</code>.</p>
+<p>Để yêu cầu một Dạng xem cụ thể để lấy tiêu điểm, hãy gọi <code>{@link android.view.View#requestFocus()}</code>.</p>
+<p>Để theo dõi các sự kiện tiêu điểm (được thông báo khi một Dạng xem nhận được hoặc mất tiêu điểm), hãy sử dụng
+<code>{@link android.view.View.OnFocusChangeListener#onFocusChange(View,boolean) onFocusChange()}</code>,
+như được đề cập trong phần <a href="#EventListeners">Đối tượng theo dõi Sự kiện</a> bên trên.</p>
+
+
+
+<!--
+<h2 is="EventCycle">Event Cycle</h2>
+ <p>The basic cycle of a View is as follows:</p>
+ <ol>
+ <li>An event comes in and is dispatched to the appropriate View. The View
+ handles the event and notifies any listeners.</li>
+ <li>If, in the course of processing the event, the View's bounds may need
+ to be changed, the View will call {@link android.view.View#requestLayout()}.</li>
+ <li>Similarly, if in the course of processing the event the View's appearance
+ may need to be changed, the View will call {@link android.view.View#invalidate()}.</li>
+ <li>If either {@link android.view.View#requestLayout()} or {@link android.view.View#invalidate()} were called,
+ the framework will take care of measuring, laying out, and drawing the tree
+ as appropriate.</li>
+ </ol>
+
+ <p class="note"><strong>Note:</strong> The entire View tree is single threaded. You must always be on
+ the UI thread when calling any method on any View.
+ If you are doing work on other threads and want to update the state of a View
+ from that thread, you should use a {@link android.os.Handler}.
+ </p>
+-->
diff --git a/docs/html-intl/intl/vi/sdk/index.jd b/docs/html-intl/intl/vi/sdk/index.jd
new file mode 100644
index 000000000000..401476ea41ef
--- /dev/null
+++ b/docs/html-intl/intl/vi/sdk/index.jd
@@ -0,0 +1,487 @@
+page.title=Tải xuống Android Studio và SDK Tools
+page.tags=sdk, android studio
+page.template=sdk
+header.hide=1
+page.metaDescription=Tải xuống Android IDE chính thức và bộ công cụ cho nhà phát triển để xây dựng ứng dụng cho điện thoại, máy tính bảng, thiết bị đeo được, TV chạy Android và nhiều thiết bị khác.
+
+studio.version=1.1.0
+
+studio.linux_bundle_download=android-studio-ide-135.1740770-linux.zip
+studio.linux_bundle_bytes=259336386
+studio.linux_bundle_checksum=e8d166559c50a484f83ebfec6731cc0e3f259208
+
+studio.mac_bundle_download=android-studio-ide-135.1740770-mac.dmg
+studio.mac_bundle_bytes=261303345
+studio.mac_bundle_checksum=f9745d0fec1eefd498f6160a2d6a1b5247d4cda3
+
+studio.win_bundle_exe_download=android-studio-bundle-135.1740770-windows.exe
+studio.win_bundle_exe_bytes=856233768
+studio.win_bundle_exe_checksum=7484b9989d2914e1de30995fbaa97a271a514b3f
+
+studio.win_notools_exe_download=android-studio-ide-135.1740770-windows.exe
+studio.win_notools_exe_bytes=242135128
+studio.win_notools_exe_checksum=5ea77661cd2300cea09e8e34f4a2219a0813911f
+
+studio.win_bundle_download=android-studio-ide-135.1740770-windows.zip
+studio.win_bundle_bytes=261667054
+studio.win_bundle_checksum=e903f17cc6a57c7e3d460c4555386e3e65c6b4eb
+
+
+
+sdk.linux_download=android-sdk_r24.1.2-linux.tgz
+sdk.linux_bytes=168121693
+sdk.linux_checksum=68980e4a26cca0182abb1032abffbb72a1240c51
+
+sdk.mac_download=android-sdk_r24.1.2-macosx.zip
+sdk.mac_bytes=89151287
+sdk.mac_checksum=00e43ff1557e8cba7da53e4f64f3a34498048256
+
+sdk.win_download=android-sdk_r24.1.2-windows.zip
+sdk.win_bytes=159778618
+sdk.win_checksum=704f6c874373b98e061fe2e7eb34f9fcb907a341
+
+sdk.win_installer=installer_r24.1.2-windows.exe
+sdk.win_installer_bytes=111364285
+sdk.win_installer_checksum=e0ec864efa0e7449db2d7ed069c03b1f4d36f0cd
+
+
+
+
+
+
+@jd:body
+
+<style type="text/css">
+ .offline {display:none;}
+ a.download-bundle-button {display:block;}
+ h2.feature {
+ padding-top:30px;
+ margin-top:0;
+ clear:both;
+ }
+ .feature-blurb {
+ margin:0px; font-size:16px; font-weight:300;
+ padding:40px 0 0 0;
+ }
+
+ .landing-button.green {
+ font-size:16px;
+ background-color:#90c653;
+ padding:8px 10px 10px;
+ margin:0;
+ width:206px;
+ text-align:center;
+ }
+
+ .landing-button.green:hover {
+ background-color:#85b84f;
+ }
+
+ .landing-button .small {
+ font-size: 12px;
+ font-weight: normal;
+ line-height: 12px;
+ display: block;
+ }
+
+ h1.studio-logo {
+ width:226px;
+ height:78px;
+ display:block;
+ padding:0;
+ white-space: nowrap;
+ text-indent: -10000px;
+ font-size:0px;
+ background: url(../images/tools/studio-logo.png);
+ background-image: -webkit-image-set(url(../images/tools/studio-logo.png) 1x, url(../images/tools/studio-logo_2x.png) 2x);
+ background-size: 226px 78px;
+ }
+
+</style>
+
+
+
+
+
+<div style="position:relative;">
+
+
+<div class="wrap" id="tos" style="display:none;width:inherit;height:650px">
+<div class="col-13" style="margin:0;">&nbsp;</div><!-- provides top margin for content -->
+
+<h1 id="tos-header" style="margin-top:0">Tải xuống</h1>
+
+<p class="sdk-terms-intro">Trước khi cài đặt Android Studio hoặc bộ công cụ SDK độc lập,
+bạn phải đồng ý với các điều khoản và điều kiện sau.</p>
+
+<div class="sdk-terms" onfocus="this.blur()">
+<h2 class="norule">Điều khoản và Điều kiện</h2>
+Đây là Thỏa thuận Cấp phép cho Bộ công cụ Phát triển Phần mềm Android
+
+<h3>1. Giới thiệu</h3>
+1.1 Bộ công cụ Phát triển Phần mềm Android (trong Thỏa thuận Cấp phép này gọi là "SDK" và cụ thể bao gồm các tệp hệ thống Android, các API dạng gói, và phần bổ sung Google API) được cấp phép cho bạn theo các điều khoản của Thỏa thuận Cấp phép này. Thỏa thuận Cấp phép hợp thành một hợp đồng ràng buộc pháp lý giữa bạn và Google liên quan tới việc bạn sử dụng SDK.
+
+1.2 "Android" có nghĩa là chồng phần mềm Android cho thiết bị, được cung cấp theo Dự án Nguồn mở Android, nằm ở địa chỉ URL sau: http://source.android.com/, được cập nhật trong từng thời kỳ.
+
+1.3 "Google" có nghĩa là Google Inc., một công ty ở Delaware với trụ sở kinh doanh chính tại 1600 Amphitheatre Parkway, Mountain View, CA 94043, Hoa Kỳ.
+
+
+<h3>2. Chấp nhận Thỏa thuận Cấp phép này</h3>
+2.1 Để sử dụng SDK, trước tiên bạn phải đồng ý với Thỏa thuận Cấp phép này. Bạn không được sử dụng SDK nếu không chấp nhận Thỏa thuận Cấp phép này.
+
+2.2 Bằng việc nhấp vào chấp nhận, theo đây bạn đồng ý với các điều khoản của Thỏa thuận Cấp phép này.
+
+2.3 Bạn không được sử dụng SDK và không được chấp nhận Thỏa thuận Cấp phép nếu bạn là người bị cấm nhận SDK theo pháp luật của Hoa Kỳ hoặc các quốc gia khác bao gồm quốc gia nơi bạn cư trú hoặc nơi mà bạn sử dụng SDK từ đó.
+
+2.4 Nếu bạn đồng ý chịu ràng buộc bởi Thỏa thuận Cấp phép này đại diện cho bên tuyển dụng của mình hoặc đơn vị khác, bạn tuyên bố và bảo đảm rằng bạn có đầy đủ thẩm quyền pháp lý để ràng buộc bên tuyển dụng của mình hoặc đơn vị đó với Thỏa thuận Cấp phép này. Nếu không có thẩm quyền cần thiết, bạn không được chấp nhận Thỏa thuận Cấp phép hay sử dụng SDK đại diện cho bên tuyển dụng của mình hoặc đơn vị khác.
+
+
+<h3>3. Giấy phép SDK từ Google</h3>
+3.1 Tùy thuộc vào các điều khoản của Thỏa thuận Cấp phép này, Google cấp cho bạn một giấy phép giới hạn, toàn cầu, miễn phí sử dụng, không thể chuyển nhượng và không độc quyền để sử dụng SDK cho mục đích duy nhất là phát triển các ứng dụng chạy trên nền tảng Android.
+
+3.2 Bạn đồng ý rằng Google hoặc các bên thứ ba sở hữu tất cả quyền, quyền sở hữu hoặc lợi ích hợp pháp trong và đối với SDK, bao gồm bất kỳ Quyền Sở hữu Trí tuệ nào nằm trong SDK. "Quyền Sở hữu Trí tuệ" có nghĩa là bất kỳ và tất cả các quyền theo luật về bằng sáng chế, luật về bản quyền, luật về bí mật thương mại, luật về nhãn hiệu thương mại và bất kỳ và tất cả các quyền sở hữu khác. Google bảo lưu tất cả các quyền không được cấp phép rõ ràng cho bạn.
+
+3.3 Bạn không được sử dụng SDK cho bất kỳ mục đích nào không được cho phép rõ ràng bởi Thỏa thuận Cấp phép này. Trừ trường hợp được yêu cầu bởi giấy phép của bên thứ ba có liên quan, bạn không được: (a) sao chép (trừ trường hợp sao lưu), sửa đổi, điều chỉnh cho phù hợp, phân phối lại, biên dịch ngược, kỹ thuật đảo ngược, phân rã, hoặc tạo sản phẩm phái sinh từ SDK hay bất kỳ phần nào của SDK; hoặc (b) tải bất kỳ phần nào của SDK lên một thiết bị cầm tay di động hoặc bất kỳ thiết bị phần cứng nào khác ngoại trừ máy tính cá nhân, kết hợp bất kỳ phần nào của SDK với phần mềm khác, hay phân phối bất kỳ phần mềm hay thiết bị nào tích hợp một phần của SDK.
+
+3.4 Bạn đồng ý rằng bạn sẽ không thực hiện bất kỳ hành động nào mà có thể gây ra hoặc dẫn đến sự phân mảnh Android, bao gồm nhưng không giới hạn trong việc phân phối, tham gia vào việc tạo lập, hoặc xúc tiến một bộ phát triển phần mềm được tạo từ SDK dưới bất kỳ hình thức nào.
+
+3.5 Việc sử dụng, tái tạo lại và phân phối các thành phần của SDK được cấp phép theo một giấy phép phần mềm nguồn mở được chi phối chủ yếu bởi các điều khoản của giấy phép phần mềm nguồn mở đó chứ không phải Thỏa thuận Cấp phép này.
+
+3.6 Bạn đồng ý rằng hình thức và tính chất của SDK mà Google cung cấp có thể thay đổi mà không có thông báo trước cho bạn và rằng các phiên bản sau này của SDK có thể không tương thích với các ứng dụng được phát triển trên những phiên bản trước của SDK. Bạn đồng ý rằng Google có thể dừng (vĩnh viễn hoặc tạm thời) cung cấp SDK (hay bất kỳ tính năng nào trong SDK) cho bạn hoặc cho người dùng nói chung theo toàn quyền quyết định của Google mà không cần thông báo trước cho bạn.
+
+3.7 Không nội dung nào trong Thỏa thuận Cấp phép này trao cho bạn quyền được sử dụng bất kỳ tên thương mại, nhãn hiệu thương mại, nhãn hiệu dịch vụ, logo, tên miền, hay các đặc trưng thương hiệu riêng khác của Google.
+
+3.8 Bạn đồng ý rằng bạn sẽ không gỡ bỏ, che chắn hay thay đổi bất kỳ thông báo về quyền sở hữu nào (bao gồm thông báo về bản quyền và nhãn hiệu thương mại) mà có thể được gắn vào hay chứa trong SDK.
+
+
+<h3>4. Việc Bạn sử dụng SDK</h3>
+4.1 Google đồng ý rằng Google không có quyền, quyền sở hữu hay lợi ích từ bạn (hay bên cấp phép của bạn) theo Thỏa thuận Cấp phép này trong hoặc đối với bất kỳ ứng dụng phần mềm nào mà bạn phát triển bằng cách sử dụng SDK, bao gồm bất kỳ quyền sở hữu trí tuệ nào nằm trong những ứng dụng đó.
+
+4.2 Bạn đồng ý sử dụng SDK và viết ứng dụng chỉ cho các mục đích được cho phép bởi (a) Thỏa thuận Cấp phép này và (b) bất kỳ luật, quy định hoặc thực hành áp dụng nào hoặc hướng dẫn được chấp nhận chung ở các lãnh thổ pháp lý có liên quan (bao gồm bất kỳ luật nào về việc xuất khẩu dữ liệu hoặc phần mềm đến và từ Hoa Kỳ hoặc các nước có liên quan khác).
+
+4.3 Bạn đồng ý rằng nếu bạn sử dụng SDK để phát triển ứng dụng cho người dùng công cộng, bạn sẽ bảo vệ quyền riêng tư và các quyền hợp pháp của những người dùng đó. Nếu người dùng cung cấp cho bạn tên người dùng, mật khẩu hoặc thông tin đăng nhập hay thông tin cá nhân khác, bạn phải thông báo cho người dùng rằng thông tin sẽ được sử dụng cho ứng dụng của bạn, và bạn phải cung cấp thông báo về quyền riêng tư và sự bảo vệ thỏa đáng về mặt pháp lý cho những người dùng đó. Nếu ứng dụng của bạn lưu trữ thông tin cá nhân hoặc nhạy cảm được cung cấp bởi người dùng, ứng dụng phải làm vậy một cách bảo mật. Nếu người dùng cung cấp cho ứng dụng của bạn thông tin về Tài khoản Google, ứng dụng của bạn chỉ được sử dụng thông tin đó để truy cập Tài khoản Google của người dùng khi, và chỉ cho các mục đích giới hạn mà người dùng đã cấp phép cho bạn để thực hiện.
+
+4.4 Bạn đồng ý rằng bạn sẽ không tham gia vào bất kỳ hoạt động nào với SDK, bao gồm việc phát triển hoặc phân phối một ứng dụng, mà can thiệp vào, làm gián đoạn, gây thiệt hại, hoặc truy cập một cách trái phép vào máy chủ, mạng hoặc tài sản hay dịch vụ khác của bất kỳ bên thứ ba nào bao gồm nhưng không giới hạn ở Google hoặc bất kỳ nhà mạng truyền thông di động nào.
+
+4.5 Bạn đồng ý rằng bạn hoàn toàn chịu trách nhiệm (và rằng Google không có trách nhiệm đối với bạn hay bất kỳ bên thứ ba nào) về bất kỳ dữ liệu, nội dung hay tài nguyên nào mà bạn tạo lập, truyền hoặc hiển thị thông qua Android và/hoặc các ứng dụng cho Android, và về hậu quả của những hành động của bạn (bao gồm bất kỳ tổn thất hay thiệt hại nào mà Google có thể phải gánh chịu) bởi việc làm như vậy.
+
+4.6 Bạn đồng ý rằng bạn hoàn toàn chịu trách nhiệm (và rằng Google không có trách nhiệm đối với bạn hay bất kỳ bên thứ ba nào) về bất kỳ vi phạm nào đối với các nghĩa vụ của bạn theo Thỏa thuận Cấp phép này, bất kỳ hợp đồng với bên thứ ba áp dụng nào hoặc các Điều khoản Dịch vụ, hoặc bất kỳ luật hay quy định áp dụng nào, và về hậu quả của những hành động của bạn (bao gồm bất kỳ tổn thất hay thiệt hại nào mà Google hoặc bất kỳ bên thứ ba nào có thể phải gánh chịu) do bất kỳ sự vi phạm nào như vậy.
+
+
+<h3>5. Thông tin Xác thực Nhà phát triển của bạn</h3>
+5.1 Bạn đồng ý rằng bạn chịu trách nhiệm duy trì tính bảo mật của bất kỳ thông tin xác thực nhà phát triển nào mà có thể được phát hành cho bạn bởi Google hoặc bạn có thể tự chọn và rằng bạn sẽ hoàn toàn chịu trách nhiệm về tất cả ứng dụng được phát triển theo thông tin xác thực nhà phát triển của bạn.
+
+
+<h3>6. Quyền riêng tư và Thông tin</h3>
+6.1 Để tiếp tục đổi mới và cải thiện SDK, Google có thể thu thập một số thống kê về sử dụng từ phần mềm bao gồm nhưng không giới hạn trong mã nhận diện duy nhất, địa chỉ IP liên kết, số phiên bản của phần mềm, và thông tin về những công cụ và/hoặc dịch vụ trong SDK đang được sử dụng và chúng đang được sử dụng như thế nào. Trước khi bất kỳ thông tin nào được thu thập, SDK sẽ thông báo cho bạn và xin sự đồng ý của bạn. Nếu bạn từ chối cho phép, thông tin sẽ không được thu thập.
+
+6.2 Dữ liệu thu thập được kiểm tra ở dạng tổng hợp để cải thiện SDK và được duy trì theo Chính sách Quyền riêng tư của Google.
+
+
+<h3>7. Ứng dụng của Bên thứ ba</h3>
+7.1 Nếu bạn sử dụng Sử dụng để chạy các ứng dụng được phát triển bởi một bên thứ ba hoặc truy cập dữ liệu, nội dung hoặc tài nguyên được cung cấp bởi một bên thứ ba, bạn đồng ý rằng Google không chịu trách nhiệm về những ứng dụng, dữ liệu, nội dung hoặc tài nguyên đó. Bạn hiểu rằng tất cả dữ liệu, nội dung hoặc tài nguyên mà bạn có thể truy cập thông qua các ứng dụng của bên thứ ba như vậy hoàn toàn thuộc trách nhiệm của người cung cấp chúng và rằng Google không chịu trách nhiệm về bất kỳ tổn thất hay thiệt hại nào mà bạn có thể gặp phải do kết quả từ việc sử dụng hay truy cập bất kỳ ứng dụng của bên thứ ba, dữ liệu, nội dung hay tài nguyên nào như vậy.
+
+7.2 Bạn cần ý thức được rằng dữ liệu, nội dung và tài nguyên được trình bày cho bạn thông qua một ứng dụng của bên thứ ba như vậy có thể được bảo vệ bởi các quyền sở hữu trí tuệ thuộc sở hữu của các nhà cung cấp (hoặc bởi cá nhân hoặc công ty khác đại diện cho họ). Bạn không được sửa đổi, thuê, cho thuê, cho vay, bán, phân phối hoặc tạo sản phẩm phái sinh dựa trên những dữ liệu, nội dung hoặc tài nguyên này (hoặc toàn bộ hoặc một phần) trừ khi bạn đã được cấp phép cụ thể để làm vậy bởi chủ sở hữu có liên quan.
+
+7.3 Bạn hiểu rằng việc bạn sử dụng các ứng dụng, dữ liệu, nội dung hoặc tài nguyên của bên thứ ba như vậy có thể phải tuân thủ các điều khoản riêng giữa bạn và bên thứ ba có liên quan. Trong trường hợp đó, Thỏa thuận Cấp phép này không ảnh hưởng tới mối quan hệ pháp lý giữa bạn và những bên thứ ba này.
+
+
+<h3>8. Sử dụng các API Android</h3>
+8.1 API Google Data
+
+8.1.1 Nếu bạn sử dụng bất kỳ API nào để truy xuất dữ liệu từ Google, bạn hiểu rằng dữ liệu có thể được bảo vệ bởi quyền sở hữu trí tuệ thuộc sở hữu của Google hoặc những bên cung cấp dữ liệu (hoặc bởi cá nhân hoặc công ty khác đại diện cho họ). Việc bạn sử dụng bất kỳ API nào như vậy có thể phải tuân theo các Điều khoản Dịch vụ bổ sung. Bạn không được sửa đổi, thuê, cho thuê, cho vay, bán, phân phối hoặc tạo sản phẩm phái sinh dựa trên dữ liệu này (hoặc toàn bộ hoặc một phần) trừ khi được cho phép bởi các Điều khoản Dịch vụ có liên quan.
+
+8.1.2 Nếu bạn sử dụng bất kỳ API nào để truy xuất dữ liệu của một người dùng từ Google, bạn hiểu và đồng ý rằng bạn sẽ chỉ truy xuất dữ liệu với sự cho phép rõ ràng của người dùng và chỉ khi, và cho các mục đích giới hạn mà người dùng đã được cấp quyền để thực hiện.
+
+
+<h3>9. Chấm dứt Thỏa thuận Cấp phép này</h3>
+9.1 Thỏa thuận Cấp phép này sẽ tiếp tục áp dụng tới khi bị chấm dứt bởi bạn hoặc Google như quy định bên dưới.
+
+9.2 Nếu bạn muốn chấm dứt Thỏa thuận Cấp phép này, bạn có thể làm vậy bằng cách dừng sử dụng SDK và bất kỳ thông tin xác thực nhà phát triển có liên quan nào.
+
+9.3 Google có thể, vào bất cứ lúc nào, chấm dứt Thỏa thuận Cấp phép này với bạn nếu:
+(A) bạn đã vi phạm bất kỳ quy định nào của Thỏa thuận Cấp phép này; hoặc
+(B) Google bị pháp luật yêu cầu phải làm vậy; hoặc
+(C) đối tác mà cùng với họ Google đã cung cấp một số phần của SDK (chẳng hạn như API) cho bạn đã chấm dứt mối quan hệ với Google hoặc dừng cung cấp một số phần của SDK cho bạn; hoặc
+(D) Google quyết định không cung cấp SDK hoặc một số phần của SDK cho người dùng ở quốc gia nơi bạn cư trú hoặc nơi mà bạn sử dụng dịch vụ từ đó, hoặc việc cung cấp SDK hoặc một số dịch vụ SDK cho bạn bởi Google, theo quyết định của Google, không còn khả thi về mặt thương mại.
+
+9.4 Khi Thỏa thuận Cấp phép này kết thúc, tất cả các quyền, nghĩa vụ và trách nhiệm hợp pháp mà bạn và Google đã hưởng lợi từ đó, phải tuân theo (hoặc đã phát sinh qua thời gian trong khi Thỏa thuận Cấp phép này có hiệu lực) hoặc được biểu hiện là sẽ tiếp tục vô thời hạn, sẽ không bị ảnh hưởng bởi sự chấm dứt này, và các quy định của đoạn 14.7 sẽ tiếp tục áp dụng cho các quyền, nghĩa vụ và trách nhiệm đó trong thời hạn không xác định.
+
+
+<h3>10. TUYÊN BỐ MIỄN TRỪ TRÁCH NHIỆM BẢO ĐẢM</h3>
+10.1 BẠN HIỂU VÀ ĐỒNG Ý RÕ RÀNG RẰNG VIỆC BẠN SỬ DỤNG SDK HOÀN TOÀN LÀ RỦI RO CỦA BẠN VÀ RẰNG SDK ĐƯỢC CUNG CẤP TRÊN CƠ SỞ “NGUYÊN TRẠNG” VÀ “CÓ SẴN” MÀ KHÔNG CÓ BẤT KỲ SỰ BẢO ĐẢM NÀO TỪ GOOGLE.
+
+10.2 VIỆC BẠN SỬ DỤNG SDK VÀ BẤT KỲ TÀI NGUYÊN NÀO ĐƯỢC TẢI XUỐNG HOẶC CÓ ĐƯỢC BẰNG CÁCH KHÁC THÔNG QUA VIỆC SỬ DỤNG SDK LÀ QUYẾT ĐỊNH VÀ RỦI RO CỦA CHÍNH BẠN VÀ BẠN HOÀN TOÀN CHỊU TRÁCH NHIỆM VỀ BẤT KỲ THIỆT HẠI NÀO ĐỐI VỚI HỆ THỐNG MÁY TÍNH HOẶC BẠN HOẶC THIẾT BỊ KHÁC HOẶC VIỆC MẤT DỮ LIỆU LÀ KẾT QUẢ TỪ VIỆC SỬ DỤNG ĐÓ.
+
+10.3 GOOGLE CÔNG KHAI TUYÊN BỐ MIỄN TRỪ TRÁCH NHIỆM ĐỐI VỚI TẤT CẢ BẢO ĐẢM VÀ ĐIỀU KIỆN CÁC LOẠI, DÙ RÕ RÀNG HAY NGỤ Ý, BAO GỒM, NHƯNG KHÔNG GIỚI HẠN TRONG NHỮNG BẢO ĐẢM VÀ ĐIỀU KIỆN NGỤ Ý VỀ KHẢ NĂNG MUA BÁN ĐƯỢC, SỰ PHÙ HỢP CHO MỘT MỤC ĐÍCH CỤ THỂ VÀ KHÔNG XÂM PHẠM.
+
+
+<h3>11. GIỚI HẠN TRÁCH NHIỆM PHÁP LÝ</h3>
+11.1 BẠN HIỂU VÀ ĐỒNG Ý RÕ RÀNG RẰNG GOOGLE, CÁC CÔNG TY CON VÀ CÔNG TY LIÊN KẾT CỦA GOOGLE, VÀ CÁC BÊN CẤP PHÉP CỦA GOOGLE SẼ KHÔNG CHỊU TRÁCH NHIỆM PHÁP LÝ ĐỐI VỚI BẠN THEO BẤT KỲ QUY ĐỊNH TRÁCH NHIỆM PHÁP LÝ NÀO VỀ BẤT KỲ THIỆT HẠI MANG TÍNH TRỰC TIẾP, GIÁN TIẾP, NGẪU NHIÊN, ĐẶC BIỆT, HẬU QUẢ HOẶC BẤT THƯỜNG NÀO MÀ BẠN CÓ THỂ PHẢI CHỊU, BAO GỒM BẤT KỲ TRƯỜNG HỢP MẤT DỮ LIỆU NÀO, DÙ GOOGLE HAY ĐẠI DIỆN CỦA GOOGLE ĐÃ ĐƯỢC BIẾT VỀ KHẢ NĂNG PHÁT SINH MẤT MÁT NHƯ VẬY HAY KHÔNG.
+
+
+<h3>12. Bồi thường</h3>
+12.1 Trong giới hạn tối đa mà pháp luật cho phép, bạn đồng ý bảo vệ, bồi thường và đảm bảo Google, các công ty liên kết của họ và các giám đốc, viên chức, nhân viên và đại lý tương ứng của họ không bị thiệt hại trước và đối với bất kỳ và tất cả các khiếu nại, hành động, kiện tụng hoặc thủ tục pháp lý cũng như bất kỳ và tất cả các tổn thất, trách nhiệm pháp lý, thiệt hại, chi phí và phí tổn nào (bao gồm phí luật sư hợp lý) phát sinh từ hoặc phải trả từ (a) việc bạn sử dụng SDK, (b) bất kỳ ứng dụng nào do bạn phát triển trên SDK mà xâm phạm bất kỳ bản quyền, nhãn hiệu thương mại, bí mật thương mại, kiểu dáng thương mại, bằng sáng chế hay quyền sở hữu trí tuệ khác của bất kỳ người nào hay bôi nhọ bất kỳ người nào hoặc vi phạm các quyền công khai hoặc riêng tư của họ, và (c) bất kỳ sự không tuân thủ nào của bạn đối với Thỏa thuận Cấp phép này.
+
+
+<h3>13. Thay đổi Thỏa thuận Cấp phép</h3>
+13.1 Google có thể thực hiện các thay đổi về Thỏa thuận Cấp phép khi họ phân phối các phiên bản mới của SDK. Khi những thay đổi này được thực hiện, Google sẽ lập một phiên bản Thỏa thuận Cấp phép mới có sẵn trên trang web nơi SDK được cung cấp.
+
+
+<h3>14. Các Điều khoản Pháp lý Chung</h3>
+14.1 Thỏa thuận Cấp phép này cấu thành toàn bộ thỏa thuận pháp lý giữa bạn và Google và chi phối việc bạn sử dụng SDK (không bao gồm bất kỳ dịch vụ nào mà Google có thể cung cấp cho bạn theo một thỏa thuận riêng bằng văn bản), và hoàn toàn thay thế bất kỳ thỏa thuận nào trước đây giữa bạn và Google liên quan tới SDK.
+
+14.2 Bạn đồng ý rằng nếu Google không thực hiện hay thi hành bất kỳ quyền hợp pháp hay biện pháp khắc phục về mặt pháp lý nào có trong Thỏa thuận Cấp phép này (hoặc Google được hưởng lợi theo bất kỳ luật áp dụng nào), điều này sẽ không được coi như sự miễn trừ hình thức đối với các quyền của Google và rằng các quyền hoặc biện pháp khắc phục đó sẽ vẫn dành cho Google.
+
+14.3 Nếu bất kỳ tòa án pháp luật nào, có thẩm quyền tài phán quyết định vấn đề này, phán rằng bất kỳ quy định nào của Thỏa thuận Cấp phép này không có hiệu lực, thì quy định đó sẽ bị xóa bỏ khỏi Thỏa thuận Cấp phép này mà không ảnh hưởng tới phần còn lại của Thỏa thuận Cấp phép này. Các quy định còn lại của Thỏa thuận Cấp phép này sẽ tiếp tục có giá trị và thi hành được.
+
+14.4 Bạn hiểu và đồng ý rằng mỗi thành viên trong nhóm các công ty mà trong đó Google là công ty mẹ sẽ là bên thụ hưởng thứ ba của Thỏa thuận Cấp phép này và rằng những công ty khác đó sẽ có quyền trực tiếp thi hành, và dựa vào, bất kỳ quy định nào của Thỏa thuận Cấp phép này mà trao lợi ích cho họ (hoặc trao quyền có lợi cho họ). Ngoài điều này ra, không người hay công ty nào khác sẽ là bên thụ hưởng thứ ba của Thỏa thuận Cấp phép này.
+
+14.5 HẠN CHẾ VỀ XUẤT KHẨU. SDK PHẢI TUÂN THEO PHÁP LUẬT VÀ QUY ĐỊNH VỀ XUẤT KHẨU CỦA HOA KỲ. BẠN PHẢI TUÂN THỦ TẤT CẢ PHÁP LUẬT VÀ QUY ĐỊNH VỀ XUẤT KHẨU TRONG NƯỚC VÀ QUỐC TẾ ÁP DỤNG CHO SDK. NHỮNG LUẬT NÀY BAO GỒM CÁC HẠN CHẾ VỀ ĐIỂM ĐẾN, NGƯỜI DÙNG CUỐI VÀ MỤC ĐÍCH SỬ DỤNG CUỐI.
+
+14.6 Các quyền được cấp trong Thỏa thuận Cấp phép này không được phép cho nhượng lại hay chuyển nhượng bởi bạn hoặc Google khi chưa có sự phê duyệt trước bằng văn bản của bên còn lại. Cả bạn hay Google đều sẽ không được cho phép giao phó các trách nhiệm hoặc nghĩa vụ của mình theo Thỏa thuận Cấp phép này khi chưa có sự phê duyệt trước bằng văn bản của bên còn lại.
+
+14.7 Thỏa thuận Cấp phép này và mối quan hệ giữa bạn với Google theo Thỏa thuận Cấp phép này sẽ được điều chỉnh bởi pháp luật của Tiểu bang California, bất kể mâu thuẫn về các quy định trong luật của Tiểu bang. Bạn và Google đồng ý trình lên theo thẩm quyền tài phán độc quyền của các tòa án tại hạt Santa Clara, California để giải quyết bất kỳ vấn đề pháp lý nào phát sinh từ Thỏa thuận Cấp phép này. Không kể điều này, bạn đồng ý rằng Google sẽ vẫn được phép xin các lệnh chế tài của tòa (hoặc một hình thức chế tài pháp lý khẩn cấp tương đương) ở bất kỳ lãnh thổ pháp lý nào.
+
+
+<em>13 tháng 11 năm 2012</em>
+</div>
+
+
+
+
+
+<div id="next-steps" style="display:none;position:absolute;width:inherit">
+ <p>Bạn chỉ còn vài bước nữa là được bắt đầu xây dựng ứng dụng cho Android!</p>
+ <p>Trong chốc lát, bạn sẽ được chuyển hướng đến
+ <a id="next-link" href="{@docRoot}sdk/installing/index.html">Cài đặt SDK Android</a>.</p>
+
+</div><!-- end next-steps -->
+
+
+
+<div id="sdk-terms-form">
+<p>
+<input id="agree" type="checkbox" name="agree" value="1" onclick="onAgreeChecked()" />
+<label id="agreeLabel" for="agree">Tôi đã đọc và đồng ý với các điều khoản và điều kiện trên</label>
+</p>
+<p><a href="" class="button disabled" id="downloadForRealz" onclick="return onDownloadForRealz(this);"></a></p>
+</div>
+
+
+</div><!-- end TOS -->
+
+
+
+
+
+
+<div id="landing">
+
+<div class="col-13">&nbsp;</div><!-- provides top margin for content -->
+
+<img src="{@docRoot}images/tools/studio-hero.png" srcset="{@docRoot}images/tools/studio-hero_2x.png 2x, {@docRoot}images/tools/studio-hero.png 1x" width="760" height="400" alt="" style="margin-bottom:80px" />
+
+<div style="color: #fff; width:226px; height:0; overflow:visible; position:absolute; top:40px; left:25px">
+
+<h1 class="studio-logo" style="margin:0 0 35px !important">Android Studio</h1>
+
+<p style="font-size: 16px; color:#bbb; position: absolute;left: 297px; top: 5px; display: block;
+width: 400px;text-align: center;">IDE Android chính thức</p>
+
+<ul style="font-size:12px">
+<li>IDE Android Studio</li>
+<li>Bộ công cụ SDK Android</li>
+<li>Nền tảng Android 5.0 (Lollipop)</li>
+<li>Ảnh hệ thống trình mô phỏng Android 5.0 cùng các API của Google</li>
+</ul>
+
+
+<a class="online landing-button green download-bundle-button" style="margin-top:30px;" href="#Other">Tải xuống Android Studio</a>
+
+<!-- this appears when viewing the offline docs -->
+<p class="offline">
+Để tải Android Studio hoặc bộ công cụ SDK độc lập, hãy truy cập <a href="http://developer.android.com/sdk/index.html">developer.android.com/sdk/</a>
+</p>
+
+<ul style="margin-top:50px;color:#444">
+ <li><a href="#Requirements">Yêu cầu Hệ thống</a></li>
+ <li><a href="#Other">Tùy chọn Tải xuống Khác</a></li>
+ <li><a href="{@docRoot}sdk/installing/migrate.html">Di chuyển tới Android Studio</a></li>
+ <li><a href="https://docs.google.com/a/google.com/forms/d/1mjsyfzv3HAnDY-_Kfj-3QJKdpuksyMFs9e73CRwmT6Q/viewform" target="_blank">Tham gia Khảo sát</a></li>
+</ul>
+
+</div>
+
+
+
+
+<h2 class="feature norule" >Trình chỉnh sửa mã thông minh</h2>
+
+<div class="col-9" style="margin:0 20px 0 0">
+ <img src="{@docRoot}images/tools/studio-hero-code.png" srcset="{@docRoot}images/tools/studio-hero-code_2x.png 2x, {@docRoot}images/tools/studio-hero-code.png 1x" width="520" />
+</div><!-- end col-9 (left column) -->
+
+<div class="col-4 feature-blurb">
+ <p>Nằm ở cốt lõi của Android Studio là một trình biên tập mã thông minh có khả năng hoàn thành
+ mã, dựng lại và phân tích mã nâng cao.</p>
+ <p>Trình chỉnh sửa mã mạnh mẽ này sẽ giúp bạn trở thành một nhà phát triển ứng dụng Android năng suất hơn.</p>
+</div>
+
+
+
+
+
+<h2 class="feature norule">Các ví dụ mã và tích hợp GitHub</h2>
+
+<div class="col-9" style="margin:0 20px 0 0">
+ <img src="{@docRoot}images/tools/studio-hero-import.png" srcset="{@docRoot}images/tools/studio-hero-import_2x.png 2x, {@docRoot}images/tools/studio-hero-import.png 1x" width="520" />
+</div><!-- end col-9 (left column) -->
+
+<div class="col-4 feature-blurb">
+ <p>Các trình hướng dẫn dự án mới sẽ giúp bắt đầu một dự án mới dễ hơn bao giờ hết.</p>
+
+ <p>Bắt đầu các dự án bằng cách sử dụng mã mẫu cho các kiểu mẫu như ngăn kéo điều hướng và các trình tạo trang dạng xem,
+ và thậm chí còn nhập được các ví dụ mã của Google từ GitHub.</p>
+</div>
+
+
+
+
+<h2 class="feature norule">Phát triển ứng dụng đa màn hình</h2>
+
+<div class="col-9" style="margin:0 20px 0 0">
+ <img src="{@docRoot}images/tools/studio-hero-screens.png" srcset="{@docRoot}images/tools/studio-hero-screens_2x.png 2x, {@docRoot}images/tools/studio-hero-screens.png 1x" width="520" />
+</div><!-- end col-9 (left column) -->
+
+<div class="col-4 feature-blurb">
+ <p>Xây dựng ứng dụng cho điện thoại, máy tính bảng Android, Android Wear,
+ Android TV, Android Auto và Google Glass.</p>
+ <p>Với Dạng xem Dự án Android mới và hỗ trợ mô-đun trong Android Studio, việc
+ quản lý các dự án và tài nguyên ứng dụng trở nên dễ dàng hơn.
+</div>
+
+
+
+
+<h2 class="feature norule">Các thiết bị ảo cho tất cả hình dạng và kích cỡ</h2>
+
+<div class="col-9" style="margin:0 20px 0 0">
+ <img src="{@docRoot}images/tools/studio-hero-avds.png" srcset="{@docRoot}images/tools/studio-hero-avds_2x.png 2x, {@docRoot}images/tools/studio-hero-avds.png 1x" width="520" />
+</div><!-- end col-9 (left column) -->
+
+<div class="col-4 feature-blurb">
+ <p>Android Studio được cấu hình sẵn cùng một ảnh trình mô phỏng được tối ưu hóa.</p>
+ <p>Trình quản lý Thiết bị Ảo được cập nhật và hợp lý hoá sẽ cung cấp
+ các cấu hình thiết bị định nghĩa sẵn cho các thiết bị Android thông thường.</p>
+</div>
+
+
+
+
+<h2 class="feature norule">
+Phát triển xây dựng Android bằng Gradle</h2>
+
+<div class="col-9" style="margin:0 20px 0 0">
+ <img src="{@docRoot}images/tools/studio-hero-gradle.png" srcset="{@docRoot}images/tools/studio-hero-gradle_2x.png 2x, {@docRoot}images/tools/studio-hero-gradle.png 1x" width="520" />
+</div><!-- end col-9 (left column) -->
+
+<div class="col-4 feature-blurb">
+ <p>Tạo nhiều tệp APK cho ứng dụng Android của bạn với các tính năng khác nhau bằng cách sử dụng cùng dự án.</p>
+ <p>Quản lý phụ thuộc của ứng dụng bằng Maven.</p>
+ <p>Xây dựng APK từ Android Studio hoặc dòng lệnh.</p>
+</div>
+
+
+
+
+<h2 class="feature norule">Tìm hiểu thêm về Android Studio</h2>
+<div style="background:#424242;padding:30px; color:#fff;margin:0 0 15px;">
+
+<a class="online landing-button green download-bundle-button" style="margin:0 0 40px 60px;float:right" href="">Tải xuống Android Studio</a>
+
+ <ul>
+ <li>Xây dựng Phiên bản Cộng đồng IntelliJ IDEA, IDE Java phổ biến của JetBrains.</li>
+ <li>Hệ thống xây dựng linh hoạt dựa trên Gradle.</li>
+ <li>Xây dựng các biến thể và khởi tạo nhiều APK.</li>
+ <li>Hỗ trợ mẫu mở rộng cho các Dịch vụ của Google và các loại thiết bị khác nhau.</li>
+ <li>Trình chỉnh sửa bố trí phong phú hỗ trợ chỉnh sửa chủ đề.</li>
+ <li>Bộ công cụ Lint để giải quyết các vấn đề về hiệu năng, khả năng sử dụng, tính tương thích với phiên bản và các vấn đề khác.</li>
+ <li>ProGuard và các khả năng ký ứng dụng.</li>
+ <li>Hỗ trợ tích hợp cho Nền tảng Đám mây của Google, giúp dễ dàng tích hợp Google Cloud
+ Nhắn tin và Công cụ Ứng dụng.</li>
+ </ul>
+
+<p style="margin:0">
+Để biết thêm chi tiết về các tính năng có sẵn trong Android Studio,
+hãy đọc hướng dẫn <a href="{@docRoot}tools/studio/index.html">Nội dung Cơ bản về Android Studio</a>.</p>
+</div>
+
+
+<p>Nếu bạn đang sử dụng Eclipse với ADT, hãy lưu ý rằng hiện Android Studio là IDE chính thức
+cho Android, vì thế bạn nên di chuyển sang Android Studio để nhận tất cả cập nhật
+IDE mới nhất. Để được trợ giúp về di chuyển các dự án,
+hãy xem phần <a href="{@docRoot}sdk/installing/migrate.html">Di chuyển sang Android
+Studio</a>.</p>
+
+
+
+
+
+
+
+<h2 id="Requirements">Yêu cầu Hệ thống</h2>
+
+<h3>Windows</h3>
+
+<ul>
+<li>Microsoft&reg; Windows&reg; 8/7/Vista/2003 (32 hoặc 64-bit)</li>
+<li>Tối thiểu 2 GB RAM, khuyến nghị 4 GB RAM</li>
+<li>Dung lượng trống đĩa cứng 400 MB</li>
+<li>Ít nhất 1 GB cho SDK Android, các ảnh hệ thống trình mô phỏng và bộ đệm ẩn</li>
+<li>Độ phân giải màn hình tối thiểu 1280 x 800</li>
+<li>Java Development Kit (JDK) 7 </li>
+<li>Tùy chọn dành cho trình mô phỏng tăng tốc: Bộ xử lý Intel® có hỗ trợ Intel® VT-x, Intel® EM64T
+(Intel® 64), và tính năng Execute Disable (XD) Bit</li>
+</ul>
+
+
+<h3>Mac OS X</h3>
+
+<ul>
+<li>Mac&reg; OS X&reg; 10.8.5 hoặc cao hơn, lên tới 10.9 (Mavericks)</li>
+<li>Tối thiểu 2 GB RAM, khuyến nghị 4 GB RAM</li>
+<li>Dung lượng trống đĩa cứng 400 MB</li>
+<li>Ít nhất 1 GB cho SDK Android, các ảnh hệ thống trình mô phỏng và bộ đệm ẩn</li>
+<li>Độ phân giải màn hình tối thiểu 1280 x 800</li>
+<li>Java Runtime Environment (JRE) 6</li>
+<li>Java Development Kit (JDK) 7</li>
+<li>Tùy chọn dành cho trình mô phỏng tăng tốc: Bộ xử lý Intel® có hỗ trợ Intel® VT-x, Intel® EM64T
+(Intel® 64), và tính năng Execute Disable (XD) Bit</li>
+</ul>
+
+<p>Trên Mac OS, hãy chạy Android Studio bằng Java Runtime Environment (JRE) 6 để dựng
+phông chữ tối ưu. Khi đó, bạn có thể cấu hình dự án của mình để sử dụng Java Development Kit (JDK) 6 hoặc JDK 7.</p>
+
+
+
+<h3>Linux</h3>
+
+<ul>
+<li>Máy tính bàn GNOME hoặc KDE</li>
+<li>GNU C Library (glibc) 2.15 hoặc mới hơn</li>
+<li>Tối thiểu 2 GB RAM, khuyến nghị 4 GB RAM</li>
+<li>Dung lượng trống đĩa cứng 400 MB</li>
+<li>Ít nhất 1 GB cho SDK Android, các ảnh hệ thống trình mô phỏng và bộ đệm ẩn</li>
+<li>Độ phân giải màn hình tối thiểu 1280 x 800</li>
+<li>Oracle&reg; Java Development Kit (JDK) 7 </li>
+</ul>
+<p>Được thử nghiệm trên Ubuntu&reg; 14.04, Trusty Tahr (có khả năng phân phối 64-bit khi chạy các ứng dụng
+32-bit).</p>
+
+
+
+
+<h2 id="Other" style="clear:left">Tùy chọn Tải xuống Khác</h2>
+
+<!-- alternative SDK options follows -->
diff --git a/docs/html-intl/intl/vi/sdk/installing/adding-packages.jd b/docs/html-intl/intl/vi/sdk/installing/adding-packages.jd
new file mode 100644
index 000000000000..728c92d760f0
--- /dev/null
+++ b/docs/html-intl/intl/vi/sdk/installing/adding-packages.jd
@@ -0,0 +1,227 @@
+page.title=Thêm Gói SDK
+
+page.tags=trình quản lý sdk
+helpoutsWidget=true
+
+@jd:body
+
+<style>
+ol.large {
+ margin-left:0;
+}
+ol.large > li {
+ list-style-position: inside;
+ list-style-type:none;
+ margin:30px 0 0 0;
+ padding:30px 20px;
+ background:#eee;
+}
+ol.large > li:nth-child(odd) {
+}
+ol.large > li:before {
+ display:inline;
+ left:-40px;
+ float:left;
+ width:20px;
+ font-size:20px;
+ line-height:20px;
+}
+ol.large > li > h2 {
+ font-size:20px;
+ line-height:20px;
+ padding:0 0 0 20px;
+ margin:0 0 20px 0;
+ display:inline-block;
+ font-weight:normal;
+}
+ol.large > li:nth-child(1):before {
+ content:"1. ";
+}
+ol.large > li:nth-child(2):before {
+ content:"2. ";
+}
+ol.large > li:nth-child(3):before {
+ content:"3. ";
+}
+ol.large > li:nth-child(4):before {
+ content:"4. ";
+}
+ol.large > li:nth-child(5):before {
+ content:"5. ";
+}
+ol.large > li:nth-child(6):before {
+ content:"6. ";
+}
+</style>
+
+
+<p>
+Theo mặc định, SDK Android không bao gồm mọi thứ bạn cần để bắt đầu phát triển.
+SDK chia những công cụ, nền tảng và các thành phần khác vào các gói mà bạn có thể
+tải xuống nếu cần bằng cách sử dụng
+<a href="{@docRoot}tools/help/sdk-manager.html">Trình quản lý SDK Android</a>.
+Vì vậy, trước khi có thể bắt đầu, có một vài gói bạn nên thêm vào SDK Android của mình.</p>
+
+<p>Để bắt đầu thêm gói, hãy khởi chạy Trình quản lý SDK Android bằng một trong những cách sau:</p>
+<ul>
+ <li>Trong Android Studio, nhấp vào <strong>Trình quản lý SDK</strong>
+<img src="{@docRoot}images/tools/sdk-manager-studio.png" style="vertical-align:bottom;margin:0;height:17px" /> ở thanh công cụ.</li>
+ <li>Nếu bạn không đang sử dụng Android Studio:
+ <ul>
+ <li>Windows: Bấm đúp tệp <code>SDK Manager.exe</code> ở gốc của thư mục SDK
+ Android.</li>
+ <li>Mac/Linux: Mở một terminal và điều hướng đến thư mục <code>tools/</code> ở vị trí
+ nơi cài đặt SDK Android, rồi chạy <code>android sdk</code>.</li>
+ </ul>
+ </li>
+</ul>
+
+<p>Khi bạn mở Trình quản lý SDK lần đầu, một vài gói sẽ được chọn
+theo mặc định. Để nguyên những gói được chọn này, nhưng hãy chắc chắn bạn có mọi thứ mình cần
+để bắt đầu bằng cách làm theo những bước sau:</p>
+
+
+<ol class="large">
+<li>
+ <h2 id="GetTools" class="norule">Tải công cụ SDK mới nhất</h2>
+
+<img src="/images/sdk_manager_packages.png" alt="" width="350" style="float:right;margin-left:20px" />
+
+ <p>Tối thiểu khi thiết đặt SDK Android,
+ bạn nên tải xuống những công cụ và nền tảng Android mới nhất:</p>
+ <ol>
+ <li>Mở thư mục Tools và chọn:
+ <ul>
+ <li><strong>Công cụ SDK Android</strong></li>
+ <li><strong>Công cụ Nền tảng SDK Android</strong></li>
+ <li><strong>Công cụ Xây dựng SDK Android</strong> (phiên bản mới nhất)</li>
+ </ul>
+ </li>
+ <li>Mở thư mục Android X.X đầu tiên (phiên bản mới nhất) và chọn:
+ <ul>
+ <li><strong>Nền tảng SDK</strong></li>
+ <li>Một ảnh hệ thống cho trình mô phỏng, chẳng hạn như <br>
+ <strong>Ảnh Hệ thống ARM EABI v7a</strong></li>
+ </ul>
+ </li>
+ </ol>
+</li>
+
+<li>
+ <h2 id="GetSupportLib" class="norule">Tải thư viện hỗ trợ cho các API bổ sung</h2>
+
+ <div class="sidebox">
+ <p>Phải có thư viện hỗ trợ đối với:</p>
+ <ul>
+ <li><a href="{@docRoot}wear/index.html">Android Wear</a></li>
+ <li><a href="{@docRoot}tv/index.html">Android TV</a></li>
+ <li><a href="{@docRoot}google/play-services/cast.html">Google Cast</a></li>
+ </ul>
+
+ <p>Nó cũng cung cấp những API phổ biến sau:</p>
+ <ul>
+ <li><a href="{@docRoot}reference/android/support/v4/widget/DrawerLayout.html">Ngăn kéo
+ điều hướng</a></li>
+ <li><a href="{@docRoot}reference/android/support/v4/view/ViewPager.html">Chế độ xem trượt nhanh</a></li>
+ <li><a href="{@docRoot}reference/android/support/v7/app/ActionBar.html">Thanh hành động
+ tương thích ngược</a></li>
+ </ul>
+ </div>
+
+ <p><a href="{@docRoot}tools/support-library/features.html">Thư viện Hỗ trợ Android</a>
+ cung cấp một tập API mở rộng tương thích với hầu hết các phiên bản của Android.</p>
+
+ <p>Mở thư mục <strong>Extras</strong> và chọn:</p>
+ <ul>
+ <li><strong>Kho Hỗ trợ Android</strong></li>
+ <li><strong>Thư viện Hỗ trợ Android</strong></li>
+ </ul>
+
+ <p>&nbsp;</p>
+ <p>&nbsp;</p>
+
+</li>
+
+
+<li>
+ <h2 id="GetGoogle" class="norule">Tải dịch vụ Google Play để có nhiều API hơn nữa</h2>
+
+ <div class="sidebox">
+
+ <p>Các API dịch vụ Google Play sẽ cung cấp nhiều tính năng và dịch vụ cho các ứng dụng Android
+ của bạn, chẳng hạn như:</p>
+ <ul>
+ <li><a href="{@docRoot}google/play-services/plus.html">Xác thực người dùng</a></li>
+ <li><a href="{@docRoot}google/play-services/maps.html">Google Maps</a></li>
+ <li><a href="{@docRoot}google/play-services/cast.html">Google Cast</a></li>
+ <li><a href="{@docRoot}google/play-services/games.html">Thành tích và bảng xếp hạng
+ trò chơi</a></li>
+ <li><a href="{@docRoot}google/play-services/index.html">Và nhiều hơn nữa</a></li>
+ </ul>
+ </div>
+
+ <p>Để phát triển bằng các API của Google, bạn cần gói dịch vụ Google Play.</p>
+ <p>Mở thư mục <strong>Extras</strong> và chọn:</p>
+ <ul>
+ <li><strong>Kho Google</strong></li>
+ <li><strong>Dịch vụ Google Play</strong></li>
+ </ul>
+
+ <p class="note"><strong>Lưu ý:</strong> Các API dịch vụ Google Play không có sẵn trên tất cả
+ thiết bị dựa trên nền tảng Android, nhưng có sẵn trên tất cả thiết bị có Google Play Store. Để sử dụng những
+ API này trong trình mô phỏng Android, bạn cũng phải cài đặt ảnh hệ thống <strong>Google API</strong>
+ từ thư mục Android X.X mới nhất trong Trình quản lý SDK.</p>
+</li>
+
+
+<li>
+ <h2 id="Install" class="norule">Cài đặt gói</h2>
+ <p>Sau khi bạn đã chọn tất cả gói mong muốn, hãy tiếp tục cài đặt:</p>
+ <ol>
+ <li>Bấm <strong>Cài đặt X gói</strong>.</li>
+ <li>Trong cửa sổ tiếp theo, bấm đúp vào tên của từng gói ở bên trái
+ để chấp nhận thỏa thuận cấp phép cho từng gói.</li>
+ <li>Bấm <strong>Cài đặt</strong>.</li>
+ </ol>
+ <p>Tiến trình tải xuống được hiện ở dưới cùng của cửa sổ Trình quản lý SDK.
+ <strong>Không được thoát Trình quản lý SDK</strong> nếu không nó sẽ hủy bỏ việc tải xuống.</p>
+</li>
+
+<li>
+ <h2 id="Build" class="norule">Xây dựng một thứ gì đó!</h2>
+
+<p>Với những gói trên có trong SDK Android của bạn, giờ bạn đã sẵn sàng để xây dựng ứng dụng
+cho Android. Khi có sẵn các công cụ mới và API khác, chỉ cần khởi chạy Trình quản lý SDK
+ để tải xuống các gói mới cho SDK của bạn.</p>
+
+<p>Sau đây là một vài tùy chọn về cách bạn nên tiến hành:</p>
+
+<div class="cols" style="padding:10px 0">
+<div class="col-4">
+<h3>Bắt đầu</h3>
+<p>Nếu bạn mới làm quen với phát triển Android, hãy tìm hiểu những nội dung cơ bản của ứng dụng Androi bằng cách làm theo
+hướng dẫn <strong><a href="{@docRoot}training/basics/firstapp/index.html">Xây dựng Ứng dụng Đầu tiên của bạn</a></strong>.</p>
+
+</div>
+<div class="col-4 box">
+<h3>Xây dựng cho thiết bị đeo được</h3>
+<p>Nếu bạn sẵn sàng bắt đầu xây dựng ứng dụng cho thiết bị đeo được Android, hãy xem hướng dẫn
+<strong><a href="{@docRoot}wear/preview/start.html">Xây dựng Ứng dụng cho Android Wear</a></strong>.</p>
+
+</div>
+<div class="col-4 box">
+<h3>Sử dụng API của Google</h3>
+<p>Để bắt đầu sử dụng các API của Google, chẳng hạn như các dịch vụ Bản đồ hoặc
+Chơi Trò chơi, hãy xem hướng dẫn
+<strong><a href="{@docRoot}google/play-services/setup.html">Thiết đặt Dịch vụ Google Play
+</a></strong>.</p>
+
+</div>
+</div><!-- end cols -->
+
+
+</li>
+
+</ol>
+
+