Android fundamentals 07.3:Broadcast receivers


Tutorial source : Google CodeLab
Date : 2021/04/06

Complete course : 教程目录 (java).

Note : The link in this article requires Google access


1、Welcome

This practical codelab is part of Unit 3: Working in the background in the Android Developer Fundamentals (Version 2) course. You will get the most value out of this course if you work through the codelabs in sequence:

  • For the complete list of codelabs in the course, see Codelabs for Android Developer Fundamentals (V2).
  • For details about the course, including links to all the concept chapters, apps, and slides, see Android Developer Fundamentals (Version 2).

Note: This course uses the terms “codelab” and “practical” interchangeably.

Introduction

Broadcasts are messages that the Android system and Android apps send when events occur that might affect the functionality of other apps or app components. For example, the Android system sends a system broadcast when the device boots up, or when headphones are connected or disconnected. If the wired headset is unplugged, you might like your media app to pause the music.

Your Android app can also broadcast events, for example when new data is downloaded that might interest some other app. Events that your app delivers are called custom broadcasts.

In general, you can use broadcasts as a messaging system across apps and outside of the normal user flow.

A broadcast is received by any app or app component that has a broadcast receiver registered for that action. BroadcastReceiver is the base class for code that receives broadcast intents. To learn more about broadcast receivers, see the Broadcasts overview and the Intent reference.

Note: While the Intent class is used to send and receive broadcasts, the Intent broadcast mechanism is completely separate from intents that are used to start activities.

In this practical, you create an app that responds to a change in the charging state of the device. To do this, your app receives and responds to a system broadcast, and it also sends and receives a custom broadcast.

What you should already know

You should be able to:

  • Identify key parts of the AndroidManifest.xml file.
  • Create Implicit intents.

What you’ll learn

  • How to subclass a BroadcastReceiver and implement it.
  • How to register for system broadcast intents.
  • How to create and send custom broadcast intents.

What you’ll do

  • Subclass a BroadcastReceiver to show a toast when a broadcast is received.
  • Register your receiver to listen for system broadcasts.
  • Send and receive a custom broadcast intent.


2、App overview

The PowerReceiver app will register a BroadcastReceiver that displays a toast message when the device is connected or disconnected from power. The app will also send and receive a custom broadcast to display a different toast message.



3、Task 1. Set up the PowerReceiver project

1.1 Create the project

  1. In Android Studio, create a new Java project called PowerReceiver. Accept the default options and use the Empty Activity template.
  2. To create a new broadcast receiver, select the package name in the Android Project View and navigate to File > New > Other > Broadcast Receiver.
  3. Name the class CustomReceiver. Make sure that Java is selected as the source language, and that Exported and Enabled are selected. Exported allows your broadcast receiver to receive broadcasts from outside your app. Enabled allows the system to instantiate the receiver.

1.2 Register your receiver for system broadcasts

A system broadcast is a message that the Android system sends when a system event occurs. Each system broadcast is wrapped in an Intent object:

  • The intent’s action field contains event details such as android.intent.action.HEADSET_PLUG, which is sent when a wired headset is connected or disconnected.
  • The intent can contain other data about the event in its extra field, for example a boolean extra indicating whether a headset is connected or disconnected.

Apps can register to receive specific broadcasts. When the system sends a broadcast, it routes the broadcast to apps that have registered to receive that particular type of broadcast.

A BroadcastReceiver is either a static receiver or a dynamic receiver, depending on how you register it:

  • To register a receiver statically, use the <receiver> element in your AndroidManifest.xml file. Static receivers are also called manifest-declared receivers.
  • To register a receiver dynamically, use the app context or activity context. The receiver receives broadcasts as long as the registering context is valid, meaning as long as the corresponding app or activity is running. Dynamic receivers are also called context-registered receivers.

For this app, you’re interested in two system broadcasts, ACTION_POWER_CONNECTED and ACTION_POWER_DISCONNECTED. The Android system sends these broadcasts when the device’s power is connected or disconnected.

Starting from Android 8.0 (API level 26 and higher), you can’t use static receivers to receive most Android system broadcasts, with some exceptions. So for this task, you use dynamic receivers:

  1. (Optional) Navigate to your AndroidManifest.xml file. Android Studio has generated a <receiver> element, but you don’t need it, because you can’t use a static receiver to listen for power-connection system broadcasts. Delete the entire <receiver> element.
  2. In MainActivity.java, create a CustomReceiver object as a member variable and initialize it.
private CustomReceiver mReceiver = new CustomReceiver();

Create an intent filter with Intent actions

Intent filters specify the types of intents a component can receive. They are used in filtering out the intents based on Intent values like action and category.

  1. In MainActivity.java, at the end of the onCreate() method, create an IntentFilter object.
IntentFilter filter = new IntentFilter();

When the system receives an Intent as a broadcast, it searches the broadcast receivers based on the action value specified in the IntentFilter object.

  1. In MainActivity.java, at the end of onCreate(), add the actions ACTION_POWER_CONNECTED and ACTION_POWER_DISCONNECTED to the IntentFilter object.
filter.addAction(Intent.ACTION_POWER_DISCONNECTED);
filter.addAction(Intent.ACTION_POWER_CONNECTED);

Register and unregister the receiver

  1. In MainActivity.java, at the end of onCreate(), register your receiver using the MainActivity context. Your receiver is active and able to receive broadcasts as long as your MainActivity is running.
// Register the receiver using the activity context.
this.registerReceiver(mReceiver, filter);
  1. In MainActivity.java, override the onDestroy() method and unregister your receiver. To save system resources and avoid leaks, dynamic receivers must be unregistered when they are no longer needed or before the corresponding activity or app is destroyed, depending on the context used.
@Overrideprotected void onDestroy() {//Unregister the receiverthis.unregisterReceiver(mReceiver);super.onDestroy();}

1.3 Implement onReceive() in your BroadcastReceiver

When a broadcast receiver intercepts a broadcast that it’s registered for, the Intent is delivered to the receiver’s [onReceive()](https://developer.android.com/reference/android/content/BroadcastReceiver#onReceive(android.content.Context, android.content.Intent)) method.

In CustomReceiver.java, inside the onReceive() method, implement the following steps:

  1. Delete the entire onReceive() method implementation, including the UnsupportedOperationException code.
  2. Get the Intent action from the intent parameter and store it in a String variable called intentAction.
@Override
public void onReceive(Context context, Intent intent) {String intentAction = intent.getAction();
}
  1. Create a switch statement with the intentAction string. (Before using intentAction, do a null check on it.) Display a different toast message for each action your receiver is registered for.
if (intentAction != null) {String toastMessage = "unknown intent action";switch (intentAction){case Intent.ACTION_POWER_CONNECTED:toastMessage = "Power connected!";break;case Intent.ACTION_POWER_DISCONNECTED:toastMessage = "Power disconnected!";break;}//Display the toast.
}
  1. After the switch statement, add code to display a toast message for a short time:
 Toast.makeText(context, toastMessage, Toast.LENGTH_SHORT).show();
  1. Run your app. After the app is running, connect or disconnect your device’s power supply. A Toast is displayed each time you connect or disconnect the power supply, as long as your Activity is running.

Note: If you’re using an emulator, toggle the power connection state by selecting the ellipses icon for the menu. Select Battery in the left bar, then use the Charger connection setting.



4、Task 2. Send and receive a custom broadcast

In addition to responding to system broadcasts, your app can send and receive custom broadcasts. Use a custom broadcast when you want your app to take an action without launching an activity, for example when you want to let other apps know that data has been downloaded to the device.

Android provides three ways for your app to send custom broadcasts:

  • Normal broadcasts are asynchronous. Receivers of normal broadcasts run in an undefined order, often at the same time. To send a normal broadcast, create a broadcast intent and pass it to sendBroadcast(Intent).
  • Local broadcasts are sent to receivers that are in the same app as the sender. To send a local broadcast, create a broadcast intent and pass it to LocalBroadcastManager.sendBroadcast.
  • Ordered broadcasts are delivered to one receiver at a time. As each receiver executes, it can propagate a result to the next receiver, or it can cancel the broadcast so that the broadcast is not passed to other receivers. To send an ordered broadcast, create a broadcast intent and pass it to [sendOrderedBroadcast(Intent, String)](https://developer.android.com/reference/android/content/Context.html#sendOrderedBroadcast(android.content.Intent, java.lang.String)).

This practical doesn’t cover ordered broadcasts, but for more information about them, see Sending broadcasts.

The broadcast message is wrapped in an Intent object. The Intent action string must provide the app’s Java package name syntax and uniquely identify the broadcast event.

For a custom broadcast, you define your own Intent action (a unique string). You can create Intent objects with custom actions and broadcast them yourself from your app using one of the methods above. The broadcasts are received by apps that have a BroadcastReceiver registered for that action.

In this task, you add a button to your activity that sends a local broadcast intent. Your receiver registers the broadcast intent and displays the result in a toast message.

2.1 Define your custom broadcast action string

Both the sender and receiver of a custom broadcast must agree on a unique action string for the Intent being broadcast. It’s a common practice to create a unique action string by prepending your action name with your app’s package name.

One of the simplest ways to get your app’s package name is to use BuildConfig.APPLICATION_ID, which returns the applicationId property’s value from your module-level build.gradle file**.**

  1. Create a constant member variable in both your MainActivity and your CustomReceiver class. You’ll use this variable as the broadcast Intent action.
private static final String ACTION_CUSTOM_BROADCAST =
BuildConfig.APPLICATION_ID + ".ACTION_CUSTOM_BROADCAST";

Important: Although intents are used both for sending broadcasts and starting activities with startActivity(Intent), these actions are completely unrelated. Broadcast receivers can’t see or capture an Intent that’s used to start an activity. Likewise, when you broadcast an Intent, you can’t use that Intent to find or start an activity.

2.2 Add a “Send Custom Broadcast” button

  1. In your activity_main.xml layout file, replace the Hello World Textview with a Button that has the following attributes:
<Buttonandroid:id = "@+id/sendBroadcast"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="Send Custom Broadcast"android:onClick="sendCustomBroadcast"app:layout_constraintBottom_toBottomOf="parent"app:layout_constraintLeft_toLeftOf="parent"app:layout_constraintRight_toRightOf="parent"app:layout_constraintTop_toTopOf="parent" />
  1. Extract the string resource.

The sendCustomBroadcast() method will be the click-event handler for the button. To create a stub for sendCustomBroadcast() in Android Studio:

  1. Click the yellow highlighted sendCustomBroadcast method name. A red light bulb appears on the left.
  2. Click the red light bulb and select Create ‘sendCustomBroadcast(View)’ in ‘MainActivity’.

2.3 Implement sendCustomBroadcast()

Because this broadcast is meant to be used solely by your app, use LocalBroadcastManager to manage the broadcast. LocalBroadcastManager is a class that allows you to register for and send broadcasts that are of interest to components within your app.

By keeping broadcasts local, you ensure that your app data isn’t shared with other Android apps. Local broadcasts keep your information more secure and maintain system efficiency.

In MainActivity.java, inside the sendCustomBroadcast() method, implement the following steps:

  1. Create a new Intent, with your custom action string as the argument.
Intent customBroadcastIntent = new Intent(ACTION_CUSTOM_BROADCAST);
  1. After the custom Intent declaration, send the broadcast using the LocalBroadcastManager class:
LocalBroadcastManager.getInstance(this).sendBroadcast(customBroadcastIntent);

2.4 Register and unregister your custom broadcast

Registering for a local broadcast is similar to registering for a system broadcast, which you do using a dynamic receiver. For broadcasts sent using LocalBroadcastManager, static registration in the manifest is not allowed.

If you register a broadcast receiver dynamically, you must unregister the receiver when it is no longer needed. In your app, the receiver only needs to respond to the custom broadcast when the app is running, so you can register the action in onCreate() and unregister it in onDestroy().

  1. In MainActivity.java, inside onCreate() method, get an instance of LocalBroadcastManager and register your receiver with the custom Intent action:
LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver,new IntentFilter(ACTION_CUSTOM_BROADCAST));
  1. In MainActivity.java, inside the onDestroy() method, unregister your receiver from the LocalBroadcastManager:
LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver);

2.5 Respond to the custom broadcast

  1. In CustomReceiver.java, inside the onReceive() method, add another case statement in the switch block for the custom Intent action. Use "Custom Broadcast Received" as the text for the toast message.
case ACTION_CUSTOM_BROADCAST:toastMessage = "Custom Broadcast Received";break;
  1. Extract the string resource.
  2. Run your app and tap the Send Custom Broadcast button to send a custom broadcast. Your receiver (CustomReceiver) displays a toast message.

That’s it! Your app delivers a custom broadcast and is able to receive both system and custom broadcasts.



5、Solution code

Android Studio project: PowerReceiver



6、Coding challenge

Note: All coding challenges are optional and are not prerequisites for later lessons.

Challenge: If you were developing a music-player app, your app might need to play or pause music when the user connected or disconnected a wired headset. To implement this functionality, you need a broadcast receiver that responds to wired headset events. Implement a broadcast receiver that shows a toast message when a wired headset is connected or disconnected.

Hint: You need to register for the ACTION_HEADSET_PLUG action. Because this is a system broadcast action, you can’t register for it statically. Instead, register your receiver dynamically by using the context with [Context.registerReceiver()](https://developer.android.com/reference/android/content/Context.html#registerReceiver(android.content.BroadcastReceiver, android.content.IntentFilter)):

IntentFilter filter = new IntentFilter(Intent.ACTION_HEADSET_PLUG);
this.registerReceiver(mReceiver, filter);

You must also unregister the receiver when you no longer need it:

unregisterReceiver(mReceiver);


7、Summary

  • Broadcast receivers are fundamental components of an Android app.
  • Broadcast receivers can receive broadcasts sent by the system or by apps.
  • The Intent used in the broadcast mechanism is completely different from intents used to start activities.
  • To process the incoming Intent associated with a broadcast, you subclass the BroadcastReceiver class and implement onReceive().
  • You can register a broadcast receiver in the Android manifest file or programmatically.
  • Local broadcasts are private to your app. To register and send local broadcasts, use LocalBroadcastManager. Local broadcasts don’t involve interprocess communication, which makes them efficient. Using local broadcasts can also protect your app against some security issues, because data stays inside your app.
  • To create unique Intent action names for broadcasts, a common practice is to prepend the action name with your package name.
  • If your app targets API level 26 or higher, you cannot use the manifest to declare a receiver for most implicit broadcasts. (Implicit broadcasts, which include most system broadcasts, are broadcasts that don’t target your app.) A few implicit broadcasts are exceptions. However, you can use dynamic receivers to receive all broadcasts.


8、Related concept

The related concept documentation is in 7.3: Broadcasts.



9、Learn more

Android developer documentation:

  • Intents and Intent Filters
  • Broadcasts overview
  • BroadcastReceiver
  • Implicit Broadcast Exceptions


10、Homework

This section lists possible homework assignments for students who are working through this codelab as part of a course led by an instructor. It’s up to the instructor to do the following:

  • Assign homework if required.
  • Communicate to students how to submit homework assignments.
  • Grade the homework assignments.

Instructors can use these suggestions as little or as much as they want, and should feel free to assign any other homework they feel is appropriate.

If you’re working through this codelab on your own, feel free to use these homework assignments to test your knowledge.

Update an app

Extend the PowerReceiver app that you created in the practical.

  1. Send extra data to your local custom broadcast receiver. To do this, generate a random integer between 1 and 20. Add the number to the extra field of the Intent before sending the local custom broadcast.
  2. In your receiver, extract the integer data from the Intent. In the toast message, display the square of the random number.

Answer these questions

Question 1

What is a system broadcast?

  • A message that your app sends and receives when an event of interest occurs in the app.
  • A message that is sent from an app to a different component of the same app.
  • A message that the Android system sends when a system event occurs.
  • A message that the Android system receives when an event of interest occurs in your app.

Question 2

Which pair of methods do you use to register and unregister your broadcast receiver dynamically?

  • registerBroadcast() and unRegisterBroadcast().
  • registerComponentCallbacks() and unRegisterComponentCallbacks().
  • registerBroadcastReceiver() and unRegisterBroadcastReceiver().
  • registerReceiver() and unRegisterReceiver().

Question 3

Which of the following are true?

  • Broadcast receivers can’t see or capture the intents used to start an activity.
  • Using a broadcast intent, you can’t find or start an activity.
  • You can use a broadcast intent to start an activity.
  • You can receive the intent used to start activity in your broadcast receiver.

Question 4

Which class is used to mitigate the security risks of broadcast receivers when the broadcasts are not cross-application (that is, when broadcasts are sent and received by the same app)?

  • SecureBroadcast
  • LocalBroadcastManager
  • OrderedBroadcast
  • SecureBroadcastManager

Submit your app for grading

Guidance for graders

Check that the app has the following features:

  • The app generates a random integer and sends the integer as an Intent extra in the LocalBroadcast.
  • In the receiver’s onReceive() method, the random integer data is extracted from the Intent, and the integer’s square is displayed in a toast message.


11、Next codelab

To find the next practical codelab in the Android Developer Fundamentals (V2) course, see Codelabs for Android Developer Fundamentals (V2).

For an overview of the course, including links to the concept chapters, apps, and slides, see Android Developer Fundamentals (Version 2).

CodeLab:Android fundamentals 07.3:Broadcast receivers相关推荐

  1. CodeLab:Android fundamentals 04.2:Input controls

    Android fundamentals 04.2:Input controls Tutorial source : Google CodeLab Date : 2021/04/06 Complete ...

  2. CodeLab:Android fundamentals 01.3:Text and scrolling views

    Android fundamentals 01.3:Text and scrolling views Tutorial source : Google CodeLab Date : 2021/04/0 ...

  3. Android学习笔记 88. Broadcast receivers 广播接收器

    Android学习笔记 Android 开发者基础知识 (Java) -- Google Developers 培训团队 文章目录 Android学习笔记 Android 开发者基础知识 (Java) ...

  4. CodeLab:Android fundamentals04.1:Clickable images

    Android fundamentals 04.1:Clickable images Tutorial source : Google CodeLab Date : 2021/04/06 Comple ...

  5. Android 源码系列之二十通过反射解决在HuaWei手机出现Register too many Broadcast Receivers的crash

    转载请注明出处:http://blog.csdn.net/llew2011/article/details/79054457 Android开发适配问题一直是一个让人头疼的话题,由于国内很多厂商都有对 ...

  6. [车联网安全自学篇] Android安全之Broadcast Receivers攻防

    也许每个人出生的时候都以为这世界都是为他一个人而存在的,当他发现自己错的时候,他便开始长大 少走了弯路,也就错过了风景,无论如何,感谢经历 0x01 前言 1.1 Broadcast Receiver ...

  7. 安卓Hacking Part 3:Broadcast Receivers攻防

    在前两篇文章中,我们讨论了攻击Activity相关组件,内容提供商泄露和防御方法.在本期的文章中,我们将讨论攻击broadcast receivers(广播接收器). 什么是broadcast rec ...

  8. Android Fundamentals

    当然是google的说明文档最权威了,给出链接: http://developer.android.com/guide/topics/fundamentals.html 然后,是我自己的一点感悟: 1 ...

  9. 通过反射解决在HuaWei手机出现Register too many Broadcast Receivers的crash

    转载请注明出处:http://blog.csdn.net/llew2011/article/details/79054457       Android开发适配问题一直是一个让人头疼的话题,由于国内很 ...

最新文章

  1. 【机器学习-学习笔记】单/多变量线性回归、多项式回归、逻辑回归、过拟合、正则化
  2. 宁波大学计算机网络实验五,宁波大学计算机网络实验答案.doc
  3. 【计蒜客 - 蓝桥训练】炮台实验(数学期望,期望dp)
  4. jstack 脚本 自动日志_GitLab从安装到全自动化备份一条龙
  5. C++ 20 还未发布,就已凉凉?
  6. DotNetTextBox V3.0 所见即所得编辑器控件Ver3.2.5 Free(免费版)
  7. 小伯利恒之歌(音乐)-Oh Little Town of Bethlehem(Virtual Tour)一次真实的旅行,看看耶稣的家乡...
  8. android 摄像头检测工具,检摄app2.0.2最新版(摄像头检测)
  9. 单阶段和两阶段目标检测
  10. Android音视频基础知识
  11. 看完比尔盖茨30年的56条思考,我才理解他为什么能17年斩获世界首富!
  12. 【刷题篇】鹅厂文化衫问题
  13. php is_subclass_of,PHP中的is_subclass_of()函数
  14. C#中Dev配色修改
  15. 字节跳动2018校招前端面试题
  16. 经济实验室帐号与国泰安数据库地址
  17. gunicorn、uwsgi、uvicorn认识
  18. 阿里云服务器代金券如何领取?阿里云高防GPU云服务器有优惠吗?
  19. office 2016打开很抱歉此功能看似已中断并需要修复
  20. tplink软件升级有用吗_如何升级路由器的软件(固件)?

热门文章

  1. 哈工大软件构造期末复习
  2. 【汇正财经】股本组织经营管理
  3. modbus rtu通信 多级工控 plc原理图modbus代码
  4. 最新资讯:700 MHz频段在5G网络优化中的应用研究
  5. MySQL高级篇——索引失效案例
  6. 如何有效进行仓库库存管理
  7. 店铺爆款是如何打造成功的
  8. 自定义组件封装之-如何使用SwfityJSON实现JSON/Model相互转换
  9. 基于SpringBoot与iOS(Swift)的电商平台设计
  10. C#开发小游戏--飞行棋