1. android插USB才會收到系統廣播怎麼回事
android在UsbManager服務中有一個名為ACTION_USB_STATE常量,值為"android.hardware.usb.action.USB_STATE",它是一個廣播供我們可以監聽USB插入與撥出的狀態。當USB連接狀態發生改變時就會發送這個廣播。為此我們只需要注冊一個action="android.hardware.usb.action.USB_STATE" 的BrocastReceiver即可,如:
<receiver android:name="com.coeus.screentapdemo.receiver.UsbConnectionReceiver" >
<intent-filter android:priority="1000" >
<action android:name="android.hardware.usb.action.USB_STATE" />
</intent-filter>
</receiver>
值得注意的是android.hardware.usb.action.USB_STATE是一個粘性的廣播,裡面封裝USB_CONNECTED(連接狀態)、USB_CONFIGURED(配置信息)、USB_FUNCTION_MASS_STORAGE(大存儲功能)、USB_FUNCTION_ADB(adb功能) 等狀態,當這些狀態發生改變時,就會發送廣播。通常接收到USB狀態廣播是一連串的,需要我們自行區分。
作者:GooSky
鏈接:https://www.jianshu.com/p/a5c8b79b7fff
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並註明出處。
2. android接受不到開機廣播
intent
判斷
intent.getAction()是否與
android.intent.action.BOOT_COMPLETED
相同,發出的是這個,你沒監聽這個Action
。
另外注意的是,如果是
3.1以下的系統,沒問題。3.1以上的系統,需要有Activity存在,並且啟動一次程序,才能夠實現廣播。
3. Android系統廣播(Broadcast)注冊,發送,接收流程解析
以下廣播簡稱Broadcast
是Android四大組件之一,在四大組件的另外兩個組件 和 擁有發送和接收廣播的能力。Android 是在 進程間通信機制的基礎上實現的,內部基於消息發布和訂閱的事件驅動模型,廣播發送者負責發送消息,廣播接收者需要先訂閱消息,然後才能收到消息。 進程間通信與 的區別在於:
有三種類型
存在一個注冊中心,也可以說是一個調度中心,即 。廣播接收者將自己注冊到 中,並指定要接收的廣播類型;廣播發送者發送廣播時,發送的廣播首先會發送到 , 根據廣播的類型找到對應的 ,找到後邊將廣播發送給其處理。
這里以普通廣播為例子, 接收者有兩種注冊方式,一種是 ,一種是 :
(廣播的發送分為 兩種,這里針對有序的廣播) 中的android:priority=""和 中的IntentFilter.setPriority(int)可以用來設置廣播接收者的優先順序,默認都是0 , 范圍是[-1000, 1000],值越大優先順序越高,優先順序越高越早收到。
在相同優先順序接收同個類型廣播時, 的廣播接收器比 的廣播接收者更快的接收到對應的廣播,這個之後會進行分析。
註:以下源碼基於rk3399_instry Android7.1.2
的流程可分為 , 和 三個部分,這里依次分析下
在Android系統的 機制中,前面提到, 作為一個注冊和調度中心負責注冊和轉發 。所以 的注冊過程就是把它注冊到 的過程。
這里我們分析 廣播的過程, 和 有一個共同的父類 ,所以它們對應的注冊過程其實是調用 ,接下來我們按照流程逐步分析調用流程的源碼。
frameworks/base/core/java/android/content/ContextWrapper.java
在之前的 Android應用程序啟動入口ActivityThread.main流程分析 分析過,在我們啟動 Activity 時會創建一個 對象,然後通過 傳給我們啟動的 ,其內部就會將該對象賦值給 ; 的 方法也是類似的賦值流程,這里放個簡易的源碼應該更好理解
可以看到最後都會將生成的 對象賦值給對應的
對象。接下來繼續分析 , 即 函數。
/frameworks/base/core/java/android/app/ContextImpl.java
這里我們首先看下如何將廣播接收者 封裝成一個 介面的 本地對象
/frameworks/base/core/java/android/app/LoadedApk.java
每一個注冊過廣播接收者的 或 組件在<font color='Crimson'> LoadedApk </font>類中都有個對應的 對象,該對象負責將 與 組件關聯起來。這些對象,以關聯的 作為關鍵字保存在一個 中。之後對應的 又以 的 作為關鍵字保存在 的成員變數 對象中。最後通過 對應的 方法獲得其 介面的 本地對象。之後再回到 注冊方法內,將 對象發給 進行注冊。
/frameworks/base/core/java/android/app/ActivityManagerNative.java
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
在的 或 注冊一個 時,並不是將其注冊到<font color='OrangeRed'>AMS</font>中,而是將與它關聯的<font color='OrangeRed'>InnerReceiver</font>對象注冊到<font color='OrangeRed'>AMS</font>中,當<font color='OrangeRed'>AMS</font>接收到廣播時,會根據 在內部找到對應的<font color='OrangeRed'>InnerReceiver</font>對象,然後在通過這個對象將這個廣播發送給對應的 處理。
注冊過程這邊畫了一個簡單的流程圖:
<font color='OrangeRed'>Broadcast</font>的發送過程可簡單描述為以下幾個過程:
frameworks/base/core/java/android/content/ContextWrapper.java
/frameworks/base/core/java/android/app/ContextImpl.java
/frameworks/base/core/java/android/app/ActivityManagerNative.java
/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java