Monday, October 18, 2010

dip和px

dip是絕對像素,在各種型號的大小不變
PX則會自動縮放大小
===========
對不起,以上的資料誤導大家了
在API文件中︰
the application must ensure that it declares its UI dimensions using density-independent pixels (dp) and scales any absolute pixel values (px)
也就是說︰dpi是根據螢幕密度去動態調整元件大小
而px是絕對大小

Sunday, October 3, 2010

kill-server後老是?????no permission

已經照著Android的教學去設定Ubuntu 的51-android.rules後
在$下達adb kill-server
再進到#下達adb start-server→adb devices
仍然是?????no permission的原因是:

Eclipse要先關掉,如果有接另一臺Android裝置也要拔掉
然後,程式才有可能成功的kill-server和start-server

Friday, October 1, 2010

onKeyDown()

如果要讓onKeyDown的返回鍵按下返回後,出現視窗並等待使用者的指令
則必須return true;
否則程式仍會跳回前一頁

Tuesday, September 21, 2010

1.5版以後不能用Widget直接update

在1.5時,各大書籍和SDKGUIDE都教我們在Widget template裡的<updateperiodmillis>設定時間來更新Widget,
但在1.6以上,Google把這項功能關閉了,強制將更新時間改為30mins以上。
所以,如果要更新,就必須改用AlarmManager,
並且,將<updateperiodmillis>設為0(事後證實,改為0後,若Service被關閉,Widget不會重開Service,所以不能改為0)。
免得像我一樣花了1天的時間在找為什麼一直出現NullPointerException><"(後來這個原因只是我程式邏輯中的問題)

Monday, September 13, 2010

有的沒的

在onCreate()建立的實體,在該Activity中,不會消失

BroadcastReceiver的兩種註冊方式

1.在主Activity的onCreate()裡registerReceiver();
2.在Androidmanifest.xml裡寫<receiver>標籤

註︰如果要自訂Broadcast的Action訊息,只能用第1種方法

Wednesday, August 25, 2010

simpleCursorAdapter和mutiple choice的問題

原本想說,simpleCursorAdapter的建構子是這樣︰
SimpleCursorAdapter(Context context, int layout, Cursor c, String[] from, int[] to)
那我只要將c.query()的回傳值Cursor放入,並指定欄位from和接收並顯示的位置to,就可以資料庫的資料一筆一筆顯示出來,
本來我資料庫還包括了_open這個boolean值


為的是要讓我的mutiple choice能控制是否被選取
結果...結果...
G前輩幫我花了一些時間去找原始碼,發現...
simpleCursorAdapter只收Text,不收其它值
simpleCursorAdapter的to位置,可以收android.R.id.text1
讓我們要顯示出來的文字可以在multiple-choice的xml標籤中顯示。

Sunday, August 22, 2010

ProgressDialog提示等待視窗

  哼,只不過是一個小視窗告知使用者︰你必須等待。這麼簡單的小東西我小鰻一下就能搞定!
  結果我一搞就搞了一個下午才搞懂。
  在SDK範例大全中,看到很多的ProgressDialog都有跟著執行緒做視窗的結束,起先我以為ProgressDialog就是要跟著執行緒了,研究到最後,才發現…其實不用。
  仔細看看程式碼,書裡寫的是︰
// 顯示Progress對話方塊
      myDialog = ProgressDialog.show
                 (
                   要顯示視窗的Context,
                   標題的文字,
                   視窗內文,
                   boolean值
                 );
      
      new Thread()
      { 
        public void run()
        { 
          try
          { 
            /* 在這裡寫上要背景執行的程式片段 */
            /* 為了明顯看見效果,以暫停3秒作為示範 */
            sleep(3000);
          }
          catch (Exception e)
          {
            e.printStackTrace();
          }
          finally
          {
            myDialog.dismiss();    // 卸載所建立的myDialog物件
          }
        }
      }.start(); //開始執行執行緒
ok,很清楚的知道,書裡在ProgressDialog的實作下,跟了一個Thread,好讓程式能夠在3秒以內完成並結束。

  但是,Thread這一段就算不寫也沒關係,反正只要用任何方法,讓
myDialog.dismiss();
能夠被執行到,視窗自然就會消失,畫面返回主程式了。

  小鰻真正在實作時,除了摸索Thread倒底要不要寫這個問題以外,還搞了一個小烏龍。
  ProgressDialog本身是能夠接受New出實體的,於是,我在
myDialog = ProgressDialog.show
                 (
                   要顯示視窗的Context,
                   標題的文字,
                   視窗內文,
                   boolean值
                 );
的上面,又加上一段
myDialog = new ProgressDialog(this);
也難怪我在執行myDialog.dismiss()時,怎麼樣也關不掉視窗!

Monday, August 16, 2010

我的隨手新聞RSS解析

話說︰
  小鰻最近在忙一個專案,其中有一段剛好跟RSS有關,研究了3、4天的SDK範例大全和另一本開發實務的書,在這裡稍微把概念記錄下來。
  android有提供幾種方式去抓取RSS資料來源,最為人知的就是使用SAXParser分析器了。
  RSS說簡單了,也只不過是一個xml檔(也有可能是其他的副檔名)。它有一定的規範與格式,所以在解析各大新聞臺的RSS時,也變得有跡可尋。

  以下是常看到的RSSxml檔案格式
  
<itme>
    <title>新聞的標題</title>
    <link>新聞的連結網址</link>
    <description>新聞內容簡述</description>
    <pubDate>發佈新聞的時間</pubDate>
</item>
  所以啦,所謂的RSS解析器,說白一點,就是在這些標籤裡,把字取出來啦!
  通常各大網站都會提供RSS新聞的連結,像yam新聞的RSS網址是這樣子的︰
http://c.yam.com/news/o5link/r.c?http://n.yam.com/RSS/Rss_life.xml
所以,到時候程式裡一定要有個地方能夠存這個網址。
------------------------------------------------------

RSS解析器裡會有4個工人分工合作著
(1)XMLReader - 閱讀工人
(2)MyAdapter(繼承自BaseAdapter) - 版面配置工人
(3)MyHandler(繼承自DefaultHandler) - 文字分配工人
(4)一個具物件導向特性的類別News - 模版工人

要能夠解析一份RSS,Android交給了4個工人幫忙
(1)XMLReader
第1個工人既然叫閱讀工人,我們就來看看這個工人是怎麼讀書的吧︰
path = "http://c.yam.com/news/o5link/r.c?http://n.yam.com/RSS/Rss_life.xml";
URL url = null;

try{
    url = new URL(path);//呼叫網址進來
    SAXParserFactory spf = SAXParserFactory.newInstance();//先蓋一個工廠
    SAXParser sp = spf.newSAXParser();//工廠有一個知識不太高的解析工人
    XMLReader xr = sp.getXMLReader();//也有一個閱讀工人
    MyHandler myHandler = new MyHandler();//用到了我們之後建立的分配工人
    xr.setContentHandler(myHandler);//將閱讀工人和分配工人做結合
    xr.parse(new InputSource(url.openStream()));//閱讀工人用parse去開啟一個InputStream放資料
    
    data = myHandler.getParsedData();//getParsedData()方法會在myHandler裡看到
}catch(Exception e){
    log.i("message","wrong!");
    }
原來光一個閱讀工人,就已經做了一些的前置動作了。

(2)MyAdapter
其實這個版面配置工人還真的是可有可無,要不是主編要求取出來的"新聞發佈時間"不能和"新聞標題"一樣大,還真的是不用請版面配置工人出來,用原本的android預設配置就好
這個配置工人,android希望我們繼承自BaseAdapter,而且,還規範了我們必須實作以下4個method
//建構子
public MyAdapter(Context context,List lt){
mInflater = LayoutInflater.from(context);
}
@Override
public int getCount(){
    return 數量;
    }
@Override
public int getItem(int position){
    return position;
    }
@Override
public int getItemId(){
    return position;
    }
@Override
public View getView(int position,View convertView,ViewGroup par){
    ViewHolder holder;
    if(convertView == null){
    convertView = mInflater.inflate(R.layout.news_row, null);
    holder = new ViewHolder();
    holder.text = (TextView) convertView.findViewById(R.id.text);
    convertView.setTag(holder);
    }else{
    holder = (ViewHolder) convertView.getTag();
    }
    return convertView;
  }

class ViewHolder{//為自己訂的版面的xml做一個類別
    TextView text;
    }
}
最後面這段「為自己訂的版面的xml做一個類別」是什麼意思呢?
其實配置工人通常會帶一個小老婆出現︰
news_row.xml
他們其實是很親密的,正所謂孟不離焦啊!
一個負責外表(xml),另一個是對應的骨架(class ViewHolder)

(3)MyHandler
既然叫Handler,當然什麼事都要幫你搞定囉!
它也有幾個一定要我們覆寫的method
public class MyHandler extends DefaultHandler{
    private List<News> li;

    public List getParsedData(){//這個是我們自己寫的,沒有一定要覆寫
    return li;
    }
    
    @Override
    pubilc void starDocument() throws SAXExcption{
    li = new ArrayList<News>();//在程式解析之初,先建立一個ArrayList容器
    }

    @Override
    pubilc void endDocument() throws SAXExcption{
    }

    @Override
    pubilc void starElement(String namespaceURI, String localName, String qName, Attributes atts) thtows SAXException{
    news = new News();//在程式解析之初,先產生實體
    }

    @Override
    pubilc void endElement(String namespaceURI, String localName, String qName, Attributes atts) thtows SAXException{
    //更多程式碼
    }

    @Override  //取標籤內的字的方式
    pubilc void characters(char ch[], int start, int length){
    //更多程式碼    
    }
}
這段的程式跑法是︰
starElement()→characters()→endElement()→starElement()→characters()→endElement().....
將一個一個的標籤辨識出來並跑完



(4)News類別
既然叫模版工人,就是說從解析器解出來的字串,要有一個一個的對應去接收資料,好讓容器能歸納整理咩

所以,模版的程式碼超基本
public class News{
    private String title="";  //新聞的標題存在這裡
    private String link="";  //新聞的連結網址存在這裡
    private String desc="";  //新聞的大綱描述存在這裡
    private String date="";  //新聞的發佈時間存在這裡
//以下是一堆的getter和setter
//像︰
    public String getTitle(){
    return title;
    }
    public String setTitle(String title){
    this.title = title;
    }
    //更多程式碼    
}

最後最後,有一個超關鍵,如果你忽略了,可能都不知道為什麼會無法解析或上網咧!

請你在AndroidManifest.xml這個apk基本配面版中的<application>區塊外,做以下的新增
<uses-permission android:name="android.permission.INTERNET" />
因為android預設的apk連網功能是關閉的,必須透過上述的設定將上網權限打開。

好啦!大功告成。
程式不多不少,但是就是因為大家的配合,才產生出了好用的RSS隨手新聞。

下臺一鞠躬(笑)。

Thursday, August 12, 2010

intent和ActivityResult

一開始不懂為什麼Activity會有一個onActivityResult(),為什麼在A畫有等待接收B畫面的回傳值的功能,不是直接從Bintent過來就好了嗎?
產生這個問題後,馬上去問k前輩
他說
 一般來說,我們用intent是為了讓畫面能從A跳到B,但是如果我們又從Bintent到A,在Android中,會產生出2個A畫面,而且intent回去的A,是A2
但是,如果在B畫面setResult傳回A的onActivityResult(),此時雖然也是回A畫面,但是回的是最先開始的A1畫面,這樣解釋能理解嗎?

自訂Adapter的inflater方法

想要替Gallery或ListView去自制樣板時,通常會用到inflater指令。

然而這個Adapter會實作以下四個method︰

public class myAdapter extends baseAdapter
1.public int getCount() //決定了要跑出幾條清單
2.public Object getItem(int position)
3.public long getItemId(int position
4.public View getView(int position, View convertView, ViewGroup parent)//顯示的前置作業

Layout的顯現前置作業,通常都是在getView()裡去交待的
經實驗後,發現邏輯是
(1)進來跑一次的getView()→輸出position=0→out程式區塊
(2)重覆步驟1,但這次是跑position=1
(3)依此類推
★以上3個步驟,實驗後發現居然run了3遍這3個步驟


如︰
(1)Gallery經過setAdapter後的自製Adapter,會一次建立一個ImageView的實體,並取得資源,一經滑動到那個位置(Position),馬上重新執行一次getView(),去重新取得新的資源
(2)在ListView的setAdapter後的自製Adapter,也是一次一個getView()的方式去完成一格的list清單,重覆呼叫,直到整個ListView都將資料呈現出來為止

Wednesday, August 11, 2010

在Google Blogger使用程式碼標註「SyntaxHighlighter」


一、前言

資訊業版的部落格常常需要貼上程式語法,
但文字和程式碼黏成一塊,
對觀看的讀者來說實在是很吃力的一件事。

因此筆者在這邊推薦一套程式語法的「高亮」標註工具︰
SyntaxHighlighter。

一起來看看它的魅力吧!

二、文章開始


將SyntaxHighlighter語法貼進Blogger中

將下列程式碼複製到你的Blogger中的在[範本]→[網頁即時狀態]→[編輯HTML]→"<head>"標籤底下

    
    
    
    
註︰因為Blogger的一些BUG,在貼上上述的code並儲存時可能會遇到您的 HTML 不被接受: 缺少結尾的標記: SCRIPT 之類的警語,請修改成對應的語法。

攢寫SyntaxHighlighter語法

如何寫漂亮的程式框架和程式呢?
將下面這段寫在你的html頁面中
如果你的程式標註使用的是JAVA︰
程式碼寫在這裡...
 

如果你的程式標註使用的是C++︰
程式碼寫在這裡...
 

如果你的程式標註使用的是javascript︰
程式碼寫在這裡...
 

如果你的程式標註使用的是objective-c︰
程式碼寫在這裡...
 

如果你的程式標註使用的是shell︰
 
程式碼寫在這裡...

如果你的程式標註使用的是html︰
 
程式碼寫在這裡...

如果你的程式標註使用的是純文字︰
 
程式碼寫在這裡...

如果還想知道更多語法的用法,
可以參考SyntaxHighlighter官網

更換SyntaxHighlighter背景主題

可以參考官網教學
將上面

改成其它的.css主題檔。


其它有趣的用法


1.不要看到行數
 
程式碼寫在這裡...
執行結果如下
程式碼寫在這裡...

2.不要看到右邊的問號
 
程式碼寫在這裡...
執行結果如下
程式碼寫在這裡...

3.替特定行數畫下重點
 
程式碼第1行
程式碼第2行
程式碼第3行
執行結果如下
程式碼第1行
程式碼第2行
程式碼第3行

4.特殊符號表 

參考網址

Tuesday, July 20, 2010

周思博趣談軟體介面設計

【重點1】當「設計模型」越接近「使用者模型」,代表你的程式介面設計的越成功
使用者模型:使用者的心中所期待的程式使用方式
【重點2】如果程式模型越不單純,就可能不是使用者模型
【重點3】「請你做出選擇」盡可能是程式設計師的責任,而非使用者。
【重點4】善用「隱喻」可以幫助使用者的使用直覺性。
如:程式裡的放大鏡,使用者馬上能聯想到「放大」
【重點5】抄襲已成功的知名軟體設計,而非創新
也許程式設計師覺得自己設計出來的版面比別套成功的軟體好用,只因使用者已習慣舊有的控制方式,就算舊的程式設計的很難用,卻都會因"我習慣了"而變得好用。
【重點6】使用者看不下任何字,不管是有耐心還是沒耐心的使用者
也許我們以為字多=好,但是別想要使用者去翻說明書來使用!
【重點7】不要以為使用者手腳都很靈活
介面最忌諱設計的死板,我一定要"拉到底",才會出現最下面的畫面
【重點8】貼心 != 雞婆
常常我們以為這樣子設計使用者一定覺得方便,但有時候就是讓人不便【重點9】大眾常用到的功能,就是要優先陳列出來的功能


設計良好軟體大概需要六個步驟:

  1. 創造一些使用者
  2. 找出重要的活動
  3. 找出使用者模型:使用者期望如何完成這些活動
  4. 草擬出初版的設計
  5. 一直反覆把設計修改得更容易,直到虛構使用者能輕易使用為止
  6. 找真人來看著他們試用你的軟體。


Thursday, July 15, 2010

計算機概論

    CPU其實內部已經含有一些小指令集,我們所使用的軟體都要經過CPU內部的微指令集來達成才行。
    世界上常見到的兩種主要CPU種 類: 分別是精簡指令集(RISC)與複雜指令集(CISC)系統。
    CPU的種類
    精簡指令集(RISC)
    複雜指令集(CISC)
    優點
    指令的執行時間都很短
    完成的動作也很單純
    指令的執行效能較佳
    每個小指令可以執行一些較低階的硬體操作
    缺點
    複雜的事情,
    就要由多個指令來完成。
    指令數目多而且複雜
    使用的公司

    公司
    出產系列
    使用單位
    昇陽
    SPARC系列
    銀行金融體系的主要伺服器
    IBM

    Power Architecture(包括PowerPC)系列
    新力(Sony)公司出產的Play Station 3(PS3)
    ARM

    廠牌手機、PDA、導航系統
    AMD、Intel、VIA
    0/1 的單位我們稱為 bit。但 bit 實在太小了, 並且在儲存資料時每份簡單的資料都會使用到 8 個 bits 的大小來記錄,因此定義出 byte 這個單位,他們的關係為:
    1 Byte = 8 bits
    時脈就是CPU每秒鐘可以進行的工作次數。 所以時脈越高表示這顆CPU單位時間內可以作更多的事情。舉例來說,Intel的Core 2 Duo型號E8400的CPU時脈為3.0GHz, 表示這顆CPU在一秒內可以進行3.0x109次工作,每次工作都可以進行少數的指令運作之意。
    不同的CPU之間不能單純的以時脈來判斷 運算效能喔!這是因為每顆CPU的微指令集不相同,時脈目前僅能用來比較同款CPU的速度!
    主機板晶片組如何進行各個電腦元件之間的溝通?這個時候就需要用到所謂的I/O位址與IRQ囉!
    I/O位址有點類似每個裝置的門牌號碼,IRQ可以想成是各個門牌連接到郵件中心(CPU)的專門路徑囉!
    CMOS主要的功能為記錄主機板上面的重要參數, 包括系統時間、CPU電壓與頻率、各項設備的I/O位址與IRQ等,由於這些資料的記錄要花費電力,因此主機板上面才有電池。 BIOS為寫入到主機板上某一塊 flash 或 EEPROM 的程式,他可以在開機的時候執行,以載入CMOS當中的參數, 並嘗試呼叫儲存裝置中的開機程式,進一步進入作業系統當中。
    文字編碼系統
    當我們要寫入檔案的文字資料時,該文字資料會由編碼對照表將該文字轉成數字後,再存入檔案當中。 同樣的,當我們要將檔案內容的資料讀出時,也會經過編碼對照表將該數字轉成對應的文字後,再顯示到螢幕上。 現在你知道為何瀏覽器上面如果編碼寫錯時,會出現亂碼了嗎?這是因為編碼對照表寫錯, 導致對照的文字產生誤差之故啦!
    big5碼的中文字編碼對於某些資料庫系統來說是很有問題的,某些字碼例如『許、蓋、功』等字, 由於這幾個字的內部編碼會被誤判為單/雙引號,在寫入還不成問題,在讀出資料的對照表時, 常常就會變成亂碼。不只中文字,其他非英語系國家也常常會有這樣的問題出現啊!
    為了解決這個問題,由國際組織ISO/IEC跳出來制訂了所謂的Unicode編碼系 統, 我們常常稱呼的UTF8或萬國碼的編碼就是這個咚咚。因為這個編碼系統打破了所有國家的不同編碼, 因此目前網際網路社會大多朝向這個編碼系統在走,所以各位親愛的朋友啊,記得將你的編碼系統修訂一下喔!
    你要讓DVD影片能夠放映, 那就得要參考DVD光碟機的硬體資訊才行。
    作業系統(Operating System, OS)其實也是一組程式, 這組程式的重點在於管理電腦的所有活動以及驅動系統中的所有硬體。

Monday, July 12, 2010

Servlet initiate parameter

Servlet在建立時,有一個生命週期
而在建立一個Servlet的一開始,會先做一些初始化的動作,
而這些動作,是在web.xml裡去設定的...


如下圖,我們要在初始時,就將要印出來的table border設為2,而顏色設為藍色,web container會在建立Servlet的一開始,就在:ServerletConfig做設定
------------------------------------------------------------------


當我們要攢寫一個新的Servlet時,我們必須要繼承HttpServlet。但是我們的初始化設定在HttpServlet的父父類別(ServletConfig), 也就是在"阿公"這一代,就已經設定了。
---------------------------------------------------------------------
init()方法,在Servlet建立的初時,只會被呼叫1次,僅1次。


原來我們不是只在web.xml做<init-param>設定就好,還要在我們新寫的Servlet裡,呼叫阿公的method:init(),並使用getInitParameter去把web.xml裡的值叫出來做對應,才算正式的完成初始化。

---------------------------------------------------------------------------
初始化完就結束了?
這個答案是否定的,因為你還沒下參數來"使用"。
下了
out.println("<table border='" + borderSize + "' bordercolor='" + borderColor + " ' >");
才算真的完成格式的載入。


使用者註冊表單的整個架構圖

特殊的html標籤

段落
<ul>
//程式碼
</ul>


青春痘
<li>//青春痘裡要輸出的字</li>

將資料從1個servlet丟到另一個servlet

如果要將資料丟到別的程式,用到一個概念:
 所以 ,修改好的程式碼應該如下:
  request.setAttribute("error", error);
               RequestDispatcher view =
                request.getRequestDispatcher("tell_me_please.view");
        view.forward(request, response);


一定要在程式forward以前將資料setAttribute出去





Sunday, July 11, 2010

實體繼續導向

在一般的網頁中,如果要將第1個網頁跳轉到第2個網頁,也許我們會在doPost()下 response.sendRedirect("第2個網頁.view");指令。
但是,這在第2個網頁,會發生requests和response為null的冏境。
下面的圖示,TellMeServlet.java是第1個網頁,而HelloServlet.java是第2個網頁。
 原來在從who_are_you.html裡傳給TellMeServlet的request和reponse,在回傳給user的browser之後,再遇到response.sendRedirect("hello.view");時,這個時候的request和reponse都被清空了。
---------------------------------------------------------------------------------------------------------
解決的辦法當然是有,利用RequestDispatcher。


這樣子request和response物件就順利丟到第2個網頁了

Servlet Request