Wear cwf Add view info

This commit is contained in:
Philoul 2023-08-24 20:41:11 +02:00
parent 55e475e772
commit 80dcb9700a
9 changed files with 205 additions and 61 deletions

View file

@ -116,8 +116,7 @@ enum class CwfMetadataKey(val key: String, @StringRes val label: Int, val isPref
CWF_PREF_WATCH_SHOW_DIRECTION("key_show_direction", R.string.pref_show_direction_arrow, true), CWF_PREF_WATCH_SHOW_DIRECTION("key_show_direction", R.string.pref_show_direction_arrow, true),
CWF_PREF_WATCH_SHOW_AGO("key_show_ago", R.string.pref_show_ago, true), CWF_PREF_WATCH_SHOW_AGO("key_show_ago", R.string.pref_show_ago, true),
CWF_PREF_WATCH_SHOW_BG("key_show_bg", R.string.pref_show_bg, true), CWF_PREF_WATCH_SHOW_BG("key_show_bg", R.string.pref_show_bg, true),
CWF_PREF_WATCH_SHOW_LOOP_STATUS("key_show_loop_status", R.string.pref_show_loop_status, true), CWF_PREF_WATCH_SHOW_LOOP_STATUS("key_show_loop_status", R.string.pref_show_loop_status, true);
CWF_PREF_WATCH_SHOW_DATE("key_show_date", R.string.pref_show_date, true);
companion object { companion object {
@ -126,41 +125,41 @@ enum class CwfMetadataKey(val key: String, @StringRes val label: Int, val isPref
} }
} }
enum class ViewKeys(val key: String, @StringRes val comment: Int?) { enum class ViewKeys(val key: String, @StringRes val comment: Int) {
BACKGROUND("background", null), BACKGROUND("background", R.string.cwf_comment_background),
CHART("chart", null), CHART("chart", R.string.cwf_comment_chart),
COVER_CHART("cover_chart", null), COVER_CHART("cover_chart", R.string.cwf_comment_cover_chart),
FREETEXT1("freetext1", null), FREETEXT1("freetext1", R.string.cwf_comment_freetext1),
FREETEXT2("freetext2", null), FREETEXT2("freetext2", R.string.cwf_comment_freetext2),
FREETEXT3("freetext3", null), FREETEXT3("freetext3", R.string.cwf_comment_freetext3),
FREETEXT4("freetext4", null), FREETEXT4("freetext4", R.string.cwf_comment_freetext4),
IOB1("iob1", null), IOB1("iob1", R.string.cwf_comment_iob1),
IOB2("iob2", null), IOB2("iob2", R.string.cwf_comment_iob2),
COB1("cob1", null), COB1("cob1", R.string.cwf_comment_cob1),
COB2("cob2", null), COB2("cob2", R.string.cwf_comment_cob2),
DELTA("delta", null), DELTA("delta", R.string.cwf_comment_delta),
AVG_DELTA("avg_delta", null), AVG_DELTA("avg_delta", R.string.cwf_comment_avg_delta),
UPLOADER_BATTERY("uploader_battery", null), UPLOADER_BATTERY("uploader_battery", R.string.cwf_comment_uploader_battery),
RIG_BATTERY("rig_battery", null), RIG_BATTERY("rig_battery", R.string.cwf_comment_rig_battery),
BASALRATE("basalRate", null), BASALRATE("basalRate", R.string.cwf_comment_basalRate),
BGI("bgi", null), BGI("bgi", R.string.cwf_comment_bgi),
TIME("time", null), TIME("time", R.string.cwf_comment_time),
HOUR("hour", null), HOUR("hour", R.string.cwf_comment_hour),
MINUTE("minute", null), MINUTE("minute", R.string.cwf_comment_minute),
SECOND("second", null), SECOND("second", R.string.cwf_comment_second),
TIMEPERIOD("timePeriod", null), TIMEPERIOD("timePeriod", R.string.cwf_comment_timePeriod),
DAY_NAME("day_name", null), DAY_NAME("day_name", R.string.cwf_comment_day_name),
DAY("day", null), DAY("day", R.string.cwf_comment_day),
MONTH("month", null), MONTH("month", R.string.cwf_comment_month),
LOOP("loop", null), LOOP("loop", R.string.cwf_comment_loop),
DIRECTION("direction", null), DIRECTION("direction", R.string.cwf_comment_direction),
TIMESTAMP("timestamp", null), TIMESTAMP("timestamp", R.string.cwf_comment_timestamp),
SGV("sgv", null), SGV("sgv", R.string.cwf_comment_sgv),
COVER_PLATE("cover_plate", null), COVER_PLATE("cover_plate", R.string.cwf_comment_cover_plate),
HOUR_HAND("hour_hand", null), HOUR_HAND("hour_hand", R.string.cwf_comment_hour_hand),
MINUTE_HAND("minute_hand", null), MINUTE_HAND("minute_hand", R.string.cwf_comment_minute_hand),
SECOND_HAND("second_hand", null) SECOND_HAND("second_hand", R.string.cwf_comment_second_hand);
} }
enum class JsonKeys(val key: String, val viewType: ViewType, @StringRes val comment: Int?) { enum class JsonKeys(val key: String, val viewType: ViewType, @StringRes val comment: Int?) {

View file

@ -48,7 +48,6 @@
<string name="metadata_label_watchface_name_version">Name: %1$s (%2$s)</string> <string name="metadata_label_watchface_name_version">Name: %1$s (%2$s)</string>
<string name="metadata_label_watchface_comment" translatable="false">Comment: %1$s</string> <string name="metadata_label_watchface_comment" translatable="false">Comment: %1$s</string>
<string name="metadata_label_watchface_authorization" translatable="false">%1$s</string> <string name="metadata_label_watchface_authorization" translatable="false">%1$s</string>
<string name="pref_show_date">Show Date</string>
<string name="pref_show_iob">Show IOB</string> <string name="pref_show_iob">Show IOB</string>
<string name="pref_show_detailed_iob">Show detailed IOB</string> <string name="pref_show_detailed_iob">Show detailed IOB</string>
<string name="pref_show_cob">Show COB</string> <string name="pref_show_cob">Show COB</string>
@ -65,5 +64,38 @@
<string name="pref_show_ago">Show Ago</string> <string name="pref_show_ago">Show Ago</string>
<string name="default_custom_watchface_comment">Default watchface, you can click on EXPORT WATCHFACE button to generate a template</string> <string name="default_custom_watchface_comment">Default watchface, you can click on EXPORT WATCHFACE button to generate a template</string>
<string name="wear_default_watchface">Default Watchface</string> <string name="wear_default_watchface">Default Watchface</string>
<string name="cwf_comment_background">Background image</string>
<string name="cwf_comment_chart">Graphs (BG, basal, prediction lines...)</string>
<string name="cwf_comment_cover_chart">Image in front of graph and behind text fields</string>
<string name="cwf_comment_freetext1">Free text 1</string>
<string name="cwf_comment_freetext2">Free text 2</string>
<string name="cwf_comment_freetext3">Free text 3</string>
<string name="cwf_comment_freetext4">Free text 4</string>
<string name="cwf_comment_iob1">IOB label or IOB Sum if detailed</string>
<string name="cwf_comment_iob2">IOB Sum or (Bolus_IOB|Basal_IOB) if detailed</string>
<string name="cwf_comment_cob1">COB label</string>
<string name="cwf_comment_cob2">COB value</string>
<string name="cwf_comment_delta">Short BG delta</string>
<string name="cwf_comment_avg_delta">Average BG delta (15min)</string>
<string name="cwf_comment_uploader_battery">Phone battery (%)</string>
<string name="cwf_comment_rig_battery">Global loop battery (%)</string>
<string name="cwf_comment_basalRate">Basal Rate</string>
<string name="cwf_comment_bgi">BGI value</string>
<string name="cwf_comment_time">Time (HH:MM or HH:MM:SS)</string>
<string name="cwf_comment_hour">Hour (HH)</string>
<string name="cwf_comment_minute">Minute (MM)</string>
<string name="cwf_comment_second">Second (SS)</string>
<string name="cwf_comment_timePeriod">AM or PM</string>
<string name="cwf_comment_day_name">Name of day of the week</string>
<string name="cwf_comment_day">Day (DD)</string>
<string name="cwf_comment_month">Month name (short)</string>
<string name="cwf_comment_loop">Loop status and ago</string>
<string name="cwf_comment_direction">Direction arrow</string>
<string name="cwf_comment_timestamp">Mintutes ago for last received BG</string>
<string name="cwf_comment_sgv">BG value</string>
<string name="cwf_comment_cover_plate">Cover image in front of text (dials...)</string>
<string name="cwf_comment_hour_hand">Image of hour hand (Analog Watch)</string>
<string name="cwf_comment_minute_hand">Image of minute hand (Analog Watch)</string>
<string name="cwf_comment_second_hand">Image of second hand (Analog Watch)</string>
</resources> </resources>

View file

@ -15,15 +15,19 @@ import info.nightscout.interfaces.versionChecker.VersionCheckerUtils
import info.nightscout.plugins.R import info.nightscout.plugins.R
import info.nightscout.plugins.databinding.CwfInfosActivityBinding import info.nightscout.plugins.databinding.CwfInfosActivityBinding
import info.nightscout.plugins.databinding.CwfInfosActivityPrefItemBinding import info.nightscout.plugins.databinding.CwfInfosActivityPrefItemBinding
import info.nightscout.plugins.databinding.CwfInfosActivityViewItemBinding
import info.nightscout.plugins.general.wear.WearPlugin import info.nightscout.plugins.general.wear.WearPlugin
import info.nightscout.rx.bus.RxBus import info.nightscout.rx.bus.RxBus
import info.nightscout.rx.logging.AAPSLogger import info.nightscout.rx.logging.AAPSLogger
import info.nightscout.rx.logging.LTag
import info.nightscout.rx.weardata.CUSTOM_VERSION import info.nightscout.rx.weardata.CUSTOM_VERSION
import info.nightscout.rx.weardata.CwfDrawableFileMap import info.nightscout.rx.weardata.CwfDrawableFileMap
import info.nightscout.rx.weardata.CwfMetadataKey import info.nightscout.rx.weardata.CwfMetadataKey
import info.nightscout.rx.weardata.CwfMetadataMap import info.nightscout.rx.weardata.CwfMetadataMap
import info.nightscout.rx.weardata.ViewKeys
import info.nightscout.shared.interfaces.ResourceHelper import info.nightscout.shared.interfaces.ResourceHelper
import info.nightscout.shared.sharedPreferences.SP import info.nightscout.shared.sharedPreferences.SP
import org.json.JSONObject
import javax.inject.Inject import javax.inject.Inject
class CwfInfosActivity : TranslatedDaggerAppCompatActivity() { class CwfInfosActivity : TranslatedDaggerAppCompatActivity() {
@ -49,9 +53,6 @@ class CwfInfosActivity : TranslatedDaggerAppCompatActivity() {
updateGui() updateGui()
// Add menu items without overriding methods in the Activity // Add menu items without overriding methods in the Activity
addMenuProvider(object : MenuProvider { addMenuProvider(object : MenuProvider {
override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {} override fun onCreateMenu(menu: Menu, menuInflater: MenuInflater) {}
@ -87,20 +88,22 @@ class CwfInfosActivity : TranslatedDaggerAppCompatActivity() {
binding.cwfComment.text = rh.gs(CwfMetadataKey.CWF_COMMENT.label, metadata[CwfMetadataKey.CWF_COMMENT] ?: "") binding.cwfComment.text = rh.gs(CwfMetadataKey.CWF_COMMENT.label, metadata[CwfMetadataKey.CWF_COMMENT] ?: "")
if (metadata.count { it.key.isPref } > 0) { if (metadata.count { it.key.isPref } > 0) {
binding.prefLayout.visibility = View.VISIBLE binding.prefLayout.visibility = View.VISIBLE
binding.prefTitle.text = rh.gs(if (cwf_authorization) R.string.cwf_infos_pref_locked else R.string.cwf_infos_pref_requested) binding.prefTitle.text = rh.gs(if (cwf_authorization) R.string.cwf_infos_pref_locked else R.string.cwf_infos_pref_required)
binding.prefRecyclerview.layoutManager = LinearLayoutManager(this) binding.prefRecyclerview.layoutManager = LinearLayoutManager(this)
binding.prefRecyclerview.adapter = PrefRecyclerViewAdapter( binding.prefRecyclerview.adapter = PrefRecyclerViewAdapter(
metadata.filter { it.key.isPref && (it.value.lowercase() == "true" || it.value.lowercase() == "false") }.toList() metadata.filter { it.key.isPref && (it.value.lowercase() == "true" || it.value.lowercase() == "false") }.toList()
) )
} else } else
binding.prefLayout.visibility = View.GONE binding.prefLayout.visibility = View.GONE
binding.viewRecyclerview.layoutManager = LinearLayoutManager(this)
binding.viewRecyclerview.adapter = ViewRecyclerViewAdapter(listVisibleView(it.json))
} }
} }
inner class PrefRecyclerViewAdapter internal constructor(private var prefList: List<Pair<CwfMetadataKey, String>>) : RecyclerView.Adapter<PrefRecyclerViewAdapter.CwfFileViewHolder>() { inner class PrefRecyclerViewAdapter internal constructor(private var prefList: List<Pair<CwfMetadataKey, String>>) : RecyclerView.Adapter<PrefRecyclerViewAdapter.CwfPrefViewHolder>() {
inner class CwfFileViewHolder(val cwfInfosActivityPrefItemBinding: CwfInfosActivityPrefItemBinding) : RecyclerView.ViewHolder(cwfInfosActivityPrefItemBinding.root) { inner class CwfPrefViewHolder(val cwfInfosActivityPrefItemBinding: CwfInfosActivityPrefItemBinding) : RecyclerView.ViewHolder(cwfInfosActivityPrefItemBinding.root) {
init { init {
with(cwfInfosActivityPrefItemBinding) { with(cwfInfosActivityPrefItemBinding) {
root.isClickable = false root.isClickable = false
@ -108,16 +111,16 @@ class CwfInfosActivity : TranslatedDaggerAppCompatActivity() {
} }
} }
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CwfFileViewHolder { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CwfPrefViewHolder {
val binding = CwfInfosActivityPrefItemBinding.inflate(LayoutInflater.from(parent.context), parent, false) val binding = CwfInfosActivityPrefItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return CwfFileViewHolder(binding) return CwfPrefViewHolder(binding)
} }
override fun getItemCount(): Int { override fun getItemCount(): Int {
return prefList.size return prefList.size
} }
override fun onBindViewHolder(holder: CwfFileViewHolder, position: Int) { override fun onBindViewHolder(holder: CwfPrefViewHolder, position: Int) {
val pref = prefList[position] val pref = prefList[position]
val key = pref.first val key = pref.first
val value = pref.second.lowercase().toBooleanStrictOrNull() // should never be null here, just safety to avoid exception val value = pref.second.lowercase().toBooleanStrictOrNull() // should never be null here, just safety to avoid exception
@ -128,6 +131,36 @@ class CwfInfosActivity : TranslatedDaggerAppCompatActivity() {
} }
} }
inner class ViewRecyclerViewAdapter internal constructor(private var viewList: List<Pair<ViewKeys, Boolean>>) : RecyclerView.Adapter<ViewRecyclerViewAdapter.CwfViewHolder>() {
inner class CwfViewHolder(val cwfInfosActivityViewItemBinding: CwfInfosActivityViewItemBinding) : RecyclerView.ViewHolder(cwfInfosActivityViewItemBinding.root) {
init {
with(cwfInfosActivityViewItemBinding) {
root.isClickable = false
}
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CwfViewHolder {
val binding = CwfInfosActivityViewItemBinding.inflate(LayoutInflater.from(parent.context), parent, false)
return CwfViewHolder(binding)
}
override fun getItemCount(): Int {
return viewList.size
}
override fun onBindViewHolder(holder: CwfViewHolder, position: Int) {
val cwfView = viewList[position]
val key = cwfView.first.key
val value = cwfView.first.comment
val visible = cwfView.second // will be used if all keys included into RecyclerView
with(holder.cwfInfosActivityViewItemBinding) {
viewKey.text = "\"$key\":"
viewComment.text = rh.gs(value)
}
}
}
private fun checkCustomVersion(metadata: CwfMetadataMap): Boolean { private fun checkCustomVersion(metadata: CwfMetadataMap): Boolean {
metadata[CwfMetadataKey.CWF_VERSION]?.let { version -> metadata[CwfMetadataKey.CWF_VERSION]?.let { version ->
@ -139,4 +172,24 @@ class CwfInfosActivity : TranslatedDaggerAppCompatActivity() {
return false return false
} }
private fun listVisibleView(jsonString: String, allViews: Boolean = false): List<Pair<ViewKeys, Boolean>> {
val json = JSONObject(jsonString)
val visibleKeyPairs = mutableListOf<Pair<ViewKeys, Boolean>>()
for (viewKey in ViewKeys.values()) {
try {
val jsonValue = json.optJSONObject(viewKey.key)
if (jsonValue != null) {
val visibility = jsonValue.optString("visibility") == "visible"
if (visibility || allViews)
visibleKeyPairs.add(Pair(viewKey, visibility))
}
} catch (e: Exception) {
aapsLogger.debug(LTag.WEAR, "Wrong key in json file: ${viewKey.key}")
}
}
return visibleKeyPairs
}
} }

View file

@ -10,7 +10,7 @@
tools:context="info.nightscout.plugins.general.wear.activities.CwfInfosActivity"> tools:context="info.nightscout.plugins.general.wear.activities.CwfInfosActivity">
<androidx.core.widget.NestedScrollView <androidx.core.widget.NestedScrollView
android:layout_width="wrap_content" android:layout_width="match_parent"
android:layout_height="0dp" android:layout_height="0dp"
android:layout_weight="1"> android:layout_weight="1">
@ -117,7 +117,7 @@
android:layout_marginTop="15dp" android:layout_marginTop="15dp"
android:paddingStart="0dp" android:paddingStart="0dp"
android:paddingEnd="10dp" android:paddingEnd="10dp"
android:text="@string/cwf_infos_pref_requested" android:text="@string/cwf_infos_pref_required"
android:textAlignment="viewStart" android:textAlignment="viewStart"
android:textAppearance="?android:attr/textAppearanceSmall" android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?attr/importListFileNameColor" android:textColor="?attr/importListFileNameColor"
@ -154,7 +154,7 @@
android:textAlignment="viewStart" android:textAlignment="viewStart"
android:textAppearance="?android:attr/textAppearanceSmall" android:textAppearance="?android:attr/textAppearanceSmall"
android:textColor="?attr/importListFileNameColor" android:textColor="?attr/importListFileNameColor"
android:textSize="15sp" /> android:textSize="18sp" />
<androidx.recyclerview.widget.RecyclerView <androidx.recyclerview.widget.RecyclerView

View file

@ -28,13 +28,13 @@
android:id="@+id/pref_label" android:id="@+id/pref_label"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_marginStart="5dp" android:layout_marginStart="10dp"
android:layout_marginTop="0dp" android:layout_marginTop="0dp"
android:layout_marginBottom="0dp" android:layout_marginBottom="0dp"
android:layout_weight="1" android:layout_weight="1"
android:ellipsize="none" android:ellipsize="none"
android:maxLines="2" android:maxLines="2"
android:paddingStart="0dp" android:paddingStart="5dp"
android:paddingEnd="10dp" android:paddingEnd="10dp"
android:scrollHorizontally="false" android:scrollHorizontally="false"
android:text="Default Custom Watchface" android:text="Default Custom Watchface"

View file

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="utf-8"?>
<com.google.android.material.card.MaterialCardView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/careportal_cardview"
style="@style/Widget.MaterialComponents.CardView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="4dp"
android:layout_marginEnd="4dp"
android:layout_marginTop="4dp"
app:cardCornerRadius="4dp"
app:contentPadding="2dp"
app:cardElevation="2dp"
app:cardUseCompatPadding="false"
android:layout_gravity="center">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="1dp"
android:gravity="center"
android:layout_marginBottom="3dp"
android:orientation="horizontal">
<TextView
android:id="@+id/view_key"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="0dp"
android:layout_marginBottom="0dp"
android:ellipsize="none"
android:maxLines="1"
android:paddingStart="5dp"
android:paddingEnd="0dp"
android:scrollHorizontally="false"
android:text="key"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="?attr/importListFileNameColor"
tools:ignore="HardcodedText" />
<TextView
android:id="@+id/view_comment"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:layout_marginTop="0dp"
android:layout_marginBottom="0dp"
android:layout_weight="1"
android:ellipsize="none"
android:maxLines="2"
android:paddingStart="2dp"
android:paddingEnd="5dp"
android:scrollHorizontally="false"
android:text="label"
android:textAppearance="?android:attr/textAppearanceMedium"
android:textColor="?attr/importListFileNameColor"
tools:ignore="HardcodedText" />
</LinearLayout>
</com.google.android.material.card.MaterialCardView>

View file

@ -366,9 +366,10 @@
<string name="resend_all_data">Resend All Data</string> <string name="resend_all_data">Resend All Data</string>
<string name="open_settings_on_wear">Open Settings on Wear</string> <string name="open_settings_on_wear">Open Settings on Wear</string>
<string name="cwf_infos_pref_locked">List of prefs locked by the Watchface</string> <string name="cwf_infos_pref_locked">List of prefs locked by the Watchface</string>
<string name="cwf_infos_pref_requested">List of prefs requested by the Watchface</string> <string name="cwf_infos_pref_required">List of prefs required for the Watchface</string>
<string name="cwf_infos_view_title">List of fields included into the Watchface</string> <string name="cwf_infos_view_title">List of fields included into the Watchface</string>
<!-- PersistentNotification--> <!-- PersistentNotification-->
<string name="ongoingnotificaction" translatable="false">Ongoing Notification</string> <string name="ongoingnotificaction" translatable="false">Ongoing Notification</string>
<string name="description_persistent_notification">Shows an ongoing notification with a short overview of what your loop is doing</string> <string name="description_persistent_notification">Shows an ongoing notification with a short overview of what your loop is doing</string>

View file

@ -496,8 +496,7 @@ class CustomWatchface : BaseWatchFace() {
SHOW_AGO(CwfMetadataKey.CWF_PREF_WATCH_SHOW_AGO.key, R.string.key_show_ago), SHOW_AGO(CwfMetadataKey.CWF_PREF_WATCH_SHOW_AGO.key, R.string.key_show_ago),
SHOW_BG(CwfMetadataKey.CWF_PREF_WATCH_SHOW_BG.key, R.string.key_show_bg), SHOW_BG(CwfMetadataKey.CWF_PREF_WATCH_SHOW_BG.key, R.string.key_show_bg),
SHOW_BGI(CwfMetadataKey.CWF_PREF_WATCH_SHOW_BGI.key, R.string.key_show_bgi), SHOW_BGI(CwfMetadataKey.CWF_PREF_WATCH_SHOW_BGI.key, R.string.key_show_bgi),
SHOW_LOOP_STATUS(CwfMetadataKey.CWF_PREF_WATCH_SHOW_LOOP_STATUS.key, R.string.key_show_external_status), SHOW_LOOP_STATUS(CwfMetadataKey.CWF_PREF_WATCH_SHOW_LOOP_STATUS.key, R.string.key_show_external_status)
SHOW_DATE(CwfMetadataKey.CWF_PREF_WATCH_SHOW_DATE.key, R.string.key_show_date)
} }
} }

View file

@ -9,13 +9,6 @@
app:wear_iconOff="@drawable/settings_off" app:wear_iconOff="@drawable/settings_off"
app:wear_iconOn="@drawable/settings_on" /> app:wear_iconOn="@drawable/settings_on" />
<CheckBoxPreference
android:defaultValue="true"
android:key="@string/key_show_date"
android:title="@string/pref_show_date"
app:wear_iconOff="@drawable/settings_off"
app:wear_iconOn="@drawable/settings_on" />
<CheckBoxPreference <CheckBoxPreference
android:defaultValue="false" android:defaultValue="false"
android:key="@string/key_vibrate_hourly" android:key="@string/key_vibrate_hourly"