Android 内置了很多系统级别的广播,我们可以在应用序中通过监听这些广播来得到各 种系统 的状态信息,比如手机开机完成后会发出一条广播、电池的电最发生变化会发出一条广 播、 时间或时区发生改变也会发出一条广播等。 想 要实现广播的 接 收,就需要使用广播按收者。广播 接 收者可以自由地对自己感兴 趣 的 进 行注册。当有相 应 的广播发出时,广播 接 收者 就 能够收到该广播。 并 在内部处理相应的 逻辑 ,注册广 播 的方式一般有两种 , 在代码中注册和在 Androi dMan ifest . xml 中 注 册,其中的 前者 被 称 为动态注册,后者 被 称为静态注册。下面分别通过检测电话状态(动态注册)以及应用 开 机自动 ( 静 态注册 ) 两个实例来讲解系统广播的具体 用 法。 动态注册广播实例 这 里通 过一个检测电话状态的实例来讲解如何动态 注 册广 播 。在实例中如 果 想要 接 收到 这些 电话状态的广 播就 需要使用广播接收者。实现一个广播接收者只需要新建一个 继承自 BroadcastReceiver 类的子类并重写父类的 onR e ceive () 方法就行了。这样当有广播到来时 . onRceive () 方法 就会 得到执行,具体的业务逻编只需 在 onR e ceive () 方法中处理或可以了。 下面我们通过来看实例代码,新建一个 Activity 类,动态注册广播。当然这里需要注意权限问题,读取电话状态是一个危险权限,除了要在 AndroidManifest.xml 文件中加入如下代码: 还需要动态获取相关权限,下面是 MainActivity 的代码: package com.rfstar.broadcasttest; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import android.Manifest; import android.content.Context; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.os.Build; import android.os.Bundle; import android.widget.Toast; public class MainActivity extends AppCompatActivity { private CallReceiver callReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getPermission(); } @Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(callReceiver); } private void setCallReceiver() { callReceiver=new CallReceiver(); IntentFilter filter=new IntentFilter(); filter.addAction("android.intent.action.PHONE_STATE"); filter.addAction("android.intent.action.NEW_OUTGOING_CALL"); registerReceiver(callReceiver,filter); } private void getPermission() { //判断版本号,在api23也就是6.0版本之前能直接获得权限 =23) { int checkCALLPermission= ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE); int checkOutCALLPermission=ContextCompat.checkSelfPermission(this, Manifest.permission.PROCESS_OUTGOING_CALLS); //判断是否具有权限 if(checkCALLPermission!= PackageManager.PERMISSION_GRANTED||checkOutCALLPermission!=PackageManager.PERMISSION_GRANTED) { //用以申请权限的方法,此时使用ActivityCompat类的该方法,以便于版本兼容 ActivityCompat.requestPermissions(this,new String permissions,int ==PackageManager.PERMISSION_GRANTED){ Toast.makeText(this,"获取权限成功",Toast.LENGTH_SHORT).show(); //获取权限成功,动态注册广播接收者 setCallReceiver(); }else{ Toast.makeText(this,"获取权限失败",Toast.LENGTH_SHORT).show(); } break; default: super.onRequestPermissionsResult(requestCode,permissions,grantResults); } } } 在 Activity 类中包括两部分内容 ∶ 一部分是动态获取权限,一部分是动态注册广播。这里只讲解动态注册广播。首先我们创建一个 Inten t Filt er 实例,并为其添加一个值为 android . intent . ac t ion.PHONE _ STATE 的 action 。接下来创建一个 CallReceiver 实例,然后调用 reg i sterRe cei ver () 方法进行注册,将 CallReceive r 的实例和 IntentFilter 的实例都传进去,这样 Ca l lRe c eiver 就会收到所有值为 android . intent . action.PHONE _ STATE 的广播,也就实现了监听电语状态的功能。一般情况下,动态注册的广播接收器一定要取消注册才行,取消注册通过在 onDestroy () 方法中通过调用 unregisterReceiver () 方法来实现。 新建一个继承自 BroadcastReceiver 类的 CallReceiver 类,用来获得用户拨打的电话号码以及接听、挂断等状态的变化,修改拨出的号码,加上一个 IP 拨号码,代码如下: package com.rfstar.broadcasttest; import android.app.Service; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.telephony.TelephonyManager; import android.widget.Toast; public class CallReceiver extends BroadcastReceiver { boolean flag=false; @Override public void onReceive(Context context, Intent intent) { //判断是来电还是去电 if(intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)){ //标识当前是拨出电话 flag=false; //获取当前号码 String phoneNumber=intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER); Toast.makeText(context,"电话已拨出,号码为:"+phoneNumber,Toast.LENGTH_LONG).show(); //将拨出的号码改为代码12159的号码 setResultData("12159"+phoneNumber); }else{ //此时监控来电时状态 //获取电话服务管理器 TelephonyManager TelephonyManager telephonyManager=(TelephonyManager)context.getSystemService(Service.TELEPHONY_SERVICE); switch (telephonyManager.getCallState()) { //电话处于响铃状态 case TelephonyManager.CALL_STATE_RINGING: //标识当前是来电 flag=true; //获取来电号码 String incomingPhoneNumber=intent.getStringExtra("incoming_number"); Toast.makeText(context,"来电号码:"+incomingPhoneNumber,Toast.LENGTH_LONG).show(); break; case TelephonyManager.CALL_STATE_OFFHOOK: if(flag){ Toast.makeText(context,"来电已被接通",Toast.LENGTH_LONG).show(); } break; case TelephonyManager.CALL_STATE_IDLE: if(flag){ Toast.makeText(context,"来电已被挂断",Toast.LENGTH_LONG).show(); } break; } } } } 在 onReceive () 方法中,首先通过 intent.getAction () 来判断是拨出电话还是外部来电。如果是拨出电话就获取拨出的号码,然后用 Toast 展示此号码,并使用 setResultData () 方法将此 号码 修改为带 IP 的号码进行拨号。如果是来电,就先通过 getSystemService () 方法获取 TelephonyManager 实例。这是一个系统服务类,专门用于管理通话。然后可以调用它的 g e t SystemService() 方法得到通话处于什么样状态,再根据不同的状态使用 Toast 展示不同的信息。 运行程序,按 home 键使当前程序进入后台,打开拨号界面,拨打电话,此时在界面上显示的号码就不再是拨出的号码,而是加上 "12159" 后的一个 I P 拨号号码。效果如 下 图所示 。 这里只展示了拨出电话时的效果。有关来电时的效果, 大家 可以使用上例自行测试验证 。 android studio工具及手机模拟器以及更多工程源代码下载请前往微信公众号:大鸟科创空间,回复:android studio即可获取。