Android入門(11)| 全局廣播與本地廣播

文章目錄

  • 廣播概念
  • 接收廣播
    • 動態注冊
      • 實例
    • 靜態注冊
      • 實例
  • 發送廣播
    • 發送標準廣播
    • 廣播的跨進程特性
    • 發送有序廣播
  • 本地廣播


廣播概念

Android 中的每個應用程序都可以對自己感興趣的廣播進行注冊,這樣該程序就只會接收到自己所關心的廣播內容,這些廣播可能是來自系統的,也可能是來自于其他應用程序的。

廣播有兩種類型——有序廣播和標準廣播:

  • 標準廣播: 一種完全異步執行的廣播,在廣播發出去之后,所有的廣播接收器幾乎都會同一時刻接收到這條廣播消息,沒有任何的先后順序可言,這種廣播的效率比較高,但是無法被截斷

在這里插入圖片描述

  • 有序廣播: 是一種同步執行的廣播,在廣播發出去之后,同一時刻只會有一個廣播接收器能夠收到這條消息,當這個廣播接收器中的邏輯執行完畢之后,廣播才會繼續傳遞,所以這時候的廣播接收器是有優先級順序的,并且前面的廣播接收器還可以截斷正在傳遞的廣播,這樣后面的廣播就無法收到廣播消息。

在這里插入圖片描述

接收廣播

動態注冊

Android內置了很多系統級別的廣播,我們可以在應用程序中通過監聽這些廣播來得到各種系統的狀態信息。比如手機開機、電池電量發生變化、時間或者時區發生改變等等。如果想要接收到這些廣播就需要使用廣播接收器。

注冊廣播的方式一般也有兩種,在 代碼中注冊(動態注冊) 或者 AndroidManifest.xml 中注冊(靜態注冊)

實例

我們實現一個能準確地告訴用戶當前有沒有網絡的功能,在實現代碼前,由于 Android 為了保護用戶設備的隱私和安全,規定了程序需要進行一些對用戶來說比較敏感的操作,必須在配置文件中聲明權限才可以,該功能監聽了網絡的變化,所以必須在 AndroidManifest.xml 配置權限才能訪問系統網絡狀態:
在這里插入圖片描述

public class BroadcastActivity extends AppCompatActivity {private IntentFilter intentFilter; // 意圖過濾器,旨在匹配可以響應對應操作的組件private NetworkChangeReceiver networkChangeReceiver; // 自定義的廣播接收器類@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);intentFilter = new IntentFilter();// android.net.conn.CONNECTIVITY_CHANGE是網絡狀態變化時系統的廣播intentFilter.addAction("android.net.conn.CONNECTIVITY_CHANGE");networkChangeReceiver = new NetworkChangeReceiver();// 注冊,將接收器與IntentFilter相匹配registerReceiver(networkChangeReceiver, intentFilter);}// 動態注冊一定要在結束時取消注冊protected void onDestroy(){super.onDestroy();// 實現取消注冊unregisterReceiver(networkChangeReceiver);}// 自定義的廣播接收器類class NetworkChangeReceiver extends BroadcastReceiver{@Overridepublic void onReceive(Context context, Intent intent) {// 通過getSystemService得到管理網絡連接的connectivityManager實例ConnectivityManager connectivityManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();// 通過isAvailable方法判斷是否有網絡if(networkInfo != null && networkInfo.isAvailable()){Toast.makeText(context, "network is available", Toast.LENGTH_SHORT).show();} else{Toast.makeText(context, "network is unavailable", Toast.LENGTH_SHORT).show();}}}
}

靜態注冊

動態注冊的廣播可以自由控制注冊、注銷,很靈活,缺點是必須在程序啟動之后才能接受到廣播,因為注冊的邏輯是寫在 onCreate() 里面的,使用靜態注冊可以讓程序在未啟動的情況下接受到廣播

實例

靜態注冊需要在 AndroidManifest.xml 進行注冊,使用 receiver 標簽,并告訴這個 receiver 注冊哪一個 action,下面是一個開機啟動接受廣播的案例:

在這里插入圖片描述

public class BootCompleteReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {// TODO: This method is called when the BroadcastReceiver is receiving// an Intent broadcast.Toast.makeText(context, "Boot Complete", Toast.LENGTH_SHORT).show();}
}

PS:不要在 onReceive() 方法中添加過多邏輯或耗時操作,因為廣播接收器中不允許開啟線程,因此當 onReceive() 運行較長時間卻未結束時,程序就會報錯。


發送廣播

發送標準廣播

發送廣播使用 Intent 進行發送,首先需要準備一個接收器用于接受發送的廣播:

public class MyBroadcastReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {// 收到自定義廣播時會彈出提示Toast.makeText(context, "received in MyBroadcastReceiver", Toast.LENGTH_LONG).show();}
}

AndroidManifest.xml 中注冊廣播的值:

實現點擊 BroadcastActivity 活動中的 send broadcast 按鈕來發送廣播:

布局文件 broad_layout.xml

<LinearLayoutxmlns:android="http://schemas.android.com/apk/res/android"android:orientation="vertical"android:layout_width="match_parent"android:layout_height="match_parent"><Buttonandroid:id="@+id/button_broadcast1"android:layout_width="match_parent"android:layout_height="wrap_content"android:text="send broadcast"/>
</LinearLayout>

活動代碼 BroadcastActivity.java

public class BroadcastActivity extends AppCompatActivity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.broad_layout);Button button = findViewById(R.id.button_broadcast1);button.setOnClickListener((View v)->{// 將要發送的廣播植入IntentIntent intent = new Intent("com.example.activitytest.Activity.MY_BROADCAST");// 參數1:包名;參數2:接收器的路徑ComponentName componentName = new ComponentName("com.example.activitytest","com.example.activitytest.Activity.MyBroadcastReceiver");// 通過調用Intent中的setComponent方法,我們可以打開另外一個應用中的Activity或者服務。intent.setComponent(componentName);// 調用Context的sendBroadcast方法發送廣播sendBroadcast(intent);});}
}

PS: ComponentName 構造函數的第一個參數指的包名是 AndroidManifest.xml 文件下 package 屬性對應的包名:
在這里插入圖片描述
而非 BroadcastActivity.java 文件所在的包名:
在這里插入圖片描述
詳見該博客

運行結果:
在這里插入圖片描述


廣播的跨進程特性

新建一個項目,創建廣播接收器 MyReceiver.java

public class MyReceiver extends BroadcastReceiver {private static final String TAG = "MyReceiver";@Overridepublic void onReceive(Context context, Intent intent) {Log.e(TAG, "onReceive: gone");Toast.makeText(context, "received gone", Toast.LENGTH_LONG).show();}
}

AndroidManifest.xml
在這里插入圖片描述
在原來項目的 BroadcastActivity.java 文件中發送第二條廣播:
在這里插入圖片描述
運行結果:
在這里插入圖片描述
在這里插入圖片描述
更多關于廣播的問題詳見本文——解決 Android 8.0 以上靜態廣播無法注冊


發送有序廣播

很多人對之前的代碼可能會有疑問,我指定廣播發送給哪個包的哪個接收器,這還算“廣播”嗎?因此,對于安卓高版本而言,還有另一種發送廣播的方法:

修改 BroadcastActivity.java 中的代碼:
在這里插入圖片描述

即可實現真正意義上的廣播。在此基礎上,我們發送有序廣播,定義接收器的優先級
在這里插入圖片描述
并在接收器 MyBroadcastReceiver.java 中截斷廣播,不允許廣播繼續傳遞:

public class MyBroadcastReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {// 收到自定義廣播時會彈出提示Toast.makeText(context, "received in MyBroadcastReceiver", Toast.LENGTH_SHORT).show();// 截斷abortBroadcast();}
}

不必對另一個接收器 MyReceiver 進行更改,此時就已達到了只有 MyBroadcastReceiver 能收到廣播,而 MyReceiver 不能收到廣播的目的。


本地廣播

前面我們發送和接受的廣播都是系統的全局廣播,發出的廣播可以被其他任何應用程序接收到。這樣容易引起安全問題,為了解決安全性問題,Android 支持發送本地廣播,其有以下特點:

  • 廣播不會離開我們的程序,無需擔心機密數據泄露;
  • 其他程序的廣播無法發送到我們程序內部,無需擔心有安全漏洞的隱患;
  • 比發送全局廣播更高效。
  • 本地廣播的接收只能使用動態注冊,因為靜態注冊就是為了讓程序在未啟動的時候也能接收到廣播,而發送本地廣播的時候應用程序肯定啟動了

本地廣播并不復雜,主要就是使用了一個 LocalBroadcastManager 來對廣播進行管理,并且提供了發送廣播和注冊廣播接收器的方法:

public class BroadcastActivity extends AppCompatActivity {private static final String TAG = "BroadcastActivity";private IntentFilter intentFilter; // 意圖過濾器private LocalReceiver localReceiver; // 自定義接收器類private LocalBroadcastManager localBroadcastManager; // support包提供的本地廣播工具@SuppressLint("WrongConstant")@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.broad_layout);localBroadcastManager = LocalBroadcastManager.getInstance(this); // 獲取實例Button button = findViewById(R.id.button_broadcast1);button.setOnClickListener((View v)->{Log.e(TAG, "onCreate: start");// 將要發送的廣播植入IntentIntent intent = new Intent("com.example.activitytest.Activity.LOCAL_BROADCAST");if(Build.VERSION.SDK_INT >= 28){// 突破隱式廣播限制intent.addFlags(0x01000000);}localBroadcastManager.sendBroadcast(intent); // 發送本地廣播});// 動態注冊的步驟intentFilter = new IntentFilter();// 添加自定義廣播intentFilter.addAction("com.example.activitytest.Activity.LOCAL_BROADCAST");// 實例化接收器localReceiver = new LocalReceiver();// 注冊接收器localBroadcastManager.registerReceiver(localReceiver, intentFilter);}// 動態注冊一定要在結束時取消注冊@Overrideprotected void onDestroy() {super.onDestroy();localBroadcastManager.unregisterReceiver(localReceiver);}class  LocalReceiver extends BroadcastReceiver {@Overridepublic void onReceive(Context context, Intent intent) {Toast.makeText(context, "本地廣播", Toast.LENGTH_LONG).show();}}
}

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/443702.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/443702.shtml
英文地址,請注明出處:http://en.pswp.cn/news/443702.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Android開發(2) | 廣播 Broadcast 的應用——強制下線功能

文章目錄功能簡介關閉所有活動登陸界面發送強制下線的廣播廣播接收器AndroidManifest.xml運行結果功能簡介 強制下線功能只需要彈出一個對話框&#xff0c;讓用戶只能點擊確定按鈕&#xff0c;回到登錄界面。 如果在每一個活動中添加一個對話框的話太過繁瑣&#xff0c;用廣播…

Android入門(12)| 數據持久化

文章目錄數據持久化文件存儲將數據存儲進文件實例從文件中讀取數據實例SharedPreferences存儲將數據存儲進文件實例從文件中讀取數據實例實現記住密碼的功能SQLite數據庫存儲創建自己的幫助類調用自己的幫助類補全 onUpgrade() 方法增刪查改增&#xff1a;SQLiteDatabase.inser…

Android入門(13)| Android權限 與 內容提供器

文章目錄普通權限與危險權限運行時申請權限內容提供器運用安卓封裝好的內容提供器自實現的內容提供器概念實現普通權限與危險權限 主要用于不同應用程序之間在保證被訪數據的安全性的基礎上&#xff0c;實現數據共享的功能。 在 Android 6.0 開始引入了運行時權限的功能&…

Java實現身份證號碼的驗證,JAVA后臺驗證身份證號碼

代碼如下&#xff1a; package cn.gov.csrc.util;/*** 18 位身份證驗證器* * author admin* */ public class IDCard {final int[] wi { 7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2, 1 };final int[] vi { 1, 0, X, 9, 8, 7, 6, 5, 4, 3, 2 };private int[] ai n…

Android入門(14)| 通知

文章目錄創建通知點擊效果其它小功能實例創建通知 創建通知的步驟&#xff1a; 管理通知的 NotificationManager&#xff0c;通常通過當前 Context 的 getSystemService() 獲取實例。它接受一個字符串參數用于確定獲取系統的什么服務。Android 8.0(O) 版本后需要通知通道&…

Android開發(3) | 權限和內容提供器的應用——調用相機和相冊

文章目錄拍照并保存到 ImageView 控件布局文件 notice_layout.xml按鈕 button_takePhoto 的點擊操作隱式 Intent 啟動后的回調AndroidManifest.xml從相冊選取照片并在 ImageView 控件中顯示布局文件 notice_layout.xml按鈕 button_takePhoto 的點擊操作自定義打開相冊的方法 op…

Android開發(4) | 系統權限、MediaPlayer類 和 VideoView類 的應用——播放多媒體文件

文章目錄MediaPlayer類播放音頻的實例VideoView類播放視頻的實例MediaPlayer類 對多種格式的音頻文件提供了全面的控制方法&#xff1a; 如何獲得MediaPlayer實例&#xff1f; 通過構造函數&#xff1a; MediaPlayer mp new MediaPlayer();調用 MediaPlayer.create() 方法&…

Android入門(15)| 網絡

文章目錄WebViewHTTP使用HttpURLConnection使用OkHttp封裝網絡操作封裝HttpURLConnection封裝OkHttpWebView WebView 可以在 應用程序中&#xff08;而不是瀏覽器&#xff09; 展示一些網頁。 布局文件 web_layout.xml&#xff1a; <LinearLayoutxmlns:android"http…

Java-單例模式

單例模式相信大家都不陌生&#xff0c;在JAVAEE應用中&#xff0c;單例模式是一種應用非常廣泛的設計模式&#xff0c;應用中許多組件都只需要單個實例&#xff0c;下面介紹單例模式。 使用單例模式的優點&#xff1a; 1.減少創建JAVA實例所帶來的系統開銷。 2.便于系統跟蹤單…

Android入門(16)| 服務

文章目錄概念Android 多線程繼承 Thread繼承 Runable 接口匿名類異步消息處理AsyncTask使用服務框架啟動/停止服務綁定/解綁服務服務的生命周期前臺服務IntentService完整版下載示例下載過程的回調接口&#xff1a;DownloadListener繼承 AsyncTask 實現下載功能&#xff1a;Dow…

2020德勤面試開始了嗎_2020國考面試開始,近期面試公告匯總,附結構化小組面試流程...

2020年國家公務員考試面試環節逐步恢復考試&#xff0c;各個招錄部門已經發布面試考察公告&#xff0c;對于進入面試環節的國考考生來說&#xff0c;有必要了解近期國考面試的招錄動態&#xff0c;提前做好面試準備。2020國考國家統計局機關面試面試確認&#xff1a;請進入面試…

項目積壓需求項目計劃_需求變更頻繁,項目經理如何做好需求管理?

項目實施過程中&#xff0c;項目經理常常面臨一個重大挑戰——需求變更。需求變更無處不在&#xff0c;市場條件變化、新業務出現、戰略目標調整、客戶需求修改、資源限制等&#xff0c;都會造成需求變更。需求變更會影響項目的時間、成本和質量&#xff0c;對整個項目和團隊成…

Android | Sensor.TYPE_ORIENTATION被廢棄后的解決辦法

文章目錄概述getOrientation 方法根據 旋轉矩陣R 獲取 設備旋轉弧度getRotationMatrix 方法根據 地磁場、加速度傳感器對象 獲取 旋轉矩陣R代碼參考資料概述 Sensor.TYPE_ORIENTATION 常數在 API 8 中已棄用&#xff0c;官方推薦使用 SensorManager.getOrientation() 替代。關…

【JAVA 開發小問題】 | String操作合集

文章目錄截取特定兩個字符之間的字符串截取特定兩個字符之間的字符串 利用正則表達式&#xff0c;圖片來源

uniapp 刷新后數據都沒有了_環境溫度傳感器都沒有連接,竟然還會有數據?

福田歐曼GTL(福康發動機、康明斯2880系統)匹配ECoffit尿素泵●故障現象&#xff1a;OBD故障燈點亮&#xff0c;不燒尿素&#xff0c;油耗高&#xff0c;動力不足●故障碼&#xff1a;●維修分析&#xff1a;①故障指出加熱器問題&#xff0c;摸下尿素箱溫度&#xff0c;發現燙手…

Android | 再探 RecyclerView 之名詞解析

文章目錄Adapter、ViewHolderchild viewLayoutManagerRecyclerScrapDirtyIndexPositionlayout position 和 adapter position四級緩存瀏覽本文前推薦先閱讀 Android入門&#xff08;九&#xff09;| 滾動控件 ListView 與 RecyclerView Adapter、ViewHolder Adapter: A subcla…

Linux學習:第一章-Linux簡介

一 UNIX發展史1 1965年&#xff0c;美國麻省理工學院&#xff08;MIT&#xff09;、通用電氣公司&#xff08;GE&#xff09;及AT&T的貝爾實驗室聯合開發Multics工程計劃&#xff0c;其目標是開發一種交互式的具有多道程序處理能力的分時操作系統&#xff0c;但因Multics追…

尼爾機器人技能快捷鍵_《尼爾機械紀元》連招操作技巧

《尼爾機械紀元》中的每個角色都可以裝備一個輕武器和一個重武器&#xff0c;技能招式也很豐富&#xff0c;下面為大家帶來了《尼爾機械紀元》連招操作技巧&#xff0c;希望對你們有所幫助。連擊技能展示視頻視頻原址&#xff1a;點擊進入基本沒有什么太難的連段&#xff0c;只…

保姆級教學!Xcode 配置 OpenGL 環境

文章目錄GLFW獲取 GLFWGLAD獲取 GLAD在 Xcode 中配置下載好的 GLFW 和 GLAD配置流程檢測是否配置成功無關配置的題外話——Xcode 下安全的刪除移動操作GLFW Graphics Library Framework&#xff08;圖形庫框架&#xff09;&#xff0c;可以讓我們通過其封裝好的 通用API 來正確…

Android入門(17)| 百度提供的 Android定位SDK

文章目錄配置百度提供的 Android定位SDK用于發布的 SHA1用于測試的 SHA1使用百度定位實例配置百度提供的 Android定位SDK 詳情參見官方文檔&#xff0c;這里僅對獲取 SHA1 做詳細介紹&#xff1a; 用于發布的 SHA1 用于測試的 SHA1 使用百度定位實例 public class LocationAc…