Android入门第48天-静态BroadCast之接受开机广播

news/2024/9/21 15:45:14

简介

我们在之前的BroadCast章节中写了动态BroadCast。但我们提过一笔BroadCast也有静态之分,而静态的BroadCast主要用于监听一些如:开机广播、SIM卡拨出插入等广播。这些广播都为静态注册广播事件。因此我们今天就以一个App监听Android开机广播为例子说明静态广播的使用方法以及如何收听开机广播。

课程目标

  1. 进一步使用Android Stduio如何模拟开机、关机;
  2. 了解AVD的冷启动、快速启动模式;
  3. 静态广播的写法;
  4. 开机广播的处理以及相应的权限-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监听到时才要去做的一些事

请自己动一下手吧。

 

 

 

 

 

 


http://lihuaxi.xjx100.cn/news/407283.html

相关文章

时序数据库 DolphinDB 线程简介

本文基于 DolphinDB server 最新版 2.00.X&#xff0c;从任务管理、存储引擎、流数据、集群管理、高可用几个方面&#xff0c;为大家简单介绍 DolphinDB 在运行中可能使用到的各种线程&#xff0c;及其相关的配置项和函数&#xff0c;以便用户掌握 DolphinDB 的线程运行情况。 …

计算机而网络——轮询访问访问介质控制

信道划分介质访问协议 信道划分介质访问控制协议&#xff08;Mac&#xff09; 基于多路复用的技术划分资源&#xff08;分时&#xff0c;分频&#xff0c;分码片&#xff09; 网络负载重&#xff1a;共享信道效率高&#xff0c;且公平 网络负载轻&#xff1a;共享信道效率低 随…

【relativistic GAN :细节注入】

Pansharpening approach via two-stream detail injection based on relativistic generative adversarial networks &#xff08;基于相对论生成对抗网络的双流细节注入全色锐化方法&#xff09; 全色锐化技术的目标是从低空间分辨率的多光谱图像&#xff08;MS&#xff09;和…

【20221215】【每日一题】爬楼梯进阶(ACM模式)

在爬楼梯的基础上&#xff0c;改为一次可以爬1阶、2阶、...一直到m阶&#xff0c;问一共有多少种办法爬到楼顶&#xff1f; 思路&#xff1a;这是一个完全背包问题&#xff0c;因为爬完一阶后&#xff0c;还可以再爬一阶&#xff0c;可以重复取&#xff1b; 动规五部曲 1、dp…

Typescript TSConfig

"references": [{ "path": "modules/xxxx" },{ "path": "modules/xxx" },],reference 可以提高构建速度"compilerOptions": {"paths": {"xx": ["modules/xxx/src/core/main/ts/xx/Main&…

Python作业题:组合数据类型(带有答案和详细分析过程)

文章目录本次作业涉及到的知识点作业内容本次作业涉及到的知识点 获取变量地址的id函数&#xff08;1Python列表的浅复制和深复制&#xff08;1字符串join函数的使用&#xff08;2列表的遍历&#xff08;3列表元素的排序&#xff08;4列表的常用方法&#xff08;5 作业内容 …

PHP+Laravel框架RabbitMQ简单使用

RabbitMQ安装教程请转到&#xff1a;RabbitMQ安装教程&#xff08;超详细&#xff09; 1、创建生产者 在app/Http/Controllers里创建一个php控制器文件&#xff0c; namespace App\Http\Controllers;use App\Http\Controllers\Controller; //引入amqp扩展 use PhpAmqpLib\Co…

NLP之文本分类模型调优(模型基于tensorflow1.14)

项目链接&#xff1a;https://pan.baidu.com/s/1yOu0DogWkL8WOJksJmeiPw?pwd4bsg 提取码: 4bsg 复制这段内容后打开百度网盘手机App&#xff0c;操作更方便哦 --来自百度网盘超级会员v4的分享 1.基于上一篇文章中的文本分类项目进行精度调优&#xff0c;提升模型准确率&…