AIR2.0入门教程[六]:结合Thinkpad APS技术和AIR2实现重力加速度监测

在之前的AIR2.0的教程序列中,我们介绍了AIR2.0的一些新特性,包括增强的拖拽支持,启动本地进程并通讯等等,其中本地进程(NativeProcess)这个特性个人感觉是AIR2.0最出彩的地方,因为这个特性大大扩展了AIR的应用范围,可以做各种有意思的应用,比如今天要说的这个例子:结合Thinkpad APS技术和AIR2实现重力加速度监测。当然有得必有失,如果使用本地进程这个特性,就要求你必须将AIR安装文件做成本地安装文件(Windows下面是EXE),而这必然会损失一些跨平台的特性。

前置知识:

NativeProcess:这是AIR2新增的类,只要是基于命令行的标准输入输出,AIR2.0的应用是可以通过NativeProcess,和任何语言编写的本地进程进行交互的,如果你还不了解这个特性,请参考:AIR2.0入门教程[三]:与本地进程的数据通讯

重力加速度监测:有一些设备,从硬件上提供了这种支持,比如苹果的笔记本电脑,iPhone,都内置了重力加速度监测的芯片,这样我们可以通过相应的API,获取到设备的当前物理状态(平放,还是侧翻,或倒转),获取到的参数一般是3个:X,Y,Z,分别代表三个坐标轴的偏移情况。

APS:在T42之后的ThinkPad笔记本电脑中,都内置了APS功能(硬盘主动保护技术,也叫硬盘防震技术),实际上它里面也是提供了类似苹果笔记本那样的重力加速度监测,这里我们就要利用这个特性,完成这个例子。

最终效果体验:

先看看这个视频吧,当我们让笔记本侧翻,你可以看到,小球会向较低的一面滚过去:

开发过程:

首先要说明的是,在Thinkpad笔记本电脑中(以笔者所用的T400为例),要获取重力加速度信息,是要通过一个DLL(动态链接库)来进行的,这个DLL的位置是:C:\Windows\System32\Sensor.DLL,所要呼叫的方法则是:ShockproofGetAccelerometerData()。由于AIR2不能直接调取DLL,所以我们需要再创建一个支持命令行标准输入输出的C++编写的EXE文件,来调取DLL,然后把得到的数据,返回给AIR应用。

步骤一:使用C++创建EXE文件

首先打开VS2008,或其它你熟悉的工具,创建一个C++文件,写入下面的代码:

  1. #include <iostream>
  2. #include "windows.h"
  3. using namespace std;
  4. typedef void(__stdcall *Print_)();
  5.  
  6. int main(){
  7. int a;
  8. HINSTANCE hDll; //DLL句柄
  9. Print_ print_; //函数指针
  10. hDll = LoadLibrary("C:/Windows/System32/Sensor.DLL");
  11. short cX = 0;
  12. short cY = 0;
  13. typedef struct
  14. {
  15. int PresentState;
  16. short LatestRawAccelDataX;
  17. short LatestRawAccelDataY;
  18. short LatestAccelDataX;
  19. short LatestAccelDataY;
  20. char Temperature;
  21. short LatestZeroG_X;
  22. short LatestZeroG_Y;
  23. } AccelerometerData;
  24. typedef void (__stdcall * funcShockproofGetAccelerometerData)( AccelerometerData * );
  25.  
  26. funcShockproofGetAccelerometerData ShockproofGetAccelerometerData;
  27. cin>>a;
  28. if (hDll != NULL)
  29. {
  30.  
  31. ShockproofGetAccelerometerData = (funcShockproofGetAccelerometerData)GetProcAddress( hDll, "ShockproofGetAccelerometerData" );
  32. if( ShockproofGetAccelerometerData )
  33. {
  34. AccelerometerData ad = { 0 };
  35. ShockproofGetAccelerometerData( &ad );
  36. cX = ad.LatestZeroG_X;
  37. cY = ad.LatestZeroG_Y;
  38. cout<<cX<<","<<cY;
  39. }
  40. } else {
  41. cout<<"hDll is null";
  42. }
  43. return 0;
  44.  
  45. }

这段代码将调取Sensor.DLL,获取到坐标值,然后输出,并被AIR应用获取。

将这个文件编译为EXE文件,待用。

步骤二:使用Flash CS4准备素材

这里例子里我们需要一个小球,这个小球我们使用Flash CS4来制作,非常方便,整个过程可能不会超过2分钟:)

首先打开Flash CS4,使用绘图工具,绘制一个小球,并转换为电影剪辑。

然后,在库面板中的电影剪辑上点击右键,设置为导出类。这是为了在Flex项目中直接使用这个类,来创建一个可视的球体。

最后,记得打开文档属性面板,设置导出SWC文件,一会儿我们需要将这个SWC文件放入Flex项目中使用。

步骤三:创建AIR项目

使用Flash Builder4,创建一个AIR2.0的项目,如果你是第一次创建,请参考这篇文章,配置好你的AIR SDK。

注意修改项目的AIR应用配置文件(如果项目是AIR2AccelerometerDemo,那么配置文件就是src目录下的AIR2AccelerometerDemo-app.xml),增加一行:

<supportedProfiles>extendedDesktop</supportedProfiles>

这是为了标明,这个AIR项目要以本地安装文件(.exe)来运行,而不是作为跨平台的AIR文件,否则你会收到不支持NativeProcess的运行时错误。

将第二步创建的SWC文件,拷贝到项目的Libs目录。

将第一步编译好的exe文件,拷贝到项目的src目录。

在你的应用程序主文件中,粘贴如下的代码:

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml"
  3. applicationComplete="init()"
  4. layout="absolute"
  5. backgroundColor="0x000000">
  6. <mx:Script>
  7. <![CDATA[
  8. import flash.display.StageDisplayState;
  9. import flash.events.Event;
  10. import flash.events.TimerEvent;
  11. import flash.utils.Timer;
  12.  
  13. import mx.controls.Alert;
  14. private var process:NativeProcess;
  15. [Bindable]
  16. private var resultData:String;
  17.  
  18. private var ball:Ball = new Ball();
  19.  
  20. private var delayTimer:Timer = new Timer(1000,0);
  21. private var ySpeed:int;
  22.  
  23. public function init():void
  24. {
  25. if (NativeProcess.isSupported)//判断是否支持调取本地进程
  26. {
  27. launchEchoTest();
  28. delayTimer.addEventListener(TimerEvent.TIMER,writeData);
  29. delayTimer.start();
  30. myContainer.addChild(ball);
  31. stage.displayState = StageDisplayState.FULL_SCREEN_INTERACTIVE;
  32. ball.x = (stage.stageWidth - ball.width)/2;
  33. ball.y = stage.stageHeight - ball.height - 20;
  34. ball.addEventListener(Event.ENTER_FRAME,enterHandler);
  35. }
  36. else
  37. {
  38. resultData = "NativeProcess not supported.";
  39. Alert(resultData);
  40. }
  41. }
  42. public function launchEchoTest():void//这个方法初始化的时候即执行,运行exe文件,等待输入参数
  43. {
  44. var file:File = File.applicationDirectory;//创建File对象
  45. file = file.resolvePath("TestCCC.exe");//指向你的exe文件
  46.  
  47. var nativeProcessStartupInfo:NativeProcessStartupInfo = new NativeProcessStartupInfo();//创建进程信息对象
  48. nativeProcessStartupInfo.executable = file;//将file指定为可执行文件
  49.  
  50. process = new NativeProcess();//创建一个本地进程
  51. process.start(nativeProcessStartupInfo);//运行本地进程
  52. process.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, onOutputData);//侦听进程的输出信息
  53. process.addEventListener(ProgressEvent.STANDARD_INPUT_PROGRESS, inputProgressListener);//侦听进程的输入信息
  54. }
  55. public function writeData(...args):void
  56. {
  57. process.standardInput.writeUTFBytes("0\n");
  58. }
  59. public function inputProgressListener(event:ProgressEvent):void
  60. {
  61. process.closeInput();//关闭输入
  62. }
  63. public function onOutputData(event:ProgressEvent):void
  64. {
  65. resultData = process.standardOutput.readUTFBytes(process.standardOutput.bytesAvailable);//获取进程返回的数据
  66. ySpeed = int(resultData.split(",")[1])-518;
  67. trace(ySpeed);
  68. launchEchoTest();//再次启动进程,并等待输入
  69. }
  70. private function enterHandler(...args):void {
  71. ball.x += ySpeed;
  72. if(ball.x > (stage.stageWidth-ball.width)) {
  73. ball.x = (stage.stageWidth-ball.width);
  74. }
  75. if(ball.x < 0) {
  76. ball.x = 0;
  77. }
  78. }
  79. ]]>
  80. </mx:Script>
  81.  
  82. <mx:UIComponent id="myContainer" />
  83.  
  84. </mx:WindowedApplication>

然后,点击运行按钮,AIR应用会在全屏模式中打开,请确保你的电脑是Thinkpad笔记本,并且支持APS,然后试着掀起电脑的一侧,观察小球的运动方向。

实例项目下载:

AIR项目下载:AIR2AccelerometerDemo.zip

riadevID: 
您给予的分值: None 平均分: 8.3 ( 3 票)

报错了

VerifyError: Error #1014: 无法找到类 flash.text.engine::TextLine。

at global$init()

是为什么啊
这个是在eclipse里用的flex3插件版+sdk4.0+airsdk2.0
在fb4里面用的是
Please correct the following problem in the app.xml file for this application.

invalid application descriptor: descriptor version does not match runtime version

Launch command details: "D:\DevTools\Adobe Flash Builder 4\sdks\4.0.0_Air\bin\adl.exe" -runtime "D:\DevTools\Adobe Flash Builder 4\sdks\4.0.0_Air\runtimes\air\win" E:\work\AIR2AccelerometerDemo\bin-debug\AIR2AccelerometerDemo-app.xml E:\work\AIR2AccelerometerDemo\bin-debug

这是为什么啊

请使用3.5的SDK

请使用3.5的SDK

回复

如果我想使用4.0的sdk我应该怎么做呢?
我现在的项目用的是4.0的sdk
我应该怎么做呢?

嘿嘿 谢谢楼主啦 上回

嘿嘿
谢谢楼主啦
上回就看到了
但是下载之后不知道放到哪里了
现在需要用到了
刚才找了好久才找到
这回注册个账号
把这个论坛收藏了

严格的来讲,这些传

严格的来讲,这些传感器都是加速度传感器。说重力加速度传感器其实局限了他的功能。

他提供的是一个监测加速度的传感器,由于重力加速度是一只都有的,并且根据分力的物理原理,可以把重力加速度分解到x,y,z轴上。从而,我们得到一些读数,根据高中物理中的分力原理,来计算出当前设备所处的角度(相对于水平面)

这个传感器不光能够检测到重力加速度,也可以检测到由人为移动而造成的加速度。ibm笔记本的重力加速度感应器实际上是为了检测由汽车或者笔记本落地的颠簸过程中,外力加速度与重力加速度合成后,得到的最终的一个加速度。知道这个加速度后,就知道设备本身受到了多大的外力的作用(重力加速度一直不会变)并且可以用来暂停硬盘的旋转来保护硬盘盘片不受外部冲击力的毁坏。

如果能写一个C++或者C#

如果能写一个C++或者C#的壳程序,利用反射的方式(本人写JAVA的,不知道C++或者C#这边是不是也这么搞),让AIR传递你想要调用的DLL,方法声明。由这个壳程序来进行调用的话,基本上可以实现AIR随意调用Win32的所有API。实际上就相当于一个更加简易版的VB,但又有很牛逼的UI效果的编程语言-AIR横空出世了,呵呵。

估计这件事情,Adobe来

估计这件事情,Adobe来做会比较好。但估计Adobe又不会一直专注在windows上。

auzn

晕, 我也做了个~~ 不过用的是C#, 国外的CODE~~

http://www.codeproject.com/KB/system/LenovoAPS.aspx

哈哈,原理是一样的

哈哈,原理是一样的,不过对关注RIA的人来说能使用Flash技术做这件事是非常棒的

结合重力加速度传感

结合重力加速度传感器,实际上使得我们可以做很多有意思的应用。

发表新评论

  • 网页地址和电子邮件地址将会被自动转换为链接。
  • 行和段被自动切分。
  • 您可以使用下面的标签来高亮显示您的评论内容: <code>, <blockcode>. 可以使用"[foo]".旁边显示标签样式 "<foo>" PHP代码可以用这样的区块来包含<?php ... ?> or <% ... %>

更多格式化选项信息

验证区域
系统验证:请回答下面的问题