Automation/app/src/main/java/com/jens/automation2/receivers/PhoneStatusListener.java

293 lines
9.4 KiB
Java
Raw Normal View History

2021-02-16 13:42:49 +01:00
package com.jens.automation2.receivers;
2021-05-16 19:51:22 +02:00
import android.Manifest;
2021-05-15 02:27:59 +02:00
import android.app.Service;
2021-02-16 13:42:49 +01:00
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import com.jens.automation2.ActivityPermissions;
import com.jens.automation2.AutomationService;
import com.jens.automation2.Miscellaneous;
import com.jens.automation2.R;
import com.jens.automation2.Rule;
2021-05-15 14:22:43 +02:00
import com.jens.automation2.Trigger;
2021-02-16 13:42:49 +01:00
import com.jens.automation2.Trigger.Trigger_Enum;
import java.util.ArrayList;
public class PhoneStatusListener implements AutomationListenerInterface
{
2021-05-15 02:27:59 +02:00
// protected static int currentStateIncoming = -1;
// protected static int currentStateOutgoing = -1;
2021-02-16 13:42:49 +01:00
protected static String lastPhoneNumber="";
protected static int lastPhoneDirection = -1; //0=incoming, 1=outgoing
2021-05-15 02:27:59 +02:00
protected static int currentState = -1;
2021-02-16 13:42:49 +01:00
protected static boolean incomingCallsReceiverActive = false;
protected static boolean outgoingCallsReceiverActive = false;
protected static IntentFilter outgoingCallsIntentFilter;
protected static IncomingCallsReceiver incomingCallsReceiverInstance;
protected static BroadcastReceiver outgoingCallsReceiverInstance;
public static boolean isIncomingCallsReceiverActive()
{
return incomingCallsReceiverActive;
}
public static boolean isOutgoingCallsReceiverActive()
{
return outgoingCallsReceiverActive;
}
protected static boolean receivedInitialIncomingSignal = false;
public static int getLastPhoneDirection()
{
return lastPhoneDirection;
}
protected static void setLastPhoneNumber(String lastPhoneNumber)
{
PhoneStatusListener.lastPhoneNumber = lastPhoneNumber;
}
public static String getLastPhoneNumber()
{
return lastPhoneNumber;
}
2021-05-14 20:07:46 +02:00
2021-05-15 02:27:59 +02:00
public static void setCurrentState(int currentState)
2021-05-14 20:07:46 +02:00
{
2021-05-15 02:27:59 +02:00
PhoneStatusListener.currentState = currentState;
}
public static int getCurrentState()
{
return currentState;
2021-05-14 20:07:46 +02:00
}
2021-02-16 13:42:49 +01:00
public static class IncomingCallsReceiver extends PhoneStateListener
{
@Override
public void onCallStateChanged(int state, String incomingNumber)
{
// Miscellaneous.logEvent("i", "Call state", "New call state: " + String.valueOf(state), 4);
2021-05-15 14:22:43 +02:00
/*
Unfortunately receivers for incoming and outgoing calls behave pretty differently:
The Outgoing-Receiver is called when starting a call (ringing)
It is not called when that outgoing call ends however, only the incoming receiver.
2021-05-14 20:07:46 +02:00
2021-05-15 14:22:43 +02:00
If the last call was outgoing the state has not changed to idle this is kind of a fake alert.
*/
2021-05-15 02:27:59 +02:00
2021-05-15 14:22:43 +02:00
if(lastPhoneDirection == 2 && currentState != TelephonyManager.CALL_STATE_IDLE)
2021-02-16 13:42:49 +01:00
{
2021-05-15 14:22:43 +02:00
// This status update is actually for an outgoing call
setCurrentState(state);
if(incomingNumber != null && incomingNumber.length() > 0) // check for null in case call comes in with suppressed number.
setLastPhoneNumber(incomingNumber);
switch(state)
{
case TelephonyManager.CALL_STATE_IDLE:
Miscellaneous.logEvent("i", "Call state", "New call state: CALL_STATE_IDLE", 4);
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Miscellaneous.logEvent("i", "Call state", "New call state: CALL_STATE_OFFHOOK", 4);
break;
case TelephonyManager.CALL_STATE_RINGING:
Miscellaneous.logEvent("i", "Call state", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.outgoingCallTo), incomingNumber), 4);
break;
}
2021-12-13 20:03:00 +01:00
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.phoneCall);
2021-05-15 14:22:43 +02:00
for(int i=0; i<ruleCandidates.size(); i++)
{
AutomationService asInstance = AutomationService.getInstance();
if(asInstance != null)
2021-12-07 23:10:37 +01:00
if(ruleCandidates.get(i).getsGreenLight(asInstance))
2021-05-15 14:22:43 +02:00
ruleCandidates.get(i).activate(asInstance, false);
}
2021-02-16 13:42:49 +01:00
}
2021-05-15 14:22:43 +02:00
else
2021-05-15 02:27:59 +02:00
{
2021-05-15 14:22:43 +02:00
// state != TelephonyManager.CALL_STATE_IDLE &&
setCurrentState(state);
setLastPhoneDirection(1);
if (incomingNumber != null && incomingNumber.length() > 0) // check for null in case call comes in with suppressed number.
setLastPhoneNumber(incomingNumber);
switch (state)
{
case TelephonyManager.CALL_STATE_IDLE:
Miscellaneous.logEvent("i", "Call state", "New call state: CALL_STATE_IDLE", 4);
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Miscellaneous.logEvent("i", "Call state", "New call state: CALL_STATE_OFFHOOK", 4);
break;
case TelephonyManager.CALL_STATE_RINGING:
Miscellaneous.logEvent("i", "Call state", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.incomingCallFrom), incomingNumber), 4);
break;
}
2021-12-13 20:03:00 +01:00
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.phoneCall);
2021-05-15 14:22:43 +02:00
for (int i = 0; i < ruleCandidates.size(); i++)
{
AutomationService asInstance = AutomationService.getInstance();
if (asInstance != null)
2021-12-07 23:10:37 +01:00
if (ruleCandidates.get(i).getsGreenLight(asInstance))
2021-05-15 14:22:43 +02:00
ruleCandidates.get(i).activate(asInstance, false);
}
2021-05-15 02:27:59 +02:00
}
2021-02-16 13:42:49 +01:00
}
}
2021-05-15 14:22:43 +02:00
static void setLastPhoneDirection(int i)
{
lastPhoneDirection = i;
}
2021-02-16 13:42:49 +01:00
public static class OutgoingCallsReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
2021-05-15 14:22:43 +02:00
/*
This receiver is ONLY triggered when outgoing calls ring, not when that call is established or ends.
*/
setLastPhoneDirection(2);
setCurrentState(TelephonyManager.CALL_STATE_RINGING);
2021-05-15 02:27:59 +02:00
2021-05-15 14:22:43 +02:00
String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
setLastPhoneNumber(phoneNumber);
Miscellaneous.logEvent("i", "Call state", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.outgoingCallTo), getLastPhoneNumber()), 4);
2021-05-15 02:27:59 +02:00
2021-12-13 20:03:00 +01:00
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidates(Trigger_Enum.phoneCall);
2021-05-15 02:27:59 +02:00
for(int i=0; i<ruleCandidates.size(); i++)
{
AutomationService asInstance = AutomationService.getInstance();
if(asInstance != null)
2021-12-07 23:10:37 +01:00
if(ruleCandidates.get(i).getsGreenLight(asInstance))
2021-05-15 02:27:59 +02:00
ruleCandidates.get(i).activate(asInstance, false);
}
2021-02-16 13:42:49 +01:00
}
}
public static boolean isInACall()
{
2021-05-15 02:27:59 +02:00
return getCurrentState() != TelephonyManager.CALL_STATE_IDLE;
2021-02-16 13:42:49 +01:00
}
2021-05-16 19:51:22 +02:00
/*
Future remark:
Apps that redirect outgoing calls should use the android.telecom.CallRedirectionService API.
Apps that perform call screening should use the android.telecom.CallScreeningService API.
*/
2021-02-16 13:42:49 +01:00
public static void startPhoneStatusListener(AutomationService automationService)
{
if(outgoingCallsIntentFilter == null)
{
outgoingCallsIntentFilter = new IntentFilter();
outgoingCallsIntentFilter.addAction(Intent.ACTION_NEW_OUTGOING_CALL);
}
if(incomingCallsReceiverInstance == null)
incomingCallsReceiverInstance = new IncomingCallsReceiver();
if(outgoingCallsReceiverInstance == null)
outgoingCallsReceiverInstance = new OutgoingCallsReceiver();
try
{
if(!incomingCallsReceiverActive)
{
Miscellaneous.logEvent("i", "PhoneStatusListener", "Starting PhoneStatusListener->incomingCallsReceiver", 4);
TelephonyManager tm = (TelephonyManager)automationService.getSystemService(Context.TELEPHONY_SERVICE);
tm.listen(incomingCallsReceiverInstance, PhoneStateListener.LISTEN_CALL_STATE);
incomingCallsReceiverActive = true;
}
if(!outgoingCallsReceiverActive)
{
Miscellaneous.logEvent("i", "PhoneStatusListener", "Starting PhoneStatusListener->outgoingCallsReceiver", 4);
automationService.registerReceiver(outgoingCallsReceiverInstance, outgoingCallsIntentFilter);
outgoingCallsReceiverActive = true;
}
}
catch(Exception ex)
{
Miscellaneous.logEvent("e", "PhoneStatusListener", "Error starting PhoneStatusListener: " + Log.getStackTraceString(ex), 3);
}
}
public static void stopPhoneStatusListener(AutomationService automationService)
{
try
{
if(incomingCallsReceiverActive)
{
Miscellaneous.logEvent("i", "PhoneStatusListener", "Stopping phoneStatusListener", 4);
TelephonyManager tm = (TelephonyManager)automationService.getSystemService(Context.TELEPHONY_SERVICE);
tm.listen(incomingCallsReceiverInstance, PhoneStateListener.LISTEN_NONE);
incomingCallsReceiverActive = false;
}
if(outgoingCallsReceiverActive)
{
Miscellaneous.logEvent("i", "PhoneStatusListener", "Stopping phoneStatusListener", 4);
automationService.unregisterReceiver(outgoingCallsReceiverInstance);
outgoingCallsReceiverActive = false;
}
}
catch(Exception ex)
{
Miscellaneous.logEvent("e", "PhoneStatusListener", "Error stopping phoneStatusListener: " + Log.getStackTraceString(ex), 3);
}
}
@Override
public void startListener(AutomationService automationService)
{
PhoneStatusListener.startPhoneStatusListener(automationService);
}
@Override
public void stopListener(AutomationService automationService)
{
PhoneStatusListener.stopPhoneStatusListener(automationService);
}
public static boolean haveAllPermission()
{
return
2021-05-16 19:51:22 +02:00
ActivityPermissions.havePermission(Manifest.permission.READ_PHONE_STATE, Miscellaneous.getAnyContext())
2021-02-16 13:42:49 +01:00
&&
2021-05-16 19:51:22 +02:00
ActivityPermissions.havePermission(Manifest.permission.PROCESS_OUTGOING_CALLS, Miscellaneous.getAnyContext());
2021-02-16 13:42:49 +01:00
}
@Override
public boolean isListenerRunning()
{
return PhoneStatusListener.incomingCallsReceiverActive | PhoneStatusListener.isOutgoingCallsReceiverActive();
}
@Override
public Trigger_Enum[] getMonitoredTrigger()
{
return new Trigger_Enum[] { Trigger_Enum.phoneCall };
}
}