I have made a class to handle almost all this in Kotlin using Coroutines

class ActivityResultHandler(

private val registry: ActivityResultRegistry

) {

private val handlers = mutableListOf>()

fun unregisterHandlers() {

handlers.forEach {

it.unregister()

}

}

suspend fun requestLocationPermission(): Boolean {

return suspendCoroutine { continuation ->

val launcher = registry.register(

LOCATION_PERMISSION_REQUEST,

// lifecycleOwner,

ActivityResultContracts.RequestPermission()

) {

continuation.resumeWith(Result.success(it))

}

handlers.add(launcher)

launcher.launch(Manifest.permission.ACCESS_FINE_LOCATION)

}

}

suspend fun requestBluetoothActivation(): Boolean {

return suspendCoroutine { continuation ->

val enableBtIntent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)

val launcher = registry.register(

BLUETOOTH_ON_REQUEST,

// lifecycleOwner,

ActivityResultContracts.StartActivityForResult()

) { result ->

continuation.resume(

result.resultCode == Activity.RESULT_OK

)

}

handlers.add(launcher)

launcher.launch(enableBtIntent)

}

}

fun checkLocationPermission(context: Context): Boolean {

return ContextCompat.checkSelfPermission(

context,

Manifest.permission.ACCESS_FINE_LOCATION

) == PackageManager.PERMISSION_GRANTED

}

private suspend fun requestLocationActivation(

intentSenderRequest: IntentSenderRequest,

): Boolean {

return suspendCoroutine { continuation ->

val launcher = registry.register(

LOCATION_ACTIVATION_REQUEST,

// lifecycleOwner,

ActivityResultContracts.StartIntentSenderForResult()

) {

continuation.resume(it.resultCode == Activity.RESULT_OK)

}

handlers.add(launcher)

launcher.launch(intentSenderRequest)

}

}

suspend fun enableLocation(context: Context): Boolean =

suspendCoroutine { continuation ->

val locationSettingsRequest = LocationSettingsRequest.Builder()

// .setNeedBle(true)

.addLocationRequest(

LocationRequest.create().apply {

priority = LocationRequest.PRIORITY_HIGH_ACCURACY

}

)

.build()

val client: SettingsClient = LocationServices.getSettingsClient(context)

val task: Task =

client.checkLocationSettings(locationSettingsRequest)

task.addOnSuccessListener {

continuation.resume(true)

}

task.addOnFailureListener { exception ->

if (exception is ResolvableApiException &&

exception.statusCode == LocationSettingsStatusCodes.RESOLUTION_REQUIRED

) {

val intentSenderRequest =

IntentSenderRequest.Builder(exception.resolution).build()

CoroutineScope(continuation.context).launch {

val result = requestLocationActivation(intentSenderRequest)

continuation.resume(result)

}

} else {

continuation.resume(false)

}

}

}

companion object {

private const val LOCATION_PERMISSION_REQUEST = "LOCATION_REQUEST"

private const val BLUETOOTH_ON_REQUEST = "LOCATION_REQUEST"

private const val LOCATION_ACTIVATION_REQUEST = "LOCATION_REQUEST"

}

}

Use it like this:

// make sure you extend AppCompatActivity

class MainActivity : AppCompatActivity() {

private val permissionRequests = ActivityResultHandler(activityResultRegistry)

override fun onCreate(savedInstanceState: Bundle?) {

super.onCreate(savedInstanceState)

setContentView(R.layout.activity_main)

// use viewmodels and fragments instead of GlobalScope

GlobalScope.launch {

// turn on bluetooth

permissionRequests.requestBluetoothActivation()

// to be able to scan for devices you also need location permission

// also show pop up to let users know why you need location

// https://support.google.com/googleplay/android-developer/answer/9799150?hl=en

permissionRequests.requestLocationPermission()

// also you need navigation to be enabled

permissionRequests.enableLocation(this@MainActivity)

}

}

override fun onDestroy() {

super.onDestroy()

permissionRequests.unregisterHandlers()

}

}

coroutines dependency in gradle

implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.2'

also add this permissions to manifest

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐