Social Icons

2013年2月17日 星期日

讓剪貼簿Clipboard相容於2.x

在寫程式的時候,會需要將文字資料複製到剪貼簿的時候,不同Android版本會產生問題。
原因就是Honeycomb(v3.0)之後,Android使用了新的剪貼簿,所以在程式裡要判斷新舊方法的使用時機,程式片段如下:
        int currentapiVersion = android.os.Build.VERSION.SDK_INT;
     if (currentapiVersion >= android.os.Build.VERSION_CODES.HONEYCOMB){
          android.content.ClipboardManager clipboard =  (android.content.ClipboardManager) getSystemService(CLIPBOARD_SERVICE); 
             ClipData clip = ClipData.newPlainText("Marathon's world", subject);
             clipboard.setPrimaryClip(clip); 
     } 
     else{
         android.text.ClipboardManager clipboard = (android.text.ClipboardManager)getSystemService(CLIPBOARD_SERVICE); 
         clipboard.setText(subject);
     }

2013年2月16日 星期六

啟動螢幕Splash Screen的設計

啟動螢幕Splash Screen常常用在程式一開始的時候,特別是用來顯示公司的logo。 這邊要介紹實作splash screen的兩種方式,第一種是利用兩個不同的xml layout檔案,第二種是寫在同一個xml layout檔案中。



如何判斷float的NaN

在我的程式中為了要顯示先現在為止位置的方向,需要得到compass或GPS的bearing,然後在利用matrix中rotate的功能將方向的圖示圖示做對應的選zhau旋轉。可是有時候程式會無法得到正確bearing的值,如果將NaN的值塞到rotate中會造成程式crash。Google了一下原來在Java中要判斷float的NaN,還是要用到一些技巧的。 

也還蠻簡單的,不過要利用Float object來判斷,程式碼如下:

Float dbear = new Float(this.myloc.bearingTo(oxlocate));
if (dbear.isNaN() == false) {

GeoCoder,判斷是否可以連上Internet兩三事

為什麼會將GeoCoder和Internet一起將起講,是因為使用GeoCoder造成我的程式會hang住,查了一陣子才發現和網路有關所以就在這裡一起談談了。 話說,Geocoder是Google提供的一個可以輸入坐標位置,然後fanc反查出地址的強大服務,不過小弟用了之後卻發生水土不服,而造成程式上吐下瀉的情況,原因是網路部位不穩,或者無法存取網路的時候,會讓程式停在哪裡,然後系統就會跳出程式無回應的警告視窗。 為什麼會這樣呢,其實是程式中會註冊座標移動的callback,當座標位置一旦有改變時就會呼叫這個callback。好死不死在這個callback中會呼叫GeoCoder來反查地址,並改變UI的文字。就這樣一旦網路不通的時候,就讓程式停在那裡了。 所以說,如果要使用GeoCoder一定要善用,只好另起一個Thread,背景執行,或者檢察現在網路是否有通嘍,下面就是檢察網路是否有通的程式碼了。
public boolean isInternetConnect() {
  boolean isConnected = false;
  ConnectivityManager connec =  (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
        if (connec.getNetworkInfo(0).isConnectedOrConnecting() == true ||  
         connec.getNetworkInfo(1).isConnectedOrConnecting() == true  ) {
         isConnected = true;
        }
        return isConnected;
}
其中connec.getNetworkInfo(0)是指Mobile phone(GPRS,3G),connec.getNetworkInfo(1)是檢察WiFi有沒有通。

Google Map Key - 您輸入的指紋無效

申請Google Map Key卻出現,對不起您輸入的指紋無效? 最近重新申請Google Map Key,照往例用keytool列出debug.keystore的憑證指紋,卻沒想到在申請頁面一直出現『您輸入的指紋無效;請按瀏覽器的 [上一頁] 按鈕,並輸入有效的憑證指紋。』的訊息。沒錯啊,整個過程都沒錯啊,怎麼會這樣? 後來看到檢察了一下發現奇怪我的key怎麼特別的長?才發現原來申請Google Map Key的憑證指紋要是MD5的,

而keytool列出來的是SHA1,
 

怎麼會這樣呢?以前都沒有問題啊!原來最近將JDK升級到版本7。結果呢!在版本7的keytool預設的輸出是SHA1,我的嗎啊!怎麼會這樣呢?需不需要降級到版本6啊?還好查了一下,只要在執行時加上 -v 這個參數就可以將所有編碼的憑證指紋都列出來了。

下回還是不要亂升級了,會搞死人的。 :)

兩個View切換中,如何產生平滑效果

因為目前在開發的程式中,有許多視窗,而使用者需要在這些視窗中切換,為了讓程式跑的順一點,並沒有create很多的activity,而是透過且切換View來達成。 但是在View切換過程,如果是使用動畫來表現的話,應該是比較好看的,所以趁這個機會研究一下Android的動畫,這邊要講的是如何在不同View之間,產生平滑移動的小效果。 首先,我們先建立幾個動畫XML檔(請放在/layout目錄下) left_in.xml
<?xml version="1.0" encoding="utf-8"?>   
<set 
        xmlns:android="http://schemas.android.com/apk/res/android">   
    <translate 
            android:fromXDelta="-100%p" 
            android:toXDelta="0"  
        android:duration="500" />   
  
</set>
left_out.xml
<?xml version="1.0" encoding="utf-8"?>   
<set 
    xmlns:android="http://schemas.android.com/apk/res/android">   
    <translate 
            android:fromXDelta="0" 
            android:toXDelta="-100%p"  
        android:duration="500" />
</set>
right_in.xml
<?xml version="1.0" encoding="utf-8"?>   
<set 
        xmlns:android="http://schemas.android.com/apk/res/android">   
    <translate 
            android:fromXDelta="100%p" 
            android:toXDelta="0"  
        android:duration="500" />   
  
</set>
right_out.xml
<?xml version="1.0" encoding="utf-8"?>   
<set 
    xmlns:android="http://schemas.android.com/apk/res/android">   
    <translate 
            android:fromXDelta="0" 
            android:toXDelta="100%p"  
        android:duration="500" />
</set>
在main.xml我們定義了兩個Views,一個一開始是顯示的,另一個是隱藏起來的,另外定義了兩個按鈕來做視窗的切換。
.....
     <LinearLayout
      android:id="@+id/map_view"
         android:layout_width="fill_parent"
         android:layout_height="wrap_content"
   android:layout_marginTop="0dip"
   android:layout_marginBottom="0dip"
   android:layout_marginLeft="3dip"
   android:layout_marginRight="3dip"
   android:layout_weight="1"
   android:visibility="gone"
      >
     </LinearLayout>
     <ListView android:id="@+id/oxcache_list"
   android:persistentDrawingCache="animation|scrolling"
   android:cacheColorHint="#00000000"
   android:divider="@color/gray_light"
   android:dividerHeight="1dip"
   android:orientation="vertical"
   android:layout_weight="1"
   android:layout_width="fill_parent"
   android:layout_height="wrap_content">
  </ListView>
.....
     <Button   
         android:id="@+id/list_btn"     
         android:layout_width="wrap_content"    
         android:layout_height="wrap_content"    
         android:layout_marginRight="0dip"
         android:text="@string/list"
         android:textColor="@color/header_text"
         android:background="@drawable/btn_left_unpress"
         style="@style/List"
     />   
     <Button   
         android:id="@+id/map_btn"     
         android:layout_width="wrap_content"    
         android:layout_height="wrap_content"
         android:layout_marginLeft="-8dip"
         android:text="@string/map"
         android:textColor="@color/header_text"
         android:background="@drawable/btn_right_unpress"
         style="@style/List"
     />
在程式中,透過監聽兩個按鈕的click event來切換不同的視窗,重點是什麼情況是右進左出,左進右出了。
listBtn.setOnClickListener(new Button.OnClickListener() {
   @Override
   public void onClick(View v) {
           mOxcacheList.setVisibility(View.VISIBLE);
           mOxcacheList.setClickable(true);
           mOxcacheList.setAnimation(AnimationUtils.loadAnimation(CacheMe.this, R.layout.push_left_in));
           mMapLinear.setVisibility(View.GONE);
           mMapLinear.setAnimation(AnimationUtils.loadAnimation(CacheMe.this, R.layout.push_right_out));
    }
   }
        });
  mapBtn.setOnClickListener(new Button.OnClickListener() {
   @Override
   public void onClick(View v) {
           mMapLinear.setVisibility(View.VISIBLE);
           mMapLinear.setClickable(true);
           mMapLinear.setAnimation(AnimationUtils.loadAnimation(CacheMe.this, R.layout.push_right_in));
           mOxcacheList.setVisibility(View.GONE);
           mOxcacheList.setAnimation(AnimationUtils.loadAnimation(CacheMe.this, R.layout.push_left_out));
    }
   }
        });