右键程序包名->New->Other->Broadcast Receiver,输入广播接收者组件名称SmsReceiver。
组件需要重写抽象基类的onReceive()方法,代码如下:
public class SmsReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
MediaPlayer mediaPlayer = MediaPlayer.create(context,R.raw.white);
mediaPlayer.start();
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.example6_1">
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<application
.......
<receiver
android:name=".SmsReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"/>
</intent-filter>
</receiver>
</application>
</manifest>
/*
以静态注册方式(在清单文件注册),使用系统短信广播示例。
功能:接收短信广播后,自行播放音乐。
测试方法:部署到Android 6.0模拟器,运行时授权短信权限->按Home键->运行系统的短信程序,
向本机(号码为5554)随便发送一条短信后,广播接收者程序将被激活(播放音乐)。
*/
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECEIVE_SMS) != PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this,new String[]{"android.permission.RECEIVE_SMS"},1);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case 1:
if(grantResults[0]!=PackageManager.PERMISSION_GRANTED){
Toast.makeText(this, "未授权,无法实现预定的功能!", Toast.LENGTH_SHORT).show();
finish();
}
}
}
@Override
protected void onDestroy() { //按手机返回键时触发
super.onDestroy();
//创建组件对象
ComponentName receiver = new ComponentName(this,SmsReceiver.class);
//获取包管理器对象
PackageManager pm = getPackageManager();
//禁用一个静态注册的广播接收者
pm.setComponentEnabledSetting(receiver, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
}
}
/*
本短信接收者程序与手机自带的短信接收程序分别起作用
发送方的一条短信可能被分割、分多次发送
当短信广播到来时,在MainActivity里显示一个包含短信信息的Toast
*/
public class SmsReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//获取发送短信意图对象携带的数据
Bundle bundle = intent.getExtras();
if(bundle != null){
//可使用动态调试,查看短信数据结构
Object[] pdus = (Object[]) bundle.get("pdus");
//发送方的一条短信可能被分割、分多次发送
SmsMessage[] msgs = new SmsMessage[pdus.length];
for (int i = 0; i < msgs.length; i++) {
byte[] pdu = (byte[]) pdus[i];
//获取分段的短信
msgs[i]= SmsMessage.createFromPdu(pdu);
}
//构建短信相关信息字符串
StringBuilder strb=new StringBuilder();
for(SmsMessage msg:msgs){
strb.append("\n发短信人电话:\n")
.append(msg.getDisplayOriginatingAddress())
.append("\n短信内容:\n")
.append(msg.getMessageBody());
//接收时间
Date date=new Date(msg.getTimestampMillis());
SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
strb.append("\n短信接收时间:\n").append(sdf.format(date));
}
//在context指示的上下文(就是模块的MainActivity)里打Toast消息
Toast.makeText(context, strb, Toast.LENGTH_LONG).show();
}
}
}
特点:短信到来时自动产生的系统广播→激活音乐播放服务程序→活动组件程序使得停止按钮可用。
只有一个Button:id为btnStop text为Stop Music!
public class MyAudioService extends Service {
MediaPlayer mediaPlayer;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
mediaPlayer = MediaPlayer.create(this,R.raw.white);
mediaPlayer.start();
}
@Override
public void onDestroy() {
mediaPlayer.stop();
}
}
/*
由于手机允许向自身发送短信,因此,使用模拟器测试时,只需向5554发送,避免开2个模拟器。
当短信到来时,启动音乐播放服务,当前活动组件里的停止按钮可用
测试本项目,需要卸载应用(模块)example6_1,不然有干扰(两个应用都接收到了短信并处理)
*/
public class MainActivity extends AppCompatActivity {
private Button btnStop;
private boolean isCast; //是否为广播激活
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECEIVE_SMS) != PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this,new String[]{"android.permission.RECEIVE_SMS"},1);
}
btnStop=findViewById(R.id.btnStop);
Intent intent = getIntent(); //获取广播意图对象
isCast = intent.getBooleanExtra("iscast", false); //默认值为false
btnStop.setEnabled(isCast); //设置停止按钮可用和单击监听
if(isCast) Toast.makeText(this, "正在播放音乐...", Toast.LENGTH_SHORT).show();
btnStop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v){
//显式服务调用意图(非绑定式)
Intent intent=new Intent(MainActivity.this,MyAudioService.class);
//在Activity组件里,停止音乐播放服务
stopService(intent);
finish(); //销毁本活动
}
});
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case 1:
if(grantResults[0]!=PackageManager.PERMISSION_GRANTED){
Toast.makeText(this, "未授权,无法实现预定的功能!", Toast.LENGTH_SHORT).show();
finish();
}else{
Toast.makeText(this, "请发一条短信验证...", Toast.LENGTH_SHORT).show();
}
}
}
}
/*
本广播接收者程序分别调用了应用的主Activity程序和播放音乐的服务程序
*/
public class SmsReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Intent serviceIntent = new Intent(context, MyAudioService.class);
//在广播组件里,通过上下文对象启动音乐播放服务组件
context.startService(serviceIntent);
//新建调用Activity组件的意图
Intent activityIntent = new Intent(context, MainActivity.class);
activityIntent.putExtra("iscast", true); //携带数据
//新建栈用来存放被启动的Activity(当已经存在时,只做移动处理)
activityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//在广播组件里,通过上下文对象启动Activity组件
context.startActivity(activityIntent);
}
}
注意:广播接收者组件创建后,需要在清单文件里配置短信权限和广播接收者组件的意图过滤器。 【Return Top】
1个Button+1个TextView
/*
运行时动态发送广播
动态注册广播接收者:在程序里动态注册一个广播接收者,不同于在清单文件里静态注册广播接收者
发送广播时,可以携带Bundle类型的数据供广播接收者程序使用
广播发送到接收可能存在一定的延迟
抽象类BroadcastReceiver包含抽象方法onReceive()
*/
public class MainActivity extends AppCompatActivity {
private TextView tv; //用于显示接收到的广播信息
private BroadcastReceiver myReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Bundle mybundle = intent.getExtras();
String str1 = mybundle.getString("data1");
String str2 = mybundle.getString("data2");
Toast.makeText(context, str1+" " +str2,Toast.LENGTH_LONG).show();
tv.setText(str1+" " +str2);
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//使用意图过滤器类IntentFilter动态注册广播接收者
IntentFilter myintentfliter = new IntentFilter();
myintentfliter.addAction("com.example.broadcast.MY_BROADCAST");
registerReceiver(myReceiver, myintentfliter);
tv = findViewById(R.id.tv);
findViewById(R.id.btn).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
Intent myintent = new Intent("com.example.broadcast.MY_BROADCAST");
Bundle bundle = new Bundle();
bundle.putString("data1", "自定义广播与接收案例");
bundle.putString("data2", "张粤~...0v0...");
myintent.putExtras(bundle); //捆绑数据
sendBroadcast(myintent); //发送广播
try {
Thread.sleep(1000); //休眠一下,模拟广播可能存在的延迟
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
1个TextView,其id为tv,默认不显示,在单击发通知后显示
1个id为btn_notification的Button,负责发通知或取消通知
/*
通过内部类Notification.Builder来构建通知(图标、标题和内容)
(NotificationManager) getSystemService(NOTIFICATION_SERVICE)得到通知管理器对象,具有发通知和取消通知的方法
延期意图PendingIntent使得在用户单击通知标题后查看通知内容成为可能
*/
public class MainActivity extends AppCompatActivity {
NotificationManager notificationManager; //通知管理器
NotificationCompat.Builder builder; //通知构造器(与Android版本相关)
Button btn_notification; //按钮
boolean isCreate = false; //通知未创建
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btn_notification = findViewById(R.id.btn_notification);
//创建设置意图对象
Intent intent = new Intent(Settings.ACTION_SETTINGS);
//创建延期意图对象
PendingIntent pendingIntent = PendingIntent.getActivity(this,0,intent,0);
//获取通知管理器
notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
//使用通知构造器
builder = new NotificationCompat.Builder(this,getPackageName());
//构建通知内容
builder.setSmallIcon(R.drawable.notification) //图标使用矢量图形
.setContentTitle("设置")
.setContentText("点击进入设置程序")
.setWhen(System.currentTimeMillis())
.setDefaults(Notification.DEFAULT_SOUND)
.setContentIntent(pendingIntent); //关键方法
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { //Android 8.0
NotificationChannel channel = new NotificationChannel( //Android 8.0需要创建通知频道
getPackageName(),
"MusicNotify",
NotificationManager.IMPORTANCE_DEFAULT
);
notificationManager.createNotificationChannel(channel);
}
btn_notification.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
isCreate = !isCreate; //在创建与取消之间切换
TextView tv=findViewById(R.id.tv);
if(isCreate) { //如果准备创建通知
//发送通知至通知栏
notificationManager.notify(1, builder.build()); //发通知
tv.setVisibility(View.VISIBLE); //设置可见
btn_notification.setText("取消通知");
}else {
notificationManager.cancel(1); //取消通知
btn_notification.setText("创建通知");
tv.setVisibility(View.INVISIBLE); //设置不可见
}
}
});
}
}