在美国飞Drone的几个常见问题

最近心血来潮买了个DJI Spark,飞了几次,也研究了很多东西,特别是在美国对于drone的一些regulation,写在这里,备个忘。

首先,需要向FAA(美国联邦航管局)注册吗?

不需要。简单来说,如果只是自娱自玩,是不需要的,但如果是以商业为目的话就需要。至于怎么区分是不是商业,这里有简单的描述。之前确实有FAA的规定说要必须注册,然后贴个注册的贴纸在drone上才能飞。但是根据今年(2017年)5月联邦上诉法院的一项裁决,自己玩玩的drone不需要向FAA提交注册,详细的可以看这里:https://www.faa.gov/uas/getting_started/registration_deletion/

那我就能随便飞了?

🙄不行。虽然不用注册,但是FAA还是列出了几项基本规定,比如在机场5-mile范围内如果没有事先说明是不能飞的。还有比如虽然是个人飞,但是如果drone超过55磅也还是需要向FAA提交注册。FAA网站上给drone写的Getting Started页面可以作为初步参考。另外,FAA也专门给个人自娱自乐型玩家写了一些guideline,比如低于400英尺,保持drone在视线之内,不要在有比赛的体育场上方飞,永远给有人飞机让行等等。

呀!我家附近就有一个机场,怎么办?

美国大大小小的机场有很多,很可能你家附近就有一个local的机场。在飞之前,查好,提前通知就好。FAA自己做了个app叫B4UFly(Before you fly),可以根据当你所在地点显示是什么regluation,也可以搜索一个具体地方的regulation以便给目的地做功课。也有直接给当地机场塔台通知的功能,填写下要飞多高多远多长时间点发送即可。

这个B4UFly app好烂!

额。。。是的。。所以我个人更推荐AirMap。实时更新的地图数据库,比如什么时间在哪里有体育比赛,也有向机场塔台通知的功能,还有质量不错的iOS/Android app。网页版有个”Fly for Fun”的filter就很实用。不会像B4UFly,连医院警察局的直升机起降机场都算在内很容易让新手觉得intimidating。

国家公园呢?

所有的国家公园都是禁飞区(除非有permit,但没见到有拿到的),违反的话目前是最高6个月的jail以及5000块的罚款。另外有一点,这里所说的国家公园并不仅仅只是像黄石大峡谷这种热门或者面积大的国家公园,只要归national park services管的都算。比如金门大桥(隶属于Golden Gate National Recreation Area),或者Malibu海滩(Santa Moica Mountains)。

差不多就是这些了,这些法律法规时不时就会变,每次出行规划的时候得查清楚以避免不要的麻烦。最后上传今天在Hermosa Beach拍的日落:

2016

2015这一年,印象最深的就是去(浪)了很多地方。

  • 3月先是胆战心惊地去了次Tijuana续签签证,胆战心惊主要是被宣传了很多那里的都市传说,索性一切还算顺利。
  • 4月底5月初去了北九州(博多长崎福冈熊本和由布院),来到了拉面的故乡博多,拉面吃得是再也不要吃了,然后在东京玩了几天。
  • 8月初又去了次Tijuana,为什么呢?因为我护照丢了。。。去洛杉矶中国领事馆重新办了新护照(花了3个礼拜,呵呵)。但是因为下个月要去德国西班牙没有有效美国签证stamp是回不来的,也没有补办签证这一说只能重新办,所以就又去了Tijuana办签证,谁叫那是离我最近的美国大使馆呢。还是走正常的流程,跟签证官说了情况后,她叫我不要再弄丢了就通过了。
  • 8月末去了次纽约,主要是因为DroidCon NYC这个Android程序员的会,票价相比别的convention实在是便宜太多就去了。看了本以为很文艺会看不懂其实很十三会笑全场的The Book of Mormon。
  • 9月下半月就去了德国跟西班牙,出发前2天刚刚拿到的签证。一共只待了10天,德国就在法兰克福周边玩玩,科隆大教堂确实比较震撼,租了两天车开了下没有限速的路,去了逼格很高的徕卡总部。尝了很多好吃的,猪肘啦啤酒啦大香肠啦。还有两只超可爱的猫Joy和Lingling!西班牙就去了巴塞罗那,终于看了一场巴萨的球,可惜梅西4分钟就受伤离场,而且那个时候我还在巴萨纪念品店里买买买,就什么也没看到。巴塞罗那印象最深的就是好吃的东西很多,海鲜饭tapas还有Jamón ibérico!
  • 11月回了趟国。中途先去了日本,带爸妈在东京京都大阪走马观花玩了一周,感觉就是时间像飞一样刹那间就到了要回上海的那天。在上海的两周,基本天天都在下雨,空气倒是蛮好的,有几天特别冷,还问我爸借了衣服穿。面基了很多新老朋友,相谈甚欢,关键,吃了很多好吃的。
  • 圣诞节的时候去了三藩,其实15年三藩大概去了三四次了,这次是去Lake Tahoe滑雪。以前在波士顿的时候没有机会,今年趁着加州大雪,尝试了skiing,第一天下来是走不动路的。

工作上呢,公司里发生了很多狗血的事情,目测2016年会继续,我也就静观其变了。这一年算是全职写Java/Android的一年,本来很讨厌这两样东西的,但这一整年下来慢慢地发现太多有意思的东西可以琢磨,现在想叫我换别的方向我还不太愿意了。

这一年有点遗憾的就是我的Gibson摸得越来越少了,希望明年能够重新拾起来,不要到时候连Green Day都不会弹了(。

2016年,想做的事情还有很多,慢慢来了就。

2014年度H1B报税

又到了一年报税的时候,本着早报税早省(拿)心(钱)的原则,一拿到W2开始着手报了。

2014年度,一整年都是H1B,就不再享受那个适用于学生的中美$5000 Treaty,但是已经是税法意义上的居民,所以就可以用居民friendly诸如Turbo Tax/H&R Block的报税软件来节省很多时间。看了the wirecutter上针对报税软件的评测后,决定就用他们认为最好的:Turbo Tax

像我这样就W2跟一些简单的1099-INT, 1099-G的话,直接用Turbo Tax免费版本就可以了。免费版本其实就是帮你填写1040EZ/1040A,如果更复杂些的,就得额外付费买更高级版本了。另外免费版本仅仅包括报联邦税,如果州税要一起报的话,是额外要花钱的。因为我在加州,网上报州税的系统超级简单,就不用额外再花钱了。只需在联邦税填完后跳过州税,如果不小心使用turbo tax报了州税的话,可以在overview的时候去掉。Turbo Tax用起来还是非常简单的,如果你的W2上有control number的话,直接就可以导入了,无需再手动输入各种数字。然后按着向导,把州税的1099-G,利息税的1099-INT依次填上就可以了。信息都填完之后,会直接显示会退多少税(一般是按standard deduction来的)。其实这个数字各大报税软件基本都是一样的。如果觉得不满意数字,就得用高级版本来找是不是有别的项目可以退税。不过个人觉得如果需要用上高级版本的话,还不如找个会计师报了。

今年报税就是这样。我自己非常“不幸”,兴冲冲地去报税,最后不仅没有拿到退税,还要补交税。:(

Disclaimer: I do not provide tax, legal or accounting advice. This material has been prepared for informational purposes only, and is not intended to provide, and should not be relied on for, tax, legal or accounting advice. You should consult your own tax, legal and accounting advisors before engaging in any transaction.

Android JDK 7签名问题

前一阵要发布一个新Android版本,在发布的前一天晚上,QA突然跟我汇报说无法在一些Android设备上安装apk。看了下logcat说是INSTALL_PARSE_FAILED_NO_CERTIFICATES

百思不得其解中,想起前不久刚在Jenkins上把Java 6升级到Java 7(终于!)来编译Android app。Google了一番,发觉原来是用来给apk签名的jarsigner在Java 7中默认使用SHA-256和SHA256withRSA算法,而Android还没有完全支持,需要在用jarsigner的时候指定MD5withRSA为签名算法以及SHA1为摘要算法即可。比如如果是Maven作为build system的,在maven-jarsigner-plugin中的arguments节点里设置就行了。

<arguments>
    <argument>-sigalg</argument><argument>MD5withRSA</argument>
    <argument>-digestalg</argument><argument>SHA1</argument>
</arguments>

2015

2014年就这样过去了。刚刚去机场把lulu送回东京,也没什么心情写总结。心神不宁地网上乱转,都是上海跨年踩踏的消息。

这一年换了个工作,算是一个比较大且开心的事情。出远门玩了几个地方,东京魔都阿拉斯加还有大峡谷什么的。花了5个月看了本Steven Pinker的大部头「The Better Angels of Our Nature」,还是云里雾里的。今年演出明显看得少了,财务问题好像略微改善了些。还有些别的,其实也挺重要的,但还是留给自己好了。

2015年,也没有什么特别想在这里说的,但感觉要做的事情还是很多的,一件一件慢慢地来吧。

在Android项目中启用ProGuard

最近不得不面对Android 65k method limit问题,所以启用ProGuard来除去一些没有被调用到的方法来降低被引用的方法总数(referenced method count)是一个不错的暂时的解决办法。

启用ProGuard
如何启用其实非常简单。如果项目是用Maven作为build system的,在app项目的pom文件里的android maven插件的节点下加入:

<proguard>
    <skip>false<skip>
    <config>proguard-project.txt</config>
</proguard>

proguard-project.txt即是配置文件,待会儿会详细讲。如果是Gradle的话,可以在buildTypes里加入1

runProguard true
proguardFiles file('proguard-project.txt')

启用后,每次build一般都会生成四份文件,dump.txt/mapping.txt/seeds.txt以及usage.txt。

  • dump.txt:包含了最终在.apk文件里的类结构
  • mapping.txt:如果启用了混淆代码的话(默认是开启的),这个文件里会列出原来的类/方法/成员的名字与混淆后的对应
  • seeds.txt:列出了没有混淆的类及其成员
  • usage.txt:列出了那些被去除的代码

配置ProGuard
在Android SDK的tools/proguard文件夹下有两个默认的配置文件,proguard-android-optimize.txt和proguard-android.txt。从文件名中可以看出一个是启用了优化另一个则是普通的配置文件。按需选择一个对一般的app来讲就足够用了。不过如果是因为64k问题而选择proguard的话,肯定也是个不一般的app,所以需要根据自己app的情况添加一些规则。这里有完整的ProGuard用法。那接下来说下我自己添加的几条规则供参考:

  • Warning: can’t find superclass/interface/referenced class:一般来讲,这是启用proguard最先会遇到的警告。这个警告说的是无法找到父类/借口/被引用的类,出现这个有可能是真的所需要的类没有被找到,需要指定包含这些类的jar的所在位置,但对于Android来说,很多情况下只需要使用-dontwarn规则来关闭这些警告就可以,因为在Android的编译过程中会自动指定所引用的jar。
  • -dontobfuscate:混淆代码后会使debug非常困难。即是是发布的版本,如果使用Crashlytics,最后收到的crash报告也是混淆后的,还是会使debug变得非常困难。虽然可以用retrace脚本来转换混淆后的stack trace,但是这样多做一步并不是很值得。不过如果你的app因为安全原因必须要混淆代码,那也只有这条路可以走了。
  • Automated Instrumentation Testing:如果你的项目里有Instrumentation测试,需要加入-keep public class * extends android.app.Application这样一条规则。因为每个测试项目会自动生成一个android.app.Application类,而ProGuard则认为这些Application类没有在任何地方被调用就自动剔除了,所以测试就没法在ci服务器上运行。这点我当时花了一天时间才最后解决的。:-(
  • Play Services:这个庞大的库本身就占用了大概两三万的方法数,虽然这个库在Android开发中算是必须的,但其实大部分都未必用得到,于是就造成了浪费。Google对于这个库有它自己推荐的规则,直接添加进来就可以。好消息是Play Services下一个版本6.5将会模块化。
  • Reflection:用到reflection的地方也是需要添加规则来保留这些类的。

Android 65k
现在我们来吐槽下这个65k问题Davlik是Android的运行时,其指令里有一个method reference index的变量,就是Davlik里最多能调用的方法数量。Android从出生到现在这个变量的大小从来没有改变过,就是16 bit,也就是令人发指的65536,从此,臭名昭著的65k限制由此而生。除了使用ProGuard外,还有一种比较流行的办法是multi-dex。

Ambitious New Android Developer

Multi-dex
随着app体积越来越大,即使用了ProGuard也还是会导致引用的方法数超过65536,于是有人就想到那我就编译多个dex文件,其中一个是主要的dex文件,然后在运行时再载入其他所需的dex。在Android新的运行时ART发布之前,这是非常繁琐低效的。随着ART的发布,multi-dex有了原生的支持,多个dex文件会在app安装的时候被编译成一个.oat文件让ART来执行,所以也不需要在运行时才载入所需的dex。而在ART之前的版本,Google也发布了支持multidex的库。详细的设置可以看这里:Configuring Your App for Multidex with Gradle。但这个归根到底还是一个hack,而且还是有很多限制,比如不怎么支持Android 4.0之前的版本,极大地增加了编译时间等等。

虽然看上去65k问题的实质很简单,但既然Google这么多年都没有能够修复,或许这真的是一个很难搞的bug。但话又说回来,随着移动领域越发地火热以及迅速地发展,不很好地解决这个问题实在很说不过去。


  1. Gradle指定ProGuard配置文件的时候还有类似getDefaultProguardFile('proguard-android.txt'),'proguard-rules.pro'这样的写法,直接从SDK里找到默认的配置文件再与自己项目特定的配置文件整合在一起,这点是Android Maven插件还无法做到的。

如何在终端下使用Swift

在安装完Xcode 6 Beta之后,首先先把Xcode的Developer tools切换到Xcode 6下。

sudo xcode-select --switch /Applications/Xcode6-Beta.app/Contents/Developer

然后在iTerm/Terminal下输入xcrun swift即可!