我是Joss,这是我在stackoverflow中的第一个问题 我想在发生地理围栏事件时激活(isEnabled = true)按钮。 适用于sendNotification的代码令人担忧,但我想添加功能添加按钮(btn_done)激活
GeofenceTransitionService.kt
class GeofenceTransitionService : IntentService("GeoTrIntentService") {
companion object {
private const val LOG_TAG = "GeoTrIntentService"
}
override fun onHandleIntent(intent: Intent?) {
val geofencingEvent = GeofencingEvent.fromIntent(intent)
if (geofencingEvent.hasError()) {
val errorMessage = GeofenceErrorMessages.getErrorString(this,
geofencingEvent.errorCode)
Log.e(LOG_TAG, errorMessage)
return
}
handleEvent(geofencingEvent)
}
private fun handleEvent(event: GeofencingEvent) {
if (event.geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER) {
btn_done.isEnabled = true //How should I code this?
val reminder = getFirstReminder(event.triggeringGeofences)
val message = reminder?.message
val latLng = reminder?.latLng
if (message != null && latLng != null) {
sendNotification(this, message, latLng)
}
}
}
private fun getFirstReminder(triggeringGeofences: List<Geofence>): Reminder? {
val firstGeofence = triggeringGeofences[0]
return (application as
ReminderApp).getRepository().get(firstGeofence.requestId)
}
}
ReminderRepository.kt
class ReminderRepository(private val context: Context) {
companion object {
private const val PREFS_NAME = "ReminderRepository"
private const val REMINDERS = "REMINDERS"
}
private val preferences = context.getSharedPreferences(PREFS_NAME,
Context.MODE_PRIVATE)
private val gson = Gson()
private val geofencingClient = LocationServices.getGeofencingClient(context)
private val geofencePendingIntent: PendingIntent by lazy {
val intent = Intent(context, GeofenceTransitionService::class.java)
PendingIntent.getService(
context,
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT)
}
fun add(reminder: Reminder,
success: () -> Unit,
failure: (error: String) -> Unit) {
// 1
val geofence = buildGeofence(reminder)
if (geofence != null
&& ContextCompat.checkSelfPermission(
context,
Manifest.permission.ACCESS_FINE_LOCATION) ==
PackageManager.PERMISSION_GRANTED) {
// 2
geofencingClient
.addGeofences(buildGeofencingRequest(geofence),
geofencePendingIntent)
.addOnSuccessListener {
// 3
saveAll(getAll() + reminder)
success()
}
.addOnFailureListener {
// 4
failure(GeofenceErrorMessages.getErrorString(context,
it))
}
}
}
private fun buildGeofence(reminder: Reminder): Geofence? {
val latitude = reminder.latLng?.latitude
val longitude = reminder.latLng?.longitude
val radius = reminder.radius
if (latitude != null && longitude != null && radius != null) {
return Geofence.Builder()
.setRequestId(reminder.id)
.setCircularRegion(
latitude,
longitude,
radius.toFloat()
)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER)
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.build()
}
return null
}
private fun buildGeofencingRequest(geofence: Geofence): GeofencingRequest {
return GeofencingRequest.Builder()
.setInitialTrigger(0)
.addGeofences(listOf(geofence))
.build()
}
fun remove(reminder: Reminder,
success: () -> Unit,
failure: (error: String) -> Unit) {
geofencingClient
.removeGeofences(listOf(reminder.id))
.addOnSuccessListener {
saveAll(getAll() - reminder)
success()
}
.addOnFailureListener {
failure(GeofenceErrorMessages.getErrorString(context, it))
}
}
private fun saveAll(list: List<Reminder>) {
preferences
.edit()
.putString(REMINDERS, gson.toJson(list))
.apply()
}
fun getAll(): List<Reminder> {
if (preferences.contains(REMINDERS)) {
val remindersString = preferences.getString(REMINDERS, null)
val arrayOfReminders = gson.fromJson(remindersString,
Array<Reminder>::class.java)
if (arrayOfReminders != null) {
return arrayOfReminders.toList()
}
}
return listOf()
}
fun get(requestId: String?) = getAll().firstOrNull { it.id == requestId }
fun getLast() = getAll().lastOrNull()
}
MainActivity.kt(仅显示重要代码)
class MainActivity : BaseActivity(), OnMapReadyCallback,
GoogleMap.OnMarkerClickListener {
companion object {
private const val MY_LOCATION_REQUEST_CODE = 329
private const val NEW_REMINDER_REQUEST_CODE = 330
private const val EXTRA_LAT_LNG = "EXTRA_LAT_LNG"
private const val LOG_TAG = "GeoTrIntentService"
fun newIntent(context: Context, latLng: LatLng): Intent {
val intent = Intent(context, MainActivity::class.java)
intent.putExtra(EXTRA_LAT_LNG, latLng)
return intent
}
}
private var map: GoogleMap? = null
private lateinit var locationManager: LocationManager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_maps)
val mapFragment = supportFragmentManager
.findFragmentById(R.id.map) as SupportMapFragment
mapFragment.getMapAsync(this)
newReminder.visibility = View.GONE
currentLocation.visibility = View.GONE
newReminder.setOnClickListener {
map?.run {
val intent = NewReminderActivity.newIntent(
this@MainActivity,
cameraPosition.target,
cameraPosition.zoom)
startActivityForResult(intent, NEW_REMINDER_REQUEST_CODE)
val geofencingEvent = GeofencingEvent.fromIntent(intent)
qwer(geofencingEvent)
}
}
btn_done.setOnClickListener {
val intent = Intent(this, sub::class.java)
startActivity(intent)
}
locationManager = getSystemService(Context.LOCATION_SERVICE) as
LocationManager
if (ContextCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
MY_LOCATION_REQUEST_CODE)
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data:
Intent?) {
if (requestCode == NEW_REMINDER_REQUEST_CODE && resultCode ==
Activity.RESULT_OK) {
showReminders()
val reminder = getRepository().getLast()
map?.moveCamera(CameraUpdateFactory.newLatLngZoom(reminder?.latLng,
15f))
Snackbar.make(main, R.string.reminder_added_success,
Snackbar.LENGTH_LONG).show()
}
}
activate_maps.xml
<Button
android:id="@+id/btn_done"
android:enabled="false"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Arrive" />
答案 0 :(得分:0)
您可以使用Kotlin interface来更改应用程序中的按钮状态。
在GeofenceTransitionService.kt中创建用于按钮状态更改的界面
class GeofenceTransitionService : IntentService("GeoTrIntentService") {
interface ChangeViewState {
fun changeButtonState() : Button
}
companion object {
private const val LOG_TAG = "GeoTrIntentService"
}
override fun onHandleIntent(intent: Intent?) {
val geofencingEvent = GeofencingEvent.fromIntent(intent)
if (geofencingEvent.hasError()) {
val errorMessage = GeofenceErrorMessages.getErrorString(this,
geofencingEvent.errorCode)
Log.e(LOG_TAG, errorMessage)
return
}
handleEvent(geofencingEvent)
}
private val changeViewState : ChangeViewState? = null
private fun handleEvent(event: GeofencingEvent) {
if (event.geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER) {
//btn_done.isEnabled = true //How should I code this?
changeViewState?.changeButtonState().isEnabled = true
val reminder = getFirstReminder(event.triggeringGeofences)
val message = reminder?.message
val latLng = reminder?.latLng
if (message != null && latLng != null) {
sendNotification(this, message, latLng)
}
}
}
private fun getFirstReminder(triggeringGeofences: List<Geofence>): Reminder? {
val firstGeofence = triggeringGeofences[0]
return (application as
ReminderApp).getRepository().get(firstGeofence.requestId)
}
}
主要活动中的实施界面
class MainActivity : BaseActivity(), OnMapReadyCallback,
GoogleMap.OnMarkerClickListener, GeofenceTransitionService.ChangeViewState {
companion object {
private const val MY_LOCATION_REQUEST_CODE = 329
private const val NEW_REMINDER_REQUEST_CODE = 330
private const val EXTRA_LAT_LNG = "EXTRA_LAT_LNG"
private const val LOG_TAG = "GeoTrIntentService"
fun newIntent(context: Context, latLng: LatLng): Intent {
val intent = Intent(context, MainActivity::class.java)
intent.putExtra(EXTRA_LAT_LNG, latLng)
return intent
}
}
private var map: GoogleMap? = null
private lateinit var locationManager: LocationManager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_maps)
val mapFragment = supportFragmentManager
.findFragmentById(R.id.map) as SupportMapFragment
mapFragment.getMapAsync(this)
// Button Ref
newReminder.visibility = View.GONE
currentLocation.visibility = View.GONE
newReminder.setOnClickListener {
map?.run {
val intent = NewReminderActivity.newIntent(
this@MainActivity,
cameraPosition.target,
cameraPosition.zoom
)
startActivityForResult(intent, NEW_REMINDER_REQUEST_CODE)
val geofencingEvent = GeofencingEvent.fromIntent(intent)
qwer(geofencingEvent)
}
}
btn_done.setOnClickListener {
val intent = Intent(this, sub::class.java)
startActivity(intent)
}
locationManager = getSystemService(Context.LOCATION_SERVICE) as
LocationManager
if (ContextCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_FINE_LOCATION
)
!= PackageManager.PERMISSION_GRANTED
) {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
MY_LOCATION_REQUEST_CODE
)
}
}
override fun onActivityResult(
requestCode: Int, resultCode: Int, data:
Intent?
) {
if (requestCode == NEW_REMINDER_REQUEST_CODE && resultCode ==
Activity.RESULT_OK
) {
showReminders()
val reminder = getRepository().getLast()
map?.moveCamera(
CameraUpdateFactory.newLatLngZoom(
reminder?.latLng,
15f
)
)
Snackbar.make(
main, R.string.reminder_added_success,
Snackbar.LENGTH_LONG
).show()
}
}
// Implement interface
override fun changeButtonState(): Button {
val button = findViewById(R.id.btn_done) as Button
return button
}
}