javaandroidkotlintelecom-manager

Kotlin to Java migration


I am unable to translate(from Kotlin to Java) or understand this statement service.connectionListener = { addConnection(it) } which is found in the inner class of the following file:

class MainActivity : AppCompatActivity() {
    private val serviceConnection = CallServiceConnection()
    private var connection: TComConnection? = null
    private val tcomManager: TComManager by lazy { TComManager(applicationContext) }
    private val requiredPermissions =
        arrayOf(
            android.Manifest.permission.READ_PHONE_STATE,
            android.Manifest.permission.READ_CALL_LOG
        )

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        drop_btn.setOnClickListener { closeConnection() }

        answer_btn.setOnClickListener {
            val conn = connection
            if (conn != null) {
                conn.setActive()
            } else {
                Toast.makeText(applicationContext, "there is no call", Toast.LENGTH_SHORT).show()
            }
        }

        incoming_btn.setOnClickListener {
            if (!hasPermissions()) {
                requestPermissions(requiredPermissions, 1)
                Toast.makeText(applicationContext, "don't have permissions", Toast.LENGTH_SHORT).show()
                return@setOnClickListener
            }

            try {
                if (tcomManager.registerAccount()) {
                    tcomManager.addIncomingCall()
                } else {
                    Toast.makeText(applicationContext, "account isn't registered", Toast.LENGTH_SHORT).show()
                }
            } catch (e: Exception) {
                Toast.makeText(applicationContext, e.message, Toast.LENGTH_SHORT).show()
            }
        }

        outgoing_btn.setOnClickListener {
            if (!hasPermissions()) {
                requestPermissions(requiredPermissions, 1)
                Toast.makeText(applicationContext, "don't have permissions", Toast.LENGTH_SHORT).show()
                return@setOnClickListener
            }

            try {
                if (tcomManager.registerAccount()) {
                    tcomManager.addOutgoingCall()
                } else {
                    Toast.makeText(applicationContext, "account isn't registered", Toast.LENGTH_SHORT).show()
                }
            } catch (e: Exception) {
                Toast.makeText(applicationContext, e.message, Toast.LENGTH_SHORT).show()
            }
        }
    }

    override fun onStart() {
        super.onStart()

        Intent(this, CallService::class.java).also { intent ->
            bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE)
        }
    }


    override fun onStop() {
        super.onStop()
        closeConnection()
        unbindService(serviceConnection)
    }


    private fun hasPermissions(): Boolean {
        return requiredPermissions.all { checkSelfPermission(it) == PackageManager.PERMISSION_GRANTED }
    }


    private fun closeConnection() {
        connection?.let {
            if (!it.isClosed()) {
                it.setDisconnected(DisconnectCause(DisconnectCause.CANCELED))
            }
            it.listener = {}
        }

        val stateText = "state: no call"
        state_label.text = stateText
    }

    private fun addConnection(newConnection: TComConnection) {
        newConnection.listener = {
            val stateText = "state: ${Connection.stateToString(it)}"
            state_label.text = stateText
        }
        connection = newConnection
        val stateText = "state: ${Connection.stateToString(newConnection.state)}"
        state_label.text = stateText
    }


    inner class CallServiceConnection : ServiceConnection {
        private var callService: CallService? = null
        override fun onServiceConnected(name: ComponentName?, binder: IBinder?) {
            val callSrvBinder = binder as CallService.CallServiceBinder
            val service = callSrvBinder.getCallService()
            service.connectionListener = { addConnection(it) }
            callService = service
        }

        override fun onServiceDisconnected(name: ComponentName?) {
            callService?.connectionListener = {}
        }
    }
}

I was unable to translate the above statement (commented out):

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.addConnection(); // <--------
            callService = service;
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            callService.addConnection(null);
        }
    }

Solution

  • This code in Kotlin:

    service.connectionListener = { addConnection(it) }
    

    Corresponds to this code in Java:

    service.setConnectionListener(connection -> {
        addConnection(connection);
        return Unit.INSTANCE;
    });
    

    It is assumed that Service class is written in Kotlin and looks like this:

    class Service {
        var connectionListener: (Connection) -> Unit = {}
    }
    

    Update:

    If you want to rewrite Service class too, your code will be:

    service.connectionListener = connection -> {
        addConnection(connection);
        return null;
    };
    

    Service class in Java:

    class Service {
        Function<Connection, Void> connectionListener = connection -> null;
    }