Android 应用如何判断是否是平板

从 Kindle Fire 到 Nexus 4 ,然后一坨坨的诡异山寨平板,现在 Android 平板也算是有一定的市场了。做 App 的时候自然会考虑去兼容一下平板版本, 兼容的方法不外乎两种,一个是再开发一套UI,然后可以出个HD版本或者直接包含在同一个APK中,另外一种就是等比缩放,让控件自适应。

听起来好像后者很厉害的样子,其实后者大部分情况都是很难看的,拉大也好,压缩也好,总是怪怪的。我个人是比较建议一个 APK 两套 UI 自动切换的模式,因为 Android 应用的包也不大,多一套 UI 也就是几百k到1M左右的事情,用户一般也都是 WIFI 下面更新应用,那么何乐而不为呢?

既然如此,那么我们就会涉及到一个问题,就是在应用中判断当前是平板还是手机,考虑到主流平板现在都是 3.2+ 的系统,这里主要讨论的是识别  3.2 以后的机器,当然出于兼容性考虑,后面我也会给出 2.x 的平板识别的方法。

最早的时候,我解决这个问题第一个想法是通过分辨率或者再考虑像素密度来解决。如果单纯考虑分辨率,大概就是这样的处理方式:

public static boolean isTablet(Activity aActivity) { DisplayMetrics metrics = new DisplayMetrics(); aActivity.getWindowManager().getDefaultDisplay().getMetrics(metrics); int width = metrics.widthPixels; int height = metrics.heightPixels; if (width > 1023 || height > 1023) { return true; } else { return false; } }

It works.只能那么说,这个方法我用了很久,基本上也没出啥问题,但是总感觉不够美观,不够 Android 的风格,到是像头痛医头,脚痛医脚的感觉,所以闲下来的时候就跑去翻看 http://developer.android.com 的一些说法。

很幸运的被我找到了,在猛击这里查看 这个页面有如下的一段描述:

One of the difficulties developers had in pre-3.2 Android devices was the “large” screen size bin, which encompasses the Dell Streak, the original Galaxy Tab, and 7″ tablets in general. However, many applications may want to show different layouts for different devices in this category (such as for 5″ and 7″ devices), even though they are all considered to be “large” screens. That’s why Android introduced the “Smallest-width” qualifier (amongst others) in Android 3.2.

于是认真的看了整个说明,发现其实 对于Android 3.2以后的机器是有比较好的区分方法的,就是通过在资源文件夹后面加 -sw600dp 来区分。比如说你想要在平板展示的layout就放到 layout-sw600dp 目录下,String, styles以及color等等都可以如此。如果是 3.2 以前的机器,可用 -xlarge 来区分。这样就可以将资源文件自动匹配映射,就和做多国语言的 Strings 一样,只要不同文件夹下的同名文件,就会匹配到相应的res中。

那么,这个解决了资源文件的区分,同样的,代码中如何区分的,比如说我平板上的 Button 叫 tButton,手机上的是 pButton,这个总不能通过新建文件夹来指定资源了吧。莫非还是要用上述的那个更具根据分辨率的方法?(其实这些资源文件夹区分方式也是系统去根据分辨率区分)显然不是,我们可以用一个更好的方法。分别建立如下文件:

res/values-sw600dp/bools.xml

true

res/values/bools.xml

false

res/values-xlarge/bools.xml

true

然后之前的 isTablet 的判断函数,就可以改成如下所示:

public static boolean isTablet(Context context) { return context.getResources().getBoolean(R.bool.isTablet); }

是不是美好简洁高端大气上档次了许多?O(∩_∩)O~

CodeBrowser3.3版本发布

这个版本的主要更新如下

1.带代码编码检测功能,常见的编码都能自动检测分析出来,中文不再悲剧

2.带代码编码选择功能,机器也会出错,万一检测出错,还可以手动选择编码,双保险

3.支持更多代码文件,基本上常见不常见的代码都能高亮,而且无序保证代码后缀名,直接自动探测代码语言

然后就感谢以下开源项目带来的帮助:
http://code.google.com/p/google-code-prettify
http://cpdetector.sourceforge.net/

详情请查看官方更新页面

http://www.zerob13.in/codebrowser/

昨日小事

在写下这篇文章的时候,一开始写的是“今日小事”,突然抬头一看,居然已经是凌晨1点多了,于是就翩然改为“昨日小事”。
昨天一天过的算是值得在记忆中留下一笔,昨天去了同学会,这是我高中毕业第二次参加同学会。依然是吃饭唱歌做游戏神马的。有的人变化很大,有的人几乎没变化,比如我。当然,不同的人不同的气质倒是在过了那么一些年后更加明显,也算是一种凝聚吧。金老师生了个女儿,挺好的,蛮有趣的一个小孩子。好吧同学会就略过吧,想说的我都说了,不想说的么,那就不说了。
晚上回来,继续开发那个胶片摄影小助手,把景深计算器的功能加上去了,然后版本更新到了0.3beta,发布在这里
http://www.zerob13.in/photographyhelper/
还有一个发布的地方是N多市场,地址在下面:
http://www.nduoa.com/
这里我要吐槽一下国内的几个android市场了,n多算是做的比较晚,但是比较好的一家,安智和安卓都是rom起家的论坛,所以在rom里面绑定,赚了不少用户。但是安卓的审核真tmd慢,安智的审核是脑残。n多的就比较好,有问题没问题都会主动联系你,比较有人情味,而且方便,很多事情你和人交流就好的多。安智的那个兼职脑残的我无语。我一个看源代码的软件放上去,这个明显是只能打开代码文件的么,他去打开其他的可执行文件之类的东西,然后说我fc还是无法显示就是bug,不通过。我说,你拿看pdf的东西去打开avi试试?太脑残了。
好吧,吐槽完毕,希望大家多支持胶片摄影小助手,这个软件还会不断完善:)

胶片摄影小助手0.2Beta 公测版

胶片摄影小助手 ,现在的版本是0.2Beta

发布页地址:http://www.zerob13.in/photographyhelper/

关于 胶片摄影小助手

这是一个帮助那些玩胶片的摄影师的一个实用的小工具

目前主要功能如下:

1.简易测光表:

通过输入现场的数据,计算出较适合的快门速度,方便摄影师估测曝光

2.定时器:

洗胶片的时候总是把握不好时间,有了这个小小的定时器,这些都不是问题了:)
正在开发中的功能:

1.水平仪

2.景深计算器

3.胶片资料查询功能

截图如下:

[1]( "1")

[2]( "2")

[4]( "4")

[3]( "3")

[5]( "5")

CodeBrowser2.6 新春特别版

下载地址:http://cid-d94239a09a81fece.office.live.com/self.aspx/.Public/CoderBrowser2.6.apk

更新如下:

  1. 修复了一些小bug
  2. 可以打开cxx,hpp等当时未考虑到的C语言源文件
  3. 修改了配色,大气的黑色背景强势回归
  4. 更新了高亮的js代码,速度略上升(基本上感觉不出来,囧)
  5. 缓存文件位置改变,不再是放在卡上,缓存放在了手机上,速度有提升

截图如下:

关于一些C语言编程的一些个人想法

首先么,这是个人风格,完全不是权威之说。
第二,记录下来只是感觉自己这样蛮舒服,分享而已。
第三,别拿某为谭姓叫兽的文章来说事情,不解释。
第四,这里的 C 语言不是狭义的指 C 这门语言,也包括 C++,object-c,甚至 Java 等类似与 C语法的语言
────────────────────────────────
好了,下面进入正文。比较琐碎,所以就想到什么讲什么了。
先说说一个判断 0 的问题吧,或者称为判断空值。一般空值常规的来思考分那么几种,NULL,0,0.0 以及 false(可能还有别的,但是常规就这些了,所以就讲这些)。那么这些分别有什么区别呢?
首先说说,写判 0 的风格是为了什么,因为 C 语言可以直接用这么一句话来表示几乎所有的空值
if(!a){}
那么,我要把判 0 的语句分开写,就是为了区别变量的类型,方便阅读代码
倒过来讲,先解释 false 的变量,一般这个变量都是布尔型的变量,那么这个变量就两个值,真或者假。所以我一般选择上面那种
if(!a){}
的方式来表示这个变量为假的时候执行什么。理由吧,个人偏好,也有一点认为,!作为一个逻辑运算符,而布尔是逻辑变量,所以凑在一起刚刚好。
然后是 0.0,这一般指 float 或者 double 的变量,这种变量的一个特点就是不精确。如果你直接用
if(a==0.0){}
之类的方法来表述,可能会出现不可意料的问题。所以这里我也选择一种比较流行的处理方法,就是让一个实型变量和一个极小的误差值 EPS 做比较。比如如下代码:
```

define EPS 1e-9

if(fabs(a-0.0)


就是这种方式,对于一个实型变量,最好把相等的比较转化成为大于小于的比较,原因么,不赘述了,学过组成原理就知道了。

整数变量不多说,最常规的方法



if(a0)


{}



然后是指针一类的,空值为 NULL 的,大家都知道 NULL 就是 0,但是书写的时候,还是最好把 NULL 写上了,这样可读性大大的增加。例:



if(a
NULL)


{}



判断0的问题大约就想到那么一些,然后说说几个小点。

第一个是一个规范问题,一般很多人都喜欢把函数声明和实现都放在一起。特别是类的成员函数,别的函数也一样。其实这个习惯不是很好,C语言也好,C++ 也好,都分为 .h 和 .c(.cpp) 两种文件,一般 .h 文件里面放声明,.c 文件里面放实现,包括成员函数。这个主要是方便别的利用你代码的人方便,不需要繁杂的翻看你的整个实现,只要看 .h 文件就可以对你的函数如何使用一目了然。

第二个是一个小细节,就是 void 参数的使用,这里说的不是



void main()




个人是很反对这种写法的,因为 main() 函数作为系统直接调用的函数,你如果不返回一个值给系统,系统怎么知道你的程序是正常还是不正常的结束的?个人感觉,我很反感用 void 来声明 main() 函数。

那么,这里的 void 指什么呢?就是指没有参数表的函数,希望在函数的参数表里面填写一个 void 原因吧,难说,这样写的确我说不上特别的好处,但是感觉会舒服很多,可能就是一个个人偏好吧。,原因是,加了void后,这个函数就被限制成为不能传入任何参数的函数了,如果你强行传入参数,编译会失败。如果不加在 C语言会认为这个函数可以传入任何参数的函数,区别还是很大的。(感谢蔡大牛提醒)。



int GetOne(void)


{

return 1;

}



第三点 就是解释一下 char* strcpy(char,char); 这个函数的返回值,然后抛砖引玉的来说说返回值的重要性。这里也许有些朋友会费解,明明 strcpy 的返回值已经给了第一个参数了,为什么还要最后 return 回来?这个不是“脱了裤子放屁──多此一举”么。其实不然,我们看如下代码就明白为什么了。



int length =strlen (strcpy(str,"zerob13"));




这个返回值就是为了这样的灵活性而考虑设计的,所以设计一个好的返回值对于一个好的函数也是非常重要的。

第四点,也是介绍一个神气的东西,叫做空循环。也许很多人学了c语言后一直不理解,为什么还要有个 do-while 循环,感觉有 while 不是已经够了么,这个东西似乎有点多此一举,其实不然。大家都知道,C语言是为了系统而出现的语言,这个 do-while 也自然和这个挂钩了。比如,你总是能够在 linux 的内核里面看到类似如下的宏。



define DUMP_WRITE(addr,nr) do{memcpy(bufp,addr,nr);bufp+=nr;}while(0)



总所周知,do-while 是先执行后判断循环,这里的while(0)也就是这个代码等价于:



define DUMP_WRITE(addr,nr) memcpy(bufp,addr,nr);bufp+=nr;



那么,我们为什么要套上这么一个 do-while 空循环呢?显然不行,一个小例子就可以说明,比如这个



if(OK)


DUMP_WRITE(addr,nr);

else


break;



如果,没有空循环,代码会变成这样子。



if(OK)


memcpy(bufp,addr,nr);

bufp+=nr;;

else


break;



然后,就悲剧了。但是,当你加上了 do-while 空循环的时候,整个循环被当作单独的一句语句,这样就可以达到正确的效果,如下:



if(OK)


do{


memcpy(bufp,addr,nr);

bufp+=nr;

}while(0);

else


break;

```

趣味:c语言递归main函数打印hello字样

今天下午没课,正好想起一个比较蛋疼的事情可以做,就是玩c语言的main函数递归。
首先还是说一下我的编译环境,哪些用m$的c语言编译器的朋友可以忽略这个文章了,放心吧,正常情况下是编译不通过的。。。
我的gcc版本是4.2.1。
先贴上代码~

#include #define ____ int #define o double #define O(x) printf("%c",x) #define (x) 1.0+1199.0*x/12.0-799.0*x*x/24.0+55.0*x*x*x/12.0-5.0*x*x*x*x/24.0 main(____ _) { o ;if(!)main(1);else if(6)return;else{=();O((____)(+0.5));main(+1);} }

跑出来就是一个不换行的Hello
哈哈,这个代码看着很恶心吧。好吧,让我给你翻译一下~如果我把上述代码的define还有一些变量整理一下,那就是这样的

#include int main(int argc) { int x; double ans; if(argc0) main(1); else{ x=argc; if(x==6) return; else{ ans=1.0+1199.0x/12.0-799.0xx/24.0+55.0xxx/12.0-5.0xxxx/24.0; printf("%c",(int)(ans+0.5)); main(x+1); } } }

现在看明白了么?
关键就是这句
ans=1.0+1199.0*x/12.0-799.0*x*x/24.0+55.0*x*x*x/12.0-5.0*x*x*x*x/24.0;
这个通项正是有穷数列72,101,108,108,111的通项。那么我是如何得到这个表达式的呢?
很简单,用多项式的拉格朗日插值公式就可以解决这个问题。
先把公式贴上来。

至于这个公式是怎么推导出来的,你可以看看这篇论文,讲解的很详细,这里就不复制过来了,哈哈
http://www.lw23.com/pdf_d659df85-fb38-47e6-ac02-147a12d2bab3/lunwen.pdf
有了这个通项就简单了,只要不断递归main函数,理论上可以答应出任意的函数出来。
ps:我求通项的时候用Mathematica来计算的,毕竟当数据多了,展开是个很麻烦的事情。。。然后又先用python写了个函数验证了通项正确后才改写成c的本身递归模式。囧

开始玩python

考虑到python的流行,于是乎我也开始凑热闹的玩起了python。
第一次写,写了一个最简单的递归八皇后~算是基础语法训练
贴代码,欢迎高手为我指出问题,不胜感激

# * coding: utf-8 * ''' Created on Aug 22, 2010 @author: yanglingfeng ''' import math a=[[0 for column in range(8)] for row in range(8)] hash1=[0 for x in range(0,8)] hash2=[0 for x in range(0,16)] hash3=[0 for x in range(0,16)] co=0 def dfs(line): global co if line>=8: str="" co=co+1 for i in range(0,8): for j in range(0,8): if a[i][j]1: str=str+'@' else: str=str+'*' str=str+'\n' print str return else: i=0 for i in range(0,8): if (hash1[i]1 or hash2[i+line]1 or hash3[i-line+8]1): continue else: hash1[i]=1 hash2[i+line]=1 hash3[i-line+8]=1 a[line][i]=1 dfs(line+1) hash1[i]=0 hash2[i+line]=0 hash3[i-line+8]=0 a[line][i]=0 return if name == 'main': dfs(0) print "共计",co,"种解"

CodeBrowser2.0 Android平台代码浏览器

首届Google暑期大学生博客分享大赛——2010 Andriod篇
支持大约20种语言的高亮了
终于支持多种语言的高亮了~
再次重新写了整个结构~
昨天的全部推翻。
用了开源项目
http://google-code-prettify.googlecode.com/
的代码,瞬间解决了各种高亮问题。。。
先上图


基本上可以当个程序使用了~
欢迎大家试用下载
猛击这里下载