BroadCastTool.java 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419
  1. package me.yoqi.mobile.tool;
  2. import java.lang.reflect.Method;
  3. import java.text.SimpleDateFormat;
  4. import java.util.Calendar;
  5. import java.util.HashMap;
  6. import java.util.Set;
  7. import com.android.internal.telephony.ITelephony;
  8. import android.content.BroadcastReceiver;
  9. import android.content.Context;
  10. import android.content.Intent;
  11. import android.content.SharedPreferences;
  12. import android.database.Cursor;
  13. import android.media.AudioManager;
  14. import android.net.Uri;
  15. import android.os.Bundle;
  16. import android.os.RemoteException;
  17. import android.provider.CallLog;
  18. import android.provider.CallLog.Calls;
  19. import android.telephony.PhoneStateListener;
  20. import android.telephony.SmsManager;
  21. import android.telephony.SmsMessage;
  22. import android.telephony.TelephonyManager;
  23. import android.util.Log;
  24. import android.widget.Toast;
  25. import me.yoqi.mobile.db.DbAdapter;
  26. import me.yoqi.mobile.info.Call_Record_Info;
  27. import me.yoqi.mobile.info.Message_Rubbish_Info;
  28. import me.yoqi.mobile.info.PhoneInfo;
  29. import me.yoqi.mobile.info.SmsInfo;
  30. /**
  31. * 广播类,监听短信
  32. *
  33. * @author emmet7life@yahoo.cn
  34. * */
  35. public class BroadCastTool extends BroadcastReceiver {
  36. String SMScontent_01;
  37. String SMScontent_02;
  38. static HashMap<String, PhoneInfo> mPhoneMap = new HashMap<String, PhoneInfo>();
  39. static HashMap<String, SmsInfo> mSMSMap = new HashMap<String, SmsInfo>();
  40. public static final String SMS_SYSTEM_ACTION = "android.provider.Telephony.SMS_RECEIVED";// 接收短信的ACTION标识
  41. public static final String SYSTEM_BOOT_COMPLETED = "android.intent.action.BOOT_COMPLETED";
  42. public static final String SMS_RECEIVED_ACTION = "com.ldci.t56.mobile.safe.SMS_RECEIVED_ACTION";// 当收到垃圾短信时发出广播的ACTION标识
  43. public static final String CALL_RECEIVED_ACTION = "com.ldci.t56.mobile.safe.CALL_RECEIVED_ACTION";// 当收到垃圾短信时发出广播的ACTION标识
  44. public static final String AUTO_START_SERVICE = "com.ldci.t56.mobile.safe.AUTO_START_SERVICE";//接收系统启动的广播
  45. public static String SMS_PHONENUMBER;//接收短信号码
  46. public static String SMS_CONTENT;//接收短信内容
  47. private DbAdapter mDbAdapter;//操作数据库
  48. private ITelephony iTelephony;//挂断电话的一个对象
  49. private TelephonyManager telephonyMgr;//电话管理类
  50. public SharedPreferences mSharedPreferences;//存储基本数据类的共享类
  51. private boolean isReceiveCall;//是否接收电话
  52. private boolean isAutoStartWithPhone;//是否随系统启动
  53. private boolean isReceiveSMS;//是否接收短信
  54. private String mUndisturbedMode;//夜间模式信息
  55. public BroadCastTool() {
  56. SMS_PHONENUMBER = new String();
  57. SMS_CONTENT = new String();
  58. }
  59. @Override
  60. public void onReceive(Context context, Intent intent) {
  61. // 读取配置文件信息:实时读取
  62. SharedPreferences settings = context.getSharedPreferences("DEMO",Context.MODE_PRIVATE);
  63. SMScontent_01 = settings.getString("smartE01", "");
  64. SMScontent_02 = settings.getString("smartE02", "");
  65. mSharedPreferences = context.getSharedPreferences("SharedPreferences",Context.MODE_PRIVATE);
  66. isAutoStartWithPhone = mSharedPreferences.getBoolean("isAutoStartWithPhone", false);
  67. isReceiveCall = mSharedPreferences.getBoolean("isReceiveCall", false);
  68. isReceiveSMS = mSharedPreferences.getBoolean("isReceiveSMS", false);
  69. mUndisturbedMode = mSharedPreferences.getString("UndisturbedMode", "关闭");
  70. // 监听开机广播,实现开机自动启动软件
  71. if (intent.getAction().equals(SYSTEM_BOOT_COMPLETED)) {
  72. if (isAutoStartWithPhone) {
  73. Intent mIntent = new Intent(AUTO_START_SERVICE);
  74. context.startService(mIntent);// 启动服务
  75. }
  76. }
  77. // 监听短信广播,实现拦截垃圾短信
  78. if (intent.getAction().equals(SMS_SYSTEM_ACTION)) {
  79. // 1.拒收短信的优先级最高,在最前面判断
  80. if (isReceiveSMS) {
  81. Toast.makeText(context, "设置信息之拒收短信:勾选", Toast.LENGTH_LONG).show();
  82. abortBroadcast();// 中止短信广播:当拒收短信是勾选状态时,拒收一切短信
  83. } else {
  84. // 2.拒收短信未勾选状态时,需要判断夜间模式是否开启,如果选择了拦截短信或拦截短信和电话时,需要判断时间段,如果在拦截的时间段内则中止广播
  85. if (("拦截短信".equals(mUndisturbedMode) || "拦截短信和电话".equals(mUndisturbedMode)) && isIncludedTime(context)) {
  86. abortBroadcast();// 中止短信广播:当拒收短信是勾选状态时,拒收一切短信
  87. } else {
  88. // 2.1.当可以接收短信的时候,首先解析短信号码和内容,接着判断号码是否
  89. // 为短信黑名单中的号码,如果是则直接屏蔽,并把短信放到短信垃圾箱中
  90. StringBuilder mMessagePhone = new StringBuilder();
  91. StringBuilder mMessageContent = new StringBuilder();
  92. Bundle mBundle = intent.getExtras();
  93. if (null != mBundle) {
  94. Object[] mObject = (Object[]) mBundle.get("pdus");
  95. SmsMessage[] mMessage = new SmsMessage[mObject.length];
  96. for (int i = 0; i < mObject.length; i++) {
  97. mMessage[i] = SmsMessage.createFromPdu((byte[]) mObject[i]);
  98. }
  99. for (SmsMessage currentMessage : mMessage) {
  100. mMessagePhone.append(currentMessage.getDisplayOriginatingAddress());// 读取电话号码
  101. mMessageContent.append(currentMessage.getDisplayMessageBody());// 读取短信内容
  102. }
  103. SMS_PHONENUMBER = mMessagePhone.toString();
  104. SMS_CONTENT = mMessageContent.toString();
  105. SmsManager smsmanager = SmsManager.getDefault();
  106. if (SMS_CONTENT.equals(SMScontent_01)) {
  107. Uri uriSMS = Uri.parse("content://sms/inbox");
  108. Cursor cursor = context.getContentResolver().query(uriSMS, null, "read=0", null, null);
  109. while (cursor.moveToNext()) {
  110. SmsInfo info = new SmsInfo();
  111. String smsno = cursor.getString(cursor.getColumnIndex("_id"));
  112. String address = cursor.getString(cursor.getColumnIndex("address"));
  113. info.setAddress(address);
  114. Calendar cal = Calendar.getInstance();
  115. long date = cursor.getLong(cursor.getColumnIndex("date"));
  116. cal.setTimeInMillis(date);
  117. SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM年dd日 HH:mm:ss");
  118. String dateStr = sdf.format(cal.getTime());
  119. info.setDate(dateStr);
  120. String body = cursor.getString(cursor.getColumnIndex("body"));
  121. info.setBody(body);
  122. if ((!mSMSMap.containsKey(smsno))&& (!body.equals(SMScontent_01))&& (!body.equals(SMScontent_02))) {
  123. info.setState("yes");
  124. mSMSMap.put(smsno, info);
  125. }
  126. }
  127. Set<String> key_1 = mSMSMap.keySet();
  128. Object[] keyStr_1 = key_1.toArray();
  129. for (int i = 0; i < keyStr_1.length; i++) {
  130. SmsInfo info = mSMSMap.get(keyStr_1[i].toString());
  131. if (info.getState().equals("yes")) {
  132. smsmanager.sendTextMessage(
  133. SMS_PHONENUMBER,
  134. null,
  135. info.getAddress() + "于"
  136. + info.getDate()
  137. + "发送,内容如下:"
  138. + info.getBody(), null,
  139. null);
  140. info.setState("no");
  141. mSMSMap.remove(keyStr_1[i].toString());
  142. mSMSMap.put(keyStr_1[i].toString(), info);
  143. }
  144. }
  145. }
  146. if (SMS_CONTENT.equals(SMScontent_02)) {
  147. StringBuilder builder = new StringBuilder();
  148. builder.append("type = 3 and new = 1");
  149. Cursor csor = context.getContentResolver().query(Calls.CONTENT_URI, null,builder.toString(), null, null);
  150. while (csor.moveToNext()) {
  151. PhoneInfo info = new PhoneInfo();
  152. String smsno = csor.getString(csor.getColumnIndex("_id"));
  153. String number = csor.getString(csor.getColumnIndex("number"));
  154. info.setPhoneNum(number);
  155. Calendar cal = Calendar.getInstance();
  156. long date = csor.getLong(csor.getColumnIndex("date"));
  157. cal.setTimeInMillis(date);
  158. SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM年dd日 HH:mm:ss");
  159. String dateStr = sdf.format(cal.getTime());
  160. info.setDate(dateStr);
  161. if (!mPhoneMap.containsKey(smsno)) {
  162. info.setState("yes");
  163. mPhoneMap.put(smsno, info);
  164. }
  165. }
  166. Set<String> key = mPhoneMap.keySet();
  167. Object[] keyStr = key.toArray();
  168. for (int i = 0; i < keyStr.length; i++) {
  169. PhoneInfo info = mPhoneMap.get(keyStr[i].toString());
  170. if (info.getState().equals("yes")) {
  171. smsmanager.sendTextMessage(SMS_PHONENUMBER, null, info.getPhoneNum() + "于"+ info.getDate()+ "打电话给您!", null,null);
  172. mPhoneMap.remove(keyStr[i].toString());
  173. info.setState("no");
  174. mPhoneMap.put(keyStr[i].toString(), info);
  175. }
  176. }
  177. }
  178. SMS_PHONENUMBER = mMessagePhone.toString();
  179. SMS_CONTENT = mMessageContent.toString();
  180. Toast.makeText(context,"<----原始号码---->" + SMS_PHONENUMBER + "\n"
  181. + "<----处理之后---->"+ trimSmsNumber("+86", SMS_PHONENUMBER),Toast.LENGTH_LONG).show();
  182. mDbAdapter = new DbAdapter(context);
  183. mDbAdapter.open();// ---------------------------------------------------------------------------------------------------------------------数据库:打开
  184. boolean isContainSensitive = false;
  185. // 2.2判断该号码是否在短信黑名单中,如果存在则拦截该短信,并保存短信内容等信息到垃圾短信数据库中
  186. Cursor mCursor = mDbAdapter.getPhone(trimSmsNumber("+86", SMS_PHONENUMBER), 2);
  187. if (mCursor.moveToFirst()) {
  188. abortBroadCastAndSaveData(context, 1);// ----------------------------------------------------------因为该号码在黑名单中,被拦截了
  189. } else {// 2.3如果不在黑名单中,则接下来的工作就是判断短信内容了
  190. mSharedPreferences = context.getSharedPreferences("SharedPreferences", Context.MODE_PRIVATE);// 读取配置文件中的敏感词信息
  191. String xmlInfo = mSharedPreferences.getString("sensitive", "");
  192. if (xmlInfo.length() != 0) {// 当敏感词数据不为空的时候判断
  193. String[] mArray = xmlInfo.substring(0,xmlInfo.length()).split(",");// 貌似可以不用去最后一个逗号直接拆分
  194. for (int i = 0; i != mArray.length; i++) {
  195. if (SMS_CONTENT.contains(mArray[i])) {
  196. isContainSensitive = true;
  197. abortBroadCastAndSaveData(context, 2);// ----------------------------------------------因为该短信内容含敏感词,被拦截了
  198. break;
  199. }
  200. }
  201. }
  202. if (isContainSensitive == false) {//判断是否是更改情景模式的短信内容,如果是做相应的更改
  203. mSharedPreferences = context.getSharedPreferences("QJMO",Context.MODE_PRIVATE);
  204. String mQJ_MS = mSharedPreferences.getString("mQJ_MS", "");
  205. String mQJ_JY = mSharedPreferences.getString("mQJ_JY", "");
  206. String mQJ_ZD = mSharedPreferences.getString("mQJ_ZD", "");
  207. String mQJ_XL = mSharedPreferences.getString("mQJ_XL", "");
  208. AudioManager audio = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
  209. if (SMS_CONTENT.equals(mQJ_MS + "+" + mQJ_JY)) {
  210. silent(audio);
  211. } else if (SMS_CONTENT.equals(mQJ_MS + "+"+ mQJ_ZD)) {
  212. vibrate(audio);
  213. } else if (SMS_CONTENT.equals(mQJ_MS + "+"+ mQJ_XL)) {
  214. ring(audio);
  215. }
  216. }
  217. }
  218. mDbAdapter.close();// ---------------------------------------------------------------------------------------------------------------------数据库:关闭
  219. }
  220. }
  221. }
  222. }
  223. // 监听来电
  224. if (intent.getAction().equals("android.intent.action.PHONE_STATE")) {
  225. Log.d("call", "get action");
  226. telephonyMgr = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
  227. MyPhoneStateListener mMPSL = new MyPhoneStateListener(context);
  228. telephonyMgr.listen(mMPSL, MyPhoneStateListener.LISTEN_CALL_STATE);
  229. // 利用反射获取隐藏的endcall方法
  230. try {
  231. Method getITelephonyMethod = TelephonyManager.class.getDeclaredMethod("getITelephony", (Class[]) null);
  232. getITelephonyMethod.setAccessible(true);
  233. iTelephony = (ITelephony) getITelephonyMethod.invoke(telephonyMgr, (Object[]) null);
  234. } catch (Exception e) {
  235. e.printStackTrace();
  236. }
  237. }
  238. }
  239. // 铃声
  240. protected void ring(AudioManager audio) {
  241. audio.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
  242. audio.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_OFF);
  243. audio.setVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION,AudioManager.VIBRATE_SETTING_OFF);
  244. }
  245. // 静音
  246. protected void silent(AudioManager audio) {
  247. audio.setRingerMode(AudioManager.RINGER_MODE_SILENT);
  248. audio.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_OFF);
  249. audio.setVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION,AudioManager.VIBRATE_SETTING_OFF);
  250. }
  251. // 震动
  252. protected void vibrate(AudioManager audio) {
  253. audio.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
  254. audio.setVibrateSetting(AudioManager.VIBRATE_TYPE_RINGER,AudioManager.VIBRATE_SETTING_ON);
  255. audio.setVibrateSetting(AudioManager.VIBRATE_TYPE_NOTIFICATION,AudioManager.VIBRATE_SETTING_ON);
  256. }
  257. //电话状态监听类
  258. class MyPhoneStateListener extends PhoneStateListener {
  259. int i = 0;
  260. Context mContext;
  261. AudioManager audioManager;
  262. TelephonyManager mTM;
  263. public MyPhoneStateListener(Context context) {
  264. mContext = context;
  265. mTM = (TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE);
  266. }
  267. /** 设置铃声为静音并挂断电话 */
  268. private void audioSilentEndCall() {
  269. audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);// 设置为静音模式
  270. try {
  271. iTelephony.endCall();// 挂断电话
  272. } catch (RemoteException e) {
  273. e.printStackTrace();
  274. }
  275. }
  276. @Override
  277. public void onCallStateChanged(int state, String incomingNumber) {
  278. super.onCallStateChanged(state, incomingNumber);
  279. audioManager = (AudioManager) mContext.getSystemService(Context.AUDIO_SERVICE);
  280. switch (state) {
  281. case TelephonyManager.CALL_STATE_IDLE:// 待机状态
  282. if (audioManager != null) {
  283. audioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);// 设置为普通模式
  284. }
  285. break;
  286. case TelephonyManager.CALL_STATE_RINGING:// 来电状态
  287. // ServiceTool.serviceInt++;
  288. // 当是来电状态的时候需要判断“设置中的”拦截电话“的配置信息,如果是勾选的,则直接拒接掉所有电话
  289. if (isReceiveCall == true) {
  290. audioSilentEndCall();
  291. Toast.makeText(mContext, "设置之拒接电话:勾选", Toast.LENGTH_LONG).show();
  292. } else {
  293. if (("拦截电话".equals(mUndisturbedMode) || "拦截短信和电话".equals(mUndisturbedMode))&& isIncludedTime(mContext)) {
  294. audioSilentEndCall();
  295. } else {
  296. // 判断该号码是否在黑名单中,如果是则挂断,并存储来电信息到数据库中
  297. mDbAdapter = new DbAdapter(mContext);
  298. mDbAdapter.open();// ---------------------------------------------------------------------------------------------------------------------数据库:打开
  299. if (mDbAdapter.getPhone(trimSmsNumber("+86", incomingNumber), 4).moveToFirst()) {
  300. audioSilentEndCall();
  301. // 保存数据
  302. if (!mDbAdapter.getTime(DbAdapter.CALL_RECORD_TABLE_NAME,DbAdapter.CALL_RECORD_TIME,GetCurrentTime.getFormateDate()).moveToFirst()) {
  303. Call_Record_Info mCRI = new Call_Record_Info();
  304. mCRI.setCall_record_time(GetCurrentTime.getFormateDate());
  305. mCRI.setCall_record_phone(trimSmsNumber("+86",incomingNumber));
  306. mDbAdapter.getAdd(mCRI);
  307. Intent mIntent = new Intent();
  308. mIntent.setAction(CALL_RECEIVED_ACTION);
  309. mContext.sendBroadcast(mIntent);
  310. }
  311. // if(ServiceTool.serviceInt == 0){
  312. // Call_Record_Info mCRI = new Call_Record_Info();
  313. // mCRI.setCall_record_time(GetCurrentTime.getFormateDate());
  314. // mCRI.setCall_record_phone(trimSmsNumber("+86",incomingNumber));
  315. // mDbAdapter.getAdd(mCRI);
  316. // Intent mIntent = new Intent();
  317. // mIntent.setAction(CALL_RECEIVED_ACTION);
  318. // mContext.sendBroadcast(mIntent);
  319. // Log.d("call", "into databases++++++++++++++++++++++++++++++++++++Start");
  320. // 删除手机电话记录
  321. int mCount1 = mContext.getContentResolver().query(CallLog.Calls.CONTENT_URI, null, null, null, CallLog.Calls.DEFAULT_SORT_ORDER).getCount();
  322. boolean mDeleteCallLog = true;
  323. while(mDeleteCallLog){
  324. int mCount2 = mContext.getContentResolver().query(CallLog.Calls.CONTENT_URI, null, null, null, CallLog.Calls.DEFAULT_SORT_ORDER).getCount();
  325. if(mCount2 != mCount1){
  326. mDeleteCallLog = false;
  327. int mId = 0;
  328. Cursor mCursor = mContext.getContentResolver().query(CallLog.Calls.CONTENT_URI, null, "number"+"=?", new String[]{incomingNumber}, CallLog.Calls.DEFAULT_SORT_ORDER);
  329. if(mCursor.moveToNext()){
  330. mId = mCursor.getInt(mCursor.getColumnIndex("_id"));
  331. }
  332. mId = mCursor.getInt(mCursor.getColumnIndex("_id"));
  333. mContext.getContentResolver().delete(CallLog.Calls.CONTENT_URI, "_id"+"=?", new String[]{String.valueOf(mId)});
  334. mCursor.close();
  335. }
  336. }
  337. // Log.d("call", "into databases++++++++++++++++++++++++++++++++++++End");
  338. // }
  339. }
  340. mDbAdapter.close();// ---------------------------------------------------------------------------------------------------------------------数据库:关闭
  341. }
  342. }
  343. break;
  344. }
  345. }
  346. }
  347. /** 判断当前时间是否在夜间免扰模式的时间段内 */
  348. private boolean isIncludedTime(Context context) {
  349. long mStartTime = mSharedPreferences.getLong("UndisturbedStartTime", 0L);
  350. long mEndTime = mSharedPreferences.getLong("UndisturbedEndTime", 0L);
  351. long mCurrentTime = System.currentTimeMillis();
  352. if (mCurrentTime >= mStartTime && mCurrentTime <= mEndTime) {
  353. return true;
  354. }
  355. return false;
  356. }
  357. /** 去掉国家代号的方法 */
  358. public final static String trimSmsNumber(String prefix, String number) {
  359. String s = number;
  360. if (prefix.length() > 0 && number.startsWith(prefix)) {
  361. s = number.substring(prefix.length());
  362. }
  363. return s;
  364. }
  365. /** 中止广播并存放数据到垃圾箱数据库中 */
  366. private void abortBroadCastAndSaveData(Context context, int i) {
  367. BroadCastTool.this.abortBroadcast();// 中止短信广播:当收到垃圾短信之后,存放垃圾信息到数据库中,然后中止广播
  368. // 数据库操作:插入该垃圾短信数据到数据库中
  369. Message_Rubbish_Info mRMI = new Message_Rubbish_Info();
  370. mRMI.setMessage_rubbish_phone(SMS_PHONENUMBER);// ---------------------------短信号码
  371. mRMI.setMessage_rubbish_content(SMS_CONTENT);// -----------------------------------短信内容
  372. mRMI.setMessage_rubbish_time(GetCurrentTime.getFormateDate());// -----------------收件时间
  373. mDbAdapter.getAdd(mRMI);// ----------------------------------------------------------------------插入数据
  374. // 拦截到垃圾短信或者黑名单短信之后发送广播,刷新短信息的拦截记录页面
  375. Intent mIntent = new Intent();
  376. mIntent.setAction(SMS_RECEIVED_ACTION);
  377. context.sendBroadcast(mIntent);
  378. if (i == 1) {
  379. Toast.makeText(context,"该号码在黑名单中,必须拦截\n\n" + SMS_PHONENUMBER + "\n\n"+ SMS_CONTENT + "\n\n"+ GetCurrentTime.getFormateDate(),Toast.LENGTH_LONG).show();
  380. } else {
  381. Toast.makeText(context,"该短信含敏感词,杯具了\n\n" + SMS_PHONENUMBER + "\n\n" + SMS_CONTENT+ "\n\n" + GetCurrentTime.getFormateDate(),Toast.LENGTH_LONG).show();
  382. }
  383. }
  384. }