原文: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、定位:

 private LocationRange range = null;
private CancellationTokenSource cts = null;
private Geolocator geolocator = null; private async void locateButton_Click(object sender, RoutedEventArgs e)
{
// 根据定位按钮的标签判定是“定位”或“取消定位”
if (locateButton.Label == "定位")
{
locateButton.Label = "取消定位";
try
{
// 获得cancellation token
cts = new CancellationTokenSource();
CancellationToken token = cts.Token;
this.infoBlock.Text = "正在定位"; // 获得位置
Geoposition pos = await geolocator.GetGeopositionAsync().AsTask(token);
this.infoBlock.Text = "定位成功";
// App.location是在App.xaml.cs中用于保存定位位置的全局变量
App.location = new Location(pos.Coordinate.Point.Position.Latitude, pos.Coordinate.Point.Position.Longitude); // 设置默认地图缩放等级
double zoomLevel = 13.0f;
// range是一个自定义控件,用一个大圆来涵盖定位区域
MapLayer.SetPosition(range, App.location);
rangeLayer.Children.Add(range);
zoomLevel = 15.0f; // 设置地图视野到给定的位置和缩放等级
map.SetView(App.location, zoomLevel);
}
catch (System.UnauthorizedAccessException)
{
this.infoBlock.Text = "定位请求被拒绝";
}
catch (TaskCanceledException)
{
this.infoBlock.Text = "定位被取消";
}
catch (System.Exception)
{
this.infoBlock.Text = "暂时无法获得您的位置";
}
finally
{
cts = null;
}
// 重置按钮
locateButton.Label = "定位";
//locateButton.Icon = ;
}
else
{
// 取消定位
if (cts != null)
{
cts.Cancel();
cts = null;
}
// 重置按钮
locateButton.Label = "定位";
//locateButton.Icon = ;
}
}

locateButton_Click

  2、添加图钉:

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

AddPinButton_Click

  3、拖动图钉:

 private bool isDragging = false;        // pin正在拖拽标志

         // 当pin被拖动时激活
public Action<Location> drag;
// 当pin开始被拖动时激活
public Action<Location> dragStart;
// 当pin停止拖动时激活
public Action<Location> dragEnd;
// 当pin被按下时,得到被按下pin的ID,判断是否可拖动,执行操作
protected override void OnPointerPressed(PointerRoutedEventArgs e)
{
base.OnPointerPressed(e); // 如果可以被拖动则开始拖动
if (draggable)
{
if (map != null)
{
center = map.Center;
// 为map的下列方面重写
map.ViewChanged += map_ViewChanged;
map.PointerReleasedOverride += map_PointerReleased;
map.PointerMovedOverride += map_PointerMoved;
}
// 得到当前鼠标位置
var pointerPosition = e.GetCurrentPoint(map);
Location location = null;
// 开始拖动
if (dragStart != null)
{
dragStart(location);
} this.isDragging = true;
}
} // 当pin被移动时
private void map_PointerMoved(object sender, PointerRoutedEventArgs e)
{
// 检查是否正在被拖动
if (this.isDragging)
{
// 随着鼠标移动图标
var pointerPosition = e.GetCurrentPoint(map); Location location = null; if (map.TryPixelToLocation(pointerPosition.Position, out location))
{
// 将图钉(this)移到到当前鼠标的位置(location)
MapLayer.SetPosition(this, location);
}
if (drag != null)
{
drag(location);
}
}
} // 当pin被松开时
private void map_PointerReleased(object sender, PointerRoutedEventArgs e)
{
if (this.isDragging)
{
if (map != null)
{
map.ViewChanged -= map_ViewChanged;
map.PointerReleasedOverride -= map_PointerReleased;
map.PointerMovedOverride -= map_PointerMoved;
} var pointerPosition = e.GetCurrentPoint(map);
Location location;
map.TryPixelToLocation(pointerPosition.Position, out location);
// 得到最终的经纬度
latitude = location.Latitude;
longitude = location.Longitude; location = null; if (dragEnd != null)
{
dragEnd(location);
} this.isDragging = false;
this.draggable = false;
}
}

PinDrag

二、BING TRANSLATE API

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

  翻译:

 private HttpClient client = null;            // 用于通信的HTTP客户端

         private async void translateButton_Click(object sender, RoutedEventArgs e)
{
// 根据translateButton的标签判定是“翻译”或“取消翻译”
if (translateButton.Label == "翻译")
{
// 进行网络检查(方法见 五、UTILITIES)
if (!App.CheckNetwork())
{
//this.infoBlock.Text = "无网络连接,请检查网络";
}
else
{
try
{
this.infoBlock.Text = "正在检查网络连接...";
string clientID = "你的clientID";
string clientSecret = "你的clientSecret";
//AzureDataMarket可以从网上找到,是一个已经写好的用于在Azure进行验证的类
var _Authentication = new AzureDataMarket(clientID, clientSecret);
AzureDataMarket.Token m_Token = await _Authentication.GetTokenAsync();
string auth = m_Token.Header;
//实例化该类,以便于后面发送Http请求获取网络数据
client = new HttpClient();
//设置读取响应内容时缓冲区的最大字节数
client.MaxResponseContentBufferSize = ;
//设置请求头部
client.DefaultRequestHeaders.Add("Authorization", auth);
}
catch
{
//this.infoBlock.Text = "连接到服务器失败";
}
}
}
else
{
this.translateButton.Label = "翻译";
}
} // 将descriptionBlock中的内容翻译成language所表示的语言
private async void translate(String language)
{
//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
string url = "http://api.microsofttranslator.com/v2/Http.svc/Translate?text=" + System.Net.WebUtility.UrlEncode(this.descriptionBlock.Text) + "&to=" + language;
//try
{
string strTranslated = await client.GetStringAsync(url);
XDocument xTranslation = XDocument.Parse(strTranslated);
string strTransText = xTranslation.Root.FirstNode.ToString();
this.titleTranslateBlock.Text = strTransText; this.translateButton.Label = "取消翻译";
}
//catch (Exception ex)
{
// this.infoBlock.Text = "不能访问Bing Translate API,错误原因:" + ex.Message.ToString();
} }
// 当englishButton按下时,翻译成英语
private void englishButton_Click(object sender, RoutedEventArgs e)
{
translate("en");
}
// 当simChineseButton按下时,翻译成简体中文
private void simChineseButton_Click(object sender, RoutedEventArgs e)
{
translate("zh-CHS");
}

translateButton_Click

三、BING AD API

  待应用......

四、LIVE SDK

  1、登入和登出live帐号:

             // live SDK使用范围:登入、获得用户基本信息、使用onedrive上传功能
private readonly string[] scopes = new string[] {
"wl.signin", "wl.basic", "wl.photos", "wl.skydrive", "wl.skydrive_update"};
private LiveAuthClient authClient = null;
private LiveConnectClient liveClient = null; private void loginButton_Click(object sender, RoutedEventArgs e)
{
// 根据loginButton判定是“登入”或“登出”
if (this.loginButton.Label == "登出")
{
this.authClient.Logout();
this.loginButton.Label = "Live帐号登入";
this.loginBlock.Text = "未登入";
}
else
{
login();
}
} private async void login()
{
try
{
this.loginButton.IsEnabled = false; this.authClient = new LiveAuthClient();
this.loginBlock.Text = "登入中";
// 登入时显示进度的进度环
this.loginProgress.IsActive = true;
// 检验网络状态
if (App.CheckNetwork())
{
// 得到登入结果
LiveLoginResult loginResult = await this.authClient.LoginAsync(this.scopes);
if (loginResult.Status == LiveConnectSessionStatus.Connected)
{
App.Session = loginResult.Session;
this.liveClient = new LiveConnectClient(loginResult.Session);
LiveOperationResult operationResult = await this.liveClient.GetAsync("me"); // 当用户登入后
dynamic meResult = operationResult.Result;
this.loginButton.Label = "登出";
if (meResult.first_name != null && meResult.last_name != null)
{
//显示用户的登录信息
this.loginBlock.Text = "欢迎! " + meResult.first_name + " " + meResult.last_name;
}
else
{
this.loginBlock.Text = "欢迎! ";
}
}
else
{
this.loginBlock.Text = "未登入";
}
}
else
{
this.infoBlock.Text = "无网络连接,请检查网络";
this.loginBlock.Text = "未登入";
}
}
catch (LiveAuthException)
{
this.infoBlock.Text = "登入请求被拒绝";
}
finally
{
// CanLogout为false的情况:应用使用windows已登入的账号时
if (this.loginButton.Label == "登出" && this.authClient != null && !this.authClient.CanLogout)
{
this.loginButton.IsEnabled = false;
}
else
{
this.loginButton.IsEnabled = true;
}
this.loginProgress.IsActive = false;
}
}

loginButton_Click

  2、上传图片至OneDrive:

 private async void syncButton_Click(object sender, RoutedEventArgs e)
{
// App.Session是用来记录当前登入账户的一次会话,登入live帐号之后产生
if (App.Session != null)
{
// 得到本地的photo文件夹
IReadOnlyList<StorageFolder> folders = await App.photosFolder.GetFoldersAsync();
// 在Onedrive中新建一个文件夹,名字为“新建文件夹”
string skyDriveFolder = await CreateDirectoryAsync("新建文件夹", "me/skydrive");
// 对photo文件夹中的子文件夹进行遍历
foreach (StorageFolder folder in folders)
{
// 获得子文件夹下的所有文件
IReadOnlyList<StorageFile> files = await folder.GetFilesAsync();
foreach (StorageFile file in files)
{
// 将文件上传
LiveOperationResult result = await liveClient.BackgroundUploadAsync(skyDriveFolder, file.DisplayName + ".jpg", file, OverwriteOption.Overwrite);
}
}
}
} private async Task<string> CreateDirectoryAsync(string folderName, string parentFolder)
{
string folderId = null;
// 查询OneDrive中是否含有folderName文件夹
var queryFolder = parentFolder + "/files?filter=folders,albums";
var opResult = await liveClient.GetAsync(queryFolder);
dynamic result = opResult.Result; foreach (dynamic folder in result.data)
{
// 如果存在这个文件夹,则返回文件夹名
if (folder.name == folderName)
{
folderId = folder.id;
break;
}
} if (folderId == null)
{
// 不存在则创建
var folderData = new Dictionary<string, object>();
folderData.Add("name", folderName);
opResult = await liveClient.PostAsync(parentFolder, folderData);
result = opResult.Result;
folderId = result.id;
} return folderId;
}

syncButton_Click

五、微博 SDK

  1、连接微博帐号:

 private void shareButton_Click(object sender, RoutedEventArgs e)
{
// 检查网络状态
if (App.CheckNetwork())
{
// 检查该应用是否已和微博连接
if (App.oauthClient.IsAuthorized == false)
{
App.oauthClient.LoginCallback += (isSucces, err, response) =>
{
if (isSucces) // 如果成功
{
// TODO: deal the OAuth result.
}
else
{
this.titleBox.Text = err.errMessage;
}
};
App.oauthClient.BeginOAuth(); // 开始验证
}
}
else
{
// no internet.
}
if (App.oauthClient.IsAuthorized == true) // 验证成功,开始分享
{
// TODO SHARE
}
else
{
this.titleBox.Text = "验证失败";
}
}

shareButton_Click

  2、发布(带图片)微博

 private async void shareWithPhoto(String path)
{
var engine = new SdkNetEngine();
// 微博sdk提供的方法,实例化一个cmd类
ISdkCmdBase cmdBase = new CmdPos MsgWithPic()
{
// 发布的文本消息
Status = shareTextBox.Text,
// 发布的图片绝对路径
PicPath = path
};
// 发布微博
var result = await engine.RequestCmd(SdkRequestType.POST_MESSAGE_PIC, cmdBase); if (result.errCode == SdkErrCode.SUCCESS)
{
// 发布成功
}
// 发布失败
else
{
// TODO: deal the error.
// 失败的状态码
switch (result.errCode)
{
case SdkErrCode.NET_UNUSUAL: this.descriptionBox.Text = "NET_UNUSUAL"; break;
case SdkErrCode.SERVER_ERR: this.descriptionBox.Text = "SERVER_ERR"; break;
case SdkErrCode.TIMEOUT: this.descriptionBox.Text = "TIMEOUT"; break;
case SdkErrCode.USER_CANCEL: this.descriptionBox.Text = "USER_CANCEL"; break;
case SdkErrCode.XPARAM_ERR: this.descriptionBox.Text = "XPARAM_ERR"; break;
}
this.descriptionBox.Text = result.specificCode;
}
}

shareWithPhoto

六、UTILITIES

  1、检查网络状态

 public static Boolean CheckNetwork()
{
bool isOnline = false;
//获得当前的网络连接状态(using Windows.Networking.Connectivity
ConnectionProfile connectionProfile = NetworkInformation.GetInternetConnectionProfile(); if (connectionProfile == null)
{
//TODO No net work
}
else
{
isOnline = true;
}
return isOnline;
}

CheckNetwork

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

 private readonly static String url = "请求地址";

         private static async Task<string> postData(String data)
{
String result = String.Empty;
// 设置字符编码
Encoding encoding = Encoding.UTF8;
// 将请求的数据转换为字节流
Byte[] bytes = encoding.GetBytes(data);
// 实例化请求对象,有多种请求对象可以使用
WebRequest req = WebRequest.Create(url);
// 请求方式和类型
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
using (Stream outputStream = await req.GetRequestStreamAsync())
{
// 发送字节流信息
outputStream.Write(bytes, , bytes.Length);
}
using (WebResponse webResponse = await req.GetResponseAsync())
{
// 得到响应信息
StreamReader sr = new StreamReader(webResponse.GetResponseStream());
result = sr.ReadToEnd();
} return result;
}

七、总结

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

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

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

    引言 简单介绍一下Cordova的来历,Cordova的前身叫PhoneGap,自被Adobe收购后交由Apache管理,并将其核心功能开源改名为Cordova.它能让你使用HTML5轻松调用本地AP ...

  2. 手机web app开发笔记

    各位朋友好,最近自学开发了一个手机Web APP,“编程之路”,主要功能包括文章的展示,留言,注册登录,音乐播放等.为了记录学习心得,提高自己的编程水平,也许对其他朋友有点启发,特整理开发笔记如下. ...

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

    引言 Cordova(PhoneGap)采用的是HTML5+JavaScript混合模式来开发移动手机APP,因此当页面需要获取手机内部某些信息时(例如:联系人信息,坐标定位,短信等),程序就需要调用 ...

  4. Android APP开发笔记

    环境搭建 windows系统上需要以下软件: android SDK -- app开发工具包, 开发运行环境(包括SDK管理工具,和虚拟设备管理). JDK -- java 开发工具包, 负责app代 ...

  5. 小学英语课文朗读APP开发笔记(一):创建Win7虚拟机

    1 缘起 以小米盒子为代表的OTT机顶盒.智能电视的快速普及,快速推动了Android技术在机顶盒.智能电视领域的普及.既然都是用的Android操作系统,那么从技术上来说应该是大同小异的,当然和手机 ...

  6. 安卓app开发笔记

    移动app应用开发也是信息技术课程科技创新的范畴,所以在个人开发app时候记录一些笔记,可能会很乱,所以选择按点来写. 首先是一些入门的资料,有很多需要自己学习的 https://www.oschin ...

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

    以前用Eclicps 用习惯了现在 想学学 用Android Studio 两天的钻研终于 在我电脑上装了一个Android Studio 并完成了AndroidAnnotations 的配置. An ...

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

    今天 ,来分享一下 ,一个博客App的开发过程,以前也没开发过这种类型App 的经验,求大神们轻点喷. 首先我们要创建一个Andriod 项目 因为要从网络请求数据所以我们先来一个请求网络的共通类. ...

  9. 默认文档接卸--手机web app开发笔记(二)

    首先我们启动HBuilderX2.0 ,界面如图2-1所示 图2-1 软件开发界面 单击“文件—新建—项目”,弹出新建项目管理界面,我们在里面进行了项目类型选择“5+APP”.项目名称填写“编程之路” ...

随机推荐

  1. ExtJS学习笔记:定义extjs类别

    类的定义 Ext.define('Cookbook.Vehicle', { Manufacturer: 'Aston Martin', Model: 'Vanquish', getDetails: f ...

  2. 进口fbx角色动画read-only解

    原文链接:http://answers.unity3d.com/questions/8172/how-to-add-new-curves-or-animation-events-to-an-im.ht ...

  3. js 滚轮事件 滚轮焦点图(轮播图)

    利用滚轮,切换轮播图.附带mousewheel插件以及原生js写法:   <!doctype html> <html> <head> <meta charse ...

  4. vs2015管理github代码

  5. mysql函数二

    四.条件推断函数 1.if(expr,v1,v2)函数:成立返回结果v1,否则结果v2 例:select id,if(grade>=60,'pass','fail') from t; 2.IFN ...

  6. NSIS:IfFileExists+Goto实现简单跳转

    原文 NSIS:IfFileExists+Goto实现简单跳转 在用户手册中有相关示例,但也许有的同学没有发现,那么我再发一个,仅供入门学习参考. IfFileExists 要检测的文件 文件存在时跳 ...

  7. Java学习笔记——泛型

    假定T不仅要指定接口的类继承.使用下面的方式: public class some<T extends Iterable<T> & Comparable<T>&g ...

  8. Display Database Image using MS SQL Server 2008 Reporting Services

    原文 Display Database Image using MS SQL Server 2008 Reporting Services With the new release of MS SQL ...

  9. 讨论oracle在rowid和rownum

    [ 概要 ] 刚刚接触oracle的同学可能经常会被rowid和rownum这两个词弄混, 弄清楚这两个家伙对于我们写sql会有非常大的帮助, 以下偶就抛砖引玉, 简单地谈谈他们之间的差别吧. [ 比 ...

  10. Git 命令速查表

    Git 命令速查表 1.常用的Git命令 命令 简要说明 git add 添加至暂存区 git add-interactive 交互式添加 git apply 应用补丁 git am 应用邮件格式补丁 ...