Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android官方文檔之App Components(Common Intents)(轉載)

Android官方文檔之App Components(Common Intents)(轉載)

編輯:關於Android編程

Intent的真正強大之處在於它的隱式Intent,隱式Intent需要配合Intent-filters使用,有關這方面的概念和知識,您可以參考我翻譯的官方文檔:《Android官方文檔之App Components(Intents and Intent Filters)》。


隱式Intent足夠強大,以至於系統提供了大量的Intent方便開發者啟動系統應用程序,本文將介紹一些常用的隱式Intent、以及如何自定義intent-filters以匹配隱式intent。


如需閱讀官方原文,您可以點擊這個鏈接:《Common Intents》


常用的Intent(Common Intents)

下面將按照啟動的目標組件類別介紹隱式Intent:


鬧鐘類別(Alarm Clock)


啟動鬧鐘(Create an alarm)

要啟動鬧鐘activity,可以這樣設定Intent:

  • Action:ACTION_SET_ALARM

  • Data URI:空

  • MIME Type:空

  • Extras:

  • EXTRA_HOUR:設定小時
  • EXTRA_MINUTES:設定分鐘
  • EXTRA_MESSAGE:設定自定義消息
  • EXTRA_DAYS:設定每周的周幾重復響鈴。該字段的值應定義成ArrayList,每個元素是Calendar類中的靜態字段(如Calendar.Monday)。對於那些一次性響鈴,無需設置這個extra。
  • EXTRA_RINGTONE:設定鬧鐘鈴聲。該字段的值應設定成一個scheme為 content: 的URI類型,該URI指向了一個音頻文件的地址;您也可以將值設定為VALUE_RINGTONE_SILENT,這表示將鬧鐘設為靜音。
  • EXTRA_VIBRATE:設定是否響鈴的同時震動。該字段的值為boolean類型。
  • EXTRA_SKIP_UI:設定啟動系統鬧鐘應用程序時,是否跳過UI界面,值為boolean類型,若為true,表示不顯示設定鬧鐘的dialog對話框,而直接進入設置鬧鐘的activity。

示例:

public void createAlarm(String message, int hour, int minutes) {
    Intent intent = new Intent(AlarmClock.ACTION_SET_ALARM)
            .putExtra(AlarmClock.EXTRA_MESSAGE, message)
            .putExtra(AlarmClock.EXTRA_HOUR, hour)
            .putExtra(AlarmClock.EXTRA_MINUTES, minutes);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

若為Intent指定的action為ACTION_SET_ALARM,則需要在manifest中配置如下權限:

<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />

可以響應該Intent的intent-filter如下:

...>
    
        "android.intent.action.SET_ALARM" />
        "android.intent.category.DEFAULT" />
    

啟動計時器(Create a timer)

!請注意:該Intent只兼容Android4.4 (API level 19) 及以上版本的設備。


要啟動計時器,可以這樣設定Intent:

  • Action:ACTION_SET_TIMER

  • Data URI:空

  • MIME Type:空

  • Extras:

  • EXTRA_LENGTH:設置倒計時的秒數
  • EXTRA_MESSAGE:設置到時消息
  • EXTRA_SKIP_UI:設定啟動系統計時器應用程序時,是否跳過UI界面,值為boolean類型,若為true,表示不顯示設定計時器的設置dialog對話框,而直接進入計時器的activity。

示例:

public void startTimer(String message, int seconds) {
    Intent intent = new Intent(AlarmClock.ACTION_SET_TIMER)
            .putExtra(AlarmClock.EXTRA_MESSAGE, message)
            .putExtra(AlarmClock.EXTRA_LENGTH, seconds)
            .putExtra(AlarmClock.EXTRA_SKIP_UI, true);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

若為Intent指定的action為ACTION_SET_TIMER,則需要在manifest中配置如下權限:

<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />

可以響應該Intent的intent-filter如下:

...>
    
        "android.intent.action.SET_TIMER" />
        "android.intent.category.DEFAULT" />
    

顯示設置的所有鬧鐘(Show all alarms)

!請注意:該Intent只兼容 Android 4.4 (API level 19) 及以上版本的設備。


  • Action:ACTION_SHOW_ALARMS
  • Data URI:空
  • MIME Type:空

示例:

...>
    
        "android.intent.action.SHOW_ALARMS" />
        "android.intent.category.DEFAULT" />
    

日期類別(Calendar)


添加日歷事件(Add a calendar event)


  • Action:ACTION_INSERT

  • Data URI:Events.CONTENT_URI

  • MIME Type:”vnd.android.cursor.dir/event”

  • Extras:

  • EXTRA_EVENT_ALL_DAY:該鍵所對應的值是boolean類型,表示事件是否為全天候事件。
  • EXTRA_EVENT_BEGIN_TIME:代表事件的起始時間,值為 從2000年到設定起始時間所經歷的毫秒數(milliseconds since epoch)。
  • EXTRA_EVENT_END_TIME:代表事件的結束時間,值為 從2000年到設定結束時間所經歷的毫秒數(milliseconds since epoch)。
  • TITLE:事件的標題
  • DESCRIPTION:事件的描述
  • EVENT_LOCATION:事件發生的地點
  • EXTRA_EMAIL:將事件郵件的形式發送,值為郵箱地址,可同時發送給多人,郵箱地址以逗號分隔。欲了解更多關於發送郵件的細節,您可以參考這個類:CalendarContract.EventsColumns

示例:

public void addEvent(String title, String location, Calendar begin, Calendar end) {
    Intent intent = new Intent(Intent.ACTION_INSERT)
            .setData(Events.CONTENT_URI)
            .putExtra(Events.TITLE, title)
            .putExtra(Events.EVENT_LOCATION, location)
            .putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, begin)
            .putExtra(CalendarContract.EXTRA_EVENT_END_TIME, end);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

可以匹配上述intent的intent-filters:

...>
    
        "android.intent.action.INSERT" />
        "vnd.android.cursor.dir/event" />
        "android.intent.category.DEFAULT" />
    

相機類別(Camera)


使用相機拍照或錄像並返回結果(Capture a picture or video and return it)


  • Action:ACTION_IMAGE_CAPTURE或ACTION_VIDEO_CAPTURE

  • Data URI Scheme:空

  • MIME Type:空

  • Extras:EXTRA_OUTPUT,該鍵所對應的值是一個Uri對象,它表示通過相機應用所照的相片或錄的視頻的存儲地址。您可以在onActivityResult()方法中通過該Uri獲取剛照的相片。

!請注意:通過ACTION_IMAGE_CAPTURE啟動activity並返回的照片是一個鍵為”data”的Bitmap類型的略縮圖(downscaled copy (a thumbnail) of the photo)

示例如下:

static final int REQUEST_IMAGE_CAPTURE = 1;
static final Uri mLocationForPhotos;

public void capturePhoto(String targetFilename) {
    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    intent.putExtra(MediaStore.EXTRA_OUTPUT,
            Uri.withAppendedPath(mLocationForPhotos, targetFilename));
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
        Bitmap thumbnail = data.getParcelable("data");
        // Do other work with full size photo saved in mLocationForPhotos
        ...
    }
}

關於如何通過這個Intent拍照、錄像,以及如何獲得存儲照片、錄像的Uri地址,您可以參考這些Training:

  • Taking Photos Simply

  • Taking Videos Simply

示例intent-filter:

...>
    
        "android.media.action.IMAGE_CAPTURE" />
        "android.intent.category.DEFAULT" />
    

啟動相機應用的照相模式(Start a camera app in still image mode)


  • Action:INTENT_ACTION_STILL_IMAGE_CAMERA

  • Data URI Scheme:空

  • MIME Type:空

  • Extras:空

示例:

public void capturePhoto() {
    Intent intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent);
    }
}

intent-filter:

...>
    
        "android.media.action.STILL_IMAGE_CAMERA" />
        "android.intent.category.DEFAULT" />
    

啟動相機應用的錄像模式(Start a camera app in video mode)


  • Action:INTENT_ACTION_VIDEO_CAMERA

  • Data URI Scheme:空

  • MIME Type:空

  • Extras:空

示例:

public void capturePhoto() {
    Intent intent = new Intent(MediaStore.INTENT_ACTION_VIDEO_CAMERA);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent);
    }
}

intent-filter:

...>
    
        "android.media.action.VIDEO_CAMERA" />
        "android.intent.category.DEFAULT" />
    

通訊錄類別(Contacts/People App)


選擇聯系人(Select a contact)


在onActivityResult()中可獲取您選擇的聯系人,如果只是通過Contacts Provider讀取聯系人信息,則無需申請READ_CONTACTS權限。


  • Action:ACTION_PICK

  • Data URI Scheme:None

  • MIME Type:Contacts.CONTENT_TYPE

示例:

static final int REQUEST_SELECT_CONTACT = 1;

public void selectContact() {
    Intent intent = new Intent(Intent.ACTION_PICK);
    intent.setType(ContactsContract.Contacts.CONTENT_TYPE);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent, REQUEST_SELECT_CONTACT);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_SELECT_CONTACT && resultCode == RESULT_OK) {
        Uri contactUri = data.getData();
        // Do something with the selected contact at contactUri
        ...
    }
}

關於如何處理返回的Uri對象contactUri ,您可以訪問這個Training:Retrieving Details for a Contact


獲得具體聯系人信息(Select specific contact data)


  • Action:ACTION_PICK

  • Data URI Scheme:空

  • MIME Type:
  • CommonDataKinds.Phone.CONTENT_TYPE,表示獲取聯系人號碼

  • CommonDataKinds.Email.CONTENT_TYPE,表示獲取聯系人Email

  • CommonDataKinds.StructuredPostal.CONTENT_TYPE,表示獲取聯系人的郵寄地址

  • 通過ContactsContract.CommonDataKinds中的其他字段,還可以獲取更多聯系人信息。

示例:

static final int REQUEST_SELECT_PHONE_NUMBER = 1;

public void selectContact() {
    // Start an activity for the user to pick a phone number from contacts
    Intent intent = new Intent(Intent.ACTION_PICK);
    intent.setType(CommonDataKinds.Phone.CONTENT_TYPE);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent, REQUEST_SELECT_PHONE_NUMBER);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_SELECT_PHONE_NUMBER && resultCode == RESULT_OK) {
        // Get the URI and query the content provider for the phone number
        Uri contactUri = data.getData();
        String[] projection = new String[]{CommonDataKinds.Phone.NUMBER};
        Cursor cursor = getContentResolver().query(contactUri, projection,
                null, null, null);
        // If the cursor returned is valid, get the phone number
        if (cursor != null && cursor.moveToFirst()) {
            int numberIndex = cursor.getColumnIndex(CommonDataKinds.Phone.NUMBER);
            String number = cursor.getString(numberIndex);
            // Do something with the phone number
            ...
        }
    }
}

查看聯系人(View a contact)

  • Action:ACTION_VIEW

  • Data URI Scheme:content:,該Uri指向了查看的聯系人地址,有兩種方法可獲得該Uri:

  • 通過上一小節的ACTION_PICK,獲得返回的Uri。此方式無需申請權限。
  • 直接檢索通訊錄聯系人( Retrieving a List of Contacts)。此方式需要READ_CONTACTS權限。

  • MIME Type:空

示例:

public void viewContact(Uri contactUri) {
    Intent intent = new Intent(Intent.ACTION_VIEW, contactUri);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

編輯聯系人信息(Edit an existing contact)


  • Action:ACTION_EDIT

  • Data URI Scheme:content:,獲取該Uri的方式和權限與上一小節的獲取方式一致。

  • MIME Type:由Uri決定。

  • Extras:ContactsContract.Intents.Insert

示例:

public void editContact(Uri contactUri, String email) {
    Intent intent = new Intent(Intent.ACTION_EDIT);
    intent.setData(contactUri);
    intent.putExtra(Intents.Insert.EMAIL, email);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

更多關於編輯聯系人的方法,您可以參考這個Training:Modifying Contacts Using Intents。


新增聯系人(Insert a contact)


  • Action:ACTION_INSERT

  • Data URI Scheme:空

  • MIME Type:Contacts.CONTENT_TYPE

  • Extras:ContactsContract.Intents.Insert

示例:

public void insertContact(String name, String email) {
    Intent intent = new Intent(Intent.ACTION_INSERT);
    intent.setType(Contacts.CONTENT_TYPE);
    intent.putExtra(Intents.Insert.NAME, name);
    intent.putExtra(Intents.Insert.EMAIL, email);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

Email類別(Email)

發送郵件並可選攜帶附件(Compose an email with optional attachments)

Action:

  • ACTION_SENDTO。用於發送不帶附件的Email(for no attachment)
  • ACTION_SEND。用於發送帶一個附件的Email(for one attachment)
  • ACTION_SEND_MULTIPLE。用於發送多個附件的Email(for multiple attachments)
  • Data URI Scheme:空
  • MIME Type:
  • "text/plain"
  • "*/*"
  • Extras:
  • Intent.EXTRA_EMAIL:該鍵所對應值為一個字符串數組,每個字符串表示一個收件人的地址。
  • Intent.EXTRA_CC:該鍵所對應值為一個字符串數組,每個字符串表示一個副本抄送地址(CC= Carbon Copy)。
  • Intent.EXTRA_BCC:該鍵所對應值為一個字符串數組,每個字符串表示一個密件抄送地址(BCC= Blind Carbon Copy)。
  • Intent.EXTRA_SUBJECT:該鍵所對應值為一個字符串,表示郵件主題。
  • Intent.EXTRA_TEXT:該鍵所對應值為一個字符串,表示郵件內容。
  • Intent.EXTRA_STREAM:該鍵所對應值為一個Uri地址,該Uri指向了添加的附件,若action為 ACTION _SEND _MULTIPLE,則值應為ArrayList,每個元素為一個Uri對象。

示例:

public void composeEmail(String[] addresses, String subject, Uri attachment) {
    Intent intent = new Intent(Intent.ACTION_SEND);
    intent.setType("*/*");
    intent.putExtra(Intent.EXTRA_EMAIL, addresses);
    intent.putExtra(Intent.EXTRA_SUBJECT, subject);
    intent.putExtra(Intent.EXTRA_STREAM, attachment);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

若您能確定通過該隱式Intent能啟動一個郵件應用的activity(而不是社交類應用或是編輯短信的應用),那麼您可以使用action為ACTION_SENDTO並且使用”mailto”作為Uri的解析字符串發送郵件:

public void composeEmail(String[] addresses, String subject) {
    Intent intent = new Intent(Intent.ACTION_SENDTO);
    intent.setData(Uri.parse("mailto:")); // only email apps should handle this
    intent.putExtra(Intent.EXTRA_EMAIL, addresses);
    intent.putExtra(Intent.EXTRA_SUBJECT, subject);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}

Intent-filter:

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <data android:type="*/*" />
        <category android:name="android.intent.category.DEFAULT" />
    
        <category android:name="android.intent.category.OPENABLE" />
    
        <data android:scheme="http" android:host="www.example.com" />
        <category android:name="android.intent.category.DEFAULT" />
        
        <category android:name="android.intent.category.BROWSABLE" />