This commit is contained in:
meet2711
2024-03-15 15:43:31 +05:30
parent f3afd81571
commit 26f2f6ccc2
5 changed files with 207 additions and 6 deletions

View File

@@ -3,7 +3,20 @@
<component name="deploymentTargetDropDown">
<value>
<entry key="app">
<State />
<State>
<targetSelectedWithDropDown>
<Target>
<type value="QUICK_BOOT_TARGET" />
<deviceKey>
<Key>
<type value="VIRTUAL_DEVICE_PATH" />
<value value="$USER_HOME$/.android/avd/Pixel_7_Pro_API_33.avd" />
</Key>
</deviceKey>
</Target>
</targetSelectedWithDropDown>
<timeTargetWasSelectedWithDropDown value="2024-03-15T09:47:16.525599Z" />
</State>
</entry>
</value>
</component>

View File

@@ -13,6 +13,7 @@
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" /> <!-- permissions for app blocking -->
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" />
<uses-feature
android:name="android.hardware.telephony"
@@ -265,7 +266,9 @@
<receiver android:name=".patient_dashboard.foodreminders.FoodReminderYesReceiver"/>
<service android:name=".patient_dashboard.foodreminders.FoodReminderNotifyingService"/>
<receiver android:name=".patient_dashboard.CallReceiver" android:enabled="true" android:exported="true">
<receiver android:name=".patient_dashboard.CallReceiver"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>

View File

@@ -1,18 +1,197 @@
package com.app.simplitend.patient_dashboard;
import static com.app.simplitend.callwhitelisting.CallUnBlockingWorker.CALL_BLOCKING_WORk;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telecom.TelecomManager;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.telephony.TelephonyManager;
import android.util.Log;
import androidx.work.OneTimeWorkRequest;
import androidx.work.WorkManager;
import androidx.work.WorkRequest;
import com.app.simplitend.apputils.AppUtil;
import com.app.simplitend.callwhitelisting.CallUnBlockingWorker;
import com.google.i18n.phonenumbers.PhoneNumberUtil;
import com.google.i18n.phonenumbers.Phonenumber;
import java.lang.reflect.Method;
import java.util.Date;
import java.util.Set;
import java.util.concurrent.TimeUnit;
public class CallReceiver extends BroadcastReceiver {
private static final String TAG = "CallReceiver";
private static int lastState = TelephonyManager.CALL_STATE_IDLE;
private static Date callStartTime;
private static boolean isIncoming;
private static String savedNumber; //because the passed incoming is only valid in ringing
@Override
public void onReceive(Context context, Intent intent) {
TelecomManager telecomManager = (TelecomManager) context.getApplicationContext().getSystemService(TelecomManager.class);
if (intent.getExtras() == null) {
Log.d(TAG, "onReceive: EXTRAS ARE NULL");
return;
}
// logBundle(intent.getExtras());
String stateStr = intent.getExtras().getString(TelephonyManager.EXTRA_STATE);
String number = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
int state = 0;
if (TelephonyManager.EXTRA_STATE_IDLE.equals(stateStr)) {
state = TelephonyManager.CALL_STATE_IDLE;
} else if (TelephonyManager.EXTRA_STATE_OFFHOOK.equals(stateStr)) {
state = TelephonyManager.CALL_STATE_OFFHOOK;
} else if (TelephonyManager.EXTRA_STATE_RINGING.equals(stateStr)) {
state = TelephonyManager.CALL_STATE_RINGING;
}
onCallStateChanged(context, state, number);
}
}
protected void logBundle(Bundle bundle) {
if (bundle != null) {
for (String key : bundle.keySet()) {
Log.e(TAG, key + " : " + (bundle.get(key) != null ? bundle.get(key) : "NULL"));
}
}
}
//Derived classes should override these to respond to specific events of interest
protected void onIncomingCallStarted(Context ctx, String number, Date start) {
Log.d(TAG, "onIncomingCallStarted: " + number);
if (!AppUtil.isCallBlockingEnabled(ctx)) {
// senior has deactivated the call blocking feature
Log.d(TAG, "onIncomingCallStarted: CALL BLOCKING IS DEACTIVATED");
return;
}
try {
Phonenumber.PhoneNumber parsed_phone = PhoneNumberUtil.getInstance().parse(number, "US");
number = "+" + parsed_phone.getCountryCode() + parsed_phone.getNationalNumber();
} catch (Exception e) {
// do nothing
}
Log.d(TAG, "AFTER FORMATTING PHONE NUMBER -> " + number);
Set<String> white_contacts = AppUtil.getWhiteListedContacts(ctx);
Log.d(TAG, "WHITE LISTED CONTACTS -> " + white_contacts);
if (AppUtil.isUserSubscribed(ctx) && white_contacts != null && !white_contacts.contains(number)) {
disconnectCall();
Log.d(TAG, "CALL ENDED");
}
}
public void disconnectCall(){
try {
String serviceManagerName = "android.os.ServiceManager";
String serviceManagerNativeName = "android.os.ServiceManagerNative";
String telephonyName = "com.android.internal.telephony.ITelephony";
Class<?> telephonyClass;
Class<?> telephonyStubClass;
Class<?> serviceManagerClass;
Class<?> serviceManagerNativeClass;
Method telephonyEndCall;
Object telephonyObject;
Object serviceManagerObject;
telephonyClass = Class.forName(telephonyName);
telephonyStubClass = telephonyClass.getClasses()[0];
serviceManagerClass = Class.forName(serviceManagerName);
serviceManagerNativeClass = Class.forName(serviceManagerNativeName);
Method getService = // getDefaults[29];
serviceManagerClass.getMethod("getService", String.class);
Method tempInterfaceMethod = serviceManagerNativeClass.getMethod("asInterface", IBinder.class);
Binder tmpBinder = new Binder();
tmpBinder.attachInterface(null, "fake");
serviceManagerObject = tempInterfaceMethod.invoke(null, tmpBinder);
IBinder retbinder = (IBinder) getService.invoke(serviceManagerObject, "phone");
Method serviceMethod = telephonyStubClass.getMethod("asInterface", IBinder.class);
telephonyObject = serviceMethod.invoke(null, retbinder);
telephonyEndCall = telephonyClass.getMethod("endCall");
telephonyEndCall.invoke(telephonyObject);
} catch (Exception e) {
Log.e(TAG,
"FATAL ERROR: could not connect to telephony subsystem");
Log.e(TAG, "Exception object: " + e);
}
}
protected void onOutgoingCallStarted(Context ctx, String number, Date start) {
Log.d(TAG, "onOutgoingCallStarted: " + number);
if ("911".equals(number)){
Log.d(TAG, "CALLED 911");
WorkManager.getInstance(ctx).cancelAllWorkByTag(TAG);
WorkRequest workRequest = new OneTimeWorkRequest.Builder(CallUnBlockingWorker.class)
.setInitialDelay(30, TimeUnit.MINUTES)
.addTag(CALL_BLOCKING_WORk)
.build();
WorkManager.getInstance(ctx).enqueue(workRequest);
AppUtil.setIsCallBlockingEnabled(ctx, false);
Log.d(TAG, "CALL BLOCKING DISABLED");
}
}
protected void onIncomingCallEnded(Context ctx, String number, Date start, Date end) {
}
protected void onOutgoingCallEnded(Context ctx, String number, Date start, Date end) {
}
protected void onMissedCall(Context ctx, String number, Date start) {
}
//Deals with actual events
//Incoming call- goes from IDLE to RINGING when it rings, to OFFHOOK when it's answered, to IDLE when its hung up
//Outgoing call- goes from IDLE to OFFHOOK when it dials out, to IDLE when hung up
public void onCallStateChanged(Context context, int state, String number) {
if (lastState == state) {
//No change, debounce extras
return;
}
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
isIncoming = true;
callStartTime = new Date();
savedNumber = number;
onIncomingCallStarted(context, number, callStartTime);
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
//Transition of ringing->offhook are pickups of incoming calls. Nothing done on them
if (lastState != TelephonyManager.CALL_STATE_RINGING) {
isIncoming = false;
callStartTime = new Date();
onOutgoingCallStarted(context, number, callStartTime);
}
break;
case TelephonyManager.CALL_STATE_IDLE:
//Went to idle- this is the end of a call. What type depends on previous state(s)
if (lastState == TelephonyManager.CALL_STATE_RINGING) {
//Ring but no pickup- a miss
onMissedCall(context, savedNumber, callStartTime);
} else if (isIncoming) {
onIncomingCallEnded(context, savedNumber, callStartTime, new Date());
} else {
onOutgoingCallEnded(context, savedNumber, callStartTime, new Date());
}
break;
}
lastState = state;
}
}

View File

@@ -78,7 +78,6 @@ public class DashBoardActivity extends AppCompatActivity implements CgHomeContra
}), null, null);
}
requestPermissions(new String[]{Manifest.permission.CALL_PHONE}, 1212);
});
registerForActivityResult(new ActivityResultContracts.RequestPermission(),
@@ -94,6 +93,8 @@ public class DashBoardActivity extends AppCompatActivity implements CgHomeContra
RoleManager roleManager = getSystemService(RoleManager.class);
Intent i = roleManager.createRequestRoleIntent(RoleManager.ROLE_CALL_SCREENING);
startActivityForResult(i, 1214, null);
}else{
requestPermissions(new String[]{Manifest.permission.CALL_PHONE, Manifest.permission.READ_PHONE_STATE, Manifest.permission.ANSWER_PHONE_CALLS}, 1212);
}
}
}).launch(Manifest.permission.READ_CONTACTS);

View File

@@ -1,8 +1,10 @@
package com.app.simplitend.patient_dashboard;
import static com.app.simplitend.callwhitelisting.CallUnBlockingWorker.CALL_BLOCKING_WORk;
import static com.app.simplitend.caregiverdashboard.activities.deactivateacc.DeActivateAccountActivity.IS_PATIENT_KEY;
import androidx.appcompat.app.AppCompatActivity;
import androidx.work.WorkManager;
import android.app.ProgressDialog;
import android.content.Context;
@@ -74,6 +76,9 @@ public class PatSettingsActivity extends AppCompatActivity implements CgHomeCont
binding.callBlockCheck.setOnCheckedChangeListener(null);
binding.callBlockCheck.setChecked(true);
binding.callBlockCheck.setOnCheckedChangeListener(this);
WorkManager.getInstance(PatSettingsActivity.this)
.cancelAllWorkByTag(CALL_BLOCKING_WORk);
}),
"Turn off", ((dialogInterface, i) -> {
AppUtil.setIsCallBlockingEnabled(PatSettingsActivity.this, false);