大家好。目前,我正在构建应用程序的一部分,按下按钮即可启用和禁用 GPS 位置跟踪。
问题是我不明白如何正确启动它并通过按按钮停止它。
这是我的代码:
package red.button.flipper_navigator.ui
import android.Manifest
import android.content.Context
import android.content.Intent
import android.os.Bundle
import android.util.Log
import android.view.View
import androidx.lifecycle.ViewModel
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.ViewModelProvider
import red.button.flipper_navigator.ui_logic.MainScreenLogic
import red.button.flipper_navigator.R
import red.button.flipper_navigator.databinding.ScreenMainBinding
import red.button.flipper_navigator.databinding.TextFieldBinding
import red.button.flipper_navigator.gps.LocationService
import red.button.flipper_navigator.gps.gps_activation
@Suppress("DEPRECATION")
class MainScreen : AppCompatActivity(), gps_activation {
private lateinit var bindingMain: ScreenMainBinding
private lateinit var bindingField: TextFieldBinding
private var context: Context? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
ActivityCompat.requestPermissions(
this,
arrayOf(
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.POST_NOTIFICATIONS
),
0
)
bindingMain = DataBindingUtil.setContentView(this, R.layout.screen_main)
bindingField = bindingMain.textField
val viewModel = ViewModelProvider(this)[MainScreenLogic::class.java]
bindingMain.mainview = viewModel
bindingField.textfieldview = viewModel
context = getApplicationContext()
// Intent(context, LocationService::class.java).apply {
// action = LocationService.ACTION_START
// startService(this)
// }
}
override fun start() {
Intent(context, LocationService::class.java).apply {
action = LocationService.ACTION_START
startService(this)
}
}
override fun stop() {
Intent(context, LocationService::class.java).apply {
action = LocationService.ACTION_STOP
startService(this)
}
}
}
//Organise string. Evidence link, make all strange symbols disappear
//val str: String = (" " + editText.text.toString() + " ").replace("\n", " ")
//
// Toast.makeText(this, fLink, Toast.LENGTH_SHORT).show()
这是我的gps_activation界面
package red.button.flipper_navigator.gps
import android.content.Context
import red.button.flipper_navigator.ui.MainScreen
interface gps_activation {
fun start()
fun stop()
companion object {
fun create(): gps_activation {
return MainScreen()
}
}
}
这是我的视图模型,我在其中触发 Start 函数来启动服务。
package red.button.flipper_navigator.ui_logic
import android.app.Application
import android.content.Context
import android.content.Intent
import android.util.Log
import android.view.View
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.async
import red.button.flipper_navigator.core.impl.link_logic.TextRef
import red.button.flipper_navigator.data.remote.GetLink
import red.button.flipper_navigator.gps.LocationService
import red.button.flipper_navigator.gps.gps_activation
@OptIn(ExperimentalCoroutinesApi::class)
@Suppress("UNUSED_PARAMETER")
class MainScreenLogic() : ViewModel() {
var link: String = ""
val gpsSet = gps_activation.create()
fun generateBt(view: View) {
val linkUnzip = TextRef.create()
val service = GetLink.create()
val glink = viewModelScope.async {
service.getPosts(linkUnzip.linkUnfolder(link))
}
glink.invokeOnCompletion {
if (it == null) {
Log.d("link111", linkUnzip.placeFind(glink.getCompleted())[1])
}
}
Log.d("link111", "ok")
}
fun connectBt(view: View) {
}
// This Button i'm trying to use to start gps //
fun StartNavBt(view: View) {
Log.d("gps", "ok")
gpsSet.start()
}
}
我收到此错误:
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String android.content.Context.getPackageName()' on a null object reference
at android.content.ComponentName.<init>(ComponentName.java:131)
at android.content.Intent.<init>(Intent.java:6858)
at red.button.flipper_navigator.ui.MainScreen.start(MainScreen.kt:58)
at red.button.flipper_navigator.ui_logic.MainScreenLogic.StartNavBt(Main_screen_logic.kt:47)
at red.button.flipper_navigator.databinding.ScreenMainBindingImpl$OnClickListenerImpl1.onClick(ScreenMainBindingImpl.java:189)
at android.view.View.performClick(View.java:7448)
at android.view.View.performClickInternal(View.java:7425)
at android.view.View.access$3600(View.java:810)
at android.view.View$PerformClick.run(View.java:28305)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
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)
按下按钮,我从界面启动一个函数,在主活动中初始化该函数,但我总是收到错误。
也许我做的完全错误?我应该用一些依赖来实现它吗?我仍在学习,它可以。
按下按钮,我从界面启动一个函数,在主活动中初始化该函数,但我总是收到错误。
也许我做的完全错误?我应该用一些依赖来实现它吗?我仍在学习,该程序可能已过时或错误。
感谢您的帮助!
问题的根本原因在于这一行:
return MainScreen()
Android 的活动、服务和其他组件由 Android 平台管理。它们是在需要时自动创建的,它们会完成初始化过程,它们在平台创建的上下文中运行。我们无法直接创建这些对象并期望它们能够正常工作。
通常,ViewModel 应该对 Activity 一无所知,它不应该保留对 Activity 的引用或调用其方法。模型用于处理数据,而不是执行操作。我们通常做的就是以
Flow
或LiveData
的形式暴露ViewModel中的一些信息。然后,我们在活动中观察这些数据,并根据变化的数据执行操作。
我没有提供可行的解决方案,因为这几乎超出了这个问题的范围。