1. 程式人生 > >Android中的context、activity、intent、service使用詳解

Android中的context、activity、intent、service使用詳解

在一個Android應用中,主要是由四種元件組成的,這四種元件分別是Context,Activity,Intent,Service。

Content被譯為上下文,是應用程式中心,應用程式所有功能可以通過他訪問。Activity活動,可以理解為視窗,是人機互動的核心,所以又被人們說成是所有程式的根本。Intent意圖,負責所有Activity視窗通訊。Service服務是相對Activity來說的,不需要人機互動,但可以為Activity提供互動必需要的一些東西。這四種元件是獨立的,它們之間可以互相呼叫,協調工作,最終組成一個真正的Android應用。

1.context ,用來獲得應用程式資訊。Context位於framework package的android.content.Context中,其實該類為LONG型,類似Win32中的Handle控制代碼。很多方法需要通過 Context才能識別呼叫者的例項:比如說Toast的第一個引數就是Context,一般在Activity中我們直接用this代替,代表呼叫者的例項為Activity,如:Button myButton =newButton(this);這裡的this就是Context,而到了一個button的onClick(Viewview)等方法時,我們用this時就會報錯,所以我們可能使用ActivityName.this來解決,主要原因是因為實現Context的類主要有Android特有的幾個模型。

a:在文件中宣告如下,方法非常豐富。

// 編譯自ContextWrapper.java (版本 1.5:49.0,超級位)

public class android.content.ContextWrapper extendsandroid.content.Context {

  publicContextWrapper(android.content.Context base);

  protected voidattachBaseContext(android.content.Context base);

  public android.content.ContextgetBaseContext();

  public android.content.res.AssetManagergetAssets();

  publicandroid.content.res.Resources getResources();

  publicandroid.content.pm.PackageManager getPackageManager();

  publicandroid.content.ContentResolver getContentResolver();

  public android.os.LoopergetMainLooper();

  public android.content.ContextgetApplicationContext();

  public void setTheme(int resid);

  publicandroid.content.res.Resources.Theme getTheme();

  public java.lang.ClassLoadergetClassLoader();

  public java.lang.StringgetPackageName();

  public android.content.pm.ApplicationInfogetApplicationInfo();

  public java.lang.StringgetPackageResourcePath();

  public java.lang.StringgetPackageCodePath();

  publicandroid.content.SharedPreferences getSharedPreferences(java.lang.String name,int mode);

  public java.io.FileInputStreamopenFileInput(java.lang.String name) throws java.io.FileNotFoundException;

  public java.io.FileOutputStreamopenFileOutput(java.lang.String name, int mode) throwsjava.io.FileNotFoundException;

  public boolean deleteFile(java.lang.Stringname);

  public java.io.FilegetFileStreamPath(java.lang.String name);

  public java.lang.String[]fileList();

  public java.io.File getFilesDir();

  public java.io.FilegetExternalFilesDir(java.lang.String type);

  public java.io.File getObbDir();

  public java.io.File getCacheDir();

  public java.io.FilegetExternalCacheDir();

  public java.io.FilegetDir(java.lang.String name, int mode);

   publicandroid.database.sqlite.SQLiteDatabase openOrCreateDatabase(java.lang.Stringname, int mode, android.database.sqlite.SQLiteDatabase.CursorFactoryfactory); 

  publicandroid.database.sqlite.SQLiteDatabase openOrCreateDatabase(java.lang.Stringname, int mode, android.database.sqlite.SQLiteDatabase.CursorFactory factory,android.database.DatabaseErrorHandler errorHandler);

  public booleandeleteDatabase(java.lang.String name);

  public java.io.FilegetDatabasePath(java.lang.String name);

  public java.lang.String[] databaseList();

public android.content.ComponentNamestartService(android.content.Intent service);

public android.content.ContextcreatePackageContext(java.lang.String packageName, int flags) throwsandroid.content.pm.PackageManager$NameNotFoundException;

public android.content.IntentregisterReceiver(android.content.BroadcastReceiver receiver,android.content.IntentFilter filter

public android.content.IntentregisterReceiver(android.content.BroadcastReceiver receiver,android.content.IntentFilter filter, java.lang.String broadcastPermission,android.os.Handler scheduler);

public android.graphics.drawable.DrawablegetWallpaper();

publicandroid.graphics.drawable.Drawable peekWallpaper();

public booleanbindService(android.content.Intent service, android.content.ServiceConnectionconn, int flags);

public boolean isRestricted();

public booleanstartInstrumentation(android.content.ComponentName className, java.lang.StringprofileFile, android.os.Bundle arguments);

public booleanstopService(android.content.Intent name);

public intcheckCallingOrSelfPermission(java.lang.String permission);

public intcheckCallingOrSelfUriPermission(android.net.Uri uri, int modeFlags);

public intcheckCallingPermission(java.lang.String permission);

public intcheckCallingUriPermission(android.net.Uri uri, int modeFlags);

public intcheckPermission(java.lang.String permission, int pid, int uid);

public intcheckUriPermission(android.net.Uri uri, int pid, int uid, int modeFlags);

public intcheckUriPermission(android.net.Uri uri, java.lang.String readPermission,java.lang.String writePermission, int pid, int uid, int modeFlags);

public intgetWallpaperDesiredMinimumHeight();

public intgetWallpaperDesiredMinimumWidth();

public java.lang.ObjectgetSystemService(java.lang.String name);

public void clearWallpaper() throwsjava.io.IOException;

public void enforceCallingOrSelfPermission(java.lang.Stringpermission, java.lang.String message);

public voidenforceCallingOrSelfUriPermission(android.net.Uri uri, int modeFlags,java.lang.String message);

public voidenforceCallingPermission(java.lang.String permission, java.lang.Stringmessage);

public voidenforceCallingUriPermission(android.net.Uri uri, int modeFlags,java.lang.String message);

public voidenforcePermission(java.lang.String permission, int pid, int uid,java.lang.String message);

public void enforceUriPermission(android.net.Uriuri, int pid, int uid, int modeFlags, java.lang.String message);

public voidenforceUriPermission(android.net.Uri uri, java.lang.String readPermission,java.lang.String writePermission, int pid, int uid, int modeFlags,java.lang.String message);

public voidgrantUriPermission(java.lang.String toPackage, android.net.Uri uri, intmodeFlags);

public voidremoveStickyBroadcast(android.content.Intent intent);

public voidrevokeUriPermission(android.net.Uri uri, int modeFlags);

public void sendBroadcast(android.content.Intentintent);

public voidsendBroadcast(android.content.Intent intent, java.lang.StringreceiverPermission);

public voidsendOrderedBroadcast(android.content.Intent intent, java.lang.StringreceiverPermission);

public void sendOrderedBroadcast(android.content.Intentintent, java.lang.String receiverPermission, android.content.BroadcastReceiverresultReceiver, android.os.Handler scheduler, int initialCode, java.lang.StringinitialData, android.os.Bundle initialExtras);

public void sendStickyBroadcast(android.content.Intentintent

public voidsendStickyOrderedBroadcast(android.content.Intent intent,android.content.BroadcastReceiver resultReceiver, android.os.Handler scheduler,int initialCode, java.lang.String initialData, android.os.BundleinitialExtras);

public voidsetWallpaper(android.graphics.Bitmap bitmap) throws java.io.IOException;

public voidsetWallpaper(java.io.InputStream data) throws java.io.IOException;

public voidstartActivities(android.content.Intent[] intents);

public voidstartActivity(android.content.Intent intent);

public voidstartIntentSender(android.content.IntentSender intent, android.content.IntentfillInIntent, int flagsMask, int flagsValues, int extraFlags) throwsandroid.content.IntentSender$SendIntentException;

public voidunbindService(android.content.ServiceConnection conn);

public voidunregisterReceiver(android.content.BroadcastReceiver receiver);

}

B:Context提供了關於應用環境全域性資訊的介面。它是一個抽象類,它的執行被Android系統所提供。它允許獲取以應用為特徵的資源和型別。同時啟動應用級的操作,如啟動Activity,broadcasting和接收intents。

C:我們最常用的是其中的GET方法,通過這些get方法可以獲取應用環境全域性資訊:

1.public abstract Context getApplicationContext() 
返回應用的上下文,生命週期是整個應用,應用摧毀它才摧毀 

2.publicabstract ApplicationInfo getApplicationInfo() 
返回上下文包資訊.

如:   //得到application物件

  ApplicationInfo appInfo = getApplicationInfo();

  //得到該圖片的id(name 是該圖片的名字,"drawable" 是該圖片存放的目錄,appInfo.packageName是應用程式的包)

  int resID = getResources().getIdentifier(name, "drawable",appInfo.packageName);

3.public abstractContentResolver getContentResolver() 
為包返回一個內容解析器

4.public abstractPackageManager getPackageManager() 
獲得資源包資訊,常用於獲取安裝資訊,
如:
ArrayList appList = new ArrayList(); //用來儲存獲取的應用資訊資料

List packages= getPackageManager().getInstalledPackages(0);

for(inti=0;PackageInfo packageInfo = packages.get(i);

AppInfotmpInfo = new AppInfo();

tmpInfo.appName= packageInfo.applicationInfo.loadLabel(getPackageManager()).toString();

tmpInfo.packageName= packageInfo.packageName;

tmpInfo.versionName= packageInfo.versionName;

tmpInfo.versionCode= packageInfo.versionCode;

tmpInfo.appIcon= packageInfo.applicationInfo.loadIcon(getPackageManager());

appList.add(tmpInfo);

}

5.public abstractString getPackageName() 
獲得包名

6.public abstractResources getResources() 
獲得包資源例項

7.public abstractSharedPreferences getSharedPreferences(Stringname, int mode) 
獲得SharedPreferences配置引數

8.public finalString getString(int resId) 
獲得包裡的資源字串資訊

9.public abstractObject getSystemService(String name) 
返回系統服務控制代碼

10.public abstract File getCacheDir();獲取快取目錄,

11.publicabstract Drawable getWallpaper,獲取桌布,

12.publicabstract void sendBroadcast(Intent intent);,傳送廣播,

13.publicabstract Intent registerReceiver(BroadcastReceiver receiver,IntentFilterfilter);註冊廣播接收器,

14.publicabstract ComponentName startService(Intent service);開啟關閉Service服務,繫結服務等,

D.Application context和Activity context。

這是兩種不同的context,也是最常見的兩種。第一種中context的生命週期與Application的生命週期相關的,context隨 著Application的銷燬而銷燬,第二種中的context跟Activity的生命週期是相關的,但是對一個Application來 說,Activity可以銷燬幾次,那麼屬於Activity的context就會銷燬多次。至於用哪種context,得看應用場景,個人感覺用 Activity的context好一點,不過也有的時候必須使用Application的context。

2 .Android中,Activity是所有程式的根本,所有程式的流程都執行在Activity之中,Activity具有自己的生命週期. 由系統控制生命週期,程式無法改變,但可以用onSaveInstanceState儲存其狀態對於Activity,關鍵是其生命週期的把握(如下圖),其次就是狀態的儲存和恢復(onSaveInstanceState onRestoreInstanceState),以及Activity之間的跳轉和資料傳輸(intent)。

Activity中常用的函式有SetContentView()  findViewById()    finish()   startActivity(),其生命週期涉及的函式有:

void onCreate(Bundle savedInstanceState)
void onStart()
void onRestart()
void onResume()
void onPause()
void onStop()
void onDestroy()

注意的是,Activity的使用需要在Manifest檔案中新增相應的<Activity>,並設定其屬性和intent-filter。

在 Android 中,多數情況下每個程式都是在各自獨立的 Linux程序中執行的。當一個程式或其某些部分被請求時,它的程序就“出生”了;當這個程式沒有必要再執行下去且系統需要回收這個程序的記憶體用於其他程式時,這個程序就“死亡”了。可以看出,Android程式的生命週期是由系統控制而非程式自身直接控制

在 Android 系統中,當某個 activity呼叫 startActivity(myIntent) 時,系統會在所有已經安裝的程式中尋找其intent filter 和 myIntent 最匹配的一個activity,啟動這個程序,並把這個 intent 通知給這個 activity。這就是一個程式的“生”。比如我們在 Home application 中選擇 “Web browser”,系統會根據這個 intent 找到並啟動 Web browser 程式,顯示 Web browser 的一個 activity 供我們瀏覽網頁(這個啟動過程有點類似我們在在個人電腦上雙擊桌面上的一個圖示,啟動某個應用程式)。在 Android 中,所有的應用程式“生來就是平等的”,所以不光 Android 的核心程式甚至第三方程式也可以發出一個 intent 來啟動另外一個程式中的一個 activity。Android 的這種設計非常有利於“程式部件”的重用。

  一個 Android 程式的程序是何時被系統結束的呢?通俗地說,一個即將被系統關閉的程式是系統在記憶體不足(low memory)時,根據“重要性層次”選出來的“犧牲品”。一個程序的重要性是根據其中執行的部件和部件的狀態決定的。各種程序按照重要性從高到低排列如下:
  1. 前臺程序。這樣的程序擁有一個在螢幕上顯示並和使用者互動的 activity 或者它的一個IntentReciver 正在執行。這樣的程式重要性最高,只有在系統記憶體非常低,萬不得已時才會被結束。
  2. 可見程序。在螢幕上顯示,但是不在前臺的程式。比如一個前臺程序以對話方塊的形式顯示在該程序前面。這樣的程序也很重要,它們只有在系統沒有足夠記憶體執行所有前臺程序時,才會被結束。
  3. 服務程序。這樣的程序在後臺持續執行,比如後臺音樂播放、後臺資料上傳下載等。這樣的程序對使用者來說一般很有用,所以只有當系統沒有足夠記憶體來維持所有的前臺和可見程序時,才會被結束。
  4. 後臺程序。這樣的程式擁有一個使用者不可見的 activity。這樣的程式在系統記憶體不足時,按照LRU的順序被結束。
  5. 空程序。這樣的程序不包含任何活動的程式部件。系統可能隨時關閉這類程序。
 

從 某種意義上講,垃圾收集機制把程式設計師從“記憶體管理噩夢”中解放出來,而 Android 的程序生命週期管理機制把使用者從“任務管理噩夢”中解放出來。我見過一些 Nokia S60 使用者和 Windows Mobile 使用者要麼因為長期不關閉多餘的應用程式而導致系統變慢,要麼因為不時檢視應用程式列表而影響使用體驗。Android 使用 Java 作為應用程式 API,並且結合其獨特的生命週期管理機制同時為開發者和使用者提供最大程度的便利。

Activity有三種基本狀態:

  1. Active:處於螢幕前景(當前task的棧頂Activity處於Active狀態),同一時刻只能有一個Activity處於Active狀態;
  2. Paused狀態:處於背景畫面畫面狀態,失去了焦點,但依然是活動狀態;
  3. stopped:不可見,但依然保持所有的狀態和記憶體資訊。

可以呼叫finish()結束處理Paused或者stopped狀態的Activity。

3 Intent

Android中提供了Intent機制來協助 應用間的互動與通訊,Intent負責對應用中一次操作的動作、動作涉及資料、附加資料進行描述,Android則根據此Intent的描述,負責找到對 應的元件,將 Intent傳遞給呼叫的元件,並完成元件的呼叫。Intent不僅可用於應用程式之間,也可用於應用程式內部的Activity/Service之間的互動。因此,Intent在這裡起著一個媒體中介的作用,專門提供元件互相呼叫的相關資訊,實現呼叫者與被呼叫者之間的解耦。在SDK中給出了 Intent作用的表現形式為:

Intent屬性的設定,包括以下幾點:(以下為XML中定義,當然也可以通過Intent類的方法來獲取和設定)

(1)Action,也就是要執行的動作

SDk中定義了一些標準的動作,包括

onstant        Target component       Action
ACTION_CALL        activity        初始化一個通話.
ACTION_EDIT        activity       為使用者的edit顯示資料.
ACTION_MAIN        activity       Start up as the initial activity of a task, with no data input and no returnedoutput.
ACTION_SYNC        activity       Synchronize data on a server with data on the mobile device.
ACTION_BATTERY_LOW        broadcast receiver       A warning that the battery is low.
ACTION_HEADSET_PLUG        broadcast receiver       A headset has been plugged into the device, or unplugged from it.
ACTION_SCREEN_ON        broadcast receiver       The screen has been turned on.
ACTION_TIMEZONE_CHANGED        broadcast receiver       The setting for the time zone has changed.
VIEW_ACTION
PICK_ACTION
GET_CONTENT_ACTION
DIAL_ACTION

SENDTO_ACTION
ANSWER_ACTION
INSERT_ACTION
DELETE_ACTION
RUN_ACTION
LOGIN_ACTION
CLEAR_CREDENTIALS_ACTION
PICK_ACTIVITY_ACTION
WEB_SEARCH_ACTION

也可以自定義動作(自定義的動作在使用時,需要加上包名作為字首,如"com.example.project.SHOW_COLOR”),並可定義相應的Activity來處理我們的自定義動作。

(2)Data,也就是執行動作要操作的資料

Android 中採用指向資料的一個URI來表示,如在聯絡人應用中,一個指向某聯絡人的URI可能為:content://contacts/1。對於不同的動作,其 URI資料的型別是不同的(可以設定type屬性指定特定型別資料),如ACTION_EDIT指定Data為檔案URI,打電話為tel:URI,訪問 網路為http:URI,而由content provider提供的資料則為content: URIs。

(3)type(資料型別),顯式指定Intent的資料型別(MIME)。一般Intent的資料型別能夠根據資料本身進行判定,但是通過設定這個屬性,可以強制採用顯式指定的型別而不再進行推導。

(4)category(類 別),被執行動作的附加資訊。例如 LAUNCHER_CATEGORY 表示Intent 的接受者應該在Launcher中作為頂級應用出現;而ALTERNATIVE_CATEGORY表示當前的Intent是一系列的可選動作中的一個,這 些動作可以在同一塊資料上執行。還有其他的為

Constant Meaning

CATEGORY_BROWSABLE The target activity can be safely invoked by the browserto display data referenced by a link — for example, an image or an e-mailmessage.

CATEGORY_GADGET The activity can be embedded inside of another activitythat hosts gadgets. CATEGORY_HOMEThe activity displays the home screen, the first screenthe user sees when the device is turned on or when the HOME key is pressed.

 CATEGORY_LAUNCHER The activity can be the initial activity of a task and islisted in the top-level application launcher.

CATEGORY_PREFERENCE The target activity is a preference panel.

(5)component(元件),指定Intent的的目標元件的類名稱。通常 Android會根據Intent 中包含的其它屬性的資訊,比如action、data/type、category進行查詢,最終找到一個與之匹配的目標元件。但是,如果 component這個屬性有指定的話,將直接使用它指定的元件,而不再執行上述查詢過程。指定了這個屬性以後,Intent的其它所有屬性都是可選的。

(6)extras(附加資訊),是其它所有附加資訊的集合。使用extras可以為元件提供擴充套件資訊,比如,如果要執行“傳送電子郵件”這個動作,可以將電子郵件的標題、正文等儲存在extras裡,傳給電子郵件傳送元件。

理解Intent的關鍵之一是理解清楚Intent的兩種基本用法:一種是顯式的Intent,即在構造Intent物件時就指定接收者;另一種是隱式的Intent,即Intent的傳送者在構造Intent物件時,並不知道也不關心接收者是誰,有利於降低傳送者和接收者之間的耦合。

對於顯式Intent,Android不需要去做解析,因為目標元件已經很明確,Android需要解析的是那些隱式Intent,通過解析,將 Intent對映給可以處理此Intent的Activity、IntentReceiver或Service。        

Intent 解析機制主要是通過查詢已註冊在AndroidManifest.xml中的所有IntentFilter及其中定義的Intent,最終找到匹配的 Intent。在這個解析過程中,Android是通過Intent的action、type、category這三個屬性來進行判斷的,判斷方法如下:

  • 如果Intent指明定了action,則目標元件的IntentFilter的action列表中就必須包含有這個action,否則不能匹配;
  • 如果Intent沒有提供type,系統將從data中得到資料型別。和action一樣,目標元件的資料型別列表中必須包含Intent的資料型別,否則不能匹配。
  • 如果Intent中的資料不是content: 型別的URI,而且Intent也沒有明確指定它的type,將根據Intent中資料的scheme (比如 http: 或者mailto:) 進行匹配。同上,Intent 的scheme必須出現在目標元件的scheme列表中。
  • 如果Intent指定了一個或多個category,這些類別必須全部出現在組建的類別列表中。比如Intent中包含了兩個類別:LAUNCHER_CATEGORY 和 ALTERNATIVE_CATEGORY,解析得到的目標元件必須至少包含這兩個類別。

Intent-Filter的定義

一些屬性設定的例子:

<action android:name="com.example.project.SHOW_CURRENT"/>

<categoryandroid:name="android.intent.category.DEFAULT" />

<dataandroid:mimeType="video/mpeg" android:scheme="http" . . ./>

<dataandroid:mimeType="image/*" />

<data android:scheme="http"android:type="video/*" />

完整的例項

<activityandroid:name="NotesList"android:label="@string/title_notes_list"><intent-filter><actionandroid:name="android.intent.action.MAIN"/><categoryandroid:name="android.intent.category.LAUNCHER"/></intent-filter><intent-filter><actionandroid:name="android.intent.action.VIEW"/><actionandroid:name="android.intent.action.EDIT"/><actionandroid:name="android.intent.action.PICK"/><categoryandroid:name="android.intent.category.DEFAULT"/><dataandroid:mimeType="vnd.android.cursor.dir/vnd.google.note"/></intent-filter><intent-filter><actionandroid:name="android.intent.action.GET_CONTENT"/><categoryandroid:name="android.intent.category.DEFAULT"/><dataandroid:mimeType="vnd.android.cursor.item/vnd.google.note"/></intent-filter></activity>

Intent用法例項

1.無引數Activity跳轉

Intent it = newIntent(Activity.Main.this, Activity2.class);

startActivity(it);  

2.向下一個Activity傳遞資料(使用Bundle和Intent.putExtras)

Intent it = newIntent(Activity.Main.this, Activity2.class);

Bundle bundle=newBundle();

bundle.putString("name", "This is from MainActivity!");

it.putExtras(bundle);       // it.putExtra(“test”, "shuju”);

startActivity(it);            // startActivityForResult(it,REQUEST_CODE);

對於資料的獲取可以採用:

Bundle bundle=getIntent().getExtras();

String name=bundle.getString("name");

3.向上一個Activity返回結果(使用setResult,針對startActivityForResult(it,REQUEST_CODE)啟動的Activity)

       Intent intent=getIntent();

       Bundle bundle2=new Bundle();

       bundle2.putString("name", "This is from ShowMsg!");

       intent.putExtras(bundle2);

       setResult(RESULT_OK, intent);

4.回撥上一個Activity的結果處理函式(onActivityResult)

@Override

    protectedvoid onActivityResult(intrequestCode, int resultCode, Intent data) {

       // TODOAuto-generated method stub

       super.onActivityResult(requestCode, resultCode,data);

       if (requestCode==REQUEST_CODE){

           if(resultCode==RESULT_CANCELED)

                  setTitle("cancle");

           elseif (resultCode==RESULT_OK) {

                 String temp=null;

                 Bundle bundle=data.getExtras();

                 if(bundle!=null)   temp=bundle.getString("name");

                 setTitle(temp);

           }

       }

    }

下面是轉載來的其他的一些Intent用法例項(轉自javaeye)

顯示網頁
   1. Uri uri =Uri.parse("http://google.com");  
   2. Intent it = new Intent(Intent.ACTION_VIEW, uri);  
   3. startActivity(it);

顯示地圖
   1. Uri uri =Uri.parse("geo:38.899533,-77.036476");  
   2. Intent it = new Intent(Intent.ACTION_VIEW, uri);   
   3. startActivity(it);   
   4. //其他geo URI 範例  
   5. //geo:latitude,longitude  
   6. //geo:latitude,longitude?z=zoom  
   7. //geo:0,0?q=my+street+address  
   8. //geo:0,0?q=business+near+city  
   9. //google.streetview:cbll=lat,lng&cbp=1,yaw,,pitch,zoom&mz=mapZoom

路徑規劃
   1. Uri uri =Uri.parse("http://maps.google.com/maps?f=d&saddr=startLat%20startLng&daddr=endLat%20endLng&hl=en"); 
   2. Intent it = new Intent(Intent.ACTION_VIEW, uri);  
   3. startActivity(it);  
   4. //where startLat, startLng, endLat, endLng are a long with 6decimals like: 50.123456 

打電話
   1. //叫出撥號程式 
   2. Uri uri = Uri.parse("tel:0800000123");  
   3. Intent it = new Intent(Intent.ACTION_DIAL, uri);  
   4. startActivity(it);  
   1. //直接打電話出去  
   2. Uri uri = Uri.parse("tel:0800000123");  
   3. Intent it = new Intent(Intent.ACTION_CALL, uri);  
   4. startActivity(it);  
   5. //用這個,要在AndroidManifest.xml 中,加上 
   6. //<uses-permissionid="android.permission.CALL_PHONE" /> 

傳送SMS/MMS
   1. //呼叫簡訊程式 
   2. Intent it = new Intent(Intent.ACTION_VIEW, uri);  
   3. it.putExtra("sms_body", "The SMStext");   
   4. it.setType("vnd.android-dir/mms-sms");  
   5. startActivity(it); 
   1. //傳送訊息 
   2. Uri uri = Uri.parse("smsto://0800000123");  
   3. Intent it = new Intent(Intent.ACTION_SENDTO, uri);  
   4. it.putExtra("sms_body", "The SMStext");  
   5. startActivity(it); 
   1. //傳送 MMS  
   2. Uri uri =Uri.parse("content://media/external/images/media/23");  
   3. Intent it = new Intent(Intent.ACTION_SEND);   
   4. it.putExtra("sms_body", "sometext");   
   5. it.putExtra(Intent.EXTRA_STREAM, uri);  
   6. it.setType("image/png");   
   7. startActivity(it); 

傳送 Email
   1. Uri uri = Uri.parse("mailto:[email protected]");  
   2. Intent it = new Intent(Intent.ACTION_SENDTO, uri);  
   3. startActivity(it); 


   1. Intent it = new Intent(Intent.ACTION_SEND);  
   2. it.putExtra(Intent.EXTRA_EMAIL, "[email protected]");  
   3. it.putExtra(Intent.EXTRA_TEXT, "The email bodytext");  
   4. it.setType("text/plain");  
   5. startActivity(Intent.createChooser(it, "Choose EmailClient")); 


   1. Intent it=new Intent(Intent.ACTION_SEND);    
   2. String[] tos={"[email protected]"};    
   3. String[] ccs={"[email protected]"};    
   4. it.putExtra(Intent.EXTRA_EMAIL, tos);    
   5. it.putExtra(Intent.EXTRA_CC, ccs);    
   6. it.putExtra(Intent.EXTRA_TEXT, "The email bodytext");    
   7. it.putExtra(Intent.EXTRA_SUBJECT, "The email subjecttext");    
   8. it.setType("message/rfc822");    
   9. startActivity(Intent.createChooser(it, "Choose EmailClient"));


   1. //傳送附件
   2. Intent it = new Intent(Intent.ACTION_SEND);  
   3. it.putExtra(Intent.EXTRA_SUBJECT, "The email subjecttext");  
   4. it.putExtra(Intent.EXTRA_STREAM,"file:///sdcard/mysong.mp3");  
   5. sendIntent.setType("audio/mp3");  
   6. startActivity(Intent.createChooser(it, "Choose EmailClient"));

播放多媒體
       Uri uri =Uri.parse("file:///sdcard/song.mp3");  
       Intent it = new Intent(Intent.ACTION_VIEW,uri);  
       it.setType("audio/mp3");  
       startActivity(it); 
       Uri uri =Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI,"1");  
       Intent it = new Intent(Intent.ACTION_VIEW,uri);  
       startActivity(it);

Market 相關
1.       //尋找某個應用 
2.        Uri uri =Uri.parse("market://search?q=pname:pkg_name"); 
3.        Intent it = newIntent(Intent.ACTION_VIEW, uri);  
4.        startActivity(it);  
5.        //where pkg_name is the fullpackage path for an application 
1.        //顯示某個應用的相關資訊 
2.        Uri uri =Uri.parse("market://details?id=app_id");  
3.        Intent it = newIntent(Intent.ACTION_VIEW, uri); 
4.        startActivity(it);  
5.        //where app_id is the applicationID, find the ID   
6.        //by clicking on your applicationon Market home   
7.        //page, and notice the ID from theaddress bar

Uninstall 應用程式
1.        Uri uri =Uri.fromParts("package", strPackageName, null); 
2.        Intent it = newIntent(Intent.ACTION_DELETE, uri);   
3.        startActivity(it); 

4.Service的種類

按執行地點分類:

類別

區別

優點

缺點

應用

本地服務(Local)

該服務依附在主程序上,

服務依附在主程序上而不是獨立的程序,這樣在一定程度上節約了資源,另外Local服務因為是在同一程序因此不需要IPC,也不需要AIDL。相應bindService會方便很多。

主程序被Kill後,服務便會終止。

非常常見的應用如:HTC的音樂播放服務,天天動聽音樂播放服務。

遠端服務(Remote)

該服務是獨立的程序,

服務為獨立的程序,對應程序名格式為所在包名加上你指定的android:process字串。由於是獨立的程序,因此在Activity所在程序被Kill的時候,該服務依然在執行,不受其他程序影響,有利於為多個程序提供服務具有較高的靈活性。

該服務是獨立的程序,會佔用一定資源,並且使用AIDL進行IPC稍微麻煩一點。

一些提供系統服務的Service,這種Service是常駐的。

其實remote服務還是很少見的,並且一般都是系統服務。

按執行型別分類:

類別

區別

應用

前臺服務

會在通知一欄顯示 ONGOING 的 Notification,

當服務被終止的時候,通知一欄的 Notification 也會消失,這樣對於使用者有一定的通知作用。常見的如音樂播放服務。

後臺服務

預設的服務即為後臺服務,即不會在通知一欄顯示 ONGOING 的 Notification。

當服務被終止的時候,使用者是看不到效果的。某些不需要執行或終止提示的服務,如天氣更新,日期同步,郵件同步等。

有 同學可能會問,後臺服務我們可以自己建立 ONGOING 的Notification 這樣就成為前臺服務嗎?答案是否定的,前臺服務是在做了上述工作之後需要呼叫startForeground ( android 2.0 及其以後版本 )或 setForeground (android 2.0 以前的版本)使服務成為前臺服務。這樣做的好處在於,當服務被外部強制終止掉的時候,ONGOING 的Notification 任然會移除掉。

按使用方式分類:

類別

區別

startService 啟動的服務

主要用於啟動一個服務執行後臺任務,不進行通訊。停止服務使用stopService

bindService 啟動的服務

該方法啟動的服務要進行通訊。停止服務使用unbindService

startService 同時也 bindService 啟動的服務

停止服務應同時使用stepService與unbindService

以上面三種方式啟動的服務其生命週期也有區別,將在隨後給出。

2、Service 與 Thread 的區別

很多時候,你可能會問,為什麼要用 Service,而不用Thread 呢,因為用 Thread 是很方便的,比起Service 也方便多了,下面我詳細的來解釋一下。

1). Thread:Thread是程式執行的最小單元,它是分配CPU的基本單位。可以用Thread 來執行一些非同步的操作。

2). Service:Service是android的一種機制,當它執行的時候如果是LocalService,那麼對應的 Service 是執行在主程序的main 執行緒上的。如:onCreate,onStart 這些函式在被系統呼叫的時候都是在主程序的 main 執行緒上執行的。如果是Remote Service,那麼對應的 Service 則是執行在獨立程序的 main 執行緒上。因此請不要把 Service 理解成執行緒,它跟執行緒半毛錢的關係都沒有!

既 然這樣,那麼我們為什麼要用 Service 呢?其實這跟android 的系統機制有關,我們先拿 Thread 來說。Thread的執行是獨立於 Activity 的,也就是說當一個Activity 被 finish 之後,如果你沒有主動停止Thread 或者 Thread 裡的 run 方法沒有執行完畢的話,Thread 也會一直執行。因此這裡會出現一個問題:當 Activity 被 finish 之後,你不再持有該 Thread 的引用。另一方面,你沒有辦法在不同的 Activity 中對同一 Thread 進行控制。

舉 個例子:如果你的 Thread 需要不停地隔一段時間就要連線伺服器做某種同步的話,該 Thread 需要在 Activity 沒有start的時候也在執行。這個時候當你 start 一個 Activity 就沒有辦法在該 Activity 裡面控制之前建立的 Thread。因此你便需要建立並啟動一個 Service ,在 Service 裡面建立、執行並控制該 Thread,這樣便解決了該問題(因為任何 Activity 都可以控制同一 Service,而系統也只會建立一個對應 Service 的例項)。

因 此你可以把 Service 想象成一種訊息服務,而你可以在任何有 Context 的地方呼叫 Context.startService、Context.stopService、 Context.bindService,Context.unbindService,來控制它,你也可以在 Service 裡註冊 BroadcastReceiver,在其他地方通過傳送 broadcast 來控制它,當然這些都是 Thread 做不到的。

3、Service的生命週期

onCreate  onStart  onDestroy  onBind

1). 被啟動的服務的生命週期:如果一個Service被某個Activity 呼叫 Context.startService 方法啟動,那麼不管是否有Activity使用bindService繫結或unbindService解除繫結到該Service,該Service都 在後臺執行。如果一個Service被st