Android知识点回顾之Intent/IntentFilter

定义:Intent是一个消息传送对象,可以用它来访问另外一个组件

可以用于以下三个场景:

  • startActivity
startActivity()
 startActivityForResult()
  • startService
    Android 5.0以上可以使用JobScheduler启动
    所有版本可以使用:
  startService();
  bindService();
  • sendBroadcast
    三种调用方法
sendBroadCast()
sendOrderedBroadCast()
sendStickyBroadcast()

Intent 类型

  • 显示类型
    直接指定调用组件的名字,一般用于自己的APP内部
  • 隐式类型
    没有指定组件的名字,而是声明一般的action行为,用此方法可以允许调用另外一个APP的组件

启动Service最好使用显示Intent,否则会存在安全风险,因为无法确定service什么时候被调用,而service又是用户感知不到的组件

Android 5.0开始,如果bindService()隐式调用启动service,会抛出异常

Intent的创建

一个Intent对象包含了Android系统应该启动哪个组件的信息

一个Intent可以包含以下信息:

  • componentName
    指定需要启动组件的名字
    此项是可选的,用来区分显示Intent和隐式Intent。
    赋值的方法有以下几种

    • Intent的构造方法
    • setComponent()
    • setClass()
    • setClassName
  • action
    指定Intent要完成的动作,为字符串常量
    action可自定义,也可使用系统的,一般自定义的话最好加上自己APP的包名前缀
    一些系统标准的Action常量
    ACTION_VIEW,startActivity(),唤起系统相册
    ACTION_SEND,startActivity(),把一些数据发送给另外的一些APP,如email,社交软件等
    ACTION_CALL,startActivity(),唤起打电话界面
    不定期补充...
    除了Intent定义了Action常量,其他的类也有定义,比如Settings,可以用来跳转到系统指定的设置界面
    action赋值的方法有一下几种:

    • Intent的构造方法
    • setAction()
  • data
    根据给定的Uri寻找匹配的目标组件,如果不给定MIME类型,会进行推导,给定MIME类型,则强制使用此类型。
    不同的Action有对应的data数据指定。
    其中data的值设置为setData(),MIME的设置为setType()
    常用值如下所示:
    tel://:      号码数据格式,后跟电话号码。 
    mailto://:    邮件数据格式,后跟邮件收件人地址。
    smsto://:    短息数据格式,后跟短信接收号码。
    content://:   内容数据格式,后跟需要读取的内容。 
    file://:      文件数据格式,后跟文件路径。
    geo:// latitude, longitude:经纬数据格式,在地图上显示经纬度所指定的位置。
    Uri指定数据指向那种数据格式,MIME指定数据具体的类型。比如Image和Audio有同样的Uri,但是MIME的类型是不同的。

setData()和setType()会互相覆盖,所以当需要同时设置Uri和MIME时,为了避免这种情况,可以调用setDataAndType()

  • category
    执行Action的附加信息。可以放置很多category,但是大多数intent是不需要category的
    常用值如下:
    CATEGORY_DEFAULT:Android系统中默认的执行方式,按照普通Activity的执行方式执行。 
    CATEGORY_HOME:设置该组件为Home Activity。
    CATEGORY_PREFERENCE:设置该组件为Preference。 
    CATEGORY_LAUNCHER:设置该组件为在当前应用程序启动器中优先级最高的Activity,通常为入口ACTION_MAIN配合使用。 
    CATEGORY_BROWSABLE:设置该组件可以使用浏览器启动。 
    CATEGORY_GADGET:设置该组件可以内嵌到另外的Activity中。
    通过addCategory()指定
  • extras
    用来存放需要传递的数据,以键值对的形式进行存储和访问
    通过putExtras()方法设置
  • flags
    设置Activity的启动模式,例如:
    FLAG_ACTIVITY_CLEAR_TOP
    FLAG_ACTIVITY_NEW_TASK
    FLAG_ACTIVITY_NO_HISTORY
    FLAG_ACTIVITY_SINGLE_TOP
    具体的笔记放到Activity上
    通过setFlags()方法设置

显示Intent的例子

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

隐式Intent的例子

其中resolveActivity()用来判断Intent是否能够被解析,防止APP崩溃

Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, textMessage);
sendIntent.setType("text/plain");
//Intent chooser = Intent.createChooser(sendIntent, title);//强制使用选择器
//if (sendIntent.resolveActivity(getPackageManager()) != null) {
//    startActivity(chooser);
//}
// Verify that the intent will resolve to an activity
if (sendIntent.resolveActivity(getPackageManager()) != null) {
    startActivity(sendIntent);
}

接收一个隐式Intent

需要在manifest文件中配置包含如下三个子项:



    
        
        
        
    

MIME类型 application/vnd.google.panorama360+jpg为指定的全景照片数据类型


    
    
        
        
    



    
    
        
        
        
    
    
    
        
        
        
        
        
        
    

使用PendingIntent

PendingIntent是对Intent的包装,使外部的APP能够像在内部APP那样对所包含的Intent进行使用
主要有如下的使用场景:

  • Notification
  • App Widget
  • AlarmManager

取得实例的方法如下:
PendingIntent.getActivity(),启动Activity
PendingIntent.getService(),启动Service
PendingIntent.getBroadcast(),启动BroadcastReceiver

状态栏通知:


  int icon = android.R.drawable.my_icon;
  long when = System.currentTimeMillis();//通知发生的时间为系统当前时间
  Notification notification = new Notification(icon, null, when);//新建一个通知,第一个参数为图标,第二个参数为短暂提示标题,第三个为通知时间
  notification.defaults = Notification.DEFAULT_SOUND;//发出默认声音
  notification.flags |= Notification.FLAG_AUTO_CANCEL;//点击通知后自动清除通知
  Intent openintent = new Intent(this, OtherActivity.class);
  PendingIntent contentIntent = PendingIntent.getActivity(this, 0, openintent, 0);//当点击消息时就会向系统发送openintent意图
  notification.setLatestEventInfo(this, "标题", "内容", contentIntent);//setLatestEventInfo表示设置点击该通知的事件
    int notifyCode = 0;
//获取通知管理器
  NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
  mNotificationManager.notify(notifyCode , notification);//第一个参数为自定义的通知唯一标识

action匹配规则

如果intent-filter设置了action的过滤规则,比如下面的XML代码,


    
    
    ...

那么:

  • intent不设置action,则直接不通过
  • intent设置了多个Action,则只要有一个匹配上,则可以通过
//不通过
Intent intent = new Intent();
//通过
intent.setAction("android.intent.action.EDIT");
//通过
intent.setAction("android.intent.action.EDIT");
intent.setAction("android.intent.action.test");

Category匹配规则

如果intent-filter设置了category的过滤规则,如下面的XML代码,


    
    
    ...

那么:

  • Intent不设置category,则都通过,不论intent-filter设置多少category
  • intent设置了category,intent上的category能够匹配上intent-filter设置的category,才能够通过

比如:

//通过
Intent intent = new Intent();
//通过
intent.addCategory("android.intent.category.DEFAULT"),可以匹配上
//通过
intent.addCategory("android.intent.category.BROWSABLE")
//不通过
intent.addCategory("android.intent.category.DEFAULT")
intent.addCategory("android.intent.category.test")

Data匹配规则

intent-filter中的结构由Uri和MIME Type组成
Uri包括如下几部分:

  • scheme:整个Uri的模式,如http,ftp,content等
    如果scheme未指定,则忽略host
    如果只指定scheme,则所有和intent-filter相同的scheme都匹配

  • host:Uri的域名,如www.google.com
    如果host未指定,则忽略port

  • port:Uri的端口

  • path:包含的路径信息,如:folder/subfolder/etc
    如果scheme,host都未指定,则忽略path

整体组成:://:/,如 content://com.example.project:200/folder/subfolder/etc

MIME Type:表示image/ipeg,video/*等媒体类型

匹配规则如下:
intent中的data必须和intent-filter完全匹配才能通过。有如下几种情况:
a.intent没有设置Uri和MIME Type,同时intent-filter也没有设置
b.intent只包含Uri,但未包含MIME Type,同时能够匹配上intent-filter设置的Uri,并且intent-filter为设置MIME Type
c.intent只设置MIME Type,同时intent-filter也设置了相同的MIME Type并且未指定Uri
d.intent设置了Uri和MIME Type,intent-filter只设置了MIME Type,则intent的Uri的scheme必须为content:或是file:。即,intent-filter如果没有设置Uri,只设置了MIME Type,则Uri为content:或file:的模式。也就是说,过滤的规则希望组件能够从文件(file)或内容提供者(content provider)获取到本地数据。

规则d例子,从相册获取图片:


    
    ...

则intent的匹配规则为:

 Intent intent = new Intent();
 intent.setDataAndType(Uri.parse("file://test"), "image/*");
 startActivity(intent);

如果intent-filter设置了多个data,则intent中的data只要和其中一个匹配就可以通过

为了防止APP崩溃,所有的intent匹配规则进行调用前都要进行判断处理:
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}

本知识点完~

你可能感兴趣的:(Android知识点回顾之Intent/IntentFilter)