private class MyPhoneListener extends PhoneStateListener{
// 电话状态发生改变的时候 调用的方法
@Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
switch (state) {
case TelephonyManager.CALL_STATE_IDLE: // 处于静止状态: 没有呼叫
endRingTime = System.currentTimeMillis();
long calltime = endRingTime-firstRingTime;
Log.i(TAG,"calltime ="+calltime);
if(firstRingTime<endRingTime && calltime<5000 && calltime >0){
Log.i(TAG,"响一声的电话");
endRingTime = 0;
firstRingTime = 0;
// 弹出来notification 通知用户这是一个骚扰电话
showNotification(incomingNumber);
}
if(view!=null){
windowmanager.removeView(view);
view = null;
}
// 再获取一次系统的时间
break;
case TelephonyManager.CALL_STATE_RINGING: // 零响状态
firstRingTime = System.currentTimeMillis();
/**
* 弹出notification 通知用户添加黑名单号码
* @param incomingNumber
*/
public void showNotification(String incomingNumber) {
//1. 获取notification的管理服务
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
//2 把一个要想显示的notification 对象创建出来
int icon =R.drawable.notification;
CharSequence tickerText = "发现响一声号码";
long when = System.currentTimeMillis();
Notification notification = new Notification(icon, tickerText, when);
// 3 .配置notification的一些参数
Context context = getApplicationContext();
CharSequence contentTitle = "响一声号码";
CharSequence contentText = incomingNumber;
notification.flags = Notification.FLAG_AUTO_CANCEL;
Intent notificationIntent = new Intent(this, CallSmsActivity.class);
// 把响一声的号码 设置到intent对象里面
notificationIntent.putExtra("number", incomingNumber);
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0);
notification.setLatestEventInfo(context, contentTitle, contentText, contentIntent);
// 4. 通过manger把notification 激活
manager.notify(0, notification);
}
case TelephonyManager.CALL_STATE_RINGING: // 零响状态
firstRingTime = System.currentTimeMillis();
Log.i(TAG,"来电号码为"+ incomingNumber);
// 判断incomingnumber是否在黑名单中
if(dao.find(incomingNumber)){
//挂断电话
endCall();
//deleteCallLog(incomingNumber);\
//不能立即删除通话记录,因为这个记录是挂断后一段时间才生成,可以用线程过几秒钟去执行删除,但体验效果不好,用下面的方式
//注册一个内容观察者 观察call_log的uri的信息
getContentResolver().registerContentObserver(CallLog.Calls.CONTENT_URI, true, new MyObserver(new Handler(),incomingNumber));
}
/**
* 根据电话号码删除呼叫记录
* @param incomingNumber 要删除呼叫记录的号码
*/
public void deleteCallLog(String incomingNumber) {
ContentResolver resolver = getContentResolver();
Cursor cursor = resolver.query(CallLog.Calls.CONTENT_URI, null, "number=?", new String[]{incomingNumber}, null);
if(cursor.moveToFirst()){//查询到了呼叫记录
String id =cursor.getString(cursor.getColumnIndex("_id"));
resolver.delete(CallLog.Calls.CONTENT_URI, "_id=?",new String[]{id});
}
}
public void endCall() {
try {
Method method = Class.forName("android.os.ServiceManager").getMethod("getService", String.class);
IBinder binder = (IBinder)method.invoke(null, new Object[]{TELEPHONY_SERVICE});
ITelephony telephony = ITelephony.Stub.asInterface(binder);
telephony.endCall();
} catch (Exception e) {
e.printStackTrace();
}
}
private class MyObserver extends ContentObserver
{
private String incomingnumber;
public MyObserver(Handler handler,String incomingnumber) {
super(handler);
this.incomingnumber = incomingnumber;
}
@Override
public void onChange(boolean selfChange) {
super.onChange(selfChange);
deleteCallLog(incomingnumber);
//当删除了呼叫记录后 反注册内容观察者
getContentResolver().unregisterContentObserver(this);
}
}
在Android源码中的NotificationManagerService.java这个类中定义了两个静态变量,分别对应Toast.LENGTH_LONG(3.5秒)和Toast.LENGTH_SHORT(2秒)的值
private static final int LONG_DELAY = 3500; // 3.5 seconds
private static final int SHORT_DELAY = 2000; // 2 seconds
在下面的方法中进行了调用:
private void scheduleTimeoutLocked(ToastRecord r, boolean immediate)
{
Message m =Message.obtain(mHandler, MESSAGE_TIMEOUT, r);
long delay =immediate ? 0 :(r.duration == Toast.LENGTH_LONG ? LONG_DELAY : SHORT_DELAY);
mHandler.removeCallbacksAndMessages(r);
mHandler.sendMessageDelayed(m, delay);
}
也就是说,Toast..makeText(Context context,CharSequence text, int duration).show() 中的duration只能设这两个值,其他值是没有用处的。