需要源码或运行有问题请点赞关注收藏后评论区留言~~~
一、接收分钟到达广播
除了应用自身的广播,系统也会发出各式各样的广播,通过监听这些系统广播,App能够得知周围环境发生了什么变化,从而按照最新环境调整运行逻辑,分钟到达广播便是系统广播之一,每当时钟到达某分某秒,也就是跳到新的分钟时刻,系统就通过全局大喇叭播报分钟广播,App只要在运行时侦听分钟广播,即可在分钟切换之际收到广播信息。接收分钟广播可分解为以下三个步骤
1:定义一个分钟广播的接收器
2:重写活动页面的onStart方法
3:重写活动页面的onStop方法
效果如下 每过一分钟就会监听一次广播
代码如下
Java类代码
package com.example.chapter09; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Bundle; import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; import com.example.chapter09.util.DateUtil; public class SystemMinuteActivity extends AppCompatActivity { private TextView tv_minute; // 声明一个文本视图对象 private String desc = "开始侦听分钟广播,请稍等。注意要保持屏幕亮着,才能正常收到广播"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_system_minute); tv_minute = findViewById(R.id.tv_minute); tv_minute.setText(desc); } @Override protected void onStart() { super.onStart(); timeReceiver = new TimeReceiver(); // 创建一个分钟变更的广播接收器 // 创建一个意图过滤器,只处理系统分钟变化的广播 IntentFilter filter = new IntentFilter(Intent.ACTION_TIME_TICK); registerReceiver(timeReceiver, filter); // 注册接收器,注册之后才能正常接收广播 } @Override protected void onStop() { super.onStop(); unregisterReceiver(timeReceiver); // 注销接收器,注销之后就不再接收广播 } private TimeReceiver timeReceiver; // 声明一个分钟广播的接收器实例 // 定义一个分钟广播的接收器 private class TimeReceiver extends BroadcastReceiver { // 一旦接收到分钟变更的广播,马上触发接收器的onReceive方法 @Override public void onReceive(Context context, Intent intent) { if (intent != null) { desc = String.format("%s\n%s 收到一个分钟到达广播%s", desc, DateUtil.getNowTime(), intent.getAction()); tv_minute.setText(desc); } } } }
xml文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="5dp" android:orientation="vertical"> <ScrollView android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:id="@+id/tv_minute" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="@color/black" android:textSize="17sp" /> </LinearLayout> </ScrollView> </LinearLayout>
二、接收网络变更广播
除了分钟广播,网络变更广播也很常见,因为手机可能会使用不同的方式上网,比如流量或者wifi,对于不同的情况需要分别判断并且处理 接收网络变更广播可分为以下三个步骤
1:定义一个网络广播的接收器
2:重写活动页面的onStart方法
3:重写活动页面的onStop方法
效果如下
代码如下
Java类代码
package com.example.chapter09; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.net.NetworkInfo; import android.os.Bundle; import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; import com.example.chapter09.util.DateUtil; import com.example.chapter09.util.NetworkUtil; public class SystemNetworkActivity extends AppCompatActivity { private TextView tv_network; // 声明一个文本视图对象 private String desc = "开始侦听网络变更广播,请开关WLAN或者数据连接,再观察广播结果"; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_system_network); tv_network = findViewById(R.id.tv_network); tv_network.setText(desc); } @Override protected void onStart() { super.onStart(); networkReceiver = new NetworkReceiver(); // 创建一个网络变更的广播接收器 // 创建一个意图过滤器,只处理网络状态变化的广播 IntentFilter filter = new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE"); registerReceiver(networkReceiver, filter); // 注册接收器,注册之后才能正常接收广播 } @Override protected void onStop() { super.onStop(); unregisterReceiver(networkReceiver); // 注销接收器,注销之后就不再接收广播 } private NetworkReceiver networkReceiver; // 声明一个网络变更的广播接收器实例 // 定义一个网络变更的广播接收器 private class NetworkReceiver extends BroadcastReceiver { // 一旦接收到网络变更的广播,马上触发接收器的onReceive方法 @Override public void onReceive(Context context, Intent intent) { if (intent != null) { NetworkInfo networkInfo = intent.getParcelableExtra("networkInfo"); String networkClass = NetworkUtil.getNetworkClass(networkInfo.getSubtype()); desc = String.format("%s\n%s 收到一个网络变更广播,网络大类为%s," + "网络小类为%s,网络制式为%s,网络状态为%s", desc, DateUtil.getNowTime(), networkInfo.getTypeName(), networkInfo.getSubtypeName(), networkClass, networkInfo.getState().toString()); tv_network.setText(desc); } } } }
XML文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:padding="5dp" android:orientation="vertical"> <ScrollView android:layout_width="match_parent" android:layout_height="wrap_content"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:id="@+id/tv_network" android:layout_width="match_parent" android:layout_height="wrap_content" android:textColor="@color/black" android:textSize="17sp" /> </LinearLayout> </ScrollView> </LinearLayout>
三、定时管理器AlarmManager
尽管系统的分钟广播能够实现定时功能,但是太低级了,既不能定制可长可短的时间间隔,也不能限制定时广播的次数,为此Android提供了专门的定时管理器,它利用系统闹钟定时发送广播,比分钟广播拥有更强大的功能 效果如下
代码如下
Java类
package com.example.chapter09; import android.app.AlarmManager; import android.app.PendingIntent; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.Build; import android.os.Bundle; import android.os.Vibrator; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.ArrayAdapter; import android.widget.CheckBox; import android.widget.Spinner; import android.widget.TextView; import androidx.appcompat.app.AppCompatActivity; import com.example.chapter09.util.DateUtil; public class AlarmActivity extends AppCompatActivity implements View.OnClickListener { private static final String TAG = "AlarmActivity"; private CheckBox ck_repeate; public TextView tv_alarm; private int mDelay; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_alarm); ck_repeate = findViewById(R.id.ck_repeate); tv_alarm = findViewById(R.id.tv_alarm); findViewById(R.id.btn_alarm).setOnClickListener(this); initDelaySpinner(); // 初始化闹钟延迟的下拉框 } // 初始化闹钟延迟的下拉框 private void initDelaySpinner() { ArrayAdapter<String> delayAdapter = new ArrayAdapter<String>(this, R.layout.item_select, delayDescArray); Spinner sp_delay = findViewById(R.id.sp_delay); sp_delay.setPrompt("请选择闹钟延迟"); sp_delay.setAdapter(delayAdapter); sp_delay.setOnItemSelectedListener(new DelaySelectedListener()); sp_delay.setSelection(0); } private int[] delayArray = {5, 10, 15, 20, 25, 30}; private String[] delayDescArray = {"5秒", "10秒", "15秒", "20秒", "25秒", "30秒"}; class DelaySelectedListener implements OnItemSelectedListener { public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3) { mDelay = delayArray[arg2]; } public void onNothingSelected(AdapterView<?> arg0) {} } @Override public void onClick(View v) { if (v.getId() == R.id.btn_alarm) { sendAlarm(); // 发送闹钟广播 mDesc = DateUtil.getNowTime() + " 设置闹钟"; tv_alarm.setText(mDesc); } } // 发送闹钟广播 private void sendAlarm() { Intent intent = new Intent(ALARM_ACTION); // 创建一个广播事件的意图 // 创建一个用于广播的延迟意图 PendingIntent pIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); // 从系统服务中获取闹钟管理器 AlarmManager alarmMgr = (AlarmManager) getSystemService(ALARM_SERVICE); long delayTime = System.currentTimeMillis() + mDelay*1000; // 给当前时间加上若干秒 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { // 允许在空闲时发送广播,Android6.0之后新增的方法 alarmMgr.setAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, delayTime, pIntent); } else { // 设置一次性闹钟,延迟若干秒后,携带延迟意图发送闹钟广播(但Android6.0之后,set方法在暗屏时不保证发送广播,必须调用setAndAllowWhileIdle方法) alarmMgr.set(AlarmManager.RTC_WAKEUP, delayTime, pIntent); } // // 设置重复闹钟,每隔一定间隔就发送闹钟广播(但从Android4.4开始,setRepeating方法不保证按时发送广播) // alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), // mDelay*1000, pIntent); } // 声明一个闹钟广播事件的标识串 private String ALARM_ACTION = "com.example.chapter09.alarm"; private String mDesc = ""; // 闹钟时间到达的描述 // 定义一个闹钟广播的接收器 public class AlarmReceiver extends BroadcastReceiver { // 一旦接收到闹钟时间到达的广播,马上触发接收器的onReceive方法 @Override public void onReceive(Context context, Intent intent) { if (intent != null) { mDesc = String.format("%s\n%s 闹钟时间到达", mDesc, DateUtil.getNowTime()); tv_alarm.setText(mDesc); // 从系统服务中获取震动管理器 Vibrator vb = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE); vb.vibrate(500); // 命令震动器吱吱个若干秒 if (ck_repeate.isChecked()) { // 需要重复闹钟广播 sendAlarm(); // 发送闹钟广播 } } } } private AlarmReceiver alarmReceiver; // 声明一个闹钟的广播接收器 @Override public void onStart() { super.onStart(); alarmReceiver = new AlarmReceiver(); // 创建一个闹钟的广播接收器 // 创建一个意图过滤器,只处理指定事件来源的广播 IntentFilter filter = new IntentFilter(ALARM_ACTION); registerReceiver(alarmReceiver, filter); // 注册接收器,注册之后才能正常接收广播 } @Override public void onStop() { super.onStop(); unregisterReceiver(alarmReceiver); // 注销接收器,注销之后就不再接收广播 } }
XML文件
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" android:padding="5dp"> <CheckBox android:id="@+id/ck_repeate" android:layout_width="match_parent" android:layout_height="wrap_content" android:gravity="left|center" android:checked="false" android:text="是否重复闹钟广播" android:textColor="@color/black" android:textSize="17sp" /> <RelativeLayout android:layout_width="match_parent" android:layout_height="40dp"> <TextView android:id="@+id/tv_delay" android:layout_width="wrap_content" android:layout_height="match_parent" android:layout_alignParentLeft="true" android:gravity="center" android:text="闹钟延迟间隔:" android:textColor="@color/black" android:textSize="17sp" /> <Spinner android:id="@+id/sp_delay" android:layout_width="match_parent" android:layout_height="match_parent" android:layout_toRightOf="@+id/tv_delay" android:gravity="left|center" android:spinnerMode="dialog" /> </RelativeLayout> <Button android:id="@+id/btn_alarm" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="设置闹钟" android:textColor="#000000" android:textSize="17sp" /> <TextView android:id="@+id/tv_alarm" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="这里是闹钟消息" android:textColor="#000000" android:textSize="17sp" /> </LinearLayout>
创作不易 觉得有帮助请点赞关注收藏~~~