无法在AndroidKotlin的Service Class中使用MainActivity的方法

ktca8awb  于 2023-05-29  发布在  Kotlin
关注(0)|答案(1)|浏览(122)

我正在制作一个SOS应用程序,我在mainactivty(sendSOS())类中定义了一个函数,该函数可以获取用户位置并向保存的联系人发送短信。现在我已经创建了一个传感器服务类,它检测到一个震动事件并在前台运行,当震动发生时,它应该再次调用(sendSOS())方法。但它不能正常工作。下面是错误和代码。如能就如何执行该计划提供任何指导,将不胜感激。

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)

SensorService代码部分,用于在设备摇动时调用MainActivty的sendSOS()。

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()
            }
        }

MainActivity sendSOS()方法沿着用于其功能的其余方法。

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
}

如果还需要什么,只要问一声,就能得到任何关于如何实现它的线索,这将是非常有用的。
此问题解释并提供了此问题的解决方案:---https:stackoverflow.com/questions/14896574/how-to-call-a-method-in-activity-from-a-service

c0vxltue

c0vxltue1#

**方法1:**要从MainActivty调用方法,需要在onShake()中的SensorService中写入以下内容:

(applicationContext as MainActivity).sendSOS(applicationContext)

方法二:

您可以使用BroadcastReceiver从服务获取数据。
在MainActivity中添加sosReceiver,它调用sendSos函数:

private val sosReceiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        sendSOS(context)
    }
}

要在onCreate函数的MainActivity中接收广播,请添加:

registerReceiver(sosReceiver, IntentFilter.create(SensorService.ACTION_SOS_SEND, null))

然后在MainActivity中的onDestroy()函数中注销接收器:

override fun onDestroy() {
    super.onDestroy()
    unregisterReceiver(sosReceiver)
}

在SensorService中发送广播:

override fun onShake(count: Int) {
        if (count == 3) {
            // other code
            val sosIntent = Intent(ACTION_SOS_SEND)
            this.sendBroadcast(sosIntent)
        }
    }

companion object {
    const val ACTION_SOS_SEND = "com.company.package.ACTION_SOS_SEND"
}

注意:不能创建包含MainActivity的Activity示例。Android自己负责这项任务

相关问题