[英]Self managed phone call using Telecom
Update:更新:
Thanks to Vadik 's help, I updated both the Main
and CallService
.感谢Vadik的帮助,我更新了
Main
和CallService
。
I am now getting the following error:我现在收到以下错误:
java.lang.RuntimeException: Unable to instantiate service com.test.phonecall.CallService: java.lang.IllegalAccessException: java.lang.Class<com.test.phonecall.CallService> is not accessible from java.lang.Class<android.app.ActivityThread>
java.lang.RuntimeException:无法实例化服务 com.test.phonecall.CallService:java.lang.IllegalAccessException:java.lang.Class<com.test.phonecall.CallService> 无法从 java.lang.Class<android 访问。 app.ActivityThread>
I was having difficulty implementing a self-managed phone call method using Telecom (as shown in the link bellow) https://developer.android.com/guide/topics/connectivity/telecom/selfManaged#connection-service我在使用 Telecom 实施自我管理的电话呼叫方法时遇到了困难(如下面的链接所示) https://developer.android.com/guide/topics/connectivity/telecom/selfManaged#connection-service
and I found a person that implemented it here:我找到了一个在这里实施它的人:
https://github.com/dmalukov/TComTest/tree/master/app/src/main/java/com/example/tcomtest https://github.com/dmalukov/TComTest/tree/master/app/src/main/java/com/example/tcomtest
But it's written in Kotlin & I need to implement & understand it in Java but I'm having a bit of difficulty translating them.但它是用 Kotlin 编写的,我需要用 Java 实现和理解它,但我在翻译它们时遇到了一些困难。 So if anybody can lend a hand in understanding & implementing it that would be great !
因此,如果有人可以帮助理解和实施它,那就太好了!
This is what I got so far: (using only the methods I 'supposedly' need to make a phone call)这就是我到目前为止所得到的:(仅使用我“据称”需要拨打电话的方法)
TComManager:通信管理器:
public class TComManager{
private TelecomManager tm;
private Context context;
public TComManager(Context context) {
tm = (TelecomManager) context.getSystemService(Context.TELECOM_SERVICE);
this.context = context;
}
public Boolean registerAccount(){
PhoneAccountHandle accountHandle = getAccountHandle();
PhoneAccount phoneAccount = tm.getPhoneAccount(accountHandle);
if (phoneAccount == null) {
PhoneAccount.Builder builder = PhoneAccount.builder(accountHandle, BuildConfig.APPLICATION_ID);
builder.setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED);
phoneAccount = builder.build();
tm.registerPhoneAccount(phoneAccount);
}
return true;
}
private PhoneAccountHandle getAccountHandle() {
String phoneAccountLabel = BuildConfig.APPLICATION_ID;
ComponentName componentName = new ComponentName(context, TComService.class);
return new PhoneAccountHandle(componentName, phoneAccountLabel);
}
public void addOutgoingCall() {
Bundle extras = new Bundle();
extras.putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, getAccountHandle());
tm.placeCall(Uri.parse("tel:123456"), extras);
}
}
TComService:通信服务:
public class TComService extends ConnectionService {
@Override
public void onCreateOutgoingConnectionFailed(PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest request) {
System.out.println("onCreateOutgoingConnectionFailed");
}
@Override
public Connection onCreateOutgoingConnection(PhoneAccountHandle handle, ConnectionRequest request){
System.out.println("onCreateOutgoingConnection - handle="+handle+", request="+request);
TComConnection connection = new TComConnection();
bindService(new Intent(getApplicationContext(), CallService.class), new CallServiceConnection(connection), 0);
return connection;
}
private class CallServiceConnection implements ServiceConnection {
private TComConnection tcomConnection;
public CallServiceConnection(TComConnection tcomConnection) {
this.tcomConnection=tcomConnection;
}
@Override
public void onServiceConnected(ComponentName name, IBinder binder) {
System.out.println("Service Connected");
CallService.CallServiceBinder callSrvBinder = (CallService.CallServiceBinder)binder;
callSrvBinder.getCallService().addConnection(tcomConnection);
unbindService(this);
}
@Override
public void onServiceDisconnected(ComponentName name) {
System.out.println("Service Disconnected");
}
}
}
TComConnection:通信连接:
public class TComConnection extends Connection {
private int listener;
public TComConnection(){
setConnectionProperties(Connection.PROPERTY_SELF_MANAGED);
}
public int getListener() {
return this.listener;
}
public void setListener(int l) {
this.listener = l;
}
@Override
public void onStateChanged(int state) {
super.onStateChanged(state);
System.out.println("onStateChanged, state="+state);
listener=state;
}
@Override
public void onReject() {
System.out.println("onReject");
close();
}
@Override
public void onDisconnect() {
System.out.println("onDisconnect");
close();
}
private void close() {
setDisconnected(new DisconnectCause(DisconnectCause.CANCELED));
destroy();
}
public Boolean isClosed() {
return this.getState() == STATE_DISCONNECTED;
}
}
CallService:呼叫服务:
class CallService extends Service{
Function<ASSComConnection, Void> connectionListener = connection -> null;
@Override
public IBinder onBind(Intent intent){
return new CallServiceBinder();
}
public void addConnection(ASSComConnection newConnection) {
connectionListener = new Function<ASSComConnection, Void>() {
@Override
public Void apply(ASSComConnection assComConnection) {
assComConnection = newConnection;
return null;
}
};
}
public class CallServiceBinder extends Binder {
public CallService getCallService() {
return CallService.this;
}
}
}
Main:主要的:
public class hello extends Activity
{
private ServiceConnection serviceConnection = new CallServiceConnection();
private TComConnection connection = null;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TComManager tcomManager = new TComManager(this);
try {
if (tcomManager.registerAccount()) {
tcomManager.addOutgoingCall();
} else {
System.out.println("*****Error: "+"account isn't registered");
}
} catch (Exception e) {
System.out.println("*****Error: "+e.getMessage());
}
}
@Override
public void onStart() {
super.onStart();
bindService(new Intent(this, CallService.class), serviceConnection, Context.BIND_AUTO_CREATE);
}
@Override
public void onStop() {
super.onStop();
closeConnection();
unbindService(serviceConnection);
}
private void closeConnection() {
if (!connection.isClosed()) {
connection.setDisconnected(new DisconnectCause(DisconnectCause.CANCELED));
}
}
private void addConnection(TComConnection newConnection) {
connection = newConnection;
}
public class CallServiceConnection implements ServiceConnection {
private CallService callService = null;
@Override
public void onServiceConnected(ComponentName name, IBinder binder) {
CallService.CallServiceBinder callSrvBinder = (CallService.CallServiceBinder)binder;
CallService service = callSrvBinder.getCallService();
service.connectionListener = connection -> {
addConnection(connection);
return null;
};
callService = service;
}
@Override
public void onServiceDisconnected(ComponentName name) {
callService.addConnection(null);
}
}
}
PS: Again this is a self-managed phone call so no startActivity(intent)
PS:这又是一个自我管理的电话,所以没有
startActivity(intent)
To fix Unable to instantiate service
caused by Service is not accessible from ActivityThread
just make your Service class public
:要修复
Unable to instantiate service
Service is not accessible from ActivityThread
由Service is not accessible from ActivityThread
导致的Unable to instantiate service
,只需将您的 Service 类Unable to instantiate service
public
:
public class CallService extends Service {
...
}
Kotlin has all classes public by default unlike Java.与 Java 不同,Kotlin 默认所有类都是公开的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.