Removed unused directory

This commit is contained in:
himalia416
2025-10-06 12:41:42 +02:00
committed by Himali Aryal
parent 900eaebdb1
commit 0785dba03d
10 changed files with 0 additions and 370 deletions

View File

@@ -1,11 +0,0 @@
plugins {
alias(libs.plugins.nordic.feature)
}
android {
namespace = "no.nordicsemi.android.permissions_ranging"
}
dependencies {
implementation(libs.accompanist.permissions)
}

View File

@@ -1,21 +0,0 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.RANGING" />
</manifest>

View File

@@ -1,42 +0,0 @@
package no.nordicsemi.android.permissions_ranging
import android.app.Activity
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.ui.platform.LocalContext
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import no.nordicsemi.android.permissions_ranging.utils.RangingNotAvailableReason
import no.nordicsemi.android.permissions_ranging.utils.RangingPermissionState
import no.nordicsemi.android.permissions_ranging.view.RangingPermissionRequestView
import no.nordicsemi.android.permissions_ranging.viewmodel.RangingPermissionViewModel
@Composable
fun RequestRangingPermission(
onChanged: (Boolean) -> Unit = {},
content: @Composable (Boolean) -> Unit,
) {
val permissionViewModel = hiltViewModel<RangingPermissionViewModel>()
val context = LocalContext.current
val activity = context as? Activity
val state by activity?.let { permissionViewModel.requestRangingPermission(it) }!!
.collectAsStateWithLifecycle()
LaunchedEffect(state) {
onChanged(state is RangingPermissionState.Available)
}
when (val s = state) {
is RangingPermissionState.Available -> content(true)
is RangingPermissionState.NotAvailable -> {
when (s.reason) {
RangingNotAvailableReason.NOT_AVAILABLE -> RangingPermissionRequestView(content)
RangingNotAvailableReason.PERMISSION_DENIED -> content(false)
}
}
}
}

View File

@@ -1,89 +0,0 @@
package no.nordicsemi.android.permissions_ranging.repository
import android.app.Activity
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import dagger.hilt.android.qualifiers.ApplicationContext
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.callbackFlow
import no.nordicsemi.android.permissions_ranging.utils.LocalDataProvider
import no.nordicsemi.android.permissions_ranging.utils.RangingNotAvailableReason
import no.nordicsemi.android.permissions_ranging.utils.RangingPermissionState
import no.nordicsemi.android.permissions_ranging.utils.RangingPermissionUtils
import javax.inject.Inject
import javax.inject.Singleton
private const val REFRESH_PERMISSIONS =
"no.nordicsemi.android.permissions_ranging.repository.REFRESH_RANGING_PERMISSIONS"
private const val RANGING_PERMISSION_REQUEST_CODE = 1001
@Singleton
internal class RangingStateManager @Inject constructor(
@param:ApplicationContext private val context: Context,
) {
private val dataProvider = LocalDataProvider(context)
private val utils = RangingPermissionUtils(context, dataProvider)
fun rangingPermissionState(activity: Activity) = callbackFlow {
trySend(getRangingPermissionState())
val rangingStateChangeHandler = object : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
trySend(getRangingPermissionState())
}
}
ContextCompat.registerReceiver(
context,
rangingStateChangeHandler,
IntentFilter(),
ContextCompat.RECEIVER_EXPORTED
)
ActivityCompat.requestPermissions(
activity,
arrayOf("android.permission.RANGING"),
RANGING_PERMISSION_REQUEST_CODE
)
awaitClose {
context.unregisterReceiver(rangingStateChangeHandler)
}
}
fun refreshRangingPermissionState() {
val intent = Intent(REFRESH_PERMISSIONS)
context.sendBroadcast(intent)
}
fun markRangingPermissionAsRequested() {
dataProvider.isRangingPermissionRequested = true
}
fun isRangingPermissionDenied(): Boolean {
return try {
utils.isRangingPermissionDenied()
} catch (_: Exception) {
false
}
}
private fun getRangingPermissionState(): RangingPermissionState {
return when {
!utils.isRangingPermissionAvailable -> RangingPermissionState.NotAvailable(
RangingNotAvailableReason.NOT_AVAILABLE
)
utils.isRangingPermissionAvailable && !utils.isRangingPermissionGranted -> RangingPermissionState.NotAvailable(
RangingNotAvailableReason.PERMISSION_DENIED
)
else -> RangingPermissionState.Available
}
}
}

View File

@@ -1,35 +0,0 @@
package no.nordicsemi.android.permissions_ranging.utils
import android.content.Context
import android.content.SharedPreferences
import android.os.Build
import androidx.annotation.ChecksSdkIntAtLeast
import androidx.core.app.ActivityCompat
import androidx.core.content.edit
import javax.inject.Inject
import javax.inject.Singleton
private const val SHARED_PREFS_NAME = "SHARED_PREFS_RANGING"
private const val PREFS_PERMISSION_REQUESTED = "ranging_permission_requested"
@Singleton
internal class LocalDataProvider @Inject constructor(
private val context: Context,
) {
private val sharedPrefs: SharedPreferences
get() = context.getSharedPreferences(SHARED_PREFS_NAME, Context.MODE_PRIVATE)
val isBaklavaOrAbove: Boolean
@ChecksSdkIntAtLeast(api = Build.VERSION_CODES.BAKLAVA)
get() = Build.VERSION.SDK_INT >= Build.VERSION_CODES.BAKLAVA
/**
* The first time an app requests a permission there is no 'Don't Allow' checkbox and
* [ActivityCompat.shouldShowRequestPermissionRationale] returns false.
*/
var isRangingPermissionRequested: Boolean
get() = sharedPrefs.getBoolean(PREFS_PERMISSION_REQUESTED, false)
set(value) {
sharedPrefs.edit { putBoolean(PREFS_PERMISSION_REQUESTED, value) }
}
}

View File

@@ -1,23 +0,0 @@
package no.nordicsemi.android.permissions_ranging.utils
internal sealed class RangingPermissionState {
/**
* Ranging is available and the app has the required permissions.
*/
data object Available : RangingPermissionState()
/**
* Ranging is not available.
*/
data class NotAvailable(
val reason: RangingNotAvailableReason,
) : RangingPermissionState()
}
internal enum class RangingNotAvailableReason {
/** Ranging is not available on this device. */
NOT_AVAILABLE,
/** The app does not have the required permissions. */
PERMISSION_DENIED,
}

View File

@@ -1,57 +0,0 @@
package no.nordicsemi.android.permissions_ranging.utils
import android.Manifest
import android.app.Activity
import android.content.Context
import android.content.ContextWrapper
import android.content.pm.PackageManager
import android.os.Build
import androidx.annotation.ChecksSdkIntAtLeast
import androidx.core.content.ContextCompat
internal class RangingPermissionUtils(
private val context: Context,
private val dataProvider: LocalDataProvider,
) {
val isRangingPermissionAvailable: Boolean
@ChecksSdkIntAtLeast(api = Build.VERSION_CODES.BAKLAVA)
get() = Build.VERSION.SDK_INT >= 36
val isRangingPermissionGranted: Boolean
get() = isRangingPermissionAvailable &&
ContextCompat.checkSelfPermission(
context,
Manifest.permission.RANGING
) == PackageManager.PERMISSION_GRANTED
fun isRangingPermissionDenied(): Boolean {
return dataProvider.isBaklavaOrAbove &&
dataProvider.isRangingPermissionRequested && // Ranging permission was requested.
!isRangingPermissionGranted // Ranging permission is not granted
&& !context.findActivity()
?.shouldShowRequestPermissionRationale(Manifest.permission.RANGING)!!
}
/**
* Finds the activity from the given context.
*
* https://github.com/google/accompanist/blob/6611ebda55eb2948eca9e1c89c2519e80300855a/permissions/src/main/java/com/google/accompanist/permissions/PermissionsUtil.kt#L99
*
* @throws IllegalStateException if no activity was found.
* @return the activity.
*/
private fun Context.findActivity(): Activity? {
return try {
var context = this
while (context is ContextWrapper) {
if (context is Activity) return context
context = context.baseContext
}
null // no activity found
} catch (e: Exception) {
null
}
}
}

View File

@@ -1,49 +0,0 @@
package no.nordicsemi.android.permissions_ranging.view
import android.Manifest
import android.os.Build
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.hilt.navigation.compose.hiltViewModel
import com.google.accompanist.permissions.ExperimentalPermissionsApi
import com.google.accompanist.permissions.PermissionStatus
import com.google.accompanist.permissions.isGranted
import com.google.accompanist.permissions.rememberPermissionState
import no.nordicsemi.android.permissions_ranging.viewmodel.RangingPermissionViewModel
@OptIn(ExperimentalPermissionsApi::class)
@Composable
internal fun RangingPermissionRequestView(
content: @Composable (Boolean) -> Unit,
) {
val rangingPermissionViewModel = hiltViewModel<RangingPermissionViewModel>()
val permission = if (Build.VERSION.SDK_INT >= 36)
Manifest.permission.RANGING else null
val rangingPermission = permission?.let {
rememberPermissionState(it)
}
if (rangingPermission != null) {
when (rangingPermission.status) {
is PermissionStatus.Denied -> {
LaunchedEffect(!rangingPermission.status.isGranted) {
rangingPermissionViewModel.markRangingPermissionRequested()
rangingPermission.launchPermissionRequest()
if (!rangingPermission.status.isGranted) {
rangingPermissionViewModel.markRangingPermissionDenied()
}
rangingPermissionViewModel.refreshRangingPermissionState()
}
content(rangingPermission.status.isGranted)
}
PermissionStatus.Granted -> content(true)
}
} else {
rangingPermissionViewModel.refreshRangingPermissionState()
content(true)
}
}

View File

@@ -1,37 +0,0 @@
package no.nordicsemi.android.permissions_ranging.viewmodel
import android.app.Activity
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.stateIn
import no.nordicsemi.android.permissions_ranging.repository.RangingStateManager
import no.nordicsemi.android.permissions_ranging.utils.RangingNotAvailableReason
import no.nordicsemi.android.permissions_ranging.utils.RangingPermissionState
import javax.inject.Inject
@HiltViewModel
internal class RangingPermissionViewModel @Inject constructor(
private val rangingStateManager: RangingStateManager,
) : ViewModel() {
fun requestRangingPermission(activity: Activity) =
rangingStateManager.rangingPermissionState(activity)
.stateIn(
viewModelScope,
SharingStarted.Lazily,
RangingPermissionState.NotAvailable(RangingNotAvailableReason.NOT_AVAILABLE),
)
fun refreshRangingPermissionState() {
rangingStateManager.refreshRangingPermissionState()
}
fun markRangingPermissionRequested() {
rangingStateManager.markRangingPermissionAsRequested()
}
fun markRangingPermissionDenied() {
rangingStateManager.isRangingPermissionDenied()
}
}