Feb
23
纯 AS3 获取 iPhone / iPad 设备“唯一”识别码
- 0 Comments
- Flash Platform
很多时候我们需要用到设备的唯一识别码。安卓系统获取设备唯一识别码的资料网上比较多,但它们也并不通用,因为现在市场上的很多安卓机实际上它们的系统都是经过设备厂商修改过的,比如小米的系统,阿里云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.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 中的权限:
<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:
for (var i:* in netWorkVec)
{
if(netWorkVec[i].hardwareAddress)
trace("MAC 物理地址:",netWorkVec[i].hardwareAddress);
}
结果输出了:
但是,同样的代码,在国内厂商经过修改后的系统里,它并不能正常输出 MAC 网卡地址,比如使用阿里云OS的联想手机经过测试就不能。所以如果 AS3 的安卓开发者们想要一个通用的获取设备硬件信息的方法,几乎是不可能。
Oct
31
随机生成字符串 / 随机生成帐号与密码
- 0 Comments
- Flash Platform
比较通用,反正 AS、JS 之类的都差不多语法。
{
//帐号一般第一个字母不能为数字
var charsForFirstChar:String = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ";
var firstChar:String = charsForFirstChar.charAt(uint(Math.random() * charsForFirstChar.length));
var chars:String = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
var randomChar:String = "";
for (var i:Number = 0; i < _len - 1; i++)
{
randomChar += chars.charAt(uint(Math.random() * chars.length));
}
randomChar = firstChar + randomChar;
return randomChar;
}
static public function randomPasswordString(_len:uint):String
{
//密码往往是区分大小写的,并且允许使用一些特殊符号
var chars:String = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.,[]{}!@#$%&*()_-+=";
var randomChar:String = "";
for (var i:Number = 0; i < _len; i++)
{
randomChar += chars.charAt(uint(Math.random() * chars.length));
}
return randomChar;
}
Jun
26
读取 iOS 屏幕物理点数完整样例代码
- 1 Comments
- Flash Platform
继续《Adobe AIR 读取屏幕物理点数(非物理尺寸、非像素尺寸)的方法》,如果不使用 StageWebViewBridge-master,这里提供一个通过 StageWebView 获取 iOS 屏幕物理点数的样例代码(如果是安卓系统,可以直接用那篇文章中引用的官方推荐值 DPI 值 160)。
JS 部份主要代码:
{
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 部份主要代码:
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);
}
Mar
12
MinimalComps 带 Tree 组件
- 0 Comments
- Flash Platform
MinimalComps 因为它的轻量级一直比较讨人喜欢,但它并没有内置的树组件。在 GitHub 上找到了一个带有 Tree 组件的版本。
下载地址: minimalcomps-master.zip
配置数据:
var treeItems:Array = [
{ label:'treelist_test_app', items:[
{ label:'bin', expanded:false, items:[
{ label:'js', items:[
{ label:'swfobject.js' }
] },
{ label:'expressInstall.swf' },
{ label:'index.html' },
{ label:'TreeListTestApp.swf' }
] },
{ label:'lib', items:[] },
{ label:'obj' , items:[
{ label:'TreeListTestAppConfig.old' },
{ label:'TreeListTestAppConfig.xml' }
] },
{ label:'src', items:[] },
{ label:'file_tree_test.as' },
{ label:'TreeList Test App.as3proj' },
] }
];
创建组件:
testTree = new TreeList(mainContainer , 0, 0, treeItems);
testTree.setSize(200, 200);
testTree.addEventListener(Event.SELECT, handleTestTreeSelect);
侦听事件:
{
trace('TreeList select:', TreeList(e.target).selectedItem.label);
}
GitHub 链接:https://github.com/AdamHarte/minimalcomps
原文链接:http://blog.adamharte.com/added-treelist-to-minimalcomps/
- Tags: minimalcomps as3
- Read More
Feb
4
Starling 粒子系统
- 0 Comments
- Flash Platform
Starling 粒子系统扩展地址:
https://github.com/Gamua/Starling-Extension-Particle-System
一个免费的在线粒子系统编辑器:
http://blog.onebyonedesign.com/flash/particle-editor-for-starling-framework/
http://onebyonedesign.com/flash/particleeditor/
ZERO 大神对此在线粒子系统编辑器的汉化版:
http://blog.zinewow.com/upload/pd.html
其它版本:
Dec
25
FlexBook / FlipPage / AS3 翻页引擎源码
- 0 Comments
- Flash Platform
原文地址:http://www.rubenswieringa.com/blog/flex-book-component-beta
原博客主好几年都未更新博客了,将来也许有一天会关闭博客,我先转载过来收藏一下,个人觉的这份 AS3 版本的 Flex 翻页源码非常棒。
它的主要功能包括:翻页效果、自定义硬翻页或软翻页效果、支持透明页面、锁定页面、撕页效果等等(反正它的原文中都介绍了并且提供了 DEMO 效果)。其中撕页效果非常炫,它能将一个页面像一张纸一样从书籍中撕下来。
我的翻页日记本程序《Dear Diary - 桫椤札记》用的就是这个翻页引擎。
源码下载: 翻页效果源码demo.zip
API 手册:
http://www.rubenswieringa.com/code/as3/flex/Book/docs/
Nov
20
AS3 单例模式
- 0 Comments
- Flash Platform
{
public class Instance
{
//是否已经有单例对象
static private var _hasInstance:Boolean = true;
//单例
static private var _instance:Instance;
public function Instance()
{
if(_hasInstance)
{
throw new Error("这是一个单例,须通过 getInstance() 获取实例");
}
}
static public function getInstance():Instance
{
if (!_instance)
{
_hasInstance=false;
_instance = new Instance();
_hasInstance=true;
}
return _instance;
}
}
}
Oct
21
支持 AS 的跨平台开发引擎:Loom SDK
- 0 Comments
- Miscellaneous
Oct
12
一个控制声音的类:SoundAS
- 0 Comments
- Flash Platform
在绝大多数情况下我们只是需要简单的控制声音的加载、播放、暂停、淡入淡出等,这个足够用了,可以免去 Flash 内置声音控制相关的类业务太繁杂的过程。
https://github.com/treefortress/SoundAS
- Tags: as3 SoundManager
- Read More
Aug
18
Flex 框架的 AS3 两次密码匹配验证器
- 0 Comments
- Flash Platform
import mx.validators.ValidationResult;
import mx.validators.Validator;
public class MatchValidator extends Validator{
private var _matchSource: Object = null;
private var _matchProperty: String = null;
private var _noMatchError: String = "Fields did not match";
[Inspectable(category="General", defaultValue="Fields did not match")]
public function set noMatchError( argError:String):void{
_noMatchError = argError;
}
public function get noMatchError():String{
return _noMatchError;
}
[Inspectable(category="General", defaultValue="null")]
public function set matchSource( argObject:Object):void{
_matchSource = argObject;
}
public function get matchSource():Object{
return _matchSource;
}
[Inspectable(category="General", defaultValue="null")]
public function set matchProperty( argProperty:String):void{
_matchProperty = argProperty;
}
public function get matchProperty():String{
return _matchProperty;
}
override protected function doValidation(value:Object):Array {
var results:Array = super.doValidation(value.ours);
var val:String = value.ours ? String(value.ours) : "";
if (results.length > 0 || ((val.length == 0) && !required)){
return results;
}else{
if(val != value.toMatch){
results.length = 0;
results.push( new ValidationResult(true,null,"mismatch",_noMatchError));
return results;
}else{
return results;
}
}
}
override protected function getValueFromSource():Object {
var value:Object = {};
value.ours = super.getValueFromSource();
if (_matchSource && _matchProperty){
value.toMatch = _matchSource[_matchProperty];
}else{
value.toMatch = null;
}
return value;
}
}
}