• Android组件通信——广播机制:BroadcastReceiver(二十九)


    1. BroadcastReceiver

    1.1 知识点

    (1)掌握广播接收器的主要作用及基本实现;

    (2)可以使用广播启动Service;

    (3)理解闹钟服务的使用;

    1.2 具体内容

    广播这个名词大家并不陌生,就像电视信号一样,打开电视都可以接受到信号。广播是一种发出后不管的机制,不管接受者能否正常接受,广播发送者只管发送。在android中经常使用到广播机制,向各个应用程序发送消息。

    通过这个图我们可以明白,广播机制里面还是需要使用Activity程序,如果说想要建立广播的话,还必须准备一个广播接收器。

    1. package com.example.broadcast;
    2. import android.content.BroadcastReceiver;
    3. import android.content.Context;
    4. import android.content.Intent;
    5. import android.widget.Toast;
    6. public class MyBroadcastReceiver extends BroadcastReceiver {
    7. public MyBroadcastReceiver(){
    8. System.out.println("=======每次广播都会实例化一个新的广播组件进行操作======");
    9. }
    10. @Override
    11. public void onReceive(Context context, Intent intent) {
    12. Toast.makeText(context, "广播已经启动", Toast.LENGTH_SHORT).show();//显示信息
    13. }
    14. }

    此时一个广播组件就定义好了,那么定义好了之后,我们需要在AndroidMainfest.xml进行注册。

    1. android:name="com.example.broadcast.MyBroadcastReceiver"
    2. android:enabled="true" –启用广播
    3. >
    4. --匹配action操作是的广播
    5. "android.intent.action.EDIT"/>

    现在发现广播配置中需要配置一个节点,表示此节点对一个指定的action操作的时候才会去启用广播。现在我们可以编写Activity程序进行广播的操作。现在通过按钮的事情启动广播。

    1. "http://schemas.android.com/apk/res/android"
    2. xmlns:tools="http://schemas.android.com/tools"
    3. android:layout_width="match_parent"
    4. android:layout_height="match_parent"
    5. android:orientation="vertical">
    6. android:id="@+id/but"
    7. android:layout_width="match_parent"
    8. android:layout_height="wrap_content"
    9. android:text="开始广播"/>

    现在的广播和服务一样,都需要通过Activity程序去启动,但是大家要记住一点,广播可以根据系统的状态进行启动。

    对于广播的注册也可以由程序完成。

    1. package com.example.broadcast;
    2. import android.app.Activity;
    3. import android.content.Intent;
    4. import android.content.IntentFilter;
    5. import android.os.Bundle;
    6. import android.view.View;
    7. import android.view.View.OnClickListener;
    8. import android.widget.Button;
    9. public class BroadcastActivity extends Activity {
    10. private Button but = null;
    11. private MyBroadcastReceiver myBroadcastReceiver = null;
    12. @Override
    13. protected void onCreate(Bundle savedInstanceState) {
    14. super.onCreate(savedInstanceState);
    15. super.setContentView(R.layout.activity_broadcast);
    16. this.but = (Button) super.findViewById(R.id.but);
    17. this.but.setOnClickListener(new OnClickListener() {
    18. @Override
    19. public void onClick(View v) {
    20. Intent it = new Intent("www.wanczy.com");//启动Action
    21. it.putExtra("msg", "jjm是万策的职工");
    22. //start 通过程序去注册广播
    23. BroadcastActivity.this.myBroadcastReceiver = new MyBroadcastReceiver();
    24. IntentFilter filter = new IntentFilter("www.wanczy.com");
    25. BroadcastActivity.this.registerReceiver(BroadcastActivity.this.myBroadcastReceiver, filter);
    26. //end 以上就是广播在程序进行注册
    27. BroadcastActivity.this.sendBroadcast(it);//进行广播
    28. }
    29. });
    30. }
    31. }

    以上的广播就是手工在程序进行注册的。

    现在我们也可以对程序进行稍稍的修改,因为现在不是针对所有的Action都进收听广播,必须针对过滤的Action进行。

    建议大家以后在开发中使用配置文件的形式进行配置。

    1. package com.example.broadcast;
    2. import android.app.Service;
    3. import android.content.Intent;
    4. import android.os.IBinder;
    5. public class MyService extends Service {
    6. @Override
    7. public IBinder onBind(Intent intent) {
    8. return null;
    9. }
    10. @Override
    11. public void onCreate() {
    12. System.out.println("=========onCreate=============");
    13. super.onCreate();
    14. }
    15. @Override
    16. public void onDestroy() {
    17. System.out.println("=========onDestroy=============");
    18. super.onDestroy();
    19. }
    20. @Override
    21. public int onStartCommand(Intent intent, int flags, int startId) {
    22. System.out.println("=========onStartCommand========="+intent);
    23. return Service.START_CONTINUATION_MASK;
    24. }
    25. }

    定义Bordcast:

    1. package com.example.broadcast;
    2. import android.content.BroadcastReceiver;
    3. import android.content.Context;
    4. import android.content.Intent;
    5. import android.widget.Toast;
    6. public class MyBroadcastReceiver extends BroadcastReceiver {
    7. public MyBroadcastReceiver(){
    8. System.out.println("=======每次广播都会实例化一个新的广播组件进行操作======");
    9. }
    10. @Override
    11. public void onReceive(Context context, Intent intent) {
    12. // Toast.makeText(context, "广播已经启动,"+intent.getStringExtra("msg") , Toast.LENGTH_SHORT).show();//显示信息
    13. context.startService(new Intent(context,MyService.class));//启动Service
    14. }
    15. }

    对于广播来说,并没有太多复杂的操作,广播里面也可以不做任何的Action的过滤。我们现在对于服务来说,Activity可以启动,广播也可以启动,但是广播是可以在耨写特定的条件下启动服务的。例如手机开机的时候,或者一些特定的应用程序运行的时候才会去启动服务。

    范例:设置闹钟

    定义一个闹钟的提示类:

    1. package com.example.alarmproject;
    2. import java.text.SimpleDateFormat;
    3. import java.util.Date;
    4. import android.app.Activity;
    5. import android.app.AlertDialog;
    6. import android.content.DialogInterface;
    7. import android.os.Bundle;
    8. public class AlarmMessage extends Activity {
    9. @Override
    10. protected void onCreate(Bundle savedInstanceState) {
    11. super.onCreate(savedInstanceState);
    12. new AlertDialog.Builder(this)
    13. .setIcon(R.drawable.logo)
    14. .setTitle("闹钟时间已到")
    15. .setMessage("闹钟响起,现在时间是:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date(System.currentTimeMillis())))
    16. .setPositiveButton("关闭", new DialogInterface.OnClickListener() {
    17. @Override
    18. public void onClick(DialogInterface dialog, int which) {
    19. AlarmMessage.this.finish();
    20. }
    21. }).show();
    22. }
    23. }
    1. package com.example.alarmproject;
    2. import android.content.BroadcastReceiver;
    3. import android.content.Context;
    4. import android.content.Intent;
    5. public class MyAlarmReceive extends BroadcastReceiver {
    6. @Override
    7. public void onReceive(Context context, Intent intent) {
    8. Intent it = new Intent(context,AlarmMessage.class);
    9. it.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//传递一个新的任务标记
    10. context.startActivity(it);//启动Intent
    11. }
    12. }

    现在打开这个对话框的操作肯定是需要广播。

    1. "http://schemas.android.com/apk/res/android"
    2. xmlns:tools="http://schemas.android.com/tools"
    3. android:layout_width="match_parent"
    4. android:layout_height="match_parent"
    5. android:orientation="vertical"
    6. android:gravity="center_horizontal">
    7. android:id="@+id/time"
    8. android:layout_width="match_parent"
    9. android:layout_height="wrap_content"
    10. />
    11. android:id="@+id/msg"
    12. android:layout_width="match_parent"
    13. android:layout_height="wrap_content"
    14. android:text="当前没有设置闹钟" />
    15. android:id="@+id/set"
    16. android:layout_width="match_parent"
    17. android:layout_height="wrap_content"
    18. android:text="设置闹钟" />
    19. android:id="@+id/delete"
    20. android:layout_width="match_parent"
    21. android:layout_height="wrap_content"
    22. android:text="删除闹钟" />

    通过定义的时间选择器,选择时间设置闹钟。

    1. package com.example.alarmproject;
    2. import java.util.Calendar;
    3. import android.app.Activity;
    4. import android.app.AlarmManager;
    5. import android.app.PendingIntent;
    6. import android.content.Context;
    7. import android.content.Intent;
    8. import android.os.Bundle;
    9. import android.view.View;
    10. import android.view.View.OnClickListener;
    11. import android.widget.Button;
    12. import android.widget.TextView;
    13. import android.widget.TimePicker;
    14. import android.widget.TimePicker.OnTimeChangedListener;
    15. import android.widget.Toast;
    16. public class MyAlarmManagerActivity extends Activity {
    17. private AlarmManager alarm = null;
    18. private Button set = null;
    19. private Button delete = null;
    20. private TextView msg = null;
    21. private TimePicker time = null;
    22. private Calendar calendar = Calendar.getInstance();// 取得日历操作类
    23. private int hourOfDay = 0;// 保存我们设置的小时数
    24. private int minute = 0;// 保存分钟
    25. @Override
    26. protected void onCreate(Bundle savedInstanceState) {
    27. super.onCreate(savedInstanceState);
    28. super.setContentView(R.layout.activity_my_alarm_manager);
    29. this.time = (TimePicker) super.findViewById(R.id.time);
    30. this.set = (Button) super.findViewById(R.id.set);
    31. this.delete = (Button) super.findViewById(R.id.delete);
    32. this.msg = (TextView) super.findViewById(R.id.msg);
    33. this.alarm = (AlarmManager) super
    34. .getSystemService(Context.ALARM_SERVICE);// 取得闹钟服务
    35. this.time.setOnTimeChangedListener(new OnTimeChangedListenerImpl());
    36. this.set.setOnClickListener(new SetOnClickListenerImpl());
    37. this.delete.setOnClickListener(new DeleteOnClickListenerImpl());
    38. this.time.setIs24HourView(true);// 设置24小时制
    39. }
    40. private class OnTimeChangedListenerImpl implements OnTimeChangedListener {
    41. @Override
    42. public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
    43. MyAlarmManagerActivity.this.calendar.setTimeInMillis(System
    44. .currentTimeMillis());// 设置当前时间
    45. MyAlarmManagerActivity.this.calendar.set(Calendar.HOUR_OF_DAY,
    46. hourOfDay);
    47. MyAlarmManagerActivity.this.calendar.set(Calendar.MINUTE, minute);
    48. MyAlarmManagerActivity.this.calendar.set(Calendar.SECOND, 0);
    49. MyAlarmManagerActivity.this.calendar.set(Calendar.MILLISECOND, 0);
    50. MyAlarmManagerActivity.this.hourOfDay = hourOfDay;
    51. MyAlarmManagerActivity.this.minute = minute;
    52. }
    53. }
    54. private class SetOnClickListenerImpl implements OnClickListener {
    55. public void onClick(View v) {
    56. Intent intent = new Intent(MyAlarmManagerActivity.this,
    57. MyAlarmReceive.class);
    58. intent.setAction("www.wanczy.com");
    59. PendingIntent sender = PendingIntent.getBroadcast(
    60. MyAlarmManagerActivity.this, 0, intent,
    61. PendingIntent.FLAG_UPDATE_CURRENT);// 指定PendingIntent
    62. MyAlarmManagerActivity.this.alarm.set(AlarmManager.RTC_WAKEUP,
    63. MyAlarmManagerActivity.this.calendar.getTimeInMillis(),
    64. sender);
    65. MyAlarmManagerActivity.this.msg.setText("闹钟响起的时间是:"
    66. + MyAlarmManagerActivity.this.hourOfDay + "时"
    67. + MyAlarmManagerActivity.this.minute + "分");
    68. Toast.makeText(MyAlarmManagerActivity.this, "设置闹钟成功",
    69. Toast.LENGTH_SHORT).show();
    70. }
    71. }
    72. private class DeleteOnClickListenerImpl implements OnClickListener {
    73. public void onClick(View v) {
    74. if (null != MyAlarmManagerActivity.this.alarm) {// 只有闹钟设置之后才能取消设置
    75. Intent intent = new Intent(MyAlarmManagerActivity.this,
    76. MyAlarmReceive.class);
    77. PendingIntent sender = PendingIntent.getBroadcast(
    78. MyAlarmManagerActivity.this, 0, intent,
    79. PendingIntent.FLAG_UPDATE_CURRENT);
    80. MyAlarmManagerActivity.this.alarm.cancel(sender);//取消闹钟
    81. MyAlarmManagerActivity.this.msg.setText("当前没有设置闹钟");
    82. Toast.makeText(MyAlarmManagerActivity.this, "闹钟删除成功",
    83. Toast.LENGTH_SHORT).show();
    84. }
    85. }
    86. }
    87. }
    1. android:name="com.example.alarmproject.MyAlarmReceive"
    2. android:enabled="true"
    3. android:process=":remote"—开辟一个新的进程
    4. >
    5. "www.wanczy.com"/>

    1.3 小结

    (1)广播属于触发式操作,当有了指定操作之后会自动启动广播;

    (2)通过广播可以实现Service程序的启动;

  • 相关阅读:
    本地FTP服务器快速搭建(windows)
    Ubuntu安装mysql8遇到的问题以及详细安装过程
    嵌入式系统开发【深入浅出】 GPIO 类设备的驱动程序
    three.js高性能渲染室外场景
    接口测试用例设计方法方式和流程一文到底
    数据结构-链表
    189. 轮转数组
    测试界的飞虎队:测试人才战略——测试行业的精英战略(学习了)
    Centos GCC 版本升级
    MapStruct类型之间映射的实现
  • 原文地址:https://blog.csdn.net/weixin_41830242/article/details/133870113