반응형

2018년 첫 회사를 퇴사하고 잠시 앱 개발에 관심을 가졌기에 이미 자주 사용한 C#을 활용할 겸 자마린을 공부했었다.

당시에도 이미 국내 자마린 카페가 서서히 죽어가고 있었는데, 그래도 온라인 강의도 있기는 있었으니 사용자는 있었다.

하지만 Fluter 의 등장으로 많은 자마린 개발자들이 옮기는 흔적들이 곳곳에 있었는데, 2024년에는 개발자들 사이에서는 사실상 죽은 프레임 워크 취급을 하는 것 같다.

Xamarin.Form 이 죽을 수 밖에 없는 이유에 대해서 생각을 해보면 그럴만한 것이 Xamarin.Form 이 동작하는 구조는 각 안드로이드, iOS, (그리고 Windows phone)를 감싼형태의 프레임워크였고, 하나의 소스코드를 사용한다고 하지만, 이것이 완전하지 않았다. 그리고 C#의 언어적으로 막는 이중 참조 구조가 필수적으로 필요한 구조가 되었기 때문에 2번씩 빌드해야 적용되는 경우도 발생했다.

따라서 신경써야 할 것이 많은 프레임 워크였고, 다른 경쟁 프레임 워크에 비해서 경쟁력이 떨어졌다(특히 Fluter). MS 에서 C# 언어 자체를 발전 시킨것처럼 지속적으로 발전을 시켰으면 다행이었겠지만, 그러지 않았다. 아마 구글링을 해도 2018년 기점으로 새롭게 올라운 글이 많이 않을 것이다.

아 물론 MS사 웹사이트를 빼고

반응형
반응형

무선 디버그(wireless debug)

무선 디버그가 필요한 경우

일반적으로 안드로이드 개발을 할 경우 유선으로 연결된 상태에서 디버그를 진행을 한다. 하지만, OTG와 같이 다른 장비에 연결 상태에서 디버그를 진행해야 하는 경우에는 무선으로 디버그를 해야 한다.

ADB 디버그 툴

Android Studio에서는 무선 디버그 용도로 ADB를 활용할 수 있다. adb는 안드로이드 스튜디오를 설치할대 sdk가 설치된 폴더안의 platform-tools라는 폴더 안에 있다.

안드로이드 스튜디오에서 터미널 창을 연다음에 해당 경로로 이동한다.

만약 sdk 경로를 바꾼적이 없다면,윈도우즈 기준으로 아래의 경로로 접근하면 된다.

c:\user\[사용자 계정명]\AppData\Local\Android\sdk\platform-tools

형식의 경로에 있다.

필자의 경우

c:\user\hp\AppData\Local\Android\sdk\platform-tools

만약 경로를 바꾼적이 있는데 기억이 잘 나지 않는다면, tools -> sdk manager 로 창을 연다음에 android sdk 항목으로 보면 android sdk가 설치된 경로를 확인할 수 있다.

무선 환경 설정

다음 명령어로 유선에 연결된 안드로이드 장치를 확인할 수 있다.

adb devices

만약 아무것도 보이지 않는다면, 선을 다시 연결하고, 장치 접근이 허용이 되었는지 확인하자.

다음 명령어로 안드로이드 장치에서 디버그에 사용할 포트를 열어주자

adb tcpip [port]

필자의 경우는 다음과 같이 하였다.

adb tcpip 11000

다음 안드로이드 장치의 무선 ip 주소를 파악을 해야한다. 안드로이드 장치에서 직접 알아내는 방법이 있다. 하지만, adb에서는 안드로이드 장치가 연결된 상태에서는 shell로 접근이 가능하다.

adb shell

해당 shell 리눅스의 shell과 비슷한 방식이기 때문에 ifconfig 명령어로 무선 ip 주소(wlan0)를 파악 하면 된다.

$ifconfig
wlan0     Link encap:UNSPEC    Driver wcnss_wlan
          inet addr:192.xxx.xxx.xxx  Bcast:192.168.0.255  Mask:255.255.255.0
          inet6 addr: xxxx::xxxx:xxxx:xxxx:xxxx/64 Scope: Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:1896200 errors:0 dropped:0 overruns:0 frame:0
          TX packets:1695900 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:889329097 TX bytes:459419469
~중략~
$exit

유닉스 계열 터미널과 같은 환경이다. 위의 wlan0(무선)의 inet addr이 있는 주소를 확인했으면, exit로 shell을 빠져나온다.

여기까지 마쳤다면, 이제 안드로이드 장치에 연결된 유선을 제거한 다음에 adb를 연결을 하면 된다.

adb connect [ip]:[port]

필자의 경우

adb connect 192.168.1.136:11000

연결이 되면, connected to 이하 메시지를 보여준다. 이제 이 상태에서 안드로이드 스튜디오에서 디버그를 실행하면, 마치 유선으로 연결된 것과 같이 똑같이 반응을 한다.

참조

회사 대표님의 조언

반응형

'Mobile Develop > (Android)JAVA' 카테고리의 다른 글

[Android]Magic Number와 String 관리  (0) 2020.02.12
반응형

Basic class 문법

Java와 관계

Java는 처음 등장시 하나의 언어로 모든 플랫폼에서 동작한다는 철학으로 처음 큰 관심을 받았고, 현재는 가장 많은 개발자들이 현업에서 사용하고 있는 언어이다. 이러한 특징때문에 구글의 안드로이드는 Java를 개발지원 언어로 채택하여서 단기간에 ios 개발 생태계를 따라잡게 된다(인해전술로).

문제는 Java는 본래 임베디드(세탁기, 전자렌지 같은 것들)를 위해 설계된 언어였고, 썬마이크로즈를 오라클에서 인수하면서 오라클사의 소유이다. 때문에 Java 오라클과 구글간 분쟁이 있었고 오라클이 재판에서 승소를 하게 되었다. 하지만, 젯브레인즈(JetBrains)사에서 구글과 협력하여 kotlin(러시아 샹트페테부르크의 앞의 섬 이름)이 등장하게 된다.

안드로이드에서 Java를 대체하고자 하는 영향도 컸으며, 안드로이드에 특화된 언어라서 Java 코드를 kotlin으로 변환하는 것도 가능하다. 즉, 안드로이드 한정으로 Java로 된 것은 kotlin으로도 가능하다(아직 필자가 low수준까지 해보지 않아 확신 못하나 그렇게들 설명하고 있다).

class

코틀린(kotlin)은 안드로이드 한정으로 자바(Java) 대체 가능한 언어기 때문에 같은 개념인 클래스가 존재한다.

클래스의 상속

자바와 반대로 코틀린은 기본적으로 상속이 금지이다. 상속을 가능하게 하기 위해서는 open 키워드를 사용한다. 프로그래밍 언어에서 특정 키워드를 추가하여 허용을 한다는 것은 해당 동작에 대해서 보수적인 것을 뜻하기도 한다.

open class Animal {
    // contents
}

class Dog : Animal {
    // contents
}

인자를 받는 생성자가 있는 클래스를 상속하는 경우 초기화 상속도 가능하다.

open class Animal(val name : String) {
}

class Dog(name: String) : Animal(name) {
}

내부 클래스

클래스 내에서 클래스를 사용하는 경우 inner 라는 키워드를 앞에 붙여 줘야 한다. 이는 기존의 가독성 문제를 보완하기 위한 것으로 생각된다.

class OuterClass {
    var a = 10

    inner class OuterClass2 {
        fun someThing() {
            a = 20
        }
    }
}

추상 클래스

자바와 비슷하게. abstract 키워드를 사용한다.

abstract class A {
    abstract fun func()

    fun func2() {

    }
}

class B : A() {
    overide fun func() {
        println("hello")
    }
}

val b = B()

참고 자료

서적: 오준석의 안드로이드 생존코딩(코틀린편)

반응형
반응형

Magic Number와 String 관리

작성 계기

 처음부터 내가 작성한 앱은 아니지만, 문자열과 상수들이 Magic Number를 관리하는 클래스에 작성이 되어 있는 것을 보고 기겁을 하였다. 무엇보다 목록이 많은 프로젝트였는데, 그 많은 목록을 일일히 타이핑을 했다는 것에 대해서 대단하게 느껴졌다. 하지만, 고객사에서는 추후라도 해외 진출도 생각을 하고 있는 것으로 보이므로 힘들지만, Magic Number와 번역 가능성이 있는 것들을 분리하기로 했다.

그리고 하는김에 분리하는 기준에 대해서 작성하다 보니 일반적인 표준이 될 것 같기 때문에 정리하여 기록을 남긴다.

Magic Number

 Magic Number는 프로그램을 개발을 하다보면 상수로 자주 사용되는 값을 말한다. 특히 string 같은 문자열의 경우 ""를 사용해서 상수형 문자열의 내용이 같으나 자주 선언을 하게 되면, 선언한 횟수 만큼 메모리를 점유하게 된다(물론 최근에는 최적화 기술이 발달해서 알아서 최적화 해줄 가능성도 크다). 또한 해당 문자열이 유지보수 과정에서 수정되어야 하는 경우에는 수정해야 하는 문자열을 찾는 과정은 상당한 일이 된다.

 따라서 대부분 초급 이상의 개발자들은 이러한 Magic Number을 특별한 네임스페이스에 따로 관리를 한다. 그리고 프로그램 실행중에는 변하지 않지만 준 Magic Number에 해당이 되는 것은 Cofigure 같은 설정값을 들 수 있다. 이러한 값들도 특별한 네임스페이스에서 관리하는 것이 개발 후반으로 갈 수 록 정신건강에 좋다.

value/string 리소스

 공식 안드로이드 개발자 가이드라인에서는 다국어 지원 서비스를 원활하게 하기 위해서는 문자열을 res/value/string.xml 에 작성하기를 권장하고 있다. 그리고 다른 언어에 대해서는 한국어에 대해서는 res/value-ko/string.xml 형식으로 관리가 된다. 물론 프로젝트 관리 메뉴에서는 string 파일이 2개로 보인다. 또한 단순히 언어만 구분을 짓는 것이 아니라 기기, 화면 비율 등에 따라서 문자열을 다르게 조절할 수 있다(자세한 것은 공식 가이드라인을 참조)

Magic Number와 value/string 리소스 구분 기준

 로직을 구현하는 문자열의 경우에는 언어에 상관이 없는 문자열들은 코드상 Magic Number로 간주하고 관리하는 것이 좋다(모드, 기능명, 분기 같은 문자열은 Magic Number로 간주).

 JAVA에서는 switch문에서 문자열로 구분을 할 수 있는 기능들이 있다. 이 switch문에서 case로 입력 받는 값은 상수형이어야 한다. 그러나 리소스에서 가져온 문자열은 일반 문자열이기 때문에 바로 swith문의 분기로 사용할 수 없다. 당연한 이야기지만, 언어가 바뀌면, 기준도 바뀌는 위험이 있기 때문이다.

덤, error: unescaped apostrophe in string 에러

종종 string.xml 에 "'"가 있는 경우에 발생하는 에러이다. 해당 문자열을 ""으로 감싸주거나, ' 앞에 \을 붙여주면 된다.

반응형

'Mobile Develop > (Android)JAVA' 카테고리의 다른 글

[Android Studio]무선 디버그(wireless debug)  (0) 2020.03.25
반응형

Xamarin.Form : 안드로이드 에뮬레이터 HAX Module 에러

접하게 된 배경

무슨 잘 못을 했는지 모르겠지만, Xamarin.Form을 공부하려고 할 때 마다 안드로이드 에뮬레이터 문제가 항상 있었왔다.

 VS 2017과는 독립적으로 안드로이드 에뮬레이터(AVD Manager)는 독립적인 툴이다. 때문에 안드로이드 스튜디오를 설치를 해도 설치가 된다. 가상 기기를 구성한 것을 제대로 기동하기 위해서는 Android SDK 에서 적합한 버전을 준비해야 한다.

 여기까지 무사히 마치고 테스트에 사용할 가상 기기를 생성한뒤에 실행해서 잘되면 다행이지만, 실행이 안되는 경우가 있다.


 필자의 경우 다음과 같은 에러 메시지를 보여준 다음에 실행이 안되었다.





해결 방법

 항상 에러 메시지를 자세히 읽어 보면 답이 있다. 필자의 경우 Device Manager에서 HAX Module version 이 낮다고 하는데, 이게 뭔지 몰라서 다시 설치해보고 업데이트를 시작해 보았지만, 해결이 안되었었다. 알고보니 HAXM 이라는 인텔에서 제공하는 패치를 직접 해야한다.


필자는 haxm-windows_v7_2_0 버전을 다운로드 받았다.


인텔 HAXM 패치 페이지 링크


 구글에서 HAX module version 을 키워드로 친다음에 검색된 인텔 웹 페이지에 접속해서 다운로드 받아서 설치해도 된다. 설치방법은 그냥 다운로드 받은 압축파일의 압축을 해제하고 안에 있는 배치파일을 실행하거나 intelhaxm-android.exe를 실행하면 된다.


 개인적인 생각에는 MS에서 자동으로 업데이트를 제공해 주었으면 좋았을 텐데 아쉬운 점이 있다.


참고자료

이 양반의 블로그로 해당 모듈의 정체를 알게 되었다.



반응형
반응형

Xamarin.Form : 빠른 시작(첫 앱 만들기)

작성 배경

 Xamarin.Form가 나온지 시간이 괘 지났음에도 한글문서가 많지 않은 것같다. 사실 튜토리얼에 있는 영문문서가 읽기에 어려운 편은 아니다. 그러나 단의 영어로 되어 있다는 점때문에 진입장벽이 생기는 것 같아서 틈틈히 정리를 한다. 물론 정리하다가 중단하게 될 수 도 있으리라...


 본문의 내용은 Xamarin.form 공식 웹페이지의 Getting Started -> Hello, Xamarin.Form -> part 1: Quickstart를 약간의 번역과 의역을 첨가하여 작성한다.



Xamain.Forms 빠른 시작


프로젝트 만들기

새프로젝트 항목 중 Visual C# 하위 목록중에서 Cross-platform를 선택을 하면 우측 괄호에 Xamarin.Form이 보이는 항목을 클릭한다.


프로젝트 이름은 "Phoneword" 로 한다.


실제 여러개의 프로젝트가 하나의 앱을 만듣는 것이기 때문에 가급적 솔루션용 폴더를 체크하도록 한다.


확인 버튼을 클릭을 하면, 크로스플래폼 앱에 대해서 세부 설정을 할 수 있다. "Blank App"을 선택하고 .NET Standard를 선택을 하고 프로젝트를 생성한다.


(먼저 Androd 프로젝트의 MainActivity.cs 파일을 열어보고 에러 메시지가 뜨는지 확인을 해야한다. Xamarin.Form이 메이저 버전이 업데이트 되면서 일부 호환이 되지 않아서 에러가 나는 경우가 있는데, 이때는 미련없이 재설치를 하자.)


여러개의 프로젝트중에서 Phoneword 프로젝트내의 MainPage.xaml을 열고 다음과 같이 수정한다.


<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
                   xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                   x:Class="Phoneword.MainPage">
    <ContentPage.Padding>
        <OnPlatform x:TypeArguments="Thickness">
            <On Platform="iOS" Value="20, 40, 20, 20" />
            <On Platform="Android, WinPhone, Windows" Value="20" />
        </OnPlatform>
    </ContentPage.Padding>
    <StackLayout>
      <Label Text="Enter a Phoneword:" />
      <Entry x:Name="phoneNumberText" Text="1-855-XAMARIN" />
      <Button x:Name="translateButon" Text="Translate" Clicked="OnTranslate" />
      <Button x:Name="callButton" Text="Call" IsEnabled="false" Clicked="OnCall" />
    </StackLayout>
</ContentPage>


변경이 끝나면, 저장(Ctrl + s)을 한다.


이제 솔루션 탐색기(Solution Explorer)의 (+)버튼을 누르면 같은 이름의 MainPage.xaml.cs 파일이 보인다(혹은 소스코드 열기로 확인할 수 있음). 해당 파일을 수정한다.


 단, 주의 해야 할점이 에러가 발생하는 코드가 있는데, 이는 진행하면서 해결하니 조급해하지 말자.


MainPage.xaml.cs 입력받은 숫자문자를 숫자로 변환을 해주는 기능이다.


using System;
using Xamarin.Forms;

namespace Phoneword
{
    public partial class MainPage : ContentPage
    {
        string translatedNumber;

        public MainPage ()
        {
            InitializeComponent ();
        }

        void OnTranslate (object sender, EventArgs e)
        {
            translatedNumber = Core.PhonewordTranslator.ToNumber (phoneNumberText.Text);
            if (!string.IsNullOrWhiteSpace (translatedNumber)) {
                callButton.IsEnabled = true;
                callButton.Text = "Call " + translatedNumber;
            } else {
                callButton.IsEnabled = false;
                callButton.Text = "Call";
            }
        }

        async void OnCall (object sender, EventArgs e)
        {
            if (await this.DisplayAlert (
                    "Dial a Number",
                    "Would you like to call " + translatedNumber + "?",
                    "Yes",
                    "No")) {
                var dialer = DependencyService.Get<IDialer> ();
                if (dialer != null)
                    dialer.Dial (translatedNumber);
            }
        }
    }
}


에러 메시지에 겁먹지 말고 Ctrl + s 를 클릭하여 변경사항을 저장한다.


 같은 솔루션 탐색기에서 같은 프로젝트의 App.xaml 하위에 있는 App.xaml.cs를 열고 아래와 같이 수정을 한다.


using Xamarin.Forms;
using Xamarin.Forms.Xaml;

[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
namespace Phoneword
{
    public partial class App : Application
    {
        public App()
        {
            InitializeComponent();
            MainPage = new MainPage();
        }

        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
        }
    }
}


역시 변경사항을 저장한다.


솔루션 탐색기에서 Phoneword 프로젝트에서 마우스 우클릭을 하여 추가(Add)에서 새항목(New Item)을 선택한다.


 Visual C#의 code 항목에서 클래스(Class)를 선택하고 이름을 "PhoneTranslator"로 작성하고 추가(Add)한다.


생성된 PhoneTranslator.cs를 다음과 같이 수정한다.

(이때 주의 할 점이 namespace 이름을 바꾼다는 것을 간과 하지 말자)


using System.Text;

namespace Core
{
    public static class PhonewordTranslator
    {
        public static string ToNumber(string raw)
        {
            if (string.IsNullOrWhiteSpace(raw))
                return null;

            raw = raw.ToUpperInvariant();

            var newNumber = new StringBuilder();
            foreach (var c in raw)
            {
                if (" -0123456789".Contains(c))
                    newNumber.Append(c);
                else
                {
                    var result = TranslateToNumber(c);
                    if (result != null)
                        newNumber.Append(result);
                    // Bad character?
                    else
                        return null;
                }
            }
            return newNumber.ToString();
        }

        static bool Contains(this string keyString, char c)
        {
            return keyString.IndexOf(c) >= 0;
        }

        static readonly string[] digits = {
            "ABC", "DEF", "GHI", "JKL", "MNO", "PQRS", "TUV", "WXYZ"
        };

        static int? TranslateToNumber(char c)
        {
            for (int i = 0; i < digits.Length; i++)
            {
                if (digits[i].Contains(c))
                    return 2 + i;
            }
            return null;
        }
    }
}


작성이 완료되었으면, 역시 저장한다.


Phoneword 프로젝트에 이번에는 Interface를 추가한다. 방법은 방금전과 마찬가지로 솔루션 탐색기에서 Phoneword 프로젝트에서 "우클릭 >> 추가 >> 새 항목" Visual C#의 code 인터페이스(interface)를 선택한뒤 IDialer로 이름을 적고 생성한다.


코드는 다음과 같이 수정한다.


namespace Phoneword
{
    public interface IDialer
    {
        bool Dial(string number);
    }
}


이 코드는 나중에 다른 프로젝트들에서 상속한다. 역시 저장을 한다.



이제, Dialer를 상속하자. 솔루션 탐색기에서 Phoneword.iOS 프로젝트에 우클릭을 한뒤에 "추가"에서 "새 항목"을 선택한다.


 새 항목 화면에서 Apple의 하위의 code를 선택하고, 클래스(Class)를 선택한다. 이때 클래스가 여러개 보이는데, 처음 보이는 것을 선택하면 된다.


 클래스 명은 "PhoneDialer"로 하여 생성한다.


코드는 다음과 같이 수정한다.


using Foundation;
using Phoneword.iOS;
using UIKit;
using Xamarin.Forms;

[assembly: Dependency(typeof(PhoneDialer))]
namespace Phoneword.iOS
{
    public class PhoneDialer : IDialer
    {
        public bool Dial(string number)
        {
            return UIApplication.SharedApplication.OpenUrl (
                new NSUrl ("tel:" + number));
        }
    }
}


변경이 완료되었으면, 저장을 한다.


이번에는 안드로이드 쪽이다. Phoneword.Android 프로젝트에 우클릭 하고 추가의 새 항목을 선택한다.


추가 창에서 visual C#하위의 Android를 선택한뒤 클래스(Class)를 선택하여 이름을 아까와 동일한 PhoneDialer로 작성하고 생성한다.


아래와 같이 코드를 수정한다(이때 임포트 되는 모듈이 많으므로 빼먹지 않도록 주의한다).


using Android.Content;
using Android.Telephony;
using Phoneword.Droid;
using System.Linq;
using Xamarin.Forms;
using Uri = Android.Net.Uri;

[assembly: Dependency(typeof(PhoneDialer))]
namespace Phoneword.Droid
{
    public class PhoneDialer : IDialer
    {
        public bool Dial(string number)
        {
            var context = MainActivity.Instance;
            if (context == null)
                return false;

            var intent = new Intent (Intent.ActionCall);
            intent.SetData (Uri.Parse ("tel:" + number));

            if (IsIntentAvailable (context, intent)) {
                context.StartActivity (intent);
                return true;
            }

            return false;
        }

        public static bool IsIntentAvailable(Context context, Intent intent)
        {
            var packageManager = context.PackageManager;

            var list = packageManager.QueryIntentServices (intent, 0)
                .Union (packageManager.QueryIntentActivities (intent, 0));

            if (list.Any ())
                return true;

            var manager = TelephonyManager.FromContext (context);
            return manager.PhoneType != PhoneType.None;
        }
    }
}


변경이 완료되었으면 저장을 한다.



솔루션 탐색기에서 Phoneword.Android 프로젝트를 더블 클릭하여 MainActivity.cs 파일을 열어서 다음과 같이 수정한다(원문은 더블클릭하라고 했지만, 해당되는 이름의 파일을 클릭해도 된다).


using Android.App;
using Android.Content.PM;
using Android.OS;

namespace Phoneword.Droid
{
    [Activity(Label = "Phoneword", Icon = "@drawable/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
    public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {
        internal static MainActivity Instance { get; private set; }

        protected override void OnCreate(Bundle bundle)
        {
            TabLayoutResource = Resource.Layout.Tabbar;
            ToolbarResource = Resource.Layout.Toolbar;

            base.OnCreate(bundle);

            Instance = this;
            global::Xamarin.Forms.Forms.Init(this, bundle);
            LoadApplication(new App());
        }
    }
}


작성이 완료되면 저장을 한다.


Phoneword.Android 프로젝트를 우클릭하여 속성을 선택한다. 속성에서 "Android 매니페스트"(Android Manifest)항목을 선택하고 하단의 Required permissions: 항목중 "CALL_PHONE"항목을 체크한다.


역시 변경되었으면 저장한다.



이제 UWP를 수정하자.

솔루션 탐색기에서 Phoneword.UWP 프로젝트에 우클릭을 한뒤 추가(Add)에 새 항목(New Item)을 선택한다. 선택화면에서는 Visual C# 에서 Code를 선택하여 클래스(Class)를 선택한다. 이름은 PhoneDialer로 작성하여 생성한다.


생성된 클래스는 다음과 같이 작성한다(아직 어셈블리를 추가하지 않았기 때문에 에러가 보이는 경우도 있으나 조급할 필요가 없다).


using Phoneword.UWP;
using System;
using System.Threading.Tasks;
using Windows.ApplicationModel.Calls;
using Windows.UI.Popups;
using Xamarin.Forms;

[assembly: Dependency(typeof(PhoneDialer))]
namespace Phoneword.UWP
{
    public class PhoneDialer : IDialer
    {
        bool dialled = false;

        public bool Dial(string number)
        {
            DialNumber(number);
            return dialled;
        }

        async Task DialNumber(string number)
        {
            var phoneLine = await GetDefaultPhoneLineAsync();
            if (phoneLine != null)
            {
                phoneLine.Dial(number, number);
                dialled = true;
            }
            else
            {
                var dialog = new MessageDialog("No line found to place the call");
                await dialog.ShowAsync();
                dialled = false;
            }
        }

        async Task<PhoneLine> GetDefaultPhoneLineAsync()
        {
            var phoneCallStore = await PhoneCallManager.RequestStoreAsync();
            var lineId = await phoneCallStore.GetDefaultLineAsync();
            return await PhoneLine.FromIdAsync(lineId);
        }
    }
}


변경이 완료되었으면 저장한다.


 프로젝트 탐색기에서 참조(Reference)를 우클릭한뒤 "참조 추가"(Add Reference)를 클릭한다. 

좌특의 Universal Windows의 하위 확장(Extensions)을 클릭한다.


 항목들중 Windows Mobile Extensions for the UWP 모듈 최신(작성시점 10.0.162..)을 체크하고, 확인 버튼을 클릭한다.

(종종 체크가 이미 되어 있는 경우가 있는데 이 때는 변경할 것이 없다.)



Phoneword.UWP 프로젝트 하위의 "Package.appxmanifest" 항목을 연다.

상위 탭버튼 중에 "기능"(Capabilities)를 선택한뒤에 좌측 기능중 "전화 통화"(Phone Call)를 체크 하고 저장한다.



이제 빌드할 시간이다. 먼저 지금까지 작성한 코드중에 에러가 있는지 확인을 해본다. 종종 IDailer를 찾지 못한다는 에러가 보일 수 있는데 이 경우 Phoneword 프로젝트를 빌드를 해주면 된다. Phoneword 프로젝트에 우클릭하여 빌드를 클릭하여 빌드하자.


Phoneword 빌드가 끝나면, 솔루션 탐색기에서 Phoneword.UWP 프로젝트를 우클릭을 한뒤 "시작프로젝트로 설정"(Set as StartUp Project)를 클릭한다. 이제 상단의 녹색화살표가 있는 "로컬 컴퓨터"(Local Machine)를 클릭한다(혹은 단축키 F5).


기다리면, UWP로 빌드된 프로그램이 실행된것을 확인할 수 있다.



참조자료

자바린 공식 페이지(영문)



반응형

+ Recent posts