Android 获取来电号码和去电号码

2019-04-13 15:42发布

转载请注明出处: http://blog.csdn.net/like_program/article/details/52662942
这篇博客将讲解 Android 如何获取来电号码和去电号码。 打开 Android Studio,新建 PhoneNumberTest 项目。 我们先实现 获取来电号码。 先修改下布局文件, activity_main.xml 代码如下: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.example.phonenumbertest.MainActivity"> <Button android:id="@+id/btn_incoming_call" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="获取来电号码"/> <Button android:id="@+id/btn_incoming_call_cancel" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="不获取来电号码"/> LinearLayout> 布局文件很简单,就是定义了两个按钮,分别用来 获取来电号码不获取来电号码。 然后,我们在 MainActivity 中实例化这两个按钮,并为它们设置按键监听。MainActivty.java 代码如下: package com.example.phonenumbertest; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.Toast; public class MainActivity extends AppCompatActivity implements View.OnClickListener { /** * 获取来电号码 */ private Button btnIncomingCall; /** * 不获取来电号码 */ private Button btnIncomingCallCancel; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 实例化控件 btnIncomingCall = (Button) findViewById(R.id.btn_incoming_call); btnIncomingCallCancel = (Button) findViewById(R.id.btn_incoming_call_cancel); // 设置按键监听 btnIncomingCall.setOnClickListener(this); btnIncomingCallCancel.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_incoming_call: Intent startIncomingService = new Intent(this, IncomingCallService.class); startService(startIncomingService); Toast.makeText(this, "获取来电号码", Toast.LENGTH_SHORT).show(); break; case R.id.btn_incoming_call_cancel: Intent stopIncomingService = new Intent(this, IncomingCallService.class); stopService(stopIncomingService); Toast.makeText(this, "不获取来电号码", Toast.LENGTH_SHORT).show(); break; } } } 然后我们新建一个 IncomingCallService.java ,继承自 Service。在这个 Service 中,我们将实现获取来电号码的逻辑。IncomingCallService.java 代码如下: package com.example.phonenumbertest; import android.app.Service; import android.content.Intent; import android.os.IBinder; import android.telephony.PhoneStateListener; import android.telephony.TelephonyManager; import android.widget.Toast; /** * 获取来电号码服务 */ public class IncomingCallService extends Service { /** * 电话服务管理器 */ private TelephonyManager telephonyManager; /** * 电话状态监听器 */ private MyPhoneStateListener myPhoneStateListener; @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); // 获取来电号码 getIncomingCall(); } @Override public void onDestroy() { super.onDestroy(); // 不获取来电号码 getIncomingCallCancel(); } /** * 获取来电号码 */ private void getIncomingCall() { // 获取电话系统服务 telephonyManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE); myPhoneStateListener = new MyPhoneStateListener(); telephonyManager.listen(myPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE); } /** * 不获取来电号码 */ private void getIncomingCallCancel() { telephonyManager.listen(myPhoneStateListener, PhoneStateListener.LISTEN_NONE); } /** * 电话状态监听器 */ class MyPhoneStateListener extends PhoneStateListener { @Override public void onCallStateChanged(int state, String incomingNumber) { super.onCallStateChanged(state, incomingNumber); switch (state) { // 如果电话铃响 case TelephonyManager.CALL_STATE_RINGING: Toast.makeText(IncomingCallService.this, "来电号码是:" + incomingNumber, Toast .LENGTH_LONG).show(); } } } } 我们可以看到,实现获取来电号码的逻辑并不复杂,在 onCreate() 方法中,我们调用了 getIncomingCall() 来获取来电号码,我们再到 getIncomingCall() 方法里看看,在 getIncomingCall() 中,我们先获取了电话系统服务(TelephonyManager),然后给电话系统服务(TelephonyManager)设置了一个监听器,这里我们设置的监听器是我们自定义的监听器,继承自 PhoneStateListener ,并且我们重写了 onCallStateChanged() 这个方法,当电话状态发生变化的时候就会回调这个方法。 注意:onCallStateChanged() 方法里有一个参数:incomingNumber 这个参数就是 来电号码,知道了这个,就好办了。 在 onCallStateChanged() 方法里,我们对当前的电话状态进行判断,如果当前的电话状态是 电话铃响 ,就弹出 Toast 提示,并把 来电号码(incomingNumber)显示出来。 还要注意一点,获取来电号码需要 READ_PHONE_STATE 权限: 以上就是获取来电号码的逻辑,我们再看下 不获取来电号码 的逻辑。在 onDestroy() 方法中,我们调用了 getIncomingCallCancel() 来 不获取来电号码,这个方法里只有一句代码,telephonyManager.listen(myPhoneStateListener, PhoneStateListener.LISTEN_NONE) ,这句代码的作用是 取消注册监听器,也就是把我们刚刚设置的电话状态监听器取消掉。这样,自然就获取不到来电号码了。 运行一下程序: 获取来电号码 不获取来电号码 实现了获取来电号码后,我们再来实现获取去电号码。 先修改布局文件,activity_main.xml 代码如下: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context="com.example.phonenumbertest.MainActivity"> ...... <Button android:id="@+id/btn_outgoing_call" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="获取去电号码"/> <Button android:id="@+id/btn_outgoing_call_cancel" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="不获取去电号码"/> LinearLayout> 在布局里,我们新增了两个按钮,分别是 获取去电号码不获取去电号码 。 然后,我们在 MainActivity 中实例化新增的两个按钮,并为它们设置按键监听。MainActivty.java 代码如下: package com.example.phonenumbertest; import android.content.Intent; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.view.View; import android.widget.Button; import android.widget.Toast; public class MainActivity extends AppCompatActivity implements View.OnClickListener { ...... /** * 获取去电号码 */ private Button btnOutgoingcall; /** * 不获取去电号码 */ private Button btnOutgoingCallCancel; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); // 实例化控件 ...... btnOutgoingcall = (Button) findViewById(R.id.btn_outgoing_call); btnOutgoingCallCancel = (Button) findViewById(R.id.btn_outgoing_call_cancel); // 设置按键监听 ...... btnOutgoingcall.setOnClickListener(this); btnOutgoingCallCancel.setOnClickListener(this); } @Override public void onClick(View v) { switch (v.getId()) { case R.id.btn_incoming_call: ...... break; case R.id.btn_incoming_call_cancel: ...... break; case R.id.btn_outgoing_call: Intent startOutgoingService = new Intent(this, OutgoingCallService.class); startService(startOutgoingService); Toast.makeText(this, "获取去电号码", Toast.LENGTH_SHORT).show(); break; case R.id.btn_outgoing_call_cancel: Intent stopOutgoingService = new Intent(this, OutgoingCallService.class); stopService(stopOutgoingService); Toast.makeText(this, "不获取去电号码", Toast.LENGTH_SHORT).show(); break; } } } 然后我们新建一个 OutgoingCallService.java ,继承自 Service。在这个 Service 中,我们将实现获取去电号码的逻辑。OutgoingCallService.java 代码如下: package com.example.phonenumbertest; import android.app.Service; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.os.IBinder; import android.widget.Toast; /** * 获取去电号码服务 */ public class OutgoingCallService extends Service { /** * 去电 Action */ private static final String OUTGOING_ACTION = "android.intent.action.NEW_OUTGOING_CALL"; /** * 去电广播接收器 */ private MyPhoneStateReceiver myPhoneStateReceiver; @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); // 获取去电号码 getOutgoingCall(); } @Override public void onDestroy() { super.onDestroy(); // 不获取去电号码 getOutgoingCallCancel(); } /** * 获取去电号码 */ private void getOutgoingCall() { IntentFilter intentFilter = new IntentFilter(); // 监听去电广播 intentFilter.addAction(OUTGOING_ACTION); myPhoneStateReceiver = new MyPhoneStateReceiver(); // 动态注册去电广播接收器 registerReceiver(myPhoneStateReceiver, intentFilter); } /** * 不获取去电号码 */ private void getOutgoingCallCancel() { // 取消注册去电广播接收器 unregisterReceiver(myPhoneStateReceiver); } /** * 监听去电广播 */ class MyPhoneStateReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { // 获取去电号码 String outgoingNumber = getResultData(); Toast.makeText(context, "去电号码是:" + outgoingNumber, Toast.LENGTH_LONG).show(); } } } 在 onCreate() 方法中,我们调用 getOutgoingCall() 来获取去电号码,我们再到 getOutgoingCall() 方法里看看,在这个方法里,我们动态注册了 去电广播接收器 ,我们注册的广播接收器 MyPhoneStateReceiver 是我们自定义的广播接收器,在 MyPhoneStateReceiver 的 onReceive() 方法中,调用了 getResultData() 方法,这个方法返回的就是 去电号码。在 intentFilter 中,添加了一个值为 android.intent.action.NEW_OUTGOING_CALL 的 Action,表示我们的 去电广播接收器 想要接收去电广播。 获取来电号码需要权限,获取去电号码也需要权限: 这样,获取去电号码的逻辑就完成了。我们再看下 不获取去电号码。在 onDestroy() 方法中,调用了 getOutgoingCallCancel() 来 不获取去电号码,再到 getOutgoingCallCancel() 方法里看看,只有一句代码,unregisterReceiver(myPhoneStateReceiver),这句代码的作用是 取消注册去电广播接收器,取消注册了之后,自然也就获取不到去电号码了 再运行一下程序: 获取去电号码 不获取去电号码 源码下载