2012年11月13日 星期二

[Android] 3.1 之後 Broadcast 行為的改變

前些陣子聽到實驗室學妹跟我說她自己寫的 App 收不到 BOOT_COMPLETED,我還嗤之以鼻的表示一定收的到啊~結果今天自己在 trace code 的時候就被打臉了 ... Q__Q
(學妹表示:你太嫩了!)

In frameworks/base/services/java/com/android/server/am/ActivityManagerService.java :

    private final int broadcastIntentLocked(ProcessRecord callerApp,
            String callerPackage, Intent intent, String resolvedType,
            IIntentReceiver resultTo, int resultCode, String resultData,
            Bundle map, String requiredPermission,
            boolean ordered, boolean sticky, int callingPid, int callingUid) {
        intent = new Intent(intent);

        // By default broadcasts do not go to stopped apps.
        intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);

        ... (略)

就是由於 Android 在 broadcast 的時候將 intent 加上了預設的 flag (Intent.FLAG_EXCLUDE_STOPPED_PACKAGES),因此,在 Stopped 階段的 packages 基本上收不到 intent,但是 3rd party app 可以自己加入 Intent.FLAG_INCLUDE_STOPPED_PACKAGES 這個 flag 讓 Stopped 階段的程式可以收到廣播內容!

因此,如果你不一想讓 App 收 System broadcast 的話,可以到管理選單上「Force Stop」,這樣就不會收到 broadcast 囉。同樣的,如果 App 沒有 Activity 的話,目前看起來就無法讓他自己跑起來了 ... ?

In frameworks/base/service/java/com/android/server/am/ActivityManagerService.java :


    public void forceStopPackage(final String packageName) {
        if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
                != PackageManager.PERMISSION_GRANTED) {
            String msg = "Permission Denial: forceStopPackage() from pid="
                    + Binder.getCallingPid()
                    + ", uid=" + Binder.getCallingUid()
                    + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
            Slog.w(TAG, msg);
            throw new SecurityException(msg);
        }

        long callingId = Binder.clearCallingIdentity();
        try {
            IPackageManager pm = AppGlobals.getPackageManager();
            int pkgUid = -1;
            synchronized(this) {
                try {
                    pkgUid = pm.getPackageUid(packageName);
                } catch (RemoteException e) {
                }
                if (pkgUid == -1) {
                    Slog.w(TAG, "Invalid packageName: " + packageName);
                    return;
                }
                forceStopPackageLocked(packageName, pkgUid);
                try {
                    pm.setPackageStoppedState(packageName, true);
                } catch (RemoteException e) {
                } catch (IllegalArgumentException e) {
                    Slog.w(TAG, "Failed trying to unstop package "
                            + packageName + ": " + e);
                }
            }
        } finally {
            Binder.restoreCallingIdentity(callingId);
        }
    }

在這邊有個 forceStopPackage() method,會呼叫 PackageManagerService.setPackageStoppedState,這個 method 會呼叫 Setting.setPackageManagerServiceLPw,然後把相對應 PackageName 的 PackageSetting 設定成 stopped ...

Android Developer 上有提到:http://developer.android.com/about/versions/android-3.1.html(但是我之前都沒注意到啊啊啊啊啊....)。

這個教訓告訴我們「要注意看 API Document」!


BTW,我這邊貼 code 是用 http://hilite.me/ 這個網站產生的。

2012年10月9日 星期二

[LaTeX] subfigure 的使用

用 LaTex 排版的時候常常會有圖 (a)、圖 (b)、圖 (c) 這種需求,但是初學者又通常搞不懂要怎麼做 ...

其實很簡單的,先在一開始的地方使用 subfigure 這個 package:
\usepackage{subfigure}

接著,在要貼入圖的地方使用:
\begin{figure}
 \centering
 \subfigure[Figure 1 (a)]{
  \includegraphics[scale=0.28]{fig1a}
  \label{fig1a}
 }
 \subfigure[Figure 1 (b)]{
  \includegraphics[scale=0.28]{fig1b}
  \label{fig1b}
 } 
 \caption{Figure 1}
 \label{fig1}
\end{figure}

簡單解說一下:
\subfigure[這裡是caption]{
 \includegraphics[scale=放大縮小的 scale]{檔名}
  \label{要 \ref 時的名字}
}

2012年10月8日 星期一

[KDE] 學習使用 Activity

KDE 有個功能叫 Activity (活動),但是看看使用 KDE 的朋友也不一定會使用 Activity,新轉進 KDE 的朋友甚至覺得 KDE 的虛擬桌面 (Virtual Desktop) 太少了,這其實是因為 KDE 有了 Activity 這東西呀!

使用方法
看看左下角那三個紅藍綠圈圈!如果找不到的話可以新增 Widget ...

然後按下 Activity Widget 之後,再按下 "Create Activity":
選擇你需要的 Templates,如果不知道該選什麼,可以直接選 "Empty Desktop" 也無所謂,選完之後就會跳出一個新的 Activity!

看到什麼都沒有請別緊張,小弟我第一次用 Activity 的時候也嚇到,想說怎麼東西都不見了,不過當你選擇 "Empty Activity" 的時候就是什麼都沒有啦!BTW,預設就有 "Desktop" 和 "Desktop Icons" 兩個 Activity 囉,平常開機完會自動進入 "Desktop" 運作。

你也可以將創好的 Activity 改名,像我就有一個叫做 "paper" 的 Activity,顧名思義就是小弟用 LaTex 寫 paper 的活動啦!

要刪除的話就請按下看起來像是 stop 的那個 button,然後:
按下那個 Delete 再確認就不見囉!

可以利用快捷鍵 "Meta + Tab" (也就是 Win + Tab) 來切換各個 Activity,當然也可以為 "Desktop" 這個 Activity 設定快捷鍵囉:
我自己是設成 "Meta+F1" 切換到傳統的 "Desktop" Activity,而在各 Activity 底下仍可使用平常習慣的 "Alt+Tab" 切換各個 Application。

另外,在 Application 的 Title bar 上面點右鍵,也可以將 Application 丟到任意的 Activity 唷。

傳教喊話
Activity 可以增加工作效率!

我們平常都會按 Alt+Tab 切換各個 Application,但是常常一切就切到 browser or PCMAN,然後自制力就不足的開始上網看網頁 or 看 PTT ... (好啦,可能只有我這樣 ...)

但是如果在一個 Activity 裡面切換,當然就不會有其他 Application 來打擾囉~自己將同類型的工作放在同個 Activity,就可以專心在裡面完成工作了!

寫論文去 .... (畫圈圈)

2012年9月8日 星期六

[openSUSE] openSUSE 12.2 + KDE 4.9 和一些雜談

openSUSE 12.2 在日前剛剛 released!所以我馬上迫不及待的把手上的 12.1 升級,原先 12.2 的 KDE version 應該是 4.8,但是因為有厲害且熱心的 Marguerite Su 寫了很棒的簡中新手 guide,所以我順手升級 KDE 到 4.9,KDE 各地方都可以微調的感覺很好,但是不知道為什麼在 Application Launcher 的 Tab 切換動畫總是有點慢,沒辦法快速反應,大概是這個動畫的問題吧?

以下有一些 screenshot,我把底下的 tray 稍微拉大一點,原本預設的高度偏窄,常常覺得按不到很討厭,不過 openSUSE 特別設計的綠配色看起來相當舒服!

第一張是原先預設桌面,KDE Plasma 發展到現在變得相當不錯,比那個讓人無法習慣的 Gnome 3 和 Unity 3D 好的太多,桌面也不只是傳統的 shortcut icon,而是用 folder view 和可以自行增減的 widget。

KDE Application Launcher 還是一樣,如果是從 Gnome 2 / Windows / LXDE / XFCE 轉換過來的朋友需要花些時間習慣,習慣之後是覺得還不錯,只是動畫動作真的很慢,再次抱怨每個 Tab 切換不即時,不知道是不是我的硬體 or driver 問題啊?

Amarok 這個音樂播放軟體我還蠻喜歡的,左邊有 free music 可以選,讓我可以換換口味,聽些沒聽過的歌。 :D

Dolphin!沒什麼好說的,還是一樣 XD。

Yast 管理介面,大部分的設定都可以在這邊搞定!

Yast 內 /etc/sysconfig Editor,懶得用文字編輯器的人可以用這個方便的 tool。

Kile,一個用來寫 LaTeX 文件的 KDE 軟體,身為一個博士生,當然要試試看 KDE 原生的LaTeX 編輯器啦,我在 Windows 和 MacOS 上用的都是 Texmaker + texlive ...

這邊有兩篇大家整理的比較表:Gnome 3 vs KDE 4.9Gtk 軟體 vs Qt 軟體,比較了兩者的優缺點,大家可以從裡面找到適合自己的 Desktop Environment 唷!

以下是一些雜談,不太重要 ...

我用過的 Linux distribution 相當雜,從高中時候第一次嘗試安裝 Slackware 開始(其實我一開始用的是 FreeBSD),CLE、Linpus、 Red Hat、Mandriva (當時叫 Mandrake),後來 Fedora Project 開始之後一直使用 Fedora,接著 Ubuntu 簡單易懂的設計讓人很容易習慣,我也用了很長的一段時間,加上 Android source code 編譯的文件都是直接支援 Ubuntu,但後來 Ubuntu 改了 DE,開始用 Unity 之後,我一直沒辦法習慣這個操作介面,最後就毅然決然跳槽 openSUSE 了 XDDD,12.2 給人的感覺相當不錯,大家可以考慮試試看!

2012年6月16日 星期六

[openSUSE] Note: compile Android source code on openSUSE 12.1

之前只要關於 Android Source Code 的東西,我通常是放在 Ubuntu 11.10 上面作,但是因為這一兩年習慣了用 openSUSE 當主要使用的 Linux distro,所以就想試試看在這平台上編譯,但是大部分文件都是寫給 Ubuntu 使用者看的,讓我遇到了不少麻煩。

在這邊寫下筆記,是希望之後的 openSUSEer 不要在花跟我一樣多的時間來找這些套件! :D

平台:openSUSE 12.1
package:
gcc python libstd++46-devel-32bit perl-Switch libncurses6-32bit ncurses-devel-32bit zlib-devel-32bit Mesa-devel-32bit

目前仍然在編譯當中,而且這也不是完整的 List,先作個筆記,之後確認完在 update!