1. 自定义广播接收器 MyBroadcastReceiver.java
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "接收到我们自定义的广播", Toast.LENGTH_LONG).show();
}
}
Code language: JavaScript (javascript)
2. AndroidManifest.xml 注册接收器(清单文件)
在 <application> 标签内添加:
<receiver
android:name=".MyBroadcastReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="com.foxdevelop.www.broadcastdemo.MY_BROADCAST" />
</intent-filter>
</receiver>
Code language: HTML, XML (xml)
关键点:
action的名字,后面发送广播时的Intent字符串必须和这里完全一致
3. activity_main.xml 布局(按钮)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/btn_send"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="发送广播"/>
</LinearLayout>
Code language: HTML, XML (xml)
4. MainActivity.java 主Activity(按钮点击发送广播)
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button = findViewById(R.id.btn_send);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
// action字符串必须和Manifest里的action完全相同
Intent intent = new Intent("cn.bamn.www.broadcastdemo.MY_BROADCAST");
sendBroadcast(intent);
}
});
}
}
Code language: JavaScript (javascript)
标准广播 vs 有序广播
- 标准广播 sendBroadcast() 异步广播,所有接收器几乎同时收到,无序、不可截断。
- 有序广播 sendOrderedBroadcast() 按优先级依次接收广播,前面接收器可以
abortBroadcast()终止广播,后面接收器收不到。
图片里的报错:Activity class ...MainActivity does not exist
报错含义:系统找不到MainActivity这个类
常见原因
- AndroidManifest.xml 中Activity的
android:name路径写错(最常见)- 包名和类名不匹配,大小写错误
- 写法错误:
android:name=".MainActivity",.代表当前application包名下 - 校验方法:在IDE里按住Ctrl点击类名,能跳转到MainActivity类,代表路径正确
- 包名不一致:build.gradle里applicationId 和清单里package名字不匹配
- 类文件丢失:MainActivity.java被删除/文件名写错(Java类名必须和文件名一模一样,区分大小写)
- 编译问题:项目编译失败,class没有生成;清理项目重建(Build -> Clean Project)
- 大小写问题:
Mainactivity和MainActivity是两个不同类,Android区分大小写
简单排查步骤
- 打开 AndroidManifest.xml,找到启动的Activity节点
<activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> - 按住Ctrl点击
.MainActivity,看能不能跳转代码 - 不能跳转 → 修改
android:name为正确完整类名 - 能跳转 → 执行
Clean Project,重新构建、重新安装apk
补充:高版本Android(API26+)注意:静态注册隐式广播有很多限制,很多系统隐式广播不允许静态注册,但是自定义的action隐式广播不受这个限制,可以正常使用,本案例可以直接跑。
Previous: 静态注册的方式实现开机提示
Next: Android 跨应用接收广播