Tag: androiddev


CWM Recovery for ZenFone 5 (POC)

警告:這篇是給 DEV 參考用,如果沒有相關基礎知識,使用後手機無法開機,本人不會幫忙解決。
雖然說手機尚未 unlock,隱藏的 partition 也無法透過 dd 寫入,但很久以前用過 Xperia Mini Pro 也是類似的狀況,但 XDA 的大神們還是想辦法搞了個 CWM recovery,理論上 ZenFone 也可以透過同樣的方式使用 CWM Recovery,所以花了點時間做個 POC (Prove of concept)。

檔案在這:zenfone_5_cwm_installer.zip,另外有 zenfone_5_cwm_update.zip,可以在刷入原廠 ROM 之後再把這個 POC 刷回去,或者參考打包用。原始檔案我都放在 github:https://github.com/shakalaca/zenfone_5_cwm

先決條件:
- 手機有 root
- 電腦有裝 adb
安裝方式:
- 解開 zenfone_5_cwm_installer.zip
- 執行 install.bat
使用方式:
- 開機時注意手機上面的指示燈,當紅燈亮起時,按一下音量大或小,沒意外就可以看到 CWM recovery 的選單了
- 目前使用的版本為 6.0.2.8,這是從 Samsung Galaxy Tab 3 (P5210) 的 CWM Recovery 抓來的版本
操作上會有點 lag,太大的檔案也無法 apply,不過因為是 POC 也就不用太強求了,有興趣的可以想想看怎麼讓它變得可用。:)

TWRP recovery 2.7.1.1 for PadFone S

檔案在這:asus_t00n_twrp_2_7_1_1.img
手機得先 root,在 shell 把映像檔寫入

dd if=asus_t00n_twrp_2_7_1_1.img of=/dev/block/platform/msm_sdcc.1/by-name/recovery

接著重開至 recovery,重開機後,當 ASUS logo 消失時等 60 秒左右,再按一下 power 按鈕,就可以看到 TWRP 選單囉。我目前還沒有驗證所有功能,有空再來試試看,請有興趣的記得先備份好手機資料。

Parameters for packing boot.img for PadFone S

筆記一下,這邊是直接拆開原始的 recovery.img 後修改 ramdisk 再打包:
$MKBOOTIMG --base 0 \
--kernel recovery.img-zImage \
--ramdisk recovery.img-ramdisk.gz \
--cmdline 'console=ttyHSL0,115200,n8 androidboot.hardware=qcom user_debug=31 msm_rtb.filter=0x37 ehci-hcd.park=3 UNLOCKED=Y’ \
--pagesize 2048 \
--ramdisk_offset 0x02500000 \
--dt recovery.img-dt \
-o new-recovery.img
cmdline 後面的 UNLOCKED=Y 加上去後再配合 default.prop 塞 service.adb.root=1 才可以讓 adb shell 進去時為 root 權限。

Use versionName & versionCode from AndroidManifest.xml in gradle

與別人合作的 project 因為對方用的是 Eclipse (其實是只有我用 Android Studio),版本的設定會習慣放在 AndroidManifest.xml 裡面,但這麼一來如果 gradle 運行中需要使用到 versionName 或者 versionCode,就得額外設定並且注意是否與 AndroidManifest.xml 同步。這麼做除了讓專案的維護更麻煩以外,還得注意不同步的問題。
最早都是透過複雜的 script 分析 AndroidManifest.xml 把設定值取出,後來發現有個很好用的工具:com.android.builder.core.DefaultManifestParser。
在你的 build.gradle 中最前面先

import com.android.builder.core.DefaultManifestParser

接著在 defaultConfig 裡面設定:
````
defaultConfig {
def manifestParser = new DefaultManifestParser()
versionName = manifestParser.getVersionName(android.sourceSets.main.manifest.srcFile)
versionCode = manifestParser.getVersionCode(android.sourceSets.main.manifest.srcFile)
}

```
That’s it ! 唯一要注意的是,sourceSets 的設定要放在 defaultConfig 之前,否則 gradle 會跟你抱怨 manifest 找不到。

Handling signingConfigs with gradle

之前都是透過 gradle.properties 分開管理 release 用的簽章,好處是不用把敏感的 information 也丟到公開的 repo,但有個問題最近困擾著我:如果存放 keystore 的路徑有中文,gradle 在 sign apk 時無法正確讀取 keystore。
試過很多亂七八糟的方法,最後是透過分開的 .gradle 檔案滿足這樣的需求。
首先建立 signing.gradle,裡面很精簡的只設定 release 用的 signingConfig:

android {
    signingConfigs {
        release {
            keyAlias 'YourKeyAlias'
            storeFile file('YourStoreFile')
            storePassword 'YourStorePassword'
            keyPassword 'YourKeyPassword'
        }
    }
    buildTypes {
        release {
            signingConfig signingConfigs.release
        }
    }
}

而在 gradle.properties 指定一個 property 存放 signing.gradle 的路徑:

releaseSignConfig=/path/to/signing.gradle

最後在主要 project 的 build.gradle 中判斷是否需要引入:

if (project.hasProperty(“releaseSignConfig") && new File(project.property(“releaseSignConfig")).exists()) {
    apply from: project.property(“releaseSignConfig");
}

或者你也可以寫:


if (project.hasProperty(“releaseSignConfig") && new File(releaseSignConfig).exists()) {
    apply from: releaseSignConfig;
}

這樣便可以解決中文或者空白路徑的問題 如果各位先進有更好的解法 也歡迎來討論

How to modify boot image of Genymotion VM

如果你有裝 Parallels Desktop or VMWare Fusion:

  • 點擊掛載 android_system_disk.vmdk, 找到 ramdisk 所在地開啟 terminal, 移出 ramdisk 到比如說 /tmp/test
  • cd /tmp/test; mkdir root; cd root; gunzip -c ../ramdisk | cpio -i
  • 做你想做的事情: 塞檔案, 編輯檔案, 比如編輯 default.prop, 把 ro.secure=1 改為 0
  • find . | cpio -o --format newc | gzip > ../ramdisk.new
    - 把 ramdisk.new 放回原來的目錄並更名為 ramdisk, 收工 !

Android project compatible with gradle 1.7 & 1.8

基本上使用 gradle wrapper 應該沒有這樣的問題, 不過由於 gradle 1.8 需要 plugin 0.6 以上, 如果 project 與其他人共用, 版本又沒統一的狀況下 (比如怕有地雷..) 可以透過判斷 gradle version 的小技巧, 讓 project 可以在 gradle 1.7 & 1.8 下都能編譯.

參考 https://gist.github.com/shakalaca/6779748 修改 project root 的 build.gradle, 在 dependencies 判斷使用的 plugin 版本即可.

搭配 gradle wrapper 使用效果更好, 如果先前用 1.7 編譯完全沒問題, 而 1.8 無法正常編譯, 修改 task wrapper 中的 gradleVersion 後, 執行一次 ./gradlew wrapper 即可退版, 等到之後 plugin 或者 gradle 有修正再切換過去.

Tip: Before upgrading gradle wrapper

如果 ~/.gradle/gradle.properties 裡面有設定 org.gradle.daemon=true , 記得在升級 gradle wrapper 之前, 先執行 gradle --stop 才不會有奇怪的 error ..

Remove jar file in apk

如果不想在 apk 裡包入某個 jar 檔 (使用 device 上的, 或者某版本沒提供某種功能) 有兩種方式: 一個是加法, 一個是減法.

加法就是透過 configuration 的設定, 在 compile 時才把把該檔案加入 class path 參考: https://gist.github.com/shakalaca/6551508

減法就是在 dex task (compile task 之後) 開始處理 jar 檔前, 把 jar 檔從 library 路徑中移除: https://gist.github.com/shakalaca/6551576

一開始最直覺的方式就是加法, 但後來發現我需要的是在某個 build 不放置 jar 檔, 才有了減法的作法, 但感覺有些醜, 再想想有沒有更好的方式..