• Android允许其他应用程序启动你的Activity


    本文译自:http://developer.android.com/training/basics/intents/filters.html

    前面的两课一直关注了故事的一边:从你的应用程序中启动另一个应用程序的Activity。但是如果你的应用能够执行一个可能对另外的应用程序有用的操作,那么你的应用程序就应该准备响应来自其他应用程序的操作请求。例如,如果你创建了一个能够跟用户的朋友共享消息和照片的社区应用,那么你就应该支持ACTION_SEND类型的Intent,以便用户能够启动来自其他应用程序的共享操作,并加载你的应用程序来执行这个操作。

    要允许其他的应用程序来启动你的Activity,你需要在你的清单文件的相应的<activity>元素中添加一个<intent-filter>元素。

    当你的应用程序被安装到设备上时,系统会识别你的Intent过滤器,并把这个信息添加到一个由所有被安装应用程序所支持的内部的Intent目录中。当一个应用程序用隐含的Intent对象来调用startActivity()或startActivityForResult()方法时,系统就会在这个目录中查找那些Activity能够响应这个Intent的请求。

    添加Intent过滤器

    为了能够正确的定义你的Activity所能处理的Intent对象,Activity接收的操作和数据应该尽可能在每个被添加的Intent过滤器中进行具体的定义。

    如果Activity有一个跟下列Intent对象条件完全匹配的Intent过滤器,系统就会把给定的Intent对象发送给这个Activity:

    Action

       定义要执行的操作名称(字符串)。通常是由平台定义的一个值,如ACTION_SEND或ACTION_VIEW。

       使用过滤器中的<action>元素来指定操作。在这个元素中指定的值必须是该操作完整的字符串名称,而不是API常量。

    Data

       定义跟该Intent匹配的数据

       使用过滤器中的<data>元素来指定数据。使用这个元素中的一个或多个属性,你能够只简单指定MIME类型、URI前缀、URI方案,或者是这些的组合,以及其他的能够接收的数据类型的指示。

       注意:如果你不需要声明指定相关数据的Uri(如当你的Activity要处理其他类型的附加数据时,而不是URI),那么就应该只指定android:mimeType属性来声明你的Activity所能处理的数据类型,如text/plain或image/jpeg。

    Category

       提供两外一种Activity处理Intent对象的方法,通常与用户的手势或其他的位置有关。系统支持几种不同的分类,但是很少被使用。但是默认情况下,所有的隐含的Intent对象都要使用CATEGORY_DEFAULT来定义。

       在Intent过滤器中使用<category>元素来指定这个分类信息。

    在你的Intent过滤器中,你可以在<intent-filter>元素中嵌套上述对应XML元素来声明你的Activity所能接收的Intent对象的条件。

    例如,以下Activity的Intent过滤器的声明,能够处理ACTION_SEND类型的Intent对象,并且数据类型可以是文本或图片:

    <activityandroid: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对象只能指定一个操作和一种数据类型,但是在每个<intent-filter>元素中则可以声明多个<action><category><data>元素的实例。

    如果任何两个操作和数据的行为是相互排斥的,那么你应该给它们建立独立的Intent过滤器,并在每个Intent过滤器中指定其可接收的操作和对应的数据类型。

    例如,假设你的Activity可以使用ACTION_SENDACTION_SENDTO类型的Intent来处理文本和图片。这种情况下,你就必须给这两个操作分别定义独立的Intent过滤器,因为ACTION_SENDTO类型的Intent对象必须使用数据的Uri来指定收件人的地址,例如:

    <activityandroid: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过滤器中必须包含CATEGORY_DEFAULT分类。如果包含了CATEGORY_DEFAULT分类,startActivity()startActivityForResult()方法启动的所有的Intent对象就会被处理,否则,隐式的Intent对象就不会被你的Activity所接收。

    在你的Activity中处理Intent对象

    为了决定在你的Activity中要执行的操作,你可以读取启动该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 ... 
        } 
    }

    返回结果

    如果你想要把结果返回给调用者,只需简单的调用setResult()方法来指定具体的结果代码和结果Intent对象。当操作完成后,并要返回到最初的调用者,就要调用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_OKRESULT_CANCELED。然后根据需要使用一个Intent对象来提供另外的数据。

    注意:默认的结果会被设置为RESULT_CANCELED。因此,在操作完成和结果被设定之前,如果用户按下返回按钮,那么初始的Activity就会收到“被取消”的结果。

    如果你只是简单的返回一个整数,来指明几个可选结果中的一个,那么你把结果代码设置为任何比0大的值。如果你使用结果代码来发送一个整数,并且不需要包含Intent对象,那么你就可以调用setResult()方法,并且只给它传递一个结果代码。例如:

    setResult(RESULT_COLOR_RED); 
    finish
    ();

    在这种情况中,可能的结果很少,因此结果代码可以是本地定义的整数(比0大)。这样在把结果返回给你自己应用程序中的Activity时,就会很好的工作,因为接收结果的Activity可以引用公共的常量来判断结果代码的值。

    注意:不需要检查你的Activity是使用startActivity()方法、还是使用startActivityForResult()方法来启动的。如果启动你的Activity期望要有返回结果,那么只需简单的调用setResult()方法就可以了。如果启动Activity调用的是startActivityForResult()方法,那么系统就会把你提供给setResult()方法的结果发送给它,否则,这个结果会被忽略。

  • 相关阅读:
    P2114 [NOI2014]起床困难综合症(二进制)
    P4577 [FJOI2018]领导集团问题
    P5290 [十二省联考2019]春节十二响(堆+启发式合并)
    P2048 [NOI2010]超级钢琴(RMQ+堆+贪心)
    P4890 Never·island(dp)
    P2617 Dynamic Rankings(树状数组套主席树)
    P5241 序列(滚动数组+前缀和优化dp)
    P3243 [HNOI2015]菜肴制作(拓扑排序)
    【LeetCode每天一题】Combination Sum II(组合和II)
    【LeetCode每天一题】Combination Sum(组合和)
  • 原文地址:https://www.cnblogs.com/xinyuyuanm/p/2995331.html
Copyright © 2020-2023  润新知