Android Intent基础

Android Intent基础

在本篇博客中会涉及以下内容:

  • Intent的概念和基本知识以及使用
  • Action解析
  • Category解析
  • Data和Extras解析
  • 建立深度搜索(在浏览器搜索结果中打开APP特定页面)

Intent概念

Intent 即为意图,意图就是你要干啥。可以通过Intent告诉系统你要干什么,找谁干,怎么干(参数)。
Intent分为两种:

  • 显式意图

    系统根据开发者指定的组件选择处理意图的对象,使用setComponent或者setClass或者setClassName来显式指定处理意图的对象。适用条件是开发者准确知道可以处理该意图的对象的确切的位置,如果调用对象在应用内可以直接指定xxxx.class,如果调用其他应用则需要指定包名以及类名的确切路径。

  • 隐式意图

    隐式意图则是通过设置Action,Category,Data,Type等之后交给系统,由系统以及用户选择处理该意图的组件。

一些代码示例

//启动一个Activity、Service或是一个发送一个广播都离不开Intent
startActivity(intent);
startService(intent);
sendBroadcast(intent);
//startActivity,startService,sendBroadcast指明了要干什么
//找谁干和怎么干就需要设置Intent中的参数了

//intent中的参数
    private String mAction;//Action
    private Uri mData;//Data
    private String mType;//Type
    private String mPackage;
    private ComponentName mComponent;//classname
    private int mFlags;//启动模式
    private ArraySet mCategories;//Category
    private Bundle mExtras;//Bundle
    private Rect mSourceBounds;
    private Intent mSelector;
    private ClipData mClipData;
    private int mContentUserHint = UserHandle.USER_CURRENT;
    private String mLaunchToken;
/**
 * intent中参数的设置
 * setClass方式是由开发者来确定由谁来完成该项工作
 * 通过setAction,addCategory,setData,setType告诉系统工作的类型以及要处理的数据和处理数据的类型,
 * 由系统决定由谁来完成(可能需要用户的参与)
 * putExtra,将数据存在bundle中,通过Intent传递的额外的数据
**/

//显式意图(通过设置ComponentName参数指定完成意图的组件)
//设置Component参数一共有三种方式
intent.setClass(this,MainActivity.class);
intent.setClassName(this,"com.nullpointer.stud.MainActivity.class");
intent.setClassName("com.nullpointer.study","com.nullpointer.study.MainActivity");
//其实质都是通过包名和类名构造了一个ComponentName
//打开当前APP内组件可以不指定包名而通过context指定,但是实质还是使用包名
//打开其他应用的组件需要指定完整包名和全限定类名


//隐式意图
//通过setAction指定操作的类型,通过setData指定操作的数据,
//通过设置Category限定类别
//通过设置setType指定操作的对象的类型

//?下面的示例就指定了一个打开拨号界面的意图,并且指定了拨号界面的数据是朕的手机号码
intent.setAction(Intent.ACTION_DIAL);
intent.setDataAndType(Uri.parse("tel:18013116680"),"uri");

//?下面的示例就打开了指定的网页
intent.setAction(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.google.com"));

//?下面的示例就打开了搜索结果页面
intent.setAction(Intent.ACTION_WEB_SEARCH);
intent.putExtra(SearchManager.QUERY,"Android");

//需要注意的是  setData和setType互斥,如果需要同时设置 请使用setDataAndType();

public @NonNull Intent setData(@Nullable Uri data) 
    mData = data;
    mType = null;
    return this;
}
public @NonNull Intent setType(@Nullable String type) {
    mData = null;
    mType = type;
    return this;
}

Android 提供了很多标准Intent的使用范例,也预置了很多标准Action

谷歌在线文档

一个不错的中文示例

有些东西没必要去死记硬背,需要的时候去翻文档就好了

IntentFilter

就像前面讲到的,我们可以通过设置Action,设置data来让系统帮我们选择进行此操作的组件,或者应用。Action指定了将要操作的行为,是打开一个网页还是去打开一个拨号页面,或者是发短信、发邮件等等等等。Data就指定了要操作的数据。

我们使用了系统提供的Action可以方便地调用系统的一些服务。如果我们的应用需要被别的应用调用呢?这个时候我们可以设置自己应用Activity或者Service或者BrocastReceiver的interFilter来告诉系统我们的组件可以处理哪些数据。相信下面的代码大家一定不会陌生:

//这是应用的启动页,设置action=main和category=launcher表示这是应用的主屏,打开应用时默认打开的页面

    
        
        
    

Action:

一个想要执行的动作的名称,通常是系统已经定义好的值或者自定义的值。使用action进行匹配需要Intent中的Action可以和xml中定义的Action中的一个相同。

Data/Type:

Intent附带的数据以及数据的类型。分为两部分:URI和mimeType.
URI的格式:scheme://host:port/path|pathPattern|pathPrefix
mimeType的常见类型:image/*、video/*、string、text/plain等

Category:用的比较少,我也不是很懂。

系统也预定义了一些Category,或者开发者可以自定义。使用category进行过滤的规则是,如果Intent中包含Category,则每一个Category都被包含在xml中Intent-Filter中的设置的category中时才能匹配成功。

根据上面的介绍的匹配规则看一下下面的示例:



    
        
        
        

        
        
        

        
    

如果根据Action 进行匹配:下面两个Intent都可以与该Activity匹配成功

Intent intent1 = new Intent();
intent1.setAction("Intent.ACTION_SEND");

Intent intent2 = new Intent();
intent2.setAction("Intent.ACTION_SENDTO");

如果根据Data进行匹配:intent1匹配不成功,intent2则匹配成功

Intent intent1 = new Intent();
intent1.setDataAndType(Uri.parse("http://www.google.com"),"text/plain");

Intent intent2 = new Intent();
intent2.setData(Uri.parse("http://www.shaishufang.com/bookdetail?bid=1234"),"text/plain");

如果根据Category进行匹配:

  1. intent1可以匹配成功,因为添加的两个category在Activity的intent-filter中都有设置
  2. intent2匹配不成功,因为虽然Maps有设置,但是Email没有设置,根据规则必须两个都在intent-filter中设置才可以匹配成功。
Intent intent1 = new Intent();
intent1.addCategory(Intent.CATEGORY_APP_MAPS);
intent1.addCategory(Intent.CATEGORY_APP_BROWSER);

Intent intent2 = new Intent();
intent2.addCategory(Intent.CATEGORY_APP_MAPS);
intent2.addCategory(Intent.CATEGORY_APP_EMAIL);

如果将三种匹配规则进行混合匹配,则必须全部满足才能匹配成功。

实战演练

下面通过两个应用中的实例来直观的感受一下如何在我们的APP中设置intent-filter达到特定的目的。
现在假设用户可以通过我们的应用给好友发送数据,但是只能发文字,我们可以这么设置。(如果也可以发图片,把注释放开就可以了):



    
        
        
        
        
    

现在又有一个常见需求,在浏览器打开网页,自动跳转了app,也是通过设置IntentFilter实现的。



    
    
    
    
    
    

好了,关于Intent的基本知识就先到这里为止了。

你可能感兴趣的:(Android Intent基础)