2019年12月31日 星期二

[AdMob] 收取廣告收益方式

markdown 最近在 AdMob 上累積的收益達到付費標準 100 美金了,於是開始準備領取這筆費用,在這邊記錄一下需要做的設定還有開戶過程,基本上在 AdMob 收益達到 10 美金時,Google 就會用郵件寄送 PIN 碼到你家,在 AdMob 中將 PIN 碼填入,就可以開始設定付款方式。 網路上大家都推薦西聯匯款,所以我也是選擇這種方式,AdMob 上設定付款方式超簡單,只要選好你要的匯款方式並且填入英文姓名然後儲存就好了,我是用護照上的英文姓名,並且都是用大寫。 原本台灣有支援的西聯匯款的銀行有元大銀行跟京城銀行,但元大已經在去年取消這個服務,所以只有去京城銀行辦理開戶了。 我是到新竹火車站附近的京城銀行辦理開戶,鄰櫃被告知要先在網路上填申請表才能開戶,銀行也沒有紙本申請表,於是用手機花了一些時間填完申請表。然後行員會說最好有 MTCN code 再來辦,基本上跟行員強力要求就是要辦應該就可以了,加上我已經有收到過匯款所以有 MTCN code,這部分沒遇到太多刁難。 接著行員問我要不要直接從銀行領現金,當然選擇不要,跟他說要回去用網路轉回帳戶,然後就是等行員的流程作業,完成後要求我下載京城銀行的 APP 做設定,基本上跟其他銀行開戶都是大同小異,整個過程還算是順利,行員的態度也很好,剩下就是等甚麼時候美金漲高一點,就可以來試著領一次匯款了。 *** Reference: * [[懶人包]Google AdSense廣告如何領錢?電匯、西聯匯款、支票。](https://sofree.cc/google-adsense-payment/) * [Admob / Adsence 西聯付款](http://development-ls.blogspot.com/2014/07/admob-adsence.html) * [全台僅存的京城銀行西聯匯款收款](https://blog.user.today/ktb-western-union/) * [免跑銀行,直接線上領取 Google AdSense 廣告收入 (西聯匯款)](http://www.vixual.net/blog/archives/149)

2019年12月10日 星期二

絕緣測試與耐壓測試

markdown Hi-Pot 測試,絕緣測試,耐壓測試,常常會搞混,在這裡註記一下不同之處,供日後備查。 ## 絕緣測試 * Insulation Resistance Test,與一般所指的 Hi-Pot 測試不是同一件事 * 通常用 500V 或 1000V 測試 * 測試結果為歐姆值,通常為幾兆歐姆 ## 耐壓測試 * Dielectric Voltage Withstand Testing、High Potential Testing、Hipot Testing 指的都是耐壓測試 * 測試期間對 DUT 施加高電壓,電壓可以是 AC 或 DC,DUT 不可發生電弧擊穿 * 量測漏電流,測試結果以 Pass/Fail 來表示 *** 參考資料: * [Electrical Safety Testers, Hipot Testers](https://hipot.com/docs/whitepapers/Basic-Facts.pdf) * [What is the difference between Insulation Resistance Testing and Dielectric Withstand Testing?](https://www.chromausa.com/product-faq/what-is-the-difference-between-insulation-resistance-testing-and-dielectric-withstand-testing/) * [絕緣電阻測試](http://powersupplytech.net/tw/news-32d3f94e-73d9-95de-01d3-e524ad6dcc31.html) * [耐壓測試](http://powersupplytech.net/tw/news-5c121d88-67a2-e54c-3608-9c2c3de321c6.html) * [安規測試](https://www.eecextech.com/tw/education/)

2019年12月9日 星期一

[Android] APP 配色法則

markdown 寫 APP 最困難的部分除了 Android 坑爹的機制之外,剩下就是 GUI 介面的設計,顏色搭配就是其中一環。尤其是對毫無美感的程式工程師來說,如何選擇 APP 的顏色真的是一大難關。 這裡收集一些配色相關的教學資源,供以後要選擇配色時參考 * [學會這幾種顏色搭配方案,讓APP UI設計配色遊刃有餘](https://kknews.cc/zh-hk/design/m2j8b9z.html) * [配色,配色,配色!看完你就懂了](https://kknews.cc/news/vm93nr4.html)

2019年12月3日 星期二

MAC OUI 查詢

markdown 最近查了 OUI 的資料,OUI 是 MAC 前 6 碼,每個網卡廠商會跟 IEEE 申請,IEEE 有個檔案記錄了被申請的 OUI 資訊,
http://standards-oui.ieee.org/oui.txt
當要查詢 OUI 的時候很好用,在這裡記錄一下。 --- Reference: * [查詢網路卡的廠商](http://blog.ilc.edu.tw/blog/index.php?op=printView&articleId=691367&blogId=25793)

2019年12月2日 星期一

[Android] Crashlytics 在 debug build 時不工作

markdown 最近想要在新的 app 上測試 Crashlytics,在 debug 中不管怎麼 crash 都沒有在 firebase 看到 crash report,後來才發現當初在 AndroidManifest.xml 裡面 Crashlytics 開關的設定是變數。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiMPayCgXXzQ1Km_0CyxRaETHWSiyBuQs4aq-aYFiw7lvfrOKMF_UCtQ5ZfKWSKoJp7KBUZ7WlpJot4lG97HOvE0a9siDASEXyR_wBUEfFuV398De7TyA-OSDFSXn0_Lkrfw5Zljy3JA6K-/s1600/Image+1.png) 而 crashlyticsEnabled 這個值在 app level 的 build.gradle 中設定,並且在 debug mode 中是設定為 false 的。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgmTlgNNe6R07dvpS5-ShbUf_J3tw1Ht13Y5GwPhXnJUITHT-qi2lU08fWLo3_ei5oNeypkniLHKiz4HHOy62E77aY2D67m4Mcq_n_5rbAwHPwe5BtkF9KUFvRSCT5fDKRv7WCPb7uzIg2w/s1600/Image+2.png) 在這邊記錄一下以免以後又忘記。 --- Reference: * [Firebase Crashlytics ](https://ithelp.ithome.com.tw/articles/10197520)

2019年11月30日 星期六

[Android] Android Studio 的 product flavor soruce set 目錄無法執行新增 package 操作

markdown 在 Android Studio 中可以新增 product flavor 來定義不同的 Build Variant,例如我新增的 ad 跟 noAd 兩個 product flavor,就會有四個 Build Variant adDebug、adRelease、noAdDebug 與 noAdRelease。 接著照 [Android 官網的文件](https://developer.android.com/studio/build/build-variants#sourcesets)操作就可以新增 source set,但是我接著要在 source set 中新增 package 的時候,發現 source set 不是 java 目錄,如下圖,正常 java 目錄是藍色,灰色是一般目錄。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi83T3qIARHbjH0N3hS_vqNVMm1te_biOn3jfynUoP8twTJSRSzOV2QrtEOFD_drX8QS3SdIcl0tVVufOzcO6yWd7Ll_Z_aWa2cVWLJ6XokzIBsEoQDINgVYDW1rbE_7rvgKYQLmYmB-cva/s1600/Image+1.png) 但是另一個 Build Variant noAd 卻又正常,接著就 clean build,重開 Android Studio 試了各種方法,都沒用,最後才發現,我的 Active Build Variant 是 noAdDebug,當切到 adDebug 後,ad 下面的 java 目錄就變成藍色,可以執行新增 package 操作了。 同理,在左側 Project view 切換到 Android 的時候,也只有 Active Build Variant 的目錄才會顯示出來。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjtiwvF7j6PiElrz86_ymy7g3WlVwPYZtfDhz10hOiTSDY_uKgmI_22QisMVWddYZqd2O32CcaWfnIKRF5s0En1bpz7QqFtFYz1AzIgRAI0AlssOOR2oXcGsVuwilZz7-coadnLobkqcfzG/s320/Image+2.png) 為了這個蠢問題浪費了幾個小時,其實不太懂這個設計的用意是為什麼阿。

2019年11月24日 星期日

[Android] NestedScrollView 嵌套 RecyclerView 時 Scoll 位置停在 RecyclerView

markdown 最近遇到的問題是,Fragment 中為一個 NextedScrollView ,裡面從上至下有 Button 等不同的 View,最下方是 RecyclerView,但是在 Fragment 顯示時,NextedScrollView 會自動滑動到 RecyclerView 的位置。 會這樣的原因是因為,NextedScrollView 在繪製時,會去找尋 child view 中有沒有 has focus 的 child view,如果有,則滾動到它的位置。而 RecyclerView 是它找到的 has focus 的 child view,因此位置就移動到 RecyclerView 了。 這也是為什麼有人呼叫 RecyclerView.setFoucsable(false) 後,就不會發生自動滾動了,因為沒有找到 has focus 的 child view。不過最好的解法,應該是在 NextedScrollView 的直接子 view 中增加 [descendantFocusability](https://developer.android.com/reference/android/view/ViewGroup#attr_android:descendantFocusability) 屬性並將之設為 blocksDescendants, 因為 NextedScrollView 繪製過程中看到了 child view 有這個屬性,就不會再做自動滾動的動作了。
<LinearLayout
    android:id="@+id/container"
    android:descendantFocusability="blocksDescendants"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
--- Reference: * [NestedScrollView、RecycleView、ViewPager 等布局方面的常见问题汇总,及解决](https://www.jianshu.com/p/8dd1e902b7cd) * [NestedScrollview won't start from top](https://stackoverflow.com/questions/33584187/nestedscrollview-wont-start-from-top) * [Recycler view inside NestedScrollView causes scroll to start in the middle](https://stackoverflow.com/questions/36314836/recycler-view-inside-nestedscrollview-causes-scroll-to-start-in-the-middle) * [ScrollView(RecyclerView等)为什么会自动滚动原理分析,还有阻止自动滑动的解决方案](https://juejin.im/post/5a2a04726fb9a045055e0993)

2019年11月21日 星期四

Linux SCP 無法使用問題

markdown 最近遇到一個問題是用 [.NET SSH library](https://github.com/sshnet/SSH.NET) 的 scp 想將檔案複製到一塊版子上時跳出 error,顯示 SCP not found,於是試著把環境變數印出來,結果發現 PATH 變數是空的。但是用 putty 登入之後卻又有 PATH 變數。查了資料才發現,shell 有 login/non-login、interactive/non-interactive shell 之分,而且不同設定的 shell 吃到的 profile 或是 bashrc 檔案是不同的。因此應該是在該版子上的 non-login 或 non-interactive shell,沒有去吃到正確的 profile 導致沒有 PATH 環境變數。 因為板子上的程式我無權修改,所以只能用迂迴的方法,在使用 scp 之前,先把板子上 scp 執行檔搬到預設登入的目錄,這樣就不會跳出 scp not found,可以順利將檔案 copy 進去了。

2019年10月19日 星期六

[Windows] USB 網卡模擬無線 AP

markdown USB WiFi adapter 除了可以做為 client 端連上 router 之外,也可以當成 AP 讓其他 client 連上,並且分享桌機上的網路。而且不必額外安裝軟體,Windows 內建就支援這個功能。 打開命令提示字元,並且輸入如下 command,就可以設定你想要開放給別人連的 SSID 跟密碼。
netsh wlan set hostednetwork mode=allow ssid=your_ssid key=your_password
這個 command 執行成功之後,你應該會看到電腦上多出一張網卡,而且它的描述會是 Microsoft Virtual WiFi Miniport Adapter。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEibPUntUng1YoaK8AB16vndLPUHhmrRMnoIcfmUM1zOOPuHyVZJ3XORWjAZ9w4t49NWX7W2Q0GYFZJZ6T2ZxQbKQYjiqxqHS_QKWzEmCnBE8E_IisSg_8es2kUO-Ja0I-8xnQ4jVscmDiPZ/s1600/Image+2.png) 這其實是一張 Windows 幫你虛擬出來的網卡,用途就是用來當成 AP 讓別人連線,只是現在現在它還沒有啟用,所以你會看到左下角有一個紅色叉叉,接下來再用一行 command 來啟用它。
netsh wlan start hostednetwork
網卡啟用後,你用手機去掃描應該可以看到多出了你設定好的 SSID,只是目前手機就算連上了也不能上網,因為這張虛擬網卡並沒有接上實體網路。不過此時只要將你桌機的實體網路分享給它就可以了,分享的方法也非常簡單,右鍵點選你的實體網路的網卡,選擇內容,在共用頁面設定要將網路分享給我們的虛擬網卡。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhqdRBv9hO1Rl6teFMfizXmam3wkPTkd4LC_riFwrEYCMnMJn5oz9w5LIM2KI7FRT8j3Z26OFRhQ7XHN1dij3KJSopA5Wb0fLMzwQTZOJvJmRQK2pc8yavOJ748vXhJJ7LcdRvr0sGnNogt/s1600/Image+3.png) 設定好分享後你的實體網卡描述會多出一個『共用的』的字眼,現在連上虛擬網卡上 AP 的裝置就可以使用桌機的實體網路上網了。 *** Reference: * [Microsoft Virtual WiFi Miniport Adapter 使用方法](https://blog.csdn.net/RuingMan/article/details/51443632) * [Windows 系統筆記型電腦設定無線基地台分享 Wi-Fi 教學](https://www.kjnotes.com/windows/12)

2019年10月1日 星期二

[Electronic] 為甚麼看得到 IR LED 紅光

markdown IR LED 就是紅外線,理論上是人眼看不到的光,但為甚麼有時可以在像是 camera 上看到 IR LED 發出紅光。 一般用的 IR LED 大致分為 850nm 跟 950nm,850nm 的 LED 是指他發出的最強光是在 850nm 波長,但是同時也會發出其他波長的光,波長離 850nm 越遠則光強度越小,因此可能會有微弱的光波長落在可見光範圍內。 940nm 的 IR LED,則因為離可見光波長較遠,基本上是看不到有紅光的。 網路上有很多用 arduino 在玩紅外線的分享,可以參考: * [Arduino練習:紅外線傳送與接收](http://yehnan.blogspot.com/2013/05/arduino.html) * [EduCake 紅外線收發功能實作 - 86Duino](http://www.86duino.com/wp-includes/file/Chapter13-TC.pdf)

2019年9月15日 星期日

[Android] Android 專案加入 Admob 流程

markdown 常常忘記將 Admob 廣告加入 Android 專案的步驟,在這邊記錄一下,以供日後備查。 ## 在 Admob 中新增 App 在 Admob 中新增 App,照著[官方文件](https://support.google.com/admob/answer/2773509?hl=en)的步驟做就可以,主要是填入 App 的 package name,然後就會生成一個 Admob App ID 出來,不管 App 是否已經在 Play Store 上發布都可以新增,只是若還沒發布的話,在之後發布後要記得回到 Admob 將發布後的 App 連結過來。 ## 新增廣告單元 新增 App 之後,接著一樣可以在 Admob 新增廣告單元,新增成功之後 Admob 會給你廣告單元的 ID。 ## 加入 Admob SDK 到專案 新增完 App 以及廣告單元到 Admob,接著就是連結 Admob App 到 firebase。 參考[官方文件](https://support.google.com/admob/answer/6383165?hl=zh-Hant)中的說明,在 Admob 的該 App 頁面中,可以看到連結 firebase 的選項,點選之後建立新的 firebase 專案,然後 Admob 會跳出視窗告訴你剩下的步驟。其實到這裡,在 Admob 和 firebase 網站的設定已經做完了,接下來主要是設定 local 端的 Android Studio 專案。 第一步是下載 firebase 的設定檔,也就是 google-services.json,在剛剛點選連結 firebase 之後跳出的視窗就有附上下載連結。 第二步將 firebase 加入到專案中,一樣照著[官方文件](https://firebase.google.com/docs/android/setup)中做,主要使用第一種方法 [Add Firebase using the Firebase console](https://firebase.google.com/docs/android/setup?hl=zh-TW#console),修改專案內 App level build.gradle 跟 Module level build.gradle 就可以。

2019年9月4日 星期三

[Car] 入手了一台中古 Prius C

markdown 有想買車的念頭已經有一段時間了,因為家裡已經有一台四門,所以想要的車型是五門掀背小車。除車型之外,其他的條件為進口、妥善、保養費低、省油,這些條件加一加,就剩下 Swift 1.0 跟 Prius C 可以選了。 Swift 1.0 真的是一台好車,進口價錢又不是很貴,但是不知道為什麼,油電車就是莫名的很吸引我,一直很想試試看油電車開起來的感覺是甚麼,但是 Prius C 新車硬是比 Swift 1.0 貴上一截,於是一直在 Swift 新車跟 Prius C 中古間猶豫,最後還是價格先決,在今年入手了七年中古 Prius C。 開了一陣子後,油電車的神秘面紗退去,新鮮感也很快消退,其實開起來就那樣XD,怠速很安靜像沒發動是真的,省油也是真的,但油電的剎車系統一直沒辦法適應,不管再小心,煞停時一定會點頭,程度大小的差別而已,我開家裡老油車是從來不會點頭的,上網查這是油電的通病,只能說他的設計就是會造成這樣的結果。 中古車當然還是有這樣那樣的小毛病,但是已經有心理準備,畢竟比新車便宜不知多少了。 在網路上有時會看到 Prius C 車主開出 30km 以上的油耗,不過自己開的時候都只有 20km 上下,一直很好奇 30km 怎麼開出來的,最近找了個機會,在路況絕佳的情況下測試,證實了原來 Prius C 30km 的油耗不是都市傳說。這個油耗需要在天時地利人和的情況下才能出現,不會是平均值,這個測試主要是做紀念的意義居多,不過七年的 Prius C,電池都不知道衰退多少了,還能跑上 30km,已經夠讓人欣慰了。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgIu6HQXEnuwdhNdYJDgfkbREhFdl8dx-HqJSPO5YrrDs7rAVNnbRHxVlMq1UlQstVBLyoYWArlhHN41RBKsJRJNngWM15An_szv5V4D3MQJByCZocF7nn9hDyuJ-wMAiFmz2BexXokWj7R/s1600/Image+22.png)

2019年8月27日 星期二

[.NET] Lambda 不能轉換為 System.Delegate Type

markdown C# 的 lambda 可以轉換為 delegate type,例如 Action 或 Func,你可以用下面的方式宣告一個 Func,並且用一個 lambda assign 給它。
Func<int, int> func = (x) => x * x;
但是無法用 lambda assign 給 [System.Delegate](https://docs.microsoft.com/zh-tw/dotnet/api/system.delegate?view=netframework-4.8) type,例如下面例子會 compile fail。
Delegate d = (x) => x * x; // Compile fail
這是因為 lambda 只能指定給 delegate type,例如 Action 或 Func,但是 System.Delegate 不是 delegate type,雖然它是所有 delegate type 的父類。這有點難理解,但 C# 就是這麼定義的。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhnShkZ9D9YsusmB_GB8FY3OOLXcGqKb3q8-c6HOSBSOcoPJFee050naiEOtO108EdzrMcWUtyklh2H0X7F5nHGBCWIF6abTs5qUsS_ABfv1Bxu0d6PQxFu2BzMJvtUEIsFM_07dsW9wylr/s1600/Image+18.png) 甚麼時候會遇到這種情況呢?在你要用 Form 的 [Invoke](https://docs.microsoft.com/zh-tw/dotnet/api/system.windows.forms.control.invoke?view=netframework-4.8#System_Windows_Forms_Control_Invoke_System_Delegate_) 或 [BeginInvoke](https://docs.microsoft.com/zh-tw/dotnet/api/system.windows.forms.control.begininvoke?view=netframework-4.8#System_Windows_Forms_Control_BeginInvoke_System_Delegate_) 的時候,因為你可以看到,Invoke 跟 BeginInvoke 接受的是一個 System.Delegate 型別的參數,所以你不能直接用 lambda 當參數傳進去。
Form f = new Form();
f.Invoke((x) => x * x);  // Compile fail
解決的方法是用 Func 或 Action instance 當參數傳進去,因為 System.Delegate 是所有 Action 和 Func 這些 delegate type 的父類,所以可以接受 Action 或 Func。
Form f = new Form();
f.Invoke(new Action(() => Console.WriteLine("Test")));

2019年7月26日 星期五

Androidx migration build fail

markdown 把一個專案從 support library 升級到 androidx 的時候 build fail,Android Studio 給出的 error message 就是
Program type already present: android.support.v4.os.ResultReceiver$1
Google 找到的好像都是說 dependency 沒有轉換乾淨,例如可能有第三方 library 還在依賴 support library,但是我的專案沒有用到第三方 library 而且確定所有依賴都是 androidx。 最後想到會不會是 build tool 版本太低導致,於是把 com.android.tools.build:gradle 從 3.1.3 升級到 3.2.1,gradle version 從 4.4 升級到 4.6,build 就成功了。 搞不懂 build tool 版本問題為什麼會跑出這個錯誤訊息,不過也不想去深究,反正 android build 總是很容易遇到奇奇怪怪的問題,只是要注意要開始導入新東西時,build tool 最好要用新一點的版本。

2019年7月1日 星期一

Block Size 與 Direct IO

markdown 在使用 direct IO 的時候,讀取/寫入的大小、buffer 的起始位置與檔案操作的 offset 需要是某個數值的整數倍,在 linux 2.4 之前,這個數值是 filesystem 的 logical block size,通常是 4K,在 linux 2.6 之後,這個數值是 device physical block size (device sector size),通常是 512 bytes。 block 在不同的語境可能會有不同的意思,容易造成混淆,在這邊解釋一下這兩個名詞的意思。 ### physical block 表示 device 本身一次能夠操作的最小單位,也有可能叫 device sector 或是 physical sector。 ### logical block 這個概念存在 linux filesystem 中,是 linux 一次 device 操作的最小單元,有時候叫 filesystem block、data block 或是直接就叫 block,logical block size 必須是 physical block size 的整數倍。 ### Advanced Format 原本 physical block size 幾乎都是 512 bytes,然而為了日漸增加的大檔需求,有些製造商推出了 4K physical block size 的儲存裝置。但不是所有 OS 與軟體都支援 4K physical block size,所以儲存裝置內的 firmware 支援一種功能,就是可以 export 出 512 bytes 的 "logical sector size" 給 linux (稱為 512e 格式),然後 firmware 內部將非 4K 對齊的 IO 操作轉換為 4K IO 操作。 若是 firmware 不使用模擬 512 bytes 模式而使用原生 4K,則稱為 4K native device,不過這要作業系統跟系統上軟體也支援才行,否則可能會遇到奇奇怪怪的問題。而 512e 與 4K native 這些新的格式與概念就是 [Advanced Format](http://idema.org/?page_id=2153) 在 512e 格式下出現的 logical sector size 與先前提到的 logical block 很容易造成混淆,在這裡我認為這兩個講的不是同一件事,一個是存在 linux filesystem 的概念,一個是存在儲存裝置內的概念,對於 512e 格式的儲存裝置,從 linux 系統的角度來看,裝置的 physical block size 是 512 bytes 的,雖然它實際上是 4K。 那對新式 4K physical block size 的儲存裝置,direct IO 要怎麼對齊?在 512e 格式的系統上,需對齊 512 bytes,但在 native 4K 的系統上,則需對齊 4K。要對齊哪個數字,可以經由查詢系統上的 logical sector size (不是 filesystem 的 logical block size) 得到,例如用 [ioctl](http://man7.org/linux/man-pages/man2/ioctl.2.html) 傳參數 BLKSSZGET。 當然查詢 physical block size 然後對齊它我覺得也是可以的,不過網路上的範例似乎都是查詢 logical block size 來作對齊,可能是因為這樣在 512e 裝置上可以對齊 512 bytes,對於對齊來說數字越小是越容易做到的。 *** Reference: * [Logical Block Size](https://docs.oracle.com/cd/E19455-01/805-7228/fsfilesysappx-9/index.html) * [I/O Limits: block sizes, alignment and I/O hints](https://people.redhat.com/msnitzer/docs/io-limits.txt) * [Support statement for 512e and 4K Native drives for VMware vSphere and vSAN](https://kb.vmware.com/s/article/2091600) * [Linux and 4K disk sectors](https://lwn.net/Articles/322777/) * [4K-sector drives and Linux](https://lwn.net/Articles/377895/) * [Linux on 4KB-sector disks: Practical advice](https://developer.ibm.com/tutorials/l-4kb-sector-disks/)

2019年6月17日 星期一

低功率訊號量測

markdown 在用 spectrum 量測訊號時,會發現下方有橫貫整個螢幕雜訊,也就是 noise floor。真實世界雜訊是一定會存在的,雜訊產生的原因可以參考 Reference [Noise floor-頻譜下方的雜訊是怎麼來的](https://www.strongpilab.com/spectrum-noise-floor/)。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhZKe8qv0i0Qe3gKOaZEoSB6ixa0ujj0MMD7gesf5BqHKD_WB2oFMtEtv4R0nEYqdClVX8qoWZPkG4KtO3GYIdgUe49ENSTWNtLVMyR_TfO_1PwvgTl9RK4TEy61zC-wBUQdodwcebvdSvA/s1600/spectrum-noise1.png =600x*) 在量測低功率的訊號時,如何降低 noise floor 就顯得很重要,因為若是欲量測的訊號強度比 noise floor 還低的話,訊號會被 noise floor 淹沒導致無法量測到訊號。 有個參數 RBW (Resolution Bandwidth) 可以降低 noise floor,這個參數的作用是設定 spectrum 用多寬的頻率當最小單位來掃描輸入的訊號,該頻寬內測得的功率,就會是螢幕上的一個點。若是這個頻寬越窄,在此頻寬內通過的雜訊就會越少,測得的雜訊功率就會越小。不過這個參數也不是越低越好,因為值越低就表示作完一次完整掃描要掃更多次,就會花更多時間。所以依據實驗需要來調整最適合的 RBW 來作量測。 Reference: * [RBW 調低讓低功率訊號浮出水面-觀察小訊號的好方法](https://www.strongpilab.com/low-power-meas-by-low-rbw/) * [頻譜原理-Spectrum內部構造簡介](https://www.strongpilab.com/spectrum-how-it-work/) * [VBW Video bandwidth做甚麼用? 頻譜軌跡的化妝師](https://www.strongpilab.com/vbw-video-bandwidth-spectrum/) * [Noise floor-頻譜下方的雜訊是怎麼來的](https://www.strongpilab.com/spectrum-noise-floor/) * [Optimization of weak signal measurement by spectrum analyzer](http://www.micronix-jp.com/english/note/application/MSA_DR_e.html)

2019年6月13日 星期四

Word 分頁符號

markdown Word 可以輸入分頁符號讓分頁符號插入點的內容強制移到下一頁去,可參考[這篇](http://www1.nttu.edu.tw/it/it03/word/layout03.htm)

2019年6月11日 星期二

Android NDK Build Fail

markdown 一個專案在加入 NDK 後遇到 Build Fail,Android Studio 一如既往給的錯誤訊息看不出是甚麼原因,只能用關鍵字 External Native Build Issues: Error configuring 來搜尋,網路上查了資料看到需要更新 Gradle Build Tool,原本是 3.1.3,更新到 3.2.1,接著 Android Studio 提示還要再連帶更新 Gradle Version,從 4.4 更新到 4.6,更新完後真的就可以 Build 成功,在此記錄一下。

2019年6月6日 星期四

Android 逆向 - 可執行檔案格式

markdown 要反組譯 Android 的程式,跟一般桌面 Java 應用程式比是要麻煩一些的,雖然 Android 上是用 Java 語言開發,但是底層的 Java 虛擬機並不是 Oracle 的 JVM,而是 Google 自己做的 Dalvik。而且從 Java 原始碼編譯出來的可執行檔案,隨著 Android 最佳化機制的演進,還會生成不同的檔案格式,因此要學 Android 逆向,首先要對這些編譯後的可執行檔案格式有些了解,在這篇會介紹一下這些檔案格式,幫自己理清思路,也順便做個筆記可供日後備查。 ## DEX 一般 Java 程式透過 javac 編譯後,得出的是一個一個 .class 檔案,內含 Java byte code,檔案格式為 [class file format](https://docs.oracle.com/javase/specs/jvms/se7/html/jvms-4.html),可以直接讓 JVM load 起來執行。但是 Android 自有的 Dalvik 虛擬機吃的不是 class 格式,而是 DEX 格式的檔案,DEX 也就是 Dalvik EXecutable 的意思。 要生成 DEX 格式檔案,在 Java 程式碼編譯為 class 檔案後,需用 Android 的 dx compiler (或是下一代 compiler [D8](https://developer.android.com/studio/command-line/d8)) 來將 class 檔再編譯成 DEX 檔案。 通常將 apk 解開來後,可以看到裡面都會有一個 classes.dex,這個就是 Dalvik 吃的 DEX 格式檔案,所有 App 的 Java 程式碼都會被編譯到這個檔案中。 ## ODEX Dalvik 在將 classes.dex 檔案跑起來的時候,會做一些最佳化例如將 virtual method 查找的動作移除改為直接呼叫某 index 上的 method 以節省時間,但這個動作是每次將 dex 載入時都會執行一次。為了節省這個時間,Android 將最佳化後的 dex 寫成檔案儲存到 Dalvik 的 cache 目錄中,也就是 odex 檔案,以後 Dalvik 要再執行同一個 App 時,載入的會是 cache 目錄中的 odex 檔。 這個 dex to odex 的轉換是由 Android 上自帶的工具 dexopt 完成的,odex 檔中大部分的內容都跟原本的 classes.dex 差不多,只是做了一些最佳化而已。 ## OAT Android 為了要讓 App 執行的更快速,在 Dalvik 中使用了 JIT 技術,將 Dalvik bytecode 轉換為 native code,但是 JIT 是在 App 執行過程中完成,而且是每次 App 跑起來都會做一次,這浪費了不必要的資源,因此在 Android 5.0 之後,採用了新的策略,在 App 安裝時就將 classes.dex 檔案裡的程式碼使用 Android 平台自帶的 dex2oat 工具編譯為 native code,並且將其放在另一種格式的檔案中。 這會造成 App 安裝的時間增加,但是 dex 到 native code 的轉換從此只要一次就好,而因為執行檔內容已經從 Dalvik bytecode 轉換為 native code 了,在這時期的虛擬機也從 Dalvik 變為 ART(Android Runtime) 來支援這種新執行檔格式。 這個新的檔案格式,實際上是一個 ELF 格式的檔案,但 ELF 只是一個殼,ELF 殼內存放的實際上是一個 Android 叫做 OAT 格式的資料。這可能不是那麼直觀,如果有網路封包概念的話,可以把它想像成類似 TCP/IP 封包架構,就像 MAC 封包的 payload 其實是 IP 封包,IP 封包的 payload 又是 TCP 封包。 而這個檔案的副檔名通常會是 .odex 或是 .oat,這可能也會讓人混淆,因為 Dalvik 時期 dex 最佳化後的檔案也叫 odex,因此 Android 上的副檔名不太可信,還是要實際看文件內容才能確定到底是甚麼格式的檔案。 要逆向 OAT 中的 native code 是極為困難的,但好在 OAT 檔案中已經包含了原本的 dex 檔案,說原本的也不太準確,它包含的是經過最佳化後的 dex 檔,但跟 native code 比起來還是好太多了,因此可以先從 OAT 中將 dex 提取出來,再作逆向。 ## VDEX 在 Android 8.0 之後,dex2oat 生成的不再是單一個 OAT 檔案,而是生成兩個檔案 classes.odex 跟 classes.vdex。 * classex.odex:包含 native code 的 OAT 檔 * classes.vdex:原本的 dex 檔的副本 這個時候要逆向,一樣可以從 vdex 中提取出 dex 檔,再作逆向 ## 結語 Android 上可執行檔的格式有 vdex、odex、oat、dex,其中又跟虛擬機 Dalvik、ART 牽扯在一起,要理清其中的關係的確不是那麼容易,在網路上看到一張圖,算是將這些檔案間的關係描述的相當清楚,放在這邊分享一下。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjdeIcIxbiOf2Bapn5YTfCIu3RMRVoHfFCmNVOkpMfg4bm2wO-EULWPambG_jNX2-SiMQQRJgHIHA_UmWDy3TFMcmSl1rZfJz0QE6Qg6Z_WkzOWlI-_EVfBnIQL96R71de0q6QwMPvWmTOe/s1600/658px-ART_view.png) Reference: * [Android formats](https://lief.quarkslab.com/doc/latest/tutorials/10_android_formats.html) * [Configuring ART](https://source.android.com/devices/tech/dalvik/configure) * [Android运行时ART加载OAT文件的过程分析](https://blog.csdn.net/Luoshengyang/article/details/39307813) * [Android ART运行时无缝替换Dalvik虚拟机的过程分析](https://blog.csdn.net/luoshengyang/article/details/18006645) * [ART view](https://en.wikipedia.org/wiki/File:ART_view.png)

2019年6月4日 星期二

電源供應器降溫筆記

markdown [之前](https://lausai360.blogspot.com/2019/06/r9-270.html)幫顯示卡成功降溫,就想著電腦裡還有甚麼發熱源可以來改善,然後發現電源供應器溫度也很高,目視看到風扇沒有在轉動,就把電源供應器也拆了,準備做個保養上油 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj-girVP64vb9w_4bdWzlrzDGzrP8UpMEKjQtJUvKV9wNZl9rUV2IenNMoKTky8AE8O1g9zR8QxKPfs7i2W8cWWY1sZRbByLKTzu3_ji1NKZqJjva3Tg8ZBKvfcourisXzWwOJgScZd3FQG/s1600/IMG_20190602_125139.jpg =600x*) 雖然顯示卡的問題跟風扇潤滑無關,但電源供應器就真的是風扇的潤滑劑乾掉了,拆下來用手轉就可以感覺到阻力極大。除了風扇外,灰塵也相當多,就簡單清了灰塵再把風扇上油,用大賣場買的膏狀黃油上到風扇軸承上再裝回去,就發現風扇好轉很多了。 電源供應器裝回電腦之後,看到風扇順利的轉起來,過了兩小時用手測溫,發現溫度很涼,跟之前摸到的高溫有天壤之別,降溫成就再加一。 原本還想幫機殼買個系統風扇來散熱,但做完顯示卡跟電源供應器降溫後應該是不需要了。

2019年6月1日 星期六

顯示卡 R9-270 降溫筆記

markdown 之前為了打遊戲買了一張憾迅 R9-270 ,不過一直沒有注意過它的溫度,最近無意中用手摸到顯示卡,才發現溫度高的驚人,於是開始想辦法讓顯示卡降溫。一開始先想到是不是風扇有問題,觀察了一下發現雖然顯示卡溫度很高但風扇卻轉速很低,於是以為是風扇潤滑乾掉了就把顯示卡拆下來保養,但沒想到拆完發現風扇的潤滑沒問題,但拆都拆了還是保養一下順便給風扇上點油。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEidqvOgoYkKHv7tPUqtYHs7L_JoaDpnnejIgTYBOAJNZqAmHL6M9xpViVx-41k65p5qrgv29goF3QdfhZg37_aMhyi27HqCVzltSkabU5QR5H6fvYAt3oBN-3pkwPls2LmVmSlDPYMmUS5a/s1600/IMG_20190601_090037.jpg =500x*) 接著谷歌找答案,發現 PTT 一篇[關鍵文章](https://www.ptt.cc/bbs/VideoCard/M.1479636880.A.335.html),情況跟我一模一樣,我這張卡待機也是 6x 度而且頻率在 450/1400。看起來是因為 BIOS 將待機頻率設的太高。接下來就是照文章中解法想辦法去改 BIOS 重刷了。 之前沒玩過顯示卡刷 BIOS,不過網路上找了一下發現也不是很麻煩,先用 [GPU-Z](https://www.techpowerup.com/gpuz/) 將原本的 BIOS 備份出來,然後用 [VBE7](https://www.techpowerup.com/forums/threads/vbe7-vbios-editor-for-radeon-hd-7000-series-cards.189089/) 修改 BIOS,然後再用 [ATIWinflash](https://www.techpowerup.com/download/ati-atiflash/) 將 BIOS 刷回去就可以了。 這種刷機玩法看似步驟並不複雜,但是當真的自己做的時候總是會發現不一定如網路上的教學文章這麼順利,像是我一開始刷完 BIOS 後發現待機頻率還是一樣在 450/1400,但是 BIOS 內我修改的風扇設定卻又有生效。這就讓人十分困惑了,那我刷的 BIOS 到底是成功還是失敗? 接下來就是瘋狂的 Google ,在 PTT 看到文章[這篇](https://www.ptt.cc/bbs/DigiCurrency/M.1495983520.A.0EF.html)跟[這篇](https://www.ptt.cc/bbs/PC_Shopping/M.1487655269.A.C5B.html)講到 AMD 新版的 driver 會鎖 BIOS,所以又抓了好幾版 driver 移除又重裝再加上用 [atikmdag-patcher](https://bitcoinforum.com/bitcoin-mining/atikmdag-patcher-1-4-7-14711/) 打 patch 不停的試。在 Try and Error 的過程中看到 [mobile01](https://www.mobile01.com/topicdetail.php?f=298&t=4988057) 有人也是用憾訊這張卡然後成功將待機頻率降低,但我不管怎麼試就是不行。 毫無頭緒的 Google 亂找,在一篇外國論壇中看到有人建議用 [DDU](https://www.wagnardsoft.com/) 移除 AMD driver,我就下載了 AMD 自己出的移除工具 [AMD Cleanup Utility](https://www.amd.com/zh-hant/support/kb/faq/gpu-601) 將 driver 移除重裝然後再刷 BIOS,神奇的事情發生了,待機頻率降到 300/150,顯示卡溫度也降到 42 度。 因為我在刷 BIOS 前曾經在 driver 中設定過頻率,我猜想也許是這個設定一直沒有被移除,直到用 AMD Cleanup Utility 後才被移掉(不過 AMD 搞到要出一個專門的移除工具會不會有點搞笑阿)。 雖然花了很多時間,但最終證實了 R9-270 刷 BIOS 是可以成功修改待機頻率與降溫的,溫度也低了差不多 20 度,結果還是挺滿意的。下面是我用的 BIOS 設定,在這邊記錄一下,而最後 driver 是用了 17.2.1 版。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjA6cfGxt_HjmkGe1NAYd3Ep9u8S0x5gcI8_I3XuTgfXqNBNLXo3d5teoG-55z2KIkjOdBgv6CPN5mYj1IPefcpSqGeR-YlfZMDBsSzuQ0ZyOmcae-sxBg8smMUZQteLWrda6qsLM58hvm4/s1600/Image+1.png =800x*)

2019年4月6日 星期六

android:supportsRtl 屬性在 Android 4.2 影響 PreferenceCategory left padding

markdown Android 踩坑又一發,最近在寫 app 時將原本的 PreferenceFragment 改為 PreferenceFragmentCompat,並且照[之前](http://lausai360.blogspot.com/2018/01/android-support-library-preference.html)介紹過的方式套用 material style,但改完後發現在 Android 4.2 上面 PreferenceCategory 的 left padding 為 0,跟其他的 preference 不對齊。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhFxc5DYrhLrxNliVBe-IIKyU0oDhJbP7YDvvC5-NQaO_z_IdMgr4iuNb8csBCqzPapOPcXtUpe_r-IdInkfI7C0PlAYGv0kaHLKR62tWS-zgmlechU_HqrE3TWHvXXjqCpSuWLEH_e216S/s1600/Image+7.png) 網路上不管怎麼搜尋,有關 left padding 的問題都是在問 support library 28 中 left padding 過大,從沒有 left padding 過小的問題,花了一天多都沒有找到原因。契而不捨的追查,血都吐了幾升,最後才發現 app 將 android:supportsRtl 設為 true 後,PreferenceCategory left padding 就恢復正常了。 android:supportsRtl 這個屬性只是影響你的 app 能不能從右到左布局,跟 Preference 根本沒有關連,怎麼都不會聯想到這個屬性會造成 Preference 布局異常。 後來用 android:supportsRtl keyword 去搜尋,也沒有找到任何跟 Preference 布局有關的討論,只能說自己太衰,踩到這個可能沒人踩過的坑。

2019年4月5日 星期五

Android allowBackup 設定

markdown 原本以為 Android app 移除後所有的資料包含 shared preference 都會被移除,但在測試 app 的時候發現,移除 app 再重新安裝後,之前儲存的 shared preference 被 reload 回來了。研究後發現這是因為 Android 會自動把 app 的資料備份出來,就算 app 被移除,備份的資料還在,當 app 重新安裝時就可以把舊資料覆蓋回來。 Android 還提供了一個 [allowBackup](https://developer.android.com/guide/topics/manifest/application-element#allowbackup) 的欄位可以讓開發者設定這個備份行為要不要打開,因為有時候也許開發者就是希望這個 app 重裝後要讓 shared preference 是初始狀態,不過這個欄位預設是 true。 後來 allowBackup 也被人提出有安全風險,因為如果這個欄位被設為 true 了,除了 Android 會自動備份之外,使用者也可以透過 adb 將 app 的 shared preference 備份出來,然後再還原到另一個機器上同樣的 app 內,這有可能會有資料洩漏的疑慮。所以在開發 app 時要注意到底要不要允許 allowBackup。

電錶的幾位半是甚麼意思

markdown 電表常常聽到四位半、五位半、六位半等等術語,這個幾位半是表示電表可以顯示的最大位數,例如三位半表示三個全位元加一個半位元的最高位,全位元是表示可以顯示 0 ~ 9 所有數字,半位元通常只能顯示 1,所以三位半的電表,若設定量程為 20v,則能顯示的最大電壓為 19.99 伏特。 因為半位元理論上要能顯示 2,但只能顯示 1,理論值為分母,實際最大值為分子,就叫 1/2 位也就是半位元。 事實上還有 2/3 位、4/5 位等等不同規格的最高位元,只是如果是統稱的話都可以叫做半位元,而每個電表的那個半位元理論值跟實際最大值多少,還是要看電表的手冊才能確定。

Android 當螢幕旋轉時保持 UI 狀態

markdown Android 的 activity 在螢幕旋轉時會被 destroy 然後再重新 create,這樣設計的用意是讓 activity 可以為不同螢幕方向套用不同的 layout,不過這樣會造成一個問題,就是 activity 重新 create 了,UI 也回復到初始狀態,想像一下如果在 UI 中有一個可以動態增加的 list,使用者只不過螢幕轉向了 list 就被清空,這應該是無法接受的。 在面對螢幕轉向的問題時,要嘛就是在 app 中限制螢幕方向不讓轉向,要嘛就是想辦法在螢幕轉向時保存 UI 資料。 螢幕轉向這種情況在 Android 中有專門的術語叫做 configuration change,螢幕轉向只是 configuration change 的其中一種,還有其他不同狀況的 configuration change 例如系統語言切換,Android 已經有提供兩個 callback function ,讓我們在 configuration change 時保存與回復資料。 * [onSaveInstanceState](https://developer.android.com/reference/android/app/Activity.html?hl=zh-tw#onSaveInstanceState(android.os.Bundle)) * [onRestoreInstanceState](https://developer.android.com/reference/android/app/Activity.html?hl=zh-tw#onRestoreInstanceState(android.os.Bundle)) 這兩個 callback function 是 activity life cycle 的其中一環,在 activity 因螢幕轉向被 destroy 和 recreate 的過程中會呼叫這兩個 callback function,開發者趁此機會把一些該存的資料保存起來。 不過這個方式有些問題,就是被保存的資料是寫入到 disk 中的,而這兩個 callback function 又是在 main thread 中執行的,若是小量單純的資料還好,但若是複雜的資料就不適合了,可能會讓 app 感覺 lag,使用者體驗變差。而且如果每次螢幕轉向資料都要寫入到 disk 一次,想想也覺得挺蠢的。 對這個問題,網上有人提出用一個 fragment 來保存這些資料,並且呼叫 Fragment.setRetainInstance(true) 讓 fragment 可以在螢幕轉向時不要被 recreate。這個方法不錯,而後在 2017 Google IO 大會上,Google 提出了一系列新的組件,其中有一個叫做 ViewModel 的組件,就是用來解決這個問題,其背後的原理,就是在內部用了一個 Fragment 並且設定 RetainInstance 為 true。 下面的圖很清楚的表達了 ViewModel 的 life cycle,除非 activity 被 finish 了,不然不管你怎麼重建,ViewModel 都還是在記憶體中活得好好的。至此,ViewModel 成為了處理螢幕轉向問題的最佳解法。 ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg0UrVMhkC_dQPGvD_0DiCoQtQwOQ7YWDWzLOG8FVPI8TsQ1zw8q9d3e_brMrGgSPr_Mnc0SimTw8vvVpdhmJPvwHuv3QG-cb4ymkps2fxq6vrugZZYm5USO_emhW8VBRiUpCbQza8yctJq/s1600/1+3Kr2-5HE0TLZ4eqq8UQCkQ.png) 但 ViewModel 的出現並不是要取代之前的 onSaveInstanceState、onRestoreInstanceState callback function,onSaveInstanceState 會在系統因一些資源匱乏的原因殺死你的 app 前呼叫,不只是在螢幕轉向時呼叫而已,將一些重要的資料保存在 disk 還是有必要的。所以還是應該視需求來決定用何種方式來保存你的 UI 資料。 Reference: * [The Real Best Practices to Save/Restore Activity's and Fragment's state. (StatedFragment is now deprecated)](https://inthecheesefactory.com/blog/fragment-state-saving-best-practices/en) * [ViewModels : A Simple Example](https://medium.com/androiddevelopers/viewmodels-a-simple-example-ed5ac416317e) * [ViewModels: Persistence, onSaveInstanceState(), Restoring UI State and Loaders](https://medium.com/androiddevelopers/viewmodels-persistence-onsaveinstancestate-restoring-ui-state-and-loaders-fc7cc4a6c090)

2019年4月2日 星期二

Intermodulation Distortion 三階互調失真

markdown IMD (Intermodulation Distortion),中文叫做互調失真,是分析 RF 性能的一個指標。它的由來是當 RF 訊號經過 power amplifier 之後造成的各階諧波雜訊與原訊號交互生成產生。 在理想的 power amplifier 中,一個在 F1 頻率的訊號進入,其輸出訊號應該只有在 F1 頻率上然後功率增強過的訊號,但是現實中的 power amplifier 會在 F1 的整數倍頻率,例如會在 2F1、3F1……等頻率產生諧波。 假如今天輸入訊號是兩個 RF 訊號 F1 跟 F2,情況就變得更複雜了,除了會產生 2F1,2F2 等諧波,還會產生 second order distortion product、third order distortion product,所謂 second order distortion product 就是在一階諧波頻率相加減的頻率處,也就是在 F1 + F2 和 F2 - F1 (假設 F2 > F1) 處產生的雜訊。third order distortion product 就是在一階諧波頻率與二階諧波頻率相加減的頻率處產生的雜訊,可見下圖。當然還有三階跟四階乃至於無限階的 distortion product。但那些不會是關注的重點,一般來說關注的只有 third order distortion product,因為它的頻率最接近原始輸入訊號,很容易影響訊號品質。 ![三階互調失真](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhtn863tETzUScNS5C9DZhaOt163jD_1kic6pRZIi2ujPEKrupntn9el1eMRCvsL91WSGKwuVvT2tkaoYvnKtMeKFm0fFDTV1V5xzKPa-TCA6kVL1dFn_XyCb6btxnV8ipTyhloj2vCMfsx/s1600/1107_MakingWaves_F1.gif) Intermodulation distortion product 還有個特性是訊號強度增加的速度是 power amplifier 輸出原始訊號強度的三倍,也就是原訊號假如增強 1db,那 intermodulation distortion product 就會增加 3db,所以理論上在原始訊號達到某個強度的時候,third order distortion product 會跟原始輸出訊號強度一樣強,而這此時的訊號強度就稱為 TOI(Third-Order Intercept) 雖然理論上 third order distortion product 有可能跟原始輸出訊號一樣強,但是這個值通常會非常大,所以一般來說都是計算得出,而不是真正量測到。TOI 的計算可以參考下圖,假設 IP 為原始訊號強度與 intermodulation distortion product 強度 Pout的差,則 TOI 的公式如下 TOI = Pout + |IP/2| ![](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiJR3F60dt2hNeNJ-kZiy_t93naObsM0v8a8xY1QeqzZYDBLYe46_IdgRvL7Va4cXdmHx2_dJ5ePQHD9wgDfMRm4z-4A6ujBWo2-geYAcBRjtKc6dSXpP303ED5XKtWjPirW9ThpM1kPkQT/s1600/Image+2.png) Reference: * [Intermodulation Distortion Measurements](https://www.electronicdesign.com/communications/understanding-intermodulation-distortion-measurements) * [Intermodulation Performance and Measurement of Intermodulation Components](http://users.tpg.com.au/users/ldbutler/Intermodulation.htm) * [Understanding Radio Frequency Distortion](https://www.dsprelated.com/showarticle/108.php) * [Intermodulation Distortion(IMD) Measurements](https://www.electrotest.co.nz/site/etl/Papers/Intermod_Measurements.pdf)

2019年3月20日 星期三

RJ45 loopback

markdown 網路線的水晶接頭,正式名稱為 RJ45,接頭總共有 8 個 pin 腳,一般在 Megabits 的速度中只會使用到 1, 2, 3, 6 四根接腳,其他四根 pin 腳其實是沒有用到的,如下圖所示 ![RJ45 接頭](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhDPO2bLH4jNL1uitQRk_hgjDpIRxogHzUfICQwBVY19edb9wOOivGiKul254afmGP5LE7w2rDCT01otYSniaXDrCtF2izwFROsjlWnVogJJkCRYT9mEjbNxXoxLohJCchNcxJ8fXpucij8/s1600/RJ45_1.jpg) ## Loopback Loopback 其實就是把 RJ45 那四根 pin 的 TX+ 接到 RX+,TX- 接到 RX-,這樣 TX 傳甚麼資料出去,就會從 RX 收回來,那為什麼會有這個需求,可能有很多原因,例如要作 ethernet 燒機時,用一個 loopback 的 RJ45 水晶頭就可以自打自收作燒機 ## Gigabit Loopback Gigabit 模式下的 loopback 有人說在 windows 下無法啟用,因為 gigabit protocol 的 NEXT 功能會讓 loopback 失效,但 gigabit loopback 在網路上資料太少,所以到底能不能用目前還是不清楚 Reference: * [《分享》RJ45網路線的針腳定義](http://www.shunze.info/forum/thread.php?threadid=1054&boardid=4&styleid=1) * [請問Gigabit NIC如何做loopback的接頭](http://phorum.study-area.org/index.php?topic=39553.0) * [Ethernet RJ45 connection wiring and cable pinout](http://pinouts.ru/NetworkCables/ethernet_10_100_1000_pinout.shtml) * [RJ-45 Link基本原理](http://gienmin.blogspot.com/2014/02/rj-45-link.html) * [Gigabit Ethernet is Full-Duplex only!](http://sqlblog.com/blogs/joe_chang/archive/2010/03/23/gigabit-and-full-duplex.aspx) * [RJ45短路環在千兆網卡上的應用](https://blog.csdn.net/smstong/article/details/8812753) * [Cable Testing 101: Understanding Near and Far End Crosstalk](https://www.flukenetworks.com/blog/cabling-chronicles/cable-testing-101-cross-talk-near-and-far)

2019年3月17日 星期日

SD Card Tester Privacy Policy

markdown samliu720 built the SD Card Tester app as an Ad Supported app. This SERVICE is provided by samliu720 at no cost and is intended for use as is. This page is used to inform visitors regarding my policies with the collection, use, and disclosure of Personal Information if anyone decided to use my Service. If you choose to use my Service, then you agree to the collection and use of information in relation to this policy. The Personal Information that I collect is used for providing and improving the Service. I will not use or share your information with anyone except as described in this Privacy Policy. The terms used in this Privacy Policy have the same meanings as in our Terms and Conditions, which is accessible at SD Card Tester unless otherwise defined in this Privacy Policy. ### Information Collection and Use For a better experience, while using our Service, I may require you to provide us with certain personally identifiable information. The information that I request will be retained on your device and is not collected by me in any way. The app does use third party services that may collect information used to identify you. Link to privacy policy of third party service providers used by the app * [Google Play Services](https://policies.google.com/privacy) ### Log Data I want to inform you that whenever you use my Service, in a case of an error in the app I collect data and information (through third party products) on your phone called Log Data. This Log Data may include information such as your device Internet Protocol (“IP”) address, device name, operating system version, the configuration of the app when utilizing my Service, the time and date of your use of the Service, and other statistics. ### Cookies Cookies are files with a small amount of data that are commonly used as anonymous unique identifiers. These are sent to your browser from the websites that you visit and are stored on your device's internal memory. This Service does not use these “cookies” explicitly. However, the app may use third party code and libraries that use “cookies” to collect information and improve their services. You have the option to either accept or refuse these cookies and know when a cookie is being sent to your device. If you choose to refuse our cookies, you may not be able to use some portions of this Service. ### Service Providers I may employ third-party companies and individuals due to the following reasons: * To facilitate our Service; * To provide the Service on our behalf; * To perform Service-related services; or * To assist us in analyzing how our Service is used. I want to inform users of this Service that these third parties have access to your Personal Information. The reason is to perform the tasks assigned to them on our behalf. However, they are obligated not to disclose or use the information for any other purpose. ### Security I value your trust in providing us your Personal Information, thus we are striving to use commercially acceptable means of protecting it. But remember that no method of transmission over the internet, or method of electronic storage is 100% secure and reliable, and I cannot guarantee its absolute security. ### Links to Other Sites This Service may contain links to other sites. If you click on a third-party link, you will be directed to that site. Note that these external sites are not operated by me. Therefore, I strongly advise you to review the Privacy Policy of these websites. I have no control over and assume no responsibility for the content, privacy policies, or practices of any third-party sites or services. ### Children’s Privacy These Services do not address anyone under the age of 13. I do not knowingly collect personally identifiable information from children under 13. In the case I discover that a child under 13 has provided me with personal information, I immediately delete this from our servers. If you are a parent or guardian and you are aware that your child has provided us with personal information, please contact me so that I will be able to do necessary actions. ### Changes to This Privacy Policy I may update our Privacy Policy from time to time. Thus, you are advised to review this page periodically for any changes. I will notify you of any changes by posting the new Privacy Policy on this page. These changes are effective immediately after they are posted on this page. ### Contact Us If you have any questions or suggestions about my Privacy Policy, do not hesitate to contact me.

2019年3月12日 星期二

Android studio build 出現 Lint found fatal errors

markdown Android studio 在 build release apk 時出現 error,訊息為
Lint found fatal errors while assembling a release target.
在 android studio 中其實找不太到甚麼有用的錯誤訊息,在 [SO](https://stackoverflow.com/questions/24098494/error-when-generate-signed-apk) 上面有人提供了解答,在在 report 路徑下會有 build fail 的詳細訊息,若是不知道 build fail 的原因的話,記得檢查一下 build fail 的 report,路徑如下
[app module]/build/reports/lint-results-yourBuildName-fatal.html

2019年3月7日 星期四

使用 R 語言繪製 CPK 圖表

markdown R 語言可以用來繪製 CPK 圖表,雖然有時候會感覺畫出來的圖不是那麼的準確,但大部分狀況下應該是堪用了,特別是有時候只想簡略的表示一下資料分布情形 用 R 語言繪製圖表前需要先將資料準備好,只要將資料以 csv 的形式存起來,並且在第一列放上 title 就可以了,如下圖 ![CPK data sample](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi3sn31ZFy6E4B3hC1-L04neSRMQNRDT27QEeUk69h7qZkDWgU4ibLfcbypG7cF1GrWWmTAa4W-DE4ElE4d_qic26nNRUKgdq1yf_38VxdVxcyErA_U5unz19ZjN5_FHq6bPFEKtKfMwzpD/s1600/cpk_data.png) 然後在 R Studio 裡面使用 read.csv 將 csv 資料讀進來,並且 assign 給你的變數 接著需要使用 SigSigma library,若是沒有安裝的話,記得先用 install.packages("SixSigma") 來安裝 這個 library 裡面已經有 function ss.study.cs 可以將資料畫出 CPK 圖出來,這個 function 有一些參數需要設定 * xST,短期資料,就是從 csv 讀進來的變數 * LSL,規格下限 * USL,規格上限 * Target,規格中心 * f.main,圖表標題 ![r studio](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEioCftaiYryvAUQMFnIwrecpHuCJDa7SXuUY9YHzoAOu3z4VETMtGE8wIEdz08D3gAMylkOTSaRhO-FV5ssvzPES2zNwcG3UXf9fKHy60_7qJeglLdfsQRQarg-Xr8rIAB9PERdaE3AGlBO/s1600/r_studio.png) 將這些變數設定好,執行這個 function,就可以畫出圖表來 ![CPK sample](https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi36bxbiW5nnWPLgOxkriDgJi-ZiSqKjnYyDLxbuz5h_ab76aqm7LVGsu_2ONjh3Ap0bfAZNgCzmOrrbT1cQXx96Sb-XrWAhQVA7-WAYKUFh4LhSyNX6y8oHWnfMwoDT4cm5dgDE29bdI5j/s1600/cpk.png) --- * [R語言中的品質工具 -- 製程能力分析](http://alipupu.blogspot.com/2016/05/r.html)

2019年1月1日 星期二

Android ImageView 搭配 wrap_content 時的寬高

markdown 當 ImageView 的寬高設定都是 wrap_content 時,很自然會想到圖片是以原始大小來顯示在螢幕上的,不過最近才發現這個原始大小的單位不是 pixel,而是 dp 例如以下 ImageView 的寫法
<ImageView
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/my_png">
</ImageView>
假設圖片的原始大小為 256 * 256 pixels,不要以為在螢幕上就是佔了 256 * 256 pixels 的大小,實際上是佔了 256 * 256 dp 的大小,dp 會隨著不同的 device 而改變。假設圖片放在 res/drawable 資料夾,如果 app 現在跑在 XXHDPI 的手機上,圖片載入後長寬會變為 3 倍,佔用的記憶體會變為 9 倍。 這除了會讓圖片在螢幕上的大小比你預想的大之外,也會讓圖片占用的記憶體大小大大超出你的預期,不可不注意。 --- Reference: * [Android中的dp,px以及wrap_content的实际展示效果](http://www.cnblogs.com/littlepanpc/p/3513929.html) * [關於Android中圖片大小、記憶體佔用與drawable資料夾關係的研究與分析](https://itw01.com/V3NTEFQ.html) * [Android坑档案:你的Bitmap究竟占多大内存?](https://zhuanlan.zhihu.com/p/20732309)