Kotlin BT App

  • 13 Antworten
  • Neuester Beitrag
Diskutiere Kotlin BT App im Android App Entwicklung im Bereich Betriebssysteme & Apps.
G

Gee1

Neues Mitglied
hey ich bräuchte mal etwas Hilfe. Ich habe ein TextView das mir die empfangenen Bluetooth Daten (nur ASCII) anzeigen soll die von meinem µC kommen.

das ist meine read Funktion:
Code:
    private fun recString(output: String) {
        if (m_bluetoothSocket != null) {
            try{
                m_bluetoothSocket!!.inputStream.read(output.toByteArray())
                var LOGTAG = null
                Log.i(LOGTAG, "Incoming data recieved: $output")
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
    }
und die ID von meinem TextView lautet: console
kann ich das mit "console.setText =" in "override fun onCreate" machen ?

Der name console ist etwas unpassend da man dort selbst nix reinschreiben kann.

Wäre für Hilfe echt dankbar. Suche schon seit tagen im Netz aber bekomme es einfach nicht hin.
 
J

jogimuc

Stammgast
Hallo

und die ID von meinem TextView lautet: console
kann ich das mit "console.setText =" in "override fun onCreate" machen ?
Nein wenn dann mit console.text ="hallo"
Setzt natürlich voraus das die variable console auch auf die Instanz Objekt der textview zeigt.
 
Zuletzt bearbeitet:
G

Gee1

Neues Mitglied
ich glaube du hast mich nicht richtig verstanden. Wie ich einen einfachen Text wie Hallo in meinem TextView anzeige weis ich selbst.

Das TextView soll mit den Bluetooth input stream anzeigen
 
J

jogimuc

Stammgast
Deine Funktion hat gar keinen Rückgabe Wert. Wenn du wirklich den string bekommst. Gibst du ihn nicht weiter du hast weder eine Klassen Variable noch einen Rückgabe Wert

Aber in der onCreate ist falsch wenn dann in der Methode wenn du im UI bist. Oder in einem listener.

Die onCreate wird nur beim Activity Start aufgerufen dann nicht mehr.

Du musst schon asyncon arbeiten.
 
Zuletzt bearbeitet:
G

Gee1

Neues Mitglied
Wie muss ich die Funktion denn ändern damit sie einen Wert zurück gibt?

Das ist mein zweiter Tag mit Kotlin / Java. Ich hab 0 Plan und versuche gerade Fuß zu fassen
 
J

jogimuc

Stammgast
Na dann würde ich sagen lernen erstmal Grundlagen Kotlin oder Java und dann kannst du dich auch an das Feamework Android machen. Was schon etwas anders ist als Java oder Kotlin auf einem Desktop PC.
Auch Grundlagen in OOP wäre sinnvoll.

Kotlin Grundlagen: Klassen und Funktionen - Kelut GmbH

der rückgabe wert folgt bei kotlin nach der Klammer

fun double(x: Int): Int {
return 2*x
}

nur ob deine read Funktion überhaupt funktioniert bin ich mir nicht sicher.
Um das sinnvoll zu beantworten ist das zu wenig Code.


Den Cast der String Variablen Output zu einem Array ist hier auch nicht sinnvoll.
Wenn dann eine neue Variabel (array) und die dann als return.


Java und Kotlin macht Call-by-Value nicht Call-by-Reference wie C/C++ was du von deinen µC kennst.
In Java gibt es keine Pointer Arithmetik mit der du einer Funktion einen übergeben String wieder zurück geben kannst.
 
Zuletzt bearbeitet:
G

Gee1

Neues Mitglied
den µC programmiere ich über 16 Bit Assembler, das ist völlig anders aufgebaut ^^
 
J

jogimuc

Stammgast
Assembler Ok ist mir nicht fremd.

Da solltest du anfangen Problem orientierte Sprachen auch zulernnen.

Ich benutze für µCs meistens C dachte du würdest dich in dieser Sprache auskennen. Assembler babe ich nur für sehr system nahe sachen benutzt.

Aber wir sind ja hier bei Java Kotlin.
 
G

Gee1

Neues Mitglied
Frage: ich habe diese Klasse importiert:
Code:
       class MyBluetoothService(
                // handler that gets info from Bluetooth service
                private val handler: Handler) {

            private inner class ConnectedThread(private val mmSocket: BluetoothSocket) : Thread() {

                private val mmInStream: InputStream = mmSocket.inputStream
                private val mmOutStream: OutputStream = mmSocket.outputStream
                private val mmBuffer: ByteArray = ByteArray(1024) // mmBuffer store for the stream

                override fun run() {
                    var numBytes: Int // bytes returned from read()

                    // Keep listening to the InputStream until an exception occurs.
                    while (true) {
                        // Read from the InputStream.
                        numBytes = try {
                            mmInStream.read(mmBuffer)
                        } catch (e: IOException) {
                            Log.d(TAG, "Input stream was disconnected", e)
                            break
                        }

                        // Send the obtained bytes to the UI activity.
                        val readMsg = handler.obtainMessage(
                                MESSAGE_READ, numBytes, -1,
                                mmBuffer)
                        readMsg.sendToTarget()
                    }
                }

                // Call this from the main activity to send data to the remote device.
                private fun write(bytes: ByteArray) {
                    try {
                        mmOutStream.write(bytes)
                    } catch (e: IOException) {
                        Log.e(TAG, "Error occurred when sending data", e)

                        // Send a failure message back to the activity.
                        val writeErrorMsg = handler.obtainMessage(MESSAGE_TOAST)
                        val bundle = Bundle().apply {
                            putString("toast", "Couldn't send data to the other device")
                        }
                        writeErrorMsg.data = bundle
                        handler.sendMessage(writeErrorMsg)
                        return
                    }

                    // Share the sent message with the UI activity.
                    val writtenMsg = handler.obtainMessage(
                            MESSAGE_WRITE, -1, -1, bytes)
                    writtenMsg.sendToTarget()
                }

                // Call this method from the main activity to shut down the connection.
                private fun cancel() {
                    try {
                        mmSocket.close()
                    } catch (e: IOException) {
                        Log.e(TAG, "Could not close the connect socket", e)
                    }

                }

            }
        }
jetzt will ich die letzte Funktion "cancel()" hier aufrufen:
Code:
 override fun onBackPressed() {
        sendString("app_disc")  // damit Generator weis das er aus dem menü rausgehen soll
        cancel()         //BT disconnect
        super.onBackPressed()   // Standardaktion (App schließen)
    }
cancel erscheint allerdings rot und er hat keinen Bezug dazu?
 
J

jogimuc

Stammgast
Hallo
Dazu musst du schon das erstellte Objekt von „MyBluetoothService“ benutzen.
Wo und ob du überhaupt eines hast also eine Instanz, hast kann ich nicht sehn.

OOP Programmierung halt.


PS. Die Fun ist private ob du da überhaupt von außen zugreifen kannst bin ich mir nicht sicher.
Auch deine Inner Class ist private somit wirst du auch nicht auf "ConnectedThread" von auserhalb der Klasse
"MyBluetoothService" zugreifen können.
Die Kasse (MyBluetoothService) geht ja auch noch weiter was wir nicht sehen. Und dort wird auch dein Thread gestart werden.
Von auserhalb wirst du nicht an die Fun "cancel()" deiner geschützen inneren Klasse kommen.

Visibility modifiers

Mit einfach Copy Paste ohne Grundlagen kommt sowas raus.



Edit das was du hier hast ist nur ein keiner Teil von dem was du brauchst.

Wenn du den Beispiellink von der Bluetooth overview | Android Developers folgst wirst sehen was alles dazugehört wie groß die Kasse eigentlich ist .

Das Beispiel auf der Google Seite von der du zukommen scheinst ist leider in Java.

vielleicht ist das etwas für dich
Transferring data between Android devices over bluetooth with Kotlin
 
Zuletzt bearbeitet:
G

Gee1

Neues Mitglied
Ich denke ich muss nichtmal direkt auf die Methoden in der Klasse zu greifen.


// Send the obtained bytes to the UI activity.
val readMsg = handler.obtainMessage(
MESSAGE_READ, numBytes, -1,
mmBuffer)
readMsg.sendToTarget()


damit sendet er so wie ich es verstehe eine Nachicht an den UI thread das der input stream abgerufen werden kann.. Nur wie mache ich das ?
 
J

jogimuc

Stammgast
damit sendet er so wie ich es verstehe eine Nachicht an den UI thread das der input stream abgerufen werden kann.. Nur wie mache ich das ?
Dann solltest du dich mal etwas mit Handlern beschäftigen.
Mulitthreading unter Android
Einen Handler übergibst du ja. Dann wirst du doch auch das Callback Interface haben.

https://developer.android.com/reference/android/os/Handler
https://developer.android.com/reference/android/os/Messag

Ich hatte dir auch einen Link mit einem einfachen Beispiel gegen was ohne Handler auskommt. Das sollte für dich als Anfänger einfacher sein.
Die Beispiele von der Developer Seite sind schon etwas Komplex.

PS das Forum ist nicht dazu da dir die Grunglagen einer Sprache Kotlin oder Java beizubringen.
 
Zuletzt bearbeitet:
G

Gee1

Neues Mitglied
Also Verbinden und Strings senden funzt. Nur mit dem Lesen und im TextView ausgeben klappt es noch nicht so richtig vielleicht kann mal einer drüber schauen.

Code:
// 

@file:Suppress("DEPRECATION")

package com.test

import android.annotation.SuppressLint
import android.app.ProgressDialog
import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.bluetooth.BluetoothSocket
import android.content.Context
import android.os.AsyncTask
import android.os.Bundle
import android.system.Os.socket
import android.util.Log
import android.widget.EditText
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import kotlinx.android.synthetic.main.control_layout.*
import java.nio.Buffer
import java.util.*
import kotlin.concurrent.thread
import org.apache.*
import java.io.*



@Suppress("DEPRECATION")


class ControlActivity: AppCompatActivity() {

    companion object {
        var m_myUUID: UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB")
        var m_bluetoothSocket: BluetoothSocket? = null
        private lateinit var m_progress: ProgressDialog
        private lateinit var m_bluetoothAdapter: BluetoothAdapter
        private var m_isConnected: Boolean = false
        private lateinit var m_address: String

    }

    var text: TextView? = null

    @SuppressLint("SetTextI18n")
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.control_layout)
        m_address = intent.getStringExtra(MainActivity.EXTRA_ADDRESS).toString()
        ConnectToDevice(this).execute()
        btn_log.setOnClickListener { sendString("1\r") }  // ASCII 1 und CR senden...         Beispiel für Hex oder Dec String: { sendCommand("{30, 78, 35, 0x35}") }

        //try {
        //    Thread.sleep(1000)
        //} catch (e: InterruptedException) {
        //    e.printStackTrace()
        //}

        thread(start = true) {
            while (m_isConnected) {
                receive_text.text = m_bluetoothSocket!!.inputStream.read().toString()
            }
        }
        }


    override fun onBackPressed() {
        sendString("app_disc")  // damit Generator weis das er aus dem menü rausgehen soll
        disconnect()            //BT disconnect
        super.onBackPressed()   // Standardaktion (App schließen)
    }

    private fun sendString(input: String) {
        if (m_bluetoothSocket != null) {
            try{
                m_bluetoothSocket!!.outputStream.write(input.toByteArray())
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
    }

    private fun recString(output: String) {
        if (m_bluetoothSocket != null) {
            try{
                m_bluetoothSocket!!.inputStream.read(output.toByteArray())
                var LOGTAG = null
                Log.i(LOGTAG, "Incoming data recieved: $output")
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
    }


    private fun disconnect() {
        if (m_bluetoothSocket != null) {
            try {
                m_bluetoothSocket!!.close()
                m_bluetoothSocket = null
                m_isConnected = false
            } catch (e: IOException) {
                e.printStackTrace()
            }
        }
        finish()
    }

    private class ConnectToDevice(c: Context) : AsyncTask<Void, Void, String>() {
        private var connectSuccess: Boolean = true
        @SuppressLint("StaticFieldLeak")
        private val context: Context = c

        override fun onPreExecute() {
            super.onPreExecute()
            m_progress = ProgressDialog.show(context, "Connecting...", "please wait")
        }

        override fun doInBackground(vararg p0: Void?): String?
        {
            try {
                if (m_bluetoothSocket == null || !m_isConnected) {
                    m_bluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
                    val device: BluetoothDevice = m_bluetoothAdapter.getRemoteDevice(m_address)
                    m_bluetoothSocket = device.createInsecureRfcommSocketToServiceRecord(m_myUUID)
                    BluetoothAdapter.getDefaultAdapter().cancelDiscovery()
                    m_bluetoothSocket!!.connect()
                }
            } catch (e: IOException) {
                connectSuccess = false
                e.printStackTrace()
            }
            return null
        }


        private fun sendString(input: String) {
            if (m_bluetoothSocket != null) {
                try{
                    m_bluetoothSocket!!.outputStream.write(input.toByteArray())
                } catch (e: IOException) {
                    e.printStackTrace()
                }
            }
        }

        override fun onPostExecute(result: String?) {
            super.onPostExecute(result)
            if (!connectSuccess) {
                Log.i("data", "couldn't connect")
            } else {
                m_isConnected = true
                sendString("app_connect")
            }
            m_progress.dismiss()
        }

    }
}
 
Zuletzt bearbeitet:
J

jogimuc

Stammgast
Hallo
Das ist ja mal wieder ein anderer von irgendwo kopierter Code.
Erstens möchte ich bemerken das AsyncTask ab API 30 nicht mehr unterstützt und verwendet werden sollte.


Du willst eine Ausgabe auf dem Bildschirm in einem Thread machen das geht nicht.
Ausgaben auf den Bildschirm gehen immer nur im UI.
Entweder benutze Handler und Listener oder benutze runOnUiThread.
Tipp schaue den Link von mir an.
Ps. er hat auch einen Link zu GitHub auf der Seite wo sein Projekt ist.


Übrigens deine beiden Sende Methoden laufen im UI.
 
Zuletzt bearbeitet:
Ähnliche Themen - Kotlin BT App Antworten Datum
3
5
14