如何让别的app启动你的activity

转载请标明出处:http://blog.csdn.net/goldenfish1919/article/details/40540613

原文:http://developer.android.com/training/basics/intents/filters.html

前面两个章节主要介绍了如何在你的应用中启动别的应用的activity。但是,如果你的应用会做一些对别的应用有用的事情,那你的应用最好准备好能响应来自别的应用的请求。比如,如果你构建了一个能够让用户给朋友分享消息或者图片的社交app,那么你最好是支持ACTION_SEND,这样用户就可以在别的应用中发起一个分享,然后启动起来你的应用,然后做分享。


为了让别的app能启动你的activity,你需要在你的manifest文件中给对应的<activity>添加<intent-filter>。

当你的app被安装在设备上以后,系统会识别出你的intent filter,然后把这个信息添加到所有安装的应用都支持的内部intent目录中。当别的app使用隐式的intent来调用startActivity()或者startActivityForResult()的时候,系统会找出那些可以响应这个intent的那些activity。

添加Intent Filter

为了能合适的定义你的activity能够处理的intent,你所添加的intent filter都必须尽可能的具体,指定具体的action的类型和activity能接受的数据。

如果activity的intent filter能够满需指定的intent对象的下列标准,那么系统就可能会把这个intent发送给这个activity:

Action:以字符串命名的要执行的动作。一般是平台定义好的值比如ACTION_SEND或者ACTION_VIEW。在intent filter中用<action>元素来指定。它的值必须是这个动作的完整的名字,而不是一个API的常量。
Data:跟intent相关联的数据的描述。在intent filter中用<data>元素来指定。这个元素可以有一个或者多个属性,比如可以指定MIME类型,或者URI前缀,或者URI schema,或者能表明可接受的数据类型的它们的组合。

注意:如果你不需要声明指定数据的uri(比如你的activity处理的不是URI的其他类型的数据),那你你就应该只是指定android:mimeType属性,它声明了你的activity能处理的数据类型,比如:text/plain或者image/jpeg。

Category:它提供了一种额外的定制你的activity处理intent的方式,一般跟用户启动activity的手势和位置有关。系统支持很多种不同的category,但是大部分很少用到。但是,所有的隐式intent默认都是用CATEGORY_DEFAULT来定义的。在intent filter中用<category>元素来指定。

在你的intent filter中,你可以声明你的activity能接受的标准,只要给每一个<activity>内部添加对应<intent-filter>元素就可以。

比如:下面是一个带有能处理ACTION_SEND的intent filter的activity的例子,intent的数据类型是文本或者是图片:

<activity android:name="ShareActivity">
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="text/plain"/>
        <data android:mimeType="image/*"/>
    </intent-filter>
</activity>

每一个请求的intent都只指定了一个action和一个数据类型,但是也可以在<intent-filter>中声明多个<action>, <category>, 和<data>元素。

如果任意的一对action+data在行为上是互斥的,那么,你应该创建单独的intent filter来指定当一对action+data出现的时候,哪个动作是可接受的。

比如,加入对于ACTION_SEND和ACTION_SENDTO这两个intent,你的应用能够处理文本和图片。这种情况下,你必须要为这两个action定义单独的intent filter,因为ACTION_SENDTO会使用Uri来指定收信人的地址,比如:
<activity android:name="ShareActivity">
    <!-- filter for sending text; accepts SENDTO action with sms URI schemes -->
    <intent-filter>
        <action android:name="android.intent.action.SENDTO"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:scheme="sms" />
        <data android:scheme="smsto" />
    </intent-filter>
    <!-- filter for sending text or images; accepts SEND action and text or image data -->
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="image/*"/>
        <data android:mimeType="text/plain"/>
    </intent-filter>
</activity>

注意:为了能接收隐式的intent,在你的intent filter中必须要包含CATEGORY_DEFAULT这个category。startActivity()和startActivityForResult()会认为所有的intent都声明了CATEGORY_DEFAULT这个category。如果你没有在你的intent filter中做声明,那么隐式的intent就不会解析到你的activity。

在你的activity中处理intent

为了能决定你的activity要做哪一种动作,必须要能读取启动它的intent。

在你的activity启动的时候,调用getIntent()可以检索出启动你的activity的intent。你可以在activity声明周期的任意时刻来读取,但是一般都会在onCreate()或者onStart()这种比较靠前的回调中来读。就像这样:

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);


    setContentView(R.layout.main);


    // Get the intent that started this activity
    Intent intent = getIntent();
    Uri data = intent.getData();


    // Figure out what to do based on the intent type
    if (intent.getType().indexOf("image/") != -1) {
        // Handle intents with image data ...
    } else if (intent.getType().equals("text/plain")) {
        // Handle intents with text ...
    }
}

返回结果

当你想给调用你的activity返回一个结果的时候,只需要调用setResult()来指定结果码和结果intent。当你的操作完成以后,用户应该能返回到原先的activity,然后调用finish()来关闭(或者销毁)你的activity。
就像:
// Create intent to deliver some kind of result data
Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri");
setResult(Activity.RESULT_OK, result);
finish();
你必须总是在结果中指定一个结果码。一般来说,要么是RESULT_OK要么是RESULT_CANCELED。你还可以用Intent提供额外所需要的数据。

注意:默认情况下的返回结果是RESULT_CANCELED。因此,如果在动作完成以前,在还没来及设置结果的时候,用户按下了back键,那么调用方会收到一个取消的结果。

如果你仅仅是需要返回一个表明结果选项的一个整数值,那么你可以把结果值设置成任意比0大的数值。如果你使用结果码来传递整数值,那么就不需要包含intent了,只需要调用setResult()然后传递结果码就可以了。
比如:
setResult(RESULT_COLOR_RED);
finish();
在这种情况下,结果只能是数的过来的几个可能的值。所以,结果码可以是本地定义的比0大的整数。当在你自己的app中从一个activity给另一个activity返回结果的时候会非常有用。因为接受结果的activity可以引用定义了结果值的公共常量。

注意:没有必要区分你的activity是用startActivity()还是startActivityForResult()启动起来的。当启动你activity的intent需要一个返回结果的时候,调用setResult()就可以了。如果启动你activity调用了startActivityForResult(),那么系统会把你提供给setResult()的结果传递给它,否则,结果会被无视掉。

你可能感兴趣的:(如何让别的app启动你的activity)