從新簽名Android pre-install APKphp
題外話: 最近在研究Android APK的自動化測試方法,期間遇到了APK簽名問題, 尤爲是Android系統pre-install的應用,它們的簽名方式比較特殊,後面會說到,因而在Eclipse裏寫好的測試代碼就會因爲權限問題,沒法測試這些應用。折騰了好幾天,頭疼。好在最後仍是搞定了,因而乎就想在這裏分享一下個人一點經驗,有感興趣的、或者有相似問題的朋友們,但願可以給大家一點幫助。
什麼是pre-installapk: 就是Android系統預裝的一些應用,例如Messaging、Contacts、Calendar等等。
pre-install apk的簽名方式: 給apk簽名的通常方法有兩種,一種是在Eclipse裏使用「Android Tools -> Export SignedApplication Package…」這種方式簽名;另外一種是用命令行簽名。這裏就不詳細描述了。 而pre-install apk的簽名比較特殊,使用源碼中的默認簽名。能夠查看Android的源代碼得知。 $ signapkpublickey.x509[.pem] privatekey.pk8 input.jar output.jar 其中,*.x509.pem爲x509格式公鑰,pk8爲私鑰。
pre-install apk的簽名方法:
- 在Eclipse裏編寫好測試apk的代碼,例如要測試「打開信息這個應用,準備發送短信息」;
- 準備Linux系統環境,並配置好Android開發環境(包括SDK、JRE、環境變量等);
- 下載自動簽名腳本
- http://code.google.com/p/robotium/downloads/detail?name=sign-debug-any-apk.sh
- 從Android系統中導出pre-install的應用(例如Mms.apk)
- adbpull /system/app/Mms.apk
- 準備Eclipse的默認簽名工具debug.keystore文件;
- 將腳本文件、Mms.apk、debug.keystore都拷貝到Linux系統中;
- 修改腳本文件,並給它加權(注二);
- 在終端中輸入命令:
- ./sign-debug-any-apk.shMms.apk Mms_signed.apk
- 若是一切順利,此apk應該已經簽好名並生成新的文件「Mms_signed.apk」;
- adb pull /data/system/packages.xml
- Openpackages.xml and remove:
- <packagename="com.android.Mms">
- </package>
- Pushpackages.xml back to device: adb push packages.xml /data/system
- Renamed「Mms_signed.apk」to 「Mms.apk」, then push the apk back to the device: adb push Mms.apk/system/app
- 運行Eclipse裏的測試代碼,順利的話你就能看到信息這個應用被調用並啓動。
特別注意:
- 測試代碼編寫正確,繼承InstrumentationTest類、target package = 「…」等無誤;
- Linux環境及其中的Android開發環境配置正確;
- 請按照上述須要的文件實際拷貝到的Linux目錄位置,修改Shell腳本,並加權;
總結: 本文介紹的方法,除了對Android系統pre-install的應用有效,同時對通常簽名的應用apk也有效(至少我拿咱們公司編寫的一些apk應用沒問題)
心得體會: 一開始,我試圖找到使用源碼簽名和上述兩種方法的互換方式。可是研究了好久,好像沒辦法互換。再後來,看到一篇資料,介紹了對已簽名的apk從新簽名的方法(注一)。因而在Window環境下試着作。前三步都沒問題,但是到了第四步就進行不下去了。就這樣被卡了三天時間。這三天裏,天天上班都滿懷但願的帶着各類嘗試方案,可是天天下班都無奈悻悻的回家。如今回頭想一想,凡事就是這樣,你作成了一件過後感受很簡單,但回頭看看其中的艱辛探索之路是旁人沒法體會的。這期間,找到了一個資料,一個自動解包打包的Shell腳本,因爲在Window環境下沒法執行,也一直沒有嘗試。到了第四天,萬念俱灰的時候,抱着試一試的態度,進行了最後的嘗試。難道凡事也必在走投無路準備放棄的時候,忽然一線起色?!在一系列的搭建環境操做以後,包括安裝虛擬機,安裝linux系統,配置Android開發環境,配置java環境變量,修改、運行腳本,輸入必要的參數,終於。。。。。。OK了!拿到Window下,搗鼓到Android虛擬機裏,運行測試代碼,哈哈,跑起來了!
注一: ‐‐Un-zip the apk file ‐‐Delete the META--‐INF folder ‐‐Re‐zip the apkfile ‐‐In Dos prompt /Command prompt >jarsigner -keystore~/.android/debug.keystore -storepass android -keypass android ApplicationToTest.apkandroiddebugkey > zipalign 4 ApplicationToTest.apkTempApplicationToTest.apk 注二:
- #!/bin/bash
- set -e
- ORIGINAL_APK="$(readlink --canonicalize $1)"
- CLEAN_SIGNED_APK="$(mktemp -t robotium.clean.apk.XXXXXXXXXXXXXX)"
- UNPACK_DIRECTORY="$(mktemp --directory -t robotium.unpack.XXXXXXXXXXXXXX)"
- ZIPALIGNED_APK="$(readlink --canonicalize $2)"
- PWD="$(pwd)"
- if [ -e "$ORIGINAL_APK" ]; then
- if [ "$2" == "" ]; then
- echo "Second argument must be the output filename for the signed apk."
- exit 2
- fi
- rm "$CLEAN_SIGNED_APK" 2>/dev/null || true
- rm "$ZIPALIGNED_APK" 2>/dev/null || true
- cd "$UNPACK_DIRECTORY"
- jar xf "$ORIGINAL_APK"
- rm META-INF/CERT.*
- jar cf "$CLEAN_SIGNED_APK" .
- jarsigner -keystore 這裏是你的debug.keystore存放路徑 -storepass android -keypass android "$CLEAN_SIGNED_APK" androiddebugkey
- zipalign 4 "$CLEAN_SIGNED_APK" "$ZIPALIGNED_APK"
- else
- echo "First argument must be an apk file."
- exit 1
- fi
|