权限:
<
uses-permission
android:name
=
"android.permission.SYSTEM_ALERT_WINDOW"
/>
-------------------------------------------------------------------------------
/**
* 来电时显示来电号码归属地的服务
*
@author
Administrator
*
*/
public
class
ShowAddressService
extends
Service {
private
TelephonyManager
tm
;
private
MyListener
listener
;
private
BroadcastReceiver
receiver
;
private
SharedPreferences
sp
;
//自定义Toast
private
View
view
;
private
WindowManager
wm
;
// "半透明","活力橙","卫士蓝","苹果绿","金属灰"
private
static
final
int
[]
bgs
= {R.drawable.
call_locate_white
,
R.drawable.
call_locate_orange
, R.drawable.
call_locate_blue
,
R.drawable.
call_locate_green
, R.drawable.
call_locate_gray
};
@Override
public
IBinder onBind(Intent intent) {
return
null
;
}
/**
* 代码的方式创建广播接收者
*/
private
class
OutCallReceiver
extends
BroadcastReceiver{
@Override
public
void
onReceive(Context context, Intent intent) {
String address = AddressDao.getAddress(getResultData(), context);
System.
out
.println(address+
"....................."
);
// Toast.makeText(context, address, 1).show();
showAddress(address);
}
}
/**
* 服务创建的时候
*/
@Override
public
void
onCreate() {
super
.onCreate();
sp
=getSharedPreferences(
"config"
,
MODE_PRIVATE
);
//创建WindowManager
wm
= (WindowManager) getSystemService(
WINDOW_SERVICE
);
//在服务创建时注册并开启广播
receiver
=
new
OutCallReceiver();
IntentFilter filter=
new
IntentFilter();
filter.addAction(
"android.intent.action.NEW_OUTGOING_CALL"
);
this
.registerReceiver(
receiver
, filter);
//创建电话管理者
tm
=(TelephonyManager) getSystemService(
TELEPHONY_SERVICE
);
listener
=
new
MyListener();
//初始化MyListener()
//注册一个监听器,监听电话状态的改变
tm
.listen(
listener
, PhoneStateListener.
LISTEN_CALL_STATE
);
}
/**
* 服务销毁的时候
*/
@Override
public
void
onDestroy() {
super
.onDestroy();
//在服务销毁时结束广播
unregisterReceiver(
receiver
);
receiver
=
null
;
// 当服务停止的时候 取消电话监听
tm
.listen(
listener
, PhoneStateListener.
LISTEN_NONE
);
listener
=
null
;
}
/**
* 电话状态的监听器
*
*/
public
class
MyListener
extends
PhoneStateListener{
@Override
public
void
onCallStateChanged(
int
state, String incomingNumber) {
super
.onCallStateChanged(state, incomingNumber);
switch
(state) {
case
TelephonyManager.
CALL_STATE_IDLE
:
//空闲状态
if
(
view
!=
null
) {
wm
.removeView(
view
);
//电话挂断时,移除土司
view
=
null
;
}
break
;
case
TelephonyManager.
CALL_STATE_RINGING
:
//响铃状态
String address = AddressDao.getAddress(incomingNumber,getApplicationContext());
// Toast.makeText(getApplicationContext(), address, 1).show();
showAddress(address);
break
;
case
TelephonyManager.
CALL_STATE_OFFHOOK
:
//接听状态
break
;
}
}
}
/**
* 显示一个自定义的土司
*
*
@param
address
*/
public
void
showAddress (String address) {
//得到自定义土司的布局
view
= View. inflate(getApplicationContext(), R.layout.
toast_address
,
null
);
TextView tv = (TextView)
view
.findViewById(R.id.
tv_info
);
tv.setText(address);
view
.setBackgroundResource(
bgs
[
sp
.getInt(
"which"
, 0)]);
//系统源码Toast设置修改
final
WindowManager.LayoutParams params =
new
LayoutParams();
//来去电时自定义Toast位置设置
params.
gravity
=Gravity.
LEFT
+Gravity.
TOP
;
params.
x
=
sp
.getInt(
"left"
, 0);
params.
y
=
sp
.getInt(
"top"
, 0);
//设置触摸事件
view
.setOnTouchListener(
new
OnTouchListener() {
int
startX
;
int
startY
;
@Override
public
boolean
onTouch(View v, MotionEvent event) {
switch
(event.getAction()) {
case
MotionEvent.
ACTION_DOWN
:
startX
= (
int
) event.getRawX();
startY
= (
int
) event.getRawY();
break
;
case
MotionEvent.
ACTION_MOVE
:
int
newX = (
int
) event.getRawX();
int
newY = (
int
) event.getRawY();
int
dx = newX -
startX
;
int
dy = newY -
startY
;
//设置toast的位置
params.
x
+=dx;
params.
y
+=dy;
wm
.updateViewLayout(
view
, params);
//更新手指的位置
startX
= (
int
) event.getRawX();
startY
= (
int
) event.getRawY();
break
;
case
MotionEvent.
ACTION_UP
:
//记录最后的距离屏幕左边 和 上边位置 存到 sp里面
break
;
}
return
true
;
}
});
//体统Toast参数配置源码
params.
height
= WindowManager.LayoutParams.
WRAP_CONTENT
;
params.
width
= WindowManager.LayoutParams.
WRAP_CONTENT
;
params.
flags
= WindowManager.LayoutParams.
FLAG_NOT_FOCUSABLE
// | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE 注释掉不可触摸配置
| WindowManager.LayoutParams.
FLAG_KEEP_SCREEN_ON
;
params.
format
= PixelFormat.
TRANSLUCENT
;
params.
type
= WindowManager.LayoutParams.
TYPE_PRIORITY_PHONE
;
//更改窗体的类型,窗体显示在最上方才能响应触摸事件
wm
.addView(
view
, params);
}
}