文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

【android编程】第八讲-Intent和BroadcastReceiver

2022-06-06 13:27

关注

第八讲Intent和BroadcastReceiver

本讲介绍了Android应用程序中最为重要Intent和四大组件之一

文章目录第八讲Intent和BroadcastReceiverIntentIntent对象构成Component nameActionDataCategoryExtrasFlagsURI和intent-filter匹配:一个打电话和发短信示例1. 布局文件2. java文件3. 添加权限BroadcastReceiver标准广播有序广播发布广播-自定义标准广播示例:接收广播-接受广播示例:实现短消息提示示例题目记录 Intent

Intent可以启动一个Activity,也可以启动一个Service,还可以发起一个广播Broadcast。

组件名称 方法名称
Activity startActivity() startActivityForResult()
Service startService() bindService()
Broadcasts sendBroadcast() sendOrderedBroadcast()sendStickyBroadcast()

1.启动Activity:

向Context.startActivity() 或[Activity.startActivityForResult()](http://developer.android.com/reference/android/app/Activity.html#startActivityForResult(android.content.Intent, int))方法传递一个Intent对象,可以启动一个activity,或使得一个已经存在的activity去做一些新的事情。

(也可以向 [Activity.setResult()](http://developer.android.com/reference/android/app/Activity.html#setResult(int, android.content.Intent)) 去传递这个Intent对象,返回调用了

startActivityForResult()
的activity的一些信息。)

2.启动Service:

向 Context.startService() 方法传递Intent对象可以初始化一个service或者向一个已经存在的service传递新的指令。

类似的,向[Context.bindService()](http://developer.android.com/reference/android/content/Context.html#bindService(android.content.Intent, android.content.ServiceConnection, int)) 方法传递Intent对象可以在调用所在的组件和目标service之间建立一种连接。如果这个service并没有开始运行,则它可以初始化这个service。

3.发起广播Broadcast

可以向下面的广播方法传递Intent对象来发起广播:

Context.sendBroadcast(),[Context.sendOrderedBroadcast()](http://developer.android.com/reference/android/content/Context.html#sendOrderedBroadcast(android.content.Intent, java.lang.String)), 或 Context.sendStickyBroadcast()。系统会找到相应的广播接收者对此进行响应。

Intent在寻找目标组件时有两种方法:

第一种,显式调用,通过Component name直接指定;

第二种,隐式调用,没有明确指定目标组件的名称,那么就要通过一定的条件过滤筛选。

启动activity、service和broadcast的消息系统是没有任何重合的,即,一个要启动activity的Intent对象是绝对不会启动一个service的。

Intent对象构成

Intent对象由以下六个部分组成:

Component name
Action
Data
Category
Extras
Flags

Component name

Component name即组件名称,是要处理这个Intent对象的组件名称。

组件名称对象由ComponentName类来封装,组件名称包含包名称类名称,被声明在AndroidManifest.xml文件中。

组件名称通过 setComponent(),[setClass()](http://developer.android.com/reference/android/content/Intent.html#setClass(android.content.Context, java.lang.Class)),[setClassName()](http://developer.android.com/reference/android/content/Intent.html#setClassName(java.lang.String, java.lang.String))设置,通过getComponent()获取。

需要注意的是Component name是一个可选项,如果被设置,那么Intent对象就显式指定了要转向的组件,如果没有被设置,则Intent对象需要根据其他信息进行筛选查找。

Action

Action是指Intent要完成的动作,是一个字符串常量。

在Intent类里面定义了很多Action常量,其中有:

ACTION_MAIN: Android Application的入口,每个Android应用必须且只能包含一个此类型的Action声明。
ACTION_VIEW: 系统根据不同的Data类型,通过已注册的对应Application显示数据。
ACTION_EDIT: 系统根据不同的Data类型,通过已注册的对应Application编辑示数据。
ACTION_DIAL: 打开系统默认的拨号程序,如果Data中设置了电话号码,则自动在拨号程序中输入此号码
ACTION_CALL: 直接呼叫Data中所带的号码
ACTION_ANSWER: 接听来电
ACTION_SEND: 由用户指定发送方式进行数据发送操作
ACTION_SENDTO: 系统根据不同的Data类型,通过已注册的对应Application进行数据发送操作
ACTION_BOOT_COMPLETED: Android系统在启动完毕后发出带有此Action的广播(Broadcast)
ACTION_TIME_CHANGED: Android系统的时间发生改变后发出带有此Action的广播(Broadcast)
ACTION_PACKAGE_ADDED: Android系统安装了新的Application之后发出带有此Action的广播(Broadcast)
ACTION_PACKAGE_CHANGED: Android系统中已存在的Application发生改变之后(如应用更新操作)发出带有此Action的广播(Broadcast)
ACTION_PACKAGE_REMOVED: 卸载了Android系统已存在的Application之后发出带有此Action的广播(Broadcast)。

Intent类中有很多预定义的常量,为了一些通常的动作;还有一些定义在Android API的其他地方。

也可以自己定义Action常量,自定义的常量需要加上你的应用的包名作为前缀。

Action在很大程度上决定了Intent的其他部分是如何构造的,尤其是 data 和 extras域。(就好像函数名会决定着参数值和返回值一样。)所以Action的名字应该尽可能具体,并且它们应该和Intent中的其他域紧密结合。

使用 setAction() 和 getAction()来设置和读取Action属性。

Data

Data属性是执行动作的URI和MIME类型,不同的动作有不同的数据规格。

比如,Action是ACTION_EDIT时,数据域将是文档的URI;Action是ACTION_CALL时,数据域是 tel: URI ,带有要拨打的电话号码;如果Action是 ACTION_VIEW,则数据域是http: URI。

当匹配intent和能够处理intent所带的数据的组件时,知道数据类型(MIME类型)是很重要的。比如,一个展示图像的组件不应该被叫去播放一个音频。

很多情况下,从URI可以看出数据类型,比如content: URIs,表示数据是在设备上,但是是由content provider控制。

数据类型也可以显式指定,比如setData()方法指定数据为URI,setType() 指定为MIME type,[setDataAndType()](http://developer.android.com/reference/android/content/Intent.html#setDataAndType(android.net.Uri, java.lang.String)) 指定它既为URI又为MIME type。读取的时候URI用getData(),MIME type用getType()。

在intent-filter中指定data属性的实际目的是:要求接收的Intent中的data必须符合intent-filter中指定的data属性,这样达到反向限定Intent的作用。

tel://: 号码数据格式,后跟电话号码。
mailto://: 邮件数据格式,后跟邮件收件人地址
smsto://: 短息数据格式,后跟短信接收号码
content://: 内容数据格式,后跟需要读取的内容。
file://: 文件数据格式,后跟文件路径
market://search?q=pname:pkgname: 市场数据格式,在Google Market里搜索包名为pkgname的应用
geo://latitude,longitude: 经纬数据格式,在地图上显示经纬度指定的位置。
Category

Category是一个字符串,提供了额外的信息,有关于能够处理这个Intent对象的组件种类。

​ Category属性用于指定当前动作(Action)被执行的环境。通过addCategory()方法或在清单文件AndroidManifest.xml中设置。默认为:CATEGORY_DEFAULT

一个Intent对象中可以包含任意数量的category描述信息。

Intent类中也定义了一些Category常量:

Constant Meaning
*CATEGORY_DEFAULT: Android系统中默认的执行方式,按照普通Activity的执行方式执行。
CATEGORY_HOME: 设置该组件为Home Activity*。*
CATEGORY_PREFERENCE: 设置该组件为Preference*。*
CATEGORY_LAUNCHER: 设置该组件为在当前应用程序启动器中优先级最高的Activity,通常为入口ACTION_MAIN配合使用。
CATEGORY_BROWSABLE: 设置该组件可以使用浏览器启动
CATEGORY_GADGET: 设置该组件可以内嵌到另外的Activity

与category相应的方法有添加addCategory()、移除removeCategory() 和获取所有category getCategories() 。

Extras

传递给Intent的额外数据,以Bundle的形式定义,就是一些键值对。就好像一些动作和特定的数据URI对应,一些动作和特定的extras对应。

比如ACTION_TIMEZONE_CHANGED intent对象有一个 "

time-zone
"的extra来确认新的时区;

ACTION_HEADSET_PLUG
有一个"
state
" extra表示耳机是否插入,还有一个 “
name
” extra关于耳机类型;

如果你要设计一个SHOW_COLOR动作,那么extra中应该包含颜色值。

Intent对象有一系列的putXXX()函数用于放入各种数据类型,相应的也有一系列的getXXX()函数用于读取数据。

实际上,数据可以被作为一个Bundle对象被使用,利用 putExtras() 和 getExtras() 方法。

EXTRA_BCC: 存放邮件密送人地址的字符串数组。
EXTRA_CC: 存放邮件抄送人地址的字符串数组
EXTRA_EMAIL: 存放邮件地址的字符串数组
EXTRA_SUBJECT: 存放邮件主题字符串
EXTRA_TEXT: 存放邮件内容
EXTRA_KEY_EVENT: 以KeyEvent对象方式存放触发Intent的按键
EXTRA_PHONE_NUMBER: 存放调用ACTION_CALL时的电话号码
Flags

各种类型的Flag。很多是用来指定Android系统如何启动activity,还有启动了activity后如何对待它。所有这些都定义在Intent类中。

参考链接:https://www.cnblogs.com/mengdd/archive/2013/03/18/2965839.html

URI和intent-filter匹配:

Intent中URI和intent-filter进行比较的时候只会进行部分的比较:

(1)当intent-filter中只设置了scheme,只会比较URI的scheme部分;

(2)当intent-filter中只设置了scheme和authority,那么只会匹配URI中的scheme和authority;

(3)当intent-filter中设置了scheme、authority和path,那么只会匹配URI中的scheme、authority、path;(path可以使用通配符进行匹配)

(4)当intent-filter中设置了mimeType,还会进行数据类型的匹配。

一个打电话和发短信示例 1. 布局文件

    
2. java文件
package com.example.bean.myapplicationv0;
import android.Manifest;
import android.content.Intent;
import android.net.Uri;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.CALL_PHONE, Manifest.permission.SEND_SMS},1);
        //申请权限
    }
    public void myClick(View view){
        EditText et1 = (EditText)findViewById(R.id.et1);
        EditText et2 = (EditText)findViewById(R.id.et2);
        Button btn = (Button)view;
        Intent intent = new Intent();//新建对象
        switch (btn.getId()){
            case R.id.bt1:
                intent.setAction(Intent.ACTION_CALL);
                intent.setData(Uri.parse("tel:"+ et1.getText().toString()));
                break;
            case R.id.bt2:
                intent.setAction(Intent.ACTION_SENDTO);
                intent.setData(Uri.parse("smsto:"+ et1.getText().toString()));
                intent.putExtra("sms_body",et2.getText().toString());
                break;
        }
        startActivity(intent);//启动Intent
    }
}
3. 添加权限

在mainfest.xml中<application前面添加


BroadcastReceiver

Android四大组件之一,用于不同组件和多线程之间的通信。

标准广播

标准广播(Normal broadcasts):是一种完全异步执行的广播,在广播发出后,所有的广播接收器几乎都会在同一时间接收到这条广播,没有先后顺序。

有序广播

有序广播(Ordered broadcasts):是一种同步执行的广播,在广播发出后,同一时刻只有一个广播接收器能接收到广播。有先后顺序。

发布广播-自定义标准广播示例:
public  void myClick(View view){
        Intent intent = new Intent();
        intent.setAction("myBroadcast");
        intent.setPackage("com.example.bean.myapplication00");
        intent.putExtra("myMsg","Hello");
        sendBroadcast(intent);
    }
接收广播-接受广播示例:

myReceiver类

public class myReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context,intent.getStringExtra("myMsg"),Toast.LENGTH_SHORT).show();
    }
}

在mainfest.xml中下面


实现短消息提示示例

步骤:

创建BroadcastReceiver类的子类。
实现onReceive()方法。
配置AndroidManifest.xmI中的receiver。
action为: “android.provider.Telephony.SMS_RECEIVED”
配置AndroidManifest.xml的短信接收许可:“android.permission.RECEIVE_SMS”
配置判断主活动中是否授权了短信的接收许可,并申请短信接收许可。

New - Other - Broadcast Recerive新建MyReceiver

public class MyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // TODO: This method is called when the BroadcastReceiver is receiving
        // an Intent broadcast.
        //throw new UnsupportedOperationException("Not yet implemented");
        if (intent.getAction().equals("android.provider.Telephony.SMS_RECEIVED"))
        Toast.makeText(context,"有短信到了!",Toast.LENGTH_SHORT).show();
    }
}

权限


main.java判断是否有权限

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.RECEIVE_SMS)!= PackageManager.PERMISSION_GRANTED)
            ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.RECEIVE_SMS},1);
    }
}
题目记录 Intent的ComponentName属性主要是 C A.指明某一个包下的,要启动的组件 B.指明要启动的组件对应的类 C.用包名和类名唯一确定一个要启动的组件 D.指明要启动的组件0.00 对于Intent的说法下列哪些是不对的 C 老师说改B A.是一个被动的数据结构 0000 B.Android的四大组件都是通过Intent来激活的0.00 C.intent保存了一个将要执行操作的抽象描述 D.Intent是一个对象 下列哪个不是Intent常用的传输机制 D A.将一个Intent对象传递给任何广播方法,都可以传递到所有感兴趣的广播接收者0.00 B.将一个Intent对象传递给Context.startActivity()启动一个活动 C.将一个Intent对象传递给Context.startService()传递一个新指令给正在运行的Service D.将一个携带数据的Intent对象ContentProvider以提供开放的数据 对于Intent的Data属性下列说法不正确的是 D A.可以向Activity传递一些额外键值对信息0.00 B.Data是作用于Intent上的数据的URI和MIME类型 0000 C.不同的动作有不同的数据规格 D.可以使用setData()方法设置URI数据 Intetn的Data属性的数据类型可以是 D A.整型 B.字符型 C.实型 D.MIME Intent的Category属性是指 D A.Intent的分类0.00 B.Intent的Action属性分类 C.Intent的Data属性的分类 D.作为被执行动作的附加信息 Intent的Extras属性 D A.只是作为留用一般不使用 B.主要用于ContentProvider向外部提供信息 C.只能使用Bundle传递额外的键值对信息 D.可以传递额外的键值对信息 显示Intent是指 D A.使用new关键字声明的Intent B.在StartActivity中使用的Intent C.使用getIntent()方法获得的Intent D.通过名称指定目标组件的Intent 隐式Intent是指 B A.不指定Extra的Intent B.不指定目标名称的Intent1.00/1.00 C.不指定Action属性的Intent D.不指定Category的Intent Intent过滤器不检测的属性是 C A.Data B.Action C.Extra1.00/1.00 D.Category Intent的Action属性 A A.很大程度上决定了Intent如何构建1.00/1.00 B.与Intent其他属性互不影响 C.必须和Component属性一同使用 D.常用于组件的显式启动 Intent有两种形式其中一种是 A E A.显式Intent1.00/1.00 B.明确式Intent C.直接Intent D.声明式Intent E.隐式Intent 对于Intent过滤器,下列说法正确的是: B A.在Activity的onCreate()方法中配置过滤器 B.过虑器的标签是1.00/1.00 C.只能为某组件设置一个过滤器 D.过滤器只适用于隐式Intent 下列哪个不是Intent的功能? D A.用于启动组件 B.封装了程序的启动意图 C.交换数据 D.只用于启动Activity ComponentName属性 A A.使用setClass方法设置1.00/1.00 B.可以通过setComponentName()方法设置 C.使用setComponentClass()方法设置 D.使用Component的构造方法设置
作者:江山点墨


阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-移动开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯