diff --git a/.npmignore b/.npmignore index e45b559b..e5be9c99 100644 --- a/.npmignore +++ b/.npmignore @@ -1,2 +1,5 @@ example/ node_modules/ +.idea/ +.github/ +docs/ diff --git a/README.md b/README.md index b76b0722..cba7f9b9 100644 --- a/README.md +++ b/README.md @@ -86,6 +86,8 @@ RNCallKeep.setup(options).then(accepted => {}); - `additionalPermissions`: [PermissionsAndroid] (optional) Any additional permissions you'd like your app to have at first launch. Can be used to simplify permission flows and avoid multiple popups to the user at different times. + +`setup` calls internally `registerPhoneAccount` and `registerEvents`. ## Constants @@ -547,6 +549,28 @@ Allows to remove the listener on an event. RNCallKeep.removeEventListener('checkReachability'); ``` +### registerPhoneAccount + +Registers Android phone account manually, useful for custom permission prompts when you don't want to call `setup()`. +This method is called by `setup`, if you already use setup you don't need it. + +_This feature is available only on Android._ + +```js +RNCallKeep.registerPhoneAccount(); +``` + +### registerAndroidEvents + +Registers Android UI events, useful when you don't want to call `setup()`. +This method is called by `setup`, if you already use setup you don't need it. + +_This feature is available only on Android._ + +```js +RNCallKeep.registerAndroidEvents(); +``` + ## Example A full example is available in the [example](https://github.com/react-native-webrtc/react-native-callkeep/tree/master/example) folder. diff --git a/android/src/main/java/io/wazo/callkeep/RNCallKeepModule.java b/android/src/main/java/io/wazo/callkeep/RNCallKeepModule.java index 25a06261..dceb8540 100644 --- a/android/src/main/java/io/wazo/callkeep/RNCallKeepModule.java +++ b/android/src/main/java/io/wazo/callkeep/RNCallKeepModule.java @@ -121,14 +121,32 @@ public void setup(ReadableMap options) { this._settings = options; if (isConnectionServiceAvailable()) { - this.registerPhoneAccount(this.getAppContext()); - voiceBroadcastReceiver = new VoiceBroadcastReceiver(); - registerReceiver(); - VoiceConnectionService.setPhoneAccountHandle(handle); + this.registerPhoneAccount(); + this.registerEvents(); VoiceConnectionService.setAvailable(true); } } + @ReactMethod + public void registerPhoneAccount() { + if (!isConnectionServiceAvailable()) { + return; + } + + this.registerPhoneAccount(this.getAppContext()); + } + + @ReactMethod + public void registerEvents() { + if (!isConnectionServiceAvailable()) { + return; + } + + voiceBroadcastReceiver = new VoiceBroadcastReceiver(); + registerReceiver(); + VoiceConnectionService.setPhoneAccountHandle(handle); + } + @ReactMethod public void displayIncomingCall(String uuid, String number, String callerName) { if (!isConnectionServiceAvailable() || !hasPhoneAccount()) { @@ -346,6 +364,10 @@ public void updateDisplay(String uuid, String displayName, String uri) { @ReactMethod public void hasPhoneAccount(Promise promise) { + if (telecomManager == null) { + this.initializeTelecomManager(); + } + promise.resolve(hasPhoneAccount()); } @@ -439,15 +461,22 @@ public void backToForeground() { } } + private void initializeTelecomManager() { + Context context = this.getAppContext(); + ComponentName cName = new ComponentName(context, VoiceConnectionService.class); + String appName = this.getApplicationName(context); + + handle = new PhoneAccountHandle(cName, appName); + telecomManager = (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE); + } + private void registerPhoneAccount(Context appContext) { if (!isConnectionServiceAvailable()) { return; } - ComponentName cName = new ComponentName(this.getAppContext(), VoiceConnectionService.class); - String appName = this.getApplicationName(appContext); - - handle = new PhoneAccountHandle(cName, appName); + this.initializeTelecomManager(); + String appName = this.getApplicationName(this.getAppContext()); PhoneAccount.Builder builder = new PhoneAccount.Builder(handle, appName) .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER); @@ -461,7 +490,6 @@ private void registerPhoneAccount(Context appContext) { PhoneAccount account = builder.build(); telephonyManager = (TelephonyManager) this.getAppContext().getSystemService(Context.TELEPHONY_SERVICE); - telecomManager = (TelecomManager) this.getAppContext().getSystemService(Context.TELECOM_SERVICE); telecomManager.registerPhoneAccount(account); } @@ -492,7 +520,8 @@ private Boolean hasPermissions() { } private static boolean hasPhoneAccount() { - return isConnectionServiceAvailable() && telecomManager != null && telecomManager.getPhoneAccount(handle).isEnabled(); + return isConnectionServiceAvailable() && telecomManager != null + && telecomManager.getPhoneAccount(handle) != null && telecomManager.getPhoneAccount(handle).isEnabled(); } private void registerReceiver() { diff --git a/index.d.ts b/index.d.ts index c6032e15..60c3f4e3 100644 --- a/index.d.ts +++ b/index.d.ts @@ -54,11 +54,19 @@ export default class RNCallKeep { static hasDefaultPhoneAccount(): boolean { } - + static answerIncomingCall(uuid: string) { } + static registerPhoneAccount(): void { + + } + + static registerAndroidEvents(): void { + + } + static displayIncomingCall( uuid: string, handle: string, diff --git a/index.js b/index.js index b09c0477..ec85cde5 100644 --- a/index.js +++ b/index.js @@ -48,6 +48,21 @@ class RNCallKeep { return this._setupIOS(options.ios); }; + registerPhoneAccount = () => { + if (isIOS) { + return; + } + RNCallKeepModule.registerPhoneAccount(); + }; + + + registerAndroidEvents = () => { + if (isIOS) { + return; + } + RNCallKeepModule.registerEvents(); + }; + hasDefaultPhoneAccount = async (options) => { if (!isIOS) { return this._hasDefaultPhoneAccount(options);