1. 개요
- 심박동 수와 스트레스 지수 표시를 위한 생체 정보 수집 필요
- 생체 정보 수집을 위해 겔럭시 워치를 사용하여 생체정보를 수집 -> 안드로이드 기기에 전달 해주어야 함
- 정보전달을 위해, 겔럭시 워치용 앱 (타이젠 기반)을 개발해야 하며, 안드로이드 앱 또한 개발해야 함.
=> 안드로이드 SDK 버전호환이 중요할것으로 보임. (STT 안드로이드 모듈과의 호환)
2. 갤럭시 워치 제품 정보 (제품 상세정보가 삼성페이지게 없음. 링크 연결이 안됨)
* 갤럭시 워치 시리즈가 최신 제품
- 갤럭시 기어 S3
- 스트레스 지수 표시 - 삼성 헬스 앱에서 별도로 계산하여 표시하는듯 함
- 심박수 측정
- 운영체제 : 타이젠 4.0
- 갤럭시 기어 Fit2 Pro
- 심박수 측정
- 스트레스 지수 표시 - 삼성 헬스 앱에서 별도로 계산하여 표시하는듯 함
- 운영체제 : 타이젠 2.3
- 갤럭시 워치 액티브2
- 스트레스 지수 표시 - 삼성 헬스 앱에서 별도로 계산하여 표시하는듯 함
- 심박수 측정
- 운영체제 : 타이젠 4.0
- 갤럭시 워치
- 스트레스 지수 표시 - 삼성 헬스 앱에서 별도로 계산하여 표시하는듯 함
- 심박수 측정
- 운영체제 : 타이젠 4.0
- 갤럭시 핏
- 심박수 체크
- 스트레스 체크 (안드로이드 앱으로 전달 가능한 여부는 아직 모름)
- 운영체제 : freeRTOS 로, 외부 앱 개발을 지원치 않는듯함.
3. 타이젠
- 모바일, 웨어러블, TV, 냉장고 등 삼성, 인텔, 리눅스에서 합작하여 만든 OS
- 리눅스 커널을 사용하는 오픈소스 프로젝트로, 실제 사용처는 많지 않음
- 바다 OS를 대체함
- 안드로이드 apk파일을 실행 할 수 없음. (단, 오픈 모바일에서 ACL을 통해 타이젠 앱으로 변환가능)
- 개발 : C 또는 C++의 네이티브 언어 개발 및 HTML5를 통한 웹개발 가능
- C++이 가능하긴하나, OOP 기반이 아니라 C와 다를바가 없음. 메인은 C
- Garbage Collection이 되지않아, 개발자가 일일히 해주어야 함.
* 타이젠 3.0 이상부터는 C#을 통한 개발 가능 (자마린 형태)
* 비쥬얼 스튜디오 개발시, debug breakpoint 동작 안함
* 중요 : 타이젠 , 안드로이드 둘다 동일한 service profile을 가지고 있어야 함. (6.1, 7.2 참조)
- 툴 : 비쥬얼 스튜디오 타이젠 익스텐션 및 자마린 기반 앱 개발 환경 가능
- 타이젠 스튜디오 : 이클립스 기반으로, 윈도우, 리눅스, Mac에서 앱개발 가능
- 이클립스 기반이라 자바 환경 구축해야 하나, Java 언어랑은 상관이 없고 사용할 수 없음.
4. 비쥬얼 스튜디오 타이젠 익스텐션
- 타이젠 3 이상부터 지원하며 C#으로 개발 가능
- 최신버전의 JDK 필요 (64bit지원)
- Visual Studio Marketplace 이동 -> Tizen Extension 설치
-> 도구 -> 확장 및 업데이트 -> 온라인 -> Visual Studio Marketplace -> 검색을 통한 설치
- 설치 후 도구 -> Tizen -> Tizen Package Manager 실행 -> Install new Tizen SDK클릭하여 SDK 설치
-> 환경에 맞는 항목 추가 설치 (wearable 관련 sdk등)
- 환경설정 추가
-> 제어판 -> 시스템 -> 고급 시스템 설정 -> 환경 변수 클릭
-> 시스템 변수 -> 새로만들기 -> 변수 이름에 CLASSPATH 입력 -> 변수 값에 %classpath%;, 입력
-> 시스템 변수 -> 새로만들기 -> 변수 이름에 JAVA_HOME 입력 -> 변수 값에 실제 java sdk 설치 위치 입력 (예 : C:\Program Files\Java\jdk1.8.0_171)
-> 시스템 변수 -> 리스트 에서 Path 선택 -> 편집 선택 -> 새로 만들기 선택 -> %JAVA_HOME%\bin 입력 후 확인
- 애뮬레이터 실행
- Cmos 에서 cpu -> 가상화 옵션 켜야 함 (Virtual Tech)(각 메인보드별 상이 하기때문에, 자체 검색 필요)
- Hyper-V 가 꺼 있어야 함.
- 시작 -> 프로그램 및 기능 -> 윈도우 기능 켜기/끄기 -> Hyper-V 체크 해제
- 비쥬얼 스튜디오 -> 도구 -> Tizen -> Tizen Enulator Manager 실행
- 에뮬레이터 선택 -> Edit -> HW Support -> CPU VT, GPU 모두 On 으로 설정
- 에뮬레이터 요구사항
5. 인증서 생성
- https://developer.samsung.com/galaxy-watch-develop/getting-certificates/create.html 참조
- 인증서에는 범용, 삼성 인증서가 따로 있으며, 삼성 기기에 설치를 위해선 삼성 인증서 발급 받아야 함.
* 비주얼 스튜디오 -> 도구 -> Tizen -> Tizen Package Manager -> Extension SDK에 Samsung 관련된 SDK 설치
- 비주얼 스튜디오 -> 도구 -> Tizen -> Tizen Certificate Manager 실행
-> Ceritificate Profile 추가 -> 우측 Samsung 클릭 -> Mobile/Wearable 선택 후 다음 클릭
-> Create a new certificate profile 선택 후, 명칭 입력 후 다음 클릭
-> Create a new author certificate 선택 후 다음 클릭
-> Author Name, Password 입력 후 다음 클릭
-> 삼성 계정에 로그인 혹은 회원 가입 후 로그인
-> backup path 설정 후 다음 클릭
-> Create a new distributor certificate 선택 후 다음 클릭
-> 하단 Add individual DUIDs 에 값 입력 후 다음 클릭
-> 비주얼 스튜디오 -> 도구 -> 옵션 -> Tizen -> Certification 클릭
-> Sing the .TPK file using the following option 에 체크
-> Use profile of Tizen Certificate Manager 선택
-> Profile -> Profile Path 확인 및 Profile 에, 위에서 추가한 active된 samsung certificate를 선택
* DUID는 기기 고유 정보로서, PC와 연결하면 자동으로 등록됨. 이를 등록해야만 기기에 앱 설치가 가능함.
* 인증서 생성기 실행 불가시, 설치경로로 이동하여 eclipse.exe 실행
6. 갤럭시 워치 프로젝트 생성
- 비주얼슈트디오 -> 파일 -> 새로만들기 -> 프로젝트 -> Visual C# -> Tizen 4.0 선택
- Tizen Watchface App 혹은 Black App 등 원하는 항목 선택
- 코드 개발은 Provider (서버 개념) 과 Consumer (클라이언트 개념) 으로 나뉨.
- (삼성 sap api 문서) https://img-developer.samsung.com/onlinedocs/gear/Tizen_SAP/namespaceSamsung_1_1Sap.html
- 솔루션 탐색기 -> 마우스 우클릭 -> Nuget 패키지 관리 -> 찾아보기 -> samsung.sap 설치 (프로젝트 생성시 마다 해줘야함)
* 겔럭시 워치앱 또는 watchface 로 프로젝트를 개발하면 안되며, 반드시 widget으로 개발할것.
=> 워치에서 개발중인 어플을 직접 실행하려면 widget으로 개발해야함. 6.8. 참조
6.1. Profile 추가
- 안드로이드와 통신을 위해 반드시 필요
- /res/xml 폴더 (없으면 생성) 에 accessoryservices.xml 파일 생성
=> /res/xml 폴더 마우스 우클릭 -> 추가 -> 새항목 -> 데이터 -> xml 파일 선택 후 파일명 입력 -> 추가
- 아래의 xml 내용 추가. application 명칭 변경 칠요하며, service profile id 는 unique한 값으로 입력해야함.
=> tizen-manifest.xml -> overview 에 기록되어 있는 application id와 같은것으로 입력. 단 '.' 을 '/'로 변경
=> /로 시작하며, 0~9까지의 숫자, a ~ z 까지 영문자와 _가 허용되며, 구분자로 / 를 사용함. 최대길이 30자
<?xml version="1.0" encoding="utf-8"?>
<resources>
<application name="MyApplication">
<serviceProfile id="/org/example/myapp/my_message" name="MyMessage"
role="consumer" version="1.0">
<supportedTransports>
<transport type="TRANSPORT_BT"/>
<transport type="TRANSPORT_WIFI"/>
</supportedTransports>
<serviceChannel id="110" dataRate="low" priority="low"
reliability="enable">
</serviceChannel>
<supportedFeatures>
<feature type="message" />
</supportedFeatures>
</serviceProfile>
</application>
</resources>
- tizen-manifest.xml 더블 클릭 -> advanced 클릭 -> add 클릭
- key 에 accessory-services-location 입력, value에 해당 파일 위치 (/res/xml/accessoryservices.xml)입력
6.2. Previlege 추가
- tizen-manifest.xml 더블 클릭 -> previleges 클릭 -> add 클릭
- custom previlige 선택 후 http://developer.samsung.com/tizen/privilege/accessoryprotocol 입력
- tizen-manifest.xml 더블 클릭 -> previleges 클릭 -> add 클릭 -> platform defined 에서 원하는 항목 선택 후 추가
* Display On을 위해 다음을 추가 : <privilege>http://tizen.org/privilege/display</privilege>
<privilege>http://tizen.org/privilege/systemsettings</privilege>
6.3. api 사용 using
- using Samsung.Sap; 추가 (삼성에서 제공하는 별도의 api)
- 패키지가 없을경우, 비주얼 스튜디오 -> 도구 -> Nuget Package 관리자 -> 솔루션용 Nuget 패키지 관리 -> 찾아보기 -> samsung 검색
-> samsung sap 설치 (매 프로젝트 마다 설치 필요)
6.4. 센서 값 사용
- using Tizen.Sensor; 추가
- tizen-manifest.xml 더블 클릭 -> previleges 클릭 -> add 클릭 -> healthinfo 추가 필요
- Tizen.Sensor를 보면, 각 센서 클래스가 있음.
- var sensor = new 센서클래스명(); 으로 메모리 할당
* 앱설치시, manifest에서 권한을 줬음에도 불구하고, 설정 -> 앱 ->권한 -> 설치된 앱 선택 -> 센서 권한 허용해야함
6.4.1. 센서 이벤트
- sensor변수명.DataUpdated 이벤트를 통해 데이터 값을 받을 수 있음.
- 이벤트 인자값은 센서마다 다른듯 함.
- sensor변수명.Start()를 통해 센서 시작
- sensor변수명.Interval 에 값을 배정함으로서 주기를 설정할 수 있음. (miliseconds)
=> 1초가 적절한 주기로 생각됨. 주기 시간이 짦을경우 app crash 발생함.
- sensor변수명.PausePolicy에 SensorPausePolicy enum값 배정으로 일시정지 정책 설정 가능
=> 예 : SensorPausePolicy.DisplayOff. None 설정시 계속 동작
=> None으로 설정해야함!!
- sensor변수명.Stop()을 통해 센서 중지. 이벤트 추가 한것도 제거해주어야 함. Dispose 호출도 필요.
* 심박수 이벤트의 경우 이벤트 인자값이 int 임. (심박수)
6.4.2. 센서 종류
- Tizen 기준이므로, 실제 기기들이 다 지원하지는 않음. 각 기기 스펙별로 확인 필요
- try catch 구현, catch 문에 NotSupportedException 수신될 경우, 지원되지 않는 센서임.
- https://docs.tizen.org/application/dotnet/guides/location-sensors/device-sensors 에 지원 전체 센서 목록 있음
6.4.3. 디스플레이 강제 on
- display를 항상 강제로 on 할 필요가 있을경우 사용
- DllImport를 통해 DevicePowerRequestLock 함수를 호출함.
- 6.2. 권한 참조하여 추가해야함.
- 1번째 인자값
- 1 : cpu 전원 off 막음
- 2 : display normal
- 3 : display dim
- 함수 리턴값
=> 0 : 정상
=> -22 : invalid parameter
=> -13 : permission denied
=> -0x01140000 또는 0x01 : operation failed
// Main 함수가 있는 프로그램 진입점 클래스에 다음을 추가
[DllImport("libcapi-system-device.so.0", EntryPoint = "device_power_request_lock", CallingConvention = CallingConvention.Cdecl)]
internal static extern int DevicePowerRequestLock(int type, int timeout_ms);
[DllImport("libcapi-system-device.so.0", EntryPoint = "device_power_release_lock", CallingConvention = CallingConvention.Cdecl)]
internal static extern int DevicePowerReleaseLock(int type);
//main 함수에 다음을 추가
// ret 값에 따라 오류 판별
int ret = DevicePowerRequestLock(1, 0);
6.5. 샘플 프로젝트
- 비주얼슈트디오 -> 파일 -> 새로만들기 -> 프로젝트 -> Visual C# -> Tizen 4.0 선택 으로 프로젝트 생성시,
6.5.1. 구조
- 프로젝트명.cs : 메인 진입점
- 기본 이벤트 함수들이 연결되어 있음.
- xxxx.xaml : UI 설정 xaml 파일
- xxxx.xaml.cs : xaml 과 연동되는 코드
- xxxViewModel.cs : UI와 연결되는 ViewModel. binding 연결 등 담당함. PropertyChanged 이벤트 구현되어 있음.
6.5.2. xaml 에 바인딩 예
- Text="{Binding Path=ViewModel에 있는 변수명, Mode=OneWay, UpdateSourceEventName=PropertyChanged}"
- ViewModel에 있는 변수명은 Public으로 선언되어 있어야 하며, Get, Set이 있어야 하고, Set의 경우 OnPropertyChanged 호출해주어야 UI 업데이트가 잘됨
- 예 :
public string _hr;
public string HR
{
get
{
return _hr;
}
set
{
_hr = value;
OnPropertyChanged("HR");
}
}
6.6. 안드로이드 기기 연결
- 삼성 API를 사용하여 안드로이드 기기와 연결. 안드로이드 기기측에서도 삼성 API를 사용하는 어플리케이션 개발이 이루어 져야 함.
- 6.1, 6.2, 6.3 을 수행 한 후에 진행.
- 첨부파일에 첨부된 SAccessoryService_Emul.apk 를 휴대폰에 설치하여 연결테스트 진행 가능
- 샘플 apk를 이용한 연결 참조 : https://developer.samsung.com/galaxy-watch-develop/creating-your-first-app/net-companion/galaxy-watch-emulator.html
//consumer
private async void Connect()
{
try
{
//getagent의 인자값 : accesoryservice.xml 에 적어놓은 serviceprofile id
//tizen-manifest.xml의 application id = accesoryservice.xml 의 serviceprofile id와 동일
Agent = await Agent.GetAgent(Samsung.Sap.Service.Profiles.First());
var peers = await Agent.FindPeers();
if (peers.Count() > 0)
{
var peer = peers.First();
Connection = peer.Connection;
Connection.DataReceived -= Connection_DataReceived;
Connection.DataReceived += Connection_DataReceived;
Connection.StatusChanged -= Connection_StatusChanged;
Connection.StatusChanged += Connection_StatusChanged;
await Connection.Open();
}
else
{
//연결 대상 찾지못함
}
}
catch (Exception ex)
{
//오류발생
}
}
private void Connection_StatusChanged(object sender, ConnectionStatusEventArgs e)
{
if(e.Reason != ConnectionStatus.Connected)
{
Tizen.Log.Debug("tag", "disconnected");
}
else
{
Tizen.Log.Debug("tag", "connected");
}
}
private void Connection_DataReceived(object sender, DataReceivedEventArgs e)
{
//메세지 수신부
}
private async void SendMessage(Peer peer, string message)
{
if (peer == null || peer.Status != PeerStatus.Found)
return;
await peer.SendMessage(Encoding.UTF8.GetBytes(message));
}
private void CloseConnection(Peer peer)
{
peer.Connection.Close();
}
6.7. 워치에 빌드앱 설치 (PC에서 빌드 - 기기에 설치)
- 참조 : https://developer.samsung.com/galaxy-watch-develop/testing-your-app-on-galaxy-watch.html
- wifi를 통해 연결 필요.
6.7.1. PC 세팅
- wifi 동글 필요 혹은 동일 ap에 접속 필요.
- 제어판 -> Windows Defender 방화벽 -> 고급 설정 -> 인바운드 규칙 -> 새 규칙 -> 포트
-> 다음 클릭 -> TCP 선택 -> 특정 로컬 포트에 26101 입력 -> 연결 허용 선택 -> 이름 입력 후 확인
* UDP에서도 동일한 세팅 필요.
* 제어판 -> Windows Defender 방화벽 -> 고급 설정 -> 아웃바운드 규칙 에도 동일한 설정 필요
6.7.2. 겔럭시 워치 세팅
- 워치 기기 -> 세팅 -> 워치 정보 -> 디버깅 켬
- 워치 기기 -> 세팅 -> 워치정보 -> 소프트웨어 -> 소프트웨어 버전을 5번 터치 시 개발자 옵션 켜짐
- PC와 동일 네트워크 혹은 PC에 wifi 동글 동작 -> 워치에서 해당 wifi 접속
- 비주얼 스튜디오 -> 도구 -> Tizen -> Tizen Device Manager 실행 -> 우측 3개의 아이콘중 가운데의 Remote Device Manager 실행
-> 스캔 버튼 클릭 -> 연결 버튼 클릭
- 비주얼 스튜디오 -> 도구 -> Tizen -> sdb command prompt 실행
- sdb devices 로 연결됨을 확인
- sdb connect ip주소 입력시 is already connected 표시됨을 확인
* 연결이 안될경우 워치 재부팅, 설정된 remote device 에서 목록 삭제 후 재 검색 등 수행
* connect 시 워치에 허용 메세지창이 뜨는데, 수락해주어야 함. 가끔 안뜰때가 있는데, 재부팅, 재접속 후 재 시도 등 해볼것
6.7.3. 앱 설치
- 비주얼 스튜디오 -> 도구 -> Tizen -> sdb command prompt 실행
- sdb install 설치파일 (tpk 확장자를 가짐)
* sdb 는 tizen 스튜디오 -> tools 에 있음. 이 위치에 tpk 파일을 위치해놓고 실행
* 계정 정보에 certificate 가 되어 있는지 확인할것. 5. 인증서 생성 참조
6.8. Widget
- 워치에 설치한 어플리케이션을 직접 실행할 방법을 찾지 못함.
- Widget 어플리케이션 만이 워치에서 개발중인 앱을 단독 실행 가능함.
6.8.1. 필수구성
- 프로젝트 마우스 우클릭 -> nuget package 관리 -> 찾아보기 -> Tizen.Wearable.CircularUI 검색 후 설치
- 프로젝트 마우스 우클릭 -> 추가 -> 새항목 -> 사용자 정의 컨트롤 (WPF) 선택 후 추가 (system 참조 오류 발생하나, 무시)
6.8.1.1. 기본 프로젝트 구성파일
- ViewModel.cs 파일 (필수는 아님 MVVM 패턴에 사용되는 부분)
- xaml 파일 2개
=> 프로그램 메인진입점 UI 페이지
=> 실제 UI 개발 페이지
- 각 xaml과 연결되는 xaml.cs 파일 2개
- 프로젝트명.cs 파일
=> 프로그램 최초 진입점
- tizen-manifest.xml 수정 필수
6.8.1.2. 메인 진입점 xaml
- 빈 껍데기만 있는 형태
- 예 :
<?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="TizenWatchfaceApp2.UserControl1">
</Application>
6.8.1.3. 메인 진입점 xaml.cs
- 실제 UI가 표시되는 클래스를 메인페이지에 연결
- 예 :
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
namespace TizenWatchfaceApp2
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class UserControl1 : Application
{
public UserControl1(ClockViewModel viewModel)
{
InitializeComponent();
MainPage = new TextWatchApplication(viewModel);
}
protected override void OnStart()
{
// Handle when your app starts
}
protected override void OnSleep()
{
// Handle when your app sleeps
}
protected override void OnResume()
{
// Handle when your app resumes
}
}
}
6.8.1.4. 실제 UI xaml
- 실제 UI가 표시되는 페이지
- Tizen CircleUI를 활용함. 따라서 해당 네임스페이스 추가해야함
- 기본 구조 :
<?xml version="1.0" encoding="utf-8" ?>
<c:CirclePage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:c="clr-namespace:Tizen.Wearable.CircularUI.Forms;assembly=Tizen.Wearable.CircularUI.Forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="네임스페이스.연동클래스명">
<c:CirclePage.Content>
<AbsoluteLayout>
<ContentView AbsoluteLayout.LayoutBounds="0, 0, 1, 1" AbsoluteLayout.LayoutFlags="All">
<StackLayout>
<!-- 이곳에 UI 개발 -->
</StackLayout>
</ContentView>
</AbsoluteLayout>
</c:CirclePage.Content>
</c:CirclePage>
6.8.1.5. 실제 UI xaml.cs
- 실제 UI가 표시되는 페이지와 연동하여 동작 코드 개발. 기존 wpf와 크게 다르지 않음.
6.8.1.6. 프로그램 메인 진입점.cs (프로젝트명.cs)
- 실제 프로그램 메인 진입점으로, 어플리케이션 실행을 담당
- 6.8.1.2. 와 6.8.1.3. 에서 기술한 메인UI를 실행시킴
- FormsWidgetBase 상속받은 클래스와 FormsWidgetApplication 상속받은 클래스로 구성됨.
- 예 :
using System;
using System.Timers;
using Tizen.Applications;
using Tizen.Wearable.CircularUI.Forms.Renderer;
using Tizen.Wearable.CircularUI.Forms.Renderer.Watchface;
using Tizen.Wearable.CircularUI.Forms.Renderer.Widget;
using Xamarin.Forms;
namespace TizenWatchfaceApp2
{
class 클래스명_A: FormsWidgetBase
{
public override void OnCreate(Bundle content, int w, int h)
{
base.OnCreate(content, w, h);
var 메인진입점 변수 = new 메인진입점클래스명();
LoadApplication(메인진입점 변수);
}
}
class 클래스명_B: FormsWidgetApplication
{
public 클래스명_B(Type type) : base(type)
{
}
static void Main(string[] args)
{
var app = new 클래스명_B(typeof(클래스명_A));
Forms.Init(app);
FormsCircularUI.Init();
app.Run(args);
}
}
}
6.8.1.7. tizen-manifest.xml 수정
- 해당파일 선택 -> 마우스 우클릭 -> 다른 프로그램으로 열기 -> xml(텍스트) 자동편집기 선택 후 확인 클릭
- <manifest> 하위에 <xxxx-application>을 <widget-application> 태그로 변경해야함.
-> 어트리뷰트 exec="프로젝트명.dll" update-period="0" 추가
- <widget-application> 하위에 <support-size preview="파일명.png">2x2</support-size> 추가
- <manifest> 하위에 <background-category value="sensor" /> 추가
- 예 :
<?xml version="1.0" encoding="utf-8"?>
<manifest package="org.tizen.example.TizenWatchfaceApp2" version="1.0.0" api-version="4" xmlns="http://tizen.org/ns/packages">
<author>park</author>
<profile name="wearable" />
<background-category value="sensor" />
<widget-application appid="org.tizen.example.TizenWatchfaceApp2" exec="TizenWatchfaceApp2.dll" update-period="0" type="dotnet">
<label>TizenWatchfaceApp2</label>
<icon>TizenWatchfaceApp2.png</icon>
<metadata key="http://tizen.org/metadata/prefer_dotnet_aot" value="true" />
<support-size preview="TizenWatchfaceApp2.png">2x2</support-size>
<metadata key="accessory-services-location" value="/res/xml/accessoryservices.xml" />
<splash-screens />
</widget-application>
<shortcut-list />
<privileges>
<privilege>http://tizen.org/privilege/alarm.set</privilege>
<privilege>http://developer.samsung.com/tizen/privilege/accessoryprotocol</privilege>
<privilege>http://tizen.org/privilege/content.write</privilege>
<privilege>http://tizen.org/privilege/bluetooth</privilege>
<privilege>http://tizen.org/privilege/datasharing</privilege>
<privilege>http://tizen.org/privilege/healthinfo</privilege>
<privilege>http://tizen.org/privilege/network.get</privilege>
<privilege>http://tizen.org/privilege/internet</privilege>
<privilege>http://tizen.org/privilege/network.profile</privilege>
<privilege>http://tizen.org/privilege/network.set</privilege>
<privilege>http://tizen.org/privilege/wifidirect</privilege>
<privilege>http://tizen.org/privilege/widget.viewer</privilege>
</privileges>
<provides-appdefined-privileges />
</manifest>
6.9. 유용한 shell 명령어
- 비주얼 스튜디오 -> 도구 -> Tizen -> Tizen Device Manager 실행
- 현재 동작중인 장비 선택 -> 마우스 우클릭 -> shell prompt 로 각종 명령어를 입력할 수 있음.
- pkginfo --listpkg : 설치된 패키지목록을 보여줌. uninstall 할때 패키지명 확인을 위해 필요.
7. 안드로이드 앱 (워치와 통신)
- https://developer.samsung.com/galaxy-watch-develop/techdoc/how-to-use-samsung-accessory-sdk.html 참조
- (샘플 코드 및 menifest 세팅) https://developer.samsung.com/galaxy-watch-develop/creating-your-first-app/net-companion/use-accessory.html
- 첨부파일 중, AccessorySDK 다운로드 필요
- 코드 개발은 Provider (서버 개념) 과 Consumer (클라이언트 개념) 으로 나뉨.
- 첨부파일인 ProgrammingGuide_Accessory pdf 문서 참조
- 안드로이드 4.4.2 이상 필요하며, 2개의 jar파일 포함해야함.
- accessory-v2.3.0.jar, sdk-v1.0.0.jar
7.1. AndroidManifest.xml 수정
7.1.1. Permission
<uses-permission
android:name="com.samsung.android.providers.context.permission.WRITE_USE_APP_FEATURE_SURV
EY"/>
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="com.samsung.accessory.permission.ACCESSORY_FRAMEWORK"/>
7.1.2. 그외
<application>
<service android:name="com.example.myapplication.ProviderService" />
<meta-data
android:name="AccessoryServicesLocation"
android:value="/res/xml/accessoryservices.xml" /> <!-- 실제 accessoryservices.xml 위치-->
<receiver android:name="com.samsung.android.sdk.accessory.RegisterUponInstallReceiver">
<intent-filter>
<action android:name="com.samsung.accessory.action.REGISTER_AGENT" />
</intent-filter>
</receiver>
<receiver android:name="com.samsung.android.sdk.accessory.ServiceConnectionIndicationBroadcastReceiver">
<intent-filter>
<action android:name="com.samsung.accessory.action.SERVICE_CONNECTION_REQUESTED" />
</intent-filter>
</receiver>
</application>
7.2. accessoryservices.xml 추가
- res/xml 에 추가 (7.1.2. 의 <meta-data> 태그 -> android:value 와 연관됨)
<!-- accessoryservices.xml 예시 -->
<?xml version="1.0" encoding="utf-8"?>
<resources>
<application name="MyApplication">
<serviceProfile
id="/org/example/myapp/my_message"
name="myapplication"
role="provider"
serviceImpl="com.example.myapplication.ProviderService"
version="1.0"
serviceLimit="ANY"
serviceTimeout="10">
<supportedTransports>
<transport type="TRANSPORT_BT" />
<transport type="TRANSPORT_WIFI" />
</supportedTransports>
<supportedFeatures>
<feature type="message" />
</supportedFeatures>
<serviceChannel
id="110"
dataRate="low"
priority="low"
reliability= "enable"/>
</serviceProfile>
</application>
</resources>
<!-- application name은 안드로이드 appname을 보통 사용함 -->
<!-- serviceProfile name, id는 아무거나 적어도 되는듯함. id의 경우 watch app의 규정과 동일 -->
<!-- serviceProfile의 role 에 provider, consumer 설정을 함 -->
7.3. Android app 코드
7.3.1. Import
- 기본으로, import com.samsung.android.sdk.accessory.*; 추가.
- 파일전송 사용시, import com.samsung.android.sdk.accessoryfiletransfer.*;
import com.samsung.android.sdk.accessoryfiletransfer.SAFileTransfer.*;
추가
7.3.2. 코드
class HelloAccessoryProvider extends SAAgent
{
...
void onCreate() {
Create SA;
try
{
Initialize SA;
}
catch (Exception e)
{
// Error Handling
}
}
void onStart() {
// Find Peer Agent
FindPeerAgent();
}
void onFindPeerAgentsResponse(SAPeerAgent []
peerAgents, int result) {
// Store found Peer Agent if success
if (result == PEER_AGENT_FOUND)
{
for (SAPeerAgent peerAgent : peerAgents)
Cache(peerAgent);
}
}
void onServiceConnectionRequested(SAPeerAgent peerAgent) {
// Received service connection request from remote, decide whether to accept or to reject.
Accept(peerAgent);
}
void onServiceConnectionResponse(SAPeerAgent peerAgent, SASocket socket, int result) {
// if result is successful, cache socket for using on sending message
Cache(socket);
}
class ServiceConnection extends SASocket
{
void onReceive(int channelId, byte[]
data) {
// Check received data
Parse(data);
// Create a worker thread and send message to Consumer
Create WorkerThread(
message = composeMessage();
CachedSocket.Send(channel id, message);
);
}
void onServiceConnectionLost(int errorCode) {
// Reset cached peer agent and close service connection
ResetCache();
Close();
}
void onError(int channelId, String errorString, int error) {
// Error handling
}
}
...
}
//consumer
class HelloAccessoryConsumer extends SAAgent
{
...
void onCreate() {
Create SA;
try
{
Initialize SA;
}
catch (Exception e)
{
// Error Handling
}
}
void onStart() {
// Find Peer Agent
FindPeerAgent();
}
void onFindPeerAgentsResponse(SAPeerAgent []
peerAgents, int result) {
// Store found Peer Agent if success
if (result == PEER_AGENT_FOUND)
{
for (SAPeerAgent peerAgent : peerAgents)
{
Cache(peerAgent);
RequestServiceConnection(peerAgent);
}
}
}
void onServiceConnectionResponse(SAPeerAgent peerAgent, SASocket socket, int result) {
// if result is successful, cache socket for using on sending message
Cache(socket);
Create WorkerThread(
try
{
message = composeMessage();
Send(channel id, message);
}
catch (Exception e)
{
// Error handling
}
);
}
class ServiceConnection extends SASocket
{
public void onReceive(int channelId, byte[] data)
{
// Check received data
Parse(data);
// Create a worker thread and show message to user
Create WorkerThread(
Show(message);
);
}
void onServiceConnectionLost(int errorCode)
{
// Reset cached peer agent and close service connection
ResetCache();
Close();
}
void onError(int channelId, String errorString, int error)
{
// Error handling
}
}
...
}
7.4. 빌드세팅
- gradle 설정에서, compileSdkVersion 24로 설정, minSdkVersion은 21로 설정 (혹시 모를 stt 모듈과의 호환성)
그외 오류시, dependencies -> com.android.support:appcompat-v7:24.2.1 로 설정 후 빌드
7.4.1. Gradle 설정 예
8. 로그
- 기존에 사용하던 Console.Write 나, Debug.Write 는 동작하지 않음.
- Tizen.Log 클래스를 활용하여 로그 작성을 해야함.
- Tizen.Log.Debug, Info 등 여러 항목이 존재함.
- Tizen.Log.Debug의 경우, (string tag, string message )를 인자로 하여 작성 가능
- 비주얼 스튜디오 -> 도구 -> Tizen -> Tizen Log Viewer 를 통해 확인 가능.
- 필터 기능을 통해 원하는 로그만 볼 수 있음 (예 : 태그명)
- 비주얼 스튜디오 디버깅 모드 실행시에만 확인가능
999. 참조
- 타이젠 개발 : http://preview.hanbit.co.kr/2764/sample_ebook.pdf
https://mintpot.synology.me:30000/issues/1309
https://cyberx.tistory.com/158
https://docs.tizen.org/application/dotnet/tutorials/overview
- https://developer.samsung.com/galaxy-watch-develop
- https://img-developer.samsung.com/onlinedocs/gear/Tizen_SAP/namespaceSamsung_1_1Sap.html
'기타 기술들(Unity 관련)' 카테고리의 다른 글
| 구글, 네이버 TTS 내용정리 (0) | 2022.03.24 |
|---|---|
| Git 서브모듈 관련 사용법 (0) | 2022.03.24 |
| 아쿠아라이더 VR 프로젝트 결과 (0) | 2022.03.24 |
| Android 기기 정보 취득 방법 (0) | 2022.03.24 |
| MTP(SDCard) 파일 및 폴더 제어 (0) | 2022.03.24 |