2013年8月23日星期五

新建的Android程式,預設無Menu bar (Action bar)

最近新建Android程式,發現Theme等背景都幫你設好了,
原本新建好的Android背景是黑的,
但新近建的Android程式,背景是白的;

查了一下,
原本是在 AndroidManifest.xml中多了android:theme="@style/AppTheme"

 <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

反正是程式自行建立的,所以應該不是壞事,
結果問題來了,在Activity中的onCreateOptionsMenu竟然跑不進去,



@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
Log.d(TAG, "onCreateOptionsMenu");
getMenuInflater().inflate(R.menu.main, menu);
return true;
}

在Log裡面居然看不到它印出onCreateOptionsMenu的Log,
趕緊上網路查查去;
原來要修改style.xml(這也是程式自己產生的)

<resources>

    <!--
        Base application theme, dependent on API level. This theme is replaced
        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
    -->
    <style name="AppBaseTheme" parent="android:Theme.Light">
        <!--
            Theme customizations available in newer API levels can go in
            res/values-vXX/styles.xml, while customizations related to
            backward-compatibility can go here.
        -->
    </style>

    <!-- Application theme. -->
    <style name="AppTheme" parent="AppBaseTheme">
        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
    </style>

</resources>



原本的Theme使用是android:Theme.Light是不會產生Menu bar(Action bar)的,
要用android:Theme.Holo.Light來取代,修改如下:


<resources>

    <!--
        Base application theme, dependent on API level. This theme is replaced
        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
    -->
    <style name="AppBaseTheme" parent="android:Theme.Holo.Light">
        <!--
            Theme customizations available in newer API levels can go in
            res/values-vXX/styles.xml, while customizations related to
            backward-compatibility can go here.
        -->
    </style>

    <!-- Application theme. -->
    <style name="AppTheme" parent="AppBaseTheme">
        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
    </style>

</resources>


這樣程式就會正常了。

2013年8月11日星期日

cakephp Facebook plugin FB.login callback 問題(已解決)

最近因工作需要,開始接觸cakephp用的FB  Plugin,
網路上找到的plugin:
webtechnick/CakePHP-Facebook-Plugin
網址:https://github.com/webtechnick/CakePHP-Facebook-Plugin

透過該網站的說明,將Plugin裝進去後,
第一關(登入)就卡關:

原程式碼:

echo $this->Facebook->login(array(
'perms' => 'email,read_stream,publish_stream',
'id'=>'loginButton',
'show-faces'=>false,
'status'=>'login',
));

狀況:
登入順利進行,但...怎麼登入後沒有導向我指定的網址?
設定網站說明的afterFacebookLogin callback也沒有用,
多加一個參數redirect後:

echo $this->Facebook->login(array(
'perms' => 'email,read_stream,publish_stream',
'id'=>'loginButton',
'show-faces'=>false,
'status'=>'login',
'redirect' => array('controller' => 'frontend', 'action' => 'login'),
));

原本看得到的登入icon,竟然不見了...
這個問題卡了二天,最後才找到解決方法;
根據
的說法,設定redirect參數是有用的,但設定後會發生login icon不見的問題,
所以要手動再設定img參數,如下方程式碼:

echo $this->Facebook->login(array(
'perms' => 'email,read_stream,publish_stream',
'id'=>'loginButton',
'show-faces'=>false,
'status'=>'login',
'redirect' => array('controller' => 'frontend', 'action' => 'login'),
'img'=>'Menubtno.png',
));

圖片因為已不是用原先FB的login圖片了,所以要自己做一張,
放在webroot/Facebook/img下,以上方的程式碼來說,
我有放一張圖在webroot/Facebook/img/Menubtno.png,
按下登入後,終於會導到我的login頁面了。

卡了二天,終於闖過第一關了。

2013年8月3日星期六

Android﹣從String取得Resources對應的int

寫Android程式時,在取Resources資源時,
正常情況不會知道對應的int,但一定會知道寫在String.xml中的name;

但因為這些name在編輯時會轉成JAVA的Field,放在R.java檔裡面,
所以取Resources資源時,必需透過類似R.string.name的方式,才能取到對應的int;

但世事不是都這麼美好的,有時name是在程式執行中才能拿到的,
而拿到手的是一個String,此時需要想辦法轉成R.string.name對應的int,
才能取對對應的,但要怎麼轉呢?

透過reflect的方式,下方是透過String取得Drawable的int範例程式碼:


public int getDrawableId(String id) throws SecurityException,NoSuchFieldException, IllegalArgumentException,IllegalAccessException {
Field f = (Field) R.drawable.class.getDeclaredField(id);
return f.getInt(R.drawable.class);
}

2013年6月17日星期一

jquerymobile 多點幾次後掛掉

前二天應朋友要求,
寫了一支用jQueryMobile架起來的手機版網站,
但在測試時,出現一個非常奇特的現像:
程式原始碼:
<a href="..." data-role="button">xxx</a>

點擊第一次時OK,點擊第二次時也OK,
結果點擊第三次時,網頁就掛在那邊,
停止回應了。

後來經過高人指點,將程式碼改為:
<a href="..." data-role="button" data-ajax="false">xxx</a>

就正常了,看起來原因是因為ajax引起,但詳細的原因不清楚,
不過改成這樣子就OK了。

2013年6月11日星期二

MAC的SSD硬碟多磁區的noatime掛載


因緣際會買了一台MAC,是SSD的硬碟,
上網查了一下,很多人在教針對SSD優化(延長壽命)的處理,
其中有一個是noatime掛載。

noatime掛載的資料請自行上網搜尋,
網路上很多人在說,
但都沒有提到,如果有第二顆SSD或第二個磁區時,
要如何讓多個磁區都能noatime掛載。

找到最後都沒有現成的,所以最後只好去研究plist裡面的東西到底是怎麼一回事,
在這裡將研究成果寫一下:
我在/Library/LaunchDaemons底下有一個com.tcj.noatime.plist(名稱自訂)檔案,內容如下(紅字為我寫的說明):


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"
        "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
    <dict>
        <key>Label</key>(不能變動,因為要給程式判斷用)
        <string>com.tcj.noatime</string>(不能和其他plist的Label內容重覆,否則會無法執行)
        <key>ProgramArguments</key>
        <array>
            <string>mount</string>
            <string>-vuwo</string>
            <string>noatime</string>
            <string>/</string>(要掛載的路徑)
        </array>
        <key>RunAtLoad</key>
        <true />
    </dict>
 </plist>

結論:
了解意思後,再來看如果有多個磁區(路徑)要使用noatime掛載的話,步驟如下:
1.使用不同的檔案(plist)
2.變更Label中的string(以上一例來說就是 com.tcj.noatime 這一串文字,跟檔案沒有關係喔)。
3.重新開機。

這樣就可以了,下方是我掛載二個磁區成功的範例:
/dev/disk0s2 on / (hfs, local, journaled, noatime)

/dev/disk0s4 on /Volumes/Data (hfs, local, journaled, noatime)

二個檔案的差別參考:
1.

檔案1:

  <key>Label</key>(不能變動,因為要給程式判斷用)
  <string>com.tcj.noatime</string>(不能和其他plist的Label內容重覆,否則會無法執行)

  <string>/</string>(要掛載的路徑)


檔案2:


  <key>Label</key>(不能變動,因為要給程式判斷用)
  <string>com.tcjData.noatime</string>(不能和其他plist的Label內容重覆,否則會無法執行)

  <string>/Volumes/Data</string>(要掛載的路徑)


參考資料
https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man5/launchd.plist.5.html

2013年5月17日星期五

GoogleCloudMessaging cannot be resolved to a type 已解決

今天在寫GCM時,一直碰到這個問題,
網路查也無解,
最後在GCM的Getting Start 中重新看到了一串

The sections below guide you through the process of setting up a GCM implementation. Before you start, make sure to set up the Google Play Services SDK. You need this SDK to use theGoogleCloudMessaging methods.


也就是說,GoogleCloudMessaging這個Class是藏在 Google Play Services SDK中的,
所以請先透過你的Andorid SDK manager,將Google Play Services下載或更新成最新版,
之後到<android-sdk-folder>/extras/google/google_play_services/libproject/google-play-services_lib/libs/,找到google-play-services.jar,把它用到你的專案來,
就可以把GoogleCloudMessaging 這個Class import進來了。

2013年4月20日星期六

android帶入預設資料sqlite

最近因為有需要,所以想讓程式安裝之時,
直接帶入一千多筆的資料,
網路上查了一下,

大部份都是說:
1.將sqlite檔丟入asset。
2.在建立DB時,判斷檔案是否存在,不存在則去asset,
透過串流的方式,將資料帶回來。

但這個方法不知道為什麼,不適用在我這邊。
所以我到最後的處理方式是:
用Insert的方式,但是一千多筆的Insert是會寫死人的,
所以最後的解決方法;
1.讀取一千多筆資料
2.透過寫入檔案的方式,將程式語法寫出來。
3.打開檔案,直接copy程式語法

這樣子就可以做到很多筆資料的Inser,
但缺點是:
1.寫出來旳程式因為是用串的,所以常常會錯,需要一改再改。
2.程式碼突然變很長。

寫出來的東西給大家參考一下:(下面那一串是用程式幫我組出來的)

db.execSQL("INSERT INTO frequency(_id, lotto_649_id, NO_1, NO_2, NO_3, NO_4, NO_5, NO_6, NO_7, NO_8, NO_9, NO_10, NO_11, NO_12, NO_13, NO_14, NO_15, NO_16, NO_17, NO_18, NO_19, NO_20, NO_21, NO_22, NO_23, NO_24, NO_25, NO_26, NO_27, NO_28, NO_29, NO_30, NO_31, NO_32, NO_33, NO_34, NO_35, NO_36, NO_37, NO_38, NO_39, NO_40, NO_41, NO_42, NO_43, NO_44, NO_45, NO_46, NO_47, NO_48, NO_49) VALUES(645, 645, 104, 110, 91, 92, 92, 78, 85, 103, 86, 90, 91, 85, 98, 79, 99, 81, 63, 95, 86, 90, 99, 102, 101, 91, 88, 97, 91, 107, 80, 93, 106, 94, 87, 84, 91, 104, 88, 101, 94, 87, 93, 93, 103, 92, 92, 82, 90, 91, 96);");