Initial commit

This commit is contained in:
Ray 2019-10-06 20:41:25 +01:00
commit 67624ae179
10 changed files with 407 additions and 0 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
/bin
/obj

60
ClockViewModel.cs Normal file
View File

@ -0,0 +1,60 @@
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace TizenWatchfaceApp1
{
public class ClockViewModel : INotifyPropertyChanged
{
protected DateTime time = DateTime.MinValue;
protected int heartRate = 0;
protected int battery = 0;
public DateTime Time
{
get => time;
set
{
if (time == value) return;
time = value;
OnPropertyChanged();
}
}
public int HeartRate
{
get => heartRate;
set
{
if (heartRate == value) return;
heartRate = value;
OnPropertyChanged();
}
}
public int Battery
{
get => battery;
set
{
if (battery == value) return;
battery = value;
OnPropertyChanged();
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}

65
TizenWatchfaceApp1.cs Normal file
View File

@ -0,0 +1,65 @@
using System;
using Tizen.Applications;
using Tizen.System;
using Tizen.Wearable.CircularUI.Forms.Renderer.Watchface;
namespace TizenWatchfaceApp1
{
class Program : FormsWatchface
{
protected WatchFaceApplication mainApplication = null;
protected override void OnCreate()
{
base.OnCreate();
mainApplication = new WatchFaceApplication();
mainApplication.ViewModel.Battery = Battery.Percent;
mainApplication.ViewModel.Time = DateTime.Now;
Battery.ChargingStateChanged += battery_ChargingStateChanged;
LoadWatchface(mainApplication);
}
protected override void OnTick(TimeEventArgs time)
{
base.OnTick(time);
if (mainApplication != null)
{
mainApplication.ViewModel.Time = new DateTime(time.Time.Year, time.Time.Month, time.Time.Day, time.Time.Hour24, time.Time.Minute, time.Time.Second, time.Time.Millisecond);
}
}
protected void battery_ChargingStateChanged(object sender, BatteryChargingStateChangedEventArgs e)
{
if (mainApplication != null)
{
mainApplication.ViewModel.Battery = Battery.Percent;
}
}
//protected override void OnAmbientChanged(AmbientEventArgs mode)
//{
// base.OnAmbientChanged(mode);
//}
//protected override void OnAmbientTick(TimeEventArgs time)
//{
// base.OnAmbientTick(time);
//}
static void Main(string[] args)
{
var app = new Program();
global::Xamarin.Forms.Platform.Tizen.Forms.Init(app);
global::Tizen.Wearable.CircularUI.Forms.Renderer.FormsCircularUI.Init();
app.Run(args);
}
}
}

31
TizenWatchfaceApp1.csproj Normal file
View File

@ -0,0 +1,31 @@
<Project Sdk="Tizen.NET.Sdk/1.0.3">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>tizen40</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugType>portable</DebugType>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>None</DebugType>
</PropertyGroup>
<ItemGroup>
<Folder Include="lib\" />
<Folder Include="res\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Tizen.Wearable.CircularUI" Version="1.2.0" />
</ItemGroup>
<ItemGroup>
<Compile Update="WatchFaceApplication.xaml.cs">
<DependentUpon>WatchFaceApplication.xaml</DependentUpon>
</Compile>
</ItemGroup>
</Project>

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ActiveDebugProfile>TizenWatchfaceApp1</ActiveDebugProfile>
</PropertyGroup>
</Project>

25
TizenWatchfaceApp1.sln Normal file
View File

@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.28307.779
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TizenWatchfaceApp1", "TizenWatchfaceApp1.csproj", "{C1F90E16-FFC1-407F-8242-768D925325B3}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{C1F90E16-FFC1-407F-8242-768D925325B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C1F90E16-FFC1-407F-8242-768D925325B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C1F90E16-FFC1-407F-8242-768D925325B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C1F90E16-FFC1-407F-8242-768D925325B3}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {8BCDA13E-6821-4FC8-BD71-4BFF290BE0DE}
EndGlobalSection
EndGlobal

82
WatchFaceApplication.xaml Normal file
View File

@ -0,0 +1,82 @@
<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="TizenWatchfaceApp1.WatchFaceApplication">
<Application.Resources>
<x:Double x:Key="FontXS">5.5</x:Double>
<x:Double x:Key="FontMD">8.5</x:Double>
<Color x:Key="ColourGrey">#535355</Color>
<!--<x:Double x:Key="FontXL">22</x:Double>-->
<Style TargetType="BoxView">
<Setter Property="VerticalOptions" Value="FillAndExpand" />
<Setter Property="HorizontalOptions" Value="FillAndExpand" />
<Setter Property="BackgroundColor" Value="{StaticResource ColourGrey}" />
</Style>
<Style TargetType="Grid">
<Setter Property="Margin" Value="0" />
<Setter Property="Padding" Value="0" />
</Style>
<Style TargetType="StackLayout" Class="canvas">
<Setter Property="Padding" Value="28, 40, 28, 40" />
<Setter Property="VerticalOptions" Value="CenterAndExpand" />
</Style>
<Style TargetType="Label">
<Setter Property="HorizontalTextAlignment" Value="Center" />
<Setter Property="HorizontalOptions" Value="FillAndExpand" />
<Setter Property="Margin" Value="0" />
</Style>
<Style TargetType="Label" Class="left">
<Setter Property="Margin" Value="30, 0, 0, 0" />
</Style>
<Style TargetType="Label" Class="right">
<Setter Property="Margin" Value="0, 0, 30, 0" />
</Style>
<Style TargetType="Label" Class="jumbo">
<Setter Property="FontAttributes" Value="Bold" />
<Setter Property="FontSize" Value="22" />
</Style>
</Application.Resources>
<Application.MainPage>
<ContentPage>
<StackLayout StyleClass="canvas">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="2" />
<RowDefinition Height="Auto" />
<RowDefinition Height="2" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="16" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Grid.Row="0" StyleClass="left" FontSize="{StaticResource FontXS}" TextColor="{StaticResource ColourGrey}" Text="Battery" />
<Label Grid.Column="2" Grid.Row="0" StyleClass="right" FontSize="{StaticResource FontXS}" TextColor="{StaticResource ColourGrey}" Text="Date" />
<Label Grid.Column="0" Grid.Row="1" StyleClass="left" FontAttributes="Bold" FontSize="{StaticResource FontMD}" Text="{Binding Battery}" />
<Label Grid.Column="2" Grid.Row="1" StyleClass="right" FontAttributes="Bold" FontSize="{StaticResource FontMD}" Text="{Binding Time, StringFormat='{0:dd/MM}'}" />
<BoxView Grid.Column="0" Grid.Row="2" />
<BoxView Grid.Column="2" Grid.Row="2" />
<Label Grid.Column="0" Grid.Row="3" Grid.ColumnSpan="3" StyleClass="jumbo" Text="{Binding Time, StringFormat='{0:hh\\:mm\\:ss}'}" />
<BoxView Grid.Column="0" Grid.Row="4" />
<BoxView Grid.Column="2" Grid.Row="4" />
<Label Grid.Column="0" Grid.Row="5" StyleClass="left" FontSize="{StaticResource FontXS}" TextColor="{StaticResource ColourGrey}" Text="Heart Rate" />
<Label Grid.Column="2" Grid.Row="5" StyleClass="right" FontSize="{StaticResource FontXS}" TextColor="{StaticResource ColourGrey}" Text="Day" />
<Label Grid.Column="0" Grid.Row="6" StyleClass="left" FontAttributes="Bold" FontSize="{StaticResource FontMD}" Text="{Binding HeartRate}" />
<Label Grid.Column="2" Grid.Row="6" StyleClass="right" FontAttributes="Bold" FontSize="{StaticResource FontMD}" Text="{Binding Time, StringFormat='{0:ddd}'}" />
</Grid>
</StackLayout>
</ContentPage>
</Application.MainPage>
</Application>

View File

@ -0,0 +1,118 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tizen.Security;
using Tizen.Sensor;
using Tizen.System;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace TizenWatchfaceApp1
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class WatchFaceApplication : Application
{
private const string heartRatePrivilege = "http://tizen.org/privilege/healthinfo";
private HeartRateMonitor heartRateMonitor = null;
public ClockViewModel ViewModel { get; set; } = null;
public WatchFaceApplication()
{
InitializeComponent();
setupPrivilegeHandler();
checkPrivilegeHandler();
this.ViewModel = new ClockViewModel();
this.BindingContext = this.ViewModel;
}
protected override void OnSleep()
{
base.OnSleep();
if (heartRateMonitor != null)
{
heartRateMonitor.Stop();
}
}
protected override void OnResume()
{
base.OnResume();
setupPrivilegeHandler();
if (heartRateMonitor != null)
{
heartRateMonitor.Start();
}
}
private void heartRateMonitor_DataUpdated(object sender, HeartRateMonitorDataUpdatedEventArgs e)
{
if (this.ViewModel != null) this.ViewModel.HeartRate = e.HeartRate;
}
private void setupPrivilegeHandler()
{
PrivacyPrivilegeManager.ResponseContext context = null;
if (PrivacyPrivilegeManager.GetResponseContext(heartRatePrivilege).TryGetTarget(out context))
{
context.ResponseFetched += privilege_ResponseFetched;
}
}
private void privilege_ResponseFetched(object sender, RequestResponseEventArgs e)
{
if (e.cause == CallCause.Error)
{
return;
}
switch (e.result)
{
case RequestResult.AllowForever:
if (HeartRateMonitor.IsSupported)
{
heartRateMonitor = new HeartRateMonitor();
heartRateMonitor.DataUpdated += heartRateMonitor_DataUpdated;
heartRateMonitor.Start();
}
break;
case RequestResult.DenyForever:
case RequestResult.DenyOnce:
break;
}
}
private void checkPrivilegeHandler()
{
CheckResult rs = PrivacyPrivilegeManager.CheckPermission(heartRatePrivilege);
switch (rs)
{
case CheckResult.Allow:
if (HeartRateMonitor.IsSupported)
{
heartRateMonitor = new HeartRateMonitor();
heartRateMonitor.DataUpdated += heartRateMonitor_DataUpdated;
}
break;
case CheckResult.Deny:
// do nothing
break;
case CheckResult.Ask:
PrivacyPrivilegeManager.RequestPermission(heartRatePrivilege);
break;
}
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.9 KiB

18
tizen-manifest.xml Normal file
View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="org.tizen.example.TizenWatchfaceApp1" version="1.0.0" api-version="4" xmlns="http://tizen.org/ns/packages">
<profile name="wearable" />
<watch-application appid="org.tizen.example.TizenWatchfaceApp1" exec="TizenWatchfaceApp1.dll" type="dotnet" ambient-support="false">
<label>TizenWatchfaceApp1</label>
<icon>TizenWatchfaceApp1.png</icon>
<metadata key="http://tizen.org/metadata/prefer_dotnet_aot" value="true" />
<splash-screens />
</watch-application>
<shortcut-list />
<privileges>
<privilege>http://tizen.org/privilege/alarm.set</privilege>
<privilege>http://tizen.org/privilege/healthinfo</privilege>
</privileges>
<provides-appdefined-privileges />
<feature name="http://tizen.org/feature/battery">true</feature>
<feature name="http://tizen.org/feature/sensor.heart_rate_monitor">true</feature>
</manifest>