昨日实现了360手机卫士的来电显示归属地的功能,具体的功能就是当来电的时候,界面会弹出来一个自定义的土司,显示当前号码的归属地,学习之后发现操作非常的简单,总结下加强自己的回忆。
具体细节大概为:别人打电话过来--->手机状态改变---->WindowManage监听到了改变,获得来电手机号查询地址----->在自定义的吐司上面显示出来。
下面是具体的代码实现:
AddressService服务类:
package com.itheima.mobilesafe.service;
import com.itheima.mobilesafe.R;
import com.itheima.mobilesafe.db.dao.AddressDao;
import com.itheima.mobilesafe.receiver.OutCallReceiver;
import android.app.ActionBar.LayoutParams;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.graphics.PixelFormat;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.view.TextureView;
import android.view.View;
import android.view.WindowManager;
import android.widget.TextView;
import android.widget.Toast;
public class AddressService extends Service {
private TelephonyManager tm;
private MyListenerPhone listener;
private BroadcastReceiver receiver;
private WindowManager wm;
private View view;
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
listener = new MyListenerPhone();
tm.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
wm = (WindowManager) getSystemService(WINDOW_SERVICE);
receiver = new OutCallReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.NEW_OUTGOING_CALL");
registerReceiver(receiver, filter);
}
@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
tm.listen(listener, PhoneStateListener.LISTEN_NONE);
listener = null;
unregisterReceiver(receiver);
receiver = null;
}
class MyListenerPhone extends PhoneStateListener {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
// TODO Auto-generated method stub
super.onCallStateChanged(state, incomingNumber);
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
String address = AddressDao.getAddress(incomingNumber);
showMyToast(address);
break;
case TelephonyManager.CALL_STATE_IDLE:
if(view!=null) {
wm.removeView(view);
view = null;
}
default:
break;
}
}
}
public void showMyToast(String address) {
int[] ids = {R.drawable.call_locate_white,R.drawable.call_locate_orange,R.drawable.call_locate_blue
,R.drawable.call_locate_gray,R.drawable.call_locate_green};
SharedPreferences sp = getSharedPreferences("config", MODE_PRIVATE);
int which = sp.getInt("which", 1);
view = View.inflate(this, R.layout.address_show, null);
TextView textView = (TextView) view.findViewById(R.id.tv_address);
textView.setText(address);
view.setBackgroundResource(ids[which]);
WindowManager.LayoutParams params = new WindowManager.LayoutParams();
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_TOAST;
wm.addView(view, params);
}
}
1.写成服务是方便开启和关闭,而且可以长期后台运行,重写onCreat()和onDestroy()方法,开启和关闭的时候分别调用这两个方法,
2.在开启方法中,会获得WindowManage服务,然后调用他的listen(1,2)方法,参数1是一个监听器,继承PhoneStateListener,写状态改变时候的动作,参数2是要监听的种类,这里是STATE
3.自定显示土司的方法showMyToast(),方法里要调用wm的addView(1,2)方法,传view对象和参数细节params。
4.R.layout.XX找不到是因为导入了错的R包,要导入自己项目的R,不是系统中的R。
5.去电时候是用广播接收者接收广播进行差不多的处理,除了可以再清单中进行注册,还可以在服务中进行注册广播接收者,这样就可以动态的开启和关闭广播接收者:
<span style="white-space:pre"> </span>receiver = new OutCallReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.NEW_OUTGOING_CALL");
registerReceiver(receiver, filter);
取消注册就用:
<span style="white-space:pre"> </span>unregisterReceiver(receiver);
receiver = null;