2013年8月10日 星期六

SQLite 3 Data Type 資料型態

Storage Classes

A. SQLite資料庫儲存資料時, 主要區分為以下五種Storage Class, 會比Data Type來的更加簡易及統籌分類, 所以在SQLite Storage Class及 Data Type可以互相替代:

   1. NULL. The value is a NULL value.

   2. INTEGER. The value is a signed integer, stored in 1, 2, 3, 4, 6, or 8 bytes
       depending on the magnitude of the value.

   3. REAL. The value is a floating point value,
       stored as an 8-byte IEEE floating point number.

   4. TEXT. The value is a text string,
       stored using the database encoding (UTF-8, UTF-16BE or UTF-16LE).

   5. BLOB. The value is a blob of data, stored exactly as it was input.

B. SQLite中並沒有Boolean, 會使用Integer的1和0來代表.

C. 在SQLite中會使用TEXT, REAL, INTEGER代表Date and Time:

  1. TEXT as ISO8601 strings ("YYYY-MM-DD HH:MM:SS.SSS").

  2. REAL as Julian day numbers,
      the number of days since noon in Greenwich on November 24, 4714 B.C.
      according to the proleptic Gregorian calendar.

  3. INTEGER as Unix Time, the number of seconds since 1970-01-01 00:00:00 UT

Type Affinity

最主要是設計用來能夠更相容於其他資料庫的Data Type, 目的在於找出資料儲存在Column中建議最適合的Storage Class, 所以在使用SQLite設計資料表時, 甚至可以不需要定義資料型態, 資料型態是建議不是必須! 當沒有指定資料型態時, 該Column可以儲存任何Storage Class的資料.

A. Type Affinity有以下五種:
    1. TEXT
    2. NUMERIC
    3. INTEGER
    4. REAL
    5. NONE

B. Rules規則:

Rule 1: 如果宣告的型態中有包含"INT"字串則會被歸類為INTEGER affinity,
            也就是直接使用INTEGER Storage Class.
            例如: INT, INTEGER, TINYINT. SMALLINT. MEDIUMINT,
                     BIGINT. UNSIGNED BIG INT, INT2, INT等

Rule 2: 如果宣告的型態中有包含"CHAR", "CLOB", or "TEXT"字串,
            則會被歸類為TEXT affinity,
            例如: VARCHAR有包含"CHAR", 所以使用TEXT Storage Class.
            也就是直接使用TEXT Storage Class.
            例如: CHARACTER(20), VARCHAR(255), VARYING CHARACTER(255),
                     NCHAR(55), NATIVE CHARACTER(70), NVARCHAR(100). TEXT, CLOB等

Rule 3: 如果宣告的型態中有包含"BLOB"字串, 則會被歸類 NONE affinity,
            也就是會直接判斷所塞入的值是適合那一個Storage Class.
            例如: BLOB, 塞入的是BLOBs值則不會管Type affinity,
                     全部都會使用BLOB Storage Class

Rule 4: 如果宣告的型態中有包含"REAL", "FLOA", or "DOUB"字串, 則會被歸類REAL affinity.
            也就是直接使用REAL Storage Class.
            例如: REAL, DOUBLE, DOUBLE PRECISION, FLOA等

Rule 5: 其他會被歸類為NUMERIC affinity,
            會直接判斷所塞入的值是適合那一個Storage Class.
            例如: NUMERIC, DECIMAL(10,5), BOOLEAN, DATE, DATETIME等

Rule 6: 如果塞入的是NULL值則不會管Type affinity, 全部都會使用NULL Storage Class.

範例:

--建立資料表
CREATE TABLE t1(
    t  TEXT,     -- 套用Rule 2
    nu NUMERIC,  -- 套用Rule 5
    i  INTEGER,  -- 套用Rule 1
    r  REAL,     -- 套用Rule 4
    no BLOB      -- 套用Rule 3
);

-- 塞入字串
INSERT INTO t1 VALUES('500.0', '500.0', '500.0', '500.0', '500.0');
SELECT typeof(t), typeof(nu), typeof(i), typeof(r), typeof(no) FROM t1;
text|integer|integer|real|text

-- 塞入浮點數1
DELETE FROM t1;
INSERT INTO t1 VALUES(500.0, 500.0, 500.0, 500.0, 500.0);
SELECT typeof(t), typeof(nu), typeof(i), typeof(r), typeof(no) FROM t1;
text|integer|integer|real|real

-- 塞入浮點數2
DELETE FROM t1;
INSERT INTO t1 VALUES(500.0, 500.123, 500.0, 500.0, 500.0);
SELECT typeof(t), typeof(nu), typeof(i), typeof(r), typeof(no) FROM t1;
text|real|integer|real|real

-- 塞入整數
DELETE FROM t1;
INSERT INTO t1 VALUES(500, 500, 500, 500, 500);
SELECT typeof(t), typeof(nu), typeof(i), typeof(r), typeof(no) FROM t1;
text|integer|integer|real|integer

-- 塞入BLOBs
DELETE FROM t1;
INSERT INTO t1 VALUES(x'0500', x'0500', x'0500', x'0500', x'0500');
SELECT typeof(t), typeof(nu), typeof(i), typeof(r), typeof(no) FROM t1;
blob|blob|blob|blob|blob

-- 塞入NULLs
DELETE FROM t1;
INSERT INTO t1 VALUES(NULL,NULL,NULL,NULL,NULL);
SELECT typeof(t), typeof(nu), typeof(i), typeof(r), typeof(no) FROM t1;
null|null|null|null|null



轉貼請註明出處,最好直接使用聯結轉貼!Thanks~
作者: Samuel - 林靖傑
Bloghttp://sabaothtech.blogspot.tw/
日期:2013/08/10


2013年5月4日 星期六

Android - 讓Android Emulator(AVD)支援相機及Webcam


        在AVD尚未支援相機模擬前如果要進行相機的模擬必須要透過架設Socket Server及安裝JMF來變相達成相機的功能但是在新版的Android Tools已經可以讓AVD藉由使用Webcam來當成相機鏡頭如下圖

 



但是這樣還是不太方便因為還需要有Webcam才能夠使用並且在本人教學上也會產生極度不方便的情況因為每個學生不可能都有Android手機或者Webcam所以開始想要將Webcam也運用軟體模擬,所以在經過測試後能夠讓AVD抓到Webcam的模擬軟體只有e2eSoft VCam這套Fake Webcam在經過測試後並無法正常使用但是需注意的是e2eSoft VCam所抓到的影像會是上下左右皆相反也就是放上的圖檔需要上下左右皆翻轉,這樣放到e2eSoft VCam上的圖片才可以正常看到畫面


e2eSoft VCam官網下載點 
http://www.e2esoft.cn/downloads.asp


當然這樣的方式支援拍照掃瞄外也支援錄影只要有關於鏡頭的功能都能使用e2eSoft VCam也支援圖片影音桌面截取及錄影等功能


使用方式

1.      需先開啟e2eSoft VCam並且放上圖片(e2eSoft VCam所抓到的影像會是上下左右皆相反也就是放上的圖檔需要上下左右皆翻轉,這樣放到e2eSoft VCam上的圖片才可以正常看到畫面)

 



2.      AVD設置上需將Back Camera選項改成Webcam0

 

3.      接著再開啟AVD注意! 請先開VCam再開AVD否則無法抓到!

4.    接下來就像相機一樣使用

 
轉貼請註明出處,最好直接使用聯結轉貼!Thanks~
作者: Samuel - 林靖傑
Bloghttp://sabaothtech.blogspot.tw/
日期:2013/05/04


2013年5月3日 星期五

Android - 掃瞄1維/2維(1D/2D)條碼 QR Code - 修改ZXing Source 2014-03-30 Updated.

 

ZXing是使用Java開發的Open Source專案,主要目的是用來進行1D/2D的條碼掃瞄,支援的格式如下:

  • UPC-A and UPC-E
  • EAN-8 and EAN-13
  • Code 39
  • Code 93
  • Code 128
  • ITF
  • Codabar
  • RSS-14 (all variants)
  • RSS Expanded (most variants)
  • QR Code
  • Data Matrix
  • Aztec ('beta' quality) 
  • PDF 417 ('alpha' quality)

官方原始碼及測試資料下載點

GitHub Project:
 
jar檔下載點
http://repo1.maven.org/maven2/com/google/zxing/

因為在測試的ZXing過程中,發現程式會直接呼叫ZXing Barcode Scanner程式中的Activity,為了不需額外安裝ZXing Barcode Scanner程式,則本人將專案修改成不需要安裝ZXing Barcode Scanner的版本,說明如下:


ZXing-2.3.1.zip下載點 經修正後,該版本可以使用在API 11(3.0) ~ API 19(4.4.2) 

  • Bug fix - 該版本修正第一次啟動會失敗的問題.
  • 該版本將所有元件整合為一個專案, 並精簡到只剩掃瞄與產出條碼功能.
  • ZXing 2.3.0版本只支持Android 4.0以後的版本, 但本人修正到支持Android 3.0, 但不再支持Android 2.x!
  1. Eclipse中匯入ZXing-2.3.1/ZXingLibs.zip壓縮檔裡的專案。
  2. Android專案按右鍵選Properties => 點選Android => 對下方的Library區塊點選Add => 選擇剛匯入的ZXingLibs專案引用。
  3. 請先確保您的Android專案已經有引用Android Support Library(android-support-v4.jar), 如遇Android Support Library版本衝突, 請統一Android Support Library版本即可!
  4. ZXing-2.3.1/AndroidManifest.xmlAndroidManifest.xml中的設定資訊, 目前只剩下掃瞄與產出條碼功能, 如需其他功能請自行使用官方原始專案! 
  5. 掃瞄呼叫方式如ZXing-2.3.1/Main.java檔。
  6. ZXing-2.3.1/EncodeAct.java檔為如何編碼的範例。

轉貼請註明出處,最好直接使用聯結轉貼! Thanks~
作者: Samuel - 林靖傑
Bloghttp://sabaothtech.blogspot.tw/
日期:2014/03/30 Updated.

2013年4月27日 星期六

Android - Fragment

        在Android 3.0之後,設計上發生了一些變革,最重要的莫過於Fragment與Action Bar,除了可以讓應用程式設計上更有彈性,使用更優雅之外,更可以重複性的使用這些Fragment,並且在Support Library的支援下,使用Fragment來設計跨版本的應用程式是個不錯的選擇。
Fragment是擁有部份功能的Activity,Fragment必須使用在Activity裡,也直接受到Activity的影響,例如:如果Activity Pause或Destroy,則在該Activity裡的Fragment也會一併Pause或Destroy。

        Fragment的設計應該視為一個可重用的Activity模組,因為Fragment會有自己的Layout及Life-cycle,並且Fragment是可以使用到不同的Activity裡進行重用,所以在設計Fragment時,不應該在Fragment裡再呼叫其他Fragment,例如:在Tablet時,因為有比較大的螢幕,所以使用單獨的兩個Fragment包在同一個Activity裡,而在Handset時,則不必再重寫Fragment,直接將不同的Fragment運用在不同的Activity裡;並且當使用FragmentTransaction添加或取代一個Fragment到一個Activity的Layout時,其Fragment的Layout是添加到Activity的ViewGroup內。



Fragment生命週期

       如果要建立一個Fragment,則必須使用繼承自Fragment的子類別,例如:ListFragment、DialogFragment、PreferenceFragment等。下圖為Fragment的生命週期,紅色框代表必須實作的事件,而onCreateView會在要呈現該Fragment畫面時就會執行,所以onCreateView所傳回的是View,並且帶入參數就有LayoutInflater,可以幫助Layout轉化成View加入到Activity的ViewGroup中,如果使用的是ListFragment,則預設該View就為ListView;如果一個Activity裡配置一個Fragment,則container參數會是null,也就是Fragment的Layout並沒有跟Activity的Layout綁在一起,如果是使用FragmentTransaction加入或取代Fragment,則container參數會是Activity的ViewGroup。
例:

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,  Bundle savedInstanceState) {
        // Inflate the layout for this fragment
        return inflater.inflate(R.layout.example_fragment, container, false);
    }


        至於其他的事件,例如:onCreate()、onStart()、onResume()、onPause()、onStop()、onDestroy(),基本上都與Activity所對應的事件相似。除了直接在Layout裡指定Fragment之外,如果要在程式端動態增加、取代、刪除Fragment,可以使用FragmentTransaction來達成,例如:

FragmentTransaction ft = getFragmentManager().beginTransaction();

//只要是ViewGroup即可,不一定要FrameLayout
ft.replace(R.id.details, details);//進行取代   
ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);

//如果有加上這一行會將Fragment加到Back Stack,
//這樣就可以直接使用上一頁鈕回到上一個Fragment的狀態,
//否則按下上一頁就會直接關掉Activity
ft.addToBackStack(null);

//完成Fragment的異動
ft.commit();

commit必須在Activity Save State
(也就是 Another activity comes into the foreground)之前執行,否則會拋錯,
要不就要執行commitAllowingStateLoss()。


轉貼請註明出處,最好直接使用聯結轉貼!Thanks~
作者: Samuel - 林靖傑
日期:2013/04/27

2013年1月18日 星期五

Android - App Widget - 基本概念

1. 需繼承AppWidgetProvider,該類別繼承自BroadcastReceiver,所以在AndroidManifest.xml註冊時需要使用receiver。
2. 對於App Widget一定需要加上接收android.appwidget.action.APPWIDGET_UPDATE這個ACTION的Intent-filter,因為當AppWidgetManager要更新時,會對App Widget進行該動作的Broadcast,至於其它的ACTION會隱含接收,所以不明確指定也會接收以下ACTION:
  • AppWidgetManager.ACTION_APPWIDGET_DELETED
  • AppWidgetManager.ACTION_APPWIDGET_ENABLED
  • AppWidgetManager.ACTION_APPWIDGET_DISABLED
  • AppWidgetManager.ACTION_APPWIDGET_OPTIONS_CHANGED
3. 必需在AndroidManifest.xml裡指定AppWidgetProviderInfo的xml檔,主要是用來描述App Widget的相關描述,例如:
<meta-data android:name="android.appwidget.provider" android:resource="@xml/appwidget_info"/>。
  • updatePeriodMillis:為了電池的使用長度,通常更新並不會一定在所設定的時間內執行,Google建議每一個小時不要更新超過一次,如果設備正在睡眠,也會在指定的時間進行更新,如果想要更新的更加頻繁,或者不想要在設備睡眠時進行更新,則可以在Configuration Activity使用AlarmManager來發起更新。
  • resizeMode:App Widget可以Resize的模式有"horizontal"、"vertical"、"none",如果要水平及垂直都允許的話,可以設置為"horizontal|vertical"。
  • previewImage:指定App Widget在選擇區時所呈現的預覽圖片,如果沒有指定就依程式預設的圖示呈現,Android 3.0開始支援。
  • android:previewImage="@drawable/preview"
  • widgetCategory:Android 4.2(API 17)後支援讓App Widget可以呈現在鎖定畫面,該設定值有"home_screen"及"keyguard",一般沒有特別設定時,App Widget預設支援"home_screen",如果要出現在鎖定頁面,則可以設定為"keyguard|home_screen"。
  • initialLayout:指定App Widget的Layout。
  • initialKeyguardLayout:Android 4.2後,支援讓App Widget可以呈現在鎖定畫面,該設定為指定鎖定畫面所呈現的App Widget Layout。
  • minWidth & minHeight:App Widget Layout最小應該呈現的長寬,以dp為單位,為了跨平台最好不要超過4*4 Cells。
  • minResizeWidth & minResizeHeight:設定使用者在resize App Widget時,最小能夠調整到的長寬,避免調整太過頭而無法操作。
 
4. AppWidgetProvider - onEnabled:不管加入多少個同樣的App Widget,這個方法只會在第一次將App Widget加入App Widget Host中時才會執行。
 
5. AppWidgetProvider - onUpdate():該方法會在User每加入一次App Widget時便會呼叫,以及updatePeriodMillis所設定的間隔呼叫,如果有使用Configuration Activity,則使用者加入App Widget時不會被呼叫,也就是如果沒有Configuration Activity,則View的Event Handler在onUpdate()設定,如果有Configuration Activity,則在Configuration Activity中設定。
 
6. AppWidgetProvider - onDeleted:每次刪除App Widget時都會執行。
 
7. AppWidgetProvider - onDisabled:當最後一個App Widget從App Widget Host中移除時便會呼叫,在這邊對應到onEnabled中所做的工作,例如在onEnabled建立暫時資料庫,則在onDisabled就需刪除暫時資料庫。
 
8. AppWidgetProvider - onReceive:因為AppWidgetProvider繼承自BroadcastReceiver,所以會有onRecived事件,但是通常不建議自行處理該處的事件,除非有需要自行處理所接收的App Widget Broadcast,否則對應的事件應該使用之前所述的onEnabled、onUpdate、onDeleted、onDisabled即可。onRecived所處理的ACTION:
  • AppWidgetManager.ACTION_APPWIDGET_UPDATE
  • AppWidgetManager.ACTION_APPWIDGET_DELETED
  • AppWidgetManager.ACTION_APPWIDGET_ENABLED
  • AppWidgetManager.ACTION_APPWIDGET_DISABLED
  • AppWidgetManager.ACTION_APPWIDGET_OPTIONS_CHANGED
 
9. AppWidgetProvider - onAppWidgetOptionsChanged():在API Level 16 (Android 4.1)後才支援,當App Widget進行Resize的動作或第一次置放時就會執行,可以使用getAppWidgetOptions()傳回的Bundle來取得以下的資訊:
  • OPTION_APPWIDGET_MIN_WIDTH—Contains the lower bound on the current width, in dp units, of a widget instance.
  • OPTION_APPWIDGET_MIN_HEIGHT—Contains the lower bound on the current height, in dp units, of a widget instance.
  • OPTION_APPWIDGET_MAX_WIDTH—Contains the upper bound on the current width, in dp units, of a widget instance.
  • OPTION_APPWIDGET_MAX_HEIGHT—Contains the upper bound on the current width, in dp units, of a widget instance.

轉貼請註明出處,最好直接使用聯結轉貼!Thanks~
作者: Samuel - 林靖傑
日期:2013/01/18