package com.itheima.mobileguard.services;

import java.lang.reflect.Method;

import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.ContentObserver;
import android.location.Address;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.SmsMessage;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast; import com.android.internal.telephony.ITelephony;
import com.itheima.mobileguard.db.dao.BlackNumberDao;
import com.itheima.mobileguard.db.dao.NumberAddressDao; public class CallSmsSafeService extends Service {
private InnerSmsReceiver receiver;
private BlackNumberDao dao;
//系统提供的电话管理器,电话管理的服务
private TelephonyManager tm;
private MyPhoneListener listener; @Override
public IBinder onBind(Intent intent) {
return null;
} @Override
public void onCreate() {
dao = new BlackNumberDao(this);
//后台运行一个服务
tm = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
listener = new MyPhoneListener();
tm.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);//设置电话监听器
//短信的广播接受者
receiver = new InnerSmsReceiver();
IntentFilter filter = new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
filter.setPriority(Integer.MAX_VALUE);//优先级最大
registerReceiver(receiver, filter);
super.onCreate();
} private class MyPhoneListener extends PhoneStateListener{//电话状态监听器
@Override
public void onCallStateChanged(int state, final String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
switch (state) {
case TelephonyManager.CALL_STATE_IDLE://空闲状态
break;
case TelephonyManager.CALL_STATE_RINGING://响铃状态
String mode = dao.findBlockMode(incomingNumber);//incomingNumber电话号码
if("1".equals(mode)||"3".equals(mode)){
Log.i("MyPhoneListener","挂断电话");
//观察(另外一个应用程序数据库的变化)呼叫记录的变化,如果呼叫记录生成了,就把呼叫记录给删除掉。
Uri uri = Uri.parse("content://call_log/calls");
getContentResolver().registerContentObserver(uri, true, new CallLogObserver(new Handler(), incomingNumber));
//用代码挂断电话。
endCall();//电话挂断之后,会在另外一个应用程序里面生成呼叫记录。
//清除黑名单号码产生的呼叫记录 }
break;
case TelephonyManager.CALL_STATE_OFFHOOK://接通状态 break;
}
}
} private class CallLogObserver extends ContentObserver{
private String incomingNumber;
public CallLogObserver(Handler handler,String incomingNumber) {
super(handler);
this.incomingNumber = incomingNumber;
}
//观察到数据库内容变化调用的方法
@Override
public void onChange(boolean selfChange) {
Log.i("CallLogObserver","呼叫记录数据库的内容变化了。");
getContentResolver().unregisterContentObserver(this);
deleteCallLog(incomingNumber);
super.onChange(selfChange);
}
} @Override
public void onDestroy() {
unregisterReceiver(receiver);
receiver = null;
tm.listen(listener, PhoneStateListener.LISTEN_NONE);
listener = null;
super.onDestroy();
} /**
* 清除呼叫记录
* @param incomingNumber
*/
public void deleteCallLog(String incomingNumber) {
ContentResolver resolver = getContentResolver();
Uri uri = Uri.parse("content://call_log/calls");
resolver.delete(uri, "number=?", new String[]{incomingNumber});
} /**
* 挂断电话
*/
public void endCall() {
try {
Class clazz = getClassLoader().loadClass("android.os.ServiceManager");//ServiceManager在代码里面点不进去,但是源码有这个类,
Method method = clazz.getDeclaredMethod("getService", String.class);
IBinder iBinder = (IBinder) method.invoke(null, TELEPHONY_SERVICE);//TELEPHONY_SERVICE="phone"
ITelephony itelephony = ITelephony.Stub.asInterface(iBinder);//ITelephony.aidl是通过源码复制的。
itelephony.endCall();
//开通呼叫转移
} catch (Exception e) {
e.printStackTrace();
}
} private class InnerSmsReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
Log.i("InnerSmsReceiver","短信到来了。");
//判断短信的发件人是否在黑名单列表里面,
Object[] objs = (Object[]) intent.getExtras().get("pdus");
for(Object obj :objs){
SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) obj);
String sender = smsMessage.getOriginatingAddress();//拿到短信的电话号码
String mode = dao.findBlockMode(sender);//模式
if("1".equals(mode)||"2".equals(mode)){
Log.i("InnerSmsReceiver","黑名单短信被拦截。");
abortBroadcast();//终止短信的广播 ,短信就被拦截
}
//智能拦截。
String body = smsMessage.getMessageBody();//拿到短信的内容
if(body.contains("发票")){ //你的头发票亮极了。
Log.i("InnerSmsReceiver","拦截到垃圾发票短信,终止");
abortBroadcast();//终止短信的广播 ,短信就被拦截
}
}
}
}
}

ITelephony.aidl

/*
* Copyright (C) 2007 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ package com.android.internal.telephony; import android.os.Bundle;
import java.util.List;
import android.telephony.NeighboringCellInfo; /**
* Interface used to interact with the phone. Mostly this is used by the
* TelephonyManager class. A few places are still using this directly.
* Please clean them up if possible and use TelephonyManager insteadl.
*
* {@hide}
*/
interface ITelephony { /**
* Dial a number. This doesn't place the call. It displays
* the Dialer screen.
* @param number the number to be dialed. If null, this
* would display the Dialer screen with no number pre-filled.
*/
void dial(String number); /**
* Place a call to the specified number.
* @param number the number to be called.
*/
void call(String number); /**
* If there is currently a call in progress, show the call screen.
* The DTMF dialpad may or may not be visible initially, depending on
* whether it was up when the user last exited the InCallScreen.
*
* @return true if the call screen was shown.
*/
boolean showCallScreen(); /**
* Variation of showCallScreen() that also specifies whether the
* DTMF dialpad should be initially visible when the InCallScreen
* comes up.
*
* @param showDialpad if true, make the dialpad visible initially,
* otherwise hide the dialpad initially.
* @return true if the call screen was shown.
*
* @see showCallScreen
*/
boolean showCallScreenWithDialpad(boolean showDialpad); /**
* End call or go to the Home screen
*
* @return whether it hung up
*/
boolean endCall(); /**
* Answer the currently-ringing call.
*
* If there's already a current active call, that call will be
* automatically put on hold. If both lines are currently in use, the
* current active call will be ended.
*
* TODO: provide a flag to let the caller specify what policy to use
* if both lines are in use. (The current behavior is hardwired to
* "answer incoming, end ongoing", which is how the CALL button
* is specced to behave.)
*
* TODO: this should be a oneway call (especially since it's called
* directly from the key queue thread).
*/
void answerRingingCall(); /**
* Silence the ringer if an incoming call is currently ringing.
* (If vibrating, stop the vibrator also.)
*
* It's safe to call this if the ringer has already been silenced, or
* even if there's no incoming call. (If so, this method will do nothing.)
*
* TODO: this should be a oneway call too (see above).
* (Actually *all* the methods here that return void can
* probably be oneway.)
*/
void silenceRinger(); /**
* Check if we are in either an active or holding call
* @return true if the phone state is OFFHOOK.
*/
boolean isOffhook(); /**
* Check if an incoming phone call is ringing or call waiting.
* @return true if the phone state is RINGING.
*/
boolean isRinging(); /**
* Check if the phone is idle.
* @return true if the phone state is IDLE.
*/
boolean isIdle(); /**
* Check to see if the radio is on or not.
* @return returns true if the radio is on.
*/
boolean isRadioOn(); /**
* Check if the SIM pin lock is enabled.
* @return true if the SIM pin lock is enabled.
*/
boolean isSimPinEnabled(); /**
* Cancels the missed calls notification.
*/
void cancelMissedCallsNotification(); /**
* Supply a pin to unlock the SIM. Blocks until a result is determined.
* @param pin The pin to check.
* @return whether the operation was a success.
*/
boolean supplyPin(String pin); /**
* Handles PIN MMI commands (PIN/PIN2/PUK/PUK2), which are initiated
* without SEND (so <code>dial</code> is not appropriate).
*
* @param dialString the MMI command to be executed.
* @return true if MMI command is executed.
*/
boolean handlePinMmi(String dialString); /**
* Toggles the radio on or off.
*/
void toggleRadioOnOff(); /**
* Set the radio to on or off
*/
boolean setRadio(boolean turnOn); /**
* Request to update location information in service state
*/
void updateServiceLocation(); /**
* Enable location update notifications.
*/
void enableLocationUpdates(); /**
* Disable location update notifications.
*/
void disableLocationUpdates(); /**
* Enable a specific APN type.
*/
int enableApnType(String type); /**
* Disable a specific APN type.
*/
int disableApnType(String type); /**
* Allow mobile data connections.
*/
boolean enableDataConnectivity(); /**
* Disallow mobile data connections.
*/
boolean disableDataConnectivity(); /**
* Report whether data connectivity is possible.
*/
boolean isDataConnectivityPossible(); Bundle getCellLocation(); /**
* Returns the neighboring cell information of the device.
*/
List<NeighboringCellInfo> getNeighboringCellInfo(); int getCallState();
int getDataActivity();
int getDataState(); /**
* Returns the current active phone type as integer.
* Returns TelephonyManager.PHONE_TYPE_CDMA if RILConstants.CDMA_PHONE
* and TelephonyManager.PHONE_TYPE_GSM if RILConstants.GSM_PHONE
*/
int getActivePhoneType(); /**
* Returns the CDMA ERI icon index to display
*/
int getCdmaEriIconIndex(); /**
* Returns the CDMA ERI icon mode,
* 0 - ON
* 1 - FLASHING
*/
int getCdmaEriIconMode(); /**
* Returns the CDMA ERI text,
*/
String getCdmaEriText(); /**
* Returns true if CDMA provisioning needs to run.
*/
boolean getCdmaNeedsProvisioning(); /**
* Returns the unread count of voicemails
*/
int getVoiceMessageCount(); /**
* Returns the network type
*/
int getNetworkType(); /**
* Return true if an ICC card is present
*/
boolean hasIccCard();
}

android143 360 短信电话拦截的更多相关文章

  1. Android开发——短信电话拦截/接听电话

    1.短信拦截 首先需要声明的是,Android4.4版本以上,如果想做到短信拦截,必须成为default sms,把所有短信相关的功能都包揽了,然后再做短信拦截.但这种做法,适配性和兼容性的工作是非常 ...

  2. Android学习笔记_19_广播接收者 BroadcastReceiver及其应用_窃听短信_拦截外拨电话

    一.广播接收者类型: 广播被分为两种不同的类型:“普通广播(Normal broadcasts)”和“有序广播(Ordered broadcasts)”. 普通广播是完全异步的,可以在同一时刻(逻辑上 ...

  3. Python短信电话报警

    sid 和token 需要自己去https://www.twilio.com/try-twilio注册twilio 账号申请是免费的  from后面的电话也是官方提供的 直接看脚本 # -*-cond ...

  4. Arduino 各种模块篇 GPRS module 手机模块 短信 电话 上网 for texting, calling, internet

    ---恢复内容开始--- The GPRS shield which I tested is one which looks like this: ---恢复内容结束--- Need to be re ...

  5. Android -- 怎么发出和接收广播, Broadcast, 电话拨号拦截,短信拦截

    1. 发送广播 使用以下三个API可以发送广播 public void click(View view){ Intent intent = new Intent(); intent.setAction ...

  6. [android] 手机卫士黑名单功能(短信拦截)

    前面我们把需要拦截的手机号都存储和展示出来了,接下来是使用广播接收者拦截短信了,这个广播接收者需要和一个服务绑定,服务开启的时候,接收者存在,服务停掉时,接收者关闭 在service包下定义一个类Ca ...

  7. Android 短信拦截及用途分析

    监听系统短信这个只能作为一个技术点来研究下,读者可能在工作中可能不会哦涉及到,一般的应用软件也不会有这个需求 但是作为程序员呢,多了解一下也是好的. Android 监听系统短信有什么用? 1.对系统 ...

  8. atitit.破解 拦截 绕过 网站 手机 短信 验证码 之自动获取手机短信方式 attilax 总结

    atitit.破解  拦截 绕过 网站 手机 短信 验证码 之自动获取手机短信方式 attilax 总结 1. 自动获取手机短信方式的原理 1 2. 调用api 1 3. ----核心代码 2 4.  ...

  9. Android 短信监听及用途分析

    监听系统短信这个只能作为一个技术点来研究下,读者可能在工作中可能不会哦涉及到,一般的应用软件也不会有这个需求 但是作为程序员呢,多了解一下也是好的. Android 监听系统短信有什么用? 1.对系统 ...

随机推荐

  1. ASP.NET MVC中的Json Binding和Validate

    引子:电子商务网站支付功能页面往往会有很多信息,对于这些信息的保存,往往是分步完成的,那么使用Ajax最合适不过了,比如其中的收货人信息模块.这些信息的新建和编辑保存都是用Ajax来完成的.那么有几种 ...

  2. 【跟我一起学Python吧】Python解释执行原理

    这里的解释执行是相对于编译执行而言的.我们都知道,使用C/C++之类的编译性语言编写的程序,是需要从源文件转换成计算机使用的机器语言,经过链接器链接之后形成了二进制的可执行文件.运行该程序的时候,就可 ...

  3. Asp.net MVC 处理文件的上传下载

    如果你仅仅只有Asp.net Web Forms背景转而学习Asp.net MVC的,我想你的第一个经历或许是那些曾经让你的编程变得愉悦无比的服务端控件都驾鹤西去了.FileUpload就是其中一个, ...

  4. 大话细说ORM

    什么是ORM? ORM,即对象关系映射(Object Relational Mapping)表示一种技术,用来把(对象模型)表示的对象映射到基于SQL的(关系模型)数据结构中去. 说得通俗点,就是在对 ...

  5. Java相关书籍推荐

    Java从入门到精通(第3版 附光盘) 作      者 明日科技 编 出 版 社 清华大学出版社 出版时间 2012-08-01 版      次 3 页      数 564 印刷时间 2012- ...

  6. ACCESS TOKEN

    Access Token 在微信公众平台接口开发中,Access Token占据了一个很重要的地位,相当于进入各种接口的钥匙,拿到这个钥匙才有调用其他各种特殊接口的权限. access_token是公 ...

  7. [算法] 冒泡排序 Bubble Sort

    冒泡排序(Bubble Sort,台湾另外一种译名为:泡沫排序)是一种简单的排序算法.它重复地走访过要排序的数列,一次比较两个元素,如果他们的顺序错误就把他们交换过来.走访数列的工作是重复地进行直到没 ...

  8. ES6学习(2)——arrows箭头函数

    Arrows => 箭头函数 箭头函数,若有了解过coffeeScript的同学,或许对此印象深刻,因为它可以让语法省略不少,特别是对于回调函数,会让代码更清晰简洁. expression 让我 ...

  9. C 语言中包含的标准头文件(24个)

    <assert.h><complex.h><ctype.h><errno.h><fenv.h><float.h><intt ...

  10. jQuery基础学习8——层次选择器next()和prev()方法

    $('.one + div').css("background","#bbffaa"); //和next()方法是等价的,前后关系,和prev()方法是对立的 ...