导航:首页 > 操作系统 > android开机广播收不到

android开机广播收不到

发布时间:2023-08-08 00:24:03

1. 为什么小米手机开机时“android.intent.action.MEDIA_MOUNTED”sd卡正常挂在的广播接收不到

您好!
一.请您备份数据,进入recovery(关机,按住音量上+开机键进入recovery)模式,清除缓存,清除用户数据,清除所有数据,恢复备份的时候,设置和手机里面的第三方安全软件这两项不要恢复。尝试可否正常使用。
二.如果还是不行,建议您使用线刷按照下面的方法重新刷一次完整包,下面的刷机教程您可以参考一下:
1.您先在小米官网下载个适合您机型的您需要的MIUI 线刷包。这是链接:http://bbs.xiaomi.cn/topic-mirom.html
2.在下载的这段时间,请您备份数据,进入recovery(关机,按住音量上+开机键进入recovery)清除缓存,清除用户数据,清除所有数据,。电脑装好驱动,下载个miflash刷机工具,这是装驱动链接:http://bbs.xiaomi.cn/thread-504332-1-1.html
3.一切准备就绪之后,请您按照官网的刷机教程使用第六种线刷,这是官方的刷机教程:http://bbs.xiaomi.cn/thread-3104435-1-1.html
4.如果您对刷机不熟悉,请您参考下米粉制作的刷机视频教程:http://v.youku.com/v_show/id_XNTEyMjQ1MzI4.html
感谢您的支持,祝您生活愉快!
欢迎您在网络小米企业平台提问:http://..com/c/xiaomi/

2. Android广播阻塞、延迟问题

        最近项目中,多次碰到app研发人员反馈广播从发送到接收器接收,间隔时间太长,要求系统进行优化,特别是开机阶段。对此,专门阅读了一下广播从发送到接收这个流程的源码,以彻底搞明白怎样让自己发送的广播尽快到达接收器。

涉及到的源码类不多,主要就是ActivityManagerService.java 和 BroadcastQueue.java。发送广播进程调用发送接口,通过IPC到达AMS,AMS根据Intent是否配置Intent.FLAG_RECEIVER_FOREGROUND,选择当前广播加入前台广播队列还是后台广播队列。根据当前广播是否有序,将广播加入广播队列的串行列表还是并行列表。广播队列和广播队列中的广播列表是影响广播接收时间的主要因素。

BroadcastQueue广播队列,负责将广播发送给广播接收器。AMS中有两个成员变量, 

BroadcastQueue mFgBroadcastQueue;//前台广播队列

BroadcastQueue mBgBroadcastQueue;//后台广播队列

前台广播队列和后台广播队列的区别有两处:1 超时时间,前台10s,后台60s. 2 是否延迟广播等待前一个广播进程完成。这两个区别已经说明前台广播对广播接收器要求更高,响应时间更短,如果广播要排队,时间上前台广播更短。同时系统默认使用后台广播队列,所以前台广播队列处理的广播要少,避免了可能的大量广播排队情况。

广播队列中的列表

//存放无序并发送给动态广播接收器的广播任务

final ArrayList<BroadcastRecord> mParallelBroadcasts = new ArrayList<BroadcastRecord>();

//存放无序发送给静态广播接收器的广播任务或者存放有序广播任务

final ArrayList<BroadcastRecord> mOrderedBroadcasts = new ArrayList<BroadcastRecord>();

mParallelBroadcasts 此列表中存放的是无序广播动态广播接收器任务,广播队列会在处理任务时通过嵌套循环,把每个广播通过ipc发送到关注它的所有进程。所有无序广播+动态广播接收器,广播不需要排队。这种情况是最快能让广播到达目标进程的方式。

mOrderedBroadcasts存放的广播任务特点:广播有序,或者广播接收器是静态注册的。此种类型的广播全部要在mOrderedBroadcasts中排队,广播之间按时间先后,同一个广播不同广播接收器按优先级。mOrderedBroadcasts存放的广播必须等一个广播任务处理完毕才能处理下一个,中间可能包含进程的启动等。

由此可见,广播最快的情况是前台广播、无序广播、动态注册广播接收器。最糟糕的情况是:后台广播、有序或静态注册广播接收器、广播接收器优先级低。如果一个应用只是简单的靠注册一个静态广播接收器拉起进程,对应的正是最糟糕的情况。如果又发生在开机阶段,自然延迟严重。

如果必须注册静态广播接收器,缩短时间的办法为:配置Intent.FLAG_RECEIVER_FOREGROUND,加入前台广播队列,设置广播优先级

源码:

广播发送:Context .sendBroadcast ->ActivityManagerNative.broadcastIntent->ActivityManagerService.broadcastIntent->ActivityManagerService.broadcastIntentLocked.到此阶段,跟发送广播的进程通信结束。此阶段AMS完成的工作主要是根据Intent查找该广播对应的动态广播接收器、静态广播接收器、以此发送该广播使用的广播队列。

private final int broadcastIntentLocked(

......//权限检查

......//特殊系统广播进行必要处理

if (sticky) {//粘性广播处理

......

//查找静态注册的接收器

receivers = collectReceiverComponents(intent, resolvedType, users);

if (intent.getComponent() == null) {

    // 查找动态广播接收器

            registeredReceivers = mReceiverResolver.queryIntent(intent,

                    resolvedType, false, userId);

        }

//动态广播接收器

        int NR = registeredReceivers != null ? registeredReceivers.size() : 0;

        if (!ordered && NR > 0) { 

//确定队列

            final BroadcastQueue queue = broadcastQueueForIntent(intent);

//创建广播任务BroadcastRecord

            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,

                    callerPackage, callingPid, callingUid, resolvedType, requiredPermission,

                    appOp, registeredReceivers, resultTo, resultCode, resultData, map,

                    ordered, sticky, false, userId);

......

//广播任务加入并行列表中

                queue.(r);

//启动异步发送广播任务

                queue.scheleBroadcastsLocked();

registeredReceivers = null;

            NR = 0;

......

while (it < NT && ir < NR) {

......

//根据优先级排序

          if (curt == null) {

                    curt = (ResolveInfo)receivers.get(it);

                }

                if (curr == null) {

                    curr = registeredReceivers.get(ir);

                }

                if (curr.getPriority() >= curt.priority) {

                    // Insert this broadcast record into the final list.

                    receivers.add(it, curr);

//获取广播队列

            BroadcastQueue queue = broadcastQueueForIntent(intent);

//创建广播任务

            BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,

                    callerPackage, callingPid, callingUid, resolvedType,

                    requiredPermission, appOp, receivers, resultTo, resultCode,

                    resultData, map, ordered, sticky, false, userId);

//加入到广播队列串行列表中

                queue.enqueueOrderedBroadcastLocked(r);

//启动异步发送任务

                queue.scheleBroadcastsLocked();

广播队列处理广播:

final void processNextBroadcast(boolean fromMsg) {

......

//并行列表,遍历广播任务

            while (mParallelBroadcasts.size() > 0) {

final int N = r.receivers.size();

//遍历接收器

                for (int i=0; i<N; i++) {

//IPC调用发送给目标进程

(r, (BroadcastFilter)target, false);

}

}

//有串行广播任务正在执行

if (mPendingBroadcast != null) {

             //接收广播的目标进程正常

                if (!isDead) {

                    // It's still alive, so keep waiting 继续等待目前进程反馈

                    return;

                }

}

             //取出第一个广播

                r = mOrderedBroadcasts.get(0);//判断是否超时,

                    if ((numReceivers > 0) && 

                            (now > r.dispatchTime + (2*mTimeoutPeriod*numReceivers))) {

                         //广播超时

                          broadcastTimeoutLocked(false);//超时处理,终止当前广播,启动下一个任务。

                          }

                if (r.receivers == null || r.nextReceiver >= numReceivers

                        || r.resultAbort || forceReceive) {

                 //所有广播任务执行完毕

}

int recIdx = r.nextReceiver++;//下一个广播接收器

r.dispatchTime = r.receiverTime;//设置派发时间

setBroadcastTimeoutLocked(timeoutTime);//启动超时计时

if (nextReceiver instanceof BroadcastFilter){//动态广播接收器

(r, filter, r.ordered);//发送

return;

}

.//静态广播

            ResolveInfo info =

                (ResolveInfo)nextReceiver;

......

//检查进程是否已启动

            ProcessRecord app = mService.getProcessRecordLocked(targetProcess,

                    info.activityInfo.applicationInfo.uid, false);

            if (app != null && app.thread != null) { /进程启动

               processCurBroadcastLocked(r, app);//发送静态广播

               return;

            }

     if ((r.curApp=mService.startProcessLocked(targetProcess,//启动进程

                    info.activityInfo.applicationInfo, true,

                    r.intent.getFlags() | Intent.FLAG_FROM_BACKGROUND,

                    "broadcast", r.curComponent,

                    (r.intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0, false, false))

                            == null) {

                      //进程启动失败

                  }

             //标志正在发送的串行广播

            mPendingBroadcast = r;

            mPendingBroadcastRecvIndex = recIdx;//正在发送的广播任务对应的接收器索引

}

3. Android App 开机自启动

<article class="_2rhmJa">

Android 设备开机自启动的可以用广播实现,因为 Android 设备开机时会发送一条开机广播 "android.intent.action.BOOT_COMPLETED"。接收后实现启动就完成了。

接下来是准备工作

如果按照上面的全部步骤后操作后,重启没有自动启动程序,怎么办呢?是怎么回事呢?

*那么首先请检查一下你的手机是不是安装了360等安全助手之类的软件,如果有,请在软件的自启动软件管理中将app设置为允许
*我的手机没有安装这些软件,但是手机中自带了安全助手,有的手机系统设置里面自带了自启动软件管理的功能 ,所以在这里将我们的app设置为允许开机启动),重启手机,测试是否成功。

然而并没有成功

接收不到BOOT_COMPLETED广播可能的原因
(1)、BOOT_COMPLETED对应的action和uses-permission没有一起添加
(2)、应用安装到了sd卡内,安装在sd卡内的应用是收不到BOOT_COMPLETED广播的
(3)、系统开启了Fast Boot模式,这种模式下系统启动并不会发送BOOT_COMPLETED广播
(4)、应用程序安装后重来没有启动过,这种情况下应用程序接收不到任何广播,包括BOOT_COMPLETED、ACTION_PACKAGE_ADDED、CONNECTIVITY_ACTION等等。
Android3.1之后,系统为了加强了安全性控制,应用程序安装后或是(设置)应用管理中被强制关闭后处于stopped状态,在这种状态下接收不到任何广播,除非广播带有FLAG_INCLUDE_STOPPED_PACKAGES标志,而默认所有系统广播都是FLAG_EXCLUDE_STOPPED_PACKAGES的,所以就没法通过系统广播自启动了。所以Android3.1之后
(1)、应用程序无法在安装后自己启动
(2)、没有ui的程序必须通过其他应用激活才能启动,如它的Activity、Service、Content Provider被其他应用调用。
存在一种例外,就是应用程序被adb push you.apk /system/app/下是会自动启动的,不处于stopped状态。

并不太懂 我的APP启动后 已经收到广播

第一种方式 我再模拟器上 测试 可以 android 9.0版本

桌面设置也会把你的app当成一个桌面主题,还有一个选项是系统桌面,你需要设置成自己的app

如果找不到桌面设置选项,可以从手机设置–应用程序-查看所有应用程序(包括系统的应用程序),找到桌面程序之类的字眼的应用,清楚其默认设置。

4. android接受不到开机广播

intent
判断
intent.getAction()是否与
android.intent.action.BOOT_COMPLETED
相同,发出的是这个,你没监听这个Action

另外注意的是,如果是
3.1以下的系统,没问题。3.1以上的系统,需要有Activity存在,并且启动一次程序,才能够实现广播。

阅读全文

与android开机广播收不到相关的资料

热点内容
如何用html5开发app 浏览:135
怎么隐藏苹果的app 浏览:320
上海積架空气压缩机 浏览:451
51单片机换行 浏览:733
哪里可以快速学看建筑图纸app 浏览:496
内部排序的算法比较 浏览:177
服务器如何定期执行指令 浏览:931
python下载python脚本 浏览:297
台达plc远程编程 浏览:263
云计算的后台服务器 浏览:589
windows7的我的电脑咋创建文件夹 浏览:492
去视频水印的app哪个好用 浏览:384
doc转为pdf 浏览:48
华为加密壁纸怎么提取 浏览:52
曲线命令的描述 浏览:454
php模板怎么修改 浏览:999
单片机和微机编程的区别 浏览:642
金牛期货哪个app好 浏览:803
程序员越老越贬值吗 浏览:211
安卓手机用计算机如何隐藏应用 浏览:459