react-native-callkeep icon indicating copy to clipboard operation
react-native-callkeep copied to clipboard

App crashing on registerPhoneAccount for Android 13 for selfManaged true mode

Open Aayushi-Mashru opened this issue 2 years ago • 5 comments

Bug report

  • [*] I've checked the example to reproduce the issue.

  • Reproduced on:

  • [*] Android

  • [ ] iOS

Description

App is crashing during setup when trying to registerPhoneAccount in RNCallKeepModule for selfManaged true mode.

Steps to Reproduce

Setup RNCallKeep with selfManaged true.

  • Install the app for the first time, app is not crashing.
  • Once you kill the app, then it's crashing everytime at launch.

Versions

- Callkeep: 4.3.1
- React Native: 0.62.3
- iOS:
- Android: 13
- Phone model: All

Logs

E/unknown:ReactNative: Exception in native call
    java.lang.IllegalArgumentException: Error, cannot change a self-managed phone account ComponentInfo{*app-package-id*/io.wazo.callkeep.VoiceConnectionService}, ***, UserHandle{0} to other kinds of phone account
        at android.os.Parcel.createExceptionOrNull(Parcel.java:3027)
        at android.os.Parcel.createException(Parcel.java:3007)
        at android.os.Parcel.readException(Parcel.java:2990)
        at android.os.Parcel.readException(Parcel.java:2932)
        at com.android.internal.telecom.ITelecomService$Stub$Proxy.registerPhoneAccount(ITelecomService.java:1738)
        at android.telecom.TelecomManager.registerPhoneAccount(TelecomManager.java:1612)
        at io.wazo.callkeep.RNCallKeepModule.registerPhoneAccount(RNCallKeepModule.java:853)
        at io.wazo.callkeep.RNCallKeepModule.registerPhoneAccount(RNCallKeepModule.java:243)
        at io.wazo.callkeep.RNCallKeepModule.setup(RNCallKeepModule.java:223)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.facebook.react.bridge.JavaMethodWrapper.invoke(JavaMethodWrapper.java:372)
        at com.facebook.react.bridge.JavaModuleWrapper.invoke(JavaModuleWrapper.java:151)
        at com.facebook.react.bridge.queue.NativeRunnable.run(Native Method)
        at android.os.Handler.handleCallback(Handler.java:942)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at com.facebook.react.bridge.queue.MessageQueueThreadHandler.dispatchMessage(MessageQueueThreadHandler.java:27)
        at android.os.Looper.loopOnce(Looper.java:226)
        at android.os.Looper.loop(Looper.java:313)
        at com.facebook.react.bridge.queue.MessageQueueThreadImpl$4.run(MessageQueueThreadImpl.java:226)
        at java.lang.Thread.run(Thread.java:1012)
     Caused by: android.os.RemoteException: Remote stack trace:
        at com.android.server.telecom.PhoneAccountRegistrar.enforceSelfManagedAccountUnmodified(PhoneAccountRegistrar.java:1000)
        at com.android.server.telecom.PhoneAccountRegistrar.addOrReplacePhoneAccount(PhoneAccountRegistrar.java:925)
        at com.android.server.telecom.PhoneAccountRegistrar.registerPhoneAccount(PhoneAccountRegistrar.java:905)
        at com.android.server.telecom.TelecomServiceImpl$1.registerPhoneAccount(TelecomServiceImpl.java:623)
        at com.android.internal.telecom.ITelecomService$Stub.onTransact(ITelecomService.java:857)

Aayushi-Mashru avatar Aug 08 '23 12:08 Aayushi-Mashru

 const granted = await PermissionsAndroid.request(
    "android.permission.READ_PHONE_NUMBERS"
  );
  
  
    const options = {
    ios: {
      appName: "My app name",
    },
    android: {
      alertTitle: "Permissions required",
      alertDescription: "This application needs to access your phone accounts",
      cancelButton: "Cancel",
      okButton: "ok",
      selfManaged: true,
      additionalPermissions: [
        "android.permission.READ_PHONE_NUMBERS",
        "android.permission.READ_PHONE_STATE",
      ],
    },
  };
  
  
  
   RNCallKeep.setup(options)
    
    
    RNCallKeep.displayIncomingCall('uuidv4', "10086", "Caller Name");
   
   
  

Please try this one

ibmmt avatar Sep 19 '23 03:09 ibmmt

Same issue for me. RNCallKeep was working perfectly. I changed the mode to Self Managed with the intend of avoiding my calls from reaching the Call Logs of the phone. The first time it worked fine & I thought I was set. But next time, I started the app it started crashing with this same issue. Error, cannot change a self-managed phone account ComponentInfo{app-package-id/io.wazo.callkeep.VoiceConnectionService}, ***, UserHandle{0} to other kinds of phone account Tried reinstalling the app from start & similar behaviour. Worked fine for a couple of times & after that started crashing.

,@ibmmt 's suggestion above did not help. Any fix for this would be helpful ? Alternatively, if there's way to avoid our calls from reaching the Call Logs of the phone, that will be great for my use case too.

Thanks !

badhrin avatar Jan 18 '24 09:01 badhrin

Having this issue on some our clients with ViVo phone. Any insights?

jikseyres16 avatar Feb 14 '24 00:02 jikseyres16

Hello, We applied some changes to unregister the PhoneAccount by calling unregisterPhoneAccount method before trying to create or register it, and it fixed the issue. Here are the changes we have made.

File: RNCallKeepModule.java

[Change 1]

private void registerPhoneAccount(Context appContext) {
        if (!isConnectionServiceAvailable()) {
            Log.w(TAG, "[RNCallKeepModule] registerPhoneAccount ignored due to no ConnectionService");
            return;
        }

        this.initializeTelecomManager();
        Context context = this.getAppContext();
        if (context == null) {
            Log.w(TAG, "[RNCallKeepModule][registerPhoneAccount] no react context found.");
            return;
        }
        String appName = this.getApplicationName(context);

        PhoneAccount.Builder builder = new PhoneAccount.Builder(handle, appName);
        if (isSelfManaged()) {
            builder.setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED);
        }
        else {
            builder.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER);
        }

        if (_settings != null && _settings.hasKey("imageName")) {
            int identifier = appContext.getResources().getIdentifier(_settings.getString("imageName"), "drawable", appContext.getPackageName());
            Icon icon = Icon.createWithResource(appContext, identifier);
            builder.setIcon(icon);
        }

        PhoneAccount account = builder.build();

        telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        //Custom change start
        telecomManager.unregisterPhoneAccount(handle);
        //Custom change end
        telecomManager.registerPhoneAccount(account);
    }

[Change 2]

public void initializeTelecomManager() {
        Context context = this.getAppContext();
        if (context == null) {
            Log.w(TAG, "[RNCallKeepModule][initializeTelecomManager] no react context found.");
            return;
        }
        ComponentName cName = new ComponentName(context, VoiceConnectionService.class);
        String appName = this.getApplicationName(context);
        //Custom change start
        if (handle != null && telecomManager != null) {
            telecomManager.unregisterPhoneAccount(handle);
        }
        //Custom change end
        handle = new PhoneAccountHandle(cName, appName);
        telecomManager = (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
    }

Hope this helps.

Aayushi-Mashru avatar Feb 14 '24 11:02 Aayushi-Mashru

Hello, We applied some changes to unregister the PhoneAccount by calling unregisterPhoneAccount method before trying to create or register it, and it fixed the issue. Here are the changes we have made.

File: RNCallKeepModule.java

[Change 1]

private void registerPhoneAccount(Context appContext) {
        if (!isConnectionServiceAvailable()) {
            Log.w(TAG, "[RNCallKeepModule] registerPhoneAccount ignored due to no ConnectionService");
            return;
        }

        this.initializeTelecomManager();
        Context context = this.getAppContext();
        if (context == null) {
            Log.w(TAG, "[RNCallKeepModule][registerPhoneAccount] no react context found.");
            return;
        }
        String appName = this.getApplicationName(context);

        PhoneAccount.Builder builder = new PhoneAccount.Builder(handle, appName);
        if (isSelfManaged()) {
            builder.setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED);
        }
        else {
            builder.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER);
        }

        if (_settings != null && _settings.hasKey("imageName")) {
            int identifier = appContext.getResources().getIdentifier(_settings.getString("imageName"), "drawable", appContext.getPackageName());
            Icon icon = Icon.createWithResource(appContext, identifier);
            builder.setIcon(icon);
        }

        PhoneAccount account = builder.build();

        telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
        //Custom change start
        telecomManager.unregisterPhoneAccount(handle);
        //Custom change end
        telecomManager.registerPhoneAccount(account);
    }

[Change 2]

public void initializeTelecomManager() {
        Context context = this.getAppContext();
        if (context == null) {
            Log.w(TAG, "[RNCallKeepModule][initializeTelecomManager] no react context found.");
            return;
        }
        ComponentName cName = new ComponentName(context, VoiceConnectionService.class);
        String appName = this.getApplicationName(context);
        //Custom change start
        if (handle != null && telecomManager != null) {
            telecomManager.unregisterPhoneAccount(handle);
        }
        //Custom change end
        handle = new PhoneAccountHandle(cName, appName);
        telecomManager = (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
    }

Hope this helps.

Its working on me thanks ! 😄 👍

alepmustaqim03 avatar May 15 '24 08:05 alepmustaqim03