当前位置:首页 » 安卓系统 » 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();

热点内容
c语言稀疏矩阵转置矩阵 发布:2025-02-01 03:47:57 浏览:530
坦克世界挂机脚本有哪些 发布:2025-02-01 03:07:41 浏览:133
串口编程at 发布:2025-02-01 03:06:05 浏览:908
合资汽车配置有什么 发布:2025-02-01 02:56:07 浏览:78
wifi共享精灵源码 发布:2025-02-01 02:40:15 浏览:973
java软件怎么安装 发布:2025-02-01 02:40:09 浏览:549
河北税务局电子密码是什么 发布:2025-02-01 02:40:07 浏览:835
检查服务器设置是什么意思 发布:2025-02-01 02:31:26 浏览:185
神偷四第四章密码是多少 发布:2025-02-01 02:07:29 浏览:13
qq登录在哪个文件夹 发布:2025-02-01 01:57:59 浏览:627