文章目錄
- 零、學習目標
- 一、廣播接收者概述
- (一)廣播分類
- 1、標準廣播
- 2、有序廣播
- (二)廣播接收者作用
- (三)廣播接收者繼承關系圖
- (四)使用廣播接收者
- 1、創建廣播接收者
- 2、注冊廣播接收者
- 3、通過意圖發送廣播
- 二、案例演示 - 發送與接收廣播
- (一)運行效果
- (二)涉及知識點
- (三)實作步驟
- 1、創建安卓應用【SendReceiveBroadcast】
- 2、將背景圖片拷貝到drawable目錄
- 3、主布局資源檔案activity_main.xml
- 4、字串資源檔案strings.xml
- 5、創建自定義廣播接收者
- 6、在專案清單檔案里注冊廣播接收者
- 7、主界面類 - MainActivity
- 8、啟動應用,查看效果
- 9、采用動態方式注冊廣播接收者
- (1)修改專案清單檔案對廣播接收者的注冊
- (2)在主界面類里動態注冊廣播接收者
- (3)啟動應用,查看效果
- 三、案例演示 - 顯示播放進度
- (一)運行效果
- (二)涉及知識點
- (三)實作步驟
- 1、創建安卓應用【DisplayProgress】
- 2、將背景圖片拷貝到drwawable目錄
- 3、主布局資源檔案activity_main.xml
- 4、字串資源檔案strings.xml
- 5、創建應用程式常量介面 - AppConstants
- 6、創建進度服務類 - ProgressService
- 7、在專案清單檔案里注冊進度服務類
- 8、主界面類 - MainActivity
- 9、啟動應用,查看效果
零、學習目標
- 知道廣播接收者的作用
- 掌握如何創建并注冊自定義廣播接收者
- 掌握如何利用廣播接收者實作組件之間的通信
一、廣播接收者概述
(一)廣播分類
1、標準廣播
標準廣播( Normal Broadcasts) 是一種完全異步執行的廣播,在廣播發出之后,所有的廣播接收者幾乎都會在同一時刻接收到這條廣播訊息,因此它們之間沒有任何先后順序可言,這種廣播的效率會比較高,但同時也意味著它是無法被截斷的,標準廣播也叫無序廣播,無序廣播不能設定優先級,沒有abortBroadcast()方法,

2、有序廣播
有序廣播( Ordered Broadcasts) 則是一種同步執行的廣播,在廣播發出之后,同一時刻只會有一個廣播接收者能夠收到這條廣播訊息,當這個廣播接收者中的邏輯執行完畢后,廣播才會繼續傳遞,所以此時的廣播接收者是有先后順序的,優先級高的廣播接收者就可以先 收到廣播訊息,并且前面的廣播接收者還可以截斷正在傳遞的廣播,這樣后面的廣播接收者就無法收到廣播訊息了,有序廣播可以設定優先級, 有 abortBroadcast() 方法,

(二)廣播接收者作用
- 廣播接收者可以實作組件之間的通信,安卓系統會發生一些事件的改變,比如,電量變低,收發短信,撥打電話,螢屏解鎖系統會發送廣播,只要應用程式接收到這條廣播,就知道系統發生了什么事件,從而執行相應的代碼,使用廣播接受者,就可以接收廣播,
(三)廣播接收者繼承關系圖

(四)使用廣播接收者
1、創建廣播接收者
- 新建一個類,讓它繼承自BroadcastReceiver,并重寫父類的 onReceive()方法就行了,這樣當有廣播到來時,onReceive()方法就會得到執行,具體的邏輯就可以在這個方法中處理,
2、注冊廣播接收者
– 動態注冊廣播接收者(在Java代碼里)
– 靜態注冊廣播接收者(在專案清單檔案里)
3、通過意圖發送廣播
– 利用sendBroadcast(Intent inten)發送廣播
二、案例演示 - 發送與接收廣播
(一)運行效果


(二)涉及知識點
- 線性布局(LinearLayout)
- 編輯框(EditText)
- 按鈕(Button)
- 廣播接收者(BroadcastReceiver)
(三)實作步驟
1、創建安卓應用【SendReceiveBroadcast】


2、將背景圖片拷貝到drawable目錄

3、主布局資源檔案activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:background="@drawable/background"
android:gravity="center"
android:orientation="vertical"
android:padding="20dp"
tools:context=".MainActivity">
<EditText
android:id="@+id/edtMessage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="@string/input_message"
android:singleLine="true"
android:textSize="20sp" />
<Button
android:id="@+id/btnSendBroadcast"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="doSendBroadcast"
android:text="@string/send_broadcast"
android:textSize="20sp" />
</LinearLayout>
4、字串資源檔案strings.xml

<resources>
<string name="app_name">發送與接收廣播</string>
<string name="input_message">請輸入要廣播的訊息</string>
<string name="send_broadcast">發送廣播的訊息</string>
</resources>
5、創建自定義廣播接收者
- 繼承BroadcastReceiver類,創建自定義廣播接收者類CustomReceiver

package net.hw.send_receive_broadcast;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
/**
* 功能:自定義廣播接收者
* 作者:華衛
* 日期:2020年12月30日
*/
public class CustomReceiver extends BroadcastReceiver {
private final String TAG = "send_receive_broadcast"; // 標記
private final String INTENT_ACTION_SEND_MESSAGE = "net.hw.intent.action.SEND_MESSAGE"; // 廣播頻道
@Override
public void onReceive(Context context, Intent intent) {
// 按照頻道獲取廣播資訊
if (intent.getAction().equals(INTENT_ACTION_SEND_MESSAGE)) {
// 獲取廣播資訊
String message = intent.getStringExtra("message");
// 輸出廣播資訊
Log.d(TAG, message);
}
}
}
6、在專案清單檔案里注冊廣播接收者
- 采用靜態方式注冊自定義廣播接收者

7、主界面類 - MainActivity

- 定義常量與變數

- 通過資源識別符號獲取控制元件實體

- 撰寫代碼發送廣播的資訊

- 查看主界面類完整源代碼
package net.hw.send_receive_broadcast;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
private final String TAG = "send_receive_broadcast"; // 標記
private final String INTENT_ACTION_SEND_MESSAGE = "net.hw.intent.action.SEND_MESSAGE"; // 廣播頻道
private EditText edtMessage; // 訊息編輯框
private int broadcastCount; // 發送廣播次數
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 利用布局資源檔案設定用戶界面
setContentView(R.layout.activity_main);
// 通過資源識別符號獲取控制元件實體
edtMessage = findViewById(R.id.edtMessage);
}
/**
* 發送廣播
*
* @param view
*/
public void doSendBroadcast(View view) {
// 統計發送廣播次數
broadcastCount++;
// 獲取用戶輸入要廣播的資訊
String message = edtMessage.getText().toString();
// 創建意圖
Intent intent = new Intent();
// 設定意圖動作(廣播頻道)
intent.setAction(INTENT_ACTION_SEND_MESSAGE);
// 設定意圖攜帶的附加內容
intent.putExtra("message", "第" + broadcastCount + "次廣播資訊:" + message);
// 按照意圖發送廣播
sendBroadcast(intent);
}
}
8、啟動應用,查看效果


9、采用動態方式注冊廣播接收者
(1)修改專案清單檔案對廣播接收者的注冊

(2)在主界面類里動態注冊廣播接收者

(3)啟動應用,查看效果

三、案例演示 - 顯示播放進度
- 本案例演示如何通過廣播實作視窗與服務之間的通信
(一)運行效果


(二)涉及知識點
- 活動視窗(Activity)
- 服務(Service)
- 廣播接收者(BroadcastReceiver)
- 標簽(TextView)
- 進度條(ProgressBar)
- 按鈕(Button)
- 線性布局(LinearLayout)
- 執行緒(Thread)
(三)實作步驟
1、創建安卓應用【DisplayProgress】


2、將背景圖片拷貝到drwawable目錄

3、主布局資源檔案activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:background="@drawable/background"
android:gravity="center"
android:orientation="vertical"
android:padding="20dp"
tools:context=".MainActivity">
<TextView
android:id="@+id/tvProgress"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="0%"
android:textColor="#0000ff"
android:textSize="50sp" />
<ProgressBar
android:id="@+id/pbPlay"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginBottom="20dp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="horizontal">
<Button
android:id="@+id/btnStart"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:onClick="doStart"
android:text="@string/start"
android:textSize="20sp" />
<Button
android:id="@+id/btnStop"
android:layout_width="150dp"
android:layout_height="wrap_content"
android:onClick="doStop"
android:text="@string/stop"
android:textSize="20sp" />
</LinearLayout>
</LinearLayout>
4、字串資源檔案strings.xml

<resources>
<string name="app_name">顯示播放進度</string>
<string name="start">開始</string>
<string name="stop">停止</string>
</resources>
5、創建應用程式常量介面 - AppConstants

package net.hw.display_progress;
/**
* 功能:應用程式常量介面
* 作者:華衛
* 日期:2020年12月30日
*/
public interface AppConstants {
String TAG = "net.hw.display_progress"; // 應用程式標記
String INTENT_ACTION_START = "net.hw.display_progress.intent.action.START"; // 開始進度廣播頻道
String INTENT_ACTION_STOP = "net.hw.display_progress.intent.action.STOP"; // 停止進度廣播頻道
String INTENT_ACTION_UPDATE_PROGRESS = "net.hw.display_progress.intent.action.UPDATE_PROGRESS"; // 更新進度廣播頻道
}
6、創建進度服務類 - ProgressService

- 繼承Service類,實作AppConstants介面

- 創建內部廣播接收者 - InnerBroadcastReceiver (功能代碼暫時空著)

- 宣告變數

- 在創建回呼方法里創建并注冊內部廣播接收者

- 創建啟動更新執行緒的方法 - startUpdateThread()

- 撰寫銷毀更新執行緒的方法

- 在銷毀回呼方法里注銷內部廣播接收者

- 撰寫內部廣播接收者代碼

- 查看進度服務類完整源代碼
package net.hw.display_progress;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.util.Log;
import androidx.annotation.Nullable;
/**
* 功能:進度服務類
* 作者:華衛
* 日期:2020年12月30日
*/
public class ProgressService extends Service implements AppConstants {
private InnerBroadcastReceiver receiver; // 內部廣播接收者
private IntentFilter filter; // 意圖過濾器
private Thread thread; // 執行緒
private boolean isRunning; // 執行緒回圈控制變數
private int progressValue; // 進度值
/**
* 創建回呼方法
*/
@Override
public void onCreate() {
super.onCreate();
// 創建內部廣播接收者
receiver = new InnerBroadcastReceiver();
// 創建意圖過濾器
filter = new IntentFilter();
// 添加意圖動作(廣播頻道)
filter.addAction(INTENT_ACTION_START);
filter.addAction(INTENT_ACTION_STOP);
// 動態注冊內部廣播接收者
registerReceiver(receiver, filter);
}
/**
* 啟動更新執行緒
*/
private void startUpdateThread() {
// 設定執行緒回圈控制變數為真
isRunning = true;
// 創建更新進度值的執行緒
thread = new Thread(new Runnable() {
@Override
public void run() {
// 執行緒回圈
while (isRunning) {
// 更新進度值
progressValue = ++progressValue % 101;
// 輸出除錯資訊
Log.d(TAG, "當前進度值:" + progressValue + "%");
// 創建意圖
Intent intent = new Intent();
// 設定意圖動作(廣播頻道)
intent.setAction(INTENT_ACTION_UPDATE_PROGRESS);
// 設定意圖攜帶的附加資料
intent.putExtra("progressValue", progressValue);
// 按意圖發送廣播
sendBroadcast(intent);
try {
// 讓執行緒睡眠500毫秒
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
// 啟動執行緒
thread.start();
}
/**
* 銷毀更新執行緒
*/
private void destroyUpdateThread() {
// 設定縣城回圈控制變數為假
isRunning = false;
// 銷毀更新進度的執行緒
thread = null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
/**
* 銷毀回呼方法
*/
@Override
public void onDestroy() {
super.onDestroy();
// 注銷內部廣播接收者
unregisterReceiver(receiver);
}
/**
* 內部廣播接收者
*/
private class InnerBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent != null) {
// 根據廣播頻道進行不同操作
switch (intent.getAction()) {
case INTENT_ACTION_START:
// 啟動更新執行緒
startUpdateThread();
Log.d(TAG, "收到啟動進度的廣播!");
break;
case INTENT_ACTION_STOP:
// 銷毀更新執行緒
destroyUpdateThread();
Log.d(TAG, "收到停止進度的廣播!");
break;
}
}
}
}
}
7、在專案清單檔案里注冊進度服務類

8、主界面類 - MainActivity

-
創建內部廣播接收者(功能代碼暫時空著)

-
宣告變數

-
實作AppConstants介面

-
通過資源識別符號獲取控制元件實體

-
啟動進度服務

-
創建并注冊內部廣播接收者

-
撰寫內部廣播接收者代碼

-
撰寫開始按鈕單擊事件處理方法

-
撰寫停止按鈕單擊事件處理方法

-
在銷毀回呼方法里停止服務,注銷內部廣播接收者

-
查看主界面類完整源代碼
package net.hw.display_progress;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.widget.ProgressBar;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity implements AppConstants {
private TextView tvProgress; // 顯示進度值的標簽
private ProgressBar pbPlay; // 播放進度條
private Intent intent; // 意圖
private IntentFilter filter; // 意圖過濾器
private InnerBroadcastReceiver receiver; // 內部廣播接受者
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 利用布局資源檔案設定用戶界面
setContentView(R.layout.activity_main);
// 通過資源識別符號獲取控制元件實體
tvProgress = findViewById(R.id.tvProgress);
pbPlay = findViewById(R.id.pbPlay);
// 創建啟動服務的意圖
intent = new Intent(this, ProgressService.class);
// 啟動進度服務
startService(intent);
// 創建內部廣播接收者
receiver = new InnerBroadcastReceiver();
// 創建意圖過濾器
filter = new IntentFilter();
// 添加意圖動作(廣播頻道)
filter.addAction(INTENT_ACTION_UPDATE_PROGRESS);
// 動態注冊內部廣播接受者
registerReceiver(receiver, filter);
}
/**
* 內部廣播接收者
*/
private class InnerBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent != null) {
// 收到來自進度服務所發送的廣播
if (INTENT_ACTION_UPDATE_PROGRESS.equals(intent.getAction())) {
// 獲取廣播傳遞過來的進度值
int progressValue = intent.getIntExtra("progressValue", 0);
// 用更新后的進度值去設定進度標簽
tvProgress.setText(progressValue + "%");
// 用更新后的進度值去設定進度條
pbPlay.setProgress(progressValue);
}
}
}
}
/**
* 開始按鈕單擊事件處理方法
*
* @param view
*/
public void doStart(View view) {
// 創建意圖
Intent intent = new Intent();
// 設定動作(廣播頻道)
intent.setAction(INTENT_ACTION_START);
// 按意圖發送廣播
sendBroadcast(intent);
}
/**
* 停止按鈕單擊事件處理方法
*
* @param view
*/
public void doStop(View view) {
// 創建意圖
Intent intent = new Intent();
// 設定動作(廣播頻道)
intent.setAction(INTENT_ACTION_STOP);
// 按意圖發送廣播
sendBroadcast(intent);
}
/**
* 銷毀回呼方法
*/
@Override
protected void onDestroy() {
super.onDestroy();
// 停止服務
stopService(intent);
// 注銷廣播接收者
unregisterReceiver(receiver);
}
}
9、啟動應用,查看效果


轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/242903.html
標籤:其他
