通过TelephonyManager可以监听电话的来电,占线和空闲状态,分别对应如下三个常量:
/** Device call state: No activity. */
public static final int CALL_STATE_IDLE = 0;
/** Device call state: Ringing. A new call arrived and is
* ringing or waiting. In the latter case, another call is
* already active. */
public static final int CALL_STATE_RINGING = 1;
/** Device call state: Off-hook. At least one call exists
* that is dialing, active, or on hold, and no calls are ringing
* or waiting. */
public static final int CALL_STATE_OFFHOOK = 2;
需要权限:android.permission.READ_PHONE_STATE
通过注册Action为Intent.ACTION_NEW_OUTGOING_CALL的广播接收器则可以监听播出去的电话号码.
需要权限:android.permission.PROCESS_OUTGOING_CALLS
本demo是通过后台服务监听来去电号码,并通过WindowManager来添加View显示号码在窗口中.文章末尾有demo下载.
PhoneInOutServer.java
/**
* 来去电监听服务
* Created by mChenys on 2016/8/21.
*/
public class PhoneInOutServer extends Service {
private TelephonyManager tm;//电话服务
private WindowManager wm;//窗体管理者
private OutCallReceiver receiver;//去电接收者
private View mMsgView;
/**
* 电话状态监听器
*/
private PhoneStateListener mPhoneStateListener = new PhoneStateListener() {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:// 来电铃声响起
showMsg("来电号码:"+incomingNumber);
break;
case TelephonyManager.CALL_STATE_IDLE://电话的空闲状态:挂电话、来电拒绝
//把这个View移除
if(mMsgView != null ){
wm.removeView(mMsgView);
}
break;
default:
break;
}
}
};
/**
* 去电广播接收者
*/
class OutCallReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// 这就是我们拿到的播出去的电话号码
String phone = getResultData();
showMsg("正在拨打:"+phone);
}
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
//获取电话管理服务
tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
//监听来电
tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
//实例化窗体
wm = (WindowManager) getSystemService(WINDOW_SERVICE);
//注册去电广播接收者
receiver = new OutCallReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_NEW_OUTGOING_CALL);
registerReceiver(receiver, filter);
}
@Override
public void onDestroy() {
// 取消监听来电
tm.listen(mPhoneStateListener, PhoneStateListener.LISTEN_NONE);
mPhoneStateListener = null;
//取消注册去电广播接收者
unregisterReceiver(receiver);
receiver = null;
}
/**
* 通过WindowManager 显示来电和去电信息
*
* @param msg
*/
private void showMsg(String msg) {
mMsgView = View.inflate(this, R.layout.address_show, null);
TextView textView = (TextView) mMsgView.findViewById(R.id.tv_address);
textView.setText(msg);
//设置窗体参数
WindowManager.LayoutParams wlp = new WindowManager.LayoutParams();
wlp.height = WindowManager.LayoutParams.WRAP_CONTENT;
wlp.width = WindowManager.LayoutParams.WRAP_CONTENT;
wlp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE//去掉焦点
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE//不可触摸
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;//保持屏幕亮起
wlp.format = PixelFormat.TRANSLUCENT;//透明
wlp.type = WindowManager.LayoutParams.TYPE_TOAST;//toast类型
//添加目标view到窗体显示
wm.addView(mMsgView, wlp);
}
}
address_show.xml 用于显示号码的布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center_vertical"
>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@android:drawable/ic_menu_call" />
<TextView
android:textColor="#000000"
android:id="@+id/tv_address"
android:textSize="22sp"
android:text="号码归属地"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
MainActivity.java
代码非常简单,仅仅是在onCreate中开启PhoneInOutServer 服务
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService(new Intent(this, PhoneInOutServer.class));
}
}
效果图: