5

I develop a VoIP app using this guide. I faced the problem with a self-manged connection service on Samsung devices.

I'm placing a call using TelecomManager. I expect that ConnectionService::onCreateOutgoingConnection or ConnectionService::onCreateOutgoingConnectionFailed will be invoked, but it doesn't happen on some Samsung devices.

After placing a call the dialog window appears. On samsung galaxy s10 an android toast appears with the text "Call not sent". Methods of connection service are not invoked.

On phones with the vanilla Android it works as expected.

Does anybody know how to solve this issue?

Manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.example.tcom">

    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.READ_CALL_LOG"/>
    <uses-permission android:name="android.permission.MANAGE_OWN_CALLS"/>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        tools:ignore="AllowBackup,GoogleAppIndexingWarning">

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <service android:name="com.example.tcom.ConnectionService"
            android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE">
            <intent-filter>
                <action android:name="android.telecom.ConnectionService" />
            </intent-filter>
        </service>

    </application>

</manifest>

ConnectionService:

public class ConnectionService extends android.telecom.ConnectionService {
    private static final String TAG = "ConnectionService";
    @Override
    public android.telecom.Connection onCreateIncomingConnection(PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request) {
        Log.i(TAG, "onCreateIncomingConnection");
        Connection connection = new Connection();
        MainActivity.setConnection(connection);
        return connection;
    }

    @Override
    public void onCreateIncomingConnectionFailed(PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request) {
        Log.i(TAG, "onCreateIncomingConnectionFailed");
        super.onCreateIncomingConnectionFailed(connectionManagerPhoneAccount, request);
    }

    @Override
    public android.telecom.Connection onCreateOutgoingConnection(PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request) {
        Log.i(TAG, "onCreateOutgoingConnection");
        Connection connection = new Connection();
        MainActivity.setConnection(connection);
        return connection;
    }

    @Override
    public void onCreateOutgoingConnectionFailed(PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request) {
        Log.i(TAG, "onCreateOutgoingConnectionFailed");
        super.onCreateOutgoingConnectionFailed(connectionManagerPhoneAccount, request);
    }
}

Connection:

public class Connection extends android.telecom.Connection {
    private static final String TAG = "Connection";

    public Connection() {
        super();
        setConnectionProperties(android.telecom.Connection.PROPERTY_SELF_MANAGED);
    }

    @Override
    public void onStateChanged(int state) {
        super.onStateChanged(state);
        Log.i(TAG, "onStateChanged state=" + android.telecom.Connection.stateToString(state));
    }
}

PhoneAccount creating:

    void createAccount() {
        tm = (TelecomManager) getSystemService(Context.TELECOM_SERVICE);
        if (tm == null) {
            throw new RuntimeException("cannot obtain telecom system service");
        }

        ComponentName connectionServiceName = new ComponentName(getApplicationContext(), ConnectionService.class);
        PhoneAccountHandle accountHandle = new PhoneAccountHandle(connectionServiceName, PHONE_ACCOUNT_LABEL);
        try {
            PhoneAccount phoneAccount = tm.getPhoneAccount(accountHandle);
            if (phoneAccount == null) {
                PhoneAccount.Builder builder = PhoneAccount.builder(accountHandle, PHONE_ACCOUNT_LABEL);
                builder.setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED);
                phoneAccount = builder.build();
                tm.registerPhoneAccount(phoneAccount);
            }
            this.accountHandle = phoneAccount.getAccountHandle();

            if (tm.getPhoneAccount(accountHandle) == null) {
                throw new RuntimeException("cannot create account");
            }

        } catch (SecurityException e) {
            throw new RuntimeException("cannot create account", e);
        }
    }

Call creating:


    void createCall() {
        try {
            Bundle extras = new Bundle();
            extras.putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, accountHandle);
            Uri uri = Uri.fromParts(PhoneAccount.SCHEME_SIP, "test_call", null);
            tm.placeCall(uri, extras);
        }
        catch (SecurityException e) {
            throw new RuntimeException("cannot place call", e);
        }
    }
tcxdev
  • 61
  • 5
  • can you share "MainActivity.setConnection(connection);" what is it doing in MainActivity? – Amos Nov 12 '20 at 05:57
  • Still experiencing connection service issues on the Tab A SM-T510 and SM-T290. Open forum post here https://forum.developer.samsung.com/t/self-managed-connectionservice-not-working/933 but no action in a while. Not sure if this will be resolved or if we will have to stick with an workaround – kjanderson2 Apr 05 '21 at 21:36
  • Would it be possible if you can publish your implementation in a sample app? I was trying to follow that same example but I'm a little lost on where to put or call the different componets – ragar90 Oct 14 '21 at 22:57

2 Answers2

1

After some firmware update the code above started working correctly. So, the problem was in the phone itself.

tcxdev
  • 61
  • 5
-1

Anybody else having this problem, just make sure of two things:

  1. Remove PhoneAccount.CAPABILITY_CALL_PROVIDER from your phone account's capabilities.
  2. You have implemented an InCallService.
barnacle.m
  • 2,070
  • 3
  • 38
  • 82