Android – Tiếp nhận tin nhắn (Broadcast Receivers)



  Broadcast Receiver chỉ đơn giản phản hồi lại những tin nhắn từ các ứng dụng khác hoặc từ chính nó. Ví dụ, một ứng dụng có thể phát ra tín hiệu báo cho các ứng dụng khác là nó đã tải xong một phần dữ liệu nào đó về thiết bị, rằng các ứng dụng khác có thể sử dụng dữ liệu đó. Broadcast Receiver này sẽ khởi tạo việc liên lạc cũng như thực hiện việc liên lạc bằng các thao tác cần thiết.

Có 2 bước quan trọng để làm cho một BroadcastReceiver làm việc cho một Broadcasted Intent hệ thống:

  • Tạo Broadcast Receiver.
  • Đăng ký (register) Broadcast Receiver

Trong trường hợp bạn viết lại các intent của riêng bạn, bạn phải làm thêm một bước khác nữa là viết lại và phát tín hiệu những intent này.

Trước khi đọc tiếp về Broadcast Receiver, hãy dừng một chút để tìm hiểu về Intent. Intent là một miêu tả về một hoạt động cần được thực hiện. Intent cho phép truyền thông điệp giữa các thành phần của cùng một ứng dụng và giữa các ứng dụng với nhau.

Tạo Broadcast Receiver

Một Broadcast Receiver được viết lại như là một lớp con của lớp BroadcastReceiver và viêt lại phương thức onReceive(), trong đó mỗi tín hiệu được nhận như là một tham số đối tượng Intent.

public class MyReceiver extends BroadcastReceiver {
   @Override
   public void onReceive(Context context, Intent intent) {
      Toast.makeText(context, "Intent Detected.", Toast.LENGTH_LONG).show();
   }
}

Đăng ký Broadcast Receiver

Một ứng dụng lắng nghe các Broadcast Intent bằng cách đăng ký một Broadcast Receiver trong tập tin AndroidManifest.xml . Chúng ta sẽ khai báo Broadcast Receiver vừa tạo MyReceiver cho hệ thống tạo sự kiện (Event) ACTION_BOOT_COMPLETED, Event này được kích hoạt bởi hệ thống khi Android kết thúc quá trình khởi động (boot process).

broadcast

Broadcast-Receiver

<application
   android:icon="@drawable/ic_launcher"
   android:label="@string/app_name"
   android:theme="@style/AppTheme" >
   <receiver android:name="MyReceiver">
   
      <intent-filter>
         <action android:name="android.intent.action.BOOT_COMPLETED">
         </action>
      </intent-filter>
   
   </receiver>
</application>

Bây giờ, khi thiết bị Android đã khởi động xong, nó sẽ được tiếp nhận bởi BroadcastReceiver MyReceiver và các lệnh được viết trong phương thức onReceive() sẽ được thực hiện.

Có nhiều Event được kích hoạt bởi hệ thống, mỗi Event được định nghĩa như là một Static Field trong lớp Intent. Trong bảng sau đây mô tả các Event hệ thống quan trọng:

Event Constant Mô tả
android.intent.action.BATTERY_CHANGED Broadcast chứa trạng thái sạc, mức độ và những thông tin khác liên quan tới pin.
android.intent.action.BATTERY_LOW Thông báo tình trạng pin yếu.
android.intent.action.BATTERY_OKAY Thông báo tình trạng pin đủ sau khi pin bị yếu.
android.intent.action.BOOT_COMPLETED Broadcast này chỉ phát ra một lần, thông báo hệ thống đã khởi động xong.
android.intent.action.BUG_REPORT Hiện ra một Activity để báo lỗi.
android.intent.action.CALL Thực hiện cuộc gọi tới một người nào đó được chỉ định trong dữ liệu.
android.intent.action.CALL_BUTTON Người dùng bấm nút gọi (call button) hoặc thực hiện các thao tác khác trên màn hình để gọi điện thoại.
android.intent.action.DATE_CHANGED Thông báo ngày (date) đã thay đổi.
android.intent.action.REBOOT Thiết bị được khởi động lại (reboot).

Broadcasting Custom Intents

Ở trên là các Event hệ thống, còn trong trường hợp bạn muốn ứng dụng của bạn tự tạo và gửi Intent theo ý muốn (Custom Intent), bạn phải tạo và gửi những Intent này bằng phương thức sendBroadcast() bên trong lớp Activity của bạn. Nếu bạn dùng phương thức sendStickyBroadcast(Intent), Intent là một sticky Intent, có nghĩa là Intent bạn đang gửi vẫn tồn tại sau khi Broadcast hoàn tất.

public void broadcastIntent(View view)
{
   Intent intent = new Intent();
   intent.setAction("com.tutorialspoint.CUSTOM_INTENT");
   sendBroadcast(intent);
}

Intent com.tutorialspoint.CUSTOM_INTENT cũng được đăng ký tương tự như Intent hệ thống:

<application
   android:icon="@drawable/ic_launcher"
   android:label="@string/app_name"
   android:theme="@style/AppTheme" >
   <receiver android:name="MyReceiver">
   
      <intent-filter>
         <action android:name="com.tutorialspoint.CUSTOM_INTENT">
         </action>
      </intent-filter>
   
   </receiver>
</application>

Ví dụ

Trong ví dụ sau đây, chúng ta sẽ cùng tạo BroadcastReceiver để nhận Custom Intent. Các bước để thực hành ví dụ được mô tả trong bảng sau:

Bước Mô tả
1 Tạo một ứng dụng Android với tên Hello World và đặt tên package là com.example.My Application.
2 Chỉnh sửa code trong tập tin MainActivity.java bằng cách thêm phương thức broadcastIntent() .
3 Tạo một tập tin java mới, đặt tên là MyReceiver.java trong package com.example.My Application, trong tập tin này, ta định nghĩa một BroadcastReceiver.
4 Một ứng dụng có thể quản lý một hoặc nhiều Intent hệ thống hoặc/và Custom Intent. Mỗi Intent phải được khai báo trong AndroidManifest.xml file dùng thẻ <receiver…/>
5 Thay đổi nội dung tập tin res/layout/activity_main.xml để thêm một nút bấm để gửi Intent.
6 Bạn không cần thay đổi tập tin string.xml mà IDE sẽ làm việc này giúp bạn.
7 Chạy ứng dụng trên Android emulator và kiểm tra kết quả.

Sau đây là nội dung tập tin src/com.example.My Application/MainActivity.java, trong đó đã thêm phương thức broadcastIntent() để gửi một Custom Intent.

package com.example.My Application;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.content.Intent;
import android.view.View;

public class MainActivity extends Activity {

   @Override
   public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      }
   
   @Override
   public boolean onCreateOptionsMenu(Menu menu) {
      getMenuInflater().inflate(R.menu.activity_main, menu);
      return true;
      }
   
   // broadcast a custom intent. 
   public void broadcastIntent(View view){
      Intent intent = new Intent();
      intent.setAction("com.tutorialspoint.CUSTOM_INTENT");
      sendBroadcast(intent);
   }
}

Đây là nội dung tập tin src/com.example.My Application/MyReceiver.java:

package com.example.My Application;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

public class MyReceiver extends BroadcastReceiver {
   @Override
   public void onReceive(Context context, Intent intent) {
      Toast.makeText(context, "Intent Detected.", Toast.LENGTH_LONG).show();
   }
}

Sau đây là nội dung tập tin AndroidManifest.xml, ở đây Custom Intent được khai báo:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.example.My Application"
   android:versionCode="1"
   android:versionName="1.0" >
   
   <uses-sdk
      android:minSdkVersion="8"
      android:targetSdkVersion="22" />
   
   <application
       android:icon="@drawable/ic_launcher"
       android:label="@string/app_name"
       android:theme="@style/AppTheme" >
       
       <activity
          android:name=".MainActivity"
          android:label="@string/title_activity_main" >
       
          <intent-filter>
             <action android:name="android.intent.action.MAIN" />
             <category android:name="android.intent.category.LAUNCHER"/>
          </intent-filter>
          
       </activity>
       
       <receiver android:name="MyReceiver">
       
       <intent-filter>
          <action android:name="com.tutorialspoint.CUSTOM_INTENT">
          </action>
       </intent-filter>
       
       </receiver>
       
   </application>
</manifest>

Sau đây là nội dung tập tin res/layout/activity_main.xml, trong đó đã thêm nút bấm để gửi custom intent ta vừa khai báo:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
   xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
   android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
   android:paddingRight="@dimen/activity_horizontal_margin"
   android:paddingTop="@dimen/activity_vertical_margin"
   android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
   
   <TextView
      android:id="@+id/textView1"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Example of Broadcast"
      android:layout_alignParentTop="true"
      android:layout_centerHorizontal="true"
      android:textSize="30dp" />
      
   <TextView
      android:id="@+id/textView2"
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:text="Tutorials point "
      android:textColor="#ff87ff09"
      android:textSize="30dp"
      android:layout_above="@+id/imageButton"
      android:layout_centerHorizontal="true"
      android:layout_marginBottom="40dp" />
      
   <ImageButton
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:id="@+id/imageButton"
      android:src="@drawable/abc"
      android:layout_centerVertical="true"
      android:layout_centerHorizontal="true" />
      
   <Button
      android:layout_width="wrap_content"
      android:layout_height="wrap_content"
      android:id="@+id/button2"
      android:text="Broadcast Intent"
      android:onClick="broadcastIntent"
      android:layout_below="@+id/imageButton"
      android:layout_centerHorizontal="true" />

</RelativeLayout>

Còn đây là nội dung tập tin res/values/strings.xml để xác định 2 Constants mới −

<resources>    
    <string name="menu_settings">Settings</string>
    <string name="title_activity_main">My Application</string>
</resources>

Hãy thử chạy ứng dụng, bạn sẽ thấy trên màn hình Emulator chạy ứng dụng hiện lên như trong hình bên dưới:

broadcast1.jpg

Bây giờ hãy gửi Custom Intent bằng cách bấm nút Broadcast Intent, Custom Intent “com.tutorialspoint.CUSTOM_INTENT” sẽ được gửi đi và BroadcastReceiver MyReceiver sẽ in ra dòng chữ “Intent Detected” lên màn hình như sau:

broadcast2

Bạn có thể tự thực hành tạo và sử dụng Broadcast Receiver để nhận các Intents hệ thống, được gửi khi hệ thống kết thúc khởi động, thay đổi ngày, trạng thái pin thay đổi…

1340 Total Views 2 Views Today