一定要注意身体啊!!!!

几个月前的样子吧手腕剧痛,尤其是抓着鼠标的右手,之后换了mba又注意休息手腕之后好了很多.

不过最近又发现后颈在每天起床之后都巨酸痛,开始来以为是破枕头的问题,刚准备攒半个月的工资买个tempur的枕头,结果发现似乎和使用电脑的坐姿有很大关系,我用笔记本都是放在桌上需要低着头用的,所以还是把钱剩下来调整坐姿试试看吧.

一定要注意好身体啊!!我在多大就那么多毛病了啊π_π

顺便推荐一个教正确坐姿的视频

http://www.tudou.com/programs/view/I-Dap66v2cs/?resourceId=0_06_02_99?fr=2#fullscreen

随笔 October 4, 2013

一大早看到极简番茄在Google Play上多了个2星的挺不爽的

不过看到Chrome在Google Play上有4万多个1星顿时就释然了。。

设计一个绝对准时又相对省电的Android 倒计时方案

如果没有小米的话就不用写这个文章了。。

本文是这个这个的后续,欲在现今环境下打造一个绝对准时又较省电的倒计时方案。

  • 目标:在软件的多个界面中都能一定准确的显示倒计时,无论手机处于何种界面或状态都能准时的提示,在非小米手机中能达到几乎不耗电量。

  • 概述方案:记录开始计时的时间和进行状态到本地,针对小米启动一个service进行wakelock防止其休眠,

小米准时唤醒验证程序:

简单的搜了下wakelock应该没被小米阉割,所以要测试的内容为:不使用wakelock下的带和不带wakeup alarmmanager 的提示情况,使用wakelock下情况。顺便记录下开机,锁屏时间。

记录内容模拟:

—————Wakeup AlarmManager TEST—————–

[2012/10/02 16:02:02]  System boot completed.

[2012/10/02 16:02:02]  add a alarmManager with wakeup to 16:12:01

[2012/10/02 16:02:02]  <16:12:01>alarmManager with wakeup alarmed at 16:15:01

[2012/10/02 19:32:22]  —Screen off—

[2012/10/02 19:32:02]  add a alarmManager with wakeup to 19:33:01

[2012/10/02 19:32:02]  —-WakelockService started—–

好累啊感觉不会再爱了T_T

update:

测试程序搞定

https://github.com/dacer/XiaoMiTest

但是发了email之后都木有人愿意帮忙..是发的姿势不对嘛!!!

update(Oct 6):

有回复了,确认有效。

我从eclipse转到IntelliJ所做的事

早就不想用那个蜗牛速的eclipse了,于是着手准备转到Android studio开发

1.鼠标悬停看javaDoc – 找到安装目录下的 bin/idea.properties ,填上下面一行

<code>auto.show.quick.doc=true</code>

但是实际测试无用。又找到一个方法可显示,如下

Settings –> Editor –> Show quick doc on mouse move

开新坑了,基于sinatra的中韩汇率查看网站

—-点击查看—–

大概就是sinatra做后端进行post等行为在银联官网上读取银联汇率,前端直接显示结果。

部署在了openshift上(就剩1个免费份额了好捉急!)

显示效果嘛很明显是抄袭google now。。果然我的设计是硬伤。。

当然这个是开源的,不过没啥意义就是了。。

github: https://github.com/dacer/RMB2WON

todos: • 汇率计算器 触摸和输入型

• FAQ

analytic

如何在Action Bar中显示一层进度条,如7x7

看到这个需求第一时间我就想到了之前很沉迷的游戏 7x7, 搜了一下果然有相关的问题,链接如下:

http://stackoverflow.com/questions/17173414/how-to-implement-a-dynamic-background-on-actionbar-like-7x7

7x7作者亲自现身说道:

I actually made a custom Action Bar that was transparent and added the level progress bar underneath it.

然后给出了这个windowActionBarOverlay链接,于是开始

尝试1:

将Action Bar设置为透明且可和下部分重叠,先简单的放了个button试了下,效果如下:

Screen-Shot-2013-09-30-at-4.49.52-PM

之后用testin测试了下其他机型的适配情况,除了联想的一个奇葩机型之外都如图显示,于是意外的得出了个结论,button高度=Action Bar高度(这是歪打正着吧(╯‵□′)╯︵┻━┻)

尝试2:

但这样还是不太方便,于是兴冲冲的研究了半天这个pull-to-refresh的源码,发现它的原理是在Action Bar上覆盖了一层,这不是完全没用嘛 (╯‵□′)╯︵┻━┻

不过发现了这个方法

1
2
3
4
5
6
7
8
9
public int getActionBarSize(Context context) {
  int[] attrs = {android.R.attr.actionBarSize};
  TypedArray values = context.getTheme().obtainStyledAttributes(attrs);
  try {
    return values.getDimensionPixelSize(0, 0);
  } finally {
    values.recycle();
  }
}

最后得出的结论就是:目前看来还是用方法一,然后写个drawable作为自定义粗的进度条
Update
最后用的方法是,仿照actionbar做一个 custom view = =

为什么部分小米用户在使用极简番茄时提醒会延迟

很多小米用户反馈时间会错乱,之前一直以为是后台的Activity所占用的内存被清空所致,但修改后发现仍未改善,最后终于让我找到了根本原因。

使用AlarmManager定的带有WAKEUP闹钟会被某些版本的MIUI系统推迟。

我下面用浅显的语言说明一下

每个软件都可以设置某个时间点的“闹钟”唤醒本程序,但是小米处于省电的考虑将每5分钟时间段内的“闹钟”集中在一起唤醒,例如启动番茄的25分钟后是12:31,但小米会强行将其改为12:35分,故程序的逻辑被彻底打断。

此问题在将来有可能会通过系统补丁的方式修正,但不知会是何时,身为软件作者对此只能很无奈了,

解决方案如下:

  1. (推荐)刷Android官方系统或者优秀的第三方CM系统可彻底解决此问题,但有可能造成使用上的略微不便(MIUI在某些方面还是有其优点的)

  2. (不推荐)使用我做的小米专用版本.apk),在未开启快速模式且开启屏幕常亮时理论上可正常使用(但仍不能确定),即不让屏幕锁定,(在番茄进行中点击时间可隐藏它,配合黑色全屏主题效果较佳)

3.等待小米更新系统修改这个问题。

以上。

更新又一种方式: 

http://bbs.zdworks.com/forum.php?mod=viewthread&tid=166869

极简番茄BUG记录

硬伤:

切换Google账户BUG:1.正常使用帐号并授权同步2.在网页端撤销授权3.同步后FC

软伤:

切换Google Task同步之后本地task不会重置

极速模式下横屏时开启屏幕会再次被锁屏(因为重新调用了onCreate中的锁屏方法)

极简番茄运作流程分析及防止后台被杀方案

本人写的软件标题为啥是分析呢,因为我已经把基本的流程忘的差不多了..所以要重看一遍源码梳理下,(果然边学边做的后果就是代码超乱的!!都想重写一遍了!!!)

把当时的规划图翻出来了,其实看看挺弱智的,毕竟当时的目标是能做出这个功能就行。。

整理了一半三分之一懒得整理了。。

Screen-Shot-2013-09-17-at-6.55.18-PM

先说一下本次修改的目标为后台的activity被杀之后仍能正常工作

Bug出现的手动方法为进行番茄,退出为后台,长按Home键退出本activity,点击通知栏的返回,重新计时25分钟。更有可能出现的情况为:内存清理软件,系统内存不足时自动清除本软件。

大体思路为:番茄/休息开始时记录结束时间以及当前为番茄还是休息,用户中断或者完成时归为0,启动软件主画面时检查当前时间是否在记录时间之前,是则跳入番茄/休息运行画面,否则继续展现主画面,进入番茄/休息画面时判断是否紧接着开始,将通知栏的进行中的intent指向MainActivity

这样像贴胶布一样的更新方式还看的真有点蛋疼,但是经一个外国人的feedback建议之后发现根据本文这样修改后可以无痛的横竖屏转换了XD

Android 使用google Task Api开发笔记

极简番茄的菜单里摆着灰色的同步google task好久了,之前曾经做了个不可编辑只可查看的版本,再往下弄发现太蛋疼了就暂缓了,这两天又心血来潮的准备填了这个坑,下面来记录一下这个制作的过程(不然我怕过两个月就看不懂代码了..)

首先先来看看Google task api的开发文档,Google提供了两种方式调用api:一种是client library,一种是发送http请求获取,我比较懒就用现成的library好了。不过竟然API一天只能5000次啊!!!我只能默默的努力减少调用了。。

怎么在项目中加入library就不细说了,下面是本文的重点,如何同步本地sqlite数据库与google服务器中的数据库。(太过细微的地方已省略)

我先建立了两个方法: public void putTasksToDB(List tList){...}public List getTasksFromDB(){...} 用于将Google给出的Task类存入本地数据库和从数据库读取出,也就是将Task的各个我所用到的属性一个个保存起来,这样就不用直接面对数据库了。 因为Task中包含delete属性,而不是直接将其删除,所以对数据库的操作可抽象为2种行为:Add Task 和 Update Task,这样给下面的流程带来了很多便利

Refresh流程

这个很重要我先把它放在首位,下列图中我将本地的Task划分为Add(新增加)Update(已修改)和 未修改(图中无显示) 第一步: 将本地数据库中Task导出至List listTaskLocal,将本地增加的Task推送至Web,同时删除本地database中对应数据(为了更新web端的identifier)

发现上述方法会因为新task的identifier相同而一次性的全删掉了。。

改为建立一个HashMap保存Task以及对应的数据库id

第一步

第二步:

将Web数据库中Task导出至List listTaskWeb,根据identifier将listTaskLocal中没有的Task存入本地数据库[*为防止之前数据库中仅有本地新增的task,需更新listTaskLocal]

第二步

第三步:

重新获取listTaskLocal与本地数据库同步,对比相同identifier的listTaskLocal和listTaskWeb中的update_date项,将该项时间较新的Task覆盖较旧的(即分别更新本地或web数据库)。

第三步

*实际使用会发现一个小Bug,在网页端删除tasklist之后同步本地的数据库不会被删除,因为这不是用delete标记过的删除行为,需要在初始化教程list的同时清空本地数据库

优化API调用流程

5000次每日真的很蛋疼啊。。只能想办法减少调用了

简略的想法就是:1.手动刷新 2.在本地储存list ID,为防止list被用户在网页端删除,在刷新检测不到list时重新初始化list

在经过不断的测试之后会发现task API在调用时list ID格式正确但不存在会返回404错误,格式错误时则会反馈400错误,故流程如下:

1.在本地保存task时identifier设置为0,从web下载所得的identifier为相应的web对应值。

2.刷新时先将本地identifier为0的Task(即仅在本地新建而未上传)上传至web端,并删除本地数据库相关数据,如上传是服务器反馈错误为404则说明用户删除了web端list,或者当新安装软件时list ID格式不正确会返回400错误,如是这两者错误则初始化web端list。

*这步有个大坑。。在本地新的Task的时候改Task的id为0,会导致上传返回400错误,必须先set为null。果然是这个方案没有经过深思熟虑的后果╮(╯_╰)╭

3.其实最佳方案是将待修改的tasks一并上传至web端,不过找了很久都没发现有这么个方法,如果有人知道怎么调用一次API将所有tasks上传上去请务必告诉我!

最后结果就是本地无改动时刷新API调用为1次,每增加一个改动/增加的task后刷新API调用加一。。

关于自定义listview和本地数据库一一对应的方法:

在本例中我自定义了一个SimpleCursorAdapter,在它的构造函数中必须包含Cursor类型的参数来super到父类,而这个cursor则保存着显示的数据,

使用这个方法即可提取出cursor中某一row为ArrayList,其中TaskRecorder.KEY_ID为要提取的数据在数据库中的。。那一列的名字? private ArrayList getAllIdOfBox(Cursor cursor) {

int idIndex = cursor.getColumnIndex(TaskRecorder.KEY_ID); ArrayList mPosition_id = new ArrayList(); for (cursor.moveToFirst(); !(cursor.isAfterLast()); cursor.moveToNext()) { int tempInt = cursor.getInt(idIndex); Integer integer = tempInt; mPosition_id.add(integer); } return mPosition_id; }

BUG!!!

在本地有的被hidden之后会出现bug!