原创 Android之动态注册广播实例

2021-12-7 13:04 1592 31 31 分类: 软件与OS 文集: android studio

Android内置了很多系统级别的广播,我们可以在应用序中通过监听这些广播来得到各种系统的状态信息,比如手机开机完成后会发出一条广播、电池的电最发生变化会发出一条广播、时间或时区发生改变也会发出一条广播等。

要实现广播的收,就需要使用广播按收者。广播收者可以自由地对自己感兴行注册。当有相的广播发出时,广播收者能够收到该广播。在内部处理相应的逻辑,注册广的方式一般有两种在代码中注册和在 AndroidManifest.xml册,其中的前者为动态注册,后者称为静态注册。下面分别通过检测电话状态(动态注册)以及应用机自动态注册两个实例来讲解系统广播的具体法。

动态注册广播实例

里通过一个检测电话状态的实例来讲解如何动态册广。在实例中如想要收到这些电话状态的广播就需要使用广播接收者。实现一个广播接收者只需要新建一个继承自BroadcastReceiver 类的子类并重写父类的 onReceive()方法就行了。这样当有广播到来时. onRceive()方法就会得到执行,具体的业务逻编只需onReceive()方法中处理或可以了。

下面我们通过来看实例代码,新建一个Activity类,动态注册广播。当然这里需要注意权限问题,读取电话状态是一个危险权限,除了要在AndroidManifest.xml文件中加入如下代码:

<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
  • <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
  • 复制代码

    还需要动态获取相关权限,下面是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版本之前能直接获得权限
  • if(Build.VERSION.SDK_INT>=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[]{Manifest.permission.READ_PHONE_STATE,
  • Manifest.permission.PROCESS_OUTGOING_CALLS},1);
  • return;
  • }else{
  • //如果已经获取了相关权限,调用initData()与initView()方法
  • setCallReceiver();
  • }
  • } else{
  • //如果api版本低于23,直接调用initData()与initView()方法
  • setCallReceiver();
  • }
  • }
  • //申请权限做出响应后的回调函数
  • public void onRequestPermissonsResult(int requestCode,String[] permissions,int[] grantResults)
  • {
  • switch (requestCode)
  • {
  • case 1:
  • if(grantResults[0]==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 类中包括两部分内容一部分是动态获取权限,一部分是动态注册广播。这里只讲解动态注册广播。首先我们创建一个 IntentFilter实例,并为其添加一个值为android.intent.action.PHONE_STATE action。接下来创建一个CallReceiver 实例,然后调用registerReceiver()方法进行注册,将CallReceiver的实例和 IntentFilter的实例都传进去,这样CallReceiver就会收到所有值为 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 实例。这是一个系统服务类,专门用于管理通话。然后可以调用它的getSystemService()方法得到通话处于什么样状态,再根据不同的状态使用Toast展示不同的信息。

    运行程序,按 home 键使当前程序进入后台,打开拨号界面,拨打电话,此时在界面上显示的号码就不再是拨出的号码,而是加上"12159"后的一个IP拨号号码。效果如图所示这里只展示了拨出电话时的效果。有关来电时的效果,大家可以使用上例自行测试验证

    android studio工具及手机模拟器以及更多工程源代码下载请前往微信公众号:大鸟科创空间,回复:android studio即可获取。

    作者: 大鸟科创空间, 来源:面包板社区

    链接: https://mbb.eet-china.com/blog/uid-me-3949041.html

    版权声明:本文为博主原创,未经本人允许,禁止转载!

    PARTNER CONTENT

    文章评论0条评论)

    登录后参与讨论
    我要评论
    0
    31
    关闭 站长推荐上一条 /3 下一条