Android入门第48天-静态BroadCast之接受开机广播
简介
我们在之前的BroadCast章节中写了动态BroadCast。但我们提过一笔BroadCast也有静态之分,而静态的BroadCast主要用于监听一些如:开机广播、SIM卡拨出插入等广播。这些广播都为静态注册广播事件。因此我们今天就以一个App监听Android开机广播为例子说明静态广播的使用方法以及如何收听开机广播。
课程目标
- 进一步使用Android Stduio如何模拟开机、关机;
- 了解AVD的冷启动、快速启动模式;
- 静态广播的写法;
- 开机广播的处理以及相应的权限-permission;
网上几乎所有的例子都没有讲清这个开机广播,Android的开机广播事件叫“android.intent.action.BOOT_COMPLETED”,为了Receive它你必须在全局的AndroidManifest里加入至少以下两个Permission。
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK"/>
同时,你不能只是简单按下Android Studio模拟器里的这个按钮
开始课程
设计一个静态Receiver
我们设计一个自己的Receiver。
<receiver
android:name="org.mk.android.demoreceivebootcomplete.BootCompleteReceiver"
android:enabled="true"
android:exported="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
把这段xml放置于AndroidManifest.xml文件中并且设置相应的uses:permission,全设完后的AndroidManifest.xml文件如下
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.DISABLE_KEYGUARD"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.DemoReceiveBootComplete"
tools:targetApi="31">
<receiver
android:name="org.mk.android.demoreceivebootcomplete.BootCompleteReceiver"
android:enabled="true"
android:exported="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.app.lib_name"
android:value="" />
</activity>
</application>
</manifest>
此处和网上到处乱抄甚至机器翻译的混乱的知识库有3处区别:
- 区别1:我们在uses:permission还要加入android.permission.WAKE_LOCK;
- 区别2:在receiver中需要指定全包路径而不是.BootCompleteReceiver这样的简写;
- 区别3:在receiver标签内还需要设android:permission;
下面来书写BootCompleteReceiver类
BootCompleteReceiver类
package org.mk.android.demoreceivebootcomplete;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.util.Log;
import android.view.WindowManager;
public class BootCompleteReceiver extends BroadcastReceiver {
public final static String TAG="mytag";
@Override
public void onReceive(Context context, Intent intent) {
Log.i(TAG,">>>>>>receive broadcast"+intent.getAction());
}
}
非常简单,只要监听到了手机开机,它就会打印一条LOG。
activiti_main.xml
Android Studio在new->empty activity时默认的hello world
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
MainActivity.java
Android Studio在new->empty activity时默认的hello world
package org.mk.android.demoreceivebootcomplete;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
如何运行看效果
网上又是一堆错的。
第一步操作:设置AVD高级模式
按照下图:
第二步操作:设置app开机模式为Cold boot模式
然后在下拉出的“Show Advanced Settings”里
把默认启动方式如果是“Quick boot”,那么请把它改成“Cold boot”。因为Quick boot是自动记录上一次手机的运行状态,它不能模拟真机的开关机。这个BOOT_COMPLETE事件就是在真正的关机开机时才发生的,举例来说,我长按着Android手机的顶部按钮10秒后卡断电源这样的关机后再开机才能触发这个BOOT_COMPLETE事件,而且只能触发一次。
如果只是短按一下手机顶部按钮->黑屏->再短按一下手机顶部按钮->亮屏,这种叫Quick boot,这种是不能触发BOOT_COMPLETE事件的。
因此网上的教程都没有说透这一个点,导致我们的初学者不知道配了多少个uses:permission、试了无数次就是无法触发这个BOOT_COMPLETE事件并浪费了大量的时间只为了触发一下这个事件的效果。
第三步操作:在AVD“已启动”模式下进行强制关机开机
你可以先把应用连同AVD先启动起来如下图,以下这样的状态就是AVD已启动模式。
用鼠标长按“开关”按钮直到出现以下第二个界面
点Restart按钮,出现以下界面
然后你要等一会,大概在15-30秒不等,然后你会得到这样的界面
最后在这个过渡界面再过2-3秒后,Android充分开机后你就可以收到以下这条消息了。
这就是Android真正的“开机收到开机广播”,网上教程统统没说清。每次你要触发这个“开机”事件,你可以每次在AVD已启动情况下点【Restart】按钮,这样才能每次触发和验证你要在开机事件被你安装在手机的APP监听到时才要去做的一些事
请自己动一下手吧。
相关文章
- “十四五”国家信息化规划:2025年5G普及率达56%
- 九州云Edge MEP作为典型产品入选《中国边缘云研究》报告
- 互联网时代,谁最懂你?
- 2022年人工智能在医疗领域的十大应用场景
- 5G将成经济增长新引擎
- VMware引领现代化安全,从开发到生产为现代应用保驾护航
- LoRaWAN成为国际标准 为LoRa发展注入新动能
- 云服务之PaaS:它有几种类型,有什么区别?
- 中国累计建成开通5G基站超过139万个
- 5G网络建设快速推进 5G应用“扬帆远航”
- 虚拟运营商为什么要给予隐私保护?
- 5G赋能工业互联网“百花齐放”
- 锐捷云桌面荣获福州工业企业优秀创新产品奖
- 盘点2021年5G十大动向:有覆盖、有应用、有未来
- 云服务之PaaS:PaaS怎么帮助企业走向云
- 揭秘:越来越多人关停5G网络,到底是因为什么原因呢?
- 各大考试都是如何防考生作弊的?
- Aruba推出全新EdgeConnect Microbranch解决方案 助力现代化混合办公体验
- 数据时代,瑞数信息5招助力运营商构筑应用数据安全防线
- 5G消息:关键在于如何分钱