Khái niệm Intents
Ứng dụng Android thường bao gồm nhiều Activity, mỗi Activity hoạt động độc lập với nhau và thực hiện những công việc khác nhau. Intent giống như người đưa thư, giúp Activity này có thể triệu gọi cũng như truyền dữ liệu cần thiết tới một Activiy khác. Điều này cũng giống như việc di chuyển qua lại giữa các Form trong lập trình Windows Form.
Hình 2.5. Dùng Intent để truyền dữ liệu giữa 2 Activity
v Sử dụng Intent để triệu gọi Activity
• Khai báo Activity tường minh: cần cung cấp chính xác thông tin của activity cần gọi (nếu 2 activity muốn gọi nhau thuộc cùng 1 ứng dụng thì chỉ cần cung cấp tên class, khác ứng dụng thì cần cung cấp thêm package và tên class).
Ví dụ: đoạn code dưới đây sẽ khởi động Activity tên là TargetActivity
Intent i = new Intent(getApplicationContext(), TargetActivity.class); startActivity(i);
• Khai báo Activity không tường minh: cần cung cấp thao tác cần làm gì, với loại dữ liệu nào, thao tác thuộc nhóm nào,… hệ thống sẽ tìm activity tương ứng để khởi động.
Ví dụ: đoạn code dưới đây sẽ khởi động Activity xem ảnh
Intent i = new Intent(Intent.ACTION_VIEW);
i.setData(MediaStore.Images.Media.EXTERNAL_CONTENT_URI); startActivity(i);
Với cách khởi động Activity không tường minh thì khi khai báo Activity trong AndroidManifest.xml cần khai báo Intent-filter bên trong Activity. Intent-filter sẽ giúp một Activity đăng ký với hệ thống Activity đó có làm được thao tác gì, trong nhóm nào, với loại dữ liệu nào. Như vậy với việc tạo ra đối tượng Intent trong code và khai báo Intent-filter cho Activity trong AndroidManifest.xml thì Activity sẽ được hệ thống khởi động.
v Sử dụng Intent để truyền dữ liệu giữa các Activity
• Khi khởi động một Activity, ta có thể gửi kèm dữ liệu trong đối tượng Intent như:
i.putExtra(“value1”, new String(“Hello”)); // i là 1 đối tượng của lớp Intent i.putExtra(“value2”, new Long(100));
• Bên phía Activity được triệu gọi, ta có thể lấy dữ liệu được gửi tới như sau:
getIntent().getExtras().getString(“value1”); getIntent().getExtras().getLong(“value2”);
• Có thể khởi động một Activity với một yêu cầu nào đó và Activity được triệu gọi khi làm xong công việc sẽ trả lại kết quả cho Activity trước
Minh họa:
• Từ IDE tạo Android project có tên PassingData
• Chỉnh sửa file main.xml trong thư mục res/layout, chú ý thêm các dòng in đậm sau:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <Button android:id="@+id/btn_SecondActivity" android:layout_width="fill_parent" android:layout_height="wrap_content"
android:text="Click to go to Second Activity"
android:onClick="onClick"/>
• Tạo file secondactivity.xml trong thư mục res/layout như sau: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:orientation="vertical" > <TextView android:layout_width="fill_parent" android:layout_height="wrap_content"
android:text="Welcome to Second Activity" /> <Button
android:id="@+id/btn_MainActivity" android:layout_width="fill_parent" android:layout_height="wrap_content"
android:text="Click to return to main activity"
android:onClick="onClick"/>
</LinearLayout>
• Tạo class SecondActivity. Viết code cho SecondActivity.java như sau:
package net.learn2develop.PassingData; import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.view.View; import android.widget.Toast;
public class SecondActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.secondactivity);
//---get the data passed in using getStringExtra()---
Toast.makeText(this,getIntent().getStringExtra("str1"), Toast.LENGTH_SHORT).show();
//---get the data passed in using getIntExtra()---
Toast.makeText(this,Integer.toString( getIntent().getIntExtra("age1", 0)), Toast.LENGTH_SHORT).show();
//---get the Bundle object passed in---
Bundle bundle = getIntent().getExtras();
//---get the data using the getString()---
Toast.makeText(this, bundle.getString("str2"), Toast.LENGTH_SHORT).show();
//---get the data using the getInt() method---
Toast.makeText(this,Integer.toString(bundle.getInt("age2")), Toast.LENGTH_SHORT).show();
}
public void onClick(View view) {
//---use an Intent object to return data---
Intent i = new Intent();
//---use the putExtra() method to return some // value---
i.setData(Uri.parse(
"Something passed back to main activity"));
//---set the result with OK and the Intent object---
setResult(RESULT_OK, i);
//---destroy the current activity---
finish(); }
}
• Thêm mã in đậm sau vào AndroidManifest.xml <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="net.learn2develop.PassingData" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="14" /> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <activity android:label="@string/app_name" android:name=".PassingDataActivity" > <intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" /> </intent-filter>
</activity>
<activity
android:label="Second Activity"
android:name=".SecondActivity" > <intent-filter >
<action android:name="net.learn2develop.PassingDataSecondActivity" />
<category android:name="android.intent.category.DEFAULT" /> </intent-filter>
</activity>
</application> </manifest>
• Viết code cho file PassingDataActivity.java, chú ý thêm các dòng in đậm sau:
package net.learn2develop.PassingData; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Toast;
public class PassingDataActivity extends Activity {
/** Called when the activity is first created. */ @Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); setContentView(R.layout.main); }
public void onClick(View view) { Intent i = new
//---use putExtra() to add new name/value pairs---
i.putExtra("str1", "This is a string");
i.putExtra("age1", 25);
//---use a Bundle object to add new name/values // pairs---
Bundle extras = new Bundle();
extras.putString("str2", "This is another string");
extras.putInt("age2", 35);
//---attach the Bundle object to the Intent object---
i.putExtras(extras);
//---start the activity to get a result back---
startActivityForResult(i, 1); }
public void onActivityResult(int requestCode,
int resultCode, Intent data) {
//---check if the request code is 1--- if (requestCode == 1) {
//---if the result is OK--- if (resultCode == RESULT_OK) {
//---get the result using getIntExtra()---
Toast.makeText(this, Integer.toString( data.getIntExtra("age3", 0)),
Toast.LENGTH_SHORT).show();
//---get the result using getData()---
Toast.makeText(this, data.getData().toString(), Toast.LENGTH_SHORT).show(); } } } } •
F11 để debug ứng dụng trên Android emulator. Nhấn button trên mỗi Activity và quan sát kết quả hiển thị.
Giải thích cách thức hoạt động của Intent trong ví dụ minh họa trên:
• Hàm putExtra() dùng để gửi kèm dữ liệu (name/value) trong đối tượng Intent:
//---use putExtra() to add new name/value pairs---
i.putExtra("str1", "This is a string");
i.putExtra("age1", 25);
Giá trị của dữ liệu (value) truyền vào có thể là kiểu nguyên thủy như: string,
integer,… hoặc kiểu Bundle.
Bundle giống như 1 từ điển lưu một tập dữ liệu với mỗi dữ liệu là cặp name/value:
//---use a Bundle object to add new name/values pairs---
Bundle extras = new Bundle();
extras.putString("str2", "This is another string");
extras.putInt("age2", 35);
//---attach the Bundle object to the Intent object---
• Activity được triệu gọi muốn nhận được thông tin dữ liệu do Activity thứ nhất gửi đến thì cần gọi lấy lại đối tượng Intent thông qua phương thức getIntent(). Sau đó gọi hàm getStringExtra(), getIntExtra(), getExtras() để lấy về giá trị do hàm putExtra() gửi đi tương ứng với các kiểu dữ liệu string, integer, Bundle từ Activity thứ nhất:
//---get the data passed in using getStringExtra()---
Toast.makeText(this,getIntent().getStringExtra("str1"),
Toast.LENGTH_SHORT).show();
//---get the data passed in using getIntExtra()---
Toast.makeText(this,Integer.toString(
getIntent().getIntExtra("age1", 0)), Toast.LENGTH_SHORT).show();
//---get the Bundle object passed in---
Bundle bundle = getIntent().getExtras();
//---get the data using the getString()---
Toast.makeText(this, bundle.getString("str2"),
Toast.LENGTH_SHORT).show();
//---get the data using the getInt() method---
Toast.makeText(this,Integer.toString(bundle.getInt("age2")),
Toast.LENGTH_SHORT).show();
• Cách khác để truyền dữ liệu giữa 2 Activity là sử dụng phương thức setData() :
//---use the setData() method to return some value---
i.setData(Uri.parse( "Something passed back to main activity"));
Thường sử dụng phương thức setData() được sử dụng để truyền dữ liệu cho các ứng dụng khác cài đặt sẵn trên thiết bị (build-in application), như truyền URL từ Activity tới ứng dụng web browser để xem nội dung web. Khi đó Activity được triệu gọi muốn nhận được dữ liệu do Intent gửi đến thông qua phương thức setData() thì cần sử dụng phương thức getData():
//---get the result using getData()---
Toast.makeText(this, data.getData().toString(),
Toast.LENGTH_SHORT).show();