NTP-57687 | Yash | Call Logs native module + Sim Details (#1143)
This commit is contained in:
3
App.tsx
3
App.tsx
@@ -21,7 +21,7 @@ import { hydrateGlobalImageMap } from '@common/CachedImage';
|
||||
import { CLICKSTREAM_EVENT_NAMES, LocalStorageKeys } from '@common/Constants';
|
||||
import { getAppVersion, sendDeviceDetailsToClickstream } from '@components/utlis/commonFunctions';
|
||||
import { linkingConf } from '@components/utlis/deeplinkingUtils';
|
||||
import { getBuildFlavour, restartApp } from '@components/utlis/DeviceUtils';
|
||||
import { fetchSimDetails, getBuildFlavour, restartApp } from '@components/utlis/DeviceUtils';
|
||||
import { initSentry } from '@components/utlis/sentry';
|
||||
import { GLOBAL, setGlobalBuildFlavour } from '@constants/Global';
|
||||
import { AppStates } from '@interfaces/appStates';
|
||||
@@ -141,6 +141,7 @@ function App() {
|
||||
});
|
||||
// Device Details
|
||||
sendDeviceDetailsToClickstream();
|
||||
fetchSimDetails();
|
||||
}, []);
|
||||
|
||||
React.useEffect(() => {
|
||||
|
||||
@@ -113,8 +113,8 @@ def jscFlavor = 'org.webkit:android-jsc:+'
|
||||
def enableHermes = project.ext.react.get("enableHermes", false);
|
||||
|
||||
|
||||
def VERSION_CODE = 263
|
||||
def VERSION_NAME = "2.19.4"
|
||||
def VERSION_CODE = 264
|
||||
def VERSION_NAME = "2.19.5"
|
||||
|
||||
android {
|
||||
namespace "com.avapp"
|
||||
|
||||
@@ -11,12 +11,14 @@ import android.app.Application;
|
||||
import android.content.Context;
|
||||
|
||||
import com.avapp.appInstallerModule.ApkInstallerPackage;
|
||||
import com.avapp.callLogs.CallLogsModulePackage;
|
||||
import com.avapp.contentProvider.ContentProviderPackage;
|
||||
import com.avapp.callModule.CallModulePackage;
|
||||
import com.avapp.deviceDataSync.DeviceDataSyncPackage;
|
||||
import com.avapp.photoModule.PhotoModulePackage;
|
||||
import com.avapp.phoneStateBroadcastReceiver.PhoneStateModulePackage;
|
||||
import com.avapp.sharedPreference.SharedPreferencesPackage;
|
||||
import com.avapp.simDetails.SimDetailsModulePackage;
|
||||
import com.avapp.utils.FirebaseRemoteConfigHelper;
|
||||
import com.avapp.wifiDetailsModule.WifiDetailsModulePackage;
|
||||
import com.avapp.restartApp.RestartPackage;
|
||||
@@ -76,6 +78,8 @@ public class MainApplication extends Application implements ReactApplication, Ap
|
||||
packages.add(new CallModulePackage());
|
||||
packages.add(new SharedPreferencesPackage());
|
||||
packages.add(new ContentProviderPackage());
|
||||
packages.add(new SimDetailsModulePackage());
|
||||
packages.add(new CallLogsModulePackage());
|
||||
return packages;
|
||||
}
|
||||
|
||||
|
||||
210
android/app/src/main/java/com/avapp/callLogs/CallLogsModule.java
Normal file
210
android/app/src/main/java/com/avapp/callLogs/CallLogsModule.java
Normal file
@@ -0,0 +1,210 @@
|
||||
package com.avapp.callLogs;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.database.Cursor;
|
||||
import android.provider.CallLog;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.content.ContextCompat;
|
||||
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.Promise;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.bridge.ReadableMap;
|
||||
import com.facebook.react.bridge.WritableArray;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public class CallLogsModule extends ReactContextBaseJavaModule {
|
||||
|
||||
private final ReactApplicationContext reactContext;
|
||||
|
||||
public CallLogsModule(ReactApplicationContext reactContext) {
|
||||
super(reactContext);
|
||||
this.reactContext = reactContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "CallLogsDetails";
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void loadAll(Promise promise) {
|
||||
load(-1, promise);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void load(int limit, Promise promise) {
|
||||
loadWithFilter(limit, null, promise);
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void loadWithFilter(int limit, @Nullable ReadableMap filter, Promise promise) {
|
||||
if (ContextCompat.checkSelfPermission(reactContext, Manifest.permission.READ_CALL_LOG)
|
||||
!= PackageManager.PERMISSION_GRANTED) {
|
||||
promise.reject("PERMISSION_DENIED", "READ_CALL_LOG permission not granted");
|
||||
return;
|
||||
}
|
||||
|
||||
WritableArray result = Arguments.createArray();
|
||||
Cursor cursor = null;
|
||||
|
||||
String selection = "";
|
||||
List<String> selectionArgsList = new ArrayList<>();
|
||||
boolean nullFilter = filter == null;
|
||||
|
||||
if (!nullFilter && filter.hasKey("minTimestamp")) {
|
||||
selection += CallLog.Calls.DATE + " >= ?";
|
||||
selectionArgsList.add(filter.getString("minTimestamp"));
|
||||
}
|
||||
|
||||
if (!nullFilter && filter.hasKey("maxTimestamp")) {
|
||||
if (!selection.isEmpty()) selection += " AND ";
|
||||
selection += CallLog.Calls.DATE + " <= ?";
|
||||
selectionArgsList.add(filter.getString("maxTimestamp"));
|
||||
}
|
||||
|
||||
try {
|
||||
String[] selectionArgs = selectionArgsList.toArray(new String[0]);
|
||||
cursor = reactContext.getContentResolver().query(
|
||||
CallLog.Calls.CONTENT_URI,
|
||||
null,
|
||||
selection.isEmpty() ? null : selection,
|
||||
selectionArgs,
|
||||
CallLog.Calls.DATE + " DESC"
|
||||
);
|
||||
if (cursor == null) {
|
||||
promise.resolve(result);
|
||||
return;
|
||||
}
|
||||
|
||||
int callLogCount = 0;
|
||||
|
||||
final int NUMBER_COLUMN_INDEX = cursor.getColumnIndex(CallLog.Calls.NUMBER);
|
||||
final int TYPE_COLUMN_INDEX = cursor.getColumnIndex(CallLog.Calls.TYPE);
|
||||
final int DATE_COLUMN_INDEX = cursor.getColumnIndex(CallLog.Calls.DATE);
|
||||
final int DURATION_COLUMN_INDEX = cursor.getColumnIndex(CallLog.Calls.DURATION);
|
||||
final int NAME_COLUMN_INDEX = cursor.getColumnIndex(CallLog.Calls.CACHED_NAME);
|
||||
final int FEATURES_COLUMN_INDEX = cursor.getColumnIndex(CallLog.Calls.FEATURES);
|
||||
|
||||
while (cursor.moveToNext() && shouldContinue(limit, callLogCount)) {
|
||||
String phoneNumber = cursor.getString(NUMBER_COLUMN_INDEX);
|
||||
int duration = cursor.getInt(DURATION_COLUMN_INDEX);
|
||||
String name = cursor.getString(NAME_COLUMN_INDEX);
|
||||
String timestampStr = cursor.getString(DATE_COLUMN_INDEX);
|
||||
long timestamp = safeParseLong(timestampStr, 0);
|
||||
boolean featuresAvailable = FEATURES_COLUMN_INDEX != -1;
|
||||
int features = featuresAvailable ? cursor.getInt(FEATURES_COLUMN_INDEX) : 0;
|
||||
|
||||
String isVideoCall = "undetected";
|
||||
String isWiFiCall = "undetected";
|
||||
String isHDCall = "undetected";
|
||||
String isPulledExternally = "undetected";
|
||||
String isVolte = "undetected";
|
||||
|
||||
if(featuresAvailable) {
|
||||
isVideoCall = String.valueOf((features & CallLog.Calls.FEATURES_VIDEO) != 0);
|
||||
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
|
||||
isWiFiCall = String.valueOf((features & CallLog.Calls.FEATURES_WIFI) != 0);
|
||||
isHDCall = String.valueOf((features & CallLog.Calls.FEATURES_HD_CALL) != 0);
|
||||
}
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N_MR1) {
|
||||
isPulledExternally = String.valueOf((features & CallLog.Calls.FEATURES_PULLED_EXTERNALLY) != 0);
|
||||
}
|
||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
|
||||
isVolte = String.valueOf((features & CallLog.Calls.FEATURES_VOLTE) != 0);
|
||||
}
|
||||
}
|
||||
|
||||
DateFormat df = SimpleDateFormat.getDateTimeInstance(SimpleDateFormat.MEDIUM, SimpleDateFormat.MEDIUM);
|
||||
String dateTime = df.format(new Date(timestamp));
|
||||
|
||||
String type = resolveCallType(cursor.getInt(TYPE_COLUMN_INDEX));
|
||||
WritableMap callLog = Arguments.createMap();
|
||||
callLog.putString("phoneNumber", phoneNumber);
|
||||
callLog.putInt("duration", duration);
|
||||
callLog.putString("name", name);
|
||||
callLog.putString("timestamp", timestampStr);
|
||||
callLog.putString("dateTime", dateTime);
|
||||
callLog.putString("type", type);
|
||||
callLog.putString("isVideoCall", isVideoCall);
|
||||
callLog.putString("isWiFiCall", isWiFiCall);
|
||||
callLog.putString("isHDCall", isHDCall);
|
||||
callLog.putString("isPulledExternally", isPulledExternally);
|
||||
callLog.putString("isVolte", isVolte);
|
||||
callLog.putInt("rawType", cursor.getInt(TYPE_COLUMN_INDEX));
|
||||
result.pushMap(callLog);
|
||||
callLogCount++;
|
||||
}
|
||||
|
||||
promise.resolve(result);
|
||||
} catch (Exception e) {
|
||||
promise.reject("CALL_LOG_ERROR", "Unexpected error while loading call logs", e);
|
||||
} finally {
|
||||
if (cursor != null && !cursor.isClosed()) {
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private long safeParseLong(String value, long defaultValue) {
|
||||
try {
|
||||
return Long.parseLong(value);
|
||||
} catch (NumberFormatException e) {
|
||||
return defaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
public static String[] toStringArray(JSONArray array) {
|
||||
if (array == null)
|
||||
return null;
|
||||
|
||||
String[] arr = new String[array.length()];
|
||||
for (int i = 0; i < arr.length; i++) {
|
||||
arr[i] = array.optString(i);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
private String resolveCallType(int callTypeCode) {
|
||||
switch (callTypeCode) {
|
||||
case CallLog.Calls.OUTGOING_TYPE:
|
||||
return "OUTGOING";
|
||||
case CallLog.Calls.INCOMING_TYPE:
|
||||
return "INCOMING";
|
||||
case CallLog.Calls.MISSED_TYPE:
|
||||
return "MISSED";
|
||||
case CallLog.Calls.VOICEMAIL_TYPE:
|
||||
return "VOICEMAIL";
|
||||
case CallLog.Calls.REJECTED_TYPE:
|
||||
return "REJECTED";
|
||||
case CallLog.Calls.BLOCKED_TYPE:
|
||||
return "BLOCKED";
|
||||
case CallLog.Calls.ANSWERED_EXTERNALLY_TYPE:
|
||||
return "ANSWERED_EXTERNALLY";
|
||||
default:
|
||||
return "UNKNOWN";
|
||||
}
|
||||
}
|
||||
|
||||
private boolean shouldContinue(int limit, int count) {
|
||||
return limit < 0 || count < limit;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.avapp.callLogs;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.avapp.simDetails.SimDetailsModule;
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.bridge.NativeModule;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.uimanager.ViewManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class CallLogsModulePackage implements ReactPackage {
|
||||
@NonNull
|
||||
@Override
|
||||
public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
|
||||
List<NativeModule> modules = new ArrayList<>();
|
||||
modules.add(new CallLogsModule(reactContext));
|
||||
return modules;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
package com.avapp.simDetails;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.Build;
|
||||
import android.telephony.SubscriptionInfo;
|
||||
import android.telephony.SubscriptionManager;
|
||||
import android.telephony.TelephonyManager;
|
||||
|
||||
import androidx.core.app.ActivityCompat;
|
||||
|
||||
import com.facebook.react.bridge.Promise;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.ReactContextBaseJavaModule;
|
||||
import com.facebook.react.bridge.ReactMethod;
|
||||
import com.facebook.react.bridge.WritableArray;
|
||||
import com.facebook.react.bridge.WritableMap;
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SimDetailsModule extends ReactContextBaseJavaModule {
|
||||
|
||||
ReactApplicationContext reactContext;
|
||||
|
||||
public SimDetailsModule(ReactApplicationContext reactContext) {
|
||||
super(reactContext);
|
||||
this.reactContext = reactContext;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "SimDetails";
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void getSimDetails(Promise promise) {
|
||||
try {
|
||||
WritableMap result = Arguments.createMap();
|
||||
|
||||
boolean hasPermission = ActivityCompat.checkSelfPermission(reactContext, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED;
|
||||
result.putBoolean("hasPermission", hasPermission);
|
||||
|
||||
WritableArray simsArray = Arguments.createArray();
|
||||
|
||||
if (hasPermission && Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP_MR1) {
|
||||
SubscriptionManager manager = (SubscriptionManager) reactContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE);
|
||||
TelephonyManager telManager = (TelephonyManager) reactContext.getSystemService(Context.TELEPHONY_SERVICE);
|
||||
|
||||
List<SubscriptionInfo> subscriptionInfos = manager.getActiveSubscriptionInfoList();
|
||||
|
||||
if (subscriptionInfos != null) {
|
||||
for (SubscriptionInfo subInfo : subscriptionInfos) {
|
||||
WritableMap simInfo = Arguments.createMap();
|
||||
simInfo.putString("carrierName", subInfo.getCarrierName().toString());
|
||||
simInfo.putString("displayName", subInfo.getDisplayName().toString());
|
||||
simInfo.putString("countryCode", subInfo.getCountryIso());
|
||||
simInfo.putInt("mcc", subInfo.getMcc());
|
||||
simInfo.putInt("mnc", subInfo.getMnc());
|
||||
simInfo.putBoolean("isNetworkRoaming", telManager.isNetworkRoaming());
|
||||
simInfo.putBoolean("isDataRoaming", subInfo.getDataRoaming() == 1);
|
||||
simInfo.putInt("simSlotIndex", subInfo.getSimSlotIndex());
|
||||
simInfo.putString("phoneNumber", subInfo.getNumber());
|
||||
simInfo.putString("simSerialNumber", subInfo.getIccId());
|
||||
simInfo.putInt("subscriptionId", subInfo.getSubscriptionId());
|
||||
|
||||
simsArray.pushMap(simInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
result.putArray("sims", simsArray);
|
||||
promise.resolve(result);
|
||||
} catch (Exception e) {
|
||||
promise.reject("SIM_ERROR", "Failed to get SIM details", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
package com.avapp.simDetails;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.facebook.react.ReactPackage;
|
||||
import com.facebook.react.bridge.NativeModule;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.uimanager.ViewManager;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class SimDetailsModulePackage implements ReactPackage {
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public List<NativeModule> createNativeModules(@NonNull ReactApplicationContext reactContext) {
|
||||
List<NativeModule> modules = new ArrayList<>();
|
||||
modules.add(new SimDetailsModule(reactContext));
|
||||
return modules;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public List<ViewManager> createViewManagers(@NonNull ReactApplicationContext reactContext) {
|
||||
return Collections.emptyList();
|
||||
}
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
263
|
||||
264
|
||||
|
||||
@@ -1 +1 @@
|
||||
2.19.4
|
||||
2.19.5
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "AV_APP",
|
||||
"version": "2.19.4",
|
||||
"buildNumber": "263",
|
||||
"version": "2.19.5",
|
||||
"buildNumber": "264",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"android:dev": "yarn move:dev && react-native run-android",
|
||||
|
||||
@@ -1644,6 +1644,11 @@ export const CLICKSTREAM_EVENT_NAMES = {
|
||||
name: 'FA_MAP_VIEW_EXPERIMENT_ERROR',
|
||||
description: 'Map view fetch experiment error',
|
||||
},
|
||||
|
||||
FA_FETCH_SIM_DETAILS: {
|
||||
name: 'FA_FETCH_SIM_DETAILS',
|
||||
description: 'Fetch SIM details',
|
||||
}
|
||||
} as const;
|
||||
|
||||
export enum MimeType {
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import { NativeModules } from 'react-native';
|
||||
import {GenericObject} from "@common/GenericTypes";
|
||||
import { GenericObject } from '@common/GenericTypes';
|
||||
import { CLICKSTREAM_EVENT_NAMES } from '@common/Constants';
|
||||
import { addClickstreamEvent } from '@services/clickstreamEventService';
|
||||
|
||||
interface CrashError {
|
||||
message: string;
|
||||
screenName: string;
|
||||
}
|
||||
|
||||
const { DeviceUtilsModule, RNRestart } = NativeModules; // this is the same name we returned in getName function.
|
||||
const { DeviceUtilsModule, RNRestart, SimDetails } = NativeModules; // this is the same name we returned in getName function.
|
||||
|
||||
export const restartJSBundle = () => RNRestart.restart();
|
||||
|
||||
@@ -27,7 +29,9 @@ export type buildConfig = {
|
||||
|
||||
export const getBuildInfo = (): Promise<string> => DeviceUtilsModule.getBuildInfo();
|
||||
|
||||
export const getBlacklistedApps = (blacklistedAppsObject: Record<string, boolean>): Promise<string> => DeviceUtilsModule.getBlacklistedApps(blacklistedAppsObject);
|
||||
export const getBlacklistedApps = (
|
||||
blacklistedAppsObject: Record<string, boolean>
|
||||
): Promise<string> => DeviceUtilsModule.getBlacklistedApps(blacklistedAppsObject);
|
||||
|
||||
export const alfredHandleSWWEvent = (error: Error) => {
|
||||
const { message = '', stack = '', name = '' } = error;
|
||||
@@ -72,8 +76,20 @@ export const sendContentToWhatsapp = (
|
||||
export const isAppInstalled = (packageName: string): Promise<boolean> =>
|
||||
DeviceUtilsModule.isAppInstalled(packageName);
|
||||
|
||||
export const getAppInfo = (packageName: string): Promise<GenericObject> => DeviceUtilsModule.getAppInfo(packageName);
|
||||
export const getAppInfo = (packageName: string): Promise<GenericObject> =>
|
||||
DeviceUtilsModule.getAppInfo(packageName);
|
||||
|
||||
export const getAppInfoFromFilePath = (filePath: string): Promise<GenericObject> => DeviceUtilsModule.getAppInfoFromFilePath(filePath);
|
||||
export const getAppInfoFromFilePath = (filePath: string): Promise<GenericObject> =>
|
||||
DeviceUtilsModule.getAppInfoFromFilePath(filePath);
|
||||
|
||||
export const restartApp = ():Promise<boolean> => DeviceUtilsModule.restartApp();
|
||||
export const restartApp = (): Promise<boolean> => DeviceUtilsModule.restartApp();
|
||||
|
||||
export const fetchSimDetails = async () => {
|
||||
try {
|
||||
const details = await SimDetails.getSimDetails();
|
||||
addClickstreamEvent(CLICKSTREAM_EVENT_NAMES.FA_FETCH_SIM_DETAILS, { details });
|
||||
return details;
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -1,20 +1,14 @@
|
||||
// @ts-expect-error
|
||||
import CallLogs from 'react-native-call-log'; // package does not have typescript implementation, used any type here
|
||||
import { DATA_SYNC_ENUM } from './dataSync.service';
|
||||
import { getGzipData, getMaxByPropFromList } from '../components/utlis/commonFunctions';
|
||||
import { API_STATUS_CODE } from '../components/utlis/apiHelper';
|
||||
import { logError } from '../components/utlis/errorUtils';
|
||||
import { Permission, PermissionsAndroid } from 'react-native';
|
||||
import { NativeModules, Permission, PermissionsAndroid } from 'react-native';
|
||||
import { addClickstreamEvent } from './clickstreamEventService';
|
||||
import { CLICKSTREAM_EVENT_NAMES } from '@common/Constants';
|
||||
import axios from 'axios';
|
||||
|
||||
const MAXIMUM_NUMBER_CALL_LOGS = 1000;
|
||||
|
||||
const callLogFilter = {
|
||||
minTimestamp: 0,
|
||||
};
|
||||
|
||||
enum CallTypeEnum {
|
||||
OUTGOING = 'OUTGOING',
|
||||
INCOMING = 'INCOMING',
|
||||
@@ -34,6 +28,11 @@ interface ICallLogs {
|
||||
rawType: number;
|
||||
timestamp: string;
|
||||
type: CallTypeEnum;
|
||||
isHDCall: boolean;
|
||||
isPulledExternally: boolean;
|
||||
isVideoCall: boolean;
|
||||
isVolte: boolean;
|
||||
isWiFiCall: boolean;
|
||||
}
|
||||
|
||||
interface ICallLogsDetails {
|
||||
@@ -42,6 +41,11 @@ interface ICallLogsDetails {
|
||||
duration?: number;
|
||||
name?: string;
|
||||
type?: CallTypeEnum;
|
||||
isHDCall?: boolean;
|
||||
isPulledExternally?: boolean;
|
||||
isVideoCall?: boolean;
|
||||
isVolte?: boolean;
|
||||
isWiFiCall?: boolean;
|
||||
}
|
||||
|
||||
interface ICallLogsDataPayload {
|
||||
@@ -71,15 +75,22 @@ export const callLogSyncServiceTele = async (url: string, syncFrom: string) => {
|
||||
const isCallLogsReadPermissionGranted = await checkReadPermissions(
|
||||
PermissionsAndroid.PERMISSIONS.READ_CALL_LOG
|
||||
);
|
||||
const { CallLogsDetails } = NativeModules;
|
||||
|
||||
if (isCallLogsReadPermissionGranted) {
|
||||
return new Promise((resolve, reject) => {
|
||||
CallLogs.loadAll().then(async (callLogJson: ICallLogs[]) => {
|
||||
CallLogsDetails.loadAll().then(async (callLogJson: ICallLogs[]) => {
|
||||
const callLogsDetailsList: ICallLogsDetails[] = callLogJson.map((callLogItem) => ({
|
||||
phoneNumber: callLogItem.phoneNumber,
|
||||
timestamp: Number.parseFloat(callLogItem.timestamp),
|
||||
duration: callLogItem.duration,
|
||||
name: callLogItem.name,
|
||||
type: callLogItem.type,
|
||||
isHDCall: callLogItem.isHDCall,
|
||||
isPulledExternally: callLogItem.isPulledExternally,
|
||||
isVideoCall: callLogItem.isVideoCall,
|
||||
isVolte: callLogItem.isVolte,
|
||||
isWiFiCall: callLogItem.isWiFiCall,
|
||||
}));
|
||||
|
||||
const maxCallLogsTimeStamp = getMaxByPropFromList(
|
||||
@@ -118,11 +129,13 @@ export const callLogSyncService = async (url: string, syncFrom: string) => {
|
||||
const isCallLogsReadPermissionGranted = await checkReadPermissions(
|
||||
PermissionsAndroid.PERMISSIONS.READ_CALL_LOG
|
||||
);
|
||||
const { CallLogsDetails } = NativeModules;
|
||||
|
||||
if (isCallLogsReadPermissionGranted) {
|
||||
return new Promise((resolve, reject) => {
|
||||
if (syncFrom) callLogFilter.minTimestamp = parseFloat(syncFrom);
|
||||
|
||||
CallLogs.load(MAXIMUM_NUMBER_CALL_LOGS, callLogFilter).then(
|
||||
CallLogsDetails.loadWithFilter(MAXIMUM_NUMBER_CALL_LOGS, {
|
||||
minTimestamp: syncFrom?.toString() || '0',
|
||||
}).then(
|
||||
async (callLogJson: Array<ICallLogs>) => {
|
||||
const callLogsDetailsList: ICallLogsDetails[] = callLogJson.map((callLogItem) => ({
|
||||
phoneNumber: callLogItem.phoneNumber,
|
||||
@@ -130,6 +143,11 @@ export const callLogSyncService = async (url: string, syncFrom: string) => {
|
||||
duration: callLogItem.duration,
|
||||
name: callLogItem.name,
|
||||
type: callLogItem.type,
|
||||
isHDCall: callLogItem.isHDCall,
|
||||
isPulledExternally: callLogItem.isPulledExternally,
|
||||
isVideoCall: callLogItem.isVideoCall,
|
||||
isVolte: callLogItem.isVolte,
|
||||
isWiFiCall: callLogItem.isWiFiCall,
|
||||
}));
|
||||
|
||||
const maxCallLogsTimeStamp = getMaxByPropFromList(
|
||||
|
||||
Reference in New Issue
Block a user