2014年3月21日

Android─如何ping網頁

因為程式需求,想要知道手機目前的wifi連線是否有連接外網的能力
所以求助google大神,結果找到了一行程式碼,就可以判斷網路是否有連外能力
參考連結
程式碼如下
if (InetAddress.getByName("www.google.com.tw").isReachable(5000))
上述程式是看能否在五秒內連結 www.google.com.tw,如果連接上回傳true,反之回傳false
但在後來測試的結果發現,不論wifi是否有對外連線能力,都會回傳false
所以又馬上求助google大神,看問題是出在哪邊
發現網路上有很多人跟遇到跟我一樣的問題
程式碼雖然精簡,但不能正常運作,所以只好退而求其次
找尋是否能有在Android程式下執行ping指令
我找到的程式碼如下
參考連結
Process p1 = java.lang.Runtime.getRuntime().exec("ping -c 1 www.google.com");
int returnVal = p1.waitFor();
boolean reachable = (returnVal==0);
上述程式碼,是對www.google.com.tw ping 一次,如果ping成功會回傳0,失敗會回傳-1
在有連外網路的狀況下的確會回傳0,但在ping不到的情況下,thread會在那一直等待ping的結果

於是我又要求助google大神,結果發現了兩種解法
  1. 設定 ping的參數
  2. //-c 是指ping的次數 3是指ping 3次 ,-w 100  w是以秒為單位的間隔時間,100是指timeout 100秒   
    Process p1 = Runtime.getRuntime().exec("ping -c 3 -w 100 " + str); 
    
    參考連結
  3. 對執行 Process做的動作執行timeout的機制
  4. public static int timeoutInSeconds=5;
    Process p1 = java.lang.Runtime.getRuntime().exec("ping -c 1 www.google.com");
    int retrunVal;
    //取得目前系統時間
    long now = System.currentTimeMillis();
    //timeout時間為5秒
    long timeoutInMillis = 1000L * timeoutInSeconds;
    long finish = now + timeoutInMillis;
    //當p1 alive及timeout還沒發生時,繼續在迴圈中
    while ( isAlive( p1 ) && ( System.currentTimeMillis() < finish ) )
    {
        Thread.sleep( 10 );
    }
    
    public static boolean isAlive( Process p ) {
        try
        {
           //p結束的值
           p.exitValue();
           return false;
        } catch (IllegalThreadStateException e) {
          return true;
        }
    }
    
    上述的程式碼是透過process是否已經取得值加上timeout的機制 來判斷是否真的有ping到網頁 當呼叫isAlive時,會去偵測p是否結束並且有回傳值,如果沒有值發生exception回傳true while迴圈則利用isAlive及時間是否超過timeout時間,來判斷是否取得ping值 參考連結

2014年3月20日

Android ─ Handler sendMessage 與 sendToTargett差異

最近在上網找有關Handler相關資訊的時候
發現了,要發送的Message實體化的方式卻有兩種
  • 如果使用sendMessage方式
程式碼如下:
Message msg=new Message();  
msg.arg1=i;  
handler.sendMessage(msg);  
  • 使用sendToTarget方式
 程式碼如下:
Message msg = handler.obtainMessage();  
msg.arg1 = i;  
msg.sendToTarget();     
上次兩種方式都可以達到相同的目的,將訊息回傳給handler去做後續的處理
都有callback的功用
但是兩者對於程式的資源消耗卻有差別
  • 使用sendMessage,我們需要自己new Message,來取得message
    如此會增加prcoess的儲存空間
  • 使用sendToTarget,採用obtainMessage()方法來取得message,是從系統的MessagePool中取得,並不會增加process的儲存空間

所以採用的obtainMessage來實體化message會是比較有效率的方法

參考連結
參考連結




2014年3月17日

Android─隱藏Action bar

如果在android 4.0以上的版本,我們想要隱藏Action bar
我們可以去專案目錄資料夾values-v14下的styles.xml加入

showHome|homeAsUp|showTitle
showHome|homeAsUp|showTitle
@android:color/transparent

如此則可以隱藏action bar

參考連結1
參考連結2

Android─控制螢幕休眠

當我們程式在執行某個片段的時候,我們想要螢幕不休眠,讓使用者可以看到我們所想要顯示的資訊,例如 轉帳中,程式移除中
我們可以透過下面的程式碼達到我們的要求

首先我們先宣告
PowerManager pm;
	PowerManager.WakeLock wakeLock;

之後在oncreate下,加入
pm = (PowerManager) getActivity().getSystemService(
				Context.POWER_SERVICE);
		wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, this.getClass()
				.getCanonicalName());

之後在你想要螢幕不休眠的地方加入
wakeLock.acquire();
//想做的動作

別忘了在做完程序時,加入
wakeLock.release();
不然整個activity都會處於不休眠的狀態下