/* Copyright 2010 Cesar Valiente Gordo This file is part of QuiteSleep. QuiteSleep is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. QuiteSleep is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with QuiteSleep. If not, see <http://www.gnu.org/licenses/>. */ package es.cesar.quitesleep.operations; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import android.content.Context; import android.media.AudioManager; import android.os.Vibrator; import es.cesar.quitesleep.ddbb.CallLog; import es.cesar.quitesleep.ddbb.ClientDDBB; import es.cesar.quitesleep.ddbb.Contact; import es.cesar.quitesleep.ddbb.Schedule; import es.cesar.quitesleep.mailmessages.SendMail; import es.cesar.quitesleep.smsmessages.SendSMSThread; import es.cesar.quitesleep.staticValues.ConfigAppValues; import es.cesar.quitesleep.utils.ExceptionUtils; import es.cesar.quitesleep.utils.QSLog; import es.cesar.quitesleep.utils.TokenizerUtils; /** * * @author Cesar Valiente Gordo * @mail cesar.valiente@gmail.com * */ public class IncomingCallOperations extends Thread { private static final String CLASS_NAME = "es.cesar.quitesleep.utils.operations.IncomingCallOperations"; private String incomingCallNumber; //---------------- Getters & Setters ----------------------------------// public String getIncomingCallNumber() { return incomingCallNumber; } public void setIncomingCallNumber(String incomingCallNumber) { this.incomingCallNumber = incomingCallNumber; } //------------------------------------------------------------------------// /** * Constructor * @param incomingCallNumber */ public IncomingCallOperations(String incomingCallNumber) { this.incomingCallNumber = incomingCallNumber; } @Override public void run () { silentIncomingCall(); } /** * Function that check if the incoming call number is from a banned contact, * if is true, put the mobile to silent mode (sound and vibrate), if is * false do nothing. * * UPDATE 05-05-2010: now, we puts always the phone in silent mode when incoming * call, but, then, quitesleep check if the contact is banned and if is in the * schedule time, if is true, creates a new CallLog object, and we don't nothing * with the phone mode, so it was put in silent mode at beginning. * But if the incoming phone not is from a banned contact and/or if not * is in the schedule time, put the mobile phone in normal mode. * I have done this, because, is the only manner i get, that the phone never ring * one sec when an incoming call from a banned contact arrives and the only way * to put the mobile phone with vibrator off, one time the mobile phone is in normal * mode the ring is too on. * The inconvenience is that whatever incoming call the first tone the mobile * phone silence it, not is the perfect way but is the only and the best way * that i have reached with >Android 2.0 at day. * */ public void silentIncomingCall () { try { /* Put the mobile phone in silent mode (sound+vibration) * Here i put this for silent all incoming call for salomonic decision * that silent all calls for later if the contact is banned let this * silent mode and if the contact isn't banned put in normal mode. * I use this because sometimes a ring second sound when an incoming call. */ //putRingerModeSilent(); ClientDDBB clientDDBB = new ClientDDBB(); String phoneNumberWhithoutDashes = TokenizerUtils.tokenizerPhoneNumber(incomingCallNumber, null); Contact contactBanned = clientDDBB.getSelects().selectBannedContactForPhoneNumber( phoneNumberWhithoutDashes); //If the contact is in the banned list if (contactBanned != null) { if (QSLog.DEBUG_D)QSLog.d(CLASS_NAME, "Contact: " + contactBanned.getContactName() + "\t isBanned: " + contactBanned.isBanned()); //create the CallLog object for log calls. CallLog callLog = new CallLog(); //check if the call is in the interval time boolean isInInterval = checkSchedule(callLog, clientDDBB); if (isInInterval) { //Put the mobile phone in silent mode (sound+vibration) putRingerModeSilent(); /* Check if the mail service is running, if it is true * create a SendMail object for try to send one or more * email to the contact with the incoming number */ sendMail(incomingCallNumber, callLog, clientDDBB); /* Check if the sms service is running, if it is true * create a SendSMS object for try to send a SMS to * the contact with the incoming number */ sendSMS(incomingCallNumber, callLog, clientDDBB); //get the nomOrder for the new CallLog int numOrder = clientDDBB.getSelects().countCallLog(); if (QSLog.DEBUG_D)QSLog.d(CLASS_NAME, "CallLog numOrder: " + numOrder); //Set the parameters and save it callLog.setPhoneNumber(phoneNumberWhithoutDashes); callLog.setContact(contactBanned); callLog.setNumOrder(numOrder+1); clientDDBB.getInserts().insertCallLog(callLog); clientDDBB.commit(); clientDDBB.close(); } //If the call isn't in the interval time else { if (QSLog.DEBUG_D)QSLog.d(CLASS_NAME, "No está en el intervalo"); //putRingerModeNormal(); clientDDBB.close(); } } //If the incoming call number isn't of the any banned contact else { if (QSLog.DEBUG_D)QSLog.d(CLASS_NAME, "ContactBanned == NULL!!!!"); //putRingerModeNormal(); clientDDBB.close(); } }catch (Exception e) { if (QSLog.DEBUG_E)QSLog.e(CLASS_NAME, ExceptionUtils.exceptionTraceToString( e.toString(), e.getStackTrace())); } } /** * Compare the present time with the schedule start and end times (interval) * * @return true if the present time is in the interval or false * if isn't * @see boolean */ private boolean checkSchedule (CallLog callLog, ClientDDBB clientDDBB) { try { //ClientDDBB clientDDBB = new ClientDDBB(); Schedule schedule = clientDDBB.getSelects().selectSchedule(); //clientDDBB.close(); if (schedule != null && CheckSettingsOperations.checkDayWeek(schedule)) { return isInInterval(callLog, schedule); } return false; }catch (Exception e) { if (QSLog.DEBUG_E)QSLog.e(CLASS_NAME, ExceptionUtils.exceptionTraceToString( e.toString(), e.getStackTrace())); return false; } } /** * Function that check if the call incoming with the now time, is between the * twho hours specified as start and end of the interval specified by the user. * * @param callLog * @param schedule * @return true or false if the incoming call with the actual hour * is in an interval delimit by the start and end hours * @see boolean */ private boolean isInInterval (CallLog callLog, Schedule schedule) { try { DateFormat timeFormat = DateFormat.getTimeInstance(DateFormat.SHORT); Calendar dateAndTime = Calendar.getInstance(); String timeNow = timeFormat.format(dateAndTime.getTime()); String timeStart = schedule.getStartFormatTime(); String timeEnd = schedule.getEndFormatTime(); String timeNowComplete = getCompleteDate(dateAndTime); if (QSLog.DEBUG_D)QSLog.d(CLASS_NAME, "time now: " + timeNowComplete); callLog.setTimeCall(timeNowComplete); SimpleDateFormat parser = new SimpleDateFormat("HH:mm"); Date start = parser.parse(timeStart); Date end = parser.parse(timeEnd); Date now = parser.parse(timeNow); if (QSLog.DEBUG_D)QSLog.d(CLASS_NAME, "start: " + start + "\ttimeStart: " + timeStart); if (QSLog.DEBUG_D)QSLog.d(CLASS_NAME, "end: " + end + "\ttimeEnd: " + timeEnd); if (QSLog.DEBUG_D)QSLog.d(CLASS_NAME, "now: " + now + "\timeNow: " + timeNow); String dayCompleteString = "24:00"; Date dayComplete = parser.parse(dayCompleteString); String dayInitString = "00:00"; Date dayInit = parser.parse(dayInitString); final int INCREASE = 24; boolean isInInterval; //If both times are equals (24h) (si 8:00 = 8:00) if (start.compareTo(end) == 0) isInInterval = true; //(Si start=10:00 end=21:00)) //If end time is after than start time (ie: start=10:00 end=21:00) else if (end.after(start) && (now.after(start) && now.before(end))) isInInterval = true; /* If end time is before than start time (ie: start=22:00 end=3:00) * then, we must be add 24 to the end time. (so ie: start=22:00 end:27:00) */ //(Si start=22:00 end=3:00 ==> newEnd=3:00+24=27:00) else if (end.before(start)) { String newEndTimeString = TokenizerUtils.addIncreaseDate( timeEnd, INCREASE, null); Date newEndTime = parser.parse(newEndTimeString); /* (Si start=22:00 now=23:00 dayComplete=24:00, antes * hemos comprobado que end<start==> end: 3:00) */ if (now.after(start) && now.before(dayComplete)) isInInterval = true; /* (Si now>00:00==> now=2:00 now<newEnd(27:00) ==> now=2:00+24=26:00) * así que ahora queda start=23:00 end=27:00 y now=26:00 */ else if (now.after(dayInit) && now.before(newEndTime)) { String newNowTimeString = TokenizerUtils.addIncreaseDate( timeNow, INCREASE, null); Date newNowTime = parser.parse(newNowTimeString); if (newNowTime.after(start) && newNowTime.before(newEndTime)) isInInterval = true; else isInInterval = false; }else isInInterval = false; }else isInInterval = false; if (QSLog.DEBUG_D)QSLog.d(CLASS_NAME, "Está en el intervalo: " + isInInterval); return isInInterval; }catch (Exception e) { if (QSLog.DEBUG_E)QSLog.e(CLASS_NAME, ExceptionUtils.exceptionTraceToString( e.toString(), e.getStackTrace())); return false; } } /** * Get the compelte format date in English mode * * @param now * @return the complete format date * @see String */ private String getCompleteDate (Calendar now) { try { return (now.get(Calendar.MONTH) + 1) + "-" + now.get(Calendar.DATE) + "-" + now.get(Calendar.YEAR) + " " + now.get(Calendar.HOUR_OF_DAY) + ":" + now.get(Calendar.MINUTE) + ":" + now.get(Calendar.SECOND); }catch (Exception e) { if (QSLog.DEBUG_E)QSLog.e(CLASS_NAME, ExceptionUtils.exceptionTraceToString( e.toString(), e.getStackTrace())); return null; } } /** * Put the vibrator in mode off */ private void vibrateOff () { try { String vibratorService = Context.VIBRATOR_SERVICE; Vibrator vibrator = (Vibrator)ConfigAppValues.getContext(). getSystemService(vibratorService); vibrator.cancel(); }catch (Exception e) { if (QSLog.DEBUG_E)QSLog.e(CLASS_NAME, ExceptionUtils.exceptionTraceToString( e.toString(), e.getStackTrace())); } } /** * Send mail to the contact caller * @param incomingNumber * @param callLog * @param clientDDBB */ private void sendMail (String incomingNumber, CallLog callLog, ClientDDBB clientDDBB) { try { if (CheckSettingsOperations.checkMailService(clientDDBB)) { //------------------------------------------------------------// //Send mail using Threads SendMail sendMail = new SendMail(incomingNumber, callLog); Thread threadMail = new Thread(sendMail); threadMail.start(); threadMail.join(); //------------------------------------------------------------// //------------------------------------------------------------// //Send mail without use Threads /* SendMail sendMail = new SendMail(incomingNumber, callLog); sendMail.sendMail(); */ } }catch (Exception e) { if (QSLog.DEBUG_E)QSLog.e(CLASS_NAME, ExceptionUtils.exceptionTraceToString( e.toString(), e.getStackTrace())); } } /** * Send SMS message to the contact caller * * @param incomingNumber * @param callLog * @param clientDDBB */ private void sendSMS (String incomingNumber, CallLog callLog, ClientDDBB clientDDBB) { try { if (CheckSettingsOperations.checkSmsService(clientDDBB)) { if (QSLog.DEBUG_D)QSLog.d(CLASS_NAME, "antes de enviar el sms"); //-- If u choose use Android Service for send SMS use this --// /* ConfigAppValues.getContext().startService( new Intent( ConfigAppValues.getContext(), SendSMSService.class).putExtra( ConfigAppValues.RECEIVER, incomingNumber)); */ //------------------------------------------------------------// //----- If u choose Java Thread for send SMS use this -----// SendSMSThread sendSMS = new SendSMSThread(incomingNumber, callLog); sendSMS.start(); sendSMS.join(); //------------------------------------------------------------// //------------------------------------------------------------// //Use without using threads /* SendSMSThread sendSMS = new SendSMSThread(incomingNumber); sendSMS.sendSms(); */ //------------------------------------------------------------// } }catch (Exception e) { if (QSLog.DEBUG_E)QSLog.e(CLASS_NAME, ExceptionUtils.exceptionTraceToString( e.toString(), e.getStackTrace())); } } /** * Put the mobile in silence mode (audio and vibrate) * */ private void putRingerModeSilent () { try { if (QSLog.DEBUG_D)QSLog.d(CLASS_NAME, "Poniendo el movil en modo silencio"); AudioManager audioManager = (AudioManager)ConfigAppValues.getContext().getSystemService(Context.AUDIO_SERVICE); audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT); }catch (Exception e) { if (QSLog.DEBUG_E)QSLog.e(CLASS_NAME, ExceptionUtils.exceptionTraceToString( e.toString(), e.getStackTrace())); } } private void putRingerModeNormal () { try { if (QSLog.DEBUG_D)QSLog.d(CLASS_NAME, "Poniendo el movil en modo normal"); AudioManager audioManager = (AudioManager)ConfigAppValues.getContext().getSystemService(Context.AUDIO_SERVICE); audioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL); }catch (Exception e) { if (QSLog.DEBUG_E)QSLog.e(CLASS_NAME, ExceptionUtils.exceptionTraceToString( e.toString(), e.getStackTrace())); } } }