Android

Android支持按键双击事件

最近做的东西比较杂,是得梳理一下了~ 参考了这篇文章。 按键双击,这种组合键的做法类似volume down键 + power键 = 截屏 因为两个按键之间肯定会有时间差,而双击其实就是x键 + x键; 开翻~ Android上keyevent,在framework层是由window manager来负责转发,找到PhoneWindowManager,会发现这里对于keyevent的各种intercept简直就是hook的绝佳地点: interceptKeyBeforeDispatching(WindowState win, KeyEvent event, int policyFlags) interceptKeyBeforeQueueing(KeyEvent event, int policyFlags) 等。。。 找到interceptKeyBeforeDispatching对volume down + power的处理(

Android

用Selinux遇到的限制

(一停手就是若干年啊。。。) 在做一个有趣的小功能,具体什么就不说了。中途遇到了一个问题,media进程直接写文件的时候无权限: fopen后strerrno(errno)是:permission denied. 翻了翻,应该是sepolicy(selinux)的限制导致的。 找到篇文章大概介绍了selinux和sepolicy设置(android L开始是建议厂商强制使用的) 还有一篇更偏实用。 打开/external/sepolicy/mediaserver.te (其实还有一个device/qcom/sepolicy/common/mediaserver.te,暂未确认是用哪个,还是做了一个交集) 但可以确认的是camera_data_

Camera

关于Camera(成像)

其实早就想写,但这种题目会让模电考试作弊才堪堪及格的我压力山大。。。 注意:这里的camera,基本指目前绝大多数的电子成像设备。 本文从一个有基本理科知识的角度,来科普性质的讲讲图像传感器都干了些什么(才助力陈老师造福全人类的)。当然也一定会有遗漏缺失错误的地方(不吝指出~) 本文很多内容,是基于《CMOS图像传感器集成电路原理、设计和应用》(罗昕 编著),这本书不错,让我重新梳理所学,值得看一看~ 小孔成像 在说到图像传感器前,先说说小孔成像;这是目前所有成像技术的光学基础 -- 光是直线传播的(在忽略引力作用的前提下): 尽管我不喜欢baidu,但是这篇百科中,墨子如是说: “景。光之人,煦若射,下者之人也高;

Android

Android Camera HAL3.0

官网文档在此 简单来说,3.0的设计初衷就是 -- 提供per-frame操作的灵活性。 更多细节在官网上写的很清楚了,这里就不再赘述。 罗列一些点,跨度比较大,想到哪说到哪。 Camera 接口 首先接口本身的设计存在缺陷: 例如setPreviewSize和setPreviewFrameRate是无关的。(但其实这很有关系) 对于ISP这种pipeline来说,类比水管,最大出水量是恒定的;所以理论上,单帧size越大,那帧率(fps)也就越低。 所以size和fps是应该有明确的对应关系的。但这个接口把这个关系打破了。 那是否就无法获取这种对应关系了那? 并不是。Camera提供了CameraCharacteristics来获取更具体的信息,但是要麻烦一些; 可以参考cts测试中,getAvailableMinFrameDurationsForFormatChecked的做法;通过StreamConfigurationMap来算出fps和width/

技术

Android library loading limitation

Android上想调用native算法库(so的形式),只能走JNI的路(用NDK来编译); 加载so的时候一般是用System.loadLibrary或System.load; 使用前者,则so只能提前push到系统目录或app对应目录下(不然找不到); 使用后者,一般情况下无路径的特别限制;这样便于控制app size(so可以单独下载到特定目录); 但是自从某个os版本后(确实不知道哪个版本后),sdcard卡上的so,也有了加载的限制。 例如报错:Android load library error — failed to map segment 该问题其实算是设备相关,某些内置卡的设备就不存在该问题;也正如stackoverflow上的回答,是权限问题; 出现该问题的设备:

技术

APK Expansion limitation

APK Expansion 公司的App打算shrink app size --> 因为有用户抱怨说app太大了看起来就觉得浪费资源bulabulabula。。。 其中APK Expansion也被列为了备选方案;翻了文档和Sample源码后确认了APK Expansion的一些限制: 超过50M的apk强制要求使用,不超过也可以使用; 可以使用任何格式作为expansion file,但只能有一个main,一个patch(即最多两个,各不超过2G) expansion的size算在app中;如160M的游戏,apk只有20M,但下载后app info看到的size依然是160M; expansion在一般情况下(on most devices)会随apk一起下载;在某些不能下载的设备上,可以手动下载;无法由app来选择,

技术

zsh + oh-my-zsh > default shell

尽管换上了MBP,terminal的使用还是不少的。。。 而且相比较ubuntu的terminal,osx默认的shell。。。配色太“单调”,提示也很弱。 所以找到了zsh + oh-my-zsh 安装配置文档都有。 可以自己make install zsh再手动配置oh-my-zsh; 或者直接curl -L http://install.ohmyz.sh | sh plugin设置好自己常用的(例如adb、git、go、osx、python等等); 然后选择一个喜欢的配色主题,就这么愉快的开工吧:

技术

Photo gallery from folder

当有大量图片需要快速分享出去的时候(例如出去玩,拍了大量照片,分享就变成了大麻烦;如果可以有一个简单的server(或其他机制)来快速分享,那就好多了) 目前搬砖的公司就遇到这个情况,年会有照片,但是因为共享机制的差异(mac访问windows共享),导致公司有不少同学无法拿到照片。 工作机之前搭过amp的环境,所以为了省时省力,就去搜了php gallery from folder Google前两位分别是UberGallery和FolioGallery 都蛮不错。我选择了后者(因为后者天生支持multi-directory listing!) 搭建起来很容易: 下载并解压缩放到web目录下 图片放到albums目录下 albums目录为www-data增加可写权限(因为需要在子目录下生成thumbnail) 浏览器打开foliogallery.php(点击对应目录生成thumbnail) 这就OK了!

Android

Android ImageFetcher

Google完善文档后,也提供了一大批优秀的源代码。 ImageFetcher就是其中之一,这货非常简洁的实现了用ImageView来异步加载网页图片,同时对图片进行二级缓存的功能。 稍微改改就可以轻松适配任何图片资源(例如本地,例如需特殊条件(如宽高,比例,透明度等)等)了。 主体代码构成: 外部调用如下: New: ImageFetcher imageFetcher = new ImageFetcher(context, width, height); 就可以了。 当然这里一般都会改动; 例如为了区分cache目录,会把unique folder name作为参数传入进去)。 例如为了替换默认图,把图标传进去。 例如为了适配任何图片资源,增加自定义的ImageProvider,

技术

Proguard混淆

这里仅仅说Android的混淆,其他平台基本相同。 不同的IDE有不同的配置方法。 Android Studio的配置略有差异,可以参考前文 混淆的大致原理就是rename class(所以混淆的过程比较慢),混淆的初衷,并不是为了不让人看源码,毕竟java的虚拟机机制就决定了,源码肯定是可以反编译出来的;其主要目的是让反编译后的代码“难以”看懂。 例如打开一个混淆后输出的mapping文件,可以看到: (某代码片段,请无视。) 这样一来,反编译后的代码里面,基本就是a.b.c(d.e)这种代码(也许原来只是Util.isNetworkAvailable(context)),大大增加了阅读难度;也就达到了防止反编译的目的。

技术

Jenkins+Github+Gradle+Android

也许题目换成《配置以Github作为源码仓库并用Gradle编译Android的Jenkins时遇到的坑》更恰当~ LOL~ 网上教学贴很多,不一一列举了。也可以参考前一篇(BTW,我想说Subversion Release Plugin比自带的Subversion Plugin好用多了)。本文主要补充配置Github和Gradle容易遇到的问题。 重要的plugin: Git plugin Gradle plugin 至于Github plugin之类的插件,自己看着办吧。 这里有几个容易出问题的地方 如何用Jenkins从Github获取代码: 建议使用Deploy keys 怎么用那?最好用.ssh/config,可以参考这里。 需要注意的是,在创建ssh key的时候,

Android

Android SparseArray中indexOfValue返回-1

继续Android。 SparseArray<T>是蛮好用的基本类型,一般用来替换掉HashMap<Integer, T>。 有时候偷懒,也会用它来替换Object[],也就是基本数组。 因为这货有indexOfValue(这样就不用去遍历找索引啦),遍历也比HashMap方便的多。可以满足对基本数组的需要(但性能不高,使用需谨慎,文档有详细解释为什么)。 但是,这玩意儿有个坑,也就在indexOfValue里面。 当用它来存储String时,可能会出现明明Value已经put进去了,但是indexOfValue就是返回-1的情况。 一开始还以为可能是线程安全相关的问题,还打算加锁来着。结果。。。 原因在于: Note also

Android

Android RelativeLayout中wrap_content和alignParentBottom的冲突

继续随便记录一下,之前也说过,Android类似的坑不少。 下面又是一例: RelativeLayout中,为了方便布局,子view经常会用到alignParentBottom/Top/Left/Right等,如: android:layout_alignParentBottom="true" 但这时候需要注意的是,如果parent是wrap_content的话,alignParentRight就意味着要求parent的layout_width="match_parent"; alignParentBottom就意味着要求parent的layout_height="match_parent" 这会带来什么问题那?

Android

Android LinearLayout动态增加item时Weight的设置

Andorid上,LinearLayout动态增加child item时,一般如下: addView(child) 即可。 child item可以从xml中直接inflate出来。 这里有个问题是,动态增加的话,child item中的weight,在add到LinearLayout后无效(用LinearLayout,很多时候就是冲着weight去的,因为可以很容易做到对齐和分割)。 唯一的办法是在addView的时候用新的LayoutParams来指定weight: addView(child, new LinearLayout.LayoutParams(0, ViewGroup.LayoutParams.MATCH_PARENT, 1)); 最好设置一下weightSum: setWeightSum(childCount); Android的layout配置中,

ghost

Ghost开机启动

Ghost本身是基于node.js的,这意味着 -- 常驻后台需要用到其他方式,例如&或者forever(官网建议) 但这样也需要使用类似sudo start_ghost.sh这种方式来启动,想开机启动的话还是需要使用update-rc.d或者cron 前者官网提供了一个说明,相当于自己写一个service 后者比较强大,用在这里有点大材小用。 简单点的做法就直接参考stackoverflow sudo mv /filename /etc/init.d/ sudo chmod +x /etc/init.d/filename

ghost

Ghost首页图片限制宽高

还是默认Theme。 如何显示图片可以参考[Ghost在首页显示图片而非摘要] 但是这样修改有一个地方漏掉了。就是图片的宽高,普通图片还好,但到了大图,就坑爹了。在首页显示比较大的图片,会直接撑破侧边。。。 本来以为Ghost应该支持类似![](xxx.jpg =500x)(以500 x auto的宽高来显示xxx.jpg)这种语法,结果不支持。。。 搜一搜,可以发现Ghost讨论组对于支持image的复杂操作(例如resize,旋转等)的呼声还是很高的,而且专门列了一贴来讨论,并且给出了若干可能的解决方案(都有各自的优缺点)。 这里先不考虑多size来适配的case,这交给Ghost的大神们吧~ 我只是希望首页显示图片后,图片宽高可控。 解决方法有两种:

技术

关于字符编码

以下内容纯个人理解,如有遗漏/错误等我反应过来再补充吧~ (感觉还是用类似Q&A的方式来写写比较好) 什么是字符? 在计算机里面,无意义的二进制0和1(如果不知道的话,继续看下去也没什么意义了。。。),按照特定的长度可以表示一个数值(例如二进制的1000表示十进制的8);对于不同的数值,如果有一个table来映射(有没有密码本的赶脚),那不同的数值就可以表示特定的含义 --- 字符。 例如,二进制里面的01000001: 十进制(也理解成表的话,只是“映射”方式更简单)就是65 在ASCII表里,对应的是英文大写字母A 你看,同一个数值,通过不同的table,就有了不同的含义(

技术

谈谈12306的数据泄露

好奇的不仅仅是数据“如何”泄露,更好奇的是哪位同学居然敢老虎嘴里拔牙,敢情也是不想在大天朝混了。 看报道说是被撞库了(个人意见:12306今年的表现确实可圈可点)。那往前推,最可能的还是CSDN那次明文密码(大500W)泄露事件(后面有一次更大规模的17173/uuu9的泄露,也是受CSDN那波的影响)。 那就拿这13W的数据(纯研究,不提供下载链接 -- Google,你懂的)分析下看看吧。 祭出杀器Notepad++,打开居然是乱码。。。改编码到GB2312,恢复正常。 考虑到CSDN上男女比例应该严重失调,那就验证看看~ 先统计一下女生(身份证倒数第二位是偶数)的数量。 打开正则表达式的WIKI(对,

技术

Android docs (OpenGLES)

最近在看OpenGLES,一直没机会系统的学习,算是补补以前的遗漏;结果发现了Android对应的官方文档。 也不知道什么时候慢慢补全完善的Android文档,终于可以看得入眼,并且有一些确实不错的内容了。 Training不那么鸡肋了。 Guide也比以前好多了。 推荐一下Android关于OpenGLES的Training和Guide。 尤其是这一段开头: Being able to define shapes to be drawn in the context of an OpenGL ES view is the first step in creating

技术

关于FFmpeg(进阶)

基本篇在此。 目前仅使用到了ffmpeg的读写文件/编解码功能,并未使用其去直接渲染。 这里说是进阶,其实也只能算浮于表面。因此主要记录使用ffmpeg以来遇到的坑,版本差异,android版本编译等。So,这里就不继续采用Q&A的方式了。 (本文并非通过ffmpeg.exe\bin传递command来进行处理,而是直接调用ffmpeg相关libraries中的api) FFmpeg libraries FFmpeg有以下库:(2014/12/24 ffmpeg 2.5.2),主要功能列在About中有基本介绍,这里不再赘述。 libavutil 54. 15.100