呼叫邀请功能,无法接受呼叫邀请

按照Github上的样例OpenDuo-Android,整合了呼叫功能,但是当一方发起呼叫后,无法接收到邀请:

public void initEngine(String userId) {

        String appId = context.getString(R.string.private_app_id);
        if (TextUtils.isEmpty(appId)) {
            throw new RuntimeException("NEED TO use your App ID");
        }

        EngineEventListener mEventListener = new EngineEventListener();
        try {
            RtcEngine mRtcEngine = RtcEngine.create(context, appId, mEventListener);
            mRtcEngine.setChannelProfile(Constants.CHANNEL_PROFILE_LIVE_BROADCASTING);
            mRtcEngine.enableDualStreamMode(true);
            mRtcEngine.enableVideo();
            mRtcEngine.setLogFile(FileUtil.rtmLogFile(context));

            RtmClient mRtmClient = RtmClient.createInstance(context, appId, mEventListener);
            mRtmClient.setLogFile(FileUtil.rtmLogFile(context));

            if (Config.DEBUG) {
                mRtcEngine.setParameters("{\"rtc.log_filter\":65535}");
                mRtmClient.setParameters("{\"rtm.log_filter\":65535}");
            }

            RtmCallManager rtmCallManager = mRtmClient.getRtmCallManager();
            rtmCallManager.setEventListener(mEventListener);

            mRtmClient.login(null, userId, new ResultCallback<Void>() {
                @Override
                public void onSuccess(Void aVoid) {
                    Log.i(TAG, "rtm client login success");
                }

                @Override
                public void onFailure(ErrorInfo errorInfo) {
                    Log.i(TAG, "rtm client login failed:" + errorInfo.getErrorDescription());
                }
            });
            Toast.makeText(context , " rtm client login success:" + userId,Toast.LENGTH_SHORT).show();
            Agora.getInstance().setmRtcEngine(mRtcEngine);
            Agora.getInstance().setmRtmClient(mRtmClient);
            Agora.getInstance().setRtmCallManager(rtmCallManager);
            Agora.getInstance().setmEventListener(mEventListener);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
  • TelemedicineCallReceiver
public class TelemedicineCallReceiver extends BroadcastReceiver {

    private static final String TAG = TelemedicineCallReceiver.class.getSimpleName();


    @Override
    public void onReceive(Context context, Intent intent) {
        String subscriber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
        Log.d(TAG, "PROCESS_OUT_GOING_CALL received, Phone number: " + subscriber);


        if (shouldIntercept(context, subscriber)) {
           /* Intent agIntent = new Intent(context, MainActivity.class);
            agIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
            context.startActivity(agIntent);
            setResultData(null);*/
        }
    }

    private boolean shouldIntercept(Context context, String phoneNumber) {
        try {
            Cursor cursor = context.getContentResolver().query(CallLog.Calls.CONTENT_URI,
                    null, CallLog.Calls.NUMBER + "=?", new String[]{phoneNumber},
                    CallLog.Calls.DATE + " DESC");
            int phoneAccountID = cursor.getColumnIndex(CallLog.Calls.PHONE_ACCOUNT_ID);

            boolean shouldIntercept = false;
            while (cursor.moveToNext()) {
                String phoneAccID = cursor.getString(phoneAccountID);
                Log.d(TAG, "phone number: " + phoneNumber + " phoneAccountID: " + phoneAccID);
                shouldIntercept = phoneAccID.equals(Constants.PA_LABEL_CALL_IN) ||
                        phoneAccID.equals(Constants.PA_LABEL_CALL_OUT);
                if (shouldIntercept) break;
            }
            cursor.close();
            return shouldIntercept;
        } catch (SecurityException e) {
            e.printStackTrace();
            return false;
        }
    }
}
  • TelemedicineCallSession
public class TelemedicineCallSession {

    private PhoneAccount mPhoneAccountOut;
    private PhoneAccount mPhoneAccountIn;
    private TelemedicineConnection mConnection;

    public void setPhoneAccountIn(PhoneAccount pa) {
        mPhoneAccountIn = pa;
    }

    public void setPhoneAccountOut(PhoneAccount pa) {
        mPhoneAccountOut = pa;
    }

    public PhoneAccount getPhoneAccountIn() {
        return mPhoneAccountIn;
    }

    public PhoneAccount getPhoneAccountOut() {
        return mPhoneAccountOut;
    }

    public void setConnection(TelemedicineConnection connection) {
        mConnection = connection;
    }


}
  • TelemedicineConnection
public class TelemedicineConnection extends Connection {

    private static final String TAG = TelemedicineConnection.class.getSimpleName();
    private Context mContext;
    private String mChannel;
    private String mUid;
    private String mSubscriber;
    private int mRole;

    public TelemedicineConnection(Context context, String uid, String channel, String subscriber, int role){
        mContext = context;
        mChannel = channel;
        mUid = uid;
        mSubscriber = subscriber;
        mRole = role;
    }

    @Override
    public void onShowIncomingCallUi() {
        Log.d(TAG, "onShowIncomingCallUi called");
        super.onShowIncomingCallUi();
    }

    @Override
    public void onDisconnect() {
        Log.d(TAG, "onDisconnect called");
        super.onDisconnect();
        setDisconnected(new DisconnectCause(DisconnectCause.LOCAL));
        destroy();
    }

    @Override
    public void onAbort() {
        Log.d(TAG, "onAbort called");
        super.onAbort();
        setDisconnected(new DisconnectCause(DisconnectCause.CANCELED));
        destroy();
    }

    @Override
    public void onAnswer() {
        Log.d(TAG, "onAnswer called");
        super.onAnswer();

        setDisconnected(new DisconnectCause(DisconnectCause.LOCAL)); // tricky way to dismiss the system incall ui

        Intent intent = new Intent(mContext, VideoActivity.class);
        intent.putExtra(Constants.CS_KEY_UID, mUid);
        intent.putExtra(Constants.CS_KEY_CHANNEL, mChannel);
        intent.putExtra(Constants.CS_KEY_SUBSCRIBER, mSubscriber);
        intent.putExtra(Constants.CS_KEY_ROLE, mRole);
        intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        mContext.startActivity(intent);
    }

    @Override
    public void onReject() {
        Log.d(TAG, "onReject called");
        super.onReject();
        setDisconnected(new DisconnectCause(DisconnectCause.REJECTED));
        destroy();
    }
}
  • TelemedicineConnectionService
public class TelemedicineConnectionService  extends ConnectionService {

    private static final String TAG = TelemedicineConnectionService.class.getSimpleName();

    public static final String SCHEME_AG = "customized_call";

    @Override
    public Connection onCreateIncomingConnection(PhoneAccountHandle phoneAccount, ConnectionRequest request) {
        Log.i(TAG, "onCreateIncomingConnection: called. " + phoneAccount + " " + request);

        Bundle extras = request.getExtras();
        String uid = extras.getString(Constants.CS_KEY_UID);
        String channel = extras.getString(Constants.CS_KEY_CHANNEL);
        String subscriber = extras.getString(Constants.CS_KEY_SUBSCRIBER);
        int role = extras.getInt(Constants.CS_KEY_ROLE);
        int videoState = extras.getInt(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE);

        TelemedicineConnection connection = new TelemedicineConnection(getApplicationContext(), uid, channel, subscriber, role);
        connection.setVideoState(videoState);
        connection.setAddress(Uri.fromParts(SCHEME_AG, subscriber, null), TelecomManager.PRESENTATION_ALLOWED);
        connection.setCallerDisplayName(subscriber, TelecomManager.PRESENTATION_ALLOWED);
        connection.setRinging();
        Agora.getInstance().getmConfig().setConnection(connection);

        return connection;
    }
    @Override
    public Connection onCreateOutgoingConnection(PhoneAccountHandle phoneAccount, ConnectionRequest request) {
        Log.i(TAG, "onCreateOutgoingConnection: called. " + phoneAccount + " " + request);

        Bundle extras = request.getExtras();
        String uid = extras.getString(Constants.CS_KEY_UID);
        String channel = extras.getString(Constants.CS_KEY_CHANNEL);
        String subscriber = extras.getString(Constants.CS_KEY_SUBSCRIBER);
        int role = extras.getInt(Constants.CS_KEY_ROLE);
        int videoState = extras.getInt(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE);

        TelemedicineConnection connection = new TelemedicineConnection(getApplicationContext(), uid, channel, subscriber, role);
        connection.setVideoState(videoState);
        connection.setAddress(Uri.fromParts(SCHEME_AG, subscriber, null), TelecomManager.PRESENTATION_ALLOWED);
        connection.setCallerDisplayName(subscriber, TelecomManager.PRESENTATION_ALLOWED);
        connection.setRinging();
        Agora.getInstance().getmConfig().setConnection(connection);

        return connection;
    }

    @Override
    public void onCreateIncomingConnectionFailed(PhoneAccountHandle phoneAccount, ConnectionRequest request) {
        Log.e(TAG, "onCreateIncomingConnectionFailed: called. " + phoneAccount + " " + request);
    }

    @Override
    public void onCreateOutgoingConnectionFailed(PhoneAccountHandle phoneAccount, ConnectionRequest request) {
        Log.e(TAG, "onCreateOutgoingConnectionFailed: called. " + phoneAccount + " " + request);
    }
}
  • AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="cn.com.telemedicine.activity">

    <uses-permission android:name="android.permission.RECORD_AUDIO"/>
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.BLUETOOTH"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    <uses-permission android:name="android.permission.CALL_PHONE"/>
    <uses-permission android:name="android.permission.MANAGE_OWN_CALLS"/>
    <uses-permission android:name="android.permission.READ_CALL_LOG"/>
    <uses-permission android:name="android.permission.WRITE_CALL_LOG"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

    <application
        android:name="cn.com.telemedicine.TelemedicineApplication"
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:requestLegacyExternalStorage="true"
        android:usesCleartextTraffic="true"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/Theme.AppCompat.NoActionBar">
        <activity android:name="cn.com.telemedicine.activity.main.MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <action android:name="android.intent.action.VIEW"/>
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity android:name="cn.com.telemedicine.activity.chat.CallActivity"
            android:noHistory="true"
            android:screenOrientation="portrait"/>

        <activity android:name="cn.com.telemedicine.activity.chat.VideoActivity"
            android:screenOrientation="portrait"/>

        <service android:name="cn.com.telemedicine.ui.calling.connectionservice.TelemedicineConnectionService"
            android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE"
            android:exported="false">
            <intent-filter>
                <action android:name="android.telecom.ConnectionService"/>
            </intent-filter>
        </service>

        <receiver android:name="cn.com.telemedicine.ui.calling.connectionservice.TelemedicineCallReceiver"
            android:exported="false">
            <intent-filter>
                <action android:name="android.intent.action.NEW_OUTGOING_CALL"/>
            </intent-filter>
        </receiver>
    </application>

</manifest>
2个回答
H 回复于 2020-07-10 03:00

刚才本地用 demo 测试是可以的。

如果你直接跑 demo 也有问题,请提供主叫方和被叫方的 rtm 日志。

回复·1

能否将你的demo发我下 niewx@tdinfo.com.cn,包括依赖的jar包,我使用的是最新的jdk

neilweixing 回复于 2020-07-10 06:42 · IP属地江苏

我看demo里使用的是 :

implementation 'io.agora.rtc:full-sdk:2.9.2'
implementation 'io.agora.rtm:rtm-sdk:1.2.2'

不是官网最新的sdk,相关的.so文件我需要从哪边下载的到:
这是是官网最新的sdk中包含的

回复·1

demo 目前适配的是这两个版本,还没适配最新版。你打开Android Studio后会自动通过gradle同步安装demo需要的so、jar文件的,无需手动下载