當前位置:首頁 » 安卓系統 » android接受廣播

android接受廣播

發布時間: 2022-10-25 10:01:34

Ⅰ android接受廣播時怎麼確定是哪個應用發送的廣播

在Intent內可以設置一個欄位作為應用的標示符,廣播通過解析這個Intent內的標示符來匹配是哪個應用發送的。簡單來說,你有3個應用能發送broadcast,用標示符0,1,2來分別標示,receiver接收到這個intent以後,解析標示符,然後就可以知道是哪個應用發送的broadcast了。

Ⅱ android 接受開機廣播

Android接收開機廣播,需要用到播廣播接收者BroadcastReceiver組件。

具體代碼:

  1. 在配置文件AndroidManifest.xml中向系統注冊receiver

    <intent-filter>
    <action android:name="android.intent.action.BOOT_COMPLETED" />
    </intent-filter>

  2. 需要添加相應許可權

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

  3. 在Receiver中就可以添加開機需要進行的操作

    public class BootCompletedReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {

    }

    }

Ⅲ 22 AndroidBroadcast廣播機制

廣播(Broadcast)機制用於進程/線程間通信,廣播分為廣播發送和廣播接收兩個過程,其中廣播接收者BroadcastReceiver便是Android四大組件之一。

BroadcastReceiver分為兩類:

從廣播發送方式可分為三類:

廣播在系統中以BroadcastRecord對象來記錄, 該對象有幾個時間相關的成員變數.

廣播注冊,對於應用開發來說,往往是在Activity/Service中調用 registerReceiver() 方法,而Activity或Service都間接繼承於Context抽象類,真正幹活是交給ContextImpl類。另外調用getOuterContext()可獲取最外層的調用者Activity或Service。

[ContextImpl.java]

其中broadcastPermission擁有廣播的許可權控制,scheler用於指定接收到廣播時onRecive執行線程,當scheler=null則默認代表在主線程中執行,這也是最常見的用法

[ContextImpl.java]

ActivityManagerNative.getDefault()返回的是ActivityManagerProxy對象,簡稱AMP.
該方法中參數有mMainThread.getApplicationThread()返回的是ApplicationThread,這是Binder的Bn端,用於system_server進程與該進程的通信。

[-> LoadedApk.java]

不妨令 以BroadcastReceiver(廣播接收者)為key,LoadedApk.ReceiverDispatcher(分發者)為value的ArrayMap 記為 A 。此處 mReceivers 是一個以 Context 為key,以 A 為value的ArrayMap。對於ReceiverDispatcher(廣播分發者),當不存在時則創建一個。

此處mActivityThread便是前面傳遞過來的當前主線程的Handler.

ReceiverDispatcher(廣播分發者)有一個內部類 InnerReceiver ,該類繼承於 IIntentReceiver.Stub 。顯然,這是一個Binder服務端,廣播分發者通過rd.getIIntentReceiver()可獲取該Binder服務端對象 InnerReceiver ,用於Binder IPC通信。

[-> ActivityManagerNative.java]

這里有兩個Binder服務端對象 caller 和 receiver ,都代表執行注冊廣播動作所在的進程. AMP通過Binder驅動將這些信息發送給system_server進程中的AMS對象,接下來進入AMS.registerReceiver。

[-> ActivityManagerService.java]

其中 mRegisteredReceivers 記錄著所有已注冊的廣播,以receiver IBinder為key, ReceiverList為value為HashMap。

在BroadcastQueue中有兩個廣播隊列mParallelBroadcasts,mOrderedBroadcasts,數據類型都為ArrayList<broadcastrecord style="box-sizing: border-box;">:</broadcastrecord>

mLruProcesses數據類型為 ArrayList<ProcessRecord> ,而ProcessRecord對象有一個IApplicationThread欄位,根據該欄位查找出滿足條件的ProcessRecord對象。

該方法用於匹配發起的Intent數據是否匹配成功,匹配項共有4項action, type, data, category,任何一項匹配不成功都會失敗。

broadcastQueueForIntent(Intent intent)通過判斷intent.getFlags()是否包含FLAG_RECEIVER_FOREGROUND 來決定是前台或後台廣播,進而返回相應的廣播隊列mFgBroadcastQueue或者mBgBroadcastQueue。

注冊廣播:

另外,當注冊的是Sticky廣播:

廣播注冊完, 另一個操作便是在廣播發送過程.

發送廣播是在Activity或Service中調用 sendBroadcast() 方法,而Activity或Service都間接繼承於Context抽象類,真正幹活是交給ContextImpl類。

[ContextImpl.java]

[-> ActivityManagerNative.java]

[-> ActivityManagerService.java]

broadcastIntent()方法有兩個布爾參數serialized和sticky來共同決定是普通廣播,有序廣播,還是Sticky廣播,參數如下:

broadcastIntentLocked方法比較長,這里劃分為8個部分來分別說明。

這個過程最重要的工作是:

BroadcastReceiver還有其他flag,位於Intent.java常量:

主要功能:

這個過主要處於系統相關的10類廣播,這里不就展開講解了.

這個過程主要是將sticky廣播增加到list,並放入mStickyBroadcasts裡面。

其他說明:

AMS.collectReceiverComponents

廣播隊列中有一個成員變數 mParallelBroadcasts ,類型為ArrayList<broadcastrecord style="box-sizing: border-box;">,記錄著所有的並行廣播。</broadcastrecord>

動態注冊的registeredReceivers,全部合並都receivers,再統一按串列方式處理。

廣播隊列中有一個成員變數 mOrderedBroadcasts ,類型為ArrayList<broadcastrecord style="box-sizing: border-box;">,記錄著所有的有序廣播。</broadcastrecord>

發送廣播過程:

處理方式:

可見不管哪種廣播方式,都是通過broadcastQueueForIntent()來根據intent的flag來判斷前台隊列或者後台隊列,然後再調用對應廣播隊列的scheleBroadcastsLocked方法來處理廣播;

在發送廣播過程中會執行 scheleBroadcastsLocked 方法來處理相關的廣播

[-> BroadcastQueue.java]

在BroadcastQueue對象創建時,mHandler=new BroadcastHandler(handler.getLooper());那麼此處交由mHandler的handleMessage來處理:

由此可見BroadcastHandler採用的是」ActivityManager」線程的Looper

[-> BroadcastQueue.java]

此處mService為AMS,整個流程還是比較長的,全程持有AMS鎖,所以廣播效率低的情況下,直接會嚴重影響這個手機的性能與流暢度,這里應該考慮細化同步鎖的粒度。

Ⅳ android 廣播自定義廣播接收問題

其實沒啥技術可言的,就是Android中可以自定義許可權的,對於四大組件的訪問加上一層保護,不多說了,直接上代碼:

發送廣播:

[java] view plain
package com.tt.test;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

public class Main extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
((Button)findViewById(R.id.button)).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent i = new Intent("COM.MESSAGE");
i.addCategory("receiver");
i.putExtra("message", "haha");
sendOrderedBroadcast(i, "xvtian.gai.receiver");
}
});
}
}
AndroidManifest.xml:

[html] view plain
<uses-permission android:name="xvtian.gai.receiver" ></uses-permission>
<permission android:protectionLevel="normal" android:name="xvtian.gai.receiver"></permission>

接收廣播:

[java] view plain
package com.tt.receiver;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

public class Receiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
Log.d("TAG", "receiver intent:" + intent.toString());
}

}
AndroidManifest.xml

[html] view plain
<uses-permission android:name="xvtian.gai.receiver" ></uses-permission>
[html] view plain
<receiver android:name=".Receiver" android:permission="xvtian.gai.receivers">
<intent-filter>
<action android:name="COM.MESSAGE" />
<category android:name="receiver" />
</intent-filter>
</receiver>

Ⅳ 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

Ⅵ 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
來源:簡書
簡書著作權歸作者所有,任何形式的轉載都請聯系作者獲得授權並註明出處。

Ⅶ 怎麼接收android 靜態廣播

在AndroidManifest.xml注冊的方式,Android不能自動銷毀廣播接收器,也就是說當應用程序關閉後,廣播接收器還是會接收廣播,而在代碼中注冊廣播接收器,可以讓程序員手動定義銷毀接收器的代碼。應該根據應用程序的需求來選擇實現廣播機制的方法。

Ⅷ android接受不到開機廣播

intent
判斷
intent.getAction()是否與
android.intent.action.BOOT_COMPLETED
相同,發出的是這個,你沒監聽這個Action

另外注意的是,如果是
3.1以下的系統,沒問題。3.1以上的系統,需要有Activity存在,並且啟動一次程序,才能夠實現廣播。

Ⅸ Android演示如何接收廣播消息

Android下面接收廣播消息比較簡單,主要實現步驟如下:
在AndroidManifest.xml中添加receiver欄位(裡面有intent-filter過濾action);
從BroadcastReceiver擴展類,添加onReceive處理;
示例代碼如下:
AndroidManifest.xml,這里演示的是監聽來電事件
注意要先添加許可權:
<uses-permission android:name=android.permission.READ_PHONE_STATE /
之後注冊Receiver:
<receiver android:name=ReceiverBroadcast
<intent-filter
<action android:name=android.intent.action.PHONE_STATE /
</intent-filter
</receiver
ReceiverBroadcast.java代碼中實現監聽事件處理:
package com.freesoft.anttest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.util.Log;
public class ReceiverBroadcast extends BroadcastReceiver {
private static String TAG=BroadcastReceiver;
public ReceiverBroadcast() {
Log.i(TAG, ReceiverBroadcast);}@Overridepublic void onReceive(Context arg0, Intent arg1) {
Log.i(TAG, onReceive);
Bundle bundle = arg1.getExtras();

熱點內容
qq登錄在哪個文件夾 發布:2025-02-01 01:57:59 瀏覽:624
如何加入安卓代理 發布:2025-02-01 01:51:40 瀏覽:2
我的世界手游伺服器刷鑽石教程 發布:2025-02-01 01:48:13 瀏覽:773
sqlifthen男女 發布:2025-02-01 01:44:59 瀏覽:690
幻靈和安卓哪個互通 發布:2025-02-01 01:43:33 瀏覽:648
電腦配置夠但為什麼打lol掉幀 發布:2025-02-01 01:37:08 瀏覽:316
21款朗逸哪個配置比較劃算 發布:2025-02-01 01:35:32 瀏覽:976
建築動畫片腳本 發布:2025-02-01 01:35:21 瀏覽:469
管家婆如何用阿里雲伺服器 發布:2025-02-01 01:29:09 瀏覽:649
解壓耳放 發布:2025-02-01 01:20:18 瀏覽:176