我正在尝试使用 Android 的 ConnectionService 创建一个呼叫应用程序。我可以成功接听电话,但我试图通过 TelecomManager.addNewIncomingCall 中的“extras”参数传递应用程序特定的数据。但是,当我在 ConnectionService 类中实际创建 Connection 对象时,我找不到访问我设置和传入的 Bundle 的位置。
当我检查 onCreateIncomingConnection(PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request) 中的传入参数时,connectionManagerPhoneAccount.getExtras() 或 request.getExtras() 都不是我传递给 TelecomManager.addNewIncomingCall 的额外参数。
有没有人在将它传递给 TelecomManager.addNewIncomingCall 后设置和检索这个额外的对象?
我正在尝试将呼叫的电话号码传递给 Connection 对象,以便我可以正确解析来自设备联系人的呼叫者 ID 并显示它。
代码:
package com.twilio.voice.quickstart;
...
public class VoiceActivity extends AppCompatActivity {
@RequiresApi(api = Build.VERSION_CODES.M)
private void handleIncomingCall() {
Log.d(TAG, "handleIncomingCall() triggered");
Bundle extras = new Bundle();
Uri uri = Uri.fromParts(PhoneAccount.SCHEME_TEL, activeCallInvite.getFrom(), null);
extras.putParcelable(TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, uri);
extras.putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, handle);
extras.putParcelable(Constants.INCOMING_CALL_INVITE, activeCallInvite);
telecomManager.addNewIncomingCall(handle, extras);
}
package com.twilio.voice.quickstart;
@RequiresApi(api = Build.VERSION_CODES.M)
public class VoiceConnectionService extends ConnectionService {
private static final String TAG = "VoiceConnectionService";
private static Connection connection;
public static Connection getConnection() {
return connection;
}
public static void deinitConnection() {
connection = null;
}
@Override
public Connection onCreateIncomingConnection(PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request) {
//Not sure how to get the extra information to rebuild the twilio call invitation back up..
Log.i(TAG, "Incoming Connection Request, came with extras: " + request.getExtras());
// CallInvite activeCallInvite = intent.getParcelableExtra(Constants.INCOMING_CALL_INVITE);
Connection incomingCallConnection = createConnection(request);
incomingCallConnection.setRinging();
return incomingCallConnection;
}
@Override
public Connection onCreateOutgoingConnection(PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request) {
Connection outgoingCallConnection = createConnection(request);
outgoingCallConnection.setDialing();
return outgoingCallConnection;
}
private Connection createConnection(ConnectionRequest request) {
connection = new Connection() {
@Override
public void onStateChanged(int state) { //Is this where we can get the phone number & set the caller id?
Log.i(TAG, "Connection Request: " + request.toString());
if (state == Connection.STATE_DIALING) {
final Handler handler = new Handler();
handler.post(new Runnable() {
@Override
public void run() {
// sendCallRequestToActivity(ACTION_OUTGOING_CALL); //I think this is getting triggered as an extra thing....
}
});
}
}
@Override
public void onCallAudioStateChanged(CallAudioState state) {
Log.d(TAG, "onCallAudioStateChanged called, current state is " + state);
}
@Override
public void onPlayDtmfTone(char c) {
Log.d(TAG, "onPlayDtmfTone called with DTMF " + c);
Bundle extras = new Bundle();
extras.putString(DTMF, Character.toString(c));
connection.setExtras(extras);
final Handler handler = new Handler();
handler.post(new Runnable() {
@Override
public void run() {
sendCallRequestToActivity(ACTION_DTMF_SEND);
}
});
}
@Override
public void onDisconnect() {
super.onDisconnect();
connection.setDisconnected(new DisconnectCause(DisconnectCause.LOCAL));
connection.destroy();
connection = null;
final Handler handler = new Handler();
handler.post(new Runnable() {
@Override
public void run() {
sendCallRequestToActivity(ACTION_DISCONNECT_CALL);
}
});
}
@Override
public void onSeparate() {
super.onSeparate();
}
@Override
public void onAbort() {
super.onAbort();
connection.setDisconnected(new DisconnectCause(DisconnectCause.CANCELED));
connection.destroy();
}
@Override
public void onAnswer() {
super.onAnswer();
Log.i(TAG, "Connection was answered!");
connection.setActive();
final Handler handler = new Handler();
handler.post(new Runnable() {
@Override
public void run() {
sendCallRequestToActivity(ACTION_ANSWER_CALL);
}
});
}
@Override
public void onReject() {
super.onReject();
connection.setDisconnected(new DisconnectCause(DisconnectCause.CANCELED));
connection.destroy();
}
@Override
public void onPostDialContinue(boolean proceed) {
super.onPostDialContinue(true);
}
};
//How to get the phone number, and resolve it to a contact/address?
//https://developer.android.com/reference/android/telecom/Connection
Log.i(TAG, "Creating the connection object for the incoming call, here are the extras: " + request.getExtras() + "; " + connection.getExtras());
connection.setConnectionCapabilities(Connection.CAPABILITY_MUTE);
if (request.getExtras().getString(CALLEE) == null) {
connection.setAddress(request.getAddress(), TelecomManager.PRESENTATION_ALLOWED);
} else {
connection.setAddress(Uri.parse(request.getExtras().getString(CALLEE)), TelecomManager.PRESENTATION_ALLOWED);
}
//both returning null
// Log.i(TAG, "CALLEE: " + request.getExtras().getString(CALLEE));
// Log.i(TAG, "CALLER: " + request.getExtras().getString(CALLER));
// connection.setDialing();
connection.setExtras(request.getExtras()); //This is where we want to connect..?
//How can we get the caller Id...?
connection.setCallerDisplayName("Example Contact.", TelecomManager.PRESENTATION_ALLOWED);
return connection;
}
/*
* Send call request to the VoiceConnectionServiceActivity
*/
private void sendCallRequestToActivity(String action) {
Log.i(TAG, "Transmitting broadcast from VoiceConnectionService to Voice Activity with action: " + action);
Intent intent = new Intent(action);
Bundle extras = new Bundle();
switch (action) {
case ACTION_OUTGOING_CALL:
Uri address = connection.getAddress();
extras.putString(OUTGOING_CALL_ADDRESS, address.toString());
intent.putExtras(extras);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
break;
case ACTION_DISCONNECT_CALL:
extras.putInt("Reason", DisconnectCause.LOCAL);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.putExtras(extras);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
break;
case ACTION_DTMF_SEND:
String d = connection.getExtras().getString(DTMF);
extras.putString(DTMF, connection.getExtras().getString(DTMF));
intent.putExtras(extras);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
break;
case ACTION_ANSWER_CALL:
// Uri address2 = connection.getAddress();
// extras.putString(OUTGOING_CALL_ADDRESS, address2.toString());
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.putExtras(extras);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
break;
default:
break;
}
}
}