Im extremely new to app development/programming, and am grossly underqualified for what my company wants me to do. But we want users to press a button on the UI, which gets the location and sends a text to 911 with their coordinates and a string regarding their type of emergency. I've fixed all the errors in the code, but still haven't figured out why Im getting a runtime error.
Here is my MainActivity.kt
package com.example.emergencyapp
import android.Manifest
import android.annotation.SuppressLint
import android.content.pm.PackageManager
import android.location.Location
import android.location.LocationListener
import android.location.LocationManager
import android.os.Bundle
import android.telephony.SmsManager
import android.util.Log
import android.widget.Button
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat.requestPermissions
import androidx.core.content.ContextCompat
import com.google.android.gms.ads.MobileAds
import com.google.android.gms.maps.GoogleMap
import com.google.android.gms.maps.SupportMapFragment
class MainActivity : AppCompatActivity() {
private lateinit var mapFragment: SupportMapFragment
private lateinit var googleMap: GoogleMap
private fun getLocation() {
val locationManager = getSystemService(LOCATION_SERVICE) as LocationManager?
val locationListener = object : LocationListener {
override fun onLocationChanged(location: Location) {
val latitude = location.latitude
val longitude = location.longitude
Log.i("test", "Latitude: $latitude ; Longitude: $longitude")
}
override fun onStatusChanged(provider: String?, status: Int, extras: Bundle?) {
}
override fun onProviderEnabled(provider: String) {
}
override fun onProviderDisabled(provider: String) {
}
}
try {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
requestPermissions(
this,
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
PERMISSION_REQUEST_ACCESS_FINE_LOCATION)
return
}
locationManager!!.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0L, 0f, locationListener)
} catch (ex: SecurityException) {
Toast.makeText(applicationContext, "Wrong Permissions!", Toast.LENGTH_SHORT).show()
}
}
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == PERMISSION_REQUEST_ACCESS_FINE_LOCATION) {
when (grantResults[0]) {
PackageManager.PERMISSION_GRANTED -> getLocation()
PackageManager.PERMISSION_DENIED -> Toast.makeText(applicationContext, "Enable Permissions!", Toast.LENGTH_SHORT).show() //Tell to user the need of grant permission
}
}
}
companion object {
private const val PERMISSION_REQUEST_ACCESS_FINE_LOCATION = 100
}
@SuppressLint("MissingPermission", "UnlocalizedSms")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val spanishString = "I only speak Spanish. "
val smsAutomatic = " ***THIS MESSAGE SENT AUTOMATICALLY***"
mapFragment = (supportFragmentManager.findFragmentById(R.id.mapView) as SupportMapFragment?)!!
mapFragment.getMapAsync {
googleMap = it
}
MobileAds.initialize(this) {}
//fusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
//locationManager = getSystemService(LOCATION_SERVICE) as LocationManager?
//get reference to button
val heartAttackButton = findViewById<Button>(R.id.heartAttackButton)
heartAttackButton.setOnClickListener {
@SuppressLint("UnlocalizedSms")
val heartSMS = spanishString + "Someone is having a cardiac emergency at the following location: " + getLocation() + smsAutomatic
try {
val smsManager = SmsManager.getDefault()
smsManager.sendTextMessage("911", null, heartSMS, null, null)
Toast.makeText(applicationContext, "Message Sent", Toast.LENGTH_LONG).show()
} catch (e: Exception) {
Toast.makeText(applicationContext, "Message failed to send", Toast.LENGTH_SHORT).show()
}
}
val strokeButton = findViewById<Button>(R.id.strokeButton)
strokeButton.setOnClickListener {
@SuppressLint("UnlocalizedSms")
val strokeSMS = spanishString + "Someone is having a stroke at the following location: " + getLocation() + smsAutomatic
try {
val smsManager = SmsManager.getDefault()
smsManager.sendTextMessage("911", null, strokeSMS, null, null)
Toast.makeText(applicationContext, "Message Sent", Toast.LENGTH_LONG).show()
} catch (e: Exception) {
Toast.makeText(applicationContext, "Message failed to send", Toast.LENGTH_SHORT).show()
}
}
val chokingButton = findViewById<Button>(R.id.chokingButton)
chokingButton.setOnClickListener {
@SuppressLint("UnlocalizedSms")
val chokeSMS = spanishString + "Someone is choking at the following location: " + getLocation() + smsAutomatic
try {
val smsManager = SmsManager.getDefault()
smsManager.sendTextMessage("911", null, chokeSMS, null, null)
Toast.makeText(applicationContext, "Message Sent", Toast.LENGTH_LONG).show()
} catch (e: Exception) {
Toast.makeText(applicationContext, "Message failed to send", Toast.LENGTH_SHORT).show()
}
}
val babyButton = findViewById<Button>(R.id.babyButton)
babyButton.setOnClickListener {
@SuppressLint("UnlocalizedSms")
val babySMS = spanishString + "Someone is having a baby at the following location: " + getLocation() + smsAutomatic
try {
val smsManager = SmsManager.getDefault()
smsManager.sendTextMessage("911", null, babySMS, null, null)
Toast.makeText(applicationContext, "Message Sent", Toast.LENGTH_LONG).show()
} catch (e: Exception) {
Toast.makeText(applicationContext, "Message failed to send", Toast.LENGTH_SHORT).show()
}
}
val breathingButton = findViewById<Button>(R.id.breathingButton)
breathingButton.setOnClickListener {
@SuppressLint("UnlocalizedSms")
val breathingSMS = spanishString + "Someone is having a respiratory emergency at the following location: " + getLocation() + smsAutomatic
try {
val smsManager = SmsManager.getDefault()
smsManager.sendTextMessage("911", null, breathingSMS, null, null)
Toast.makeText(applicationContext, "Message Sent", Toast.LENGTH_LONG).show()
} catch (e: Exception) {
Toast.makeText(applicationContext, "Message failed to send", Toast.LENGTH_SHORT).show()
}
}
val bleedingButton = findViewById<Button>(R.id.bleedingButton)
bleedingButton.setOnClickListener {
@SuppressLint("UnlocalizedSms")
val bleedSMS = spanishString + "Someone is bleeding at the following location: " + getLocation() + smsAutomatic
try {
val smsManager = SmsManager.getDefault()
smsManager.sendTextMessage("911", null, bleedSMS, null, null)
Toast.makeText(applicationContext, "Message Sent", Toast.LENGTH_LONG).show()
} catch (e: Exception) {
Toast.makeText(applicationContext, "Message failed to send", Toast.LENGTH_SHORT).show()
}
}
val fightButton = findViewById<Button>(R.id.fightButton)
fightButton.setOnClickListener {
@SuppressLint("UnlocalizedSms")
val fightSMS = spanishString + "Someone is fighting at the following location: " + getLocation() + smsAutomatic
try {
val smsManager = SmsManager.getDefault()
smsManager.sendTextMessage("911", null, fightSMS, null, null)
Toast.makeText(applicationContext, "Message Sent", Toast.LENGTH_LONG).show()
} catch (e: Exception) {
Toast.makeText(applicationContext, "Message failed to send", Toast.LENGTH_SHORT).show()
}
}
val gunShotButton = findViewById<Button>(R.id.gunShotButton)
gunShotButton.setOnClickListener {
@SuppressLint("UnlocalizedSms")
val gunShotSMS = spanishString + "Someone has been shot at the following location: " + getLocation() + smsAutomatic
try {
val smsManager = SmsManager.getDefault()
smsManager.sendTextMessage("911", null, gunShotSMS, null, null)
Toast.makeText(applicationContext, "Message Sent", Toast.LENGTH_LONG).show()
} catch (e: Exception) {
Toast.makeText(applicationContext, "Message failed to send", Toast.LENGTH_SHORT).show()
}
}
val stabbedButton = findViewById<Button>(R.id.stabbedButton)
stabbedButton.setOnClickListener {
@SuppressLint("UnlocalizedSms")
val stabbedSMS = spanishString + "Someone has been stabbed at the following location: " + getLocation() + smsAutomatic
try {
val smsManager = SmsManager.getDefault()
smsManager.sendTextMessage("911", null, stabbedSMS, null, null)
Toast.makeText(applicationContext, "Message Sent", Toast.LENGTH_LONG).show()
} catch (e: Exception) {
Toast.makeText(applicationContext, "Message failed to send", Toast.LENGTH_SHORT).show()
}
}
val fireButton = findViewById<Button>(R.id.fireButton)
fireButton.setOnClickListener {
@SuppressLint("UnlocalizedSms")
val fireSMS = spanishString + "Something is on fire at the following location: " + getLocation() + smsAutomatic
try {
val smsManager = SmsManager.getDefault()
smsManager.sendTextMessage("911", null, fireSMS, null, null)
Toast.makeText(applicationContext, "Message Sent", Toast.LENGTH_LONG).show()
} catch (e: Exception) {
Toast.makeText(applicationContext, "Message failed to send", Toast.LENGTH_SHORT).show()
}
}
val intruderButton = findViewById<Button>(R.id.intruderButton)
intruderButton.setOnClickListener {
@SuppressLint("UnlocalizedSms")
val intruderSMS = spanishString + "There is an intruder at the following location: " + getLocation() + smsAutomatic
try {
val smsManager = SmsManager.getDefault()
smsManager.sendTextMessage("911", null, intruderSMS, null, null)
Toast.makeText(applicationContext, "Message Sent", Toast.LENGTH_LONG).show()
} catch (e: Exception) {
Toast.makeText(applicationContext, "Message failed to send", Toast.LENGTH_SHORT).show()
}
}
val overdoseButton = findViewById<Button>(R.id.overdoseButton)
overdoseButton.setOnClickListener {
@SuppressLint("UnlocalizedSms")
val overdoseSMS = spanishString + "Someone has overdosed at the following location: " + getLocation() + smsAutomatic
try {
val smsManager = SmsManager.getDefault()
smsManager.sendTextMessage("911", null, overdoseSMS, null, null)
Toast.makeText(applicationContext, "Message Sent", Toast.LENGTH_LONG).show()
} catch (e: Exception) {
Toast.makeText(applicationContext, "Message failed to send", Toast.LENGTH_SHORT).show()
}
}
val fallButton = findViewById<Button>(R.id.fallButton)
fallButton.setOnClickListener {
@SuppressLint("UnlocalizedSms")
val fallSMS = spanishString + "Someone has fallen at the following location: " + getLocation() + smsAutomatic
try {
val smsManager = SmsManager.getDefault()
smsManager.sendTextMessage("911", null, fallSMS, null, null)
Toast.makeText(applicationContext, "Message Sent", Toast.LENGTH_LONG).show()
} catch (e: Exception) {
Toast.makeText(applicationContext, "Message failed to send", Toast.LENGTH_SHORT).show()
}
}
val faintButton = findViewById<Button>(R.id.faintButton)
faintButton.setOnClickListener {
@SuppressLint("UnlocalizedSms")
val faintSMS =
spanishString + "Someone has fainted at the following location: " + getLocation() + smsAutomatic
try {
val smsManager = SmsManager.getDefault()
smsManager.sendTextMessage("911", null, faintSMS, null, null)
Toast.makeText(applicationContext, "Message Sent", Toast.LENGTH_LONG).show()
} catch (e: Exception) {
Toast.makeText(
applicationContext,
"Message failed to send",
Toast.LENGTH_SHORT,
).show()
}
}
}
}
/*override fun onClick(v: View?) {
//val clickListener = View.OnClickListener { view ->
//val destinationNumber = "911"
//var contactOneNumber = "+12622260839"
//var contactTwoNumber = "+14148413538"
//var locationSMS = "test"
//SMS messages used to be delcared here
/*when (view.id) {
R.id.heartAttackButton -> getDefault().sendTextMessage(destinationNumber, null, heartSMS, null,null)
R.id.strokeButton -> getDefault().sendTextMessage(destinationNumber, null, strokeSMS, null,null)
R.id.chokingButton -> getDefault().sendTextMessage(destinationNumber, null, chokeSMS, null,null)
R.id.babyButton -> getDefault().sendTextMessage(destinationNumber, null, babySMS, null,null)
R.id.bleedingButton -> getDefault().sendTextMessage(destinationNumber, null, bleedSMS, null,null)
R.id.breathingButton -> getDefault().sendTextMessage(destinationNumber, null, breathingSMS, null,null)
R.id.fightButton -> getDefault().sendTextMessage(destinationNumber, null, fightSMS, null,null)
R.id.gunShotButton -> getDefault().sendTextMessage(destinationNumber, null, gunShotSMS, null,null)
R.id.stabbedButton -> getDefault().sendTextMessage(destinationNumber, null, stabbedSMS, null,null)
R.id.fireButton -> getDefault().sendTextMessage(destinationNumber, null, fireSMS, null,null)
R.id.overdoseButton -> getDefault().sendTextMessage(destinationNumber, null, overdoseSMS, null,null)
R.id.intruderButton -> getDefault().sendTextMessage(destinationNumber, null, intruderSMS, null,null)
R.id.fallButton -> getDefault().sendTextMessage(destinationNumber, null, fallSMS, null,null)
R.id.faintButton -> getDefault().sendTextMessage(destinationNumber, null, faintSMS, null,null)
else -> println("You shouldnt see this message ")
}
*/
}
}
}
*/
And here is my AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.example.emergencyapp">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_SMS"/>
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.LOCATION_HARDWARE"
tools:ignore="ProtectedPermissions" />
<application
android:allowBackup="true"
android:fullBackupContent="@xml/backup_descriptor"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.EmergencyApp">
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-4486073063816949~9502047390">
</meta-data>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
My activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<com.google.android.gms.maps.MapView
android:id="@+id/mapView"
android:layout_width="405dp"
android:layout_height="213dp"
android:layout_marginTop="391dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="@+id/tableLayout" />
<TableLayout
android:id="@+id/tableLayout"
style="?android:attr/buttonBarStyle"
android:layout_width="409dp"
android:layout_height="0dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<TableRow
style="?android:attr/buttonBarStyle"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/heartAttackButton"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="180dp"
android:layout_height="wrap_content"
android:text="@string/heartAttack" />
<Button
android:id="@+id/strokeButton"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/stroke" />
</TableRow>
<TableRow
style="?android:attr/buttonBarStyle"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/chokingButton"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/choking" />
<Button
android:id="@+id/babyButton"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/baby" />
</TableRow>
<TableRow
style="?android:attr/buttonBarStyle"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/breathingButton"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/breathing" />
<Button
android:id="@+id/bleedingButton"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/bleeding" />
</TableRow>
<TableRow
style="?android:attr/buttonBarStyle"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/fightButton"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/fight" />
<Button
android:id="@+id/gunShotButton"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/gunshot" />
</TableRow>
<TableRow
style="?android:attr/buttonBarStyle"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/stabbedButton"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/stabbed" />
<Button
android:id="@+id/fireButton"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/fire" />
</TableRow>
<TableRow
style="?android:attr/buttonBarStyle"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/intruderButton"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/intruder" />
<Button
android:id="@+id/overdoseButton"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/overdose" />
</TableRow>
<TableRow
style="?android:attr/buttonBarStyle"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:id="@+id/fallButton"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/fall" />
<Button
android:id="@+id/faintButton"
style="?android:attr/buttonBarButtonStyle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/faint" />
</TableRow>
</TableLayout>
</androidx.constraintlayout.widget.ConstraintLayout>
And the logcat output
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.emergencyapp, PID: 25250
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.emergencyapp/com.example.emergencyapp.MainActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3449)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
Caused by: java.lang.NullPointerException
at com.example.emergencyapp.MainActivity.onCreate(MainActivity.kt:87)
at android.app.Activity.performCreate(Activity.java:8000)
at android.app.Activity.performCreate(Activity.java:7984)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1309)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3422)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3601)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:85)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2066)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:223)
at android.app.ActivityThread.main(ActivityThread.java:7656)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)
I/Process: Sending signal. PID: 25250 SIG: 9
Ive narrowed down the error to line 87 mapFragment = (supportFragmentManager.findFragmentById(R.id.mapView) as SupportMapFragment?)!!
Ive tried cleaning up the code, rebuilding and that didn't work. I made sure I had a dot before the activity name on my manifest. I couldn't seem to find any other threads here that helped me at all. Id appreciate any help as I still don't really understand what I'm doing.