This commit is contained in:
2025-04-04 17:04:55 +02:00
commit 3f5f894e86
16 changed files with 753 additions and 0 deletions

56
android/build.gradle Normal file
View File

@@ -0,0 +1,56 @@
group 'dev.rexios.wear_plus'
version '1.0-SNAPSHOT'
buildscript {
ext.kotlin_version = '1.7.20'
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.3.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
rootProject.allprojects {
repositories {
google()
mavenCentral()
}
}
apply plugin: 'com.android.library'
apply plugin: 'kotlin-android'
//apply plugin: 'kotlin-android-extensions'
android {
compileSdkVersion 31
sourceSets {
main.java.srcDirs += 'src/main/kotlin'
}
defaultConfig {
minSdkVersion 23
consumerProguardFiles 'proguard-rules.pro'
}
lintOptions {
disable 'InvalidPackage'
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_11
targetCompatibility JavaVersion.VERSION_11
}
kotlinOptions {
jvmTarget = '11'
}
namespace "dev.rexios.wear_plus"
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'androidx.wear:wear:1.3.0'
implementation 'com.google.android.support:wearable:2.9.0'
compileOnly 'com.google.android.wearable:wearable:2.9.0'
}

View File

@@ -0,0 +1,2 @@
android.useAndroidX=true
android.enableJetifier=true

View File

@@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.5-all.zip

3
android/proguard-rules.pro vendored Normal file
View File

@@ -0,0 +1,3 @@
-keep class dev.rexios.wear_plus.** { *; }
-dontwarn com.google.android.wearable.compat.WearableActivityController$AmbientCallback
-dontwarn com.google.android.wearable.compat.WearableActivityController

1
android/settings.gradle Normal file
View File

@@ -0,0 +1 @@
rootProject.name = 'wear'

View File

@@ -0,0 +1,11 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="dev.rexios.wear_plus"
>
<!-- Flags the app as a Wear app -->
<uses-feature android:name="android.hardware.type.watch" />
<!-- Required for ambient mode support -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
</manifest>

View File

@@ -0,0 +1,147 @@
package dev.rexios.wear_plus
import android.os.Bundle
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.LifecycleOwner
import com.google.android.wearable.compat.WearableActivityController
import io.flutter.embedding.engine.plugins.FlutterPlugin
import io.flutter.embedding.engine.plugins.activity.ActivityAware
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
import io.flutter.embedding.engine.plugins.lifecycle.HiddenLifecycleReference
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.common.MethodChannel.Result
class WearPlugin : FlutterPlugin, ActivityAware, MethodCallHandler, LifecycleEventObserver {
private var mAmbientCallback = WearableAmbientCallback()
private var mMethodChannel: MethodChannel? = null
private var mActivityBinding: ActivityPluginBinding? = null
private var mAmbientController: WearableActivityController? = null
companion object {
const val TAG = "WearPlugin"
const val BURN_IN_PROTECTION = WearableActivityController.EXTRA_BURN_IN_PROTECTION
const val LOW_BIT_AMBIENT = WearableActivityController.EXTRA_LOWBIT_AMBIENT
}
override fun onAttachedToEngine(binding: FlutterPlugin.FlutterPluginBinding) {
mMethodChannel = MethodChannel(binding.binaryMessenger, "wear")
mMethodChannel!!.setMethodCallHandler(this)
}
override fun onDetachedFromEngine(binding: FlutterPlugin.FlutterPluginBinding) {
mMethodChannel?.setMethodCallHandler(this)
mMethodChannel = null
}
override fun onAttachedToActivity(binding: ActivityPluginBinding) {
attachAmbientController(binding)
}
override fun onDetachedFromActivityForConfigChanges() {
detachAmbientController()
}
override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {
attachAmbientController(binding)
}
override fun onDetachedFromActivity() {
detachAmbientController()
}
private fun attachAmbientController(binding: ActivityPluginBinding) {
mActivityBinding = binding
mAmbientController = WearableActivityController(TAG, binding.activity, mAmbientCallback)
mAmbientController?.setAmbientEnabled()
val reference = (binding.lifecycle as HiddenLifecycleReference)
reference.lifecycle.addObserver(this)
}
private fun detachAmbientController() {
mActivityBinding?.let {
val reference = (it.lifecycle as HiddenLifecycleReference)
reference.lifecycle.removeObserver(this)
}
mActivityBinding = null
}
override fun onMethodCall(call: MethodCall, result: Result) {
when (call.method) {
"getShape" -> {
val activity = mActivityBinding?.activity
when {
activity == null -> {
result.error("no-activity", "No android activity available.", null)
}
activity.resources.configuration.isScreenRound -> {
result.success("round")
}
else -> {
result.success("square")
}
}
}
"isAmbient" -> {
result.success(mAmbientController?.isAmbient ?: false)
}
"setAutoResumeEnabled" -> {
val enabled = call.argument<Boolean>("enabled")
if (mAmbientController == null || enabled == null) {
result.error("not-ready", "Ambient mode controller not ready", null)
} else {
mAmbientController!!.setAutoResumeEnabled(enabled)
result.success(null)
}
}
"setAmbientOffloadEnabled" -> {
val enabled = call.argument<Boolean>("enabled")
if (mAmbientController == null || enabled == null) {
result.error("not-ready", "Ambient mode controller not ready", null)
} else {
mAmbientController!!.setAmbientOffloadEnabled(enabled)
result.success(null)
}
}
else -> result.notImplemented()
}
}
inner class WearableAmbientCallback : WearableActivityController.AmbientCallback() {
override fun onEnterAmbient(ambientDetails: Bundle) {
val burnInProtection = ambientDetails.getBoolean(BURN_IN_PROTECTION, false)
val lowBitAmbient = ambientDetails.getBoolean(LOW_BIT_AMBIENT, false)
mMethodChannel?.invokeMethod("onEnterAmbient", mapOf(
"burnInProtection" to burnInProtection,
"lowBitAmbient" to lowBitAmbient
))
}
override fun onExitAmbient() {
mMethodChannel?.invokeMethod("onExitAmbient", null)
}
override fun onUpdateAmbient() {
mMethodChannel?.invokeMethod("onUpdateAmbient", null)
}
override fun onInvalidateAmbientOffload() {
mMethodChannel?.invokeMethod("onInvalidateAmbientOffload", null)
}
}
override fun onStateChanged(source: LifecycleOwner, event: Lifecycle.Event) {
when (event) {
Lifecycle.Event.ON_CREATE -> mAmbientController?.onCreate()
Lifecycle.Event.ON_RESUME -> mAmbientController?.onResume()
Lifecycle.Event.ON_PAUSE -> mAmbientController?.onPause()
Lifecycle.Event.ON_STOP -> mAmbientController?.onStop()
Lifecycle.Event.ON_DESTROY -> mAmbientController?.onDestroy()
else -> {}
}
}
}