input und output mit socket und bluetooth

  • Antworten:1
  • Bentwortet
Robbiani Renato
  • Forum-Beiträge: 634

08.05.2022, 18:30:19 via Website

Hallo zusammen

In einem Buch habe ich ein Beispiel welches eine Socket Verbindung über Bluetooth macht. Leider kriege ich das Beispiel nicht zum laufen.

package ch.robbisoft.bluetoothchatdemo

import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.content.pm.PackageManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import android.view.KeyEvent
import android.widget.*
import ch.robbisoft.bluetoothchatdemo.databinding.ActivityMainBinding
import java.io.*
import java.util.*
import java.util.jar.JarInputStream
import android.Manifest
import android.os.Build
import kotlin.concurrent.thread

private const val DEVICE1 = "..."
private const val DEVICE2 = "..."
private const val REQUEST_FINE_LOCATION = 321
private val MY_UUID = UUID.fromString("dc4f9aa6-ce43-4709-bd2e-7845a3e705f1")
private val TAG = MainActivity::class.simpleName

class MainActivity : AppCompatActivity() {

private lateinit var binding: ActivityMainBinding
private val adapter = BluetoothAdapter.getDefaultAdapter()

private var serverThread : Thread? = null
private var clientThread : Thread? = null

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ActivityMainBinding.inflate(layoutInflater)
    val view = binding.root
    setContentView(view)

    input.isEnabled = false
}

override fun onStart() {
    super.onStart()
    if( if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
        } else {
            TODO("VERSION.SDK_INT < M")
        }
    ){
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            requestPermissions(arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), REQUEST_FINE_LOCATION)
        }
    }else{
        startOrFinish()
    }
}

override fun onPause() {
    super.onPause()
    serverThread?.interrupt()
    serverThread = null
    clientThread?.interrupt()
    clientThread = null
}

override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    if (requestCode == REQUEST_FINE_LOCATION && grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED){
        startOrFinish()
    }
}

private fun startOrFinish(){
    if( isBluetoothEnabled() ){
        connect()
    }else{
        finish()
    }
}

private fun isBluetoothEnabled() : Boolean {
    val enabled = adapter?.isEnabled ?: false
    if( !enabled ){
        Toast.makeText(this, R.string.enable_bluetooth, Toast.LENGTH_LONG).show()
    }
    return enabled
}

private fun connect() {
    val myName = adapter?.name
    val otherName = if(DEVICE1 == myName) DEVICE2 else DEVICE1
    for( device in adapter?.bondedDevices ?: emptyList<BluetoothDevice>()){
        if(otherName == device.name){
            val serverSocketThread = ServerSocketThread(adapter, TAG, MY_UUID)
            serverThread = createAndStartThread(serverSocketThread)
            val clientSocketThread = ClientSocketThread(device, MY_UUID)
            clientThread = createAndStartThread(clientSocketThread)
            input.isEnabled = true
        }
    }
}

private fun createAndStartThread(t : SocketThread) : Thread = thread {
    var keepRuning = true
    try {
        t.start()
        Log.d(TAG, "joining " + t.name)
        t.join()
        t.getSocket()?.run {
            Log.d(TAG, String.format("connection type %d for %s", connectionType, t.name))
            input.setOnEditorActionListener{ _ : TextView?, _ : Int, _ : KeyEvent? ->
                send(outputStream, input.text.toString())
                runOnUiThread { input.setText("") }
                true
            }
            while ( keepRuning ){
                receive(inputStream)?.let {
                    runOnUiThread { output?.appent(it) }
                }
            }
        }
    }catch (thr : Throwable){ //InterruptedException, IOException
        Log.e(TAG, thr.message, thr)
        keepRuning = false
    }finally {
        Log.d(TAG, "calling cancel() of " + t.name)
        t.cancel()
    }
}

private fun send( stream : OutputStream, text : String){
    stream.use {
        stream.write(text.toByteArray())
    }
}

private fun receive(stream : InputStream) : String? {
    stream.use {
        val num = stream.available()
        if(num > 0){
            val buffer = ByteArray(num)
            var bytesToRead = num
            while (bytesToRead > 0){
                val read = stream.read(buffer, num - bytesToRead, bytesToRead)
                if( read == -1){
                    break
                }
                bytesToRead -= read
            }
            return String(buffer)
        }
    }
    return null
}

}

Die Wörter "input" und "output" bleiben rot mit der Meldung ich soll für sie eine Variable erstellen. Im Beispiel geht es aber ohne. Wie machen die das?

Die Imports habe ich alle überprüft. Auch in den build.gradle habe ich nach geschaut. Einfach nichts zum Importieren oder so was. Auch in der Klasse hat es keine Vererbung.

Wo liegt das Problem?

Gruss Renato

Kommentieren
Beste Antwort
Robbiani Renato
  • Forum-Beiträge: 634

16.05.2022, 21:30:47 via Website

Hallo zusammen

Ich habe das Problem viel zu weit gesucht.

input und output sind zwei Elemente aus dem Layout. Nun funktioniert es.

Gruss Renato

Hilfreich?
Kommentieren