步骤:
1.到窗口管理器对象WindowManager wm,
2.得到布局文件构造的一个view,
3.构造WindowManager.LayoutParams()布局参数wparam
4.使用窗口布局管理器将view按照wparam的布局来显示mWM.addView(view, params);
代码:
package com.itheima.mobilesafe.service;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.view.Gravity;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.WindowManager;
import android.widget.TextView;
import com.itheima.mobilesafe.R;
import com.itheima.mobilesafe.dao.NumberAddressDao;
import com.itheima.mobilesafe.receiver.OutCallBroadcastReceiver;
public class NumberAddressService extends Service {
private WindowManager mWM;
private WindowManager.LayoutParams params;
private View view;
private OutCallBroadcastReceiver receiver;
private SharedPreferences sp;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCreate() {
super.onCreate();
TelephonyManager tm = (TelephonyManager) this
.getSystemService(TELEPHONY_SERVICE);
// 监听电话的呼叫状态
tm.listen(new MyPhoneStateListener(),
PhoneStateListener.LISTEN_CALL_STATE);
//取消监听代码
// tm.listen(listener, PhoneStateListener.LISTEN_NONE);
receiver = new OutCallBroadcastReceiver();
// 添加接收事件类型
IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.NEW_OUTGOING_CALL");
// 注册广播接收者
registerReceiver(receiver, filter);
}
private class MyPhoneStateListener extends PhoneStateListener {
/**
* 电话的呼叫状态发生变化时会调用这个方法
*/
@Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
switch (state) {
case TelephonyManager.CALL_STATE_IDLE:// 空闲状态
// 电话挂断时移除归属地提示框
if (view != null) {
mWM.removeView(view);
view = null;
}
break;
case TelephonyManager.CALL_STATE_RINGING:// 铃声响起状态
// 查询号码归属地
String address = NumberAddressDao
.queryNumberAddress(incomingNumber);
// Toast.makeText(NumberAddressService.this, address, 0).show();
getMyToast(address);
break;
case TelephonyManager.CALL_STATE_OFFHOOK:// 接通状态
break;
default:
break;
}
}
}
private void getMyToast(String address) {
sp = getSharedPreferences("config", Context.MODE_PRIVATE);
int which = sp.getInt("which", 0);
// private String[] items = new String[] { "半透明", "活力橙", "金屬灰", "衛士藍",
// "蘋果綠" };
int[] ids = new int[] { R.drawable.call_locate_white,
R.drawable.call_locate_orange, R.drawable.call_locate_gray,
R.drawable.call_locate_blue, R.drawable.call_locate_green };
view = View.inflate(this, R.layout.show_toast, null);
view.setBackgroundResource(ids[which]);
//给view添加一个触摸的监听器
view.setOnTouchListener(new OnTouchListener() {
private int startX = 0;
private int startY = 0;
@Override
public boolean onTouch(View v, MotionEvent event) {
// 得到触摸事件的类型
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:// 按下的事件
startX = (int) event.getRawX();
startY = (int) event.getRawY();
break;
case MotionEvent.ACTION_MOVE:// 移动的事件
//2、在移动的过程中得到结束坐标点
int endX = (int) event.getRawX();
int endY = (int) event.getRawY();
//3、计算移动的偏移量
int dX = endX - startX;
int dY = endY - startY;
//4、更新图标的位置
params.x +=dX;
params.y +=dY;
if(params.x < 0){
params.x = 0;
}
if(params.y < 0){
params.y = 0;
}
if(params.x > mWM.getDefaultDisplay().getWidth()-view.getWidth()){
params.x = mWM.getDefaultDisplay().getWidth()-view.getWidth();
}
if(params.y > mWM.getDefaultDisplay().getHeight()-view.getHeight()){
params.y = mWM.getDefaultDisplay().getHeight()-view.getHeight();
}
//4、更新图标的位置
mWM.updateViewLayout(view, params);
//5、得到新的开始坐标点
startX = (int) event.getRawX();
startY = (int) event.getRawY();
break;
case MotionEvent.ACTION_UP:// 抬起的事件
int lastX = params.x ;
int lastY = params.y;
Editor editor = sp.edit();
editor.putInt("lastX", lastX);
editor.putInt("lastY", lastY);
editor.commit();
break;
}
return true;
}
});
TextView tv = (TextView) view.findViewById(R.id.tv_address);
// 在自定义的吐司上显示归属地
tv.setText(address);
// 得到系统提供窗口管理器
mWM = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
// 得到布局文件的参数对象
params = new WindowManager.LayoutParams();
// 设置布局文件显示用到的参数
//添加显示时参考的位置
params.gravity = Gravity.LEFT + Gravity.TOP;
//根据之前保存的显示位置来显示当前位置
int lastX = sp.getInt("lastX", 0);
int lastY = sp.getInt("lastY", 0);
params.x = lastX;
params.y = lastY;
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.windowAnimations =
// com.android.internal.R.style.Animation_Toast;
params.type = WindowManager.LayoutParams.TYPE_PRIORITY_PHONE;
// 在窗口中显示自定义的吐司
mWM.addView(view, params);
// mWM.removeView(view);
}
@Override
public void onDestroy() {
super.onDestroy();
// 取消掉已经注册的广播接收者
unregisterReceiver(receiver);
}
}
show_toast.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal"
>
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@android:drawable/ic_menu_call" />
<TextView
android:layout_marginTop="8dip"
android:id="@+id/tv_address"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="北京电信"
android:textSize="15sp"
android:gravity="center_vertical"
/>
</LinearLayout>