BackgroundDownloader 이용해서 로컬에 다운로드 받기

 

두번째 삽질의 내용이다. 리스트로 이미지를 보여 줄 때는 BitmapImage에 UriSource 프로퍼티에 주소를 넣어 주는 것이 가장 성능이 좋은 듯하다. 그러나, 상세 보기로 들어가면 약간 큰 이미지를 매번 네트워크로 받아 오도록 하는 것이 정말 좋은 방법인가에 대해 고민을 하다가, 일단 임시 폴더에 다운로드를 받고 이미지를 보여 주도록 했다.

 

 

참고 포스트

Downloading Files with BackgroundDownloader in Windows Store Apps – Boredom Challenge Day 6

http://eren.ws/2013/10/10/downloading-files-with-backgrounddownloader-in-windows-store-apps-boredom-challenge-day-6/ 

 

Migrating your Windows Phone app from the Background Transfer Service to the converged Windows.Networking.BackgroundTransfer API

http://blogs.windows.com/buildingapps/2014/05/29/migrating-your-windows-phone-app-from-the-background-transfer-service-to-the-converged-windows-networking-backgroundtransfer-api/

 

 

일단 아래 사진을 보면 상세 화면으로 들어 왔을 때 웹에서 처음에 불러왔던 작은 이미지를 보여주다가 다운로드가 완료되면, 깨끗한 이미지로 바꾸어 준다.

 

Before 

 After

 

음 이렇게 구현하기 까지도 많은 삽질이 있었는데...

 

그 중에 제일 큰 삽질이 어제 저녁에 집에서 개발 할때 Windows Phone 8.1 RT에서 다운로드가 잘 되던 사진들이 오늘 다시 시도해 보니 다운로드가 않되는 것이다.

 

 

그래서, 다운로드가 완료되지 않은 DownloadOperation이 존재해서 그런가하고, 아래 코드를 추가했다.

이 코드는 혹시라도 BackgroundDownloader를 사용하여 다운로드를 받고 있었는데, 알 수 없는 이유(?)로 앱이 죽어서, 앱을 다시 시작했을 때, 이전에 다운로드를 받던 DownloadOperation을 다시 시작하거나, 취소하기 위한 작업이다.

 

 

        private CancellationTokenSource _cancellationToken;

 

        private async void Init()
        {
            _cancellationToken = new CancellationTokenSource();

            //이전 응용 프로그램에서 사용하던 DownloadOperation 목록 조회

            var downloads = await BackgroundDownloader.GetCurrentDownloadsAsync();
            foreach (var download in downloads)
            {
                try
                {

                    //다운로드 작업 취소
                    download.AttachAsync().Cancel();

                    //연결된 파일 삭제
                    await download.ResultFile.DeleteAsync();

                    //다운로드 재시작(?) 참고 포스트 1번 내용 확인
                    //await download.AttachAsync().AsTask(_cancellationToken.Token);
                }
                catch (Exception ex)
                {
                    Debug.WriteLine(ex.Message);
                }
            }

        }

 

기능을 넣고 다시 실행보니 남아 있는 녀석들이 존재한다. 후후 모두 작업 취소!!

원드라이브의 사진 경로는 일정 시간이 지나면 변경되기 때문에 취소하고 다시 받는 것이 좋다.

 

으흠..그렇게 했는데도 여전히 다운로드 않됨;;

그래서 다시 방황의 시간을 보내던 중 참고 포스트 2번을 발견해서 읽음.. 대충 읽어 내려가다가 표를 보고나서 음음 생각에 잠김

 

Scenario

UnrestrictedOnly

Default

Always

Wi-Fi

Allow

Allow

Allow

Metered connection, not roaming, under data limit, on track to stay under limit

Deny

Allow

Allow

Metered connection, not roaming, under data limit, on track to exceed limit

Deny

Deny

Allow

Metered connection, roaming, under data limit

Deny

Deny

Allow

Metered connection, over data limit. This state only occurs when the user enables “Restrict background data in the Data Sense UI.

Deny

Deny

Deny

 

처음에는 그냥 그런가보다 했는데.. 어제 집에서는 분명 Wi-Fi에 붙어있었는데, 낮에는 붙어 있지 않은...으아~~

 

기본적으로 DownloadOperation을 만들면, CostPolicy가 UnrestrictedOnly로 지정이 되어있다. 그래서, Wi-Fi가 아니면 다운로드 보류 중이 걸려서 다운로드가 않되었던 것이다.

 

ㅜㅜ 이런거 미리미리 알려주면 않되는 것이냐고!!

 

 

DownloadOperation download = _backgroundDownloader.CreateDownload(new Uri(imageUri, UriKind.Absolute), localFile);
download.CostPolicy = BackgroundTransferCostPolicy.Always;

 

      await download.StartAsync();
      bi.UriSource = new Uri(Path.Combine(ApplicationData.Current.TemporaryFolder.Path, filename));

 

그래서 CostPolicy를 Always로 입력하는 코드를 한 줄 추가하고, 다운로드가 정상적으로 되었다. 그나마 다행인 것은 한 2시간 정도만 삽질했다는 것이다.

 

 

다운로드 받는 전체 코드이다.

 

 

        private async Task<bool> DownloadImage(string imageUri, string filename, BitmapImage bi)
        {
            //로컬파일 만들고
            IStorageFile localFile =
                await
                    ApplicationData.Current.TemporaryFolder.CreateFileAsync(filename,
                        CreationCollisionOption.ReplaceExisting);


            DownloadOperation download = _backgroundDownloader.CreateDownload(new Uri(imageUri, UriKind.Absolute), localFile);
            download.CostPolicy = BackgroundTransferCostPolicy.Always;

            bool hasDownloadError = false;
            try
            {
                await download.StartAsync();
                bi.UriSource = new Uri(Path.Combine(ApplicationData.Current.TemporaryFolder.Path, filename));
            }
            catch (Exception ex)
            {
                hasDownloadError = true;
                Debug.WriteLine(ex.Message);
            }

            if (hasDownloadError)
            {
                download.AttachAsync().Cancel();
                await localFile.DeleteAsync();
            }
            return hasDownloadError;
        }

블로그 이미지

kaki104

/// Microsoft MVP - Windows Development - Apr 2014 ~ Mar 2018 /// email : kaki104@daum.net, twitter : @kaki104, facebook : https://www.facebook.com/kaki104 https://www.facebook.com/groups/w10app/

티스토리 툴바