About

<#TEMPLATE_INCLUDE_NINEPAGE_ABOUTME#>
  • Feb

    23

    很多时候我们需要用到设备的唯一识别码。安卓系统获取设备唯一识别码的资料网上比较多,但它们也并不通用,因为现在市场上的很多安卓机实际上它们的系统都是经过设备厂商修改过的,比如小米的系统,阿里云OS手机系统等等,所以实际上并不存在一个真正通用的方法。以下这个方法仅适用于 iPhone / iPad 设备或桌面设备,并不适用于 Android 系统(原因在后面)。

    苹果设备的 “IDFA、IDFV、UDID、OpenUDID 等等”这些标识区别可以在百度上找到,这些标识除了真正的 UDID 和 MAC 物理地址之外,其它的标识在很多情况下是会发生变化的:最常见的情况就是还原出厂设置后,会生成一个新的标识符。网络上一些第三方能够获得 UDID 的 SDK,实际上都是 OpenUDID,并不是真正的 UDID。

    苹果公司政策规定开发者是不能够获取用户设备的物理信息的(在 iOS 4.x 时代是获取 UDID 和 MAC 物理地址的,后来的新系统中都开始禁止了访问这些信息)。如果利用核客技术访问私有 API 被审核人员发现,那么一定会遭到苹果公司拒审;既便上架了被发现也会被下架。

    重要的事情说三边

    1、苹果公司政策规定不允许第三方开发者获取设备真正的唯一识别码!苹果公司政策规定不允许第三方开发者获取设备真正的唯一识别码!苹果公司政策规定不允许第三方开发者获取设备真正的唯一识别码!

    2、利用核客技术或系统漏洞调用苹果私有 API 会拒和下架!利用核客技术或系统漏洞调用苹果私有 API 会拒和下架!利用核客技术或系统漏洞调用苹果私有 API 会拒和下架!

    3、利用任何标识符统计用户数据必须接受苹果公司审核!利用任何标识符统计用户数据必须接受苹果公司审核!利用任何标识符统计用户数据必须接受苹果公司审核!

    4、开发者不要仅研究技术,也要知晓各平台的政策!开发者不要仅研究技术,也要知晓各平台的政策!开发者不要仅研究技术,也要知晓各平台的政策!

    技巧

    同一时间是指精确到毫秒级的时间!目录与创建时间!!硬件磁盘根目录即文件目录!!!

    从理论上来说,我们可以在同一时间创建两个目录,但那仅仅是理论上的,所以标题中“唯一”两个字加了引号。两块闪存盘同时间被格式化完成?这个概率可能比两个目录的创建时间完全相同的机率还要低。

    代码

    import flash.filesystem.File;
    import flash.globalization.DateTimeFormatter;

    trace("硬件信息:");

    var rootDirArr:Array = File.getRootDirectories();

    for (var i:uint = 0; i < rootDirArr.length; i++) 
    {
        var file:File = rootDirArr[i];

        var date:Date = file.creationDate;

        var dtf:DateTimeFormatter = new DateTimeFormatter(LocaleID.DEFAULT);
            dtf.setDateTimePattern("yyyy/MM/dd HH:mm:ss");

        var creationTime:String = dtf.format(date);

        //看到最后的这个 milliseconds 值了吗
        trace(file.nativePath + ":" + creationTime + "," + date.milliseconds);
    }

    如果是在我的 Windows 7 中调试运行,它会显示(它并不需要系统管理员的权限就能读取):

    硬件信息:
    C:\:2009/07/14 10:38:56,526
    D:\:2010/08/23 23:59:31,18
    E:\:2010/08/23 23:59:46,99

    如果是在我的 iOS 9.2 (iPhone6 Plus)中运行,它会显示(不需要越狱):

    硬件信息:
    /:2015/06/25 17:47:25,10

    使用这个方法最大好处就是不需要 ANE 文件。既便用户在系统设置中还原位置与隐私、还原广告标示符、抹掉所有内容与设置、升级系统等,磁盘的创建时间都不会发生变化,既便用户完全重置系统,还原所有设置到出厂状态,磁盘的创建时间都不会发生变化。经过测试,只有在使用线刷 / 强制刷机的情况下,磁盘才会被重新创建并且格式化,磁盘的创建时间才会发生变化 

    额外的话题:关于 Android 系统

    然后,以上这个方法并不适用于 Android 系统,在 Adobe 官方的 API  手册中 getRootDirectories() 方法下面已经有说明:“在根不可读的文件系统上,例如 Android 文件系统,返回的 File 对象的属性并不总是反映真实值。例如,在 Android 上,spaceAvailable 属性报告 0。” 安卓系统可以使用原生的方式获取设备id,制作成 ANE 文件给 AS3 调用。但正如前面第一段所述的,既便是 Google 提供的 getDeviceId() 这个 API 并不通用,因为国内很多手机厂商对安卓系统进行了修改,很多权限都发生了改变。

    比如,在不使用 ANE 的情况下,在未经修改的安卓系统中,可以用如下方法读取 MAC 网卡地址。我在 HTC 手机中进行了测试,-app.xml 中的权限:

    <!--删除 android.permission.INTERNET 权限将导致无法调试设备上的应用程序-->
    <uses-permission android:name="android.permission.INTERNET"/>
    <!--应同时切换 ACCESS_NETWORK_STATE 和 ACCESS_WIFI_STATE 权限,才能使用 AIR 的 NetworkInfo API-->
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>

    AS3:

    var netWorkVec:Vector.<NetworkInterface > = NetworkInfo.networkInfo.findInterfaces();

    for (var i:* in netWorkVec)
    {
        if(netWorkVec[i].hardwareAddress)
            trace("MAC 物理地址:",netWorkVec[i].hardwareAddress);
    }

    结果输出了:

    MAC 物理地址: D8:B3:77:7F:00:47

    但是,同样的代码,在国内厂商经过修改后的系统里,它并不能正常输出 MAC 网卡地址,比如使用阿里云OS的联想手机经过测试就不能。所以如果 AS3 的安卓开发者们想要一个通用的获取设备硬件信息的方法,几乎是不可能。

    Jun

    26

    继续《Adobe AIR 读取屏幕物理点数(非物理尺寸、非像素尺寸)的方法》,如果不使用 StageWebViewBridge-master,这里提供一个通过 StageWebView 获取 iOS 屏幕物理点数的样例代码(如果是安卓系统,可以直接用那篇文章中引用的官方推荐值 DPI 值 160)。

    JS 部份主要代码:

    package
    {
        public class ScreenJS
        {
            public function ScreenJS()
            {
                throw Error("无法实例化的类")
            }

            //这是一个奇怪的字符串写法
            //可以参考这个贴子:http://blog.zinewow.com/post/270.html
            //这样写的目的只是为了方便字符串在AS中换行
            static public const xmlString:String =

            (<![CDATA[
                <script type="text/javascript">

                    function getInfo() 
                    {
                        var u = navigator.userAgent;


                        if(u.indexOf('iPhone') > -1 || u.indexOf('iPad') > -1)
                        {
                            window.location.href = "http://127.0.0.1/?" + window.screen.height + "x" + window.screen.width;
                        }
                    }     

                    getInfo() ;

                </script>
            ]]>);
        }
    }

    AS 部份主要代码:

    //某个地方生成了 StageWebView 对象并添加了侦听器,一般就要主函数吧
    var view:StageWebView = new StageWebView();

    view.stage = stage;
    view.addEventListener(LocationChangeEvent.LOCATION_CHANGING, locationChaningHandler);
    view.loadString(ScreenJS.xmlString);


    //侦听器函数
    private function locationChaningHandler(e:LocationChangeEvent):void
    {
          e.preventDefault();//我们并不是为了跳转网页,所以这里中止跳转

          var location:String = e.location;
          var dpi:String= String(location.split("?")[1]);
          trace("dpi:", dpi);
    }

    Jun

    25

    BlackBerry PlayBook SDK for Adobe AIR

    • 0 Comments
    • Flash Platform

    在找资料的时候发现黑莓曾经居然为 ADOBE AIR 移动开发做过独立的组件:

    https://developer.blackberry.com/playbook/air/apis/qnx/ui/listClasses/package-detail.html

    Mar

    27

    <android>
            <manifestAdditions><![CDATA[
                <manifest android:installLocation="auto">

                    <!-- 防止APP打开时移动设备自动进入休眠状态 -->
                    <uses-permission android:name="android.permission.WAKE_LOCK" />
                    <uses-permission android:name="android.permission.WRITE_SETTINGS" />

                    <!-- 百度与AdMob所需权限 -->
                    <uses-permission android:name="android.permission.INTERNET"/>
                    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
                    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
                    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
                    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
                    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
                    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

                     <application>
                            <meta-data     android:name="com.google.android.gms.version"
                                           android:value="@integer/google_play_services_version" />
                                 <activity     android:name="com.google.android.gms.ads.AdActivity" 
                                               android:configChanges="keyboard|keyboardHidden|orientation|screenLayout|uiMode|screenSize|smallestScreenSize"/>

                                 <activity android:name="com.baidu.mobads.AppActivity" android:configChanges="keyboard|keyboardHidden|orientation"/>
                     </application>

                </manifest>
            ]]></manifestAdditions>
        </android>

    Feb

    27

    <name>:用于屏幕上显示的目的,它可以包含类似空格、中文等字符。

    <filename>:用于作为设备上安装 AIR 应用时文件名路径的目的。(但经验丰富的开发者们推荐文件名路径的值最好不要包含空格、中文等字符,个人猜测可能是因为低版本的安卓系统、或特定的安卓系统中文件名路径不能很好的支持这类字符)。

    备注:另外打包时调有的 ADT 目标(target 参数)如果为安卓平台,那么 AIR 打包时的应用程序描述符文件也不能包含中文字符。比如在Flash IDE 环境中,它会提示“创建文件时出错,无法解析应用程序描述符文件”,命令行中也是相同的。

    Feb

    21

    Flash Builder 4.x (简称 FB)版本中提供了新建 Fla 项目的功能,但如 Fla 项目本身是一个 AIR 项目,FB 在“属性 - AS 构建路径”中是没有 ANE 扩展选项卡的。但如果 AIR 又必须用到 ANE 文件,又不想返回到 Flash 环境中去编写代码(因为 Flash IDE 代码编辑器的功能比较弱,没有代码重构、代码历史记录等功能,编码快捷键少),就可以用修改文件名后缀的技巧。

    用 WinRAR 等解压软件其实可以打开 ane 文件,会发现它的文件结构其实跟 swc 文件是一样的。所以只需要将 ane 文件名后缀改为 swc,然后添加到库路径中即可,这样就可以在 FB 中像普通的 swc 库文件一样使用代码提示、代码重构等功能了。

    一个更简单的方法是将 ane 文件放在项目文件夹的 libs 目录中,FB 会自动把 ANE 文件当成库文件来用:)

    Feb

    20

    国外的平台审核、提现都比较麻烦,比如信用卡、电汇码什么的。有些平台官方只提供了 SDK,没有提供 ANE,但 GOOGLE 上却又放着 ANE,也不知到底是官方提供的还是网友提供的。而且有些国外平台虽然提供了中文网站,但用的却是“蹩脚的中文”。

    国内的平台看了之后相对来说觉的方便一些,而且很多平台支持支付宝。因为是国内平台,所以中文很地道,不会因为是“蹩脚的中文”而看的一知半解。另外,国内的用户都喜欢即时通信工具 QQ,所以 QQ 客服很重要,能快速的回复各种问题。 

    比较之后,最后我选定了《芒果移动广告优化平台》,主要有以下几个原因:

    1、当天注册了 7 个广告平台,只有芒果移动广告优化平台在注册后不到一小时就通过 QQ 联系了我,并且回答了我一些咨讯,即快速又热情。

    2、官方直接提供了 iOS 和 Android 两个版本的 ANE,这个在国内很少见,一般国内提供的都是对应的 SDK,AIR 开发者需要自己手动去生成 ANE 文件。

    3、这个是一个广告聚合平台,所以各种主流的国内或国外的广告平台可以自己选。

    4、官方还提供了“云测试”,可以把开发好的 APP 上传后在多个平台进行测试。

    基本上就是冲着这四点就选定这个平台。

    Feb

    20

    原文链接:http://bbs.9ria.com/thread-156257-1-1.html

    ANE(AIR Native Extension)—— 是指本机扩展。简单来说,就是 AIR 在特定的平台上,想要实现 AIR 本身不能实现的功能,就可以通过 ANE 扩展实现。比如 AIR 只能被鼠标控制,但本身不能控掉鼠标,但 C 语言能实现这个功能,把 C 程序和 AS 程序打包起来,AS 调用 C 来完成 AIR 不能完成的任务。

    More...

    Mar

    12

     在 Adobe AIR 运行时环境中,Window 是 AIR 桌面应用程序中其它窗口的顶级容器,它除了最大化窗口功能(maximize())外,还可以使用全屏功能(StageDisplayState.FULL_SCREEN_INTERACTIVE)。但在全屏功能中它有一个“小陷井”,在某些情况下,如果按了ESC键或CTRL+S键这后,它有可能会退出全屏模式,甚至还会让窗口变的只剩两个滚动条(这应该是 Adobe AIR Window 留下的Bug)。不过可以通过对舞台(stage)实例添加全局的键盘事件(KeyboardEvent.KEY_DOWN)来屏蔽这情况:

    if(e.keyCode == Keyboard.ESCAPE)
    e.preventDefault();
    if(e.keyCode == 83 && e.ctrlKey)
    e.preventDefault()

    More...

    Feb

    19