CodeHighlight

2017年11月4日 星期六

[開箱] mooink 電子書閱讀器


這東西其實已經拿到好一段時間了,不過因為這是我的第一個電子書閱讀器,所以花了點時間熟悉他。

Moooink,是由臺灣廠商「Readmoo讀墨」自製發行的電子書閱讀器,

本身搭載Android 4.4.2,主要賣點在電子紙材質的顯示器,如同Kindle一樣,本身並不會自行發光,需要借助外在光源才可以看。

也就是說,這樣看起來就像紙本書一樣適合長時間閱讀,不會像手機平板一樣看久會眼睛痠痛

當然,這還是無助於看到書就會頭痛想睡的症狀就是了。


當初購買時是跟上群募的首購優惠,所以手邊拿到的是木紋材質版本




可以看到整機都是以木紋呈現,摸起來質感有點像是木紋紙的感覺,

下方從左到右各別是micro USB、micro SD card插槽、電源鈕

在現在新手機都是type C當道的情況下,他讓目前快失業的micro USB可以得以續命呀!

micro SD card可以擴充裡面的空間,也可以在更新後,把ebup格式傳進去讀取

電源鈕則是開關機和喚醒設備,Home鍵則是在螢幕下方那顆大顆的按鈕


六吋的大小對於我來說拿起來剛好,單手看不會感受到太負擔,不過個人私心還是希望可以在大一些

才可以和過往讀紙本書的經驗相符呀~

(補一張和紙本書的對照圖)

操作上個人上來算直覺,基本上就和手機板的Readmoo配置相似

網路連線上是走Wi-Fi,然後他只有支援2.4G,所以找不到5G AP是很正常的



書櫃頁面可以選擇先把書下載下來,這樣之後到沒有網路的地方,也可以正常的閱讀。

相關的閱歷會在連上網路後在一併同步到網路上。


點開書之後,就直接進入閱讀畫面,

以橫式書籍來說,點右邊或是由右往左滑都是翻到下一頁

反之則是翻到上一頁


輕點螢幕中間後,選中間的「aA」圖示可以調整字型、字體,還有橫書直書的設定



變成直書模式時,翻頁的手式就和橫書相反

點左邊或由左滑到右是下一頁,反之則是上一頁


翻頁的速度個人覺得還不算慢,和看紙本書的節奏感差距不大。

不過在開新書,以及圖片較多的頁面時,讀取會明顯被拖慢,這應該是顯像相關的限制

但整體上不太影響閱讀體驗。



​在書櫃的上方可以選擇要從哪邊選書

「書籍」代表從readmoo上面購買的電子書

「文件」則是上傳到readmoo的epub、pdf、docx、txt檔案

「本機」「SD卡」便是代表放在這兩個地方的epub、pdf、docx、txt檔案


​個人是只有試過上傳到readmoo的方式,在Readmoo的網站上面中有個「文件」的功能,在那邊可以上傳相關檔案。

之後再將Mooink連網,並同步整個書櫃,這些資料就會出現在你的閱讀器上面了。
身為一個長年有在閱讀的小書蟲,最大的問題就是家裡書櫃空間有限

尤其現在在外租屋,空間上更顯不足,在圖書館借書又會有時限的問題。

電子書閱讀器剛好補足這方面的需求

在電量部分,看來他會在進入待機模式時把Wi-Fi關掉。

因此手邊這台待機兩個禮拜,都還有剩下10%~20%的電

以個人使用上算是相當足夠了


書籍來源的部分除了readmoo本身的書籍外,

匯入epub應該才是主要的書籍來源,畢竟現在線上電子書的數量有限,

還是需要更多的書籍來源來補足這一塊。


如果手邊已經有Kindle的人,這個可能就不這麼適合

因為基本功能上是相同的,而且會用Kindle的人,應該也都有自己的書籍來源

不過如果是剛踏入電子書這個坑的人,Mooink會是不錯的入門選擇。

至少,有中文電子書就先加分了!

2017年6月18日 星期日

[桌遊] 台北大空襲開箱&簡單心得

看文之前,先上首主題曲
(雖然官方是和閃靈合作,不過我覺得這首歌比較適合這個遊戲)


    這款桌遊最近在募資上面還蠻熱門的,問了身邊也在玩桌遊的朋友,幾乎都有聽過這一款的募資訊息。遊戲背景是基於1945年5月31日,美軍在台北地區發動的大規模空襲行動為發想的一款合作生存遊戲。遊戲目的就是在試著在戰爭結束之前「一個都不能少」利用地圖上所剩的資源,努力的支持到戰爭結束。

    當初會加入這個募資方案,一部分是對這段歷史的好奇。你知我知獨眼龍也知我們的歷史課本是教了哪些東西,在多年來大中國主義的教育基調下,即使經歷了多次的課綱修改,這種和台灣相關的歷史多數是付之闕如...

    咳咳,讓我們先回到桌遊上面,另一個吸引我的點在於,以往接觸到合作類型作品的稀少。不過也可能是小弟比較顧人怨,多次開團總是會被選擇對抗/陣營類型的桌遊,然後成為被集火的那一個。因此想說來入手一款合作類型的桌遊,算是做為一種嘗鮮。

開箱紀錄

    


    拿到貨的時候,想說這怎麼比預期的大那麼多,為了讓大家知道實際大小,就拿本末日之旅來當個比例尺吧!歐對了,最近剛看完第三集,這系列在這本完結篇後,強勢降臨本人生涯推薦書單前三名!

    

     因為我是跟募資首發的早鳥版本,所以除了遊戲以外,還有附贈海報兩張,還有台灣神社御朱印紀念物一份。



    台灣神社,最早是祭祀北白川宮能久親王用的,不過看來和台灣的廟宇有點類似,久了之後除了主祭的之外,也會一同供奉其他的神祇,這樣要朝拜的話,一間廟宇可以滿足多種需求
    不過小弟沒有去過真正的日本神社,所以也沒有看過其他神社的御朱印是長甚麼樣子,不過身為參拜的憑證,感覺是個很神聖的東西呀。

    


    兩張募資首發限定的海報:台北大空襲和媽祖接炸彈。是說照片拍的不是很好,反光真的頗嚴重...
   


    正面是台北大空襲的燙金文字,配上黑底與煙霧的圖案,展現出煙硝瀰漫的氛圍


    反面是一家八口一字排開,每個人背負著自己的故事,在一波波空襲中要努力活下去



「攤開時代,我們摺疊命運」,「贏就一起贏,輸就一起輸!!」
兩句標語放在包裝盒的側面


另外兩側是台北大空襲的中英標語,背景一個是龍山寺,另一個應該是北一女中



拿掉外面的包裝,裡面的封面是整個台北城被轟炸的景象


    說明書一本,內容後續會在提到。


    人物標記和建築毀損標記,當「台北大空襲」事件發生之後,所有的特殊建築會被炸毀而失效。這個應該是紙類的材質,不過摸起來相當的扎實。


    遊戲地圖,攤開來其實還挺大的,黃色的部分代表道路,可以看到帝大醫院、台灣神社這類地方都有額外的buff效果,遊戲中會需要妥善利用。




    八個遊戲角色:爺爺、奶奶、爸爸、媽媽、哥哥、姐姐、弟弟、妹妹
每個人的飽食、生命、心情、體力、行動點上限都不同,只要其中飽食、生命、心情、體力任一歸零,該角色就陣亡了。那個弟弟的飽食只有三是要逼死誰呀!


    上方是人物角色卡,下方則是事件卡。每個角色都有各自的故事,如果沒有完成的話,每回合都會有debuff的效果,甚至還會把心情上限鎖到1...
    事件卡則是很大程度的決定該回合的走向,如果未能達成相關條件,一樣會受到debuff的效果。滿滿的debuff呀!

    
    轟炸事件卡,每回合抽出一張,決定該回合哪個地方被轟炸。
如果被轟炸時人也在那邊的話,健康直接扣兩點。
其中遊戲分成前期(1~3回合)、中期(4~6回合)和後期(7~9回合)
前期有機會抽到「媽祖接炸彈」,代表下回合所有轟炸效果移除,不會有新的轟炸點出現。
中期則有機會出「台北大空襲」,所有地點都會受到轟炸傷害,而且buff地點全數失效
後期則是大家期待的「戰爭結束」,如果抽到這張時大家都還活著,則宣告遊戲勝利。




遊戲中可以藉由探索取得各式各樣的物資,其中分成食物、道具、藥品和羈絆

食物卡:主要是補充飽食度用的,當然如果是拿到腐爛食物或動物屍體的話,就需要找簡易火爐煮一煮,來消除負面效果。

是說他只是簡易火爐而以呀,所以用一次就壞,也是很合理的~
然後不用懷疑,小黑和桃子也是可以當食物的,只是吃了之後呢...



道具卡:多數提供buff效果,各有各的強項,不過硬要說的話,還是期待可以抽到空襲傳單~
其中機密文件是屬於羈絆類的道具卡


藥品卡:用來回覆生命和體力之用,祖先牌位是羈絆類的藥品卡,如果沒有相關人物任務的話,是可以不用放進去的。


羈絆卡,主要是針對各個人物任務的需求才要加到遊戲裡面的


B-24 空襲標記和起始玩家指示物,空襲標記的金屬材質拿起來質感還不錯。

狀態指示物,標準的木製質感,他絕對不是MM巧克力!

遊戲心得

    拿到後一周才過完大概的流程和糾到人跑流程。自己過完說明書後感受到滿滿的debuff惡意,所以決定用推薦的初始角色和羈絆任務來進行遊戲,下面是首次跑關的概略紀錄。

初期階段(1~3回合)

    身為一家之中最小的妹妹,我心愛的桃子在空襲之後不見了!心裡好難過好難過,所以為了可以快點找到他,我馬上拿了手推車往外跑,希望可以快點找到我心愛的桃子。
    為什麼不在家裡附近先找呢?因為哥哥和奶奶已經翻完家裡的東西啦!桃子看來已經逃離家裡了。
    爸爸則是一開始就往外跑,聽他說好像是要找到甚麼機密文件的。不過這不重要啦,我的桃子才是最重要的。
    台北驛翻完了之後,手推車也滿了,可是還沒找到心愛的桃子。這時候遇到路過的爸爸,我趕緊手邊的食物分一點給他,亂丟食物奶奶可是會生氣的呀,不小心把他氣死就麻煩了。然後趕到下一個地點鐵道飯店,希望可以找到我心愛的桃子。
     但是在這時候,一波空襲來到鐵道飯店,幸好沒有被直接炸中,不過被飛濺的碎石和衝擊波傷了手腳,不過還不礙事,為了心愛的桃子,一切都值得!

中期階段(4~6回合)

      最後,在江山樓那邊找到了桃子,我發誓這次不會在和牠分開了。
聽說前段時間有人看到一個白藍頭髮的漂亮姐姐,接下了從天而降的炸彈。
不過這不太重要啦,因為爸爸找到了空襲的傳單,在加上哥哥在圖書館裡面找到的機密文件,換得後面幾波空襲的情報。看來我們只要躲好一點,這樣應該就不會受到影響了吧。
    話說如此,最近一波大霧讓附近伸手不見五指,找東西都變得十分困難了,還是先找地方躲躲吧。這時候看了一下後續的轟炸點,得知美軍即將進行全面的轟炸!
    看看爸爸身上攙扶著的美國大兵,這不對呀!那位大兵如此行動不便,怎麼可能再撐的過一次轟炸呢!還是給她點盤纏讓她去避難吧!
    可是大兵表示,希望可以給兩份食物讓他好避難。好呀,這個時候大家都不夠吃了,手上的食物是兩隻大雞腿,一隻可以讓我們一家多撐一天耶,怎麼可以給你呢!
    這時哥哥姍姍來遲,給了大兵一份香蕉飴。爸爸看著我,一副無奈又堅持的表情,到底支持爸爸的是人道精神,還是甚麼其他的情感呢?只知道如果大兵掛了,爸爸應該也不能獨活吧。
    事以至此,我只能默默的交出一隻大雞腿,看著蹣跚而去的大兵,大空襲接著而來...

後期階段(7~9回合)

    大空襲結束後滿目瘡痍,附近的食物也幾乎吃完了,手上的只剩下雞腿和動物的屍體,到底我們還能支撐多久呢...
    如果真的不行的話,只能犧牲小黑了嗎?比起桃子,還是先犧牲小黑吧,可是他畢竟是我們的一份子呀!
     就在糾結的時候,突然響起了廣播聲:「朕深鑑世界大勢與帝國現狀,欲以非常措置收拾時局,茲告爾忠良臣民...」
     停戰了!戰爭結束了!這段苦難終於結束了,我們終於可以恢復正常的生活了!

後紀

    果然是官方推薦的入門劇本,基本上完成羈絆任務之後,大概有1/3的空襲地點是可以提前知道的,每次避開被炸的狀況,就可以減少去找藥品的負擔,也大大提升了生存的可能。
    然後食物方面在四人局的情況下,如果要撐到第九回合的話,應該勢必得面臨到吃小黑或桃子的狀況,而且到時後沒有台灣神社的強大快樂buff,消失的快樂補不回來的情況下,可能會面臨快樂歸零的陣亡情況。
    
    總體而言,這遊戲的合作性算中上,各自的任務基本上可以各自解掉,但是如果可以分工收集物資,可以大幅增加存活的機會。只是其中有些道具的使用說明沒有那麼清楚,但是看到官方有公告規則書補正的計畫,就看看最後面能不能把那些洞補完吧!

2017年6月2日 星期五

[Android] Monkey testing in Android

在進行開發的時候,驗證也是其中很重要的一環。

基本的測試多是利用預期的行為去作驗證。

但是使用的情境百百種,沒辦法完全涵蓋住。

為了彌補這個狀況,Monkey Testing就由此而生


第一次接觸到這名詞時,覺得是不是養一隻猴子在那邊亂點XD

不過實際運作起來,其實也差不多了

Android本身就內建Monkey Testing的測試工具

可以透過adb shell的指令去把它開起來

基本的測試指令如下:

adb shell monkey -s 50 -v 500

-s: 給予一個seed,Monkey會根據這個Seed隨機產生不同的測試flow

-v: 總共需要幾個測試步驟,代表會進行500次操作


開始跑之後,就會發現手機的螢幕開始瘋狂的亂跳,代表有一隻看不見的猴子在幫你測試了'XD

2017年4月26日 星期三

[Android] Build break: ERROR XXX undefined

最近案子整個大爆炸呀!

幾乎每天都在跨日大戰,腦容量整個降到一個低點。

還好這幾日應該慢慢狀況慢慢穩定下來了。

好想休假呀~~

=====================碎碎念結束=========================

前陣子在帶新案子起來的時候,過程中各個module在把好幾包code倒來倒去

某日就接到了Build break在我這邊的module:



ERROR: "msm_11ad_modinit" [drivers/net/wireless/ath/wil6210/wil6210.ko] undefined!
ERROR: "msm_11ad_dev_init" [drivers/net/wireless/ath/wil6210/wil6210.ko] undefined!
ERROR: "msm_11ad_modexit" [drivers/net/wireless/ath/wil6210/wil6210.ko] undefined!
make[2]: *** [__modpost] Error 1
make[1]: *** [modules] Error 2
make[1]: *** Waiting for unfinished jobs...

嗯,看起來應該是倒code的時候某些東西沒有跟上了吧!
看了一下,Undefined的部分是編wil6210.ko的時候。
所以這個時候就有兩條路了:

  1. 是那些東西沒有define
  2. 這個module到底有沒有要build
如果是第一種,那就是trace code的功夫了,那也就沒甚麼好說的。
會在這邊廢話,代表狀況其實是第二種。
內部查了一下,發現wil6210這個東西其實本來就沒有要build的。
那為什麼會被build進去呢?

原來在build kernel的階段,每個module會根據kconfig的內容,決定要不要build這個東西
像這次就是CONFIG_WIL6210這個值在倒code時被設起來了,
所以才會出現這樣的狀況。

解法:在Kconfig中找到CONFIG_WIL6210,拔掉它即可。

2017年4月5日 星期三

[Android] sendEmptyMessage 和 sendEmptyMessageDelayed

    最近在測試上面,有需要在Android上面針對特定功能反覆開關的需求。

本來是想說在原本的原始碼上面讓他定時反覆啟動。

不過這樣每次都要額外加code以及build code,實在是有點麻煩。

所以這邊試著寫一個簡單的APP去定時做這件事情。

不過Android APP嗎,你知道的,如果用一般的delay的話,過一下就ANR了

爬了一下Android framework的做法,後來決定用Handler thread + delay message的方法來做

概念上是宣告一個handler thread,這東西會用一個獨立的thread去聽message。

如果有人對這個handler 送message,handler可以根據不同的message,去做不同的事情。

而利用延遲訊息(delayMessage),可以達到定時去做同一件事情的效果。

這邊筆記一下Handler底下sendEmptyMessage 和sendEmptyMessageDelayed的差異。


sendEmptyMessage

原生宣告是 boolean sendEmptyMessage (int what)

顧名思義,這個function是送一個空的訊息給Handler

所以不用把東西特別包成Message型態,可以直接送一個int的值



sendEmptyMessageDelayed

原生宣告是 boolean sendEmptyMessageDelayed (int what, long delayMillis)

相較於sendEmptyMessage,他可以決定到底這個message要等多久後再送,單位是ms


下面是一個簡單的範例:



    
    private static final int NEXT_ACTION_INTERVAL_MS = 5000;                                                                                                                                                 

...

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.i(TAG, "onCreate()+");
    setContentView(R.layout.main);
    context = this;
    mWifiManager = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);
    mLock = mWifiManager.createMulticastLock(TAG);

    mHandler = new Handler(Looper.getMainLooper()) ;

    // 宣告一個按鈕,按下去後就會去sendEmptyMessage(CMD_START_TEST)給mThreadHandler
    button1 = (Button) findViewById(R.id.button1);
    button1.setOnClickListener( new OnClickListener() {
            public void onClick(View v) {
            mThreadHandler.sendEmptyMessage(CMD_START_TEST);
            result_text.setText("Start thread action");
            }
            });

...

    mThread = new HandlerThread("name");
    mThread.start();
    mThreadHandler = new Handler(mThread.getLooper()) {
        private boolean isRunning = false;
        private int mCounter = 0;
        @Override
            public void handleMessage (Message msg) {
                super.handleMessage(msg);
                switch (msg.what) {
                    // ** 接到CMD_START_TEST後,除了做特定的事情外。
                    // ** 並會等候NEXT_ACTION_INTERVAL_MS後再發CMD_LOOP_TEST
                    case CMD_START_TEST:
                        if (!isRunning) {
                            this.sendEmptyMessageDelayed(CMD_LOOP_TEST, NEXT_ACTION_INTERVAL_MS);
                            isRunning = true;
                            Log.e(TAG, "Start Testing!");
                            mWifiManager.startScan();
                            mCounter++;
                            result_text.setText("Repeat times: " + mCounter);
                        }
                        break;
                    case CMD_STOP_TEST:
                        isRunning = false;
                        mCounter = 0;
                        break;
                    // ** 接到CME_LOOP_TEST後,繼續相同的測試&準備下一個NEXT_ACTION_INTERVAL_MS後的message
                    case CMD_LOOP_TEST:
                        if (isRunning) {
                            mWifiManager.startScan();
                            mCounter++;
                            result_text.setText("Repeat times: " + mCounter);
                            this.sendEmptyMessageDelayed(CMD_LOOP_TEST, NEXT_ACTION_INTERVAL_MS);
                        }
                        break;
                }
            }
    };




2017年3月29日 星期三

[C/C++] fchmod/chmod

    最近遇到一個檔案權限的問題,是log檔要統一給獨立的module去抓。
因此除了寫檔案外,還需要給予合適的檔案權限。 想到檔案權限,第一個可以用的就是chmod - 經典的linux檔案變更API。
不過餵了狗之後,發現還有fchmod這個貨可以用。


chmod
基本上這東西和linux的chmod是一樣的,主要改變指定檔案的權限
宣告原型是 int chmod(const char *pathname, mode_t mode);
第一個參數是檔案名稱,第二個參數是mode
mode的設法和chmod相同,是以bitwise的方式指定三方的權限

#include <stdio.h>
#include <stdlib.h>

int main(){
    FILE *fp;
    fp = fopen("file.txt", "w");
    fputs("1234", fp);
    fclose(fp);
    chmod("file.txt", 0777);
    return 0;
}


fchmod
修改操作中的file number的檔案權限,相較於chmod,這個可以在打開檔案後就設定這個檔案的權限。
(雖然個人試過在開檔之後用chmod也是可以,只是不確定這樣的操作會有甚麼風險)
宣告原型為int fchmod(int fd, mode_t mode);
第一個參數是打開檔案的file descriptor,第二個則是mode
mode的設法和chmod相同。

#include <stdio.h>
#include <stdlib.h>

int main(){
    FILE *fp;
    fp = fopen("file.txt", "w");
    fchmod(fileno(fp), 0777);
    fputs("1234", fp);
    fclose(fp);
    return 0;
}

就個人來說,我會比較偏好用fchmod在開檔案前就把權限一併設好,
尤其在log檔這種即時性比較高的應用上,可以避免一些因為權限問題而抓不到log的狀況



Reference: