Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Self-managed connection service callbacks aren't invoked on Samsung devices

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);
        }
    }
like image 454
tcxdev Avatar asked Nov 17 '22 11:11

tcxdev


1 Answers

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

like image 119
tcxdev Avatar answered Dec 15 '22 22:12

tcxdev