转载请注明出处: 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)
,这句代码的作用是 取消注册去电广播接收器,取消注册了之后,自然也就获取不到去电号码了
再运行一下程序:
源码下载