Here we will make a class that will monitor readings from the accelerometer, and put a feature to lower the chances of an accidental emergency message being sent.
This is the fifth article in a series on making a real-time hazard detector with Android and Tensorflow Lite. In this part, we will add crash detection to the application and give the application the ability to send notifications to an emergency contact.
Taking advantage of the features of most Android devices, we can add crash detection to the device. In most Android devices, the device has an accelerometer and GPS. Together, we can use these to send a message if we think that a crash has occurred and send an emergency message with a location.
To detect crashes, I’ve created a new class named CrashDetector
. The class will monitor readings from the accelerometer. When it receives a reading that is above a certain level then it is assumed that the vehicle experienced an impact. The value that I’ve selected for indicating an impact here is a best estimate based on reading about car crashes.
var coolDownExpiry:Long = 0
val COOL_DOWN_TIME = 10000
fun resetCooldown() {
coolDownExpiry = Date().time + COOL_DOWN_TIME
}
fun hasCooldownExpired():Boolean {
val now = Date().time
return now > coolDownExpiry
}
fun alert(direction: Int) {
// using the when statement to filter out invalid
// values should they be passed to this function
if(hasCooldownExpired() && currentSpeedMPS>MIN_ALERT_MPS) {
when (direction) {
ALARM_CENTER, ALARM_RIGHT, ALARM_LEFT -> {
soundPlayer = MediaPlayer.create(context, direction)
soundPlayer!!.start()
}
}
}
resetCooldown()
}
There are some other conditions that could result in a sudden high reading from the accelerometer. It is possible that the device was dropped, that the user drove over a pothole, or the user had a collision for which they do not want to send an alert. To lower the chances of an accidental emergency message being sent, there is a delay before the message is sent. During this delay, the device shows a prompt allowing the user to either cancel the message or send it out. If nothing is selected when the dialog expires, it will send out a message to the phone number that the user had selected as their emergency contact. If there is a last-known location for the driver, it will be sent as a link to Google Maps.
fun sendEmergencyMessage() {
var msg = crashMessage
if(this.location != null) {
msg = msg + " https://www.google.com/maps/@${location!!.latitude},${location!!.longitude},15z"
}
val smsManager = SmsManager.getDefault() as SmsManager
smsManager.sendTextMessage(crashPhoneNumber, null,msg , null, null)
}
Now that all of the major functions are built, we can get the last piece in place and have the application use the live video stream instead of the static images. In the next part of this series, we’ll have the application process live data.