【WP开发】在手机屏幕点亮时播放声音
今天说的内容有点流氓,请诸君在开发应用时谨慎使用。
那么,这活儿到底有多流氓呢?
先介绍一下要实现的功能:当用户按电源键(也可以是双击屏幕)点亮手机的屏幕时播放一下短音乐,而且应用程序可以不在前台运行的时候播放。
有朋友脑海里也许马上浮现出两个词:后台音频,后台任务。
是的,灰常正确,能在应用程序不在前台运行或者不运行时播放声音,只有用后台音频了。好,原理就是这样,我相信没有什么难理解的吧。下面就是如何达到这一目的。
在8.1中播放后台音频可以用Windows.Media.Playback命名空间下的BackgroundMediaPlayer类,该类专门用于在前台和后台之间操作音频播放,无论是前台还是后台都能用它。通过静态的Current属性可以返回一个MediaPlayer实例,这个类用起来和XAML中的MediaElement比较像,但MediaPlayer是专用来播放声音的,不能看片子的。
因此我们会想到,第一步是为MediaPlayer设置源,有以下三种方法可以设置播放源。
1、SetFileSource方法,直接把一个音乐文件的StorageFile实例传进去即可;
2、SetStreamSource方法,以流的形式传递;
3、SetUriSource方法,直接以URI来设置源。
当然,还有一个SetMediaSource方法,这玩意比较复杂,暂时不考虑。
如果把MediaPlayer的AutoPlay设置为True,当源被设置后就后马上播放;如果为False,那就需要调用Play方法它才会播放。
现在,我们要考虑最“头疼”的问题了,如何在手机屏幕点亮时就运行后台任务呢? 不要急,来,慢慢看。
Windows.ApplicationModel.Background命名空间下定义了许多后台任务触发器,用于触发后台任务的,其中有一个触发器类,专门用来捕捉系统事件的——SystemTrigger,在创建SystemTrigger实例时,需要指定SystemTriggerType,表示触发行为类型,由SystemTriggerType枚举定义。我们看看其中两个值:
UserPresent:在用户可见时触发后台,啥意思呢? 在平板或电脑上,是当用户登录系统时触发;而在手机上,是当用户按下电源键点亮手机屏幕时触发。哈哈,现在你明白如何在点亮屏幕时播放声音的方法了吧?
UserAway:在电脑或平板上当用户注销时触发;在手机上,当用户关闭屏幕时触发,所以如果想让声音在锁屏时播放,可以使用这类型。
现在,大家肯定明白思路了。就是结合后台音频和触发器来实现。但是,千万千万严重地记住,在点亮屏幕时播放的声音不要太长,你别来一首歌,那样会很恶心很流氓,而且系统也不会让你播放那么长的,所以,做人不能太流氓。所以,建议就用5秒钟左右的声音比较合理。
好,还愣着干什么,开工!
首先在解决方案中添加一个运行时组件项目,注意,不是类库,是运行时组件,编译后生成.wimd后缀的文件的,不是.dll,类库才是.dll。
这个运行时组件就是要执行的后台任务,定义一个类,并且实现IBackgroundTask接口,要实现了这个接口,系统才认你是后任务,否则系统不鸟你。
public sealed class Back:IBackgroundTask
{
BackgroundTaskDeferral deferral = null;
public async void Run ( IBackgroundTaskInstance taskInstance )
{
deferral = taskInstance.GetDeferral();
Uri media = new Uri("ms-appx:///1.mp3");
// 打开文件流
StorageFile file = await StorageFile.GetFileFromApplicationUriAsync(media);
var stream = await file.OpenReadAsync();
// 获取播放器控制对象
MediaPlayer player = BackgroundMediaPlayer.Current;
player.AutoPlay = true; //设置自动播放
player.MediaEnded += player_MediaEnded;
player.MediaFailed += player_MediaFailed;
// 设置源后自动播放
player.SetStreamSource(stream);
} void player_MediaFailed ( MediaPlayer sender, MediaPlayerFailedEventArgs args )
{
BackgroundMediaPlayer.Shutdown();
deferral.Complete();
} void player_MediaEnded ( MediaPlayer sender, object args )
{
BackgroundMediaPlayer.Shutdown();
deferral.Complete();
} }
代码不是很长,应该能理解,就是从BackgroundMediaPlayer.Current中拿到player,得到player后就给它setSource,set完source后就开始播放声音了。
那么,GetDeferral方法返回的BackgroundTaskDeferral对象有什么用呢? 说白了,就是用来拖延时间的,别让后台任务这么快结束,等声音播放完再结束,听完仙乐后再死也不迟。当你觉得差不多了,要结束后台任务了,就调用Complete方法来告诉系统,这个后台任务完蛋了,该入土为安了,于是系统就会X掉后台并回收资源。
Good,后台任务写好了,再弄前台,
首先要在前台应用程序中引用刚才写的运行时组件,就个和引用程序集一样,就是在“引用”上右击,然后“添加引用”,相信你会操作,不然你就不是学.net的。
然后打开清单文件Package.appxmanifest,切换到“声明”选项卡,在下拉列表中选择“后台任务”,然后点击添加按钮,好,后台声明加了。然后要设置一下参数。
在支持的任务类型下勾选“音频”,注意只选音频就可以了,不要选其他,否则无法运行程序。如下图。

接着,在入口点处填上刚才运行时组件中写的那个实现IBackgroundTask接口的类名,注意连命名空间名字也填上,如下图。

好了,保存并关闭清单文件,但是,后台任务还没注册,声明只是告诉系统允许哪些后台任务而已,并没有真正注册。
可以在页面的OnNavigated方法中注册,也可以在App的OnLaunch方法中注册,随你喜欢,反正要在后台任务运行前进行注册。
foreach (IBackgroundTaskRegistration task in BackgroundTaskRegistration.AllTasks.Values)
{
if (task.Name == TASKNAME)
{
task.Unregister(true);
break;
}
}
// 必须调用以下代码,否则不能注册后台任务
var result = await BackgroundExecutionManager.RequestAccessAsync();
if (result == BackgroundAccessStatus.AllowedMayUseActiveRealTimeConnectivity)
{
BackgroundTaskBuilder taskbd = new BackgroundTaskBuilder();
taskbd.Name = TASKNAME;
taskbd.TaskEntryPoint = ENTRY_POINT; //入口点
// 添加触发器
SystemTrigger trigger = new SystemTrigger(SystemTriggerType.UserPresent, false);
/*
* 当用户点亮手机屏幕时就会触发
*/
taskbd.SetTrigger(trigger);
// 注册后台任务
try
{
var reg = taskbd.Register();
tb.Text = "后台任务注册成功。\n" + string.Format("任务名:{0}\n", reg.Name) + string.Format("任务ID:{0}", reg.TaskId);
}
catch
{
tb.Text = "后台任务注册失败。";
}
}
先从BackgroundTaskRegistration.AllTasks.Values中找一下任务是不是已经注册了,如果是,先干掉它,再重新注册。
因为要在用户点亮手机屏幕时播放声音,所以,SystemTrigger触发器使用的类型为UserPresent。
还有一个严重关键的地方,在注册后台任务前,不要忘了调用BackgroundExecutionManager.RequestAccessAsync方法,虽然调用后没看到提示,但必须调用了该方法并返回BackgroundAccessStatus.AllowedMayUseActiveRealTimeConnectivity后才能注册后台任务,否则会出错。
好了,就这样就行了,运行应用程序,让它注册后台任务,然后可以关掉程序。接着关闭掉手机屏幕,然后再点亮屏幕,这时候就能听到仙乐了。
示例源代码下载:http://files.cnblogs.com/tcjiaan/playAudioOnPresentSP.zip
【WP开发】在手机屏幕点亮时播放声音的更多相关文章
- Android开发——Android手机屏幕适配方案总结
)密度无关像素,单位为dp,是Android特有的单位 Android开发时通常使用dp而不是px单位设置图片大小,因为它可以保证在不同屏幕像素密度的设备上显示相同的效果. /** * dp与px的转 ...
- 【WP开发】记录屏幕操作
在某些应用中,比如游戏,有时候需要将用户的操作记录下来.ScreenCapture类提供了这个功能.但必须注意的是:此屏幕记录功能只对当前应用程序的屏幕有效,即只有当前应用程序在前台运行时才有效. 与 ...
- flexible.js在华某为手机上使用rem时,页面宽度超出手机屏幕宽度
问题:手机端项目在华为的某款手机上显示时页面内容没有自适应手机宽度,出现横向滚动条 原因:手机获取手机屏幕宽度并计算出rem时出现偏差,明显宽余真实手机屏宽度 解决方案一:在页面里获取页面最外层dom ...
- webapp开发——‘手机屏幕分辨率’与‘浏览器分辨率’不要混淆
关于webApp响应式设计遇到的问题,分享给大家,最近在做一个手机webApp,因为我手机是”米3“,屏幕截图大小是1080宽,所以css样式用@media screen and(min-width: ...
- Android 如何将手机屏幕投影到 PC 屏幕上或者投影仪上做演示?
Android 如何将手机屏幕投影到 PC 屏幕上或者投影仪上做演示? 公司开发款APP,要给领导演示,总不能用手机面对面演示吧.所以找了好久,找到一款体验超好的: Total Control-帮助你 ...
- cocos2d-x 保持屏幕点亮及自动变灰
很早之前遇到的问题,现在记录一下.有一家Android渠道(抱歉,时间太长了已经记不大清楚是哪一家了 oppo/联想/酷派?)在我们提交新版本时拒绝了,理由是:手机背光状态下,屏幕不会自动变灰. 这里 ...
- Android程序对不同手机屏幕分辨率自适应的方法
相信各位Android开发爱好者都知道,由于OEM之间的竞争,各种Android操作系统的手机简直就是琳琅满目,屏幕分辨率的差异可想而知.目前比较主流的有WVGA=800x480,HVGA=480x3 ...
- Unity3D Android手机屏幕分辨率问题
Android手机屏幕分辨率五花八门,导致开发时不好把握,还好各个引擎对这个屏幕分辨率问题都有较好的处理方式:unity3D 也为我们提供了一个不错的解决方案. 在Unity3D 进行 android ...
- Android针对不同的手机屏幕大小设计图片资源与编码
注:本文转载于:http://blog.csdn.net/welovesunflower/article/details/7930248 一些术语 Screen Size 屏幕尺寸: 实际的物理尺寸, ...
随机推荐
- 《转》python线程池
线程池的概念是什么? 在IBM文档库中这样的一段描写:“在面向对象编程中,创建和销毁对象是很费时间的,因为创建一个对象要获取内存资源或者其它更多资源.在Java中更是 如此,虚拟机将试图跟踪每一个对象 ...
- C# 以附加文件方式连接SQL Server数据库文件
string str = @"data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFileName=z:\ttt.mdf;Us ...
- 特征处理(Feature Processing)
[本文链接:http://www.cnblogs.com/breezedeus/p/4109456.html,转载请注明出处] 我的博客主营地迁至github,欢迎朋友们有空去看看:http://br ...
- 在c#中使用bitblt显示图片
使用bitblt比DrawImage有更好的性能 using AForge.Video.DirectShow; using System; using System.Collections.Gener ...
- js学习笔记之一
一.Javascript 中的对象 1. 建立自定义对象 方法1:对象={属性1:属性值1,属性2:属性值2……属性n:属性值n} 方法2:先定义构造函数,再new创建对象实例. 如: functio ...
- TFT-LCD的相关概念
显示尺寸(display size) 是指实际可视区域的对角线长度,单位是英寸,简称寸(1英寸=2.54厘米). 长宽比(aspect ratio) 是指TFT-LCD可视区域的长度和宽度之比,也叫做 ...
- Sphinx : 高性能SQL全文检索引擎
Sphinx的特点 快速创建索引:3分钟左右即可创建近100万条记录的索引,并且采用了增量索引的方式,重建索引非常迅速. 闪电般的检索速度:尽管是1千万条的大数据量,查询数据的速度也在毫秒级以上,2- ...
- 使用开源库MAGICODES.WECHAT.SDK进行微信公众号支付开发
概要 博客使用Word发博,发布后,排版会出现很多问题,敬请谅解.可加群获取原始文档. 本篇主要讲解微信支付的开发流程,相关业务基于MAGICODES.WECHAT.SDK实现.通过本篇教程,您可以很 ...
- android oauth 微博客户端 架构一
最近研究oauth协议,为了进一步 的巩固自己的学习成果,顾完成了android的新浪客户端.他的架构如下: UI层微博中的各个窗体 就是所谓的各个activitylogic层程序的核心控制调度模块 ...
- Actor的原理
先从著名的c10k问题谈起.有一个叫Dan Kegel的人在网上(http://www.kegel.com/c10k.html)提出:现在的硬件应该能够让一台机器支持10000个并发的client.然 ...