您的位置:首页 > 其它

51清除电话拦截的通话记录

2014-12-18 20:11 260 查看
系统的电话记录保存在contacts2.db这张表中,而我们的通话记录则保存在calls这张表中,如图:



那么清除通话记录需要访问源码,打开联系人源码的清单文件:

我们看到主机名如下:



再进入.java文件中查看CallLogProvider类,我们看到路径名是什么了:



/**
	 * 利用内容提供者去删除通话记录
	 * 
	 * @param incomingNumber
	 */
	public void deleteCallLog(String incomingNumber) {
		//内容提供者解析器
		ContentResolver resolver = getContentResolver();
		//呼叫记录的uri路径
		Uri uri = Uri.parse("content://call_log/calls");
		
		//CallLog.CONTENT_URI  直接使用常量也可以
		
		
		resolver.delete(uri, "number=?", new String[]{incomingNumber});
		
	}


也可以直接使用Android提供的CallLog类:



调用:

endCall();// 在另外一个进程里面运行的远程服务的方法,方法调用后,呼叫记录可能还没有生成,导致清除不掉呼叫记录
					// 删除呼叫记录
					// 另外一个应用程序的私有的联系人数据库

					deleteCallLog(incomingNumber);//本方法和endCall()不在一个进程中运行


那么此时会有很大的问题:

我们会发现有时候log清除的很及时,有时候又不是很及时,原因在于endCall()这个方法,这个方法是在另外一个进程里面运行的远程服务的方法,而删除记录的方法是在另外一个进程中运行的。

我们可以让清除的方法睡眠两秒进行,但是这样的体验很差,实践的做法是:

注册一个ContentObserver去监听数据库中呼叫记录的变化,当有呼叫记录变化时,调用清除的方法,同时,当监听到呼叫记录变化时,ContentObserver也不需要了,可以取消注册。

private class MyListener extends PhoneStateListener {

		@Override
		public void onCallStateChanged(int state, String incomingNumber) {
			switch (state) {
			case TelephonyManager.CALL_STATE_RINGING:
				String mode = dao.findMode(incomingNumber);
				if ("1".equals(mode) || "3".equals(mode)) {
					// 挂断电话
					Log.i(TAG, "挂断电话");
					
					
					//观察呼叫记录数据库内容的变化
					// 呼叫记录的uri路径
					Uri uri = Uri.parse("content://call_log/calls");
					getContentResolver().registerContentObserver(uri, true, new CallLogObserver(incomingNumber,new Handler()));
					
					

					endCall();// 在另外一个进程里面运行的远程服务的方法,方法调用后,呼叫记录可能还没有生成,导致清除不掉呼叫记录
					// 删除呼叫记录
					// 另外一个应用程序的私有的联系人数据库

					//deleteCallLog(incomingNumber);//本方法和endCall()不在一个进程中运行

					
				
					
					
				}
				break;
			case TelephonyManager.CALL_STATE_IDLE:

				break;
			case TelephonyManager.CALL_STATE_OFFHOOK:

				break;

			default:
				break;
			}
			super.onCallStateChanged(state, incomingNumber);
		}

	}
	
	
	
	private class CallLogObserver extends ContentObserver{

		private String incomingNumber;
		
		public CallLogObserver(String incomingNumber,Handler handler) {
			super(handler);
			this.incomingNumber = incomingNumber;
		}

		@Override
		public void onChange(boolean selfChange) {
			Log.i(TAG, "数据库的内容变化了,产生了呼叫记录");
			//取消注册
			getContentResolver().unregisterContentObserver(this);
			deleteCallLog(incomingNumber);
			super.onChange(selfChange);
		}
		
	}


incomingNumber通过构造器传过去。

清除呼叫记录需要两个权限:

<uses-permission android:name="android.permission.READ_CALL_LOG"/>
    <uses-permission android:name="android.permission.WRITE_CALL_LOG"/>


内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: