При вызове функции OnClickStop, которая содержит serialPort.close (), мое приложение вылетает. Я буду содержать как мой код xml, так и logcat - может кто-нибудь сообщить мне, где я ошибаюсь?
Ссылка на код: https://codeshare.io/G8xLXE Logcat видно ниже
Мое мобильное устройство подключено к плате Arduino. У меня есть датчик давления, подключенный к моей Arduino. Arduino действует как эхо. После вызова функции onClickSend мой arduino отвечает данными датчика давления. Затем он отправляется на мое мобильное устройство и отображается в виде тепловой карты в функции тепловой карты. Моя панель поиска сохраняет эти значения датчика давления в массиве, где в шкале времени функции - используя панель поиска, я могу воспроизвести значения путем фильтрации по массиву
Почему происходит сбой моего приложения при вызове функции onClickStop ()?
Код
package com.example.surf10
import android.os.Bundle
import android.view.View
import android.widget.Button
import androidx.appcompat.app.AppCompatActivity
import android.app.PendingIntent
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.graphics.Color
import android.hardware.usb.UsbDevice
import android.hardware.usb.UsbDeviceConnection
import android.hardware.usb.UsbManager
import android.os.Handler
import android.util.Log
import android.widget.SeekBar
import android.widget.TextView
import android.widget.Toast
import com.felhr.usbserial.UsbSerialDevice
import com.felhr.usbserial.UsbSerialInterface
import com.felhr.usbserial.UsbSerialInterface.UsbReadCallback
import kotlinx.android.synthetic.main.activity_surfboard.*
import java.io.UnsupportedEncodingException
import java.util.*
import kotlin.text.Charsets.UTF_8
import kotlin.collections.ArrayList as ArrayList1
class Surfboard : AppCompatActivity() {
val ACTION_USB_PERMISSION = "com.surf10.USB_PERMISSION"
var startButton: Button? = null
var sendButton: Button? = null
var stopButton: Button? = null
var textView: TextView? = null
var textView2: TextView? = null
var seekText: TextView? = null
var statusText: TextView? = null
var usbManager: UsbManager? = null
var device: UsbDevice? = null
var serialPort: UsbSerialDevice? = null
var connection: UsbDeviceConnection? = null
var reading: String? = null
var seekBar: SeekBar? = null
var storeList = arrayListOf<Int>()
var mCallback = UsbReadCallback { arg0 ->
//Defining a Callback which triggers whenever data is read.
//var data: String? = null
try {
var data = String(
arg0,
UTF_8
) //data received will be in raw bites, re-ecncode it into a readable form UTF-8
heatMap(data) //Printing data to TextView and setting TextView colour
timescale(data) // Sending data to array for replay of data
} catch (e: UnsupportedEncodingException) {
e.printStackTrace()
}
}
private val broadcastReceiver: BroadcastReceiver = object : BroadcastReceiver() {
//Broadcast Receiver to automatically start and stop the Serial connection.
override fun onReceive(
context: Context,
intent: Intent
) {
if (intent.action == ACTION_USB_PERMISSION) { //if the user has granted permission
val granted = intent.extras!!.getBoolean(
UsbManager.EXTRA_PERMISSION_GRANTED
)
if (granted) {
connection = usbManager!!.openDevice(device)
serialPort = UsbSerialDevice.createUsbSerialDevice(device, connection)
if (serialPort != null) {
if (serialPort!!.open()) { //Set Serial Connection Parameters.
setUiEnabled(true)
serialPort!!.setBaudRate(9600) //chosen 9600 baud rate
serialPort!!.setDataBits(UsbSerialInterface.DATA_BITS_8) //default parameters for an UNo
serialPort!!.setStopBits(UsbSerialInterface.STOP_BITS_1)
serialPort!!.setParity(UsbSerialInterface.PARITY_NONE)
serialPort!!.setFlowControl(UsbSerialInterface.FLOW_CONTROL_OFF)
serialPort!!.read(mCallback)
tvAppend(statusText, "Serial Connection Opened!\n")
} else {
Log.d("SERIAL", "PORT NOT OPEN")
}
} else {
Log.d("SERIAL", "PORT IS NULL")
}
} else {
Log.d("SERIAL", "PERM NOT GRANTED")
}
} else if (intent.action == UsbManager.ACTION_USB_DEVICE_ATTACHED) {
onClickStart(startButton) //if USB is attached run the onClickStart function
} else if (intent.action == UsbManager.ACTION_USB_DEVICE_DETACHED) {
onClickStop(stopButton) //if USB is detashed run the onClickStop function
}
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_surfboard)
usbManager = getSystemService(Context.USB_SERVICE) as UsbManager
startButton = findViewById<View>(R.id.buttonStart) as Button
sendButton = findViewById<View>(R.id.activate) as Button
stopButton = findViewById<View>(R.id.deactivate) as Button
textView = findViewById<View>(R.id.textView) as TextView
textView2 = findViewById<View>(R.id.test) as TextView
seekText = findViewById<View>(R.id.seekText) as TextView
statusText = findViewById<View>(R.id.statusText) as TextView
seekBar = findViewById<View>(R.id.seekBar) as SeekBar
setUiEnabled(false)
val filter = IntentFilter()
filter.addAction(ACTION_USB_PERMISSION)
filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED)
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED)
registerReceiver(broadcastReceiver, filter)
// val buttons = arrayOf(
//// findViewById<Button>(R.id.b00),
//// findViewById<Button>(R.id.b01),
//// findViewById<Button>(R.id.b02)
// /*findViewById<Button>(R.id.b10),
// findViewById<Button>(R.id.b11),
// findViewById<Button>(R.id.b12),
// findViewById<Button>(R.id.b20),
// findViewById<Button>(R.id.b21),
// findViewById<Button>(R.id.b22)*/
// )
//Reading(buttons)
}
fun setUiEnabled(bool: Boolean) {
startButton!!.isEnabled = !bool
sendButton!!.isEnabled = bool
stopButton!!.isEnabled = bool
textView!!.isEnabled = bool
}
fun onClickStart(@Suppress("UNUSED_PARAMETER") view: View?) {
val usbDevices = usbManager!!.deviceList
if (!usbDevices.isEmpty()) {
var keep = true
for ((_, value) in usbDevices) {
device = value
val deviceVID = device!!.vendorId
if (deviceVID == 0x2341) //Arduino Vendor ID
{
val pi =
PendingIntent.getBroadcast(this, 0, Intent(ACTION_USB_PERMISSION), 0)
usbManager!!.requestPermission(device, pi)
keep = false
} else {
connection = null
device = null
}
if (!keep) break
}
}
}
fun onClickSend(@Suppress("UNUSED_PARAMETER") view: View?) {
val string = "g" //data sent to arduino
// serialPort!!.write(string.toByteArray())
// tvAppend(statusText, "\nData Sent : " + string)
// var circuit = 0
for (i in 1..100) { //sending string 100 times to arduino
Handler().postDelayed({
serialPort!!.write(string.toByteArray()) //sending data to arduino
}, 1000) //delay of 1 second between each message sent
}
}
fun onClickStop(@Suppress("UNUSED_PARAMETER") view: View?) { //CRASHHH
// setUiEnabled(false)
// Toast.makeText(this, "Hi there! This is a Toast.", Toast.LENGTH_SHORT).show()
//serialPort!!.close()
serialPort?.close()
//tvAppend(statusText, "\nSerial Connection Closed! \n") //Serial status message
}
private fun tvAppend(tv: TextView?, text: CharSequence) { // Print status messages
runOnUiThread {
tv!!.text = text
}
}
private fun heatMap(data: String) {
textView2?.text = data
if (data.toInt() >= 1000) {
textView2?.setBackgroundColor(Color.GREEN)
} else if (data.toInt() >= 750) {
textView2?.setBackgroundColor(Color.YELLOW)
} else if (data.toInt() >= 500) {
textView2?.setBackgroundColor(Color.rgb(255, 165, 0))
} else if (data.toInt() >= 250) {
textView2?.setBackgroundColor(Color.RED)
} else if (data.toInt() >= 0) {
textView2?.setBackgroundColor(Color.BLACK)
}
}
private fun timescale(data: String) {
storeList.add(data.toInt())
var arraySize = storeList.size
seekBar!!.max = arraySize - 1
textView!!.text = storeList.size.toString()
seekBar?.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) {
seekText!!.text = storeList[progress].toString()
if (storeList[progress] >= 1000) {
seekText?.setBackgroundColor(Color.GREEN)
} else if (storeList[progress] >= 750) {
seekText?.setBackgroundColor(Color.YELLOW)
} else if (storeList[progress] >= 500) {
seekText?.setBackgroundColor(Color.rgb(255, 165, 0))
} else if (storeList[progress] >= 250) {
seekText?.setBackgroundColor(Color.RED)
} else if (storeList[progress] >= 0) {
seekText?.setBackgroundColor(Color.BLACK)
}
}
override fun onStartTrackingTouch(seekBar: SeekBar?) {
}
override fun onStopTrackingTouch(seekBar: SeekBar?) {
}
})
}
}
XML
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context=".Surfboard"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/surfboard"
>
<!--Table Layout with 3 rows and each row with 3 buttons-->
<TableLayout
android:layout_width="300dp"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerInParent="true"
android:rowCount="3"
android:columnCount="3"
android:padding="8dp">
<Button
android:id="@+id/buttonStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClickStart"
android:text="@string/Begin"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/statusText"
android:layout_below="@+id/buttonSend"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="true" />
<Button
android:id="@+id/activate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/activate"
android:onClick="onClickSend"
tools:ignore="OnClick" />
<Button
android:id="@+id/deactivate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="onClickStop"
android:text="@string/deactivate"/>
<TextView
android:id="@+id/test"
android:layout_width="150dp"
android:layout_height="100dp"
android:gravity="center"
android:textSize="32dp"
android:textColor="#FFFFFF"
android:background="#E0E0E0"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/textView"
android:layout_below="@+id/buttonSend"
android:layout_marginTop="20dp"
android:background="#E0E0E0" />
<SeekBar
android:id="@+id/seekBar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="48dp"
android:progressDrawable="@drawable/seek_bar"
android:thumb="@drawable/seek_thumb"
/>
<TextView
android:layout_width="100dp"
android:layout_height="100dp"
android:id="@+id/seekText"
android:gravity="center"
android:textSize="32dp"
android:layout_below="@+id/buttonSend"
android:layout_marginTop="20dp"
android:textColor="#FFFFFF"
android:background="#E0E0E0" />
</TableLayout>
</RelativeLayout>
Logcat
2020-04-20 17:13:42.040 22833-22833/? E/Zygote: isWhitelistProcess - Process is Whitelisted
2020-04-20 17:13:42.042 22833-22833/? E/libpersona: scanKnoxPersonas
2020-04-20 17:13:42.042 22833-22833/? E/libpersona: Couldn't open the File - /data/system/users/0/personalist.xml - No such file or directory
2020-04-20 17:14:01.283 22833-23200/com.example.surf10 E/AndroidRuntime: FATAL EXCEPTION: Thread-5
Process: com.example.surf10, PID: 22833
java.lang.NumberFormatException: For input string: ""
at java.lang.Integer.parseInt(Integer.java:620)
at java.lang.Integer.parseInt(Integer.java:643)
at com.example.surf10.Surfboard.timescale(Surfboard.kt:219)
at com.example.surf10.Surfboard.access$timescale(Surfboard.kt:32)
at com.example.surf10.Surfboard$mCallback$1.onReceivedData(Surfboard.kt:59)
at com.felhr.usbserial.UsbSerialDevice$WorkerThread.onReceivedData(UsbSerialDevice.java:209)
at com.felhr.usbserial.UsbSerialDevice$WorkerThread.run(UsbSerialDevice.java:184)
2020-04-20 17:14:02.116 22833-22833/com.example.surf10 E/ActivityThread: Activity com.example.surf10.Surfboard has leaked IntentReceiver com.example.surf10.Surfboard$broadcastReceiver$1@e42873b that was originally registered here. Are you missing a call to unregisterReceiver()?
android.app.IntentReceiverLeaked: Activity com.example.surf10.Surfboard has leaked IntentReceiver com.example.surf10.Surfboard$broadcastReceiver$1@e42873b that was originally registered here. Are you missing a call to unregisterReceiver()?
at android.app.LoadedApk$ReceiverDispatcher.<init>(LoadedApk.java:1357)
at android.app.LoadedApk.getReceiverDispatcher(LoadedApk.java:1122)
at android.app.ContextImpl.registerReceiverInternal(ContextImpl.java:1428)
at android.app.ContextImpl.registerReceiver(ContextImpl.java:1401)
at android.app.ContextImpl.registerReceiver(ContextImpl.java:1389)
at android.content.ContextWrapper.registerReceiver(ContextWrapper.java:622)
at com.example.surf10.Surfboard.onCreate(Surfboard.kt:124)
at android.app.Activity.performCreate(Activity.java:7183)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1220)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2910)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3032)
at android.app.ActivityThread.-wrap11(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1696)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6944)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)