Windows 8.1 store app 开发笔记

零、简介

  一切都要从博彦之星比赛说起。今年比赛的主题是使用Bing API(主要提到的有Bing Map API、Bing Translate API和Bing AD API)设计移动应用(Windows store app和Windows phone app)。从7月初开始设计到现在,应用的功能已经基本完成,就差美工来给界面优化一下。下面是我设计的应用的功能和实现的方法,

一、BING MAP API

  作为一个以Bing Map API为主的应用,主要有以下的功能:

  1、定位:

 1 private LocationRange range = null;
 2         private CancellationTokenSource cts = null;
 3         private Geolocator geolocator = null;
 4
 5 private async void locateButton_Click(object sender, RoutedEventArgs e)
 6         {
 7             // 根据定位按钮的标签判定是“定位”或“取消定位”
 8             if (locateButton.Label == "定位")
 9             {
10                 locateButton.Label = "取消定位";
11                 try
12                 {
13                     // 获得cancellation token
14                     cts = new CancellationTokenSource();
15                     CancellationToken token = cts.Token;
16                     this.infoBlock.Text = "正在定位";
17
18                     // 获得位置
19                     Geoposition pos = await geolocator.GetGeopositionAsync().AsTask(token);
20                     this.infoBlock.Text = "定位成功";
21                     // App.location是在App.xaml.cs中用于保存定位位置的全局变量
22                     App.location = new Location(pos.Coordinate.Point.Position.Latitude, pos.Coordinate.Point.Position.Longitude);
23
24                     // 设置默认地图缩放等级
25                     double zoomLevel = 13.0f;
26                     // range是一个自定义控件,用一个大圆来涵盖定位区域
27                     MapLayer.SetPosition(range, App.location);
28                     rangeLayer.Children.Add(range);
29                     zoomLevel = 15.0f;
30
31                     // 设置地图视野到给定的位置和缩放等级
32                     map.SetView(App.location, zoomLevel);
33                 }
34                 catch (System.UnauthorizedAccessException)
35                 {
36                     this.infoBlock.Text = "定位请求被拒绝";
37                 }
38                 catch (TaskCanceledException)
39                 {
40                     this.infoBlock.Text = "定位被取消";
41                 }
42                 catch (System.Exception)
43                 {
44                     this.infoBlock.Text = "暂时无法获得您的位置";
45                 }
46                 finally
47                 {
48                     cts = null;
49                 }
50                 // 重置按钮
51                 locateButton.Label = "定位";
52                 //locateButton.Icon = ;
53             }
54             else
55             {
56                 // 取消定位
57                 if (cts != null)
58                 {
59                     cts.Cancel();
60                     cts = null;
61                 }
62                 // 重置按钮
63                 locateButton.Label = "定位";
64                 //locateButton.Icon = ;
65             }
66         }            

locateButton_Click

  2、添加图钉:

 1 private async void AddPinButton_Click(object sender, RoutedEventArgs e)
 2         {
 3             // 实例化一个图钉类(这个图钉类是我自定义的)
 4             pin = new MapediaPin(map);
 5             // 为图钉添加Drag和Tap触发方法(当然还有Hold等)
 6             pin.drag += pin_Dragged;
 7             pin.Tapped += pin_Tapped;
 8             //将图钉显示到地图的中央
 9             MapLayer.SetPosition(pin, map.Center);
10             pinLayer.Children.Add(pin);
11         }

AddPinButton_Click

  3、拖动图钉:

 1 private bool isDragging = false;        // pin正在拖拽标志
 2
 3         // 当pin被拖动时激活
 4         public Action<Location> drag;
 5         // 当pin开始被拖动时激活
 6         public Action<Location> dragStart;
 7         // 当pin停止拖动时激活
 8         public Action<Location> dragEnd;
 9         // 当pin被按下时,得到被按下pin的ID,判断是否可拖动,执行操作
10         protected override void OnPointerPressed(PointerRoutedEventArgs e)
11         {
12             base.OnPointerPressed(e);
13
14             // 如果可以被拖动则开始拖动
15             if (draggable)
16             {
17                 if (map != null)
18                 {
19                     center = map.Center;
20                     // 为map的下列方面重写
21                     map.ViewChanged += map_ViewChanged;
22                     map.PointerReleasedOverride += map_PointerReleased;
23                     map.PointerMovedOverride += map_PointerMoved;
24                 }
25                 // 得到当前鼠标位置
26                 var pointerPosition = e.GetCurrentPoint(map);
27                 Location location = null;
28                 // 开始拖动
29                 if (dragStart != null)
30                 {
31                     dragStart(location);
32                 }
33
34                 this.isDragging = true;
35             }
36         }
37
38         // 当pin被移动时
39         private void map_PointerMoved(object sender, PointerRoutedEventArgs e)
40         {
41             // 检查是否正在被拖动
42             if (this.isDragging)
43             {
44                 // 随着鼠标移动图标
45                 var pointerPosition = e.GetCurrentPoint(map);
46
47                 Location location = null;
48
49                 if (map.TryPixelToLocation(pointerPosition.Position, out location))
50                 {
51                     // 将图钉(this)移到到当前鼠标的位置(location)
52                     MapLayer.SetPosition(this, location);
53                 }
54                 if (drag != null)
55                 {
56                     drag(location);
57                 }
58             }
59         }
60
61         // 当pin被松开时
62         private void map_PointerReleased(object sender, PointerRoutedEventArgs e)
63         {
64             if (this.isDragging)
65             {
66                 if (map != null)
67                 {
68                     map.ViewChanged -= map_ViewChanged;
69                     map.PointerReleasedOverride -= map_PointerReleased;
70                     map.PointerMovedOverride -= map_PointerMoved;
71                 }
72
73                 var pointerPosition = e.GetCurrentPoint(map);
74                 Location location;
75                 map.TryPixelToLocation(pointerPosition.Position, out location);
76                 // 得到最终的经纬度
77                 latitude = location.Latitude;
78                 longitude = location.Longitude;
79
80                 location = null;
81
82                 if (dragEnd != null)
83                 {
84                     dragEnd(location);
85                 }
86
87                 this.isDragging = false;
88                 this.draggable = false;
89             }
90         }

PinDrag

二、BING TRANSLATE API

  用的这个API的地方,是在对图钉上面的信息进行翻译的时候:

  翻译:

 1 private HttpClient client = null;            // 用于通信的HTTP客户端
 2
 3         private async void translateButton_Click(object sender, RoutedEventArgs e)
 4         {
 5             // 根据translateButton的标签判定是“翻译”或“取消翻译”
 6             if (translateButton.Label == "翻译")
 7             {
 8                 // 进行网络检查(方法见 五、UTILITIES)
 9                 if (!App.CheckNetwork())
10                 {
11                     //this.infoBlock.Text = "无网络连接,请检查网络";
12                 }
13                 else
14                 {
15                     try
16                     {
17                         this.infoBlock.Text = "正在检查网络连接...";
18                         string clientID = "你的clientID";
19                         string clientSecret = "你的clientSecret";
20                         //AzureDataMarket可以从网上找到,是一个已经写好的用于在Azure进行验证的类
21                         var _Authentication = new AzureDataMarket(clientID, clientSecret);
22                         AzureDataMarket.Token m_Token = await _Authentication.GetTokenAsync();
23                         string auth = m_Token.Header;
24                         //实例化该类,以便于后面发送Http请求获取网络数据
25                         client = new HttpClient();
26                         //设置读取响应内容时缓冲区的最大字节数
27                         client.MaxResponseContentBufferSize = 256000;
28                         //设置请求头部
29                         client.DefaultRequestHeaders.Add("Authorization", auth);
30                     }
31                     catch
32                     {
33                         //this.infoBlock.Text = "连接到服务器失败";
34                     }
35                 }
36             }
37             else
38             {
39                 this.translateButton.Label = "翻译";
40             }
41         }
42
43         // 将descriptionBlock中的内容翻译成language所表示的语言
44         private async void translate(String language)
45         {
46             //language可表示的语言:ar bg ca zh-CHS zh-CHT cs da nl en et fi fr de el ht he hi mww hu id it ja tlh tlh-Qaak ko lv lt ms mt no fa pl pt ro ru sk sl es sv th tr uk ur vi
47             string url = "http://api.microsofttranslator.com/v2/Http.svc/Translate?text=" + System.Net.WebUtility.UrlEncode(this.descriptionBlock.Text) + "&to=" + language;
48             //try
49             {
50                 string strTranslated = await client.GetStringAsync(url);
51                 XDocument xTranslation = XDocument.Parse(strTranslated);
52                 string strTransText = xTranslation.Root.FirstNode.ToString();
53                 this.titleTranslateBlock.Text = strTransText;
54
55                 this.translateButton.Label = "取消翻译";
56             }
57             //catch (Exception ex)
58             {
59                 //     this.infoBlock.Text = "不能访问Bing Translate API,错误原因:" + ex.Message.ToString();
60             }
61
62         }
63         // 当englishButton按下时,翻译成英语
64         private void englishButton_Click(object sender, RoutedEventArgs e)
65         {
66             translate("en");
67         }
68         // 当simChineseButton按下时,翻译成简体中文
69         private void simChineseButton_Click(object sender, RoutedEventArgs e)
70         {
71             translate("zh-CHS");
72         }

translateButton_Click

三、BING AD API

  待应用......

四、LIVE SDK

  1、登入和登出live帐号:

 1             // live SDK使用范围:登入、获得用户基本信息、使用onedrive上传功能
 2  private readonly string[] scopes = new string[] {
 3             "wl.signin", "wl.basic", "wl.photos", "wl.skydrive", "wl.skydrive_update"};
 4         private LiveAuthClient authClient = null;
 5         private LiveConnectClient liveClient = null;
 6
 7 private void loginButton_Click(object sender, RoutedEventArgs e)
 8         {
 9             // 根据loginButton判定是“登入”或“登出”
10             if (this.loginButton.Label == "登出")
11             {
12                 this.authClient.Logout();
13                 this.loginButton.Label = "Live帐号登入";
14                 this.loginBlock.Text = "未登入";
15             }
16             else
17             {
18                 login();
19             }
20         }
21
22 private async void login()
23         {
24             try
25             {
26                 this.loginButton.IsEnabled = false;
27
28                 this.authClient = new LiveAuthClient();
29                 this.loginBlock.Text = "登入中";
30                 // 登入时显示进度的进度环
31                 this.loginProgress.IsActive = true;
32                 // 检验网络状态
33                 if (App.CheckNetwork())
34                 {
35                     // 得到登入结果
36                     LiveLoginResult loginResult = await this.authClient.LoginAsync(this.scopes);
37                     if (loginResult.Status == LiveConnectSessionStatus.Connected)
38                     {
39                         App.Session = loginResult.Session;
40                         this.liveClient = new LiveConnectClient(loginResult.Session);
41                         LiveOperationResult operationResult = await this.liveClient.GetAsync("me");
42
43                         // 当用户登入后
44                         dynamic meResult = operationResult.Result;
45                         this.loginButton.Label = "登出";
46                         if (meResult.first_name != null && meResult.last_name != null)
47                         {
48                             //显示用户的登录信息
49                             this.loginBlock.Text = "欢迎! " + meResult.first_name + " " + meResult.last_name;
50                         }
51                         else
52                         {
53                             this.loginBlock.Text = "欢迎! ";
54                         }
55                     }
56                     else
57                     {
58                         this.loginBlock.Text = "未登入";
59                     }
60                 }
61                 else
62                 {
63                     this.infoBlock.Text = "无网络连接,请检查网络";
64                     this.loginBlock.Text = "未登入";
65                 }
66             }
67             catch (LiveAuthException)
68             {
69                 this.infoBlock.Text = "登入请求被拒绝";
70             }
71             finally
72             {
73                 // CanLogout为false的情况:应用使用windows已登入的账号时
74                 if (this.loginButton.Label == "登出" && this.authClient != null && !this.authClient.CanLogout)
75                 {
76                     this.loginButton.IsEnabled = false;
77                 }
78                 else
79                 {
80                     this.loginButton.IsEnabled = true;
81                 }
82                 this.loginProgress.IsActive = false;
83             }
84         }

loginButton_Click

  2、上传图片至OneDrive:

 1 private async void syncButton_Click(object sender, RoutedEventArgs e)
 2         {
 3             // App.Session是用来记录当前登入账户的一次会话,登入live帐号之后产生
 4             if (App.Session != null)
 5             {
 6                 // 得到本地的photo文件夹
 7                 IReadOnlyList<StorageFolder> folders = await App.photosFolder.GetFoldersAsync();
 8                 // 在Onedrive中新建一个文件夹,名字为“新建文件夹”
 9                 string skyDriveFolder = await CreateDirectoryAsync("新建文件夹", "me/skydrive");
10                  // 对photo文件夹中的子文件夹进行遍历
11                 foreach (StorageFolder folder in folders)
12                 {
13                     // 获得子文件夹下的所有文件
14         IReadOnlyList<StorageFile> files = await folder.GetFilesAsync();
15                     foreach (StorageFile file in files)
16                     {
17                         // 将文件上传
18         LiveOperationResult result = await liveClient.BackgroundUploadAsync(skyDriveFolder, file.DisplayName + ".jpg", file, OverwriteOption.Overwrite);
19                     }
20                 }
21             }
22         }
23
24 private async Task<string> CreateDirectoryAsync(string folderName, string parentFolder)
25         {
26             string folderId = null;
27             // 查询OneDrive中是否含有folderName文件夹
28             var queryFolder = parentFolder + "/files?filter=folders,albums";
29             var opResult = await liveClient.GetAsync(queryFolder);
30             dynamic result = opResult.Result;
31
32             foreach (dynamic folder in result.data)
33             {
34                 // 如果存在这个文件夹,则返回文件夹名
35                 if (folder.name == folderName)
36                 {
37                     folderId = folder.id;
38                     break;
39                 }
40             }
41
42             if (folderId == null)
43             {
44                 // 不存在则创建
45                 var folderData = new Dictionary<string, object>();
46                 folderData.Add("name", folderName);
47                 opResult = await liveClient.PostAsync(parentFolder, folderData);
48                 result = opResult.Result;
49                 folderId = result.id;
50             }
51
52             return folderId;
53         }

syncButton_Click

五、微博 SDK

  1、连接微博帐号:

 1 private void shareButton_Click(object sender, RoutedEventArgs e)
 2         {
 3             // 检查网络状态
 4             if (App.CheckNetwork())
 5             {
 6                 // 检查该应用是否已和微博连接
 7                 if (App.oauthClient.IsAuthorized == false)
 8                 {
 9                     App.oauthClient.LoginCallback += (isSucces, err, response) =>
10                     {
11                         if (isSucces)                   // 如果成功
12                         {
13                             // TODO: deal the OAuth result.
14                         }
15                         else
16                         {
17                             this.titleBox.Text = err.errMessage;
18                         }
19                     };
20                     App.oauthClient.BeginOAuth();    // 开始验证
21                 }
22             }
23             else
24             {
25                 // no internet.
26             }
27             if (App.oauthClient.IsAuthorized == true)       // 验证成功,开始分享
28             {
29                 // TODO SHARE
30             }
31             else
32             {
33                 this.titleBox.Text = "验证失败";
34             }
35         }

shareButton_Click

  2、发布(带图片)微博

 1 private async void shareWithPhoto(String path)
 2         {
 3             var engine = new SdkNetEngine();
 4             // 微博sdk提供的方法,实例化一个cmd类
 5             ISdkCmdBase cmdBase = new CmdPos    MsgWithPic()
 6             {
 7                 // 发布的文本消息
 8                 Status = shareTextBox.Text,
 9                 // 发布的图片绝对路径
10                 PicPath = path
11             };
12             // 发布微博
13             var result = await engine.RequestCmd(SdkRequestType.POST_MESSAGE_PIC, cmdBase);
14
15  if (result.errCode == SdkErrCode.SUCCESS)
16             {
17                  // 发布成功
18             }
19             // 发布失败
20             else
21             {
22                 // TODO: deal the error.
23                 // 失败的状态码
24                 switch (result.errCode)
25                 {
26                     case SdkErrCode.NET_UNUSUAL: this.descriptionBox.Text = "NET_UNUSUAL"; break;
27                     case SdkErrCode.SERVER_ERR: this.descriptionBox.Text = "SERVER_ERR"; break;
28                     case SdkErrCode.TIMEOUT: this.descriptionBox.Text = "TIMEOUT"; break;
29                     case SdkErrCode.USER_CANCEL: this.descriptionBox.Text = "USER_CANCEL"; break;
30                     case SdkErrCode.XPARAM_ERR: this.descriptionBox.Text = "XPARAM_ERR"; break;
31                 }
32                 this.descriptionBox.Text = result.specificCode;
33             }
34         }

shareWithPhoto

六、UTILITIES

  1、检查网络状态

 1 public static Boolean CheckNetwork()
 2         {
 3             bool isOnline = false;
 4             //获得当前的网络连接状态(using Windows.Networking.Connectivity
 5             ConnectionProfile connectionProfile = NetworkInformation.GetInternetConnectionProfile();
 6
 7             if (connectionProfile == null)
 8             {
 9                 //TODO No net work
10             }
11             else
12             {
13                 isOnline = true;
14             }
15             return isOnline;
16         }

CheckNetwork

  2、向服务器post请求(服务器端我用的是Servlet+Tomcat+MySQL来接收和处理)

 1 private readonly static String url = "请求地址";
 2
 3         private static async Task<string> postData(String data)
 4         {
 5             String result = String.Empty;
 6             // 设置字符编码
 7             Encoding encoding = Encoding.UTF8;
 8             // 将请求的数据转换为字节流
 9             Byte[] bytes = encoding.GetBytes(data);
10             // 实例化请求对象,有多种请求对象可以使用
11             WebRequest req = WebRequest.Create(url);
12             // 请求方式和类型
13             req.Method = "POST";
14             req.ContentType = "application/x-www-form-urlencoded";
15             using (Stream outputStream = await req.GetRequestStreamAsync())
16             {
17                 // 发送字节流信息
18                 outputStream.Write(bytes, 0, bytes.Length);
19             }
20             using (WebResponse webResponse = await req.GetResponseAsync())
21             {
22                 // 得到响应信息
23                 StreamReader sr = new StreamReader(webResponse.GetResponseStream());
24                 result = sr.ReadToEnd();
25             }
26
27             return result;
28         }

七、总结

  第一次上手C#和xaml,而且是在这略浩大的工程中(对我而言),在开发过程中不免会遇到各种困难,当然也积累了各种经验。经历了多次Visual Studio 2013的安装(从Update1到Update3,从vs安装时写临时文件夹拒绝访问到designer安装失败),各种神奇的、离奇的失败最后都在谷歌和MSDN上找到了答案,也锻炼了我查找和阅读答案的能力。希望以上我的分享能给刚上手win8 app开发的同行们减轻一些查api(当然api也是要仔细看的)查谷歌的负担,共同进步。

Windows 8.1 store app 开发笔记,布布扣,bubuko.com

时间: 2024-10-06 12:07:34

Windows 8.1 store app 开发笔记的相关文章

Android APP开发笔记

环境搭建 windows系统上需要以下软件: android SDK -- app开发工具包, 开发运行环境(包括SDK管理工具,和虚拟设备管理). JDK -- java 开发工具包, 负责app代码编译运行. eclipse -- app开发集成环境, 开发app代码, 编译后在 android SDK上运行调试. ADT -- eclipse 的 android 开发工具插件, 将android SDK植入eclipse. 具体搭建步骤: Android开发环境搭建指南 本文以window

安卓app开发笔记

移动app应用开发也是信息技术课程科技创新的范畴,所以在个人开发app时候记录一些笔记,可能会很乱,所以选择按点来写. 1.网络通信协议,我优先选择http,因为熟悉,okhttp很好用,但是我使用更简单的httpurlconnection来开发 2.数据解析,建议优先选择json传输,一种轻量型的数据格式,解析库也是很多,可以自己写接口啥的. 3.涉及到数组类型的数据传输与保存,建议使用json保存,包括传输与数据库中,300个整型数组或者字符,可以构造成json数据,保存在数据库也是只有一个

Android移动APP开发笔记——Cordova(PhoneGap)通过CordovaPlugin插件调用 Activity 实例

引言 Cordova(PhoneGap)采用的是HTML5+JavaScript混合模式来开发移动手机APP,因此当页面需要获取手机内部某些信息时(例如:联系人信息,坐标定位,短信等),程序就需要调用手机内部的API跟页面进行信息交换.Cordova 特别为此定制了完善的解决方案,以方便用户进行程序编辑.在这一章里将为大家逐一介绍Cordova与Actitity通讯的实现原理. 目录 一.CordovaPlugin类简介 二.页面通过 cordova.exec 函数调用 CordovaPlugi

Android移动APP开发笔记——最新版Cordova 5.1.1(PhoneGap)搭建开发环境

引言 简单介绍一下Cordova的来历,Cordova的前身叫PhoneGap,自被Adobe收购后交由Apache管理,并将其核心功能开源改名为Cordova.它能让你使用HTML5轻松调用本地API接口和发布应用到商店的应用开发平台.有低成本,低开发周期,轻量化等优点.它统一封装了Andriod,IOS,WindowsPhone,Symbian等几大移动开发平台的API,采用HTML5+JavaScript的混合开发的模式来开发智能移动的APP,解决系统兼容等问题.使用Cordova把APP

win10 UWP app 开发笔记 - 01

介绍 UWP 是Universal Windows Platform 的缩写,顾名思义,这是一个统一化的windows平台,无论是PC,xbox,windwos phone, hololens等,你可以用相同的一套API,开发出能运行在装有win10的各种硬件设备上,并且他们公用同一个store, 也就是windows phone和win10 PC,Xbox 上看到的是同一个商店. 多牛逼的构想啊,虽然现实不尽如意,很多uwp应用的使用率一直不高,现在windows mobile也寿终正寝,沦落

Android请求网络共通类——Hi_博客 Android App 开发笔记

今天 ,来分享一下 ,一个博客App的开发过程,以前也没开发过这种类型App 的经验,求大神们轻点喷. 首先我们要创建一个Andriod 项目 因为要从网络请求数据所以我们先来一个请求网络的共通类. 思路: 1.把请求网络的方法放到一个类里面 2.创建一个接口将数据发给Activity 3.Activity 实现接口获得服务器返回的数据 4.解析数据 来我们一先来看第一步 请求网络 在这里请求网络我们用Volley .Volley是Android平台上的网络通信库,能使网络通信更快,更简单,更健

Android Studio配置 AndroidAnnotations——Hi_博客 Android App 开发笔记

以前用Eclicps 用习惯了现在 想学学 用Android Studio 两天的钻研终于 在我电脑上装了一个Android Studio 并完成了AndroidAnnotations 的配置. AndroidAnnotations是一个能够让你快速进行Android开发的开源框架,它能让你专注于真正重要的地方.使代码更加精简,使项目更加容易维护,它的目标就是“Fast Android Development.Easy maintainance”. 说白了 就是可以少写很多代码,哈哈. Andr

Android:漫画APP开发笔记之ListView中图片按屏幕宽度缩放

一.listview <ListView android:id="@+id/piclist" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_above="@+id/bottom" android:layout_marginTop="106dp" android:divider

Android:漫画APP开发笔记之从WAP网站解析图片地址并加载图片

一.使用Jsoup解析网页 <pre><code class="prettyprint"><span class="typ">Document</span><span class="pln"> doc </span><span class="pun">=</span><span class="pln">