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);
}
}
After some firmware update the code above started working correctly. So, the problem was in the phone itself.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With