在Android里面有各式各样的广播,比如:电池的状态变化、信号的强弱状态、电话的接听和短信的接收等等,接下来将介绍系统发送、监听这些广播的机制。
1. 发送广播
可利用Intent来发送广播,创建Intent对象,将信息的内容和用于过滤的信息封装起来,共有三种发送广播的方法:
1.1 sendBroadcast()
普通广播:满足条件的接收者都会响应,但不能保证顺序。
1.2 sendOrederBroadcast()
顺序广播:接收者根据注册时设置的优先级来接收广播。
1.3 sendStickyBroadcast()
粘性广播:发送出的Intent会一直存在,之后注册的接收者匹配时,也会响应。
3种发送广播方式的区别:
1. sendBroadcast或sendStickyBroadcast发送出去的Intent,对于所有满足条件的BroadcastReceiver都会执行其onReceive方法。但若有多个满足条件的BroadcastReceiver,其执行onReceive方法的顺序是没有保证的。
2. 通过sendOrderedBroadcast方法发送出去的Intent,会根据BroadcastReceiver注册时IntentFilter设置的优先级的顺序来执行onReceive方法,相同优先级的BroadcastReceiver执行onReceive方法的顺序是没有保证的。
3. sendStickyBroadcast主要的不同是Intent在发送后会一直存在,并且在以后调用registerReceiver注册相匹配的Receiver时会把这个Intent对象直接返回给新注册的Receiver。
发送广播:
通常我们在发送广播时使用的是sendBroadcast()方法,需要注意的是,在构造Intent时必须用一个全局唯一的字符串标识其要执行的动作,通常使用应用程序包的名称,也可以采用自己定义的动作。如果要在Intent中传递其他的数据,可以用Intent的putExtra()方法。
//指定Intent对象的动作(一般为包名)
String It_Ation = "lession.example.com.androidlession529_1";
//定义Intent对象
Intent it = new Intent(It_Ation);
//使用sendBroadcast来发送广播
sendBroadcast(it);
2. 接收广播:
通过继承BroadcastReceiver类来实现广播接收:创建BroadcastReceiver类的子类,在BroadcastReceiver子类中重写onReceiver()方法。
3. 声明广播:
需把广播接收器注册到系统中,以响应对应的事件。
两种注册方法:
1. 使用代码进行注册:
非常驻型广播,随程序的生命周期存在。
//生成广播接收器
MyBroadcastReceiver receiver = new MyBroadcastReceiver();
//实例化过滤器并设置要过滤的广播
IntentFilter intentFilter = new IntentFilter("Intent_Action");
//注册广播
registerReceiver(receiver,intentFilter);
2. 在AndroidManifest.XML中配置广播:
常驻型广播:即使应用关闭,当广播过来时,也会被系统调用。
<intent-filter>
intent-filter>
receiver>
☆☆☆Android Studio实现广播的发送与接收
1.打开Android Studio,新建工程后,在activity_main.xml中,添加一个Button。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="lession.example.com.androidlession529_1.MainActivity">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:text="广播实例"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/button"
android:textColor="@android:color/holo_red_dark"
android:textSize="20sp" />
LinearLayout>
RelativeLayout>
2.新建类MyBroadcastReceiver,用于接收消息。
package lession.example.com.androidlession529_1;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class MyBroadcastReceiver extends BroadcastReceiver {
String It_Ation = "lession.example.com.androidlession529_1";
@Override
public void onReceive(Context context, Intent intent) {
String Ation = intent.getAction();
if (It_Ation.equals(Ation)){
Toast.makeText(context,"响应接收消息",Toast.LENGTH_LONG).show();
}
}
}
3.在MainActivity中,编写代码,用于发送广播。
package lession.example.com.androidlession529_1;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
String It_Ation = "lession.example.com.androidlession529_1";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
MyBroadcastReceiver myBCR = new MyBroadcastReceiver();
IntentFilter itf = new IntentFilter(It_Ation);
registerReceiver(myBCR,itf);
Button bt = (Button) findViewById(R.id.button);
bt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent it = new Intent(It_Ation);
sendBroadcast(it);
}
});
}
}
3.在AndroidManifest.xml中,注册广播。
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="lession.example.com.androidlession529_1">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
intent-filter>
activity>
<receiver android:name=".MyBroadcastReceiver">
<intent-filter>
<action android:name="lession.example.com.androidlession529_1"/>
intent-filter>
receiver>
application>
manifest>
运行结果:
4. 常见广播Action变量
对于广播来说,Action指被广播出去的动作。理论上Action可以为任何字符串,而与Android系统应用有关的Action字符串以静态字符串常量的形式定义在了Intent类中。Action包含很多种,例如呼入、呼出电话、接受短信等等,下面是Android定义好的常见的一些标准广播常量,如下表所示:
常量 | 值 | 意义 |
---|---|---|
android.intent.action.BOOT_COMPLETED | ACTION_BOOT_COMPLETED | 系统启动 |
android.intent.action.ACTION_TIME_CHANGED | ACTION_TIME_CHANGED | 时间改变 |
android.intent.action.ACTION_DATE_CHANGED | ACTION_DATE_CHANGED | 日期改变 |
android.intent.action.ACTION_TIMEZONE_CHANGED | ACTION_TIMEZONE_CHANGED | 时区改变 |
android.intent.action.ACTION_BATTERY_LOW | ACTION_BATTERY_LOW | 电量低 |
android.intent.action.ACTION_MEDIA_EJECT | ACTION_MEDIA_EJECT | 插入或拔出外部媒体 |
android.intent.action.ACTION_MEDIA_BUTTON | ACTION_MEDIA_BUTTON | 按下多媒体 |
android.intent.action.ACTION_PACKAGE_ADDED | ACTION_PACKAGE_ADDED | 添加包 |
android.intent.action.ACTION_PACKAGE_REMOVED | ACTION_PACKAGE_REMOVED | 删除包 |
android.intent.action.ACTION_POWER_CONNECTED | ACTION_POWER_CONNECTED | 插上外部电源 |
android.intent.action.ACTION_POWER_DISCONNECTED | ACTION_POWER_DISCONNECTED | 断开外部电源 |
android.provider.Telephony.SMS_RECEIVED | Telephony.SMS_RECEIVED | 接收短信 |
android.intent.action.Send | Send | 发送邮件 |
广播小实例
使用AlarmManager对象来设定闹钟
AlarmManager类负责设置和管理闹钟及提醒事件。
☆☆☆Android Studio实现闹钟
1.打开Android Studio,新建工程后,在activity_main.xml中,建立1个TextView和1个Button。
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="lession.example.com.android2019529.MainActivity">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:text="TextView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/textView"
android:textColor="@android:color/holo_red_dark"
android:textSize="20sp"
android:gravity="center" />
<Button
android:text="设置闹钟时间"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/button"
android:textColor="@android:color/background_dark"
android:textSize="20sp" />
LinearLayout>
RelativeLayout>
2.定义一个广播类,作为闹钟启动的组件,重写广播类的接收事件,确定闹钟对应的动作。
package lession.example.com.android2019529;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.media.MediaPlayer;
import android.widget.Toast;
public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if ("lession.example.com.android2019529".equals(intent.getAction())){
Toast.makeText(context,"设定的时间到了",Toast.LENGTH_LONG).show();
MediaPlayer mPlayer = MediaPlayer.create(context,R.raw.again);
mPlayer.start();
}
}
}
3.在MainActivity中,编写代码。
package lession.example.com.android2019529;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.TimePickerDialog;
import android.content.Context;
import android.content.Intent;
import android.icu.util.Calendar;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.TimePicker;
public class MainActivity extends AppCompatActivity {
private AlarmManager alarmMan;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button bt = (Button) findViewById(R.id.button);
final TextView tv = (TextView) findViewById(R.id.textView);
alarmMan = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
bt.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
int h,m;
Calendar cal = Calendar.getInstance();
h = cal.get(Calendar.HOUR_OF_DAY);
m = cal.get(Calendar.MINUTE);
TimePickerDialog tpDialog = new TimePickerDialog(MainActivity.this,
new TimePickerDialog.OnTimeSetListener() {
@Override
public void onTimeSet(TimePicker view, int hourOfDay, int minute) {
Calendar calSet = Calendar.getInstance();
calSet.set(Calendar.HOUR_OF_DAY,hourOfDay);
calSet.set(Calendar.MINUTE,minute);
tv.setText("提醒时间:"+hourOfDay+":"+minute);
Intent it = new Intent();
it.setAction("lession.example.com.android2019529");
PendingIntent pit =
PendingIntent.getBroadcast(MainActivity.this,0,it,0);
alarmMan.set(AlarmManager.RTC_WAKEUP,calSet.getTimeInMillis(),pit);
}
},h,m,true);
tpDialog.show();
}
});
}
}
4.在Manifests中注册接收器
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="lession.example.com.android2019529">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
intent-filter>
activity>
<receiver android:name=".AlarmReceiver">
<intent-filter>
<action android:name="lession.example.com.android2019529"/>
intent-filter>
receiver>
application>
manifest>