Intent

Intent有三种基本的使用场景。

  • 启动一个Activity。
    • startActivity(),无法从新Activity获取结果。
    • startActivityForResut() ,然后重写 onActivityResult() 获取结果。
  • 启动一个Service
    • startService() ,启动一个服务执行一项操作,比如下载一个文件。
    • bindService()
  • 发送broadcast
    • sendBroadcast()
    • sendOrderedBroadcast()
    • sendStickBroadcast()

      Intent 类型

      有两种Intent
  • 显式Intent(Explicit Intent)
    在Intent中指定组件名称(class的完全限定名),通常用来启动app内部的组件。比如启动一个Activity响应用户的action,或者启动一个Service在后台下载一个文件。
  • 隐式Intent (Implicit Intent)
    不指定组件名称,而是声明一个通用的动作(action),允许另一个应用中的组件来处理这个动作。比如可使用另一个应用来在地图上显示用户位置。

如果创建了一个显式Intent来启动Activity或Service。系统会立即启动Intent中指定的组件。

如果创建了一个隐式Intent,系统通过将所有应用的清单文件(manifest file)中声明的intent filter和制定的Intent作比较,从而找到合适的组件,如果有个多个匹配结果,会弹出一个对话框让用户选择要执行的组件。

注意: 为了安全,启动Service时应该使用显式Intent,并且不要为自己的Service声明intent filter。从Android 5.0 (API Level 21)开始,如果bindService()中使用了隐式Intent,会抛出异常。

构建Intent

Intent 包括如下信息:

  • 组件名称(component name)
    指定了要启动的组件。指定组件名称就是显式Intent,否则是隐式Intent。
  • 动作(action),String类型
    指定了要执行的动作(如view或pick)。 Intent类中包含了一些常量定义了通用的Action。其他类中也定义了一些Action,比如Settings类。
    如果想自定义Action。需要定义一个常量定义,并且这个常量值应该以包名作前缀。如:

    static final String ACTION_TIMETRAVEL = "com.example.action.TIMETRAVEL";
    
  • 数据(Data)
    setData() ,指向要执行动作的数据的URI
    setType() ,指定数据的MIME Type
    setDataAndType() ,同时指定URI和MIME Type,不能通过两次setData()和setType()来代替本方法。

  • 类别(Category),String类型,指定了要处理该Intent的组件的种类。一个Intent可包含多个category,但是大多少Intent不需要Category。
    可调用addCategory()指定Category。
    常见的Category有CATEGORY_BROWSABLE,CATEGORY_LAUNCHER
  • 额外数据(Extras)
    可putExtra()添加额外数据,也可创建一个包括所有额外数据的Bundle对象,然后调用putExtras()。
  • 标识(Flag)
    指定了Android System如何运行一个Activity。

显示Intent示例

Intent downloadIntent = new Intent(this, DownloadService.class);
downloadIntent.setData(Uri.parse(fileUrl));
startService(downloadIntent);

隐式Intent示例

Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, textMessage);
sendIntent.setType("text/plain");
// Verify that the intent will resolve to an activity
if (sendIntent.resolveActivity(getPackageManager()) != null) {
    startActivity(sendIntent);
}

强制选择App

系统自带的Chooser可设置默认值,如果不需要这种行为。当有多个Activity匹配时,可强制弹出Chooser。

Intent sendIntent = new Intent(Intent.ACTION_SEND);
...
// Always use string resources for UI text.
// This says something like "Share this photo with"
String title = getResources().getString(R.string.chooser_title);
// Create intent to show the chooser dialog
Intent chooser = Intent.createChooser(sendIntent, title);
// Verify the original intent will resolve to at least one activity
if (sendIntent.resolveActivity(getPackageManager()) != null) {
    startActivity(chooser);
}

接收隐式Intent

<activity android:name="MainActivity">
    <!-- This activity is the main entry, should appear in app launcher -->
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
    </intent-filter>
</activity>
<activity android:name="ShareActivity">
    <!-- This activity handles "SEND" actions with text data -->
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="text/plain"/>
    </intent-filter>
    <!-- This activity also handles "SEND" and "SEND_MULTIPLE" with media data -->
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <action android:name="android.intent.action.SEND_MULTIPLE"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="application/vnd.google.panorama360+jpg"/>
        <data android:mimeType="image/*"/>
        <data android:mimeType="video/*"/>
    </intent-filter>
</activity>

results matching ""

    No results matching ""