android接受广播
Ⅰ android接受广播时怎么确定是哪个应用发送的广播
在Intent内可以设置一个字段作为应用的标示符,广播通过解析这个Intent内的标示符来匹配是哪个应用发送的。简单来说,你有3个应用能发送broadcast,用标示符0,1,2来分别标示,receiver接收到这个intent以后,解析标示符,然后就可以知道是哪个应用发送的broadcast了。
Ⅱ android 接受开机广播
Android接收开机广播,需要用到播广播接收者BroadcastReceiver组件。
具体代码:
在配置文件AndroidManifest.xml中向系统注册receiver
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>需要添加相应权限
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
在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();