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 开发笔记的更多相关文章
- Android移动APP开发笔记——最新版Cordova 5.3.1(PhoneGap)搭建开发环境
引言 简单介绍一下Cordova的来历,Cordova的前身叫PhoneGap,自被Adobe收购后交由Apache管理,并将其核心功能开源改名为Cordova.它能让你使用HTML5轻松调用本地AP ...
- 手机web app开发笔记
各位朋友好,最近自学开发了一个手机Web APP,“编程之路”,主要功能包括文章的展示,留言,注册登录,音乐播放等.为了记录学习心得,提高自己的编程水平,也许对其他朋友有点启发,特整理开发笔记如下. ...
- Android移动APP开发笔记——Cordova(PhoneGap)通过CordovaPlugin插件调用 Activity 实例
引言 Cordova(PhoneGap)采用的是HTML5+JavaScript混合模式来开发移动手机APP,因此当页面需要获取手机内部某些信息时(例如:联系人信息,坐标定位,短信等),程序就需要调用 ...
- Android APP开发笔记
环境搭建 windows系统上需要以下软件: android SDK -- app开发工具包, 开发运行环境(包括SDK管理工具,和虚拟设备管理). JDK -- java 开发工具包, 负责app代 ...
- 小学英语课文朗读APP开发笔记(一):创建Win7虚拟机
1 缘起 以小米盒子为代表的OTT机顶盒.智能电视的快速普及,快速推动了Android技术在机顶盒.智能电视领域的普及.既然都是用的Android操作系统,那么从技术上来说应该是大同小异的,当然和手机 ...
- 安卓app开发笔记
移动app应用开发也是信息技术课程科技创新的范畴,所以在个人开发app时候记录一些笔记,可能会很乱,所以选择按点来写. 首先是一些入门的资料,有很多需要自己学习的 https://www.oschin ...
- Android Studio配置 AndroidAnnotations——Hi_博客 Android App 开发笔记
以前用Eclicps 用习惯了现在 想学学 用Android Studio 两天的钻研终于 在我电脑上装了一个Android Studio 并完成了AndroidAnnotations 的配置. An ...
- Android请求网络共通类——Hi_博客 Android App 开发笔记
今天 ,来分享一下 ,一个博客App的开发过程,以前也没开发过这种类型App 的经验,求大神们轻点喷. 首先我们要创建一个Andriod 项目 因为要从网络请求数据所以我们先来一个请求网络的共通类. ...
- 默认文档接卸--手机web app开发笔记(二)
首先我们启动HBuilderX2.0 ,界面如图2-1所示 图2-1 软件开发界面 单击“文件—新建—项目”,弹出新建项目管理界面,我们在里面进行了项目类型选择“5+APP”.项目名称填写“编程之路” ...
随机推荐
- Kafka项目实践
用户日志上报实时统计之编码实践 1.概述 本课程的视频教程地址:<Kafka实战项目之编码实践> 该课程我以用户实时上报日志案例为基础,带着大家去完成各个KPI的编码工作,实现生产模块. ...
- vs2015web工程中的html引用压缩后css后无法智能提示的问题解决
环境:win10x64 vs2015企业版 项目:空白web项目(.net framework4) 问题:html页面加入压缩后的css(eg:bootstrap.min.css),编码的时候无法智能 ...
- C++的感想
C++的感想 大学期间,学了一学期的C语言,当然包括学习数据结构时,用的也是C语言.当时刚刚接触计算机,对于编程更是一无所知.上课学习学习,偶尔会照着书上敲一下代码.大二下学期,就丢掉了不用了.最近由 ...
- 中国澳门sinox很多平台CAD制图、PCB电路板、IC我知道了、HDL硬件描述语言叙述、电路仿真和设计软件,元素分析表
中国澳门sinox很多平台CAD制图.PCB电路板.IC我知道了.HDL硬件描述语言叙述.电路仿真和设计软件,元素分析表,可打开眼世界. 最近的研究sinox执行windows版protel,powe ...
- java.util.Timer demo good
package timer; import java.util.Date; import java.util.Timer; import java.util.TimerTask; import org ...
- Java加深理解有关注释
一.获取应用笔记 常常会遇到这种情况 package Tokyo.Hot; public class Demo { public static void main(String[] args) { n ...
- js之按键总结
js 实现键盘记录 兼容FireFox和IE 2009-01-07 11:43 作者:羽殇仁 转载请注明出处,谢谢. 本篇文章是我的第一百篇blog文章,恭喜一下! 这两天突然想弄弄js的键盘记录,所 ...
- WP 前台或后台显示ShellToast
原文:WP 前台或后台显示ShellToast using Microsoft.Phone.Shell; ShellToast toast = new ShellToast(); toast.Titl ...
- ABP依赖注入
ABP依赖注入 点这里进入ABP系列文章总目录 基于DDD的现代ASP.NET开发框架--ABP系列之6.ABP依赖注入 ABP是“ASP.NET Boilerplate Project (ASP.N ...
- hdu 2191 (多重背包+二进制优化)
Problem Description 急!灾区的食物依然短缺!为了挽救灾区同胞的生命,心系灾区同胞的你准备自己采购一些粮食支援灾区,现在假设你一共有资金n元,而市场有m种大米,每种大米都是袋装产品, ...