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

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

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

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

动态注册广播实例

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

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

  1. <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
  2. <uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>

还需要动态获取相关权限,下面是MainActivity的代码:

  1. package com.rfstar.broadcasttest;
  2. import androidx.appcompat.app.AppCompatActivity;
  3. import androidx.core.app.ActivityCompat;
  4. import androidx.core.content.ContextCompat;
  5. import android.Manifest;
  6. import android.content.Context;
  7. import android.content.IntentFilter;
  8. import android.content.pm.PackageManager;
  9. import android.os.Build;
  10. import android.os.Bundle;
  11. import android.widget.Toast;
  12. public class MainActivity extends AppCompatActivity {
  13. private CallReceiver callReceiver;
  14. @Override
  15. protected void onCreate(Bundle savedInstanceState) {
  16. super.onCreate(savedInstanceState);
  17. setContentView(R.layout.activity_main);
  18. getPermission();
  19. }
  20. @Override
  21. protected void onDestroy()
  22. {
  23. super.onDestroy();
  24. unregisterReceiver(callReceiver);
  25. }
  26. private void setCallReceiver()
  27. {
  28. callReceiver=new CallReceiver();
  29. IntentFilter filter=new IntentFilter();
  30. filter.addAction("android.intent.action.PHONE_STATE");
  31. filter.addAction("android.intent.action.NEW_OUTGOING_CALL");
  32. registerReceiver(callReceiver,filter);
  33. }
  34. private void getPermission() {
  35. //判断版本号,在api23也就是6.0版本之前能直接获得权限
  36. if(Build.VERSION.SDK_INT>=23)
  37. {
  38. int checkCALLPermission= ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE);
  39. int checkOutCALLPermission=ContextCompat.checkSelfPermission(this, Manifest.permission.PROCESS_OUTGOING_CALLS);
  40. //判断是否具有权限
  41. if(checkCALLPermission!= PackageManager.PERMISSION_GRANTED||checkOutCALLPermission!=PackageManager.PERMISSION_GRANTED)
  42. {
  43. //用以申请权限的方法,此时使用ActivityCompat类的该方法,以便于版本兼容
  44. ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.READ_PHONE_STATE,
  45. Manifest.permission.PROCESS_OUTGOING_CALLS},1);
  46. return;
  47. }else{
  48. //如果已经获取了相关权限,调用initData()与initView()方法
  49. setCallReceiver();
  50. }
  51. } else{
  52. //如果api版本低于23,直接调用initData()与initView()方法
  53. setCallReceiver();
  54. }
  55. }
  56. //申请权限做出响应后的回调函数
  57. public void onRequestPermissonsResult(int requestCode,String[] permissions,int[] grantResults)
  58. {
  59. switch (requestCode)
  60. {
  61. case 1:
  62. if(grantResults[0]==PackageManager.PERMISSION_GRANTED){
  63. Toast.makeText(this,"获取权限成功",Toast.LENGTH_SHORT).show();
  64. //获取权限成功,动态注册广播接收者
  65. setCallReceiver();
  66. }else{
  67. Toast.makeText(this,"获取权限失败",Toast.LENGTH_SHORT).show();
  68. }
  69. break;
  70. default:
  71. super.onRequestPermissionsResult(requestCode,permissions,grantResults);
  72. }
  73. }
  74. }

Activity 类中包括两部分内容一部分是动态获取权限,一部分是动态注册广播。这里只讲解动态注册广播。首先我们创建一个 IntentFilter实例,并为其添加一个值为android.intent.action.PHONE_STATE action。接下来创建一个CallReceiver 实例,然后调用registerReceiver()方法进行注册,将CallReceiver的实例和 IntentFilter的实例都传进去,这样CallReceiver就会收到所有值为 android.intent.action.PHONE_STATE 的广播,也就实现了监听电语状态的功能。一般情况下,动态注册的广播接收器一定要取消注册才行,取消注册通过在

onDestroy()方法中通过调用 unregisterReceiver()方法来实现。

新建一个继承自BroadcastReceiver类的CallReceiver类,用来获得用户拨打的电话号码以及接听、挂断等状态的变化,修改拨出的号码,加上一个IP拨号码,代码如下:

  1. package com.rfstar.broadcasttest;
  2. import android.app.Service;
  3. import android.content.BroadcastReceiver;
  4. import android.content.Context;
  5. import android.content.Intent;
  6. import android.telephony.TelephonyManager;
  7. import android.widget.Toast;
  8. public class CallReceiver extends BroadcastReceiver {
  9. boolean flag=false;
  10. @Override
  11. public void onReceive(Context context, Intent intent)
  12. {
  13. //判断是来电还是去电
  14. if(intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)){
  15. //标识当前是拨出电话
  16. flag=false;
  17. //获取当前号码
  18. String phoneNumber=intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
  19. Toast.makeText(context,"电话已拨出,号码为:"+phoneNumber,Toast.LENGTH_LONG).show();
  20. //将拨出的号码改为代码12159的号码
  21. setResultData("12159"+phoneNumber);
  22. }else{
  23. //此时监控来电时状态
  24. //获取电话服务管理器 TelephonyManager
  25. TelephonyManager telephonyManager=(TelephonyManager)context.getSystemService(Service.TELEPHONY_SERVICE);
  26. switch (telephonyManager.getCallState())
  27. {
  28. //电话处于响铃状态
  29. case TelephonyManager.CALL_STATE_RINGING:
  30. //标识当前是来电
  31. flag=true;
  32. //获取来电号码
  33. String incomingPhoneNumber=intent.getStringExtra("incoming_number");
  34. Toast.makeText(context,"来电号码:"+incomingPhoneNumber,Toast.LENGTH_LONG).show();
  35. break;
  36. case TelephonyManager.CALL_STATE_OFFHOOK:
  37. if(flag){
  38. Toast.makeText(context,"来电已被接通",Toast.LENGTH_LONG).show();
  39. }
  40. break;
  41. case TelephonyManager.CALL_STATE_IDLE:
  42. if(flag){
  43. Toast.makeText(context,"来电已被挂断",Toast.LENGTH_LONG).show();
  44. }
  45. break;
  46. }
  47. }
  48. }
  49. }

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条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
30
关闭 站长推荐上一条 /3 下一条