Geofence triggering issues in Android

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-09 03:06:27

Let me show you what i have done for a similar task. Below code has been used to achieve geofencing.

class LocationService : Service(), GoogleApiClient.OnConnectionFailedListener, GoogleApiClient.ConnectionCallbacks {

var mLocationManager: LocationManager? = null
var googleApiClient: GoogleApiClient? = null
var pendingIntent: PendingIntent? = null
var geofencingRequest: GeofencingRequest? = null
var mGeofenceList: ArrayList<Geofence>? = null

private inner class LocationListener(provider: String) : android.location.LocationListener {
    private var mLastLocation: Location = Location(provider)

    override fun onLocationChanged(location: Location) {
        mLastLocation.set(location)
    }

    override fun onProviderDisabled(provider: String) {}

    override fun onProviderEnabled(provider: String) {}

    override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {}
}

internal var mLocationListeners = arrayOf<android.location.LocationListener>(LocationListener(LocationManager.GPS_PROVIDER), LocationListener(LocationManager.NETWORK_PROVIDER))


override fun onBind(arg0: Intent): IBinder? {
    return null
}

override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
    mGeofenceList = ArrayList()
    populateGeofenceList()
    super.onStartCommand(intent, flags, startId)
    return Service.START_STICKY
}

override fun onCreate() {
    initializeLocationManager()
    try {
        mLocationManager!!.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, Constant.LOCATION_INTERVAL.toLong(), Constant.LOCATION_DISTANCE, mLocationListeners[1])
    } catch (ex: java.lang.SecurityException) {
        ex.printStackTrace()
    } catch (ex: IllegalArgumentException) {
        ex.printStackTrace()
    }

    try {
        mLocationManager!!.requestLocationUpdates(
                LocationManager.GPS_PROVIDER, Constant.LOCATION_INTERVAL.toLong(), Constant.LOCATION_DISTANCE,
                mLocationListeners[0])
    } catch (ex: java.lang.SecurityException) {
        ex.printStackTrace()
    } catch (ex: IllegalArgumentException) {
        ex.printStackTrace()
    }

}

override fun onDestroy() {
    super.onDestroy()
    if (mLocationManager != null) {
        for (i in mLocationListeners.indices) {
            try {
                mLocationManager!!.removeUpdates(mLocationListeners[i])
            } catch (ex: Exception) {
                ex.printStackTrace()
            }
        }
    }
}

private fun initializeLocationManager() {

    googleApiClient = GoogleApiClient.Builder(this)
            .addApi(LocationServices.API)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this).build()
    googleApiClient!!.connect()
    if (mLocationManager == null) {
        mLocationManager = applicationContext.getSystemService(Context.LOCATION_SERVICE) as LocationManager?
    }
}

private fun startLocationMonitor() {
    val locationRequest = LocationRequest.create()
            .setInterval(Constant.LOCATION_INTERVAL.toLong())
            .setFastestInterval(Constant.LOCATION_INTERVAL.toLong())
            .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
    try {
        LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, object : com.google.android.gms.location.LocationListener {
            override fun onLocationChanged(location: Location) {
                DashBoardActivity.latitude = location.latitude
                DashBoardActivity.longitude = location.longitude
                if (BuildConfig.DEBUG) {
                    Log.e("LocationChanged:", location.latitude.toString() + " ," + location.longitude)
                }
            }
        })
    } catch (e: SecurityException) {
        e.printStackTrace()
    }
}

private fun startGeofencing() {
    pendingIntent = getGeofencePendingIntent()
    geofencingRequest = GeofencingRequest.Builder()
            .setInitialTrigger(Geofence.GEOFENCE_TRANSITION_ENTER)
            .addGeofences(mGeofenceList)
            .build()

    if (googleApiClient?.isConnected!!) {
        try {
            LocationServices.GeofencingApi.addGeofences(googleApiClient, geofencingRequest, pendingIntent).setResultCallback(object : ResultCallback<Status> {
                override fun onResult(status: Status) {
                }
            })
        } catch (e: SecurityException) {
            e.printStackTrace()
        }
    }
}

private fun populateGeofenceList() {
    for (entry in Constant.AREA_LANDMARKS.entries) { // Replace with your Location List

        mGeofenceList?.add(Geofence.Builder()
                .setRequestId(entry.key)
                .setCircularRegion(entry.value.latitude, entry.value.longitude, Constant.GEOFENCE_RADIUS_IN_METERS)
                .setExpirationDuration(Geofence.NEVER_EXPIRE)
                .setNotificationResponsiveness(1000)
                .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER or Geofence.GEOFENCE_TRANSITION_EXIT)
                .build())
    }
}

private fun getGeofencePendingIntent(): PendingIntent? {
    if (pendingIntent != null) {
        return pendingIntent
    }
    val intent = Intent(this, GeofenceRegistrationService::class.java)
    pendingIntent = PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)
    return pendingIntent
}

override fun onConnected(bundle: Bundle?) {
    startGeofencing()
    startLocationMonitor()
}

override fun onConnectionSuspended(i: Int) {}

override fun onConnectionFailed(connectionResult: ConnectionResult) {}

}

For getting the geofence events, i have used below code:

class GeofenceRegistrationService : IntentService("GeoIntentService") {

val TAG = "GeoIntentService"
var mGeofencList: ArrayList<Geofence>? = null

override fun onHandleIntent(intent: Intent?) {
    mGeofencList = ArrayList()
    val geofencingEvent = GeofencingEvent.fromIntent(intent)
    if (geofencingEvent.hasError()) {
        if (BuildConfig.DEBUG) {
            Log.d(TAG, "Error" + geofencingEvent.errorCode)
        }
    } else {
        try {
            val transaction = geofencingEvent.geofenceTransition
            val geofences = geofencingEvent.triggeringGeofences
            for (i in 0 until geofences.size) {
                mGeofencList?.add(geofences[i])
            }
            if (transaction == Geofence.GEOFENCE_TRANSITION_ENTER) {
                sendBroadCast(true)
                if (BuildConfig.DEBUG) {
                    Log.d(TAG, "You are inside Geofenced area")
                }
            }
            if (transaction == Geofence.GEOFENCE_TRANSITION_EXIT) {
                sendBroadCast(false)
                if (BuildConfig.DEBUG) {
                    Log.d(TAG, "You are outside Geofenced area")
                }
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }

    }
}

private fun sendBroadCast(isInside: Boolean) {
    val broadCastIntent = Intent(Constant.SRI_GEO_FENCE)
    broadCastIntent.putExtra(Constant.KEY_GEOFENCE_STATE, isInside)
    broadCastIntent.putExtra(Constant.KEY_GEOFENCE_LIST, mGeofencList)
    LocalBroadcastManager.getInstance(this).sendBroadcast(broadCastIntent)
}

}

Then you just have to start the LocationService as follows:

 val locationIntent = Intent(activity, LocationService::class.java)
                    activity.startService(locationIntent)

It has been tested and working perfectly. If there is any question, please approach me. Thanks

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!