使用电信的自我管理电话

问题描述

更新:

感谢 Vadik 的帮助,我更新了 MainCallService

我现在收到以下错误

java.lang.RuntimeException:无法实例化服务 com.test.phonecall.CallService: java.lang.illegalaccessexception: java.lang.class 不是 可从 java.lang.class

访问

我在使用 Telecom 实施自我管理的电话呼叫方法时遇到了困难(如下面的链接所示) https://developer.android.com/guide/topics/connectivity/telecom/selfManaged#connection-service

在这里找到了一个实现它的人:

https://github.com/dmalukov/TComTest/tree/master/app/src/main/java/com/example/tcomtest

但它是用 Kotlin 编写的,我需要用 Java 实现和理解它,但我在翻译它们时遇到了一些困难。因此,如果有人可以帮助理解和实施它,那就太好了!

这是我目前得到的:(仅使用我“应该”需要打电话的方法

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;
    }
}

呼叫服务:

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;

            }
        }
}

主要内容

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,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);
        }
    }

}

P.S:这又是一个自我管理的电话,所以没有 startActivity(intent)

解决方法

要修复由 Unable to instantiate service 引起的 Service is not accessible from ActivityThread,只需将您的服务类设为 public

public class CallService extends Service {
   ...
}

与 Java 不同,Kotlin 的所有类默认都是公开的。