2010年10月25日 星期一

Android Component Lifecycles - Broadcast Receiver(三)

一.Broadcast Receiver Lifecycle
只有一個LifeCycle callback method
void onReceive(Context curContext, Intent broadcastMsg)
當有訊息傳達到receiver,Android就會呼叫執行Receiver內的 onReceive()
並把intent傳進去給onReceive(),只有在執行onReceive()時,receiver的狀態是active的,當執行完return後
就會變成inactive狀態

當receiver在active狀態時是被保護不被殺的,一旦執行完處於inactive狀態,則在任何時間要砍都可以
記憶體不足時就可先砍掉這receiver

receiver存在的一個隱藏性的危險是,如果當receiver要回應broadcast message,需要開啟一個新的thread去處理時,receiver在開啟thread後會立刻return(其實,處理程序還在運作),receiver已經被當作是inactive狀態,隨時有可能會被砍掉。解決的方式是啟動一個service去處理要做的事,而不要在receiver內去開啟新的thread。

二.Processes 重要性順序
Android系統會盡可能保留所有的process,但如果當記憶體不足時,就會需要砍掉一些較不重要的process。如何判斷process的重要性,以下為重要性順序
1. foreground process:也就是正在進行中的程序
    1.使用者正在互動執行的Activity
    2.正在執行中Activity所正在呼叫運作的Service
    3.Service內部正在進行不可中斷的callback包括onCreate() 
      onStart()或onDestroy()
    4.正在執行onReceive()的BroadCast Receiver物件
      除非系統記憶體已經太低太低,否則系吐統不太可能把正在
      前景執行的程序砍掉
2.visible process:
    1.不是在前景運作,但仍然在螢幕上看的到的元件(已經呼叫了
      onPause())例如前景activity是個對話窗,但還允許前一個
      activity在後面被看到
    2.與visible Activity有關聯的Service
3.service process:
    透過startService()啟動的service,但不在以上兩層次範圍內
    雖然service並非直接與使用者看到的東西關聯在一起,但仍在
    用作使用者在意的事
    例如在背景播放音樂或在背後下載資料,除非記憶體不足否則系
    統會讓他保持運作
4.background process
    一個在背景已經看不到的Activity(已經呼叫了onStop),通常都
    會有許多background process被保留在後面,在記憶體不足時可
    以砍掉節省資源
5.empty process
    沒有任何Activity的元件,就如同cache一樣,這存在只是用來改
    善啟動效能的快慢,為了調節效能,process cache與
    kernal cache經常會被清除

因為一個service的排序是高於一個visible activity,所以在Activity初始化時,若需要進行較長時間處理,最好是啟動一個service來作,效果會比產生一個thread來作好。例如播放音樂與上傳圖片到網站上,在service作會比較好。還有就是在receiver的onReceive處理內,啟動service去執行也較佳

Android Component Lifecycles - Service(二)

一.Service可以用以下兩種模式運作
1.被啟動後一直運行,直到被呼叫停止或自行停止
  外部利用呼叫Context.startService()啟動
  呼叫Context.stopService()停止
  Service內部自己執行Service.stopSelf()或
  Service.stopSelfResult()停止
  無論startService()呼叫了幾次,停止都只需要
  呼叫一次stopService()
2.利用與Service物件建立連線,使用連線呼叫使用Service
  Client利用Context.bindService()建立一個連線到Service物件,
  並使用這連線去呼叫Service。
  若要關閉連線則利用Context.unbindService()關閉連線
  多個client是可以綁定相同的service,如果要用的service還沒被
  啟動,在bindService()時會自動啟動它

這兩個模式並非是完全獨立的,你可以透過startService()後再bind Service。例如一個背景音樂播放的service利用傳遞一個包含音樂播放資訊的intent給startService(intent)來啟動,之後使用者要由這歌取得資訊,Activity會透過呼叫bindService()建立與service的連線,在這case裡stopService並不會真的停止service,因為已經被bind
需要unbind後才會完全停止。

二.Service LifeCycle Method
Service的lifeCycle method只有以下三個,你可以overroide來掌握state的變化。
與Activity的差別是,這裡的method是public,而Activity是protected
public void onCreate() 
public void onStart(Intent intent) 
public void onDestroy()

三.Service 的幾個階段
1.entire lifetime
    在onCreate與onDestroy()之間
    利用onCreate()來作初始化,而在onDestroy()釋放所有資源
    例如音樂播放service在onCreate()時產生thread來播放
    而在onDestroy()停止thread

2.active lifetime
    由onStart()開始,這階段會接收到由startService()傳來
    的intent物件。如果是一個音樂播放的Service會在這階段
    利用取得的intent物件,找到要播放的音樂資料做播放 

無論service是用Context.startService()或Context.bindService()啟動,都會觸發 onCreate()與onDestroy(),但onStart只有是在用 startService()啟動才會被觸發。

四.Bind流程會觸發的事件
如果透過Bind來使用Service,以下事件在過程中被觸發,可以透過實作以下method。
IBinder onBind(Intent intent) 
boolean onUnbind(Intent intent) 
void onRebind(Intent intent)

只要service 啟動後允許其他人來bind,那就會有以下事件會被觸發onBind() onUnbind()

在onBind()被傳入一個來自Activity執行bindService的intent物件。onUnBind()被傳入一個來自Activity執行unbindService()的intent物件。無論service是被用哪種方式啟動,都還是可以隨時去bind(),所以service都可以接收onBind()與onUnbind()事件。

Android Component Lifecycles - Activity(一)

Android內幾種主要元件都有自己的生命週期,在其生命週期的每個階段,都有相對應的callBack method,也就是說當元件在進入該階段時,Android系統就會自動執行該階段的callBack。因此我們可以看到各種元件都會有一些內建的callBack method,如果我們希望在元件的某個階段去執行一些動作,你可以依照需要override認一階段的method

一.Activity的3種狀態(state)
1.active,running
    出現在螢幕的前景,也就是在目前task的activy堆疊的最上層,
    這Activity正被focus並接受使用者的動作
2.paused
    失去了focus,但使用者還是可以看到Activity,其他activity
    在其上方,也許是透明或沒有全螢幕覆蓋,因此paused的Activity
    還可以被看到,一個paused Activy還是在存活狀態(還保有所有資料,
    並被window manager所管理)但在系統記憶體過低時還是可能被砍掉
3.stopped
    當完全被其他的Activity所遮蔽,他是保有一些狀態資料,
    但已經看不到,他的視窗已經被隱藏,當系統記憶體過低會被砍掉

當系統記憶體過低,會將屬於paused與stopped狀態的Activity 砍掉,也就是呼叫其finish()或直接就砍了其process,當要再重新顯示在使用者面前,需要完全restart並restore之前的state 資料

二.Activity LifeCycle Method
當Activity由一個state轉到另一個state的過程中,以下幾個內部method會被自動觸發通知,所以我們若要在特定時間點執行特定動作需要override 相關protected method
protected    void onCreate(Bundle savedInstanceState) 
protected    void onStart() 
protected    void onRestart() 
protected    void onResume() 
protected    void onPause() 
protected    void onStop() 
protected    void onDestroy()

三.Activity 的幾個階段
每個Activity一定要Override onCreate()來作初始化功能,有的會需要override onPause()
去把資料改變記錄下來,以因應可能停止的動作
1.entire lifetime完整生命週期
    一個Activity由onCreate()開始,到最後onDestroy()結束,會在
    onCreate()時做所有初始化的動作,在onDestroy()內釋放所有的
    系統資源。
    例如有一個Thread在背景進行網路資料下載,這thread會在onCreat()
    程序內產生,而在onDestroy()停止這thread
2.visible lifetime
    由呼叫onStart()開始到 onStop()結束,在這過程使用者可以看到
    Activity在螢幕上,在這期間使用者可以看到元件顯示在畫面上,
    但不見得在前景或與使用者互動。
    例如你可以在onStart註冊一個BroadcastReceiver,而在onStop()
    中解除註冊,利用BroadcastReceiver監看UI上的變化,這樣就可
    以觀察到相關的變化,在Activity運作上,onStart()與onStop()
    在進行中可以被多次呼叫
3.foreground lifetime
    由呼叫onResume()到onPause()間,在這區間,Activity在前景,並可
    與使用者互動。Activity經常在這兩個狀態間跳動。    
    例如當Device進入睡眠狀態或另一個Activty要開啟,就會呼叫
    onPause(),而當activity繼續執行,或一個新的intent被發送出來
    Activity內的onResume()就會被呼叫執行

四.Activity LifeCycle Method狀態說明
1.onCreate()
    當activity第一次被產生後,會被執行。
    你可以在這程序內create View,bind data與list,
    在這method被執行時會接收到一個Bundle物件,
    這物件包含了Activity之前的state資料
    
    接下來會執行的有onStart()
2.onRestart()
    當Activity被停止後,又重新啟動時執行(與onStart同)
    接下來會執行的有onStart()
3.onStart()
    在Activity要變成Visible前執行
    
    如果接下來要把Activity顯示在前景,則伴隨著onResume()
    如果接下來要把Activity隱藏,則伴隨著onStop()    
4.onResume()
    在Activity開始與使用者互動前被呼叫
    在這點Activity是在Activity堆疊的最頂端
    
    接下來的會是onPause()
5.onPause()
    當系統要啟動其他Activity,這程序會被呼叫,
    在這程序中需要去處理,把尚未儲存的資料儲存下來,
    停止動畫與其他會消耗CPU的動作,這過程需要非常快速,
    因為下一個Activity會等他return才會執行
    
    若接下來這Activity要回到前景,接下來的會是onResume()
    若接下來這Activity要變隱藏,則接下來會是onStop()
6.onStop()
    當Activity不再讓使用者看到時呼叫
    可能發生在這Activity準備要destroy或是其他的Activity
    回復到前景
    
    假使這Activity要回到前景,接下來會是onResume()
    假若這Activity要整個關閉,接下來會是onDestroy()
7.onDestroy()
    當Activity被Destroyed前被呼叫
    這會是這Activity最後一個接收到通知,
    他可能發生在呼叫了finish()之後,或因為系統因為記憶體
    不足要節少空間而刪除,可以利用isFinishing()來判斷是
    什麼原因造成    

五.儲存Activity state
若要在Activity被關閉重開啟後,可以保留之前的狀態,
可以實做onSaveInstanceState()把資料存下來,儲存到Bundle物件上
而在重啟後讀出來
其相關順序為
onSaveInstanceState()->onPause()
onStart()->onRestoreInstanceState() 
在這過程中只儲存過渡性的資料,不要儲存固定的資料,因為onSaveInstanceState並非會一直被執行到

Monday - God Is an Astronaut

星期一的早上
天氣是舒服的秋涼
有太陽
上班的路上 也沒有太壅塞的車潮
辦公室裡 陽光溫暖 也明亮

一早的電話 帶來了幾許煩躁
打壞了原本的美好

打開音樂
用God Is an Astronaut來恢復平靜

2010年10月21日 星期四

AndroidManifest 設定檔- 基本概念

一.說明
在每個Android Application內一定會在Project根目錄下配置一個AndroidManifest.xml檔案
這檔案提供以下幾個作用
1.設定這個Application的Java Package Name
  也就是設定一個Java Package路徑用來代表這個Application        
2.設定組成這App的所有元件
  包括Activity,Service,ContentProvider,BroadCast Receiver等,
  開發好的元件都需要註冊在這Manifest檔案內,如果沒註冊在這裡,
  元件無法被使用。除了註冊元件,並利用Intent Filter讓Android
  知道在什麼狀況可以啟動哪個元件        
3.決定哪些程序將可以控制元件
4.宣告了App需要有哪些權限去取得被保護的資料或執行其他App的元件功能      
5.宣告了本App允許讓其他App互動的權限    
6.提供執行中Instrumention Classes清單與相關資料
  這些資料只有開發階段會存在,發布後會被移除
7.宣告了這App執行所要求的最低Android API版本        
8.設定這App需要連結的API Libraries
    除了預設使用Android API外,可以利用設定<uses-library>
    使用其他package的元件功能API
二.語法原則
1.element
1.<manifest> and <application>只能出現一次,其他的都可以出現多次
2.<activity>, <provider>與<service> 可以沒有順序性的出現在任何
  地方,但<activity-alias>一定要跟在<activity>後面
2.attribute
所有的屬性都是非必填的選項,除了manifest外,所有元素的屬性一定都是以android:命名
3.Class name
在Manifest內,多數的元素都直接對應到Java Class,包括application本身
如activities (activity), services (service), broadcast receivers (receiver)
與content providers (provider)


如果要在Manifest內加入這幾個class的subclass,subclass,則在name屬性上,
輸入完整的Class名稱(包括package name)
例 加入一個繼承自Service的subClass SecretService
 <manifest . . . >  
      <application . . . >  
           <service android:name="com.example.project.SecretService" . . . >  
                . . .  
           </service>  
           . . .  
      </application>  
 </manifest>  

如果這subClass是在這Application的package下,則在name屬性上
只要用.ClassName方式設定即可,系統看到.name會自動將Ap的package 加上去

 <manifest package="com.example.project" . . . >  
      <application . . . >  
           <service android:name=".SecretService" . . . >  
                . . .  
           </service>  
           . . .  
      </application>  
 </manifest>  

當要啟動這元件時,若這subClass存在,系統會產生這subclass(範例是SecretService)的instance使用,
若subclass不存在,則會產生其base class(範例是Service)的instance
4.Multiple values
若一個項目可以有多個值存在,會用多個tag repeat,而不會在一個tag寫入多個值

 <intent-filter . . . >  
      <action android:name="android.intent.action.EDIT" />  
      <action android:name="android.intent.action.INSERT" />  
      <action android:name="android.intent.action.DELETE" />  
      . . .  
 </intent-filter>  
5.resource value
會需要用到resource 當作屬性值時會以
[package:]type:name表示
若是來自於style theme的值則會是
?[package:]type:name
6.String values
當屬性值為字串會用到\\當跳脫字元,例\\n 換行

三.幾項元素功能作用
1.Intent Filters
在manifest內,主要的幾個元件如Activity Service...等利用Intent Filter設定對intent的處理能力
也就是說,用Intent Filter描述他可以處理那些intent,在一個元件可以是可以同時設定多組的intent filter。
Android系統在收到intent後可以依此決定要啟動哪個元件來處理intent需求

2.Icons and Labels
許多元素都有icon與label顯示小圖與文字在使用介面上,有的會有description 放比較多的說明文字。
例如在permission上,這三個屬性都有,當Application對系統要求取得權限時,依照提供的permission設定
就可以把這3個屬性的資料顯示在介面上

如果在上層的container上設定icon與label,那麼其子元素的icon與label都會以上層設定
當作預設值

3.Permissions
用來設定去存取Device資料,啟動其他App的元件或是本身元件被其他App使用的權限設定
一個Appication可以用permission保護其元件,所有的Permission都被定義在
android.Manifest.permission Class內,也可以自行定義自己的Permission


 <manifest . . . >  
      <permission android:name="com.example.project.DEBIT_ACCT" . . . />  
      . . .  
      <application . . .>  
           <activity android:name="com.example.project.FreneticActivity"  
                      android:permission="com.example.project.DEBIT_ACCT"  
                      . . . >  
                . . .  
           </activity>  
      </application>  
      . . .  
      <uses-permission android:name="com.example.project.DEBIT_ACCT" />  
      . . .  
 </manifest>  
以上除了定義permission外還要宣告uses-permission讓其他App可以使用這個元件
<permission-tree>:定義一個permissions group的namespace
<permission-group> :定義一組permission的label,純粹只是定義一個名稱
<permission>:若要定義屬於哪個group,則在group屬性設定
     <permission-group>設定的名稱即可

4.Libraries
每個Application預設連結到Android Library,如果要使用其他Library的package
則需要用uses-library宣告

Android Intent Filter-判斷intent傳遞對象

一.Intent接收原理
當使用者發送一個intent出來,要求元件去執行動作,如果這個intent裡有很清楚的設定了ComponentName,那麼intent就會直接被送到指定的元件,並啟動該元件,如果沒有設定,則會由Android系統自動去判斷該把這intent送到哪個元件上啟動他。

大多數在本身專案內元件可以處理的動作,intent通常都會直接指明要給哪個元件處理,如果沒有指定元件名稱的intent大多是用來啟動其他Application上的元件

二.Intent Filter的作用
Android系統如何判斷哪個元件可以接收哪個intent,就是依靠在ManiFest檔案內,宣告元件(Activity,Service)時所加入的Intent Filter設定,每個Activity內可以設定0~多組的intent filter,每一組的Intent Filter都是一份比對規則

當intent發出來時,系統會去檢查Manifest內各元件內的intent filter,而啟動適合的元件,若元件沒有設定filter,那就只能接收到有清楚指定component的intent

三.Intent Filter
Intent filter內會設定的資料包括action,data與category三種。也就是說filter只會與intent裡的這三種資料做比對動作,而在每個filter內可以同時存在著多個data action與category

雖然每個Intent Filter都屬於IntentFilter類別,但因Android系統在元件啟動錢就必需測試其相容性,所以Intent Filter都是以XML方式寫在AndroidManifest.xml檔內,而不以Java Code去產生。唯一的例外是broadcast receivers的intent filter可以透過Context.registerReceiver()來動態設定

Context.registerReceiver(BroadcastReceiver receiver, IntentFilter filter)
在註冊時,把filter動態加入

Intent Filter內要設定的值,包括action,data與category都定義在Intent Class內,也就是說在Intent物件內設定這3種資料的值與Intent Filter內要設定這3種資料的值都定義在Intent Class內,在JavaCode裡,可以透過Class引用參數,但在Manifest內設定,需要設定字串值,就要去查Class內參數實體的字串值

例:Manifest.xml設定filter
 <intent-filter . . . >  
      <category android:name="android.intent.category.DEFAULT" />  
      <category android:name="android.intent.category.BROWSABLE" />  
      . . .  
 </intent-filter>  

JavaCode設定intent Object的Category
intent.setCategory(Intent.CATEGORY_DEFAULT);

四.Intent Test 找到要接收intent的元件
當intent發出來時,會與元件在Manifest內所定義的intent filter做比對,比對時需進行3個test,當這3個test都通過時,才會確認這元件可以接手處理這Intent。若同時有不只一個的Activity或Service通過Test,那系統會問你要啟動哪一個,若都不符合,則會發生錯誤

五.Intent Test-Action Test
1.當一個intent object若沒有指定Action,則這項pass
2.filter內至少要有一項action,若都沒有就沒有任何intent
  可以通過這filter


 <intent-filter . . . >  
  <action android:name="com.example.project.SHOW_CURRENT" />  
  <action android:name="com.example.project.SHOW_RECENT" />            
      . . .  
 </intent-filter>  

六.Intent Test-Category Test
1.若intent有設定Category,必須intent object可以通過所有filter設定
  的Category,Test才會pass
2.若intent沒有設定Category,則設定pass
3.當執行startActivity()而使用沒有明確設定目標的intent,都會當作他
  至少會有一個Category: Intent.CATEGORY_DEFAULT
  (也就是"android.intent.category.DEFAULT")    

因此若Activity要能夠接收到這intent,則在Mainfest內定義這Activity的intent filter部份需要有Category為"android.intent.category.DEFAULT"的值,才會有可能接收到,也就是說在Manifest內的Activity,至少要有Intent.CATEGORY_DEFAUL(也就是"android.intent.category.DEFAULT")的值,而在已經設定為啟動的Activity內多設定Intent.CATEGORY_DEFAUL,也可以但並無用處

在filter內設定category值,需設定完整字串值,這部份查Intent Class,因為在xml tag接受的值是字串,而在Java Code內設定intent的Category就可以用Class的常數去書寫

七.Intent Test-Data Test
每個data tag都包含了URI與data type (MIME media type)
而URI會以scheme, host, port,與 path來表示
也就是可以把一個完整的URI看成
scheme://host:port/path
若host沒指定,則port可略
data type可以用*代表允許任何型態的資料
如text/*" or "audio/*"

URI為
content://com.example.project:200/folder/subfolder/etc

則設定Filter的寫法為
 <intent-filter . . . >  
      <data android:mimeType="video/mpeg" android:scheme="content" android:host="com.example.project" android:port="200" android:path="folder/subfolder/etc"/>   
      <data android:mimeType="audio/mpeg" android:scheme="http" . . . />  
      . . .  
 </intent-filter>  

data在filter與intent內data比對的原則是
1.當filter內沒有設定任何data tag,而intent內也沒有設定URI與data type,
  那這test就通過
2.當filter有設定URI,沒有設定data type,而intent object也是只有URI沒有
  data type,這時候通過,這通常只會發生在mailto: 與tel: 時
3.當filter內只有設定data type 沒有設定URI,而intent object有設定相同
  的data type無URI則通過
4.當filter內設定的data type與URI都與intent Object內設定的對應即通過
  若filter內只有設定data type而URI不設定,只有在intent Object內的
  data type有對應,而URI為content: 或file:才會通過

八.Example
1.設定元件可以顯示local端 任何Image檔案
 <data android:mimeType="image/*" />  
當要由local contentProvider顯示檔案,這樣寫即可,不需再指定URI部份用content:或file:
2.設定允許播放來自internet的任何影片檔
 <data android:scheme="http" android:type="video/*" />  
當使用者透過web page連結要開啟一個資源,會先使用html page開啟看看,若不行,則會與未指定對象
的intent一樣,去查找哪一個Activity適合去開啟這個資源,若不知道,則會開啟Download Manager去下載
3.設定啟動預設執行的Activity
 <intent-filter . . . >  
      <action android:name="code android.intent.action.MAIN" />  
      <category android:name="code android.intent.category.LAUNCHER" />  
 </intent-filter>  
不需透過任何intent去觸發,在開啟App即會自動執行這個Activity

九.Intent與Intent Filter
Intent Filter的作用,不僅是找出intent所要啟動的元件,還包括了設定元件該出現在Device的相關訊息
例如在Filter內設定了
"android.intent.action.MAIN"與"android.intent.category.LAUNCHER"
這元件會出現在device最上層的Launch清單上

若元件的filter設定了android.intent.category.HOME"
那這元件就會顯示在Home screen上

利用PackageManager Class的相關method針對指定intent找出適合的元件
透過query..() method可以讓你找到可以接收指定intent的component
透過resolve..()可以找到最適合接收指定intent的component
例如queryIntentActivities()可以取得所有適合的Activity清單

2010年10月20日 星期三

Android Intent物件

一.說明
在Android內三個核心元件activities, services, and broadcast receivers,都是靠Intents傳遞訊息來啟動

1.啟動Activity
透過將intent放到 Context.startActivity(intent) 或 Activity.startActivityForResult(intent)內來啟動Activity,或取得一個已存在的Activity去執行。另外可透過Activity.setResult(resultCode,intent)取得由呼叫Activity.startActivityForResult()所回傳的資訊

2.啟動Service
透過放intent到Context.startService(intent),去初始化啟動一個Service,亦可將intent傳給Context.bindService(intent),建立元件與service的連線。

3.發布給Broadcast Receivers
將intent物件傳給任何broadcast methods,可以發布給所有有興趣的broadcast receivers,例如Context.sendBroadcast(), Context.sendOrderedBroadcast(), or Context.sendStickyBroadcast()

當有intent被發出時(以上3種方式),Android會找到適合的物件回應這intent,也就是說屬於broadcast的不會去處發到service,而透過startActivity()傳遞的intent只會被Activity接收到

二.Intent Object
intent物件是一個資訊包,他包括了要接收到這intent的元件所會有興趣的資料,如要執行哪些動作,要用到哪些資料
與Android系統所會有興趣的資料,如哪些類別的元件要來接收這intent,與要如何去啟動目標的Activity
一個Intent物件包含以下資訊

1.Component name:ComponentName Class,非必填
指定需要去處理這個intent的Component,這欄位資料為ComponentName 類別,包括這元件的完整class名稱(如com.oz.)與註冊在manifest內的Applcation package name,可利用 setComponent(), setClass(), or setClassName()寫入,用getComponent()讀取

ComponentName cn=intent.getComponent();
cn.getClassName()

2.Action:String,非必填
指定這intent要執行的動作,在Intent Class內已經定義好幾個const代表要執行的動作

ACTION_CALL:初始化phone call
ACTION_EDIT:顯示資料讓使用者編輯
可透過setAction() 設定,利用getAction()讀取,若要使用自己定義的Action sring,使用時需加完整的package路徑
如"com.example.project.SHOW_COLOR"

3.Data:,非必填
包含資料的URI與資料的MIME type,不同的Action會需要不同的data type,譬如說
當action是設定Action_EDIT,data欄位會是需要要編輯的文件URI
當action是設定ACTION_CALL,data欄位將會是一個 tel:電話號碼的URI
當action是設定ACTION_VIEW,data欄位會是http:的URI
接收到的Activity就會去下載顯示這URI

當Activity去處理這些data時,會需要知道他的MIME Type才知道要如何處理
譬如說image檔案就不會有play功能出現

大多數都能由URI去猜測data type,譬如說,content: 的URI,資料會是在device上,可利用setData() setType() setDataAndType()來設定,而利用getData() and the type by getType()來讀取

4.Category: string Set,非必填
設定那一類型的元件可以去處理這個intent,在一個intent內可以放多個Category
以下已經預定的常數為
1.CATEGORY_BROWSABLE:target Activity可以被browswer開啟,
  如email或image
2.CATEGORY_GADGET:這Activity可以嵌在這GADGET的另一個
  Activity內
3.CATEGORY_HOME:Activity會顯示在使用者開啟device的第
  一個畫面,也就是Home按鈕開啟的畫面上
4.CATEGORY_LAUNCHER:Activity會被列在最上層的launcher上
5.CATEGORY_PREFERENCE:target Activity是preference panel
  也就是屬於preference panel才能處理接收這intent 

透過addCategory()加入,透過removeCategory()移除,透過getCategories()取得SET

5.Extras:Bundle類別,非必填
intent要傳遞給元件的其他資訊,會以Key-value pairs型態存在,有一些intent個別會有一些特別的extra資料存在
例如
ACTION_TIMEZONE_CHANGED 會有一個extra 'time-zone',值是最新的time zone
ACTION_HEADSET_PLUG有 'state' 值為"plugged"或"unplugged"
SHOW_COLOR 會有'color' 值為色碼值
可透過一系列的putXXXExtra()設定,getXXXExtra()取得
或用putExtra(Bundle)設定 getExtra()設定取得

在intent裡加入Extra有很多方式
可以先產生一個Bundle物件,把所有要加入的值都放到Bundle內
再利用intent.putExtra(bundle)放進去
也可以利用intent.putExtra(string key,string value)加入
putExtra可以呼叫多次,所有加入的值都會被累加到extra物件上
不管加入多少,都可以透過
如 intent.getExtras().getString(stringKey)方式取得資料

6.Flags:String,非必填
通知Android系統如何去啟動這Activity,例如要把這Activity加入到哪個Task內(或是啟動一個新的Task)在Intent Class內已經建好這些相關常數

Android Resources 資源檔-使用(三)

resourceID的值由兩個部份組成type(如string)與name(如hello)
取得Resource的方式
一.在Java Code中使用resource
1.取得resourceID的語法為
package_name.R.resource_type.resource_name
若在自己專案內package_name可以不用寫

R.string.hello
android.R.color.secondary_text_dark
2.取得Resource Class
利用 Context.getResources()取得Resource Class
再利用Resource提供的各項method來取得各類型的resource
3.範例
例1:
Resources res=Context.getResources();
String str=res.getString(R.string.hello)
例2:
TextView.setText(rsid:int)就可直接使用,用自己找出resources
例3:
imageView.setImageResource(R.drawable.myimage);
二.在XML中使用resource
1.取得resourceID的語法為
@package_name:resource_type/resource_name
如果是在自己專案內的resource就不用寫package_name
在tag內將resourceID指定給tag,tag即會利用resourceID取得資源
2.使用sttle的語法為
?package_name:resource_type/resource_name

2.範例
例1:
 <?xml version="1.0" encoding="utf-8"?>  
 <EditText xmlns:android="http://schemas.android.com/apk/res/android"  
      android:layout_width="fill_parent"  
      android:layout_height="fill_parent"  
      android:textColor="@android:color/secondary_text_dark"  
      android:text="@string/hello" />       
以上範例,textColor用到android內建的資源,所以用@android:color/secondary_text_dark
而text用到是自己專案內的資源,所以用@string/hello
例2:
 <EditText id="text"  
           android:layout_width="fill_parent"  
           android:layout_height="wrap_content"  
           android:textColor="?android:textColorSecondary"  
           android:text="@string/hello_world" />       

三.使用系統內建resource
若要使用系統預設的resource,可用android.R取得
注意:R是本身專案的resource檔案,而android.R是系統提供的預設resource檔


四.執行過程中的異動
當使用者的Device在使用過程中做了變動,譬如說,旋轉或改變語系,系統會因為這樣的改變而將正在進行的Activity進行onDestroy(),然後進行onCreate()重新顯示以套用新的改變。
而在進行onDestroy()前會進行資料儲存動作,好讓重新建立後可以回復資料,其流程如下
onSaveInstanceState()->onDestroy()->onCreate()->onRestoreInstanceState()
其執行方式有以下兩種方式,各有優缺點
1.保留資訊,自動重新啟動
當config改變發生時,允許Activity在自動restart,並把狀態資料帶到Activity新的instance上,若要重新建立新的instance,如果資料來源是來自網路,可能會因為重新建立連線而發生更久的時間。
通常用來儲存狀態用的都是bundle物件,但bundle物件並不適合儲存大量資料(如點陣圖),所以在runtime時要保留資料會是用以下作法
1.Override onRetainNonConfigurationInstance()回傳你要儲存
  的物件,onRetainNonConfigurationInstance()會發生在
  onStop()與onDestroy()之間
2.當create後呼叫getLastNonConfigurationInstance()取回物件

儲存
@Override
public Object onRetainNonConfigurationInstance() {
    final MyDataObject data = collectMyLoadedData();
    return data;
}    
取回
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    final MyDataObject data = (MyDataObject) getLastNonConfigurationInstance();
    if (data == null) {
        data = loadMyData();
    }
    ...
}    
2.取得通知,自己手動處理改變的訊息
當config改變發生時,只發出相關通知,讓使用者自己決定是否要restart,為了效能考量,在部份config發生改變時,並不自動restart Activity,就需要使用者自己手動去處理外觀異動的部份,而無法享受到使用衍生res所帶來的方便
作法如下:
1.先在Manifest內設定Activity要監聽哪些事件變化
2.覆寫onConfigurationChanged(),當有config改變時,
  這裡會接收到新的config物件

manifest.xml
 <activity android:name=".MyActivity"  
       android:configChanges="orientation|keyboardHidden"  
       android:label="@string/app_name">  

Activity內
@Override
public void onConfigurationChanged(Configuration newConfig) {
    super.onConfigurationChanged(newConfig);
    // Checks the orientation of the screen
    if (newConfig.orientation == Configuration.ORIENTATION_LANDSCAPE) {
        Toast.makeText(this, "landscape", Toast.LENGTH_SHORT).show();
    } else if (newConfig.orientation == Configuration.ORIENTATION_PORTRAIT){
        Toast.makeText(this, "portrait", Toast.LENGTH_SHORT).show();
    }
    // Checks whether a hardware keyboard is available
    if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_NO) {
        Toast.makeText(this, "keyboard visible", Toast.LENGTH_SHORT).show();
    } else if (newConfig.hardKeyboardHidden == Configuration.HARDKEYBOARDHIDDEN_YES) {
        Toast.makeText(this, "keyboard hidden", Toast.LENGTH_SHORT).show();
    }
}    

Android Resources 資源檔-Sample與使用範例(二)

一.anim/:XML檔案
定義所有的tween動畫
例:res/anim/hyperspace_jump.xml
 <set xmlns:android="http://schemas.android.com/apk/res/android"  
      android:shareInterpolator="false">  
      <scale  
           android:interpolator="@android:anim/accelerate_decelerate_interpolator"  
           android:fromXScale="1.0"   
           android:toXScale="1.4"   
           android:fromYScale="1.0"   
           android:toYScale="0.6"   
           android:pivotX="50%"  
           android:pivotY="50%"  
           android:fillAfter="false"  
           android:duration="700" />  
      <set  
           android:interpolator="@android:anim/accelerate_interpolator"  
           android:startOffset="700">  
           <scale  
                android:fromXScale="1.4"   
                android:toXScale="0.0"  
                android:fromYScale="0.6"  
                android:toYScale="0.0"   
                android:pivotX="50%"   
                android:pivotY="50%"   
                android:duration="400" />  
           <rotate  
                android:fromDegrees="0"   
                android:toDegrees="-45"  
                android:toYScale="0.0"   
                android:pivotX="50%"   
                android:pivotY="50%"  
                android:duration="400" />  
      </set>  
 </set>  
在Java內使用動畫
ImageView image = (ImageView) findViewById(R.id.image);
Animation hyperspaceJump = AnimationUtils.loadAnimation(this, R.anim.hyperspace_jump);
image.startAnimation(hyperspaceJump);

二.color/:XML檔案
定義colors state list,也就是以一個物件的方式設定在各種狀態時的color變化,如button會有各種state的color變化,可將這樣的color state設定成xml
例:res/color/button_text.xml:
 <?xml version="1.0" encoding="utf-8"?>  
 <selector xmlns:android="http://schemas.android.com/apk/res/android">  
      <item android:state_pressed="true"  
            android:color="#ffff0000"/> <!-- pressed -->  
      <item android:state_focused="true"  
            android:color="#ff0000ff"/> <!-- focused -->  
      <item android:color="#ff000000"/> <!-- default -->  
 </selector>  
在XML Layout上套用到Button上
 <Button  
 android:layout_width="fill_parent"  
 android:layout_height="wrap_content"  
 android:text="@string/button_text"  
 android:textColor="@color/button_text" />  

三.drawable/:bitmap檔案
包括(.png .9.png .jpg .gif),或透過XML檔案所描述的圖形,
如State lists,Color drawables,Shapes

四.layout/:XML檔案
定義使用者使用介面的layout,每一個Layout會相當於我們看到的一個page

五.menu/:XML檔案
定義該App的menu,例如Options Menu, Context Menu, or Sub Menu
例:res/menu/example_menu.xml:
 <menu xmlns:android="http://schemas.android.com/apk/res/android">  
      <item android:id="@+id/item1"  
            android:title="@string/item1"  
            android:icon="@drawable/group_item1_icon" />  
      <group android:id="@+id/group">  
           <item android:id="@+id/group_item1"  
                 android:title="@string/group_item1"  
                 android:icon="@drawable/group_item1_icon" />  
           <item android:id="@+id/group_item2"  
                 android:title="G@string/group_item2"  
                 android:icon="@drawable/group_item2_icon" />  
      </group>  
      <item android:id="@+id/submenu"  
            android:title="@string/submenu_title" >  
           <menu>  
                <item android:id="@+id/submenu_item1"  
                      android:title="@string/submenu_item1" />  
           </menu>  
      </item>  
 </menu>  
在Activity的Java內使用
public boolean onCreateOptionsMenu(Menu menu) {
  MenuInflater inflater = getMenuInflater();
  inflater.inflate(R.menu.example_menu, menu);
  return true;
}

六.raw/:任意檔案用他原本的資料格式儲存
系統不會對檔案做壓縮處理,要開啟這些檔案的InputStream,要透過Resources.openRawResource()呼叫該resourceID(R.raw.filename)取得,若是希望透過原始檔名來取得檔案,建議可以把檔案存在/assets/目錄下
在/assets/目錄下的檔案是沒有resourceID的,都是透過AssetManager來存取

七.values/:XML檔案
包含一些簡單的值設定,如string,color,style,通常會把同類型的寫在一個檔案內
1.arrays.xml

 <?xml version="1.0" encoding="utf-8"?>  
 <resources>  
      <array name="icons">  
           <item>@drawable/home</item>  
           <item>@drawable/settings</item>  
           <item>@drawable/logout</item>  
      </array>  
      <array name="colors">  
           <item>#FFFF0000</item>  
           <item>#FF00FF00</item>  
           <item>#FF0000FF</item>  
      </array>  
 </resources>  

JAVA使用
Resources res = getResources();
TypedArray icons = res.obtainTypedArray(R.array.icons);
Drawable drawable = icons.getDrawable(0);
TypedArray colors = res.obtainTypedArray(R.array.icons);
int color = colors.getColor(0,0);
2.colors.xml

 <?xml version="1.0" encoding="utf-8"?>  
 <resources>  
   <color name="opaque_red">#f00</color>  
   <color name="translucent_red">#80ff0000</color>  
 </resources>  

JAVA使用
Resources res = getResources();
int color = res.getColor(R.color.opaque_red);

XML使用
 <TextView  
 android:layout_width="fill_parent"  
 android:layout_height="wrap_content"  
 android:textColor="@color/translucent_red"  
 android:text="Hello"/>  
3.dimens.xml

 <?xml version="1.0" encoding="utf-8"?>  
 <resources>  
      <dimen name="textview_height">25dp</dimen>  
      <dimen name="textview_width">150dp</dimen>  
      <dimen name="ball_radius">30dp</dimen>  
      <dimen name="font_size">16sp</dimen>  
 </resources>  

Java使用
Resources res = getResources();
float fontSize = res.getDimension(R.dimen.font_size);

XML使用
 <TextView  
 android:layout_height="@dimen/textview_height"  
 android:layout_width="@dimen/textview_width"  
 android:textSize="@dimen/sixteen_sp"/>  
4.string.xml

 <?xml version="1.0" encoding="utf-8"?>  
 <resources>  
      <string name="hello">Hello!</string>  
 </resources>  

JAVA使用
String string = getString(R.string.hello);

XML使用
 <TextView  
 android:layout_width="fill_parent"  
 android:layout_height="wrap_content"  
 android:text="@string/hello" />  
5.style.xml

 <?xml version="1.0" encoding="utf-8"?>  
 <resources>  
      <style name="CustomText" parent="@style/Text">  
           <item name="android:textSize">20sp</item>  
           <item name="android:textColor">#008</item>  
      </style>  
 </resources>  

XML使用
 <?xml version="1.0" encoding="utf-8"?>  
 <EditText  
      style="@style/CustomText"  
      android:layout_width="fill_parent"  
      android:layout_height="wrap_content"  
      android:text="Hello, World!" />  

八.xml/:任何其他的xml檔案放在這目錄
以Resource.getXML()讀取,各式的XML設定檔config都放在這目錄下

Android Resources 資源檔-基本概念(一)

一.說明
在Android下會需要用到的各種資源都會放在res/目錄下,包括版面,圖片,文字字串,資料陣列,顏色...等各式實體內容都會放在這目錄下,而在res/下主要了包含以下8個目錄,分別代表8種不同類型的resource
1.anim/:XML檔案,ㄐ定義所有的tween動畫
2.color/:XML檔案,定義colors state list,也就是以一個物件的
  方式設定在各種狀態時的color變化
3.drawable/:bitmap檔案,包括(.png .9.png .jpg .gif)
4.layout/:XML檔案,定義使用者使用介面的layout
5.menu/:XML檔案,定義該App的menu,例如Options Menu, Context Menu, or Sub Menu
6.raw/:任意檔案用他原本的資料格式儲存
7.values/:包含一些簡單的值設定,如string,color,style
8.xml/:任何其他的xml檔案放在這目錄

二.作業原理
在Android將整個專案Compile時,會將所有在res/目錄下的資源都會被Compile成一個R Class,而在res下的各種類型,則會成為R的subClass 如R.string R.drawable都是一個 class 。所以透過R Class可以讓你直接找到資源的resourceID,再利用resourceID來取到resource實體內容。無論資料內容是任何類型的資料,resourceID都只是個int值,而非實體資料內容,要取得實體內容,都需要依照要取得的resource類型,透過resourceID來取得
例如
在res/values/strings.xml內有一筆
 <string name='hello'>測試</string>  
因此R.string.hello即是這筆資料的resourceID,透過getString()才能取得真正的內容
String string = getString(R.string.hello);

三.R下SubClass
R下面的subclass,並非由各目錄的名稱或xml檔案名稱所訂,而是對應到資料類型。譬如說R.string這個次類別,string是來自於strings.xml內有tag,至於這tag所依附的xml檔名,是可以任意的設定(並非一定要設成strings.xml)
也可以把不同類型的資料放到同一個xml檔案內,只是通常會把相同資源放在同一個xml檔案內,方便管理

四.res下更多的衍生類別目錄
除了標準的八種類型目錄外,在res下可以看到更多的其他衍生出來的目錄。
譬如說有layout/ 也可看到layout-land/目錄,這些衍生出來的目錄,都是因應可以讓你開發的應用程式,可以因偵測到使用者device的條件不同,而提供有不同的使用介面與設定,包括解析度尺寸不同,或多語系,都可設定各自的顯視介面,這些目錄名稱的命名都是有規則的,在規則性的命名下,Android系統即會自動判斷要取用哪個目錄下的資源,來顯示在使用者的Device上

例如
在res/下除了有一個 layout/目錄提供標準的版面給使用者外,另外還有一個layout-land/目錄提供給橫向螢幕使用,也就是說當使用者以直式使用時,畫面上是以layout/目錄下的設定來顯示,當使用者把device轉向成橫式時,就會自動切換到以layout-land/目錄下的設定顯示

五.res衍生目錄命名規則
目錄名稱命名方式為resources_name-config_qualifier
resources_name:即原來資源類型的名稱,如string,color,array,...
config_qualifier:依照各類型資源各有不同的值可用
例如:
以Screen orientation螢幕方向來分,config_qualifier允許的值為port直,land橫
res/layout:一般標準layout
res/layout-land:針對橫向時用的layout

幾個常見的config_qualifier包括

1.Language:用來儲存依照不同語系地區所提供的resource
  例 值:en ,fr,tw,cn
  產生的目錄會是
  values-tw/
2.Screen size:螢幕解析度
  值:small,normal,large
3.Wider/taller screens:螢幕形狀,長形或一般
  值:long,notlong
4.Screen orientation:螢幕是直式或橫式
  值:port直,land橫
5.Dock mode:一般或車上模式 
可以用多個config_qualifier串接如 drawable-port-hdpi/,但順序需依照規格書內列表的順序描述

六.res衍生目錄需要用到重複資源的處理方式
當有一份resource(例如圖檔),要給多種設定檔使用,可以不用copy到每個folder各有一份,只需要建立Alias即可,並非所有resource都可提供Alias機制,如animation, menu, raw, 與其他在xml/ 目錄下的都不行
1.drawable 圖檔
例:如果有一張圖檔icon.png原本放在drawable目錄下,要給多個設定檔使用
但又不希望直接copy檔案到各目錄

1.將icon.png rename為 icon_oz.png(只要不是原檔名就好)
將檔案放到drawable/目錄下
2.產生一個icon.xml檔案
 <?xml version="1.0" encoding="utf-8"?>  
 <bitmap xmlns:android="http://schemas.android.com/apk/res/android"  
      android:src="@drawable/icon_oz" />  
放到各drawable-xxx/目錄下
3.使用上用
R.drawable.icon可取得
2.layout
例:有一份layout要提供多個設定檔使用
1.將原layout main.xml 改名為main_oz.xml
放到res/layout/
2.產生一個main.xml
 <?xml version="1.0" encoding="utf-8"?>  
 <merge>  
      <include layout="@layout/main_oz"/>  
 </merge>  
放到各目錄下
3.使用上
R.layout.main
3.string或其他
在要alias的項目填上對應資料即可
 <?xml version="1.0" encoding="utf-8"?>  
 <resources>  
      <string name="hello">Hello</string>  
      <string name="hi">@string/hello</string>  
 </resources>  

2010年10月19日 星期二

Android基本概念

一.基本概念
Android Application是使用Java開發,compile成Java code,再利用Appt Tool將相關的resource包裝成apk檔,讓使用者可以下載安裝到他的device上,每個Application會以下列方式在系統執行。
1.每個App跑自己獨立的Linux Process,在不使用時關閉
2.每個Process有自己的VM,所以Ap是在一個完全隔離的環境下運作
3.預設每個App指定一個唯一的Linux user ID,App file只允許該
  App與該User使用,若要讓不同的App共用資料則要設定相同的
  User ID

二.元件
Android一個相當重要的特性是,每個App內包含了許多的元件,每個元件的功能都可以提供其他的App使用,你所開發的App想要使用其他App已經開發好的功能元件,不需要在程式內全部包進來或是去link它,也就是說系統會自行判斷,可以任何需要的時候去啟動任何Application的任何部份功能。

Android App並沒有一個單一的程式進入點(如main()),而是存在著以下四種元件,在必要時就實體化來使用執行
1.Activities
    每個Activity都繼承自Activity Class。
    Activity負責提供使用者介面讓使用者操作與互動。
    一個App可以包含一到多個Activity,在App起始時啟動,一個
    Activity,再由已開啟的Activity去開啟其他的Activity。
    每個Activity都會包含一個Window用來顯示畫面,預設window會
    填滿整個screen(手機),但window可以設定的更小或浮動在其他
    window上,例如popup window,window上所放的物件都是繼承自
    View Class,每個view都佔據著window內的一個矩形區塊,上層
    的view負責其子元素的layout安排,而最底層的child view則負
    責直接回應使用者的動作與輸入,利用Activity.setContentView()
    設定Activity最上層使用的View
    
2.Services
    Service提供一個可以在背景定時執行,無使用者介面的服務。
    譬如說在背景播放音樂,或是在internet上取得資料提供給
    Activity使用。    
    
3.Broadcast receivers
    繼承自BroadcastReceiver Class
    Broadcast receiver 是用來接收廣播的訊息並做回應,許多的
    廣播是來自於系統,譬如說時區改變、電池電力不足或使用者改
    變語系等,另外廣播也可來自於App的其他元件所發出來,例如
    App在下載完資料可以提供給其他App使用時,可以透過廣播讓其
    他App的Broadcast receiver可以接收到並使用
    
    Broadcast receiver沒有UI,但他可啟動Activity去顯示回應,
    或使用NotificationManager去提示使用者。
    Notification可以是device振動、或是閃爍...播放音效等可以
    吸引使用者注意,通常都會在螢幕上放一個icon,當Broadcast
    receiver接收到訊息要提示使用者,可以用NotificationManager
    讓icon有所變化    
    
4.Content providers
    繼承自ContentProvider
    Content provider提供可以讓其他App使用的data,data可以用
    file或sqlite形式儲存,提供讓其他App可以讀取與儲存資料的
    方法。App並不能直接呼叫ContentProvider的method,而是需要
    透過ContentResolver物件來呼叫ContentProvider。
    ContentResolver可以跟任何的ContentProvider做溝通,利用他
    來管理內部程序上的溝通

三.使用intent啟動元件
除了ContentProvider是透過ContentResolver來驅動使用外,其他三種元件的啟動都是透過Intent來啟動,一個intent物件是包含了要執行的內容資訊。對activities 與 services來說,intent包含了要執行的action與要用的data URI,譬如開啟圖片的連結位置等資訊,對Broadcast receiver來說,包含了要發布的action,例如當相機按鈕被按下時,將這按下按鈕的訊息發布給接收者

以下是各種元件的啟動方式
1.Activity
    透過傳遞intent物件給Context.startActivity()來啟動。接收
    到這intent的Activity,在Activity內可以透過getIntent()取
    得該intent資料。    
    一個Activity通常是由另一個Activity所觸發,如果在觸發的
    Activity後想要得到回傳資料,則改用
    Activity.startActivityForResult()來啟動Activity。
    例如要啟動另一個Activity讓使用者可以選取圖片,當使用者
    選好後,希望把選好的圖片回傳回來,回傳的資料會是用intent
    物件被回傳到原呼叫者的onActivityResult()內
2.Service
    透過傳遞intent到 Context.startService()內或是呼叫Service
    的onStart()來啟動Service。
    同樣的可以將intent傳給Context.bindService()在元件與Service
    間建立一個持續性的連線,當建立連線時,系統即會自動觸發
    Service內的onBind(),同時把intent物件丟給onBind(),若在呼
    叫onBind時,若還沒建立連線,則會自動呼叫bindService()建立,
    接下來就可以使用Service本身的method來用
3.Broadcast receiver
     透過傳遞intent到Context.sendBroadcast()、Context.sendOrderedBroadcast(),
     與Context.sendStickyBroadcast(),就可以把intent包好的訊息
     廣播出去,系統就會自動觸發有興趣的Broadcast receiver內部的
     onReceive(),同時onReceive()會接收到這個intent物件在做後續
     的處理程序    

四.關閉元件
ContentProvider只回應ContentResolver的需求,Broadcast receiver只在回應廣播時啟動,所以這兩種元件都不需要手動去關閉它,需要被關閉的元件只有Activity與Service。
1.Activity本身可透過finish()來關閉,而要關閉其他的Activity,
  例如利用startActivityForResult(),所啟動的Activity可以利用
  finishActivity()來關閉其他Activity
2.service本身可以透過stopSelf()關閉,或由外部透過
  Context.stopService()關閉,當元件已經不再被使用或當系統記
  憶體不足時會被強制關閉
五.manifest設定檔
一個Android程式包含了許多的元件還有resource檔案,在Android使用之前,需先確認資料的存在,每個App內都會有一個結構性的描述檔 AndroidManifest.xml,包含了包括activity,service,receiver,provider 等元素宣告,activity,service,provider若沒宣告在manifest檔案內,在系統內是無法使用的,只有receiver除了可以宣告在manifest內,也可以透過Context.registerReceiver()動態產生註冊到系統內

2010年10月1日 星期五

Air File實體檔案路徑

在開發AIR專案,如果需要利用File對使用者端做檔案存取
取得需要的實體檔案路徑,需要透過File的static變數來取得
以下是各變數所對應在Windows下的實體檔案位置

1.File.userDirectory:使用者目錄
C:\Documents and Settings\username

2.File.applicationDirectory:AIR APP執行檔所在路徑
D:\MyAirApp
3.File.applicationStorageDirectory:使用者本機可供該AIR應用程式,儲存資料的路徑
C:\Documents and Settings\username\Application Data\MyAirApp\Local Store

4.File.desktopDirectory:使用者桌面
C:\Documents and Settings\username\桌面

5.File.documentsDirectory:使用者我的文件資料夾
C:\Documents and Settings\username\My Documents