How to use Socket.IO in android kotlin - android

In my application i want use Socket.io and for this i add below library and write below codes.
But when run application and click on button not show me any event!
I used kotlin for write android application.
After click on button, should show me socket state in textView, but not show any state!
Socket library :
compile 'com.github.nkzawa:socket.io-client:0.5.2'
My Codes:
class SocketActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_socket)
val opts = IO.Options()
opts.query = "token=${Constants.BIDZILA_TOKEN}"
var socket = IO.socket(Constants.BIDZILA_SOCKET, opts)
btnSend.setOnClickListener {
socket.connect()
Handler(Looper.getMainLooper()).postDelayed(
{ socket?.on(Socket.EVENT_CONNECT) {
Log.d("SocketLog", "==============================CONNECTED")
socket_stateTxt.text = socket.connected().toString()
}?.on(Socket.EVENT_DISCONNECT) {
Log.d("SocketLog", "==============================OFF")
socket_stateTxt.text = socket.connected().toString()
} },
2000
)
}
}
}
How can i fix it?

I'm establishing the connection like this:
private var socket = IO.socket("<YOUR_URL>")
socket.let {
it!!.connect()
.on(Socket.EVENT_CONNECT) {
Log.d("SignallingClient", "Socket connected!!!!!")
}
}

Related

signalr android (kotlin) cannot connect to server because it is always DISCONNECTED

I use implementation 'com.microsoft.signalr:signalr:6.0.8' for android (kotlin) and backend is .Net 6
but the emulator cannot connect to the server (localhost). I try to code a function to check hubConnection.connectionState, it is DISCONNECTED.
no error happened. Can anyone guide me to find the error, here is the code:
import com.microsoft.signalr.Action1
import com.microsoft.signalr.HubConnection
import com.microsoft.signalr.HubConnectionBuilder
import com.microsoft.signalr.HubConnectionState
import io.reactivex.rxjava3.core.Single
import org.slf4j.Logger
import org.slf4j.LoggerFactory
class SignalRListener private constructor(){
private var hubConnection: HubConnection
private var logger: Logger
init {
logger = LoggerFactory.getLogger(HubConnection::class.java)
// define in constructor
hubConnection = HubConnectionBuilder.create("http://10.0.2.2:5291/hubs/presence")
.withAccessTokenProvider(Single.defer { Single.just("${Constanst.TOKEN}") })
.build()
hubConnection.on("UserIsOnline",
Action1 { member: Member -> println(member.DisplayName + "online") },
Member::class.java
)
hubConnection.on("UserIsOffline",
Action1 { username: String -> println(username+" offline") },
String::class.java
)
hubConnection.on(
"GetOnlineUsers",
Action1 { usersOnline : List<Member> ->
for (item in usersOnline) {
println(item.DisplayName)
}
},
List::class.java
)
hubConnection.start().doOnError({ logger.info("Client connected error.") })
}
private object Holder { val INSTANCE = SignalRListener() }
companion object {
#JvmStatic
fun getInstance(): SignalRListener{
return Holder.INSTANCE
}
}
fun stopHubConnection(){
if(hubConnection.connectionState == HubConnectionState.CONNECTED){
hubConnection.stop()
}
}
fun getConnectionState(){
println(hubConnection.connectionState.toString())
}
fun log(){
logger.info("Debug infor siganlR {}", hubConnection.connectionId)
}
}
Web (React) runs well with the backend.
class MainActivity : AppCompatActivity() {
lateinit var signalR: SignalRListener;
var btnCheck: Button? = null
var btnLog: Button? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
signalR = SignalRListener.getInstance()
btnCheck = findViewById(R.id.btnCheck)
btnCheck?.setOnClickListener {
signalR.getConnectionState()
}
btnLog = findViewById(R.id.btnLog)
btnLog?.setOnClickListener {
signalR.log()
}
}
}
As you are in the android emulator, You have to access your localhost so that it reaches your server. If you need internet through proxy you can also set it from the Settings and Proxy and there you can define your proxy settings.
I fixed the problem with the following:
in BE(.Net Core) remove this line:
app.UseHttpsRedirection();
and the client calls http not https:
hubConnection = HubConnectionBuilder.create("http://10.0.2.2:5291/hubs/presence")
hubConnection.start().blockingAwait()
It worked fine

Android Bluetooth Service to Transfer data between devices

Hello am new in Android development I was reading about android bluetooth Here on Android development documentation.
I was able to setup bluetooth, find the bonded device and to connect but am having an issue on transfer data between them
Here is the bluetooth server socket code that listen to bluetooth connection request.
class BluetoothActivity : AppCompatActivity() {
private lateinit var listen: Button
private lateinit var msgBox:TextView
private lateinit var status:TextView
private lateinit var sendButton: Button
private lateinit var writeMsg:EditText
private lateinit var listDevice:Button
private lateinit var listView: ListView
private val handler = Handler()
private var bluetoothDevices = arrayListOf<BluetoothDevice>()
private var deviceName = arrayListOf<String>()
private inner class ServerAcceptThread:Thread(){
private val mmServerSocket:BluetoothServerSocket? by lazy(LazyThreadSafetyMode.NONE){
bluetoothAdapter?.listenUsingInsecureRfcommWithServiceRecord(myName,myUUID)
}
override fun run() {
//Keep listen until error occured or socket is returned
var shouldKeepListen = true
while (shouldKeepListen){
val socket:BluetoothSocket? = try {
mmServerSocket?.accept()
}catch (e:IOException){
Log.e("bluetoothSocket","ServerSocket failde",e)
shouldKeepListen = false
null
}
if (socket!= null){
val connected = ConnectedThread(socket)
connected.start()
}
}
}
//Close server socket and cause the thread to finish
fun cancel(){
try {
mmServerSocket?.close()
}catch (e:IOException){
Log.e("ConnectionFailed!", "Connection close failed",e)
}
}
}
And down below is the code for Bluetooth client that connect to bluetooth server socket.
private inner class ClientConnectThread(device: BluetoothDevice):Thread(){
private val mmSocket:BluetoothSocket? by lazy(LazyThreadSafetyMode.NONE){
device.createRfcommSocketToServiceRecord(myUUID)
}
public override fun run() {
//Cancel the discovery process because it slow down the connection
bluetoothAdapter?.cancelDiscovery()
mmSocket?.let { socket ->
socket.connect()
}
}
fun cancel(){
try {
mmSocket?.close()
}catch (e:IOException){
Log.e("Socket", "Could not close the client socket",e)
}
}
}
And Then I have bluetooth service that read and write data to send to remote device (client). which take BluetoothSocket as parameter, were the server is listening to
private inner class ConnectedThread(private val mmSocket:BluetoothSocket):Thread(){
private val mmInPutStream:InputStream = mmSocket.inputStream
private val mmOutPutStream:OutputStream = mmSocket.outputStream
private val mmBuffer:ByteArray = ByteArray(1024)
override fun run() {
var numByte:Int //number of bytes returns from read()
//keep listen to the InputStream until an error occured
while (true){
//Read from inputStream
numByte = try {
mmInPutStream.read(mmBuffer)
}catch (e:IOException){
Log.e(TAG,"InputStream was disconnected",e)
break
}
//Send the message to Ui activity
val readMsg = handler.obtainMessage(
MESSAGE_READ,numByte,-1,mmBuffer
)
readMsg.sendToTarget()
}
}
//Call this function to mainActivity to send data to remote device
fun write(byte:ByteArray){
try {
mmOutPutStream.write(byte)
}catch (e:IOException){
Log.e(TAG,"Error occured during send messge",e)
//Send the failed message back to activity
val writeErrorMessage = handler.obtainMessage(MESSAGE_TOAST)
val bundle = Bundle().apply {
putString("Toast","could not send the data")
}
writeErrorMessage.data = bundle
handler.sendMessage(writeErrorMessage)
return
}
//Share the sent message with UI activity
val writtenMsg = handler.obtainMessage(
MESSAGE_WRITE, -1,-1,mmBuffer
)
writtenMsg.sendToTarget()
}
//Call this method to activity to shut socket
fun cancle(){
try {
mmSocket.close()
}catch (e:IOException){
Log.e(TAG,"Connection closed failed!")
}
}
}
}
And I have also implement the listener for UI to start listen to a connection request, list Bonded device and connect to remote device and transfer data through each other.
fun implementsListeners(){
listDevice.setOnClickListener {
val pairedDevice: Set<BluetoothDevice>? = bluetoothAdapter?.bondedDevices
var index:Int = 0
val pairedDevice: Set<BluetoothDevice>? = bluetoothAdapter?.bondedDevices
if (pairedDevice != null){
var listDeviceName = arrayListOf<String>()
try {
pairedDevice.forEachIndexed { index, device ->
listDeviceName.add(index, device.name)
bluetoothDevices.add(device)
}
}catch (e:IndexOutOfBoundsException){
Log.e(TAG, "indexOutOfBond",e)
}
val arrayAdapter:ArrayAdapter<String> = ArrayAdapter(
this,android.R.layout.simple_list_item_1,listDeviceName
)
listView.adapter =arrayAdapter
}
listen.setOnClickListener {
val serverClass = ServerAcceptThread()
serverClass.start()
}
listView.setOnItemClickListener { parent, view, position, id ->
val client = ClientConnectThread(bluetoothDevices[position])
client.start()
status.text = "Connecting..."
}
sendButton.setOnClickListener {
val client = BluetoothService(Handler())
//Call the write() method to write data
}
My Question is how can I access the write() method and read() that is on ConnectedThread. I have tried to Instantiate ConnectedThread but it's take BluetoothSocket as parameter I can't access the socket outside client or server class. Method Any help or suggestion on. I would Appreciate

How to use socket in Android with Kotlin

I want to achieve something in Android using Kotlin to do:
If I click a button on the app, the app sends a word to a TCP server (which I wrote with python). The server will send back another word, and the app will show a toast message.
Here is what I have done so far, I can figure out the sending part but I can't manage to make it keep listening to the socket to hear from the server.
I am trying to use coroutine but after finding all the resources online, this is as best as I can get.
Also, I am not sure if I am setting the IP address in the correct manner.
Thank you in advance for your help!
'''
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val sendBtn = findViewById<Button>(R.id.sendBtn )
val ipBtn = findViewById<Button>(R.id.ipBtn)
val ipInput = findViewById<TextView>(R.id.ipInput)
var ipAddress: String = "192.168.0.101"
// Below is my attempt to keep listening to the socket, if commented, the sending would work.
// My guess is the IO thread is caught in the while loop so the other coroutines cannot use
// IO thread to send to the server.
CoroutineScope(IO).launch{
val socket = Socket(ipAddress, 9999)
var text = ""
while (true) {
text = BufferedReader(InputStreamReader(socket.inputStream)).readLine()
// if text is not null
// Toast.makeText(this#MainActivity, "Set IP", Toast.LENGTH_SHORT).show()
}
}
suspend fun sendMessage(message:String){
val socket = Socket(ipAddress, 9999)
socket.outputStream.write(message.toByteArray())
socket.close()
}
ipBtn.setOnClickListener {
Toast.makeText(this#MainActivity, "Set IP", Toast.LENGTH_SHORT).show()
ipAddress = ipInput.text.toString()
}
sendBtn .setOnClickListener {
CoroutineScope(IO).launch {
Log.d("TAG", "message")
sendMessage("record")
}
}
'''
To send a Data from P2P Fist we required a Server and Client . Here the Socket act as end point for sending and receiving data across the network .
Create a Server Class like this
class ServerClass() :Thread(){
lateinit var serverSocket:ServerSocket
lateinit var inputStream: InputStream
lateinit var outputStream: OutputStream
lateinit var socket: Socket
override fun run() {
try {
serverSocket = ServerSocket(8888)
socket = serverSocket.accept()
inputStream =socket.getInputStream()
outputStream = socket.getOutputStream()
}catch (ex:IOException){
ex.printStackTrace()
}
val executors = Executors.newSingleThreadExecutor()
val handler = Handler(Looper.getMainLooper())
executors.execute(Runnable{
kotlin.run {
val buffer = ByteArray(1024)
var byte:Int
while (true){
try {
byte = inputStream.read(buffer)
if(byte > 0){
var finalByte = byte
handler.post(Runnable{
kotlin.run {
var tmpMeassage = String(buffer,0,finalByte)
Log.i("Server class","$tmpMeassage")
}
})
}
}catch (ex:IOException){
ex.printStackTrace()
}
}
}
})
}
fun write(byteArray: ByteArray){
try {
Log.i("Server write","$byteArray sending")
outputStream.write(byteArray)
}catch (ex:IOException){
ex.printStackTrace()
}
}
}
Create a client Class where we need to pass hostaddress
class ClientClass(hostAddress: InetAddress): Thread() {
var hostAddress: String = hostAddress.hostAddress
lateinit var inputStream: InputStream
lateinit var outputStream: OutputStream
lateinit var socket: Socket
fun write(byteArray: ByteArray){
try {
outputStream.write(byteArray)
}catch (ex:IOException){
ex.printStackTrace()
}
}
override fun run() {
try {
socket = Socket()
socket.connect(InetSocketAddress(hostAddress,8888),500)
inputStream = socket.getInputStream()
outputStream = socket.getOutputStream()
}catch (ex:IOException){
ex.printStackTrace()
}
val executor = Executors.newSingleThreadExecutor()
var handler =Handler(Looper.getMainLooper())
executor.execute(kotlinx.coroutines.Runnable {
kotlin.run {
val buffer =ByteArray(1024)
var byte:Int
while (true){
try{
byte = inputStream.read(buffer)
if(byte>0){
val finalBytes = byte
handler.post(Runnable{
kotlin.run {
val tmpMeassage = String(buffer,0,finalBytes)
Log.i("client class", tmpMeassage)
}
})
}
}catch (ex:IOException){
ex.printStackTrace()
}
}
}
})
}
}
make sure server and client port should be same , this is two way communication where we can transfer data in both sides .

Receive input from Android application EditText and send to Kafka

The language used is Kotlin, implemented by Android Studio.
I want to change the EditText existing in the xml of the layout folder into String type and send it as Kafka value, but I keep getting an error somewhere.
It is said that it is impossible to conclude the visible error theory. Where exactly is the problem?
class Registration() : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.Sign_Up)
val rc: Button = findViewById(R.id.Registration_Completed)
val id: EditText = findViewById(R.id.ID)
val pw: EditText = findViewById(R.id.PW)
val UserID = id.text.toString() //convert id to string
val UserPW = pw.text.toString() //convert pw to string
rc.setOnClickListener {
val intent = Intent(this, next_activity::class.java)
Producer()
Toast.makeText(this, "registration completed", Toast.LENGTH_SHORT).show()
startActivity(intent)
}
}
Below is the Producer code
class Producer {
companion object {
#JvmStatic
fun main(args: String){
val TOPIC= "test"
val SERVERS = "localhost:9092"
val configs = Properties()
configs.put(ProducerConfig.BOOTSTRAP_SERVERS_CONFIG, SERVERS)
configs.put(ProducerConfig.KEY_SERIALIZER_CLASS_CONFIG,
"org.apache.kafka.common.serialization.StringSerializer")
configs.put(ProducerConfig.VALUE_SERIALIZER_CLASS_CONFIG,
"org.apache.kafka.common.serialization.StringSerializer")
val producer = KafkaProducer<String, String>(configs)
var record: ProducerRecord<String, String> =ProducerRecord(TOPIC,"print")
Up to this point, the output is normal.
producer.send(ProducerRecord(TOPIC, UserID))
producer.send(ProducerRecord(TOPIC, UserPW))
producer.close()
try {
producer.send(ProducerRecord<String, String> (TOPIC, "SUCCESS!"))
} catch (exception:Exception)
{
exception.printStackTrace()
}
finally { producer.close() }
The connection may not work well because the cord is partially cut.
I used the id and pw variables in the Producer by dragging the EditText to Internal fun() under the Registration class.
Producer and connection, how to pull variables, etc., function errors, etc. Which is the problem?

How can I use work manager in my code - android

This is My Code :
#RequiresApi(Build.VERSION_CODES.M)
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.home_activity)
loadProductForTheFirst()
#RequiresApi(Build.VERSION_CODES.M)
private fun hasNetworkAvilable(context: Context): Boolean {
val service = Context.CONNECTIVITY_SERVICE
val manager = context.getSystemService(service) as ConnectivityManager
val network = manager.activeNetwork
return (network != null)
}
#RequiresApi(Build.VERSION_CODES.M)
fun loadProductForTheFirst(){
swipeRefreshMain.isRefreshing = true
viewModel.getalldata().observe(this, Observer {
if (!it.isNullOrEmpty()) {
recycler_main.apply {
layoutManager = GridLayoutManager(this#HomeActivity, 2)
adapter = RecyclerAdapterMain(it, this#HomeActivity)
swipeRefreshMain.isRefreshing = false
}
} else {
if (hasNetworkAvilable(this)) {
viewModel.products.observe(this, Observer {
recycler_main.apply {
layoutManager = GridLayoutManager(this#HomeActivity, 2)
adapter = RecyclerAdapterMain(it, this#HomeActivity)
swipeRefreshMain.isRefreshing = false
}
})
viewModel.setup()
} else {
/// in here if the user not internet for loading the products
/// the alert dialog displays .
AlertDialog.Builder(this)
.setTitle("Internet State")
.setMessage("please turn on your internet connection")
.create()
.show()
/// in here I want a method ( workmanager )
// that as soon as the internet be accessible
/// my product will be updated .
}
}
})
}
well , For the first time that user open my app need the internet to load product from api .
So I just want the method like WorkManager to check if the intenrnet avalibility is accessible .
And after that my method will be load from api .
I did some search but could'nt find any useful example of work with workmanager.
anyone can help me with this . ?
I did this code and work for me .
I put it here if someone looking for this method .
I used work manager to get data from api whenever the network is on .
val constraints = Constriants.builder(this)
.setRequiredNetworkType(NetworkType.Connected)
val workManager : WorkManager = WorkManager.getInstance(this)
val oneRequestWork = OneRequestWorker.build(UploadWorker::class.java)
.setconstrints(constraints)
.build
workmanager.enqueue(oneRequestWork)
the Upload worker class :
class UploadWorker(context : Context , param : WorkerParameters) : Worker(context , param)
private val viewModel: ViewModelRoom by lazy {
ViewModelProvider(
ViewModelStore(),
FactoryRoom(RepositoryCart(DataBaseRoom.invoke(applicationContext)))
)
.get(ViewModelRoom::class.java)
}
override fun dowork() : Result {
return try {
viewModel.setup()
Result.success()
} catch (e: Exception) {
Result.failure()
}

Categories

Resources