티스토리 뷰

반응형

MSDN의 셈플 프로젝트를 보면 Tile sample과 BackgroundTask sample이 각 각 존재 하지만, Live Tile을 구현하는 예제는 없다. 그래서, 이번에 2가지의 셈플 프로젝트를 참고해서 LiveTile을 만들어 보도록 하겠다.

 

* 참고

Introduction to Background Tasks(꼭 읽어보도록 한다)

http://www.microsoft.com/en-us/download/details.aspx?id=27411

 

Background task sample

http://code.msdn.microsoft.com/windowsapps/Background-Task-Sample-9209ade9

 

App tiles and badges sample

http://code.msdn.microsoft.com/windowsapps/App-tiles-and-badges-sample-5fc49148

 

Visual Studio 2012 Debuging tip

http://kaki104.tistory.com/entry/Visual-Studio-2012-Debuging-tip

 

Syndication sample

http://code.msdn.microsoft.com/windowsapps/Syndication-sample-07ef6b0d

 

Example Metro app /WinRT: background task that uppdates internet connection and metering (roaming) information based on network changes -> 시스템 트리거를 이용한 포스트인데 정리가 잘되어있네요

http://www.irisclasson.com/2012/07/04/example-metro-app-winrt-background-task-that-uppdates-internet-connection-and-metering-roaming-information-based-on-network-changes/comment-page-1/#comment-4104

 

WinRT: Example of Using Periodic Notifications for Live Tiles

http://mikaelkoskinen.net/winrt-example-of-using-periodic-notifications-for-live-tiles

 

 

 

 

1. 솔루션 구성

 

1) Split App template project 생성 - 메인 앱

2) Class Library 추가 - RSS Reading, Tile Update 작업용

3) Windows Runtime Component 추가 - BackgroundTask 용

4) App tiles and badges sample 프로젝트에 포함되어있는 NotificationsExtensions 추가

 

* 레퍼런스는 프로젝트 참고

 

2. RssReaderViewModel.cs

RSS 피드를 읽어오는 기능을 한다.

 

namespace BackgroundLiveTileSample.CL
{
    public class RssReaderViewModel : BindableBase
    {
        SyndicationClient client;

        private static RssReaderViewModel instance;
        //인스턴스 객체
        public static RssReaderViewModel Instance
        {
            get
            {
                if (instance == null)
                {
                    instance = new RssReaderViewModel();
                }
                return instance;
            }
        }

        private SyndicationFeed currentFeed;
        /// <summary>
        /// 현재 피드
        /// </summary>
        public SyndicationFeed CurrentFeed
        {
            get { return currentFeed; }
            set
            {
                currentFeed = value;
                OnPropertyChanged();
            }
        }

        public RssReaderViewModel()
        {
            client = new SyndicationClient();
            client.BypassCacheOnRetrieve = true;
            client.SetRequestHeader("User-Agent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)");
        }

        public async Task<bool> GetFeed(Uri feedUri)
        {
            try
            {
                CurrentFeed = await client.RetrieveFeedAsync(feedUri);
                return true;
            }
            catch (Exception ex)
            {
                return false;
            }
        }
    }
}

 

3. ItemsPageViewModel.cs

 

namespace BackgroundLiveTileSample
{
    public class ItemsPageViewModel : BackgroundLiveTileSample.CL.BindableBase
    {
        const string feedUri = "http://web2.ruliweb.daum.net/daum/rss.htm?bbs=1&id=547&bbsId=G007&c1=6&c2=5";

        public RssReaderViewModel RssReader { get; set; }

        public ItemsPageViewModel()
        {
            RssReader = RssReaderViewModel.Instance;
        }

        public async void GetFeed()
        {
            var result = await RssReader.GetFeed(new Uri(feedUri));
            if (result == true)
            {
            }
        }
    }
}

 

4. ItemsPage.xaml.cs

 

namespace BackgroundLiveTileSample
{
    public sealed partial class ItemsPage : BackgroundLiveTileSample.Common.LayoutAwarePage
    {
        public ItemsPageViewModel ViewModel
        {
            get { return this.DataContext as ItemsPageViewModel; }
            set
            {
                this.DataContext = value;
            }
        }

        public ItemsPage()
        {
            this.InitializeComponent();

            ViewModel = new ItemsPageViewModel();
            ViewModel.GetFeed();

            if (Windows.ApplicationModel.DesignMode.DesignModeEnabled == true)
            {
            }
            else
            {
            }

        }

        protected override void LoadState(Object navigationParameter, Dictionary<String, Object> pageState)
        {
            //ViewModel.GetFeed();
        }

        void ItemView_ItemClick(object sender, ItemClickEventArgs e)
        {

            //아이템 클릭하면 브라우저 실행시켜서 보여준다.
            SyndicationItem item = e.ClickedItem as SyndicationItem;
            if (item != null)
            {
                var link = item.Links.FirstOrDefault();
                Launcher.LaunchUriAsync(link.Uri);
            }
        }
    }
}

 

xaml과 ItemTemplate는 소스를 참고

 

5. TileUpdateTask.cs

 

namespace BackgroundLiveTileSample.BackgroundTasks
{
    public sealed class TileUpdateTask : IBackgroundTask
    {
        const string feedUri = "http://web2.ruliweb.daum.net/daum/rss.htm?bbs=1&id=547&bbsId=G007&c1=6&c2=5";

        BackgroundTaskDeferral _deferral = null;

        RssReaderViewModel RssReader;

        //백그라운드테스크 이벤트 처리부분
        public async void Run(IBackgroundTaskInstance taskInstance)
        {
            // Get the deferral object from the task instance, and take a reference to the taskInstance;
            _deferral = taskInstance.GetDeferral();

            RssReader = RssReaderViewModel.Instance;

            var result = await RssReader.GetFeed(new Uri(feedUri));
            if (result == true)
            {
                UpdateTile();
            }
            //백그라운드 작업 완료
            _deferral.Complete();
        }

        //타일 업데이트
        public void UpdateTile()
        {
            //타일 로테이션 가능하도록 변경
            TileUpdateManager.CreateTileUpdaterForApplication().EnableNotificationQueue(true);

            foreach (var item in RssReader.CurrentFeed.Items.Take(5))
            {
                //큰타일
                ITileWideText09 tileContent = TileContentFactory.CreateTileWideText09();
                tileContent.TextHeading.Text = item.Title.Text;
                tileContent.TextBodyWrap.Text = item.Summary.Text;

                //작은타일
                ITileSquareText02 squareContent = TileContentFactory.CreateTileSquareText02();
                squareContent.TextHeading.Text = item.Title.Text;
                squareContent.TextBodyWrap.Text = item.Summary.Text;
                tileContent.SquareContent = squareContent;

                //타일노티 만들고
                TileNotification tileNotification = tileContent.CreateNotification();
                //tileNotification.Tag = item.Id;

                //센드 타일
                TileUpdateManager.CreateTileUpdaterForApplication().Update(tileNotification);
            }
        }
    }
}

 

6. BackgroundTaskUtil.cs

백그라운드 테스크를 등록하거나 해지하는 유틸

 

namespace BackgroundLiveTileSample
{
    class BackgroundTaskUtil
    {
        public const string BackgroundTaskEntryPoint = "BackgroundLiveTileSample.BackgroundTasks.TileUpdateTask";
        public const string BackgroundTaskName = "TileUpdateTask";
        public static bool BackgroundTaskRegistered = false;

        /// <summary>
        /// Register a background task with the specified taskEntryPoint, name, trigger,
        /// and condition (optional).
        /// </summary>
        /// <param name="taskEntryPoint">Task entry point for the background task.</param>
        /// <param name="name">A name for the background task.</param>
        /// <param name="trigger">The trigger for the background task.</param>
        /// <param name="condition">An optional conditional event that must be true for the task to fire.</param>
        public static BackgroundTaskRegistration RegisterBackgroundTask(String taskEntryPoint, String name, IBackgroundTrigger trigger, IBackgroundCondition condition)
        {
            var builder = new BackgroundTaskBuilder();

            builder.Name = name;
            builder.TaskEntryPoint = taskEntryPoint;
            builder.SetTrigger(trigger);

            if (condition != null)
            {
                builder.AddCondition(condition);
            }

            BackgroundTaskRegistration task = builder.Register();

            UpdateBackgroundTaskStatus(name, true);

            //
            // Remove previous completion status from local settings.
            //
            var settings = ApplicationData.Current.LocalSettings;
            settings.Values.Remove(name);

            return task;
        }

        /// <summary>
        /// Unregister background tasks with specified name.
        /// </summary>
        /// <param name="name">Name of the background task to unregister.</param>
        public static void UnregisterBackgroundTasks(string name)
        {
            //
            // Loop through all background tasks and unregister any with SampleBackgroundTaskName or
            // SampleBackgroundTaskWithConditionName.
            //
            foreach (var cur in BackgroundTaskRegistration.AllTasks)
            {
                if (cur.Value.Name == name)
                {
                    cur.Value.Unregister(true);
                }
            }

            UpdateBackgroundTaskStatus(name, false);
        }

        /// <summary>
        /// Store the registration status of a background task with a given name.
        /// </summary>
        /// <param name="name">Name of background task to store registration status for.</param>
        /// <param name="registered">TRUE if registered, FALSE if unregistered.</param>
        public static void UpdateBackgroundTaskStatus(String name, bool registered)
        {
            switch (name)
            {
                case BackgroundTaskName:
                    BackgroundTaskRegistered = registered;
                    break;
            }
        }

        /// <summary>
        /// Get the registration / completion status of the background task with
        /// given name.
        /// </summary>
        /// <param name="name">Name of background task to retreive registration status.</param>
        public static String GetBackgroundTaskStatus(String name)
        {
            var registered = false;
            switch (name)
            {
                case BackgroundTaskName:
                    registered = BackgroundTaskRegistered;
                    break;
            }

            var status = registered ? "Registered" : "Unregistered";

            var settings = ApplicationData.Current.LocalSettings;
            if (settings.Values.ContainsKey(name))
            {
                status += " - " + settings.Values[name].ToString();
            }

            return status;
        }
    }
}

 

7. App.xaml.cs

 

OnLaunched 메소드에

 

                //백그라운드 테스크 등록
                RegisterBackgroundTask();

 

하단에 메소드 추가

 

        /// <summary>
        /// 백그라운드 테스크 등록
        /// </summary>
        private async void RegisterBackgroundTask()
        {
            //백그라운드 등록 서비스 알림
            await BackgroundExecutionManager.RequestAccessAsync();
            //백그라운드 서비스 등록해제
            BackgroundTaskUtil.UnregisterBackgroundTasks(BackgroundTaskUtil.BackgroundTaskName);
            //백그라운드 서비스 등록(15분 간격으로 발생, 인터넷이 연결되어있을때만 실행)
            var task = BackgroundTaskUtil.RegisterBackgroundTask(BackgroundTaskUtil.BackgroundTaskEntryPoint,
                                                                   BackgroundTaskUtil.BackgroundTaskName,
                                                                   new TimeTrigger(15, false),
                                                                   new SystemCondition(SystemConditionType.InternetAvailable));
        }

 

8. 타일 노티피케이션을 사용하기 위한 작업

 

1) BackgroundLiveTileSample 프로젝트의 Package.appxmanifest open

2) Lock screen notifications -> Badge and Tile Text 선택, Wide logo, Badge logo 추가

(필요한 이미지는 셈플 프로젝에 있는 이미지 복사해서 사용)

3) Declarations -> Background Tasks 추가 -> Properties : Timer 선택 -> App settings , Entry point : BackgroundLiveTileSample.BackgroundTasks.TileUpdateTask 입력

 

9. 실행

처음 실행하면 아래와 같이 확인 창이 출력된다. 허용을 클릭한다.

 

 

앱 실행 화면

 

백그라운드 테스크가 디버깅은  상단에 참고에 있는 Visual Studio 2012 Debuging tip 을 참고해서 디버그 실행 중 TileUpdateTask를 선택하면 바로 디버깅을 할 수 있다. 이 방법을 모르면 15분 기다려야 한다는..

 

10. 소스

 

BackgroundLiveTileSample.BackgroundTasks.zip

반응형

'Previous Platforms > Samples' 카테고리의 다른 글

Text file encoding sample  (0) 2012.11.28
WinRT File Based Database sample  (0) 2012.11.12
InputPane using Popup sample  (0) 2012.10.29
GridView item drag&drop move sample  (0) 2012.10.15
ISupportIncrementalLoading Sample  (1) 2012.10.07
댓글