Android từ đầu: Kết nối các Activity và các Application
Vietnamese (Tiếng Việt) translation by Dai Phong (you can also view the original English article)
Một ứng dụng Android bao gồm nhiều Activity đơn giản thường cung cấp một trải nghiệm người dùng tốt hơn so với một cái trong đó nhồi nhét tất cả các chức năng thành một Activity lớn và phức tạp. Quy tắt là cố gắng và giới hạn mỗi một Activity mà bạn tạo ra đối với chỉ một tác vụ không thể phân chia.
Tuy nhiên, để hoàn thành công việc với các Activity đơn giản, bạn phải tạo các kết nối giữa các Activity và cho phép chúng liên tục trao đổi dữ liệu với nhau. Trong hướng dẫn này, tôi sẽ chỉ cho bạn cách sử dụng Intent để tạo kết nối giữa các Activity và gửi dữ liệu từ một trong những Activity khác.
1. Intent là gì?
Trong thế giới thực, trước khi bạn bắt đầu thực hiện một hành động, bạn thường có ý định thực hiện nó. Tương tự trong thế giới của các ứng dụng Android. Để bắt đầu một Activity trong Android, bạn phải có một ý định cho nó.
Các Intent là các đối tượng của lớp Intent
. Chúng là một phần không thể tách rời của nền tảng Android mà thậm chí đơn giản nhất mà ứng dụng cần đến chúng. Ví dụ, hãy xem xét ứng dụng Hello World mà bạn đã tạo ra trước đó trong loạt bài này. Nó có thể chạy khi bạn chạm vào biểu tượng của nó bởi vì nó có thể đáp ứng một Intent được tạo ra bởi ứng dụng launcher trên thiết bị của bạn.
Cùng với thông tin chi tiết về Activity, một Intent có thể chứa dữ liệu bổ sung, được gọi là extra data, để gửi cho đối số hoặc trả về các kết quả từ một trong những Activity khác.
2. Kiểu của Intent?
Intent có thể là rõ ràng (explicit) hoặc ngầm (implicit). Một Intent được cho là rõ ràng khi bạn khởi tạo nó bằng cách sử dụng tên lớp của Activity mà bạn muốn khởi động. Trong trường hợp Intent ngầm, bạn chỉ xác định hành động mà bạn muốn thực hiện và để cho hệ điều hành Android xác định chính xác Activity sẽ được khởi động.
Thông thường, Intent rõ ràng được sử dụng để khởi động các Activity thuộc về ứng dụng của bạn trong khi Intent ngầm có nghĩa là cho các Activity thuộc về các ứng dụng khác được cài đặt trên thiết bị của người dùng.
3. Tạo một Intent rõ ràng
Để tạo một Intent rõ ràng, bạn có thể sử dụng phương thức setClass()
của một đối tượng Intent
và truyền tên lớp của một Activity vào nó, cùng với một tham chiếu đến Activity hiện tại của bạn như là ngữ cảnh (context). Ví dụ, nếu Activity hiện tại của bạn là MainActivity
và bạn muốn tạo ra một Inent để bắt đầu một Activity được gọi là OtherActivity
, bạn sẽ sử dụng các code sau đây:
1 |
Intent intent = new Intent(); |
2 |
intent.setClass(MainActivity.this, OtherActivity.class); |
Nếu bạn muốn tạo ra một Intent rõ ràng cho một Activity mà không thuộc về ứng dụng của bạn, bạn hãy dùng phương thức setComponent()
để thay thể. Một đối số mà bạn phải truyền vào là một đối tượng ComponentName
, được khởi tạo bằng cách sử dụng tên gói của ứng dụng cần thiết và tên lớp đầy đủ của Activity yêu cầu
Ví dụ, đây là cách bạn sẽ tạo ra một Intent cho một Activity được gọi là OtherActivity
thuộc về một ứng dụng có tên gói là com.example.otherapp:
1 |
Intent intent = new Intent(); |
2 |
intent.setComponent( |
3 |
new ComponentName("com.example.otherapp", |
4 |
"com.example.otherapp.OtherActivity"
|
5 |
)
|
6 |
);
|
4. Tạo một Intent ngầm
Để tạo ra một Intent ngầm, bạn phải sử dụng phương thức setAction()
của một đối tượng Intent
và truyền một đối tượng string cho nó. Đối tượng string chỉ định tên của hành động mà bạn có ý định thực hiện. Android SDK có một số hành động tiêu chuẩn. Đối với hầu hết chúng, bạn cũng phải sử dụng phương thức setData()
để xác định các dữ liệu mà hành động sẽ làm việc với nó. Dữ liệu luôn luôn phải ở trong hình thức của một đối tượng Uri
.
Một trong những hành động tiêu chuẩn được sử dụng rộng rãi nhất là ACTION_VIEW
, nó có thể được sử dụng để khởi động một loạt các ứng dụng, chẳng hạn như trình duyệt mặc định, trình gọi điện và ứng dụng danh bạ. Ví dụ, ở đây là cách bạn tạo ra một Intent ngầm để quay số 123456789:
1 |
Intent intent = new Intent(); |
2 |
intent.setAction(Intent.ACTION_VIEW); |
3 |
|
4 |
// Generate a valid URI for the telephone number
|
5 |
// using the Uri.parse method and pass it to setData
|
6 |
intent.setData(Uri.parse("tel:123456789")); |
Bằng cách đơn giản thay đổi đối tượng Uri
mà bạn truyền vào phương thức setData()
, bạn có thể thay đổi ứng dụng mà ACTION_VIEW sẽ mở ra. Ví dụ, nếu bạn muốn khởi động trình duyệt và mở trang web https://tutsplus.com/ trên nó, thì gọi setData()
sẽ phải như thế này:
1 |
intent.setData(Uri.parse("https://tutsplus.com")); |
5. Thêm dữ liệu bổ sung cho một Intent
Một số Intent phải chứa các dữ liệu bổ sung để chúng làm việc một cách chính xác. Dữ liệu bổ sung này được gọi là một Extra. Một Extra không có gì khác ngoài một cặp khóa-giá trị thuộc về một đối tượng Bundle
. Sử dụng một Bundle
cũng giống như sử dụng một HashMap
với hai giới hạn:
- các khoá phải luôn luôn là các đối tượng
String
- các giá trị phải luôn luôn là nguyên thủy hoặc các đối tượng
Parcelable
Các Extra có thể được sử dụng với Intent ẩn và rõ ràng. Để thêm một Extra vào một đối tượng Intent
, bạn có thể sử dụng phương thức putExtra()
. Ví dụ, ở đây là cách bạn có thể thêm một Extra với khoá message và giá trị Hello:
1 |
intent.putExtra("message", "Hello"); |
6. Sử dụng một Intent
Bây giờ thì bạn đã hiểu cách làm thế nào để tạo ra một Intent và thêm dữ liệu và Extra vào nó, bây giờ hãy sử dụng các đối tượng Intent
để khởi động các Activity. Cách đơn giản để khởi động một Activity bằng cách sử dụng một đối tượng Intent
là truyền nó như là đối số vào phương thức startActivity()
.
1 |
startActivity(intent); |
Phương thức startActivity()
thường được sử dụng chỉ khi bạn muốn chuyển từ một Activity sang một Activity khác. Nói cách khác, startActivity()
sẽ giúp bạn mang người dùng từ một màn hình ứng dụng của bạn sang một màn hình ứng dụng khác.
Nếu bạn muốn khởi động một Activity để thực hiện một tác vụ cụ thể và lấy kết quả trả về, bạn phải sử dụng phương thức startActivityForResult()
để thay thế. Phương thức này, bên cạnh đối tượng Intent
, cũng cần một con số nguyên mà bạn sử dụng để xác định kết quả của Activity. Số nguyên được gọi là một request code.
Ngoài ra, để có thể nhận được kết quả của một Activity được bắt đầu bằng cách sử dụng phương thức startActivityForResult()
, thì Activity của bạn phải override phương thức onActivityResult()
. Ví dụ như đoạn code sau đây sẽ cho bạn thấy cách làm thế nào để tạo ra một Intent ẩn để chụp một bức ảnh bằng cách sử dụng ứng dụng camera mặc định của thiết bị và nhận được một hình thu nhỏ của hình ảnh được chụp như là kết quả:
1 |
// An integer to identify the result of the
|
2 |
// camera app's activity
|
3 |
final static int CAMERA_RESULT_REQUEST_CODE = 1; |
4 |
|
5 |
private void takePhoto() { |
6 |
Intent intent = new Intent(); |
7 |
|
8 |
// Use ACTION_IMAGE_CAPTURE to refer to the
|
9 |
// default camera app's activity
|
10 |
intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE); |
11 |
|
12 |
// Launch the activity, and specify that
|
13 |
// you expect a result whose request
|
14 |
// code is equal to CAMERA_RESULT_REQUEST_CODE
|
15 |
startActivityForResult(intent, CAMERA_RESULT_REQUEST_CODE); |
16 |
}
|
17 |
|
18 |
@Override
|
19 |
protected void onActivityResult(int requestCode, int resultCode, Intent result) { |
20 |
|
21 |
// Check if requestCode matches the request
|
22 |
// code passed to the startActivityForResult method.
|
23 |
|
24 |
// Also check if the result is valid using the
|
25 |
// resultCode parameter
|
26 |
|
27 |
if(requestCode == CAMERA_RESULT_REQUEST_CODE && resultCode == RESULT_OK) { |
28 |
Bitmap thumbnail = |
29 |
(Bitmap)result.getExtras().get("data"); |
30 |
}
|
31 |
}
|
Lưu ý rằng kết quả của một Activity cũng là một đối tượng Intent
. Trong đoạn code ở trên, tôi trước tiên sử dụng phương thức getExtras()
để lấy Bundle
có chứa Extra nằm trong kết quả. Tiếp theo, tôi sử dụng phương thức get()
để lấy hình thu nhỏ như là một đối tượng Bitmap
.
7. Sử dụng Intent Filter
Trong các bước trước đó, bạn đã thấy cách làm thế nào để sử dụng các Intent ẩn để khởi động các Activity thuộc về các ứng dụng khác được cài đặt trên thiết bị của người dùng. Bây giờ bạn có thể tự hỏi nếu các ứng dụng khác có thể bắt đầu một Activity thuộc về ứng dụng của bạn bằng cách sử dụng cùng một cách thức có được không. Câu trả lời cho câu hỏi đó là "không, trừ khi bạn muốn." Mặc định, vì lý do bảo mật, một Activity không thể được bắt đầu bằng các Activity thuộc về các ứng dụng khác.
Để trưng một Activity cho các ứng dụng khác, bạn phải tạo một Intent Filter cho nó. Để làm như vậy, bạn phải thêm một thẻ intent-filter
cho nó trong tập tin AndroidManifest.xml của dự án.
Ví dụ, nếu bạn muốn một Activity được gọi là MyCustomActivity
đáp ứng một hành động tuỳ biến được đặt tên my.custom.action, thì các mục trong manifest phải giống như thế này:
1 |
<activity android:name=".MyCustomActivity"> |
2 |
<intent-filter>
|
3 |
<action android:name="my.custom.action"/> |
4 |
<category android:name="android.intent.category.DEFAULT" /> |
5 |
</intent-filter>
|
6 |
</activity>
|
Lưu ý rằng, cùng với các thẻ action
chỉ định tên của hành động, thì thẻ intent-filter
cũng phải chứa một thẻ category
mà thuộc tính name
được thiết lập thành android.intent.category.DEFAULT. Nếu không có thẻ category
, thì Activity của bạn sẽ không thể đáp ứng các Intent ẩn.
Với Intent Filter mà chúng ta vừa mới tạo ra, thì bất kỳ ứng dụng nào cũng có thể khởi chạy MyCustomActivity
bằng cách sử dụng các code sau đây:
1 |
Intent intent = new Intent(); |
2 |
|
3 |
// The string passed to the setAction method
|
4 |
// must match the action name mentioned in the
|
5 |
// intent filter
|
6 |
intent.setAction("my.custom.action"); |
7 |
|
8 |
startActivity(intent); |
Nếu bạn không muốn sử dụng các Intent Filter, mà vẫn muốn trưng ra một Activity cho các ứng dụng khác, thì bạn có thể thêm một thuộc tính exported
vào định nghĩa của Activity trong manifest, thiết lập giá trị của nó thành true
.
1 |
<activity android:name=".MyCustomActivity" android:exported="true"/> |
Trong trường hợp này, các ứng dụng khác không có lựa chọn nào ngoài sử dụng Intent rõ ràng để bắt đầu Activity.
Tổng kết
Bây giờ bạn đã biết cách làm thế nào để kết nối bất kỳ hai Activity hiện tại trên thiết bị của người dùng bằng cách sử dụng Intent ẩn và rõ ràng. Với kiến thức này, bạn có thể bắt đầu tạo ra các ứng dụng phức tạp, có nhiều màn hình. Bạn cũng có thể dễ dàng tái sử dụng các chức năng đã có trong các ứng dụng khác được cài đặt trên thiết bị của người dùng.
Để tìm hiểu thêm về các Intent, bạn có thể tham khảo tài liệu chính thức.