输入地理围栏时,我不知道如何更改“ btn_done.isEnabled = true”代码

时间:2019-06-10 04:19:51

标签: android kotlin android-geofence

我是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" />

1 个答案:

答案 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
        }


    }