获取来电号码,要引入两个包:
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
清单文件中加两个权限:
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
1,开启一个Service,后台监听
在oncreate()中:
mTelManager = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
mListener = new PhoneCallListener();
mTelManager.listen(mListener, PhoneStateListener.LISTEN_CALL_STATE);
mWindowManager = (WindowManager) getApplicationContext().getSystemService(WINDOW_SERVICE);
// TODO 设置悬浮框的位置 和 属性
mParams = new WindowManager.LayoutParams();
// TODO 小米系统用这个type 悬浮框不出来
//mParams.type = WindowManager.LayoutParams.TYPE_SYSTEM_ALERT;// 系统提示window
mParams.type = WindowManager.LayoutParams.TYPE_TOAST;
mParams.format = PixelFormat.TRANSLUCENT;// 支持透明
//mParams.format = PixelFormat.RGBA_8888;
mParams.flags |= WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;// 焦点
mParams.width = ViewGroup.LayoutParams.WRAP_CONTENT;//窗口的宽和高
mParams.height = ViewGroup.LayoutParams.WRAP_CONTENT;
mParams.gravity = Gravity.TOP + Gravity.LEFT;
// TODO 查询最后滑动的位置,记录之前的位置
int x = mPreferenceUtil.getInt(SHOW_CONTACT_X, 0);
int y = mPreferenceUtil.getInt(SHOW_CONTACT_Y, 0);
if (x != 0 || y != 0){
mParams.x = x;
mParams.y = y;
Log.d("CommonService",mParams.x +" old "+ mParams.y);
}else{
mParams.x = 30;//窗口位置的偏移量
mParams.y = 30;
Log.d("CommonService",mParams.x +" default "+ mParams.y);
}
//mParams.alpha = 0.1f;//窗口的透明度
Log.d("CommonService","onCreate");
2,来电的监听:
// 监听通话状态
public class PhoneCallListener extends PhoneStateListener{
@Override
public void onCallStateChanged(int state, String incomingNumber) {
// TODO Auto-generated method stub
switch (state) {
/*判断手机目前是待机状态*/
case TelephonyManager.CALL_STATE_IDLE:
<span style="white-space:pre"> </span>// 挂掉电话后,发送消息,悬浮框消失
mHandler.sendEmptyMessage(CALL_SHOW_CONTACT_CANCEL);
break;
/*判断状态为通话中*/
case TelephonyManager.CALL_STATE_OFFHOOK:
break;
/*判断状态为来电*/
case TelephonyManager.CALL_STATE_RINGING:
if (StringUtil.isEmpty(incomingNumber)) {
return;
}
<span style="white-space:pre"> </span> // 发送消息去显示悬浮框
Message message = Message.obtain();
message.what = CALL_SHOW_CONTACT_DISPLAY;
message.obj = incomingNumber;
mHandler.sendMessage(message);
Log.d("CommonService",incomingNumber);
break;
}
super.onCallStateChanged(state, incomingNumber);
}
}
/**
* 显示悬浮框
* @param phone
*/
private void showCallView(String phone){
try {
mUid = mPreferenceUtil.getString(PreferenceUtil.CLIENT_USEID, "-1");
List<String> contact = mCloudDBOperation.findOneContact(mUid,PhoneNumberUtils.cutPlus86Formatter(phone));
Log.d("CommonService",contact.toString());
if (contact.size() > 0){
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
mContactInfoView = inflater.inflate(R.layout.show_contact_layout, null);
TextView contactPhone = (TextView) mContactInfoView.findViewById(R.id.show_tv_contact);
contactPhone.setText(contact.get(1));
TextView contactGroup = (TextView) mContactInfoView.findViewById(R.id.show_tv_group);
contactGroup.setText(contact.get(0));
// TODO 监听滑动的位置
mContactInfoView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View paramView, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
mShowContactX = (int) event.getRawX();
mShowContactY = (int) event.getRawY();
break;
case MotionEvent.ACTION_MOVE:
float newX = event.getRawX();
float newY = event.getRawY();
float dX = newX - mShowContactX;
float dY = newY - mShowContactY;
mParams.x += dX;
mParams.y += dY;
//left
if (mParams.x < 0) {
mParams.x = 0;
}
//top
if (mParams.y < 0) {
mParams.y = 0;
}
//right
if (mParams.x > mWindowManager.getDefaultDisplay().getWidth() - mContactInfoView.getWidth()) {
mParams.x = mWindowManager.getDefaultDisplay().getWidth() - mContactInfoView.getWidth();
}
//bottom
if (mParams.y > mWindowManager.getDefaultDisplay().getHeight() - mContactInfoView.getHeight()) {
mParams.y = mWindowManager.getDefaultDisplay().getHeight() - mContactInfoView.getHeight();
}
mWindowManager.updateViewLayout(mContactInfoView, mParams);
//update start position
mShowContactX = event.getRawX();
mShowContactY = event.getRawY();
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}
});
<span style="white-space:pre"> </span>// 添加悬浮框到手机窗口中
mWindowManager.addView(mContactInfoView,mParams);
}
}catch (Exception e){
e.printStackTrace();
}
}
4,悬浮框消失:
if (mContactInfoView != null){
mWindowManager.removeViewImmediate(mContactInfoView);
mContactInfoView = null;
mPreferenceUtil.save(SHOW_CONTACT_X,mParams.x);
mPreferenceUtil.save(SHOW_CONTACT_Y,mParams.y);
Log.d("CommonService",mParams.x +" save "+ mParams.y);
}
记住,让悬浮框消失时,一定要把悬浮框的View置为null,否则,后台没杀死,当再一次出现时,可能会出现两个,甚至多个。。。。