From eccc7b8bcb606655bdff71f29e7da4904d52664e Mon Sep 17 00:00:00 2001 From: Dave Antoine Date: Sat, 24 May 2025 18:22:36 -0400 Subject: [PATCH 1/6] WearableManager: improve handling for remote action callback --- .../simplewear/wearable/WearableManager.kt | 105 +++++++++--------- 1 file changed, 53 insertions(+), 52 deletions(-) diff --git a/mobile/src/main/java/com/thewizrd/simplewear/wearable/WearableManager.kt b/mobile/src/main/java/com/thewizrd/simplewear/wearable/WearableManager.kt index fb6b6bf..cb4bd80 100644 --- a/mobile/src/main/java/com/thewizrd/simplewear/wearable/WearableManager.kt +++ b/mobile/src/main/java/com/thewizrd/simplewear/wearable/WearableManager.kt @@ -83,16 +83,18 @@ import kotlinx.coroutines.cancel import kotlinx.coroutines.delay import kotlinx.coroutines.isActive import kotlinx.coroutines.launch +import kotlinx.coroutines.suspendCancellableCoroutine import kotlinx.coroutines.tasks.await import kotlinx.coroutines.withContext import java.io.BufferedWriter import java.io.OutputStreamWriter import java.nio.ByteBuffer import java.util.Collections +import kotlin.coroutines.cancellation.CancellationException +import kotlin.coroutines.resume @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) -class WearableManager(private val mContext: Context) : OnCapabilityChangedListener, - RemoteActionReceiver.IResultReceiver { +class WearableManager(private val mContext: Context) : OnCapabilityChangedListener { init { init() } @@ -102,22 +104,16 @@ class WearableManager(private val mContext: Context) : OnCapabilityChangedListen private lateinit var mCapabilityClient: CapabilityClient private var mWearNodesWithApp: Collection? = null - private lateinit var mResultReceiver: RemoteActionReceiver private var mPackageValidator = PackageValidator(mContext) private fun init() { mCapabilityClient = Wearable.getCapabilityClient(mContext) mCapabilityClient.addListener(this, WearableHelper.CAPABILITY_WEAR_APP) - - mResultReceiver = RemoteActionReceiver().apply { - resultReceiver = this@WearableManager - } } fun unregister() { scope.cancel() mCapabilityClient.removeListener(this) - mResultReceiver.resultReceiver = null } suspend fun isWearNodesAvailable(): Boolean { @@ -1102,26 +1098,58 @@ class WearableManager(private val mContext: Context) : OnCapabilityChangedListen } } - private fun performRemoteAction(action: Action): ActionStatus { + private suspend fun performRemoteAction(action: Action): ActionStatus { return try { - if (mPackageValidator.isKnownCaller(WearSettingsHelper.getPackageName())) { - mContext.startService( - Intent(ACTION_PERFORMACTION).apply { - component = WearSettingsHelper.getSettingsServiceComponent() - putExtra( - EXTRA_ACTION_DATA, - action.toRemoteAction(mResultReceiver) - ) - putExtra( - EXTRA_ACTION_CALLINGPKG, - mContext.packageName - ) + suspendCancellableCoroutine { continuation -> + val remoteActionReceiver = RemoteActionReceiver().apply { + resultReceiver = object : RemoteActionReceiver.IResultReceiver { + override fun onReceiveResult(resultCode: Int, resultData: Bundle) { + if (resultCode == Activity.RESULT_OK) { + if (continuation.isActive) { + continuation.resume(ActionStatus.SUCCESS) + } + } else { + var resultStatus = ActionStatus.REMOTE_FAILURE + + if (resultData.containsKey(EXTRA_ACTION_ERROR)) { + Logger.writeLine( + Log.ERROR, + "Error executing remote action; Error: %s", + resultData.getString(EXTRA_ACTION_ERROR) + ) + } else if (resultData.containsKey(EXTRA_ACTION_DATA)) { + val actionData = resultData.getString(EXTRA_ACTION_DATA) + val resultAction = + JSONParser.deserializer(actionData, Action::class.java) + resultStatus = resultAction?.actionStatus ?: resultStatus + } + + if (continuation.isActive) { + continuation.resume(resultStatus) + } + } + } } - ) - ActionStatus.UNKNOWN - } else { - throw IllegalStateException("Package: ${WearSettingsHelper.getPackageName()} has invalid certificate") + } + + continuation.invokeOnCancellation { + remoteActionReceiver.resultReceiver = null + } + + if (mPackageValidator.isKnownCaller(WearSettingsHelper.getPackageName())) { + mContext.startService( + Intent(ACTION_PERFORMACTION).apply { + component = WearSettingsHelper.getSettingsServiceComponent() + putExtra(EXTRA_ACTION_DATA, action.toRemoteAction(remoteActionReceiver)) + putExtra(EXTRA_ACTION_CALLINGPKG, mContext.packageName) + } + ) + } else { + throw IllegalStateException("Package: ${WearSettingsHelper.getPackageName()} has invalid certificate") + } } + } catch (ce: CancellationException) { + ActionStatus.UNKNOWN } catch (ise: IllegalStateException) { // Likely background service restriction Logger.writeLine(Log.ERROR, ise) @@ -1131,31 +1159,4 @@ class WearableManager(private val mContext: Context) : OnCapabilityChangedListen ActionStatus.REMOTE_FAILURE } } - - override fun onReceiveResult(resultCode: Int, resultData: Bundle) { - if (resultData.containsKey(EXTRA_ACTION_ERROR)) { - Logger.writeLine( - Log.ERROR, - "Error executing remote action; Error: %s", - resultData.getString(EXTRA_ACTION_ERROR) - ) - } - if (resultCode == Activity.RESULT_CANCELED && resultData.containsKey(EXTRA_ACTION_DATA)) { - // Check for remote failure - val actionData = resultData.getString(EXTRA_ACTION_DATA) - val action = JSONParser.deserializer(actionData, Action::class.java) - if (action?.actionStatus == ActionStatus.REMOTE_FAILURE || - action?.actionStatus == ActionStatus.REMOTE_PERMISSION_DENIED - ) { - scope.launch { - sendMessage( - null, - WearableHelper.ActionsPath, - actionData?.stringToBytes() - ) - WearSettingsHelper.launchWearSettings() - } - } - } - } } \ No newline at end of file From a033f21624d116f72072a13be033dcd21eb46649 Mon Sep 17 00:00:00 2001 From: Dave Antoine Date: Sat, 24 May 2025 18:23:24 -0400 Subject: [PATCH 2/6] wear: increase action timeout to 5s --- .../com/thewizrd/simplewear/viewmodels/DashboardViewModel.kt | 2 +- .../com/thewizrd/simplewear/viewmodels/ValueActionViewModel.kt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/wear/src/main/java/com/thewizrd/simplewear/viewmodels/DashboardViewModel.kt b/wear/src/main/java/com/thewizrd/simplewear/viewmodels/DashboardViewModel.kt index 61b8712..4d13e0d 100644 --- a/wear/src/main/java/com/thewizrd/simplewear/viewmodels/DashboardViewModel.kt +++ b/wear/src/main/java/com/thewizrd/simplewear/viewmodels/DashboardViewModel.kt @@ -130,7 +130,7 @@ class DashboardViewModel(app: Application) : WearableListenerViewModel(app) { requestAction(jsonData) - val timer: CountDownTimer = object : CountDownTimer(3000, 500) { + val timer: CountDownTimer = object : CountDownTimer(5000, 500) { override fun onTick(millisUntilFinished: Long) {} override fun onFinish() { diff --git a/wear/src/main/java/com/thewizrd/simplewear/viewmodels/ValueActionViewModel.kt b/wear/src/main/java/com/thewizrd/simplewear/viewmodels/ValueActionViewModel.kt index 364a4d3..8e4bfa3 100644 --- a/wear/src/main/java/com/thewizrd/simplewear/viewmodels/ValueActionViewModel.kt +++ b/wear/src/main/java/com/thewizrd/simplewear/viewmodels/ValueActionViewModel.kt @@ -77,7 +77,7 @@ class ValueActionViewModel(app: Application) : WearableListenerViewModel(app) { viewModelScope.launch { timer?.cancel() - timer = object : CountDownTimer(3000, 500) { + timer = object : CountDownTimer(5000, 500) { override fun onTick(millisUntilFinished: Long) {} override fun onFinish() { From 8b05493071972702c9549b018973facce2bd8a45 Mon Sep 17 00:00:00 2001 From: Dave Antoine Date: Sat, 24 May 2025 18:36:31 -0400 Subject: [PATCH 3/6] wearsettings: fix check for Shizuku state --- .../java/com/thewizrd/wearsettings/actions/LocationAction.kt | 5 ++--- .../com/thewizrd/wearsettings/actions/LockScreenAction.kt | 4 ++-- .../com/thewizrd/wearsettings/actions/MobileDataAction.kt | 4 ++-- .../java/com/thewizrd/wearsettings/actions/WifiAction.kt | 4 ++-- .../com/thewizrd/wearsettings/actions/WifiHotspotAction.kt | 4 ++-- .../java/com/thewizrd/wearsettings/shizuku/ShizukuUtils.kt | 2 ++ 6 files changed, 12 insertions(+), 11 deletions(-) diff --git a/wearsettings/src/main/java/com/thewizrd/wearsettings/actions/LocationAction.kt b/wearsettings/src/main/java/com/thewizrd/wearsettings/actions/LocationAction.kt index 9e2eb75..7d8bdb0 100644 --- a/wearsettings/src/main/java/com/thewizrd/wearsettings/actions/LocationAction.kt +++ b/wearsettings/src/main/java/com/thewizrd/wearsettings/actions/LocationAction.kt @@ -17,7 +17,6 @@ import com.thewizrd.shared_resources.utils.Logger import com.thewizrd.wearsettings.root.RootHelper import com.thewizrd.wearsettings.shizuku.ShizukuUtils import com.thewizrd.wearsettings.shizuku.grantSecureSettingsPermission -import rikka.shizuku.Shizuku import rikka.shizuku.ShizukuBinderWrapper import rikka.shizuku.SystemServiceHelper import com.thewizrd.wearsettings.Settings as SettingsHelper @@ -29,7 +28,7 @@ object LocationAction { return if (checkSecureSettingsPermission(context)) { setLocationState(context, state) - } else if (Shizuku.pingBinder()) { + } else if (ShizukuUtils.isRunning(context)) { context.grantSecureSettingsPermission() setLocationState(context, state) } else if (SettingsHelper.isRootAccessEnabled() && RootHelper.isRootEnabled()) { @@ -38,7 +37,7 @@ object LocationAction { ActionStatus.REMOTE_PERMISSION_DENIED } } else if (action is ToggleAction) { - return if (Shizuku.pingBinder()) { + return if (ShizukuUtils.isRunning(context)) { setLocationEnabledShizuku(context, action.isEnabled) } else if (checkSecureSettingsPermission(context)) { setLocationEnabled(context, action.isEnabled) diff --git a/wearsettings/src/main/java/com/thewizrd/wearsettings/actions/LockScreenAction.kt b/wearsettings/src/main/java/com/thewizrd/wearsettings/actions/LockScreenAction.kt index f2f5c0d..c9d3254 100644 --- a/wearsettings/src/main/java/com/thewizrd/wearsettings/actions/LockScreenAction.kt +++ b/wearsettings/src/main/java/com/thewizrd/wearsettings/actions/LockScreenAction.kt @@ -11,8 +11,8 @@ import com.thewizrd.shared_resources.actions.ActionStatus import com.thewizrd.shared_resources.actions.NormalAction import com.thewizrd.shared_resources.utils.Logger import com.thewizrd.wearsettings.root.RootHelper +import com.thewizrd.wearsettings.shizuku.ShizukuUtils import com.topjohnwu.superuser.Shell -import rikka.shizuku.Shizuku import rikka.shizuku.ShizukuBinderWrapper import rikka.shizuku.SystemServiceHelper import com.thewizrd.wearsettings.Settings as SettingsHelper @@ -20,7 +20,7 @@ import com.thewizrd.wearsettings.Settings as SettingsHelper object LockScreenAction { fun executeAction(context: Context, action: Action): ActionStatus { if (action is NormalAction) { - return if (Shizuku.pingBinder()) { + return if (ShizukuUtils.isRunning(context)) { lockScreenShizuku(context) } else if (SettingsHelper.isRootAccessEnabled() && RootHelper.isRootEnabled()) { lockScreenRoot() diff --git a/wearsettings/src/main/java/com/thewizrd/wearsettings/actions/MobileDataAction.kt b/wearsettings/src/main/java/com/thewizrd/wearsettings/actions/MobileDataAction.kt index 52ae7c4..1b526c0 100644 --- a/wearsettings/src/main/java/com/thewizrd/wearsettings/actions/MobileDataAction.kt +++ b/wearsettings/src/main/java/com/thewizrd/wearsettings/actions/MobileDataAction.kt @@ -11,8 +11,8 @@ import com.thewizrd.shared_resources.actions.ActionStatus import com.thewizrd.shared_resources.actions.ToggleAction import com.thewizrd.shared_resources.utils.Logger import com.thewizrd.wearsettings.root.RootHelper +import com.thewizrd.wearsettings.shizuku.ShizukuUtils import com.topjohnwu.superuser.Shell -import rikka.shizuku.Shizuku import rikka.shizuku.ShizukuBinderWrapper import rikka.shizuku.SystemServiceHelper import com.thewizrd.wearsettings.Settings as SettingsHelper @@ -20,7 +20,7 @@ import com.thewizrd.wearsettings.Settings as SettingsHelper object MobileDataAction { fun executeAction(context: Context, action: Action): ActionStatus { if (action is ToggleAction) { - return if (Shizuku.pingBinder()) { + return if (ShizukuUtils.isRunning(context)) { setMobileDataEnabledShizuku(context, action.isEnabled) } else if (SettingsHelper.isRootAccessEnabled() && RootHelper.isRootEnabled()) { setMobileDataEnabledRoot(action.isEnabled) diff --git a/wearsettings/src/main/java/com/thewizrd/wearsettings/actions/WifiAction.kt b/wearsettings/src/main/java/com/thewizrd/wearsettings/actions/WifiAction.kt index e77984c..d3177c2 100644 --- a/wearsettings/src/main/java/com/thewizrd/wearsettings/actions/WifiAction.kt +++ b/wearsettings/src/main/java/com/thewizrd/wearsettings/actions/WifiAction.kt @@ -14,8 +14,8 @@ import com.thewizrd.shared_resources.actions.ToggleAction import com.thewizrd.shared_resources.utils.Logger import com.thewizrd.wearsettings.Settings import com.thewizrd.wearsettings.root.RootHelper +import com.thewizrd.wearsettings.shizuku.ShizukuUtils import com.topjohnwu.superuser.Shell -import rikka.shizuku.Shizuku import rikka.shizuku.ShizukuBinderWrapper import rikka.shizuku.SystemServiceHelper @@ -26,7 +26,7 @@ object WifiAction { return if (status != ActionStatus.SUCCESS) { // Note: could have failed due to Airplane mode restriction // Try with root - if (Shizuku.pingBinder()) { + if (ShizukuUtils.isRunning(context)) { setWifiEnabledShizuku(context, action.isEnabled) } else if (Settings.isRootAccessEnabled() && RootHelper.isRootEnabled()) { setWifiEnabledRoot(action.isEnabled) diff --git a/wearsettings/src/main/java/com/thewizrd/wearsettings/actions/WifiHotspotAction.kt b/wearsettings/src/main/java/com/thewizrd/wearsettings/actions/WifiHotspotAction.kt index 0cd83b0..3a56ac1 100644 --- a/wearsettings/src/main/java/com/thewizrd/wearsettings/actions/WifiHotspotAction.kt +++ b/wearsettings/src/main/java/com/thewizrd/wearsettings/actions/WifiHotspotAction.kt @@ -16,7 +16,7 @@ import com.thewizrd.shared_resources.actions.Action import com.thewizrd.shared_resources.actions.ActionStatus import com.thewizrd.shared_resources.actions.ToggleAction import com.thewizrd.shared_resources.utils.Logger -import rikka.shizuku.Shizuku +import com.thewizrd.wearsettings.shizuku.ShizukuUtils import rikka.shizuku.ShizukuBinderWrapper import rikka.shizuku.SystemServiceHelper @@ -26,7 +26,7 @@ object WifiHotspotAction { fun executeAction(context: Context, action: Action): ActionStatus { if (action is ToggleAction) { - return if (Shizuku.pingBinder()) { + return if (ShizukuUtils.isRunning(context)) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { setHotspotEnabledShizuku(action.isEnabled) } else { diff --git a/wearsettings/src/main/java/com/thewizrd/wearsettings/shizuku/ShizukuUtils.kt b/wearsettings/src/main/java/com/thewizrd/wearsettings/shizuku/ShizukuUtils.kt index 331fef8..1f093a0 100644 --- a/wearsettings/src/main/java/com/thewizrd/wearsettings/shizuku/ShizukuUtils.kt +++ b/wearsettings/src/main/java/com/thewizrd/wearsettings/shizuku/ShizukuUtils.kt @@ -104,6 +104,8 @@ object ShizukuUtils { } } + fun isRunning(context: Context): Boolean = getShizukuState(context) == ShizukuState.RUNNING + private fun getPlayStoreURI(): Uri { return Uri.parse(PLAY_STORE_APP_URI) } From 312b035381666e5d036603310f025d3b23805566 Mon Sep 17 00:00:00 2001 From: Dave Antoine Date: Sat, 24 May 2025 19:33:12 -0400 Subject: [PATCH 4/6] gradle: update dependencies --- build.gradle | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/build.gradle b/build.gradle index 143cfc4..6a141a3 100644 --- a/build.gradle +++ b/build.gradle @@ -11,20 +11,20 @@ buildscript { desugar_version = '2.1.5' - firebase_version = '33.12.0' + firebase_version = '33.13.0' activity_version = '1.10.1' appcompat_version = '1.7.0' constraintlayout_version = '2.2.1' core_version = '1.16.0' fragment_version = '1.8.6' - lifecycle_version = '2.8.7' + lifecycle_version = '2.9.0' preference_version = '1.2.1' recyclerview_version = '1.4.0' coresplash_version = '1.0.1' - work_version = '2.10.0' - navigation_version = '2.8.9' - datastore_version = '1.1.4' + work_version = '2.10.1' + navigation_version = '2.9.0' + datastore_version = '1.1.7' test_core_version = '1.6.1' test_runner_version = '1.6.2' @@ -35,15 +35,15 @@ buildscript { material_version = '1.12.0' - compose_bom_version = '2025.04.00' + compose_bom_version = '2025.05.00' compose_compiler_version = '1.5.15' wear_compose_version = '1.4.1' wear_tiles_version = '1.4.1' wear_watchface_version = '1.2.1' horologist_version = '0.6.23' - accompanist_version = '0.37.2' + accompanist_version = '0.37.3' - gson_version = '2.13.0' + gson_version = '2.13.1' timber_version = '5.0.1' // Shizuku @@ -57,7 +57,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:8.9.1' + classpath 'com.android.tools.build:gradle:8.10.0' classpath 'com.google.gms:google-services:4.4.2' classpath 'com.google.firebase:firebase-crashlytics-gradle:3.0.3' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" From 44ce29f8819163e990fc44b0b83ba5b94187c874 Mon Sep 17 00:00:00 2001 From: Dave Antoine Date: Sat, 24 May 2025 19:40:54 -0400 Subject: [PATCH 5/6] SimpleWear: v1.16.1-build5 --- mobile/build.gradle | 4 ++-- .../thewizrd/shared_resources/helpers/WearSettingsHelper.kt | 2 +- .../com/thewizrd/shared_resources/helpers/WearableHelper.kt | 2 +- wear/build.gradle | 4 ++-- wearsettings/build.gradle | 4 ++-- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/mobile/build.gradle b/mobile/build.gradle index 9c02907..fd7b6b9 100644 --- a/mobile/build.gradle +++ b/mobile/build.gradle @@ -22,8 +22,8 @@ android { targetSdkVersion rootProject.targetSdkVersion // NOTE: Version Code Format [TargetSDK, Version Name, Build Number, Variant Code (Android: 0, WearOS: 1)] // NOTE: update SUPPORTED_VERSION_CODE if needed - versionCode 341916040 - versionName "1.16.0" + versionCode 341916050 + versionName "1.16.1" vectorDrawables.useSupportLibrary = true } diff --git a/shared_resources/src/main/java/com/thewizrd/shared_resources/helpers/WearSettingsHelper.kt b/shared_resources/src/main/java/com/thewizrd/shared_resources/helpers/WearSettingsHelper.kt index 268c6da..83d436d 100644 --- a/shared_resources/src/main/java/com/thewizrd/shared_resources/helpers/WearSettingsHelper.kt +++ b/shared_resources/src/main/java/com/thewizrd/shared_resources/helpers/WearSettingsHelper.kt @@ -11,7 +11,7 @@ import com.thewizrd.shared_resources.utils.Logger object WearSettingsHelper { // Link to Play Store listing const val PACKAGE_NAME = "com.thewizrd.wearsettings" - private const val SUPPORTED_VERSION_CODE: Long = 1030000 + private const val SUPPORTED_VERSION_CODE: Long = 1030002 fun getPackageName(): String { var packageName = PACKAGE_NAME diff --git a/shared_resources/src/main/java/com/thewizrd/shared_resources/helpers/WearableHelper.kt b/shared_resources/src/main/java/com/thewizrd/shared_resources/helpers/WearableHelper.kt index ee299e2..ec5e2c6 100644 --- a/shared_resources/src/main/java/com/thewizrd/shared_resources/helpers/WearableHelper.kt +++ b/shared_resources/src/main/java/com/thewizrd/shared_resources/helpers/WearableHelper.kt @@ -24,7 +24,7 @@ object WearableHelper { // Link to Play Store listing private const val PLAY_STORE_APP_URI = "market://details?id=com.thewizrd.simplewear" - private const val SUPPORTED_VERSION_CODE: Long = 341916000 + private const val SUPPORTED_VERSION_CODE: Long = 341916050 fun getPlayStoreURI(): Uri = Uri.parse(PLAY_STORE_APP_URI) diff --git a/wear/build.gradle b/wear/build.gradle index 8ddcf9b..d679732 100644 --- a/wear/build.gradle +++ b/wear/build.gradle @@ -13,8 +13,8 @@ android { minSdkVersion 26 targetSdkVersion rootProject.targetSdkVersion // NOTE: Version Code Format (TargetSDK, Version Name, Build Number, Variant Code (Android: 0, WearOS: 1) - versionCode 341916041 - versionName "1.16.0" + versionCode 341916051 + versionName "1.16.1" vectorDrawables.useSupportLibrary = true } diff --git a/wearsettings/build.gradle b/wearsettings/build.gradle index 09431f9..b221308 100644 --- a/wearsettings/build.gradle +++ b/wearsettings/build.gradle @@ -13,8 +13,8 @@ android { //noinspection ExpiredTargetSdkVersion targetSdk 28 // NOTE: update SUPPORTED_VERSION_CODE if needed - versionCode 1030001 - versionName "1.3.0" + versionCode 1030002 + versionName "1.3.1" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } From 237c943a3c4c5c1a1c22fab8da4d917a0a51dc4f Mon Sep 17 00:00:00 2001 From: Dave Antoine Date: Mon, 26 May 2025 03:24:41 -0400 Subject: [PATCH 6/6] pages: update companion app --- docs/settings-helper.md | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/docs/settings-helper.md b/docs/settings-helper.md index a1ccdc7..0319e45 100644 --- a/docs/settings-helper.md +++ b/docs/settings-helper.md @@ -8,9 +8,11 @@ permalink: /settings-helper Companion app for SimpleWear -Latest version: [SimpleWear Settings v1.3.0]({{ site.github.repository_url}}/releases/download/v1.16.0_beta/wearsettings-release-1.3.0.apk) +Latest version: [SimpleWear Settings v1.3.1]({{ +site.github.repository_url}}/releases/download/v1.16.1_release/wearsettings-release-1.3.1.apk) -Previous version: [SimpleWear Settings v1.2.0]({{ site.github.repository_url}}/releases/download/v1.15.2-release/wearsettings-release-1.2.0.apk) +Previous version: [SimpleWear Settings v1.3.0]({{ +site.github.repository_url}}/releases/download/v1.16.0_beta/wearsettings-release-1.3.0.apk) ## WiFi and Location Toggle @@ -23,8 +25,12 @@ If you are using Android 10 and above, and want to toggle **Wi-Fi** settings or ## Mobile Data -SimpleWear is unable to toggle mobile data without system permissions. [Root access](./root-access) or for unrooted devices, [Shizuku](https://github.com/RikkaApps/Shizuku) can be used. Please follow the instructions in app to start. +SimpleWear is unable to toggle mobile data without system permissions. [Root access](./root-access) +or for unrooted devices, [Shizuku](https://github.com/RikkaApps/Shizuku) can be used. Please follow +the instructions in app to start. ## Bluetooth -As of Android 13 (or T), non-system apps are no longer allowed to toggle Bluetooth on or off. This helper app is needed in order to allow SimpleWear to toggle Bluetooth . The helper app is built for an older version of Android which allows it to be able to toggle Bluetooth. \ No newline at end of file +As of Android 13 (or T), non-system apps are no longer allowed to toggle Bluetooth on or off. This +helper app is needed in order to allow SimpleWear to toggle Bluetooth. The helper app is built for +an older version of Android which allows it to be able to toggle Bluetooth. \ No newline at end of file