Android Intent

对于Anddroid Intent。这个对大家来说想必是再熟悉不过了。比如开启一个activity啥的,都会用到它。

Android总结篇——Intent机制详解及示例总结

Intent简略描述

Intent中文意思,意图,可以理解为不同组件通信之间的"媒介",专门提供组件互相调用的相关信息。其中对于Android四大组件,Activity,BroadCaster,Service, ContentProvider,这几个应该有个大致上的了解了。Intent的使用与前三个都有关系。Intent可以理解为一个将要执行的动作的抽象描述,一般来说是作为参数来使用,由Intent来协助完成Android各组件之间的通信。比如说调用startActivity()来启动一个Activity,或者由broadcastIntent()来传递给所有感兴趣的BroadCaseReceiver,再或者由startService()/bindService()来启动一个后台的Service,所以可以看出来,intent主要是用来启动其他的activity,service,所以可以将intent理解为activity之间的粘合剂。


Intent关于启动组件的相关方法

1 Activity 的启动,有 startActivity(), startActivityForResult().

2 Service :有 startService(), bindService()

3 Broadcasts: sendBroadcasts(), sendOrderedBroadcasts(), cendStickyBroadcasts().


Intent涉及的属性:

源码中部分intent类的成员变量:

    private String mAction;
    private Uri mData;
    private String mType;
    private String mPackage;
    private ComponentName mComponent;
    private int mFlags;
    private ArraySet<String> mCategories;
    private Bundle mExtras;
    private Rect mSourceBounds;
    private Intent mSelector;
    private ClipData mClipData;
    private int mContentUserHint = UserHandle.USER_CURRENT;

其中最常用的是Action属性和Data属性。

1 Action属性

action属性一般被作为

mOpenActivityBTv.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent  = new Intent(BActivity.ACTION);
                startActivity(intent);
            }
        });
public static final String ACTION = "android.intent.action.myBActivity";
        <activity android:name=".Activity.BActivity">
            <!--需要注意的是,action要和category都要设置,否则会出现调用不起来的异常-->
            <intent-filter>
                <action android:name="android.intent.action.myBActivity"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
        </activity>

action通常用作隐式启动activity。它在intent的初始化里无需给出到底要跳到哪个activity,只需要写下activity具有的特点就可以。这样跳转的时候,跳转条件相匹配的activity就会启动。。针对于这些跳转条件,就是在AndroidManifest.xml文件中给出的。

当然上述代码的action是我们自定义的,对于android系统而言,里面有好多已经写好的action可以供我们使用。如下:

Android常用的intent action汇总

Intent.ACTION_MAIN: 标识Activity为一个程序的启动activity。

Intent.ACTION_CALL: 呼叫执行的电话号码。

Intent intent = new Intent();
intent.setAction(Intent.ACTION_CALL);
intent.setData(Uri.paese("tel:10086"));
startActivity(intent);

Intent.ACTION_POWER_CONNECTED:插上外部电源的时候发出的广播

Intent.ACTION_POWER_DISCONNECTED: 已断开外部电源连接时发出的广播。

Intent.ACTION_DIAL: 调用拨号面板

Intent intent = new Intent();
intent.setAction(Intent.ACTION_DIAL);
intent.setData(Uri.parse("tel : 10086"));
startActivity(intent);

Intent.ACTION_ALL_APPS:列出所有的应用。

Intent.ACTION_ANSWER:处理呼入的电话

Intent.ACTION_BUG_REPORT:显示bug报告。

Intent.ACTION_CALL_BUTTON:相当于按拨号键。

Telephony_SMS_RECEIVED:接收短信的action

<intent-filter>
  <action android:name="android.provider.Telephony.SMS_RECEIVED"/>
  <data android:host="localhost"/>
</intent-filter>

Intent.ACTION_GET_CONNECT:允许用户选择特殊类的数据,并返回(特殊种类的数据:照一张照片或者录一点音)

Intent.ACTION_BATTERY_LOW:标识电池电量低

Intent.ACTION_SEND:发送邮件的action

Intent>ACTION_CALL_PRIVILEGED:调用skype的action:

Intent intent = newIntent("android.intent.action.CALL_PRIVILEGED");
intent.setClassName("com.skype.raider",
"com.skype.raider.Main");
intent.setData(Uri.parse("tel:" + phone));
startActivity(intent);
Intent.ACTION_CLOSE_SYSTEM_DIALOGS:当屏幕超时进行锁屏时,当用户按下电源按钮,长按或者短按,进行锁屏时,andriod都会广播此Action消息。


2Data和Extras,即执行动作要操作的数据和传递目标的附加信息

浏览器交互案例:

public void invokeWebBrowser() {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setData(Uri.parse("http://baidu.com"));
        startActivity(intent);
}

public void involeWebSearch() {
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_WEB_SEARCH);
        intent.putExtra(SearchManager.QUERY, "android");
        startActivity(intent);
}

上述的两个方法,第一个是启动浏览器并打开指定的网页,第二个是进行关键字的搜索。分别针对的action是Intent.ACTION_VIEW, 和 Intent.ACTION_WEB_SEARCH,前者需要指定相应的网页,后者需要指定关键字信息,对于关键字搜索来说,浏览器会按照自己设置的默认搜索引擎进行搜索。

但是应当注意到的是,在打开网页的时候,Inten指定了一个data属性,这其实是指定要操作的数据,是一个URL的形式,我们可以将一个指定前缀的字符串转换成特定的URI类型,比如http, https 表示网络地址类型, tel表示电话号码类型, mailto表示邮箱地址类型,如果要给呼叫指定的电话号码,可以这样写:

public void call10086() {
        Intent intent = new Intent(Intent.ACTION_CALL);
        intent.setData(Uri.parse("tel : 10086"));
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            Toast.makeText(getApplicationContext(), "没有得到权限", Toast.LENGTH_LONG).show();
            return;
        }
        startActivity(intent);
    }

那么我们如何知道目标是否接受这种前缀呢?看下<data>标签的匹配规则。

android:scheme 匹配url中的前缀,除了"http", "https", "tel"之外,还可以定义自己的前缀

android:host: 匹配url中的主机名部分,比如“baiducom”,如果定义为*,就表示匹配任意主机名

android:port:匹配url中的端口

android:path 匹配url中的路径。

如果此时你想写一个自己的activity来响应这样的intent,使其startActivity的时候可以打开自己自定义的这个activity,那么需要在AndroidManifest.xml文件中写出对应的规则即可。

所以看下面代码:

 <activity android:name=".Activity.IntentTestActivity2">
            <intent-filter>
                <action android:name="android.intent.action.INTENTTESTACT2"/>

                <category android:name="android.intent.category.DEFAULT"/>

                <data android:scheme="yayali" android:host="music.zhangbichen" android:path="/xuerumo" android:port="8888" />
            </intent-filter>
        </activity>

可见新写的这个Activity定义了他的隐式启动匹配规则。这个规则是我们自己定义的。那么当我们这么调用的时候,就会打开。

private void openItentTestActivit2() {
        Intent intent = new Intent();
        intent.setAction(IntentTestActivity2.INTENT_OPEN);
        intent.setData(Uri.parse("yayali://music.zhangbichen:8888/xuerumo"));
        startActivity(intent);
    }

这种情况下,url中的每一个部分必须和TargetActivity匹配信息中全部一致才能跳转成功。否则就会被系统拒绝。

Intent有一个也相当中要的方法,叫putExtra(),这个方法实则是和Extra有些关系。上面也有用到过这个方法,就是搜索关键字的时候。对于putExtra,实则是将数据加到了一个Bundle里面,bundle又维护了一个map。例如:

 /**
     * Add extended data to the intent.  The name must include a package
     * prefix, for example the app com.android.contacts would use names
     * like "com.android.contacts.ShowAll".
     *
     * @param name The name of the extra data, with package prefix.
     * @param value The boolean data value.
     *
     * @return Returns the same Intent object, for chaining multiple calls
     * into a single statement.
     *
     * @see #putExtras
     * @see #removeExtra
     * @see #getBooleanExtra(String, boolean)
     */
    public @NonNull Intent putExtra(String name, boolean value) {
        if (mExtras == null) {
            mExtras = new Bundle();
        }
        mExtras.putBoolean(name, value);
        return this;
    }
/**
     * Inserts a Boolean value into the mapping of this Bundle, replacing
     * any existing value for the given key.  Either key or value may be null.
     *
     * @param key a String, or null
     * @param value a boolean
     */
    public void putBoolean(@Nullable String key, boolean value) {
        unparcel();
        mMap.put(key, value);
    }

category 要执行的目标所局域的特质或者归类

在AndroidManifest.xml中,总会有一个Activity是启动的第一个是anctivity,他们的配置大多是这个样子

<activity android:name=".Activity.IntentTestActivity1" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

里面就用到了一个很重要的关键字--category,上方代码代表的是该应用所在的task中的初始Activity并且出现在系统launcher应用列表中。

常见的category有下面几项:

常量

解释

CATEGORY_DEFAULT

默认的category

CATEGORY_BROWSABLE

指定了此category后,在网页上点击图片或链接时,系统会考虑将此目标Activity列入可选列表,供用户选择以打开图片或链接。

CATEGORY_GADGET

The activity can be embedded inside of another activity that hosts gadgets.

CATEGORY_HOME

The activity displays the home screen, the first screen the user sees when the device is turned on or when the HOME key is pressed.

CATEGORY_LAUNCHER

The activity can be the initial activity of a task and is listed in the top-level application launcher.

CATEGORY_PREFERENCE

表示该目标Activity是一个首选项界面;


为Intent设置category时,应是应用addCategory(sting category)方法向intent中添加指定的类别信息,来匹配声明此类别的目标Activity。 

如下,是回到Home界面的例子:

private void gotoHome() {
        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_HOME);
        startActivity(intent);
    }

Type:要执行动作的目标Activity所能处理的MIME数据类型。

例如一个可以处理图片的目标activity在其声明中包含这样的mimeType:

<data android:mimeType="image/*"/>

在使用intent进行匹配的时候,我们可以使用setType(String type)或者setDataAndType(Uri data, String type)来设置mimeType。

Component目标组件的包或者类名:

在使用component进行匹配的时候一般采用以下几种形式:

1 intent.setComponent(new ComponentName(getApplicationContext(), TargetActivity.class));  
2 intent.setComponent(new ComponentName(getApplicationContext(), "com.scott.intent.TargetActivity"));  
3 intent.setComponent(new ComponentName("com.scott.other", "com.scott.other.TargetActivity")); 

其中前两种用于匹配同一包中的目标,第三种用于匹配其他包内的目标。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值