May 25, 2014

[Android] 分析最近頗有名的簡訊病毒

今天要來討論一下最近非常夯的簡訊病毒,很多朋友都有收到這樣的簡訊,我的 Android 手機也收到好幾次,雖然我很笨的點下連結,但還好我即時點下 Back 鍵,沒發生什麼意外。

不過,既然自己接觸 Android 也有不短的時間了,那就剛好發揮一下專業來看看這個病毒到底會做些什麼事情。

Sep 17, 2013

[Android] Porting the live555 library onto Android

LIVE555 is a well-known multimedia streaming library on low-cost embedded system. It had been ported on armlinux, FreeBSD, iPhone OS, Mac OS X, OpenBSD, and uClinux.
This library uses the open standard streaming protocols such as RTP/RTCP/RTSP/SIP. In this article, we will provide a series of steps for explaining how to port the library onto ARM-based Android System.

Before porting the library, you should prepare these resources,
a. Cross-Compiler:  We can get the cross-compiler from Android Developer Website.
b. The LIVE555 source code: Download Site version: 11-Sep-2013
c. Linux Environment is BEST!

Jun 17, 2013

[Android] How to build the JNI with a prebuilt shared library in the Android Application?

Sometimes, we need to develop C/C++ for achieving the performance-sensitive calculation via JNI technology in a Android application. In addition, we also probably to encounter these problems such as,
  1. You don't want to distribute your source code, but, want to distribute your libraries to third-party NDK developers.
  2. You want to speed up your project build via providing the prebuilt library.

May 31, 2013

[Android] Access the static enum field from JNI

In the world of Java Native Interface (JNI) on Android, we often need to access the field of Java class. But, the difficulties are we should understand what the code relationship between Java and JNI. In the previous post Programming Objects between Java and JNI, I've showed how to access the Java class that you are created. In this post, I will illustrate the method of accessing the Java enum class.

Feb 10, 2013

[Agile] 完整前期設計 vs. 漸進式設計

傳統開發團隊在轉換到 Agile 時,第一個遇到的問題應該會是如何切換成「Iterative and Incremental Development」。也就是說,通常一時間會難以接受沒有細部設計就開始實作的方式,不過 Picker 很幸運,剛好有機會嘗試這兩種開發方式,這邊來談談施行經驗與觀察吧。

這裡的結論可能不是很客觀,Picker 嘗試這兩種方法的時間點不同,所以成員的能力也有差異,另外,這也只是我憑著記憶整理出來的結果,不過 Picker 相信結論不會悖離事實太多。

因為這邊談到的狀況,不全然是基於 Scrum 框架下的運作,所以這邊定義一下角色,針對寫程式的人,我們叫做 Programmer,而 (Architecture) Designer 則是軟體架構的主要設計者。

環境: 
  • Programmer 的能力偏向 Junior Engineer,沒有 Design 能力,看得懂 UML 表達方法。
  • 時程壓力不大
  • 專案的需求變動度低
開發方法:
  • 完整前期設計: 定義出 Designer 及 Programmer,從需求分析到 UML 圖設計都先做完後,再進行實作,後續有問題時,再由 Designer 進行修改。
  • 漸進式設計: 定義出 Designer 及 Programmer,由 Designer 將基礎架構訂出後,就開始實作,並由 Designer 擔任設計顧問,Programmer 主導區塊的設計細節。

觀察的結果大致如下,


前期準備時間 單一開發週期產生之成果 成員自我管理
完整前期設計(方法1)
漸進式設計 (方法2)

在方法1的執行過程中,團隊初期會比較專注在架構的設計,而不是產出可用的軟體單元,但偏偏又無法在初期就做出沒有問題的架構設計,所以日後還是推翻先前的分析與設計。方法1很難在短時間裡,從實作面得到需求和架構意見,日後還是要花時間大幅度修正架構。

在方法2中,因為直接讓 Programmer 投入細部設計並直接實作,所以可以從早期就取得許多回饋,並能與 Designer 早點將問題引入架構設計的討論中,架構因此能夠逐步穩定,並且讓 Programmer 及 Designer 對架構和需求理解更有信心。

在成員的成長方面,方法2對於 Programmer 的學習有很大幫助,Programmer 可以參與架構的細部設計,一方面可以讓成員有學習設計的機會,並且直接了解架構細節,另一方面,能增加成員自我管理的可能性。而方法1則造成 Programmer 按圖施工的可能性大增,而忽略達成需求的目標,此外,也無法從 Programmer 身上取得較多的回饋,增加架構崩壞的可能性。

不過,雖然早點開始實作,可以在一定的時間內取得部份成果,但是,對於主導的 Designer 卻是很大的負擔。這是因為成員不懂軟體設計相關議題,所以要確保實作品質、協助 Programmer 理解需求、串連不同的單元,跟 Programmer 就會有極大量的溝通。這樣的好處是在過程中,比較有機會直接讓 Programmer 了解什麼是有效的設計,也能降低實作與需求之間的落差,而且 Programmer 會比較懂得反應問題點,並討論解決方法。但問題就是會耗費大量時間,卻未必可以在週期內出現有效的產出,而且Programmer 和 Designer 也可能彈性疲乏。


從實行結果來看,方法1相當可惜,因為前期準備時間過長,後期溝通成本又居高不下(因為 Programmer 還無法理解設計,也無法提出細部設計的意見),所以最後還來不及產出可用的成品,就因為其他專案的加入而中止了。

但方法2也不是沒有缺點,因為總是會有些看得到的產出,但是內容物可能很有問題,可能是沒寫測試、可能有不容易察覺的 bug、可能實作方式有些架構上的問題,這些技術債會留下,但可展示的產出物卻會讓客戶有「什麼都做好了」的錯覺。這時候 Definition of Done (DoD) 及 Refactor 就會顯得非常重要了。

綜合以上的狀況,我會採取方法2的策略,藉此協助 Programmer 提昇技術能力,並洗腦教育 Programmer 能夠在每個週期內產出可運作的軟體,幫助自己確認需求內容。
將架構設計的思考導入 Programmer 後,就能漸漸地增加 Programmer 在設計上的責任,然後再進一步達成 Programmer 身兼 Design、Implement、Testing 的目標。

-----
以上純屬 Picker 個人經驗與觀察,請審慎採用。XD

Jan 31, 2013

[Agile] 一冬的Agile/Scrum學習里程


從前年開始,為了慢慢在工作中採行Agile方法,但又害怕因為不當地理解Agile精神,而導致恐怖的結果,所以自己花了一整年的時間,透過講座、書籍、討論區及詢問朋友的經驗,藉此了解Agile細節,然後在過程中選定Scrum及XP為實踐框架,並進一步學習細節內容。除此之外,為了能夠了解CMMI和Scrum的思考差異,也特地用平常時間去參與CMMI的訓練課程,希望能透過不同角度來討論Scrum。
其實在了解Scrum的過程中自己也碰到很多難以接受(理解)的部份,針對這部份,Picker為了讓學習能夠繼續,只好讓自己思緒放空,像Teddy說的,用「傻的願意相信」的心態,先好好實踐Agile/Scrum的精神和框架再說。

記得Picker花了將近一年的時間去了解Agile/Scrum,想想時機差不多了,就帶著大陸的一個Team跑了一次Scrum Project,過程中真的百般痛苦,自己要身兼Product Owner及Scrum Master,簡直是分身乏術,尤其是討論的過程中,身為Product Owner要仔細且耐心的跟Scrum Team討論Story,還要轉換身份到Scrum Master,循循善誘,讓Scrum Team能夠提出自己的看法 (都快人格分裂了),話說,Sprint Planning結束的當天晚上,Picker可是一點都沒失眠!!!

但話說回來,我猜咱們的Team Member肯定也痛苦啊!想想以前只要聽從命令,照著資深工程師幫忙切好的Task去施工,自己只要專注在如何實作完Task就可以了,想到這裡,Picker心情也輕鬆多了 (哈哈,萬惡的Picker魔王帶來了恐怖的地獄工作生活!!!)。

不過,在實踐過程中,Picker也發現了之前一直疑惑的部份,慢慢有茅塞頓開的感覺。Picker之前常常認為Agile/Scrum的精神是基於Scrum Team的能力很強,這樣才有機會把Agile/Scrum運作的順暢,結果Picker在實際運作時發現,

妹有錯!!! 
如果Scrum Team的能力不足,那簡直是拿石頭砸自己腳。

是的,一點都沒錯,想達到理想的Agile精神,Scrum Team會是重要的因素之一,畢竟User Story切割成Task、針對Task施工、應付多變需求,這些都跟Scrum Team有密不可分的關係,如果Scrum Team能力不足,根本無法將User Story細分成多個Task,也無法在施工過程中做些小設計、Unit Testing,就更別說想讓Scrum Team把架構慢慢長出來。(好啦,我是說有效的架構)。

但是這樣就無法運作Agile/Scrum嗎?似乎也不然,Picker遵循著Iterative and incremental development的原則,慢慢把Scrum Team的能力拉起來,Picker相信終有一天能讓我們一步步地符合Agile精神。

當然,實務上,就是得倚賴Scrum Master是否有足夠的能力帶領Scrum Team去學習Agile精神的實踐方法,也許短期內無法讓Scrum Team達到Agile理想國度,但順著Agile精神邁進,相信Team Member都可以達到自我管理的階段,而能夠讓每個Project都成功完成!

困難的不是Agile/Scrum,最難的是改變你的Mindset。


推薦一下Teddy的Blog,資訊很豐富,

http://teddy-chen-tw.blogspot.tw/

Dec 17, 2012

[Android] How to Enable LOGV?

In the system/core/include/cutils/log.h

It defines the logging macro and tell us how to enable the logger.

We should concern three conditions,

1. For a single file:

You should define LOG_NDEBUG in top of the file,

    #define LOG_NDEBUG 0

In addition, you can define the LOG_TAG to specify the module name.


2. For a Library:

You should define the symbol in the LOCAL_CFLAGS in the Android.mk,

    LOCAL_CFLAGS += -DLOG_NDEBUG=0


3. For the multiple files:

You should define the symbol in the COMMON_GLOBAL_CFLAGS in the device/{DEVICE}/BoardConfig.mk,

    COMMON_GLOBAL_CFLAGS += -DLOG_NDEBUG=0

Oct 21, 2012

[Android] ProGuard Error: Proguard returned with error code 1

Recent days, I met a problem about the Proguard on the Android application. When I want to release the signed APK, the Eclipse feedback the error message that is like the following example,

org.eclipse.core.runtime.CoreException: Proguard returned with error code 1. See console

 at com.android.ide.eclipse.adt.internal.project.ExportHelper.exportReleaseApk(ExportHelper.java:280)

 at com.android.ide.eclipse.adt.internal.wizards.export.ExportWizard.doExport(ExportWizard.java:296)

 at com.android.ide.eclipse.adt.internal.wizards.export.ExportWizard.access$0(ExportWizard.java:233)

 at com.android.ide.eclipse.adt.internal.wizards.export.ExportWizard$1.run(ExportWizard.java:218)

 at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:121)

Caused by: Proguard Error 1

Output:

Note: there were 201 duplicate class definitions.

Warning: com.company.xxx.ui.ccc: can't find superclass or interface com.company.xxx.ui.bbbb$Listener

Warning: com.company.xxx.ui.abcde: can't find referenced class com.company.xxx.aaaa.InterfaceAAA

...

...

...


Warning: there were 70 unresolved references to classes or interfaces.

You may need to specify additional library jars (using '-libraryjars').

Error: Please correct the above warnings first.
 at com.android.ide.eclipse.adt.internal.build.BuildHelper.runProguard(BuildHelper.java:571)
 at com.android.ide.eclipse.adt.internal.project.ExportHelper.exportReleaseApk(ExportHelper.java:244)
 ... 4 more

Because the application includes the 3rd-party jar library, I think this may be just the library-reference problem.
So, at the first, I followed the explanation of the error and tried to add the "-libraryjars" in the proguard-project.txt, but I didn't obtain the right result. Therefore, I searched the error message on the Google, but I didn't get any useful information.
So sad! I went to read the manual in the ProGuard website. In the manual, the section Shrink and Optimization give the hint. I think Shrink and Optimization may occur the error, so I added the "-dontshrink" and "-dontoptimize" parameters in the proguard-project.txt. Unfortunately, I got the error again!

By the way, sometimes, I could get the final APK, but the APK is missing some classes (definitely, almost all the classes is missed). Sometimes, I could get correct final APK. It's so dangerous, if I don't test the final APK fully. I perhaps have the errors after publishing the application.

Finally, I found out some developers discuss the AdMob jar library should be added into the "/libs" in the project. Therefore, I think this may could apply for my condition. In the Android project, I copy the 3rd-party jar library into the /libs directory in the project, and then I change the Libraries Build Path to the "/libs" directory. Then, I succeed in building the released APK correctly and it is not missing any classes now. Happy!

Oct 3, 2012

[Android] Update the Notification Text

In recent days, I found out my application always shows the new notification in the status bar. This is not right in my scenario. So, I try to solve the problem about how to update the notification text.

Here is a short example to describe how to create the notification.

public void refresh() {
    mTicketText = mContext.getString(R.string.service_start_notification);
    RemoteViews contentView = new RemoteViews(
                mContext.getPackageName(), R.layout.notification);
    contentView.setImageViewResource(R.id.notification_icon, mIcon);

    mNotification.icon = mIcon;
    mNotification.tickerText = mTicketText;
    mNotification.flags = Notification.FLAG_NO_CLEAR
                | Notification.FLAG_ONLY_ALERT_ONCE
                | Notification.FLAG_FOREGROUND_SERVICE;

    /* Set title */
    final String title = mTicketText;
    contentView.setTextViewText(R.id.title, title);
    /* Set action summary */
    String summary = mContext.getString(R.string.launch_summary);
    contentView.setTextViewText(R.id.text, summary);
    mNotification.contentView = contentView;

    Intent notificationIntent = new Intent(mContext,
                FingerTranslateSettings.class);
    PendingIntent contentIntent = PendingIntent.getActivity(mContext,
                0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
    mNotification.contentIntent = contentIntent;

    mNotificationManager.notify(NOTIFICATION_ID, mNotification);
}

I always use this example to create and to update my notification. But, when I just want to update the notification text, the notification will be re-created. This seems a noise. Therefore, I try to find out the reason about the problem.

Finally, I see the description of Notification in the Android SDK.

public CharSequence tickerText

Since: API Level 1
Text to scroll across the screen when this item is added to the status bar on large and smaller devices.
See Also


It seems the tickerText is scrolled across the screen. So, when you change the tickerText, Android will scroll the new text on the screen. This behavior is not re-created the notification, it just refreshes the newer tickerText. For this reason, we can arrange the initialize the tickerText to the constructor, then the workflow will same as my idea.