WebsiteBeaver / CordovaCall

Cordova CallKit & ConnectionService plugin for iOS/Android that displays the native call UI for VOIP apps
MIT License
196 stars 91 forks source link

Plugin initialize crashes app on Android 5.x (fix included) #46

Closed sachingarg05 closed 6 years ago

sachingarg05 commented 6 years ago

Plugin's initialize routine uses PhoneAccount.CAPABILITY_CALL_PROVIDER which is only available in Android M (SDK 23+), which causes a crash on Android 5.x.

https://developer.android.com/reference/android/telecom/PhoneAccount.html#CAPABILITY_CALL_PROVIDER says: "added in API level 23".

While the plugin can be 'used' only on Android M+, it should be possible to 'include' it in apps supporting older versions of Android. App can have OS version checks to decide when to use this plugin's functionality or not.

Fix is to add a

        if (android.os.Build.VERSION.SDK_INT >= 23) {

Around both instances of

            phoneAccount = new PhoneAccount.Builder(handle, appName)
                    .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
                    .build();
            tm.registerPhoneAccount(phoneAccount);

Full Patch for the fix (only adds two if conditions):

diff --git a/cordova-call/src/android/CordovaCall.java b/cordova-call/src/android/CordovaCall.java
index fcb5966..f7f66ea 100644
--- a/cordova-call/src/android/CordovaCall.java
+++ b/cordova-call/src/android/CordovaCall.java
@@ -70,10 +70,12 @@ public class CordovaCall extends CordovaPlugin {
                   .build();
           tm.registerPhoneAccount(phoneAccount);
         }
-        phoneAccount = new PhoneAccount.Builder(handle, appName)
-                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
-                 .build();
-        tm.registerPhoneAccount(phoneAccount);
+        if (android.os.Build.VERSION.SDK_INT >= 23) {
+            phoneAccount = new PhoneAccount.Builder(handle, appName)
+                    .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
+                    .build();
+            tm.registerPhoneAccount(phoneAccount);
+        }
         callbackContextMap.put("answer",new ArrayList<CallbackContext>());
         callbackContextMap.put("reject",new ArrayList<CallbackContext>());
         callbackContextMap.put("hangup",new ArrayList<CallbackContext>());
@@ -177,10 +179,12 @@ public class CordovaCall extends CordovaPlugin {
                   .build();
               tm.registerPhoneAccount(phoneAccount);
             }
-            phoneAccount = new PhoneAccount.Builder(handle, appName)
-                 .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
-                 .build();
-            tm.registerPhoneAccount(phoneAccount);
+            if (android.os.Build.VERSION.SDK_INT >= 23) {
+                phoneAccount = new PhoneAccount.Builder(handle, appName)
+                    .setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER)
+                    .build();
+                tm.registerPhoneAccount(phoneAccount);
+            }
             this.callbackContext.success("App Name Changed Successfully");
             return true;
         } else if (action.equals("setIcon")) {
dmarcs commented 6 years ago

@sachingarg05 Thank you so much for providing this code. We always welcome PRs 😃

I'm glad you shared this, so that someone can browse the issues section in case they need this code. The reason I don't want to add it to the main codebase is because many of the functions I used only work in Android M and above.

The Android code uses ConnectionService which was added in added in API level 23, so while I'd like for this plugin to work on versions below Android M, it's not possible.

sachingarg05 commented 6 years ago

Its not about supporting Android versions below M. Only not crashing on Android versions below M.

Goal is to have an app build which works on Android 4.0+ and can decide to use CordovaCall features when running on Android M+.

All the features are usable only on Andriod M+, but it should be possible to add this plugin to an app which supports Android 4.0+ and not crash.

Then within app's code, app can check OS version and decide if it wants to use the features in this plugin if app is running on Android M+.

dmarcs commented 6 years ago

@sachingarg05 Fair enough. I didn't realize that just installing this plugin caused crashes on versions below Android M. I used your fix in b8ccb0d2684b3c769b27b33711df5113f2e874f4. Now when users install cordova-call version 1.1.6, the crash on versions below Android M won't happen.

sachingarg05 commented 6 years ago

Thanks, tested on a few devices. Fixes the crash.