昨天東元的張醫師在檢查完之後很詳細的跟我解釋觀察到的
之前裝上支架的前端一點的血管後來也有阻塞,但他說不至於有太大影響,最讓我覺得奇妙的事,右邊的血管長新分支到左邊已經損壞的血管支援
生命真是神奇,就像株羅記公園臺詞一樣
抓到Gingerbread之後本來要build一份給Nexus one的, 後來Build break後就懶得管它, 昨天稍微研究一下解法, 果然跟我想的差不多
Builde break的點在於libcameraservice, 主要是某H公司的camera driver並沒open source, 要build必須先從Nexus One取出binary來build, 但偏偏Gingerbread的libcameraservice跟camera driver的interface有變, 像是HAL_getNumberOfCameras, HAL_getCameraInfo在舊版的driver並不存在
解決的方法有兩種:
目前實驗出來的結果很…殘念..還是沒能讓它的camera可以正常使用… orz
第一個方法比較簡單, 只要改makefile: frameworks/base/services/camera/libcameraservice/Android.mk
把USE_CAMERA_STUB:=true變成always的true (就是把一些判斷都mark掉就好)
這樣build出來的就會是用camera stub
第二個方法可以參考這邊
這方法只是加個wrapper把需要的幾個function加上去, 並包裝舊的call
一樣要改frameworks/base/services/camera/libcameraservice/Android.mk, 只是多個目錄放wrapper
Cyanogenmod也是用同一招解決的, 不同的是, 它並沒多生出一個lib來放這warpper, 它是直接改在CameraService.cpp
其實是同一個方法, 由於它多生一個define : BOARD_USE_FROYO_LIBCAMERA來enable/disable這段code(畢竟Cyanogenmod不是只有for N1), 所以要在 device/htc/passion-common/BoardConfigCommon.mk 裡面加上 BOARD_USE_FROYO_LIBCAMERA := true 來把它打開
基本上, 兩種方法N1的Camera都等於廢了, 所以用哪一種都一樣
如果使用過Google MapView你會發現G社會叫你用你的package signature去申請map key(參考這邊)
那MapView本身又是如何取得你的package signature的呢?
其實很簡單, 可以透過目前的Context用Context.getPackageName()取得package name, 然後再利用package name去PackageManager.getPackageInfo()去查詢package的資訊(PackageInfo), 裡面有項資訊"signatures"就是我們所要的(一個package是可以被sign多次的)
Facebook Android SDK所提供的Single sign on (SSO)也是得先在server端註冊你的package signature, 這樣它可以避免別人偷用你的API key去做single sign on的動作(因為別人的AP可能不會跟你sign同一個signature)
但Facebook的SSO是透過Facebook for Android來做login的動作的, 你的application是透過startActivityForResult去叫Facebook for Android, 這牽涉到兩個不同的package, 如果依上面的例子的話, MapView其實是鑲嵌在你的UI上, 跟你的application是同一個package, 所以可以拿context來取得這資訊
Facebook for Android是如何取得call他的人的signature呢?
其實也是用PackageManager.getPackageInfo() 來取得, 但它如何知道呼叫他的人是哪個package的?
這只要組合兩個API就可以辦到了
第一個是Binder.getCallingUid() , 這可以讓你取得你的Calling process的UID
第二個是PackageManager.getPackagesForUid() , 這可以讓你取得屬於這UID的所有package
或許這邊你可能會有點疑問, 不是不同的package可以share UID嗎? 這樣取出來的package可能有很多個, 我怎知道用哪個? 我們目的只是要取得signature, 所以用哪個都一樣, 因為share UID的必要條件就是這些相同UID的package都是要sign同一把key, 所以只要找出所有package共通的signature就大功告成了
透過Facebook Android SDK去sign in Facebook其實很單純, 只需要這樣幾行code:
if (!facebook.isSessionValid()) {
facebook.authorize(this, new String[] { “publish_stream” }, new AuthDialogListener());
}
其中AuthDialogListener是繼承自Facebook.DialogListener, 因為Authentication dialog是由Facebook SDK處理的, 應用程式只要負責處理onComplete, onError等等callback
但單純這樣的code會在手機內有安裝Facebook for Android時發生問題
因為後來Facebook導入所謂Single sign on的機制, 讓Application跟Facebook for Android是可以用同一使用者的
Single sign on的原理很簡單, 只是透過Facebook for Android去做proxy login的動作而已, Application只消去Facebook註冊一個自己的package signature就可以了
但由於原本舊的Login視窗是包在SDK內一起被build進applciation package, 但在SSO機制內, Dialog是由Facebook for Android出的, 因此如果沒有加下面的code, AuthDialogListener的callback都不會被call到
p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 11.0px Monaco} span.s1 {color: #9a1867} span.s2 {color: #0023c7} span.Apple-tab-span {white-space:pre}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
facebook.authorizeCallback(requestCode, resultCode, data);
}
這是由於Facebook SDK是用startActivityForResult去call Facebook for Android, 因此application必須加上這行自己接它的callback再轉送給原本的listener