I am making an SOS app, where I have defined a function in mainactivty ( sendSOS() ) class that gets user location and sends a sms to contacts saved. Now i have created a sensor service class that detects a shake event and runs in foreground, and when a shake happens it is supposed to again invoke the (sendSOS() ) method. But its not working properly. Below is the error and code. Any guidance on how to implement it would be appreciated.
java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference
at android.content.ContextWrapper.getApplicationContext(ContextWrapper.java:135)
at com.google.android.gms.common.api.GoogleApi.<init>(com.google.android.gms:play-services-base@@18.1.0:7)
at com.google.android.gms.common.api.GoogleApi.<init>(com.google.android.gms:play-services-base@@18.1.0:1)
at com.google.android.gms.internal.location.zzbp.<init>(com.google.android.gms:play-services-location@@21.0.1:1)
at com.google.android.gms.location.LocationServices.getFusedLocationProviderClient(com.google.android.gms:play-services-location@@21.0.1:1)
at com.chrizlove.helpapp.MainActivity.sendSOS(MainActivity.kt:142)
at com.chrizlove.helpapp.SensorService$onCreate$1.onShake(SensorService.kt:67)
at com.chrizlove.helpapp.ShakeDetector.onSensorChanged(ShakeDetector.kt:51)
The SensorService code part which will be used to call the sendSOS() of MainActivty when device is shaken.
override fun onShake(count: Int) {
// check if the user has shacked
// the phone for 3 time in a row
if (count == 3) {
// vibrate the phone
vibrate()
//here i want to call the sendSos method that is in the mainActivity
val mActivity = MainActivity()
mActivity.sendSOS(applicationContext)
Toast.makeText(applicationContext,"Shaken", Toast.LENGTH_SHORT).show()
}
}
The MainActivity sendSOS() method along with rest of the methods used for its functioning.
public fun sendSOS(context: Context) {
fusedLocationProviderClient=LocationServices.getFusedLocationProviderClient(this)
getCurrentLocationAndSendSMS(context)
}
private fun sendSMS() {
Log.d(TAG,"2")
if(checkSMSPermission(this)){
val smsManager: SmsManager
smsManager = SmsManager.getDefault()
for (contact in contactViewModel.contacts.value!!){
smsManager.sendTextMessage(contact.c_number, null,
"Hi, I am in an emergency! This is my location https://www.google.com/maps/?q="+location.latitude+","+location.longitude,
null, null)
}
Toast.makeText(applicationContext,"SMS Sent",Toast.LENGTH_SHORT).show()
}
else{
requestSMSPermission()
}
}
private fun requestSMSPermission() {
ActivityCompat.requestPermissions(this,
arrayOf(Manifest.permission.SEND_SMS), PERMISSION_REQUEST_SMS)
}
private fun checkSMSPermission(context: Context): Boolean {
return ActivityCompat.checkSelfPermission(context,Manifest.permission.SEND_SMS)==PackageManager.PERMISSION_GRANTED
}
public fun getCurrentLocationAndSendSMS(context: Context) {
Log.d(TAG,"1")
if(checkLocationPermission(context)){
if(locationEnabled()){
fusedLocationProviderClient.lastLocation.addOnCompleteListener(this) {task->
location=task.result
if(location==null){
//do something later on
}
else{
//SEND sms when gotten location
sendSMS()
}
}
}
else{
//send last known location
}
}
else{
//request permission
requestLocationPermission()
}
}
companion object{
private const val PERMISSION_REQUEST_ACCESS_LOCATION=100
private const val PERMISSION_REQUEST_SMS=99
}
private fun requestLocationPermission() {
ActivityCompat.requestPermissions(this,
arrayOf( Manifest.permission.ACCESS_COARSE_LOCATION,Manifest.permission.ACCESS_FINE_LOCATION),
PERMISSION_REQUEST_ACCESS_LOCATION)
}
private fun locationEnabled(): Boolean {
val locationManager: LocationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) || locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)
}
private fun checkLocationPermission(context: Context): Boolean {
if(ActivityCompat.checkSelfPermission(context,Manifest.permission.ACCESS_COARSE_LOCATION)==PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(context,Manifest.permission.ACCESS_FINE_LOCATION)==PackageManager.PERMISSION_GRANTED)
{
return true
}
return false
}
If anything else is needed just ask, it would be very helpful to get any sort of lead as to how to implement it.
This question explains and and provides the solution to this provlem:---https://stackoverflow.com/questions/14896574/how-to-call-a-method-in-activity-from-a-service