Android 基礎知識6:經常使用的隱式 Intent

前言

本篇文章的內容實際上是屬於上一篇文章(Android 基礎知識5:Intent 和 Intent 過濾器)的延伸,考慮到篇幅長度的緣由,因此沒有把本篇文章的內容寫到上一篇文章中,另外單獨寫成一篇文章還有個好處就是方便讀者查閱。這篇文章主要爲你們列舉了經常使用的隱式 Intent,你們若是在平時工做中有相關的需求能夠直接複製代碼使用。java

本文目錄

目錄

1、鬧鐘相關的操做

(一)建立鬧鐘

下面介紹一下如何建立一個鬧鐘:android

1.屬性設置 架構

建立鬧鐘Intent
2.Intent 示例

  • kotlin版本:
fun createAlarm(message: String, hour: Int, minutes: Int) {
    val intent = Intent(AlarmClock.ACTION_SET_ALARM).apply {
        putExtra(AlarmClock.EXTRA_MESSAGE, message)
        putExtra(AlarmClock.EXTRA_HOUR, hour)
        putExtra(AlarmClock.EXTRA_MINUTES, minutes)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}
複製代碼
  • Java版本
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);
    }
}
複製代碼

所需權限app

<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
複製代碼

3.intent-filter 示例ide

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.SET_ALARM" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>
複製代碼

運行效果以下: post

建立鬧鐘

(二)建立定時器

下面介紹一下如何建立一個定時器:測試

1.屬性設置 ui

建立定時器Intent
2.Intent 示例

  • kotlin版本:
fun startTimer(message: String, seconds: Int) {
    val intent = Intent(AlarmClock.ACTION_SET_TIMER).apply {
        putExtra(AlarmClock.EXTRA_MESSAGE, message)
        putExtra(AlarmClock.EXTRA_LENGTH, seconds)
        putExtra(AlarmClock.EXTRA_SKIP_UI, true)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}
複製代碼
  • Java版本
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);
    }
}
複製代碼

所需權限this

<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
複製代碼

3.intent-filter 示例google

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.SET_TIMER" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>
複製代碼

運行效果以下

爲了方便演示,我把 AlarmClock.EXTRA_SKIP_UI 設置成了 false

建立定時器

(三)顯示全部鬧鐘

調用此 Intent 的應用並很少(使用它的主要是系統應用),可是若是應用的類型是鬧鐘的話都應實現此 Intent 過濾器。

1.屬性設置

顯示全部鬧鐘Intent
2.Intent 示例

  • kotlin版本:
fun allAlarm() {
        val intent = Intent(AlarmClock.ACTION_SHOW_ALARMS)
        if (intent.resolveActivity(packageManager) != null) {
            startActivity(intent)
        }
    }
複製代碼
  • Java版本
public void allAlarm() {
	Intent intent = new Intent(AlarmClock.ACTION_SHOW_ALARMS);
		if (intent.resolveActivity(getPackageManager()) != null) {
			startActivity(intent);
		}
}
複製代碼

3.intent-filter 示例

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.SHOW_ALARMS" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>
複製代碼

運行效果以下

顯示全部鬧鐘

2、日曆

如需向手機的日曆添加新事件,請參考以下屬性設置:

1.屬性設置

日曆Intent
2.Intent 示例

  • kotlin版本
fun addEvent(title: String, location: String, begin: Long, end: Long) {
    val intent = Intent(Intent.ACTION_INSERT).apply {
        data = 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(packageManager) != null) {
        startActivity(intent)
    }
}
複製代碼
  • Java版本
public void addEvent(String title, String location, long begin, long 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);
    }
}
複製代碼

3.intent-filter 示例

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.INSERT" />
        <data android:mimeType="vnd.android.cursor.dir/event" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>
複製代碼

運行效果:

添加日曆事件
調用 addEvent() 方法的測試代碼以下:

addEvent("去機場接人", "國際機場", System.currentTimeMillis(), System.currentTimeMillis());
複製代碼

3、相機相關的操做

(一)拍攝照片或視頻並將其返回

如需打開相機並接收拍攝的照片或視頻,請使用 ACTION_IMAGE_CAPTUREACTION_VIDEO_CAPTURE 操做。此外,還可在 EXTRA_OUTPUT extra 中指定相機將照片或視頻保存到的 URI 位置。

1.屬性設置

在這裏插入圖片描述
當相機成功將焦點歸還給 Activity(onActivityResult() 回調)時,能夠根據 EXTRA_OUTPUT 指定的 URI 訪問照片或視頻。

2.代碼示例

調用相機的方法若是按照Android 官方文檔上的作法是沒辦法實現的,緣由是調用相機其實會涉及到權限申請(6.0及其以上的系統),還會涉及到拍照完成後,獲取拍照的結果的問題,在 7.0 以前和 7.0 以後的獲取方式有很大差別,所以若是按照官方文檔的方式寫代碼,會發現根本調不起來相機。關於權限申請和相機相關的知識,咱們後面會單獨寫文章介紹。本文的目的只是幫助你們介紹一下Intent 的使用,因此若是你們遇到不太明白的代碼也不用太深究,重點看一下 Intent 便可。完整代碼示例以下,你們重點看下 dispatchTakePictureIntent() 方法裏的 Intent 用法便可:

public class MainActivity extends AppCompatActivity {
    private TextView mBtnCreateAlarm;
    private ImageView mIvCapturePhoto;

    private static final int MY_PERMISSIONS_REQUEST = 0;
    private static final int REQUEST_TAKE_PHOTO = 1;

    /** * 須要使用可是沒被受權的權限保存到此List集合中 */
    private List<String> permissionNotGrantedList = new ArrayList<>();
    private String currentPhotoPath;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mBtnCreateAlarm = findViewById(R.id.btn_create_alarm);
        mIvCapturePhoto = findViewById(R.id.iv_capture_photo);

        mBtnCreateAlarm.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                    //Android 6.0 及其以上系統內會動態去申請權限
                    checkPermission();
                } else {
                    dispatchTakePictureIntent();
                }
            }
        });

    }

    /** * Android 6.0 動態權限申請 */
    private void checkPermission() {
        // 判斷權限是否已經授予,沒有就把該權限添加到列表中
        if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA)
                != PackageManager.PERMISSION_GRANTED) {
            permissionNotGrantedList.add(Manifest.permission.CAMERA);
        }

        if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {
            permissionNotGrantedList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
        }

        if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {
            permissionNotGrantedList.add(Manifest.permission.READ_EXTERNAL_STORAGE);
        }

        // 若是列表爲空,就是所有權限都獲取了,不用再次獲取了。不爲空就去申請權限
        if (!permissionNotGrantedList.isEmpty()) {
            ActivityCompat.requestPermissions(MainActivity.this,
                    permissionNotGrantedList.toArray(new String[permissionNotGrantedList.size()]), MY_PERMISSIONS_REQUEST);
        } else {
            dispatchTakePictureIntent();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case MY_PERMISSIONS_REQUEST:
                List<String> list = new ArrayList();
                if (grantResults.length > 0) {
                    for (int i = 0; i < grantResults.length; i++) {
                        if (grantResults[i] == PackageManager.PERMISSION_DENIED) {
                            list.add(permissions[i]);
                        }
                    }

                    if (list.isEmpty()) {
                        dispatchTakePictureIntent();
                    }
                } else {
                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                }
                break;
            default:
                break;
        }
    }

    /** * 構建 Intent */
    private void dispatchTakePictureIntent() {
        Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

        if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
            File photoFile = null;
            try {
                photoFile = createImageFile();
            } catch (IOException ex) {

            }

            if (photoFile != null) {
                Uri photoURI;
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                    photoURI = FileProvider.getUriForFile(this, getPackageName() + ".fileprovider", photoFile);
                } else {
                    photoURI = Uri.fromFile(photoFile);
                }

                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
                startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
            }
        }
    }


    private File createImageFile() throws IOException {
        // Create an image file name
        String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
        String imageFileName = "JPEG_" + timeStamp + "_";
        File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        File image = File.createTempFile(
                imageFileName,
                ".jpg",
                storageDir
        );

        // Save a file: path for use with ACTION_VIEW intents
        currentPhotoPath = image.getAbsolutePath();
        return image;
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_TAKE_PHOTO && resultCode == RESULT_OK) {
            Bitmap bitmap = BitmapFactory.decodeFile(currentPhotoPath);
            mIvCapturePhoto.setImageBitmap(bitmap);
        }
    }
}
複製代碼

運行效果

拍攝照片或視頻並將其返回

(二)以靜態圖像模式啓動相機應用

以靜態圖像模式啓動相機應用的意思是直接跳轉到相機應用裏,拍照的照片直接保存到手機的相冊裏,不會將結果返回給調用的 Activity。以靜態圖像模式啓動相機應用須要用到的Action是:INTENT_ACTION_STILL_IMAGE_CAMERA

1.Intent 示例:

  • kotlin版本
fun capturePhoto() {
    val intent = Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA)
    if (intent.resolveActivity(packageManager) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_CAPTURE)
    }
}
複製代碼
  • Java版本
public void capturePhoto() {
    Intent intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
    }
}
複製代碼

2.intent-filter 示例

<activity ...>
    <intent-filter>
        <action android:name="android.media.action.STILL_IMAGE_CAMERA" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>
複製代碼

運行效果

以靜態圖像模式啓動相機應用
能夠看到拍照完成後,直接就把結果保存到了相冊裏,不會出現讓用戶選擇重拍或者選取拍照結果的按鈕。

(三)以視頻模式啓動相機應用

以視頻模式啓動相機應用須要用到的Action是:INTENT_ACTION_VIDEO_CAMERA

1.Intent 示例

  • Kotlin版本
fun capturePhoto() {
    val intent = Intent(MediaStore.INTENT_ACTION_VIDEO_CAMERA)
    if (intent.resolveActivity(packageManager) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_CAPTURE)
    }
}
複製代碼
  • Java版本
public void capturePhoto() {
    Intent intent = new Intent(MediaStore.INTENT_ACTION_VIDEO_CAMERA);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_CAPTURE);
    }
}
複製代碼

2.intent-filter 示例

<activity ...>
    <intent-filter>
        <action android:name="android.media.action.VIDEO_CAMERA" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>
複製代碼

4、聯繫人相關操做

(一)選擇聯繫人

若是須要獲取某個聯繫人,請使用 ACTION_PICK 操做,並將 MIME 類型指定爲 Contacts.CONTENT_TYPE。選取聯繫人後返回的結果是一個 content:URI。此操做是利用 Contacts Provider API 授予該該聯繫人的臨時讀取權限,所以不須要咱們去添加 READ_CONTACTS 權限。

1.屬性設置

選擇聯繫人
2.Intent 實例

  • Kotlin版本
const val REQUEST_SELECT_CONTACT = 1

fun selectContact() {
    val intent = Intent(Intent.ACTION_PICK).apply {
        type = ContactsContract.Contacts.CONTENT_TYPE
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivityForResult(intent, REQUEST_SELECT_CONTACT)
    }
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    if (requestCode == REQUEST_SELECT_CONTACT && resultCode == RESULT_OK) {
        val contactUri: Uri = data.data
        // Do something with the selected contact at contactUri
        //...
    }
}
複製代碼
  • Java版本
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 後如何檢索聯繫人詳情的信息在這裏不展開,咱們會在後面的文章中介紹。

(二)選擇聯繫人的某個特定數據

在上一節中,咱們介紹瞭如何選擇和獲取某個聯繫人的 Uri ,若是須要該聯繫人的其餘更具體的信息,咱們須要對該 Uri 進行特殊解析,這樣作的好處是咱們能夠根據該 Uri 獲取該聯繫人的全部信息,缺點是須要編寫更多的解析代碼。可是若是咱們的需求只是獲取某個聯繫人的電話號碼或者只須要某個聯繫人的郵箱(好比獲取張三這個聯繫人的電話號碼,或者獲取張三這個聯繫人的郵箱)這樣的需求就可使用本節介紹的內容。一樣的,本操做也不須要爲應用授予 READ_CONTACTS 權限。

1.屬性設置

選擇聯繫人的某個特定數據
2.Intent 實例

  • Kotlin版本
const val REQUEST_SELECT_PHONE_NUMBER = 1

fun selectContact() {
    // Start an activity for the user to pick a phone number from contacts
    val intent = Intent(Intent.ACTION_PICK).apply {
        type = CommonDataKinds.Phone.CONTENT_TYPE
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivityForResult(intent, REQUEST_SELECT_PHONE_NUMBER)
    }
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    if (requestCode == REQUEST_SELECT_PHONE_NUMBER && resultCode == Activity.RESULT_OK) {
        // Get the URI and query the content provider for the phone number
        val contactUri: Uri = data.data
        val projection: Array<String> = arrayOf(CommonDataKinds.Phone.NUMBER)
        contentResolver.query(contactUri, projection, null, null, null).use { cursor ->
            // If the cursor returned is valid, get the phone number
            if (cursor.moveToFirst()) {
                val numberIndex = cursor.getColumnIndex(CommonDataKinds.Phone.NUMBER)
                val number = cursor.getString(numberIndex)
                // Do something with the phone number
                ...
            }
        }
    }
}
複製代碼
  • Java版本
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
            //...
        }
    }
}
複製代碼

運行效果:

選擇聯繫人的某個特定數據

(三)查看聯繫人

咱們能夠根據聯繫人的 Uri 查詢該聯繫人的詳細信息,同時不須要任何應用權限。

1.屬性設置

查看聯繫人
1.Intent 示例

  • Kotlin版本
fun viewContact(contactUri: Uri) {
    val intent = Intent(Intent.ACTION_VIEW, contactUri)
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}
複製代碼
  • Java版本
public void viewContact(Uri contactUri) {
    Intent intent = new Intent(Intent.ACTION_VIEW, contactUri);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}
複製代碼

運行效果:

查看聯繫人

(四)編輯現有聯繫人

如需編輯已知聯繫人,請使用 ACTION_EDIT 操做,使用 content: URI 做爲 Intent 數據指定聯繫人,並將 extra 中由常量指定的任何已知聯繫人信息包括在 ContactsContract.Intents.Insert 中。同時,使用 ACTION_PICK 返回的聯繫人 URI 的話不須要任何權限。

1.屬性設置

編輯現有聯繫人
2.Intent 示例

  • Kotlin版本
fun editContact(contactUri: Uri, email: String) {
    val intent = Intent(Intent.ACTION_EDIT).apply {
        data = contactUri
        putExtra(ContactsContract.Intents.Insert.EMAIL, email)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}
複製代碼
  • Java版本
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);
    }
}
複製代碼

運行效果:

編輯現有聯繫人

(五)插入聯繫人

如需插入新聯繫人,使用 ACTION_INSERT 操做,將 Contacts.CONTENT_TYPE 指定爲 MIME 類型,Extra 裏保存聯繫人信息,聯繫人的信息的 Key 關鍵字定義在 ContactsContract.Intents.Insert 中,如ContactsContract.Intents.Insert.NAME

1.屬性設置

插入聯繫人
2.Intent 示例

  • Kotlin版本
fun insertContact(name: String, email: String) {
    val intent = Intent(Intent.ACTION_INSERT).apply {
        type = ContactsContract.Contacts.CONTENT_TYPE
        putExtra(ContactsContract.Intents.Insert.NAME, name)
        putExtra(ContactsContract.Intents.Insert.EMAIL, email)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}
複製代碼
  • Java版本
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);
    }
}
複製代碼

運行效果:

插入聯繫人

5、電子郵件

本節介紹發送電子郵件:

1.屬性設置

發送電子郵件
2.Intent 示例

  • Kotlin版本
fun composeEmail(addresses: Array<String>, subject: String, attachment: Uri) {
    val intent = Intent(Intent.ACTION_SEND).apply {
        type = "*/*"
        putExtra(Intent.EXTRA_EMAIL, addresses)
        putExtra(Intent.EXTRA_SUBJECT, subject)
        putExtra(Intent.EXTRA_STREAM, attachment)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}
複製代碼
  • Java版本
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 只由電子郵件應用(而非其餘短信或社交應用)進行處理,則需使用 ACTION_SENDTO 操做並加入 "mailto:" 類型的 Data。例如:

  • Kotlin版本
fun composeEmail(addresses: Array<String>, subject: String) {
    val intent = Intent(Intent.ACTION_SENDTO).apply {
        data = Uri.parse("mailto:") // only email apps should handle this
        putExtra(Intent.EXTRA_EMAIL, addresses)
        putExtra(Intent.EXTRA_SUBJECT, subject)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}
複製代碼
  • Java版本
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);
    }
}
複製代碼

3.intent-filter 示例

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <data android:type="*/*" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
    <intent-filter>
        <action android:name="android.intent.action.SENDTO" />
        <data android:scheme="mailto" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>
複製代碼

運行效果:

發送郵件

6、文件存儲

(一)獲取指定類型的文件

若是須要從文件管理器中獲取文檔或者照片可使用 ACTION_GET_CONTENT 操做並指定所需 MIME 類型。獲取的結果是文件的 URI。該 URI 能夠是任何類型,http: URI、file: URI 或 content: URI

在 Android 4.3(API 級別 18)及更高版本上,還能夠經過爲 Intent 添加 EXTRA_ALLOW_MULTIPLE 並將其設置爲 true,容許用戶選擇多個文件。而後就能夠在由 getClipData() 返回的 ClipData 對象中訪問每個選定的文件。

1.屬性設置

獲取指定類型的文件
2.Intent 示例

  • Kotlin版本
const val REQUEST_IMAGE_GET = 1

fun selectImage() {
    val intent = Intent(Intent.ACTION_GET_CONTENT).apply {
        type = "image/*"
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_GET)
    }
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    if (requestCode == REQUEST_IMAGE_GET && resultCode == Activity.RESULT_OK) {
        val thumbnail: Bitmap = data.getParcelableExtra("data")
        val fullPhotoUri: Uri = data.data
        // Do work with photo saved at fullPhotoUri
        ...
    }
}
複製代碼
  • Java版本
static final int REQUEST_IMAGE_GET = 1;

public void selectImage() {
    Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
    intent.setType("image/*");
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(intent, REQUEST_IMAGE_GET);
    }
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_IMAGE_GET && resultCode == RESULT_OK) {
        Bitmap thumbnail = data.getParcelable("data");
        Uri fullPhotoUri = data.getData();
        // Do work with photo saved at fullPhotoUri
        ...
    }
}
複製代碼

運行效果:

獲取指定類型的文件
固然,也能夠支持多選:

static final int REQUEST_IMAGE_GET = 1;

    public void selectImage() {
        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.setType("image/*");
        //在 Android 4.3(API 級別 18)及更高版本上
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
            intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
        }

        if (intent.resolveActivity(getPackageManager()) != null) {
            startActivityForResult(intent, REQUEST_IMAGE_GET);
        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == REQUEST_IMAGE_GET && resultCode == RESULT_OK) {
            ClipData clipData = data.getClipData();
            if (clipData != null) {
                StringBuilder stringBuilder = new StringBuilder();
                for (int i = 0; i < clipData.getItemCount(); i++) {
                    ClipData.Item itemAt = clipData.getItemAt(i);
                    Uri uri = itemAt.getUri();
                    stringBuilder.append(uri + "\n");
                }
                textView.setText(stringBuilder);
            }
        }
    }
複製代碼

獲取指定類型的文件-多選

(二)打開特定類型的文件

在 Android 4.4 或更高版本上運行時,可使用 ACTION_OPEN_DOCUMENT 來替代 ACTION_GET_CONTENT

1.屬性設置

打開指定類型的文件
2.Intent 示例

  • Kotlin版本
const val REQUEST_IMAGE_OPEN = 1

fun selectImage2() {
    val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
        type = "image/*"
        addCategory(Intent.CATEGORY_OPENABLE)
    }
    // Only the system receives the ACTION_OPEN_DOCUMENT, so no need to test.
    startActivityForResult(intent, REQUEST_IMAGE_OPEN)
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    if (requestCode == REQUEST_IMAGE_OPEN && resultCode == Activity.RESULT_OK) {
        val fullPhotoUri: Uri = data.data
        // Do work with full size photo saved at fullPhotoUri
        ...
    }
}
複製代碼
  • Java版本
static final int REQUEST_IMAGE_OPEN = 1;

public void selectImage() {
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
    intent.setType("image/*");
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    // Only the system receives the ACTION_OPEN_DOCUMENT, so no need to test.
    startActivityForResult(intent, REQUEST_IMAGE_OPEN);
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQUEST_IMAGE_OPEN && resultCode == RESULT_OK) {
        Uri fullPhotoUri = data.getData();
        // Do work with full size photo saved at fullPhotoUri
        ...
    }
}
複製代碼

7、電話

如需打開電話應用並撥打電話號碼,請使用 ACTION_DIAL 操做,並使用下文定義的 URI 架構指定電話號碼。電話應用打開時會顯示電話號碼,但用戶必需按撥打電話按鈕才能開始通話。

如需直接撥打電話,請使用 ACTION_CALL 操做,並使用下文定義的 URI 架構指定電話號碼。電話應用打開時便會撥打電話,用戶無需按撥打電話按鈕。

ACTION_CALL 操做須要您在清單文件中添加 CALL_PHONE 權限:

<uses-permission android:name="android.permission.CALL_PHONE" />
複製代碼

1.屬性設置

撥打電話
2.Intent 示例

  • Kotlin版本
fun dialPhoneNumber(phoneNumber: String) {
    val intent = Intent(Intent.ACTION_DIAL).apply {
        data = Uri.parse("tel:$phoneNumber")
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}
複製代碼
  • Java版本
public void dialPhoneNumber(String phoneNumber) {
    Intent intent = new Intent(Intent.ACTION_DIAL);
    intent.setData(Uri.parse("tel:" + phoneNumber));
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}
複製代碼

運行效果:

撥打電話

8、搜索

(一)使用特定應用搜索

如需支持在本身的應用環境內進行搜索,請使用 SEARCH_ACTION 操做在應用中聲明一個 Intent 過濾器,以下文示例 Intent 過濾器中所示:

<activity android:name=".SearchActivity">
    <intent-filter>
        <action android:name="com.google.android.gms.actions.SEARCH_ACTION"/>
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
</activity>
複製代碼

(二)使用網頁搜索

如需發起網頁搜索,請使用 ACTION_WEB_SEARCH 操做,並在 SearchManager.QUERY extra 中指定搜索字符串。

1.屬性設置

執行網頁搜索
2.Intent 示例

  • Kotlin版本
fun searchWeb(query: String) {
    val intent = Intent(Intent.ACTION_WEB_SEARCH).apply {
        putExtra(SearchManager.QUERY, query)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}
複製代碼
  • Java版本
public void searchWeb(String query) {
    Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
    intent.putExtra(SearchManager.QUERY, query);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}
複製代碼

運行效果:

使用網頁搜索

9、設置

如需打開某個系統設置頁面,請使用下列其中一個 Intent 操做:

  • ACTION_SETTINGS
  • ACTION_WIRELESS_SETTINGS
  • ACTION_AIRPLANE_MODE_SETTINGS
  • ACTION_WIFI_SETTINGS
  • ACTION_APN_SETTINGS
  • ACTION_BLUETOOTH_SETTINGS
  • ACTION_DATE_SETTINGS
  • ACTION_LOCALE_SETTINGS
  • ACTION_INPUT_METHOD_SETTINGS
  • ACTION_DISPLAY_SETTINGS
  • ACTION_SECURITY_SETTINGS
  • ACTION_LOCATION_SOURCE_SETTINGS
  • ACTION_INTERNAL_STORAGE_SETTINGS
  • ACTION_MEMORY_CARD_SETTINGS

Intent 示例

  • Kotlin版本
fun openWifiSettings() {
    val intent = Intent(Settings.ACTION_WIFI_SETTINGS)
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}
複製代碼
  • Java版本
public void openWifiSettings() {
    Intent intent = new Intent(Settings.ACTION_WIFI_SETTINGS);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}
複製代碼

運行效果:

打開設置

10、發送短信

如需發起短信或彩信,請使用如下其中一個 Intent 操做,並使用下列 extra 鍵指定電話號碼、主題和消息正文等消息詳情。

1.屬性設置

發送短信
2.Intent 示例

  • Kotlin版本
fun composeMmsMessage(message: String, attachment: Uri) {
    val intent = Intent(Intent.ACTION_SENDTO).apply {
        type = HTTP.PLAIN_TEXT_TYPE
        putExtra("sms_body", message)
        putExtra(Intent.EXTRA_STREAM, attachment)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}
複製代碼
  • Java版本
public void composeMmsMessage(String message, Uri attachment) {
    Intent intent = new Intent(Intent.ACTION_SENDTO);
    intent.setType(HTTP.PLAIN_TEXT_TYPE);
    intent.putExtra("sms_body", message);
    intent.putExtra(Intent.EXTRA_STREAM, attachment);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}
複製代碼

若是您想確保 Intent 只由短信應用(而非其餘電子郵件或社交應用)進行處理,則需使用 ACTION_SENDTO 操做並加入 "smsto:" 數據架構。例如:

  • Kotlin版本
fun composeMmsMessage(message: String, attachment: Uri) {
    val intent = Intent(Intent.ACTION_SEND).apply {
        data = Uri.parse("smsto:")  // This ensures only SMS apps respond
        putExtra("sms_body", message)
        putExtra(Intent.EXTRA_STREAM, attachment)
    }
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(intent)
    }
}
複製代碼
  • Java版本
public void composeMmsMessage(String message, Uri attachment) {
    Intent intent = new Intent(Intent.ACTION_SEND);
    intent.setData(Uri.parse("smsto:"));  // This ensures only SMS apps respond
    intent.putExtra("sms_body", message);
    intent.putExtra(Intent.EXTRA_STREAM, attachment);
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(intent);
    }
}
複製代碼

2.intent-filter 示例

<activity ...>
    <intent-filter>
        <action android:name="android.intent.action.SEND" />
        <data android:type="text/plain" />
        <data android:type="image/*" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>
複製代碼

參考文檔: 通用 Intent

相關文章
相關標籤/搜索