1.认识广播
1、建立广播接收器(类)MyBroadcastReceiver并继承BroadcastReceiver
public class MyBroadcastReceiver extends BroadcastReceiver {
public MyBroadcastReceiver(){
Log.d("jian", "MyBroadcastReceiver: 每次广播都会实例化的一个新的广播组件");
}
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "广播已经启动", Toast.LENGTH_SHORT).show();
}
}
2、Manifest中注册广播
<receiver android:name=".MyBroadcastReceiver" android:enabled="true">
<intent-filter>
<action android:name="android.intent.action.EDIT"/>//自己指定的action
</intent-filter>
</receiver>
在配置广播中,配置一个intent-filter节点,表示对一个指定的action操作的时候才会启动广播,这个action可以通过intent完成
3、activity文件
public class MainActivity extends AppCompatActivity {
private Button butStartBroad=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
butStartBroad=findViewById(R.id.butStartBroad);
butStartBroad.setOnClickListener(new OnClickListenerImpl());
}
private class OnClickListenerImpl implements View.OnClickListener{
@Override
public void onClick(View v) {
Intent intent=new Intent(Intent.ACTION_EDIT);//操作的过滤
MainActivity.this.sendBroadcast(intent);//广播和服务一样,都是通过Activity程序启动,但是广播可以自动根据系统的状态启动
Log.d("jian", "onClick: ----");
}
}
}
结果,并未实现,感觉是权限问题。
2.手工注册广播
1、建立广播接收器(类)MyBroadcastReceiver并继承BroadcastReceiver
public class MyBroadcastReceiver extends BroadcastReceiver {
public MyBroadcastReceiver(){
Log.d("jian", "MyBroadcastReceiver: 每次广播都会实例化的一个新的广播组件");
}
@Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "广播已经启动", Toast.LENGTH_SHORT).show();
}
}
2、Manifest中注册广播
<receiver android:name=".MyBroadcastReceiver"
android:enabled="true">
<intent-filter>
<action android:name="com.fengray.TEST"/>//自定义的过滤器
</intent-filter>
</receiver>
3、主activity文件
public class MainActivity extends AppCompatActivity {
private Button butStartBroad=null;
private MyBroadcastReceiver broadcastReceiver=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
butStartBroad=findViewById(R.id.butStartBroad);
butStartBroad.setOnClickListener(new OnClickListenerImpl());
}
private class OnClickListenerImpl implements View.OnClickListener{
@Override
public void onClick(View v) {
Intent intent=new Intent("com.fengray.TEST");//操作的过滤
intent.putExtra("msg","com.fengray.TEST");//传递附加信息
IntentFilter filter=new IntentFilter("com.fengray.TEST");//以自定义方式创建filter过滤器
//注册广播
broadcastReceiver=new MyBroadcastReceiver();
registerReceiver(broadcastReceiver,filter);
MainActivity.this.sendBroadcast(intent);//广播和服务一样,都是通过Activity程序启动,但是广播可以自动根据系统的状态启动
}
}
}
结果
2020-03-19 22:29:55.460 11950-11950/com.fengray.myex018broadcast D/jian: MyBroadcastReceiver: 每次广播都会实例化的一个新的广播组件
2020-03-19 22:29:55.465 11950-11950/com.fengray.myex018broadcast D/jian: onReceive:
3.过滤器改进
上例的基础上
1、建立广播接收器(类)MyBroadcastReceiver并继承BroadcastReceiver
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if ("com.fengray.TEST".equals(intent.getAction())){
String msg=intent.getStringExtra("msg");
Log.d("jian", msg);
Toast.makeText(context, "广播已经启动"+msg, Toast.LENGTH_SHORT).show();
}
}
}
结果:
2020-03-19 22:32:32.223 12072-12072/com.fengray.myex018broadcast D/jian: com.fengray.TEST
4.通过BroadCast启动Service
通过activity启动广播,通过广播在启动service
1、manifest文件
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.fengray.myex018broadcast">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
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" android:enabled="true">
<intent-filter>
<action android:name="com.fengray.TEST"/>
</intent-filter>
</receiver>
<service android:name=".MyService"/>
</application>
</manifest>
2、创建广播接收类
public class MyBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.d("jian", "onReceiveBroadcast: -----");
//通过广播启动了service
context.startService(new Intent(context,MyService.class));
}
}
3、创建服务类
public class MyService extends Service {
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
Log.d("jian", "service onCreate: ------");
super.onCreate();
}
@SuppressLint("WrongConstant")
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("jian", "onStartCommand: ------");
return Service.START_CONTINUATION_MASK;
}
@Override
public void onDestroy() {
Log.d("jian", "service onDestroy: ------");
super.onDestroy();
}
}
4、activity文件
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent=new Intent("com.fengray.TEST");//操作的过滤
//注册广播
sendBroadcast(intent);//广播和服务一样,都是通过Activity程序启动,但是广播可以自动根据系统的状态启动
}
@Override
protected void onStop() {
//注销广播
super.onStop();
}
}
结果:
未能显示,不知道原因,大概率同第一个例子
改成手动注册,则可以成功
主activity文件改为:
public class MainActivity extends AppCompatActivity {
private BroadcastReceiver broadcastReceiver=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent=new Intent("com.fengray.TEST");//操作的过滤
intent.putExtra("msg","com.fengray.TEST");//传递附加信息
IntentFilter filter=new IntentFilter("com.fengray.TEST");//以自定义方式创建filter过滤器
//注册广播
broadcastReceiver=new MyBroadcastReceiver();
registerReceiver(broadcastReceiver,filter);
MainActivity.this.sendBroadcast(intent);//广播和服务一样,都是通过Activity程序启动,但是广播可以自动根据系统的状态启动
//注册广播
sendBroadcast(intent);//广播和服务一样,都是通过Activity程序启动,但是广播可以自动根据系统的状态启动
}
@Override
protected void onStop() {
//注销广播
super.onStop();
}
}
结果:
2020-03-19 23:07:53.527 13160-13160/com.fengray.myex018broadcast D/jian: onReceiveBroadcast: -----
2020-03-19 23:07:53.529 13160-13160/com.fengray.myex018broadcast D/jian: onReceiveBroadcast: -----
2020-03-19 23:07:54.207 13160-13160/com.fengray.myex018broadcast D/jian: service onCreate: ------
2020-03-19 23:07:54.207 13160-13160/com.fengray.myex018broadcast D/jian: onStartCommand: ------
2020-03-19 23:07:54.218 13160-13160/com.fengray.myex018broadcast D/jian: onStartCommand: ------
但时间久后为关闭程序
5.一个通过broadcast的闹钟的案例
1、布局文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TimePicker
android:id="@+id/time"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/msg"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="当前没有设置闹钟"/>
<Button
android:id="@+id/butset"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="设置闹钟"/>
<Button
android:id="@+id/butdelet"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="删除闹钟"/>
</LinearLayout>
2、设置一个AarmMessage类
public class AlarmMessage extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new AlertDialog.Builder(this)
.setIcon(R.drawable.dress01)
.setTitle("时间已经到")
.setMessage("闹钟响了,现在时间:"+new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒").format(new Date()))
.setPositiveButton("关闭", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
}).show();
}
}
3、设置一个BroadcastReveiver类
public class MyAlarmReveiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Intent it=new Intent(context,AlarmMessage.class);
it.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startService(it);
}
}
4、activity文件
public class MainActivity extends AppCompatActivity {
private AlarmManager alarmManager=null;
private Button butset,butdelet;
private TextView msg;
private TimePicker timePicker=null;
private int hourOfDay,minute;
private Calendar calendar=Calendar.getInstance();//返回值是长整形
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
butset=findViewById(R.id.butset);
butdelet=findViewById(R.id.butdelet);
msg=findViewById(R.id.msg);
timePicker=findViewById(R.id.time);
alarmManager= (AlarmManager) getSystemService(Context.ALARM_SERVICE);
butset.setOnClickListener(new SetterOnclickListenerImpl());
butdelet.setOnClickListener(new DeleterOnclickListenerImpl());
timePicker.setIs24HourView(true);
timePicker.setOnTimeChangedListener(new OnTimeChangeListenerImpl());
}
private class OnTimeChangeListenerImpl implements TimePicker.OnTimeChangedListener{
@Override
public void onTimeChanged(TimePicker view, int hourOfDay, int minute) {
MainActivity.this.calendar.setTimeInMillis(System.currentTimeMillis());
MainActivity.this.calendar.set(Calendar.HOUR_OF_DAY,hourOfDay);
MainActivity.this.calendar.set(Calendar.MINUTE,minute);
MainActivity.this.calendar.set(Calendar.SECOND,0);
MainActivity.this.hourOfDay=hourOfDay;
MainActivity.this.minute=minute;
}
}
private class SetterOnclickListenerImpl implements View.OnClickListener{
@Override
public void onClick(View v) {
Intent intent=new Intent(MainActivity.this,MyAlarmReveiver.class);
intent.setAction("com.fengray.action.setalarm");
PendingIntent sender=PendingIntent.getBroadcast(MainActivity.this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.set(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(),sender);
msg.setText("闹钟响起的时间是:"+hourOfDay+"时"+minute+"分");
Toast.makeText(MainActivity.this, "闹钟设置成功", Toast.LENGTH_SHORT).show();
}
}
private class DeleterOnclickListenerImpl implements View.OnClickListener{
@Override
public void onClick(View v) {
if (alarmManager!=null){
Intent intent=new Intent(MainActivity.this,MyAlarmReveiver.class);
intent.setAction("com.fengray.action.setalarm");
PendingIntent sender=PendingIntent.getBroadcast(MainActivity.this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.cancel(sender);//取消intent
msg.setText("当前没有设置闹钟");
Toast.makeText(MainActivity.this, "闹钟删除成功", Toast.LENGTH_SHORT).show();
}
}
}
}
结果: