Created
September 7, 2020 12:36
-
-
Save yusufceylan/c93eb95a2f7f3bbef638bf5658d2a332 to your computer and use it in GitHub Desktop.
Huawei Location Manager Wrapper
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Wrapper class for handling Location related methods | |
*/ | |
class HuaweiLocationManager constructor(private val context : Context) { | |
//region vars | |
private val mFusedLocationProviderClient: FusedLocationProviderClient by lazy { | |
LocationServices.getFusedLocationProviderClient(context) | |
} | |
private val mSettingsClient: SettingsClient by lazy { | |
LocationServices.getSettingsClient(context) | |
} | |
private var mLocationCallback: LocationCallback? = null | |
//endregion | |
companion object { | |
const val REQUEST_CHECK_SETTINGS = 123 | |
const val REQUEST_ENABLE_GPS = 456 | |
} | |
/** | |
* Create location setting task with Success Callback | |
*/ | |
private fun getLocationSettingsTask( | |
onSuccess: ((locationSettingsResponse: LocationSettingsResponse?) -> Unit)? = null | |
): Task<LocationSettingsResponse>? { | |
val builder = LocationSettingsRequest.Builder() | |
val locationRequest = LocationRequest() | |
builder.addLocationRequest(locationRequest) | |
val locationSettingsRequest = builder.build() | |
// Check the device location settings. | |
return mSettingsClient.checkLocationSettings(locationSettingsRequest) | |
.addOnSuccessListener { | |
// Initiate location requests when the location settings meet the requirements. | |
LogUtils.d("LocationManager -> Device location is open") | |
// Notify | |
onSuccess?.invoke(it) | |
} | |
} | |
/** | |
* Check Location settings is enable or not | |
* Manually handle success and fail situations | |
*/ | |
fun checkLocationSettings( | |
onSuccess: ((locationSettingsResponse: LocationSettingsResponse?) -> Unit)? = null, | |
onFail: ((exception: Exception) -> Unit)? = null | |
) { | |
// Check the device location settings. | |
getLocationSettingsTask(onSuccess)?.addOnFailureListener { e -> | |
// Device location settings do not meet the requirements. | |
val statusCode = (e as ApiException).statusCode | |
LogUtils.d("LocationManager -> Device location is close with status code $statusCode exception: ${e.localizedMessage}") | |
// Notify | |
onFail?.invoke(e) | |
} | |
} | |
/** | |
* Check Location settings is enable or not | |
* If location disable, automatically show system dialog for enable location | |
* | |
* Handle on Activity Result | |
* | |
* if (requestCode == REQUEST_CHECK_SETTINGS) { | |
* when (resultCode) { | |
* Activity.RESULT_OK -> { | |
* LogUtils.d("User confirm to access location") | |
* } | |
* Activity.RESULT_CANCELED -> { | |
* LogUtils.d("User denied to access location") | |
* } | |
* } | |
* } | |
*/ | |
fun checkLocationSettingsAndShowPopup( | |
activity: Activity, | |
onSuccess: ((locationSettingsResponse: LocationSettingsResponse?) -> Unit)? = null | |
) { | |
getLocationSettingsTask(onSuccess)?.addOnFailureListener { e -> | |
// Device location settings do not meet the requirements. | |
val statusCode = (e as ApiException).statusCode | |
LogUtils.d("LocationManager -> Device location is close with status code $statusCode, User will get system dialog for enable location") | |
when (statusCode) { | |
LocationSettingsStatusCodes.RESOLUTION_REQUIRED -> try { | |
val rae = e as ResolvableApiException | |
// Call startResolutionForResult to display a pop-up asking the user to enable related permission. | |
// rae.startResolutionForResult(activity, REQUEST_CHECK_SETTINGS) // -> Only call Activity's onActivityResult | |
activity.startIntentSenderForResult( | |
rae.resolution.intentSender, | |
REQUEST_CHECK_SETTINGS, null, 0, 0, 0, null | |
) // -> Call also Fragment's onActivityResult | |
} catch (sie: IntentSender.SendIntentException) { | |
LogUtils.d("LocationKit -> Error while showing system pop-up with error message:" + sie.message) | |
} | |
} | |
} | |
} | |
/** | |
* Check Location settings is enable or not | |
* If location disable, automatically show system dialog for enable location | |
* | |
* Handle on Activity Result | |
* | |
* if (requestCode == REQUEST_CHECK_SETTINGS) { | |
* when (resultCode) { | |
* Activity.RESULT_OK -> { | |
* LogUtils.d("User confirm to access location") | |
* } | |
* Activity.RESULT_CANCELED -> { | |
* LogUtils.d("User denied to access location") | |
* } | |
* } | |
* } | |
*/ | |
fun checkLocationSettingsAndShowPopup( | |
fragment: Fragment, | |
onSuccess: ((locationSettingsResponse: LocationSettingsResponse?) -> Unit)? = null | |
) { | |
getLocationSettingsTask(onSuccess)?.addOnFailureListener { e -> | |
// Device location settings do not meet the requirements. | |
val statusCode = (e as ApiException).statusCode | |
LogUtils.d("LocationManager -> Device location is close with status code $statusCode, User will get system dialog for enable location") | |
when (statusCode) { | |
LocationSettingsStatusCodes.RESOLUTION_REQUIRED -> try { | |
val rae = e as ResolvableApiException | |
// Call startResolutionForResult to display a pop-up asking the user to enable related permission. | |
// rae.startResolutionForResult(activity, REQUEST_CHECK_SETTINGS) // -> Only call Activity's onActivityResult | |
fragment.startIntentSenderForResult( | |
rae.resolution.intentSender, | |
REQUEST_CHECK_SETTINGS, null, 0, 0, 0, null | |
) // -> Call also Fragment's onActivityResult | |
} catch (sie: IntentSender.SendIntentException) { | |
LogUtils.d("LocationKit -> Error while showing system pop-up with error message:" + sie.message) | |
} | |
} | |
} | |
} | |
/** | |
* Open Location settings page | |
* | |
* User manually handle result in onActivityResult | |
* | |
* (requestCode == REQUEST_ENABLE_GPS) { | |
* val locationManager = getSystemService(LOCATION_SERVICE) as LocationManager | |
* val isGpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) | |
* if (!isGpsEnabled) { | |
* LogUtils.d("User closed to settings page") | |
* } else { | |
* LogUtils.d("User open location from settings page") | |
* } | |
* } | |
*/ | |
fun openGpsEnableSetting(activity: Activity) { | |
val intent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS) | |
activity.startActivityForResult(intent, REQUEST_ENABLE_GPS) | |
} | |
/** | |
* Open Location settings page | |
* | |
* User manually handle result in onActivityResult | |
* | |
* (requestCode == REQUEST_ENABLE_GPS) { | |
* val locationManager = getSystemService(LOCATION_SERVICE) as LocationManager | |
* val isGpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) | |
* if (!isGpsEnabled) { | |
* LogUtils.d("User closed to settings page") | |
* } else { | |
* LogUtils.d("User open location from settings page") | |
* } | |
* } | |
*/ | |
fun openGpsEnableSetting(fragment: Fragment) { | |
val intent = Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS) | |
fragment.startActivityForResult(intent, REQUEST_ENABLE_GPS) | |
} | |
/** | |
* Obtaining Location Availability from Huawei Location Services | |
*/ | |
fun getLocationAvailability( | |
onSuccess: ((locationAvailability: LocationAvailability?) -> Unit)? = null, | |
onFail: ((exception: Exception) -> Unit)? = null | |
) { | |
val locationAvailabilityTask: Task<LocationAvailability> = mFusedLocationProviderClient.locationAvailability | |
locationAvailabilityTask.addOnSuccessListener { locationAvailability -> | |
if (locationAvailability != null) { | |
LogUtils.d("Location Kit -> getLocationAvailability onSuccess:${locationAvailability.isLocationAvailable}") | |
} | |
// Notify | |
onSuccess?.invoke(locationAvailability) | |
} | |
.addOnFailureListener { e -> | |
LogUtils.d("getLocationAvailability onFailure:" + e.message) | |
// Notify | |
onFail?.invoke(e) | |
} | |
} | |
/** | |
* Check location service hard wares are available | |
*/ | |
fun checkLocationServiceAvailability(): Boolean? { | |
val lm = context.getSystemService(AppCompatActivity.LOCATION_SERVICE) as LocationManager | |
var isGpsEnable = false | |
var isNetworkEnable = false | |
try { | |
isGpsEnable = lm.isProviderEnabled(LocationManager.GPS_PROVIDER) | |
} catch (ex: Exception) { | |
} | |
try { | |
isNetworkEnable = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER) | |
} catch (ex: Exception) { | |
} | |
if (!isGpsEnable && !isNetworkEnable) { | |
LogUtils.d("Location Kit -> checkLocationServiceAvailability: False") | |
return false | |
} | |
LogUtils.d("Location Kit -> checkLocationServiceAvailability: True") | |
return true | |
} | |
/** | |
* Get Last Know Location | |
*/ | |
fun getLastKnownLocation( | |
onSuccess: ((lastKnownLocation: Location?) -> Unit)? = null, | |
onFail: ((exception: Exception) -> Unit)? = null | |
) { | |
val task: Task<Location> = mFusedLocationProviderClient.lastLocation | |
task.addOnSuccessListener { lastKnowLocation -> | |
if (lastKnowLocation == null) { | |
LogUtils.d("LocationKit -> Last Known Location is empty") | |
} else { | |
val currentLatLng = LatLng( | |
lastKnowLocation.latitude, | |
lastKnowLocation.longitude | |
) | |
LogUtils.d("LocationKit -> Last Known Location: $currentLatLng") | |
} | |
// Notify | |
onSuccess?.invoke(lastKnowLocation) | |
}.addOnFailureListener { exception -> | |
LogUtils.d("LocationKit -> Failed to get Last Known Location with exception: ${exception.localizedMessage}") | |
// Notify | |
onFail?.invoke(exception) | |
} | |
} | |
/** | |
* Start listening location updates | |
*/ | |
fun registerLocationUpdates( | |
interval: Long = 10000, | |
onSuccess: ((location: Location?) -> Unit)? = null, | |
onFail: ((locationAvailability: LocationAvailability?) -> Unit)? = null | |
) { | |
val mLocationRequest = LocationRequest() | |
// Set the location update interval (in milliseconds). | |
mLocationRequest.interval = interval | |
// Set the weight. | |
mLocationRequest.priority = LocationRequest.PRIORITY_HIGH_ACCURACY | |
// Create location callback | |
if (mLocationCallback == null) | |
mLocationCallback = createLocationCallback(onSuccess, onFail) | |
// Request location update | |
mFusedLocationProviderClient.requestLocationUpdates( | |
mLocationRequest, | |
mLocationCallback, | |
Looper.getMainLooper() | |
) | |
.addOnSuccessListener { | |
// Requesting location updates is started successfully. | |
LogUtils.d("LocationKit -> Start Location Updates Successfully") | |
} | |
.addOnFailureListener { exception -> | |
// Failed to start location updates. | |
LogUtils.d("LocationKit -> Start Location Updates Failed with exception: ${exception.localizedMessage}") | |
} | |
} | |
/** | |
* Stop listening location updates | |
*/ | |
fun unregisterLocationUpdates() { | |
mLocationCallback?.let { locationCallback -> | |
mFusedLocationProviderClient.removeLocationUpdates(locationCallback) | |
.addOnSuccessListener { | |
// Requesting location updates is stopped successfully. | |
LogUtils.d("LocationKit -> Stop Listening Location Successfully") | |
} | |
.addOnFailureListener { | |
// Failed to stop requesting location updates. | |
LogUtils.d("LocationKit -> Stop Listening Location Failed with exception: ${it.localizedMessage}") | |
} | |
} | |
} | |
/** | |
* Create Location Callback | |
*/ | |
private fun createLocationCallback( | |
onSuccess: ((location: Location?) -> Unit)? = null, | |
onFail: ((locationAvailability: LocationAvailability?) -> Unit)? = null | |
): LocationCallback { | |
return object : LocationCallback() { | |
override fun onLocationResult(locationResult: LocationResult) { | |
val currentLatLng = LatLng( | |
locationResult.lastLocation.latitude, | |
locationResult.lastLocation.longitude | |
) | |
LogUtils.d("LocationKit -> currentLatLng: $currentLatLng") | |
// Notify | |
onSuccess?.invoke(locationResult.lastLocation) | |
} | |
override fun onLocationAvailability(locationAvailability: LocationAvailability) { | |
val flag = locationAvailability.isLocationAvailable | |
LogUtils.i("LocationKit isLocationAvailable:$flag") | |
// Notify | |
onFail?.invoke(locationAvailability) | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment