Windows 8.1 store app 开发笔记

原文: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         }

View Code

七、总结

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

 

时间: 2024-10-26 02:00:32

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

windows store app-windows store APP 开发storyboard动画问题

问题描述 windows store APP 开发storyboard动画问题 各位大神,请赐教,小弟初学.刚学习win8 商店应用开发,想做个小动画,如下:首先把图片随便弄好 也定义好了projection, 然后定义两个移动,一个Y轴垂直移动 一个Z轴旋转的storyboard 我想实现一张图片可以直线拐弯直线拐弯最后回到原来位置 那么问题来了,两个storyboard 单独放在两个不同按钮里 是可以实现的.现在我放在一起 ,想让它一直转,就定义了个定时器 private static Th

c++-win8 store app开发中如何通过点击一个Button从而显示一张图片

问题描述 win8 store app开发中如何通过点击一个Button从而显示一张图片 开发语言是c++ 结合XAML写UI 原来设想是通过click改变Image的Visiblity属性的值,但发现行不通. 求助

使用WACK工具对Windows Store APP进行测试

对于开发者的最终目的而言,无疑是所开发的APP得以成功上架(此处我们排除企业内部部署的应用),我们简要了解一下Windows Store App的上架过程: 参照上图中箭头方向:APP 提交以前,开发者需要注册开发者账号,有了该账号,才能登录到APP的管理端口-Windows Store App Dashboard或者Windows Phone App Dashboard(开发者仪表盘),进行APP提交及相关管理:APP开发完成后,登录到相应Dashboard提交APP到Store进行审核.审核

C# Windows Phone App 开发,自制LockScreen 锁定画面类别(Class),从【网路图片】、【Assets资源】、【UI】修改锁定画面。

原文:C# Windows Phone App 开发,自制LockScreen 锁定画面类别(Class),从[网路图片].[Assets资源].[UI]修改锁定画面. 一般我们在开发Windows Phone App,有时会需要修改锁定画面,而锁定画面的程式码又臭又长,若日後还有很多支APP需要使用到这个功能,岂不是要打很多次?所以我们何不创建一个自定义类别,将锁定画面的功能写一次就好了,日後若有其他专案使用到该功能,我们只要引入Class或Dll参考即可. ? 本篇文章将引导您自制LockS

C# Windows Phone App 开发,修改【锁定画面】,从【Assets】、【UI】、【网路图片】,并解决失灵问题。

原文:C# Windows Phone App 开发,修改[锁定画面],从[Assets].[UI].[网路图片],并解决失灵问题. 一般我们在开发Windows Phone App,有时会希望透过应用程式来改变锁定画面,但是锁定画面的设定有时会发生非常吊诡的现象,譬如锁定画面只会在第一次设定的时候成功,第二次之後全数失败,而且没有发生任何错误,这究竟是为什麽呢?! ? 本篇文章将引导您修改[锁定画面],从[Assets].[UI].[网路图片],并解决失灵问题. ? 制作修改锁定画面的APP必

Windows phone Store APP如何设置页面横竖屏

在 windows phone store app 中,判断和设置页面横竖屏的方法,与 silverlight 中的 Page 类 不同,不能直接通过 Page.Orientation 进行设置.而是通过 DisplayInformation 类,方法如下: // 横屏 Windows.Graphics.Display.DisplayInformation.AutoRotationPreferences = Windows.Graphics.Display.DisplayOrientations

Windows App开发之开发准备

操作系统及SDK 操作系统 显而易见,想要开发Windows App就得在Windows 8/8.1/10上进行,老旧的Windows XP/Vista/7已经不能满足时代的需要了.当然,在Windows App的发展过程中,其本身也有着较大的变动,为了使用新的特性,建议使用Windows 10.我在写这个教程时,Windows 10正式版并未面世,因此暂时未介绍Windows 10上的新特性,随后会继续更新,欢迎您的继续关注. 操作系统除了在官网下载之外,还可以在DreamSpark等地方下载

张高兴的 Windows 10 IoT 开发笔记:使用 MAX7219 驱动 8&amp;#215;8 点阵

原文:张高兴的 Windows 10 IoT 开发笔记:使用 MAX7219 驱动 8×8 点阵 GitHub:https://github.com/ZhangGaoxing/windows-iot-demo/tree/master/MAX7219

张高兴的 Windows 10 IoT 开发笔记:使用 ADS1115 读取模拟信号

原文:张高兴的 Windows 10 IoT 开发笔记:使用 ADS1115 读取模拟信号 考虑到 Raspberry Pi 读取模拟信号是很烦人的事情,更何况是在没人玩的 Windows 10 IoT 下,所以准备正儿八经的写点东西.   需求:使用 Raspberry Pi 读取输出模拟信号的 MQ 系列气体传感器.(GitHub:https://github.com/ZhangGaoxing/windows-iot-demo/tree/master/ADS1115) 由于 Raspberr