Android: Broadcast Receiver trong Android

Các khóa học qua video:
Python SQL Server PHP C# Lập trình C Java HTML5-CSS3-JavaScript
Học trên YouTube <76K/tháng. Đăng ký Hội viên
Viết nhanh hơn - Học tốt hơn
Giải phóng thời gian, khai phóng năng lực

Broadcast Receiver phản hồi các thông báo phát ra từ các ứng dụng khác hoặc từ chính hệ thống. Những thông báo này đôi khi được gọi là các event hoặc intent. Ví dụ, các ứng dụng cũng có thể khởi tạo các tín hiệu broadcast để thông báo cho ứng dụng khác biết rằng một số dữ liệu đã được về tới thiết vị và là có sẵn cho chúng để sử dụng, vì thế Broadcast Receiver thông dịch thông tin đó và khởi tạo hành động thích hợp.

Sau đây là hai bước quan trọng để làm Broadcast Receiver làm việc cho các Intent:

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

Có thể có một bước bổ sung nếu bạn đang triển khai các Custom Intent của bạn, thì khi đó bạn sẽ phải tạo và phát các Intent đó.

Tạo Broadcast Receiver trong Android

Một Broadcast Receiver được triển khai như là một lớp con của lớp BroadcastReceiver và ghi đè phương thức onReceive(), nơi mà mỗi thông báo được nhận như là một tham số của đố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 trong Android

Một ứng dụng nghe các Intent được phát ra cụ thể bằng cách đăng ký một Broadcast Receiver trong AndroidManifest.xml file. Giả sử chúng ta đang đăng ký MyReceiver cho system event (sự kiện được tạo từ hệ thống) đã được tạo là ACTION_BOOT_COMPLETED, mà được kích hoạt bởi hệ thống một khi hệ điều hành Android đã hoàn thành tiến trình boot.

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ờ, bất cứ khi nào thiết bị Android của bạn được boot, thì thông báo sẽ được nhận bởi MyReceiver và trình triển khai logic bên trong phương thức onReceive() sẽ được thực thi.

Có một số system event được định nghĩa là là các trường final static trong lớp Intent. Bảng dưới liệt kê một số system event quan trọng:

Event Miêu tả
android.intent.action.BATTERY_CHANGED Thông báo này chứa trạng thái nạp, mức độ, và thông tin khác về pin
android.intent.action.BATTERY_LOW Chỉ trạng thái low battery trên thiết bị
android.intent.action.BATTERY_OKAY Chỉ rằng pin bây giờ là tốt sau khi low battery
android.intent.action.BOOT_COMPLETED Đây là tín hiệu broadcast thông báo sau khi hệ thống đã kết thúc boot
android.intent.action.BUG_REPORT Chỉ activity để báo cáo một bug
android.intent.action.CALL Thông báo một lời gọi tới ai đó được xác định bởi dữ liệu
android.intent.action.CALL_BUTTON Người dùng nhấn nút call để tới Dialer (trình gọi điện) hoặc giao diện UI thích hợp khác để tạo một cuộc gọi
android.intent.action.DATE_CHANGED Date đã được thay đổi
android.intent.action.REBOOT Reboot thiết bị

Tín hiệu Custom Intent

Nếu bạn muốn chính ứng dụng của bạn nên tạo và gửi các Custom Intent, thì khi đó bạn sẽ phải tạo và gửi các Intent đó bằng việc sử dụng phương thức sendBroadcast() bên trong lớp Activity của bạn. Nếu bạn sử dụng phương thức sendStickyBroadcast(Intent) thì Intent là sticky, nghĩa là Intent bạn đang gửi vẫn ở đâu đó sau khi tín hiệu kết thúc.

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

Ở đây v1study.com.CUSTOM_INTENT cũng có thể được đăng ký theo cách tương tự như chúng ta đã đăng ký intent được tạo ra từ hệ thống (system intent).

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <receiver android:name="MyBroadcastReceiver">
        <intent-filter>
            <action android:name="v1study.com.CUSTOM_INTENT"></action>
        </intent-filter>
    </receiver>
</application>

Ví dụ

Ví dụ này sẽ giải thích cách tạo BroadcastReceiver để chặn Custom Intent. Khi bạn đã quen với Custom Intent, bạn có thể lập trình ứng dụng để chặn các system intent. Bạn theo các bước sau để sửa đổi ứng dụng Android đã tạo trong chương Ví dụ Hello World.

Bước Miêu tả
1 Bạn sẽ sử dụng Android Studio để tạo một ứng dụng Android và đặt tên nó là BroadcastReceiverV1Study dưới một package là v1study.com.broadcastreceiverv1study
2 Sửa đổi file MainActivity.java để thêm phương thức broadcastIntent()
3 Tạo một file MyReceiver.java dưới package v1study.com.broadcastreceiverv1study để định nghĩa một BroadcastReceiver
4 Một ứng dụng có thể xử lý một hoặc nhiều Custom Intent và System Intent mà không có bất cứ hạn chế nào. Mỗi Intent bạn muốn chặn phải được đăng ký trong file AndroidManifest.xml sử dụng thẻ <receiver.../>
5 Sửa đổi nội dung mặc định của file res/layout/activity_main.xml để bao gồm một button để thông báo Intent
6 Không cần sửa đổi string.xml file, Android Studio sẽ tự thực hiện
7 Chạy ứng dụng để chạy Android Emulator và kiểm tra kết quả các thay đổi đã thực hiện trong ứng dụng.

Sau đây là nội dung của file main activity đã được sửa đổi. File này có thể bao các phương thức nền tảng. Chúng ta đã thêm phương thức broadcastIntent() để phát một Custom Intent.

package v1study.com.broadcastreceiverv1study;

import androidx.appcompat.app.AppCompatActivity;

import android.content.Intent;
import android.os.Bundle;
import android.view.View;

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

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

Còn đây là nội dung của MyBroadcastReceiver.java:

package v1study.com.broadcastreceiverv1study;

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

public class MyBroadcastReceiver 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 đã sửa đổi của file AndroidManifest.xml. Ở đây, chúng ta đã thêm thẻ <receiver.../> để tích hợp service:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:dist="http://schemas.android.com/apk/distribution"
    package="v1study.com.broadcastreceiverv1study">

    <dist:module dist:instant="true" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver android:name=".MyBroadcastReceiver">
            <intent-filter>
                <action android:name="v1study.com.CUSTOM_INTENT"></action>
            </intent-filter>
        </receiver>
    </application>

</manifest>

Dưới đây là nội dung của file res/layout/activity_main.xml đã đưa vào một button để phát Custom Intent:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/broadcastreceiver"
        android:textColor="#8BC34A"
        android:textSize="30sp"
        android:textStyle="bold"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.127" />

    <ImageView
        android:id="@+id/logoV1Study"
        android:layout_width="170dp"
        android:layout_height="170dp"
        android:contentDescription="@string/logo_v1study"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHorizontal_bias="0.497"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.329"
        app:srcCompat="@mipmap/logo_v1_regular" />

    <Button
        android:id="@+id/broadcastIntent"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:background="#8BC34A"
        android:onClick="broadcastIntent"
        android:text="@string/broadcast_intent"
        android:textColor="#FFEB3B"
        android:textSize="30sp"
        android:textStyle="bold"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintHorizontal_bias="0.6"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.698" />

</androidx.constraintlayout.widget.ConstraintLayout>

Và nội dung của file res/values/strings.xml:

<resources>
    <string name="app_name">BroadcastReceiverV1Study</string>
    <string name="broadcastreceiver">BroadcastReceiverV1Study</string>
    <string name="logo_v1study">Logo V1Study</string>
    <string name="broadcast_intent">Broadcast Intent</string>
</resources>

Chạy ứng dụng ở trên. Giả sử bạn đã tạo AVD trong khi cài đặt. Để chạy ứng dụng từ Android Studio, mở activity file và nhấn biểu tượng Run từ thanh công cụ.

Broadcast Receiver trong Android

Bây giờ, để phát Custom Intent, bạn nhấn vào nút Broadcast Intent nó sẽ phát "v1study.com.CUSTOM_INTENT" mà sẽ bị chặn bởi BroadcastReceiver đã đăng ký là MyBroadcastReceiver và màn hình mô phỏng sẽ như sau:

Broadcast Receiver trong Android

Bạn có thể triển khai BroadcastReceiver khác để chặn các System intent như Bootup, date changed, low battery, …

» Tiếp: Content Provider trong Android
« Trước: Service trong Android
Các khóa học qua video:
Python SQL Server PHP C# Lập trình C Java HTML5-CSS3-JavaScript
Học trên YouTube <76K/tháng. Đăng ký Hội viên
Viết nhanh hơn - Học tốt hơn
Giải phóng thời gian, khai phóng năng lực
Copied !!!