2012年11月22日 星期四

Java RFC3986 URL Encode

http://designdotworks.blogspot.tw/2009/05/java-urlencode.html

因為在Java這邊目前沒有找到比較好的 RFC3986 規格的 URLEncode 。
也就是除了 a-zA-Z0-9 和 -_.~ 這四個符號,其他都要被 encode 過。 不過跟網頁內不同的是,我是改成


  1. encoded = encoded.replace("*""%2A");  
  2. encoded = encoded.replace("%7E""~");  
  3. encoded = encoded.replace("+""%20");  

Android findViewById Dynamically

http://stackoverflow.com/questions/3806847/how-to-create-findviewbyid-parm-dynamically-or-programmatically-at-runtime


int id = getResources().getIdentifier("cell00", "id", getPackageName());
TextView currcell = (TextView) findViewById(id); 

2012年11月21日 星期三

Put MapView In ScrollView

參考:http://stackoverflow.com/questions/6546108/mapview-inside-a-scrollview

簡單說就是讓ScrollView內的那一層不要接收Touch事件


@Override
public boolean onTouchEvent(MotionEvent ev) {
    int action = ev.getAction();
    switch (action) {
    case MotionEvent.ACTION_DOWN:
        // Disallow ScrollView to intercept touch events.
        this.getParent().requestDisallowInterceptTouchEvent(true);
        break;

    case MotionEvent.ACTION_UP:
        // Allow ScrollView to intercept touch events.
        this.getParent().requestDisallowInterceptTouchEvent(false);
        break;
    }

    // Handle MapView's touch events.
    super.onTouchEvent(ev);
    return true;
}

2012年10月23日 星期二

AQuery - jQuery For Android


jQuery For Android (AQuery)
http://code.google.com/p/android-query/

稍微看了一下,他把jQuery很喜歡用的 Chaining 作法拿過來用
所以整個用法看起來跟在寫網頁的 jQuery 語法很像。

而且這整套其實還是在 Java 環境下,並非在App內放WebView去做。
所以其實並不能叫做用 jQuery 去開發。

而且jQuery的核心精神就是 Write Less, do more.
看起來是真的少了滿多行程式。
而且也把一些常用的 Async 工作包好來用,例如:
  去遠端讀取圖片這種平常要寫一海票程式碼才能處理的很漂亮的東西

2012年10月18日 星期四

Use iPhone Like Pull-To-Refresh ListView

這一套是可以讓你做出像是 Facebook 那樣,可以讓使用者下拉列表就可以讀取新資料的Lib

https://github.com/johannilsson/android-pulltorefresh

Use ActionBar Before Android 3.x

這是一套可以讓 Android 2.1 以上的手機,呈現和 3.x 才有的 ActionBar 一樣的介面。
並且也幫你處理掉一些相容性問題。

Sherlock ActionBar
http://actionbarsherlock.com/

jQueryMobile 1.2

1.2正式版出了,所以有專案要使用也比較ok。
比較大的改變是多了一些元件可以使用,請自己點要看的元件玩玩。
Popup
Collapsible ListView

如果不熟的人,想要自己兜畫面給客戶看也可以用下面的工具,比較可惜的是新的元件還不支援。
http://jquerymobile.com/#try

有興趣的看更詳細的再自己看吧~

2012年9月20日 星期四

Sort List With Custom Comparator In Python

def asc_comparator(a, b):
    return a - b


def desc_comparator(a, b):
    return b - a

my_list = [8, 1, 3]
my_list.sort(asc_comparator)
>> [1, 3, 8]

my_list.sort(desc_comparator)
>> [8, 3, 1]

如果a, b是兩個物件也可以自訂comparator去取出要比的東西出來。
comparator 回傳值必須是 int
此為比較日期時因為我用 timedelta.total_seconds() 才注意到的

2012年8月13日 星期一

Git Flow Tutorial


英文的,這篇會用指令帶著做一次。
http://alblue.bandlem.com/2011/11/git-tip-of-week-git-flow.html

中文的
http://ihower.tw/blog/archives/5140/


指令:
https://github.com/nvie/gitflow/wiki/Command-Line-Arguments

git flow 是一套可以幫助你快速完成並且符合 git 的優良用法的輔助工具
下面介紹基本用法。

  1. 當然是先安裝 git 和 git flow 啦。
    brew install git git-flow
  2. 複製一個 git repository 回來
    git clone git@YOUR_HOST/YOUR_REPOS
  3. cd 進去資料夾用預設設定做 init
    cd YOUR_REPOS
    git flow init -d
  4. 開始寫功能abc
    git flow feature start abc
  5. 中間 git commit 好多次後,功能完成
    此時 git flow 會幫你 merge 回 develop
    git flow feature finish abc
  6. 重複 5. 多次後,準備 release 1.0版
    git flow release start v1.0
  7. 修修改改,準備上正式,此時 git flow 會幫你 merge 回 develop 和 master
    git flow frelease finish v1.0

2012年8月12日 星期日

Git Ignore Sample

在各種語言或環境中,可能會 ignore 的範例


把各自的內容寫到各 git 的專案根目錄下的 .gitignore 檔案即可

如果有通用原則,則可以寫到 ~/.gitignore 內。

2012年8月8日 星期三

Use Cookie In Iframe

Header加上 P3P 為 CP="NOI ADM DEV COM NAV OUR"

參考

GCM - Google Cloud Messaging FAQ

Google Cloud Messaging(GCM)是一個完全免費的推播服務,也就是能夠讓短訊息由客戶的第三方伺服器透過 Google 發給每個移動裝置的一個服務。

GCM 的前身 Cloud to Device Messaging(C2DM)服務也已經在2012年06月26號正式 Deprecated,不再接受註冊,必須改用 GCM。目前已有的 C2DM 仍可繼續使用。

使用限制

  1. Android 2.2 以上
  2. 有開啟 Google 服務的背景傳輸
  3. Android 4.0.4(不含)之前的手機要有一個 Google 帳號。

參數解釋

Client Side

  • Sender ID
    • 代表發送者的 ID。
    • 最多 100 個,超過以逗號隔開,如:"12345678,43218765"
    • 在 App 內指定要收哪些發送者的,用逗號隔開,App 收到時會包含此 ID。也就是說可以做不同角色的發送。

Server Side

  • collapse_key
    • Google 最多會存 4 個,超過不保證哪個會被忽略。
    • 如果今天是新郵件通知,使用者在關機時收到 100 個郵件,你不會希望使用者在手機打開時收到 100 次通知,就可以指定 collapse_key 讓使用者只會收到 1 次新郵件通知。
  • time_to_live
    • 最少 0 秒,最多 2,419,200 秒(3天)。
    • 某些通知所要傳達的事件可能是有時效性的,例如:有視訊電話打來、行事歷通知、奧運即時賽況分數…
    • 常常會和 delay_while_idle 設成 true 一起用。
  • registration_ids
    • 要發送的裝置 ID,每個 request 最多 1000 個。
  • data
    • 發送的內容,長度限制 4kb。
  • delay_while_idle
    • 如果裝置收不到,等到上線才會收到。

常見問題

  • Sender ID
    • 在 APIs Console 瀏覽器網址列的 Project 那串數字。
  • Sender Auth Token
    • Server 向 Google 發送推播的驗證
    • 在 APIs Console 的 Simple API Access 中的 API key

  • Registration ID
    • 由 Google 取回代表此裝置的 ID,要送給 Server 存起來。

2012年6月18日 星期一

Change ROM For Nexus Phone

Galaxy Nexus & Nexus S
官方 ROM 下載點
https://developers.google.com/android/nexus/images?hl=zh-TW

  1. 直接把電池拔下看手機背面的資訊,分辨自己手機的型號。
  2. 下載自己手機的 ROM
  3. 手機關機後,按住開關和音量鍵進入 Bootloader 模式。
  4. 解壓縮後執行 flash-all.sh

Root Yout Galaxy Nexus

參考:
http://www.modaco.com/topic/348161-01-feb-r4-superboot-rooting-the-gsm-lte-galaxy-nexus/

  1. 下載 Superboot r4 GSM,台灣是GSM。
  2. 在 Mac 上的話,用 command line 執行

    install-superboot-mac.sh

2012年6月10日 星期日

Decompile Android apk

參考:http://a4apphack.com/security/sec-code/extract-android-apk-from-market-and-decompile-it-to-java-source

下載完後,大概只要10 秒鐘。

  1. 使用 root 過的手機,從 /data/app 取出 .apk 檔。
  2. 下載 dex2jar ,執行 dex2jar.sh YOUR.apk,將 apk 轉為 jar 檔。
    http://code.google.com/p/dex2jar/
  3. 下載 JD-GUI 來看 jar 檔內的程式碼。
    http://java.decompiler.free.fr/?q=jdgui

2012年6月6日 星期三

NCR Encode In Java

到 Apache 下載 jar 檔
http://commons.apache.org/lang/download_lang.cgi

使用 StringEscapeUtils.escape() 即可。

參考:
http://stackoverflow.com/questions/2825985/how-to-convert-from-html-to-utf-8-in-java

2012年5月22日 星期二

Cocos2d-x Set Background Transparent

Cocos2d-x是一套可以支援多個平台上開發的 2D Game Lib
似乎有請到 Cocos2d 原作者加持,目前(May 2012)活躍度頗高。
http://www.cocos2d-x.org/

將背景設為透明(如果有需求是在後面疊相機的View)
http://www.cocos2d-x.org/boards/10/topics/4804

setZOrderOnTop(true);
http://stackoverflow.com/questions/2034822/android-opengl-es-transparent-background

2012年4月29日 星期日

Missing Translation When Export

不知道在哪一版的 Android SDK Tool 將 ANDROID_LINT_COMPLETE_REGIONS 改為要檢查。
在 Export 時會出一海票錯。

在 Mac OS 用 Eclipse 的話,Eclipse > Preference > Android > Lint Error Checking
的 Correctness: Messages > MissingTranslate
將 Severity 從 Fetal 改為 Warming 之類的。

不過秉持著做出好的 App 的良心,不建議大家把它改掉。
當然!我很沒良心的改掉它了。

2012年4月26日 星期四

Intent ACTION_SEND Share URL To Facebook

Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, "http://www.google.com/"); startActivity(Intent.createChooser(intent, "Share With")); 

這樣就可以直接在 FB 上分享網址,內容只能放網址!
當然,這方法有一好沒二好,因為是text/plain,所以Email就不能變成連結格式。

2012年4月2日 星期一

Android Version Code Length Limitation

AndroidManifest.xml versionCode 還是有長度限制的...就是一般 32-bit Integer 的長度限制。
官網只有寫Integer...這真是太隱晦了。
好啦,我承認我笨,看到 Integer 沒直覺想到這件事情。

不然你就會看到:Google Play requires versionCode to be set to a positive 32-bit integer in AndroidManifest.xml

參考:http://developer.android.com/guide/publishing/versioning.html#appversioning

2012年3月26日 星期一

2012年3月8日 星期四

Intergate Zxing To Android Project

http://damianflannery.wordpress.com/2011/06/13/integrate-zxing-barcode-scanner-into-your-android-app-natively-using-eclipse/

2012年3月6日 星期二

Android Load Local Image To WebView

前提:
我已經把圖檔抓到Local端了,用 openFileOutput 寫入了。

方法1:
注意!!
用loadData時,要把 '#', '%', '\', '?' 分別轉換成 %23, %25, %27, %3f
且因為這個方法無法從遠端讀取資料,必須要把圖檔讀出來做過Base64 Encode
( Android 2.2 才有 Base64.java這個 Class,沒有需要自己去偷過來用!)


方法2:
個人較推薦,較不會犯錯。

2012年3月1日 星期四

Android afreechart

afreechart為android上一套免費的繪圖lib,是把jfreechart porting過來的。

Bug:
XYTextAnnotation 553行 應該為outlinePaintType
如果有設背景會讓字和背景色一樣,導致看不出來。
http://code.google.com/p/afreechart/source/browse/trunk/afreechart/src/org/afree/chart/annotations/XYTextAnnotation.java

2012年2月22日 星期三

Android Switch Between Full Screen And Not Full Screen

最主要就是要記得clearFlags,這種東西果然是睡醒就會突然想到了。

final Window window = getWindow();
switch(orientation) {
case ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE:
window.clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
showLandscape();
break;
case ActivityInfo.SCREEN_ORIENTATION_PORTRAIT:
default:
window.clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
window.setFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN, WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
showPortraitView();
break;
}

2012年1月17日 星期二

Run Rails Project On Mac

先安裝Mysql
$ brew install mysql

按照Gemfile安裝需要的套件
$ bundle install

安裝DB資料
$ rake db:create
$ rake db:migrate
$ rake db:seed

跑rails server
$ rails server

修改後上線步驟
rake assets:precompile
nginx reload

Mac Install Imagemagick

$ brew install imagick

2012年1月13日 星期五

Apache RewriteMap Usage

從 IP 判斷User的合約
ip_contract_map.txt 如下:第一欄為User IP,第二欄為合約ID
10.1.1.254 1
60.199.248.193 2
60.251.144.84 3
114.32.4.229 3

Apache設定:

...
#打開RewriteEngine
RewriteEngine on

#將 mapping 讀出來當成contracts這變數。
RewriteMap contracts txt:/srv/www/ip_contract_map.txt

#不覆寫原本的網址,直接用 User 的 IP 當成 key 去 mapping 裡面找。
# %{REMOTE_ADDR} 是遠端的IP
RewriteRule .* - [E=REDIRECT_CONTRACT_ID:${contracts:%{REMOTE_ADDR}}]
...

2012年1月11日 星期三

Install Ubuntu As Server On EC2

0. 修正Locale,看起來爽一點。加到 .bashrc 最後
export LC_ALL="en_US.UTF-8"

1. 格式化新硬碟,(在Amazon Console已經掛上來的前提)
看一下其他硬碟的格式
$ cat /etc/mtab
/dev/sda1 / ext3 rw 0 0

開始格式化成ext3
$ mkfs.ext3 /dev/sdf
/dev/sdf is entire device, not just one partition!
Proceed anyway? (y,n) y

2. 將格式化好的硬碟掛到 /mnt
看一下沒mount前。
$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 7.9G 745M 6.8G 10% /
none 285M 112K 284M 1% /dev
none 318M 0 318M 0% /dev/shm
none 318M 52K 318M 1% /var/run
none 318M 0 318M 0% /var/lock
none 318M 0 318M 0% /lib/init/rw

$ mount /dev/sdf /mnt/

$ df -h
Filesystem Size Used Avail Use% Mounted on
/dev/sda1 7.9G 745M 6.8G 10% /
none 285M 112K 284M 1% /dev
none 318M 0 318M 0% /dev/shm
none 318M 52K 318M 1% /var/run
none 318M 0 318M 0% /var/lock
none 318M 0 318M 0% /lib/init/rw
/dev/sdf 99G 188M 94G 1% /mnt

3. 設定開機掛載
$ vi /etc/fstabs
加在最後,剛剛格式化成ext3,mount到mnt
/dev/sdf /srv ext3 defaults 0 0

確認mount是否有掛好
$ mount /srv

4. 安裝apache
$ apt-get install apache2-mpm-prefork

5. 安裝php及常用lib
$ apt-get install libapache2-mod-php5 php5-gd php5-common php5-cli

6. 安裝mysql
$ apt-get install mysql-server libapache2-mod-auth-mysql php5-mysql

7. 安裝tomcat (optional)
$ apt-get install tomcat6
安裝Solr參考:http://charlesleifer.com/blog/how-to-set-up-solr-on-ubuntu-1004-or-whatever/

8. 安裝geoip (optional)
$ apt-get install php5-geoip
GeoIP後續步驟參考:http://www.php.net/manual/en/geoip.setup.php#93000

9. 安裝imagemagick
$ apt-get install imagemagick php5-imagick

10. 調整 php.ini 上傳檔案的大小限制(optional)
$ vi /etc/php5/apache2/php.ini
post_max_size調整為12M
upload_max_filesize調整為10M

11. 啟用module rewrite
$ cd /etc/apache2/mods-enabled/
$ ln -s ../mods-available/rewrite.load rewrite.load

11. 安裝svn
$ apt-get install subversion

12. 調整log位置
$ cp -r /var/log /srv/log
$ mv /var/log /var/log-bak
$ ln -s /srv/log /var/log

13. 安裝 cronolog (recaommand)
$ apt-get install cronolog

2012年1月5日 星期四

Mysql Import Data

Import Command:
mysql -u USER_NAME -p DB_NAME < YOUR.sql

如果sql檔太大,會出現以下錯誤。
ERROR 1153 (08S01) at line 523: Got a packet bigger than 'max_allowed_packet' bytes

解決方法,進入mysql,執行以下SQL:
set global max_allowed_packet=1000000000;
set global net_buffer_length=1000000;

2012年1月4日 星期三

C# SHA1 As PHP

public static string sha1(string input, bool rawOutput = false)
{
System.Text.UTF8Encoding encoder = new System.Text.UTF8Encoding();
System.Security.Cryptography.SHA1Managed hash =
new System.Security.Cryptography.SHA1Managed();
byte[] output = hash.ComputeHash(encoder.GetBytes(input));
return rawOutput ?
Convert.ToBase64String(output) :
BitConverter.ToString(output).Replace("-", "").ToLowerInvariant();
}

C# UrlEncode To Uppercase

http://stackoverflow.com/questions/918019/net-urlencode-lowercase-problem

public static string UpperCaseUrlEncode(string s)
{
char[] temp = HttpUtility.UrlEncode(s).ToCharArray();
for (int i = 0; i < temp.Length - 2; i++)
{
if (temp[i] == '%')
{
temp[i + 1] = char.ToUpper(temp[i + 1]);
temp[i + 2] = char.ToUpper(temp[i + 2]);
}
}
return new string(temp);
}