• Intent学习


    1.Intent是什么


    Android中提供了Intent机制来协助应用间的交互与通讯,Intent负责对 
    应用中一次操作的动作、动作涉及数据、附加数据进行描述,Android则 
    根据此Intent的描述,负责找到对应的组件,将 Intent传递给调用的组 
    件,并完成组件的调用。 
    Intent不仅可用于应用程序之间,也可用于应用程序内部的Activity/Service 
    之间的交互。因此,Intent在这里起着一个中介的作用,专门提供组 
    件互相调用的相关信息,实现调用者与被调用者之间的解耦。

    2.Intent定义的内容


    在Android参考文档中,对Intent的定义是执行某操作的一个抽象描述。

    (1)Action,也就是要执行的动作 
    (2)Data,也就是执行动作要操作的数据 
    (3)type(数据类型) 
    (4)category(类别) 
    (5) component(组件) 
    (6) extras(附加信息)

    2.1)执行的动作(action)


    动作(action)的一个简要描述,如VIEW_ACTION(查看)、EDIT_ACTION 
    (修改)等,Android为我们定义了一套标准动作。

    系统定义的动作(action) 
    ACTION_CALL    activity    Initiate a phone call. 
    ACTION_EDIT    activity    Display data for the user to edit. 
    ACTION_MAIN    activity    Start up as the initial activity of a task, with no data input and no returned output. 
    ACTION_SYNC    activity    Synchronize data on a server with data on the mobile device. 
    ACTION_BATTERY_LOW    broadcast receiver    A warning that the battery is low. 
    ACTION_HEADSET_PLUG    broadcast receiver    A headset has been plugged into the device, or unplugged from it. 
    ACTION_SCREEN_ON    broadcast receiver    The screen has been turned on. 
    ACTION_TIMEZONE_CHANGED    broadcast receiver    The setting for the time zone has changed.

    2.2)执行动作要操作的数据(data)


    Android中采用指向数据的一个URI来表示, 
    如在联系人应用中,一个指向某联系人的URI可能为:content://contacts/1。

    这种URI表示,通过 ContentURI这个类来描述,具体可以参考android.net.ContentURI类的文档。

    以联系人应用为例,以下是一些action / data对,及其它们要表达的意图

    VIEW_ACTION content://contacts/1-- 显示标识符为"1"的联系人的详细信息 
    EDIT_ACTION content://contacts/1-- 编辑标识符为"1"的联系人的详细信息 
    VIEW_ACTION content://contacts/-- 显示所有联系人的列表 
    PICK_ACTION content://contacts/-- 显示所有联系人的列表,并且允许用户在列表中选择一个联系人,然后把这个联系人返回给父activity。

    --------------------code----------------- 
    action为Intent.ACTION_VIEW,data为ContactsContract.Contacts.CONTENT_URI 
    查看联系人列表

    Intent intent = new Intent(Intent.ACTION_VIEW,Uri.parse("content://com.android.contacts/contacts"));
    //Intent intent = new Intent(Intent.ACTION_VIEW,ContactsContract.Contacts.CONTENT_URI);


    startActivity(intent); 
    查看某一个联系人

    Intent intent = new Intent(Intent.ACTION_VIEW,Uri.parse("content://com.android.contacts/contacts/190"));
    //Intent intent = new Intent(Intent.ACTION_VIEW,ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, 190));

    startActivity(intent); 
    编辑某一个联系人

    Intent intent = new Intent(Intent.ACTION_EDIT,Uri.parse("content://com.android.contacts/contacts/190"));
    //Intent intent = new Intent(Intent.ACTION_EDIT,ContentUris.withAppendedId(ContactsContract.Contacts.CONTENT_URI, 190));


    startActivity(intent); 
    注意:不能编辑一个联系人列表。

    Intent intent = new Intent(Intent.ACTION_EDIT,Uri.parse("content://com.android.contacts/contacts"));//错


    显示联系人列表,并选择一个,然后获取该联系人信息;

    复制代码
    Intent intent = new Intent(Intent.ACTION_PICK,ContactsContract.Contacts.CONTENT_URI);
    startActivityForResult(intent, 100);
    @Override
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
            if(requestCode == 100){
                if(resultCode == RESULT_OK){
                    Uri uri = data.getData();
                    Cursor cursor = getContentResolver().query(uri, null, null, null, null);
                    if(cursor.moveToFirst()){
                        String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
                        System.out.println(name);
                    }
                    cursor.close();
                }
            }
        }
    复制代码


    -----------------------code-------------------------------

    复制代码
    Uri uri = data.getData();
    Cursor cursor = getContentResolver().query(uri, null, null, null, null);
    if(cursor.moveToFirst()){
        String name = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME));
        nameet.setText(name);
        String id = cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));
        
        Cursor c2 = getContentResolver().query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID+"="+id, null, null);
        c2.moveToFirst();
        String phone = c2.getString(c2.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
        phoneet.setText(phone);
        
        c2.close();
        cursor.close();
    }
    复制代码

     

    2.3)category 类别


    category(类别)是被执行动作的附加信息。

    2.4)type(数据类型)


    type(数据类型),显式指定Intent的数据类型(MIME)。一般Intent 
    的数据类型能够根据数据本身进行判定, 
    但是通过设置这个属性,可以强制采用显式指定的类型而不再进行推导。

    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setDataAndType(Uri.parse("file:///mnt/sdcard/a.pdf"),"application/pdf");
    startActivity(intent);

    2.5)component(组件)


    component(组件),指定Intent的的目标组件的类名称。 
    通常 Android会根据Intent 中包含的其它属性的信息 
    ,比如action、data/type、category进行查找,最终找到一个 
    与之匹配的目标组件。 
    但是,如果 component这个属性有指定的话,将直接 
    使用它指定的组件,而不再执行上述查找过程。 
    指定了这个属性以后,Intent的其它所有属性都是可选的。

    Intent intent = new Intent();
    ComponentName component = 
            new ComponentName(getApplicationContext(), SecondActivity.class);
    intent.setComponent(component);
    startActivity(intent);

    2.6)extras(附加信息)


    extras(附加信息),是其它所有附加信息的集合。使用extras可以为 
    组件提供扩展信息,比如,如果要执行“发送电子邮件”这个动作,可以 
    将电子邮件的标题、正文等保存在extras里,传给电子邮件发送组件。

    3.Android如何解析Intent


    在应用中,我们可以以两种形式来使用Intent:

    直接Intent:

    指定了component属性的Intent(调用setComponent 
    (ComponentName)或者setClass(Context, Class)来指定)。 
    通过指定具体的组件类,通知应用启动对应的组件。 
    间接Intent:没有指定comonent属性的Intent。这些Intent需要 
    包含足够的信息,这样系统才能根据这些信息,在所有的可用组件 
    中,确定满足此Intent的组件。

    间接Intent


    Intent解析机制主要是通过查找已注册在AndroidManifest.xml中 
    的所有IntentFilter及其中定义的Intent,最终找到匹配的Intent。

    IntentFilter意图筛选器 
    IntentFilter用来描述Activity能够做些什么事情。 
    应用程序的组件为了告诉Android自己能响应、处理哪些隐式Intent 
    请求,可以声明一个甚至多个Intent Filter。每个Intent Filter描 
    述该组件所能响应Intent请求的能力——组件希望接收什么类型的请求 
    行为,什么类型的请求数据。

    间接Intent匹配


    隐式Intent(Explicit Intents)和Intent Filter(Implicit Intents) 
    进行比较时的三要素是Intent的动作、数据以及类别。(隐式Intent:指的是在 
    Intent intent = new Intent()时的java代码,而Intent filter是在androidmanifest.xml 
    文件中定义的。) 
    实际上,一个隐式Intent请求要能够传递给目标组件,必要通过这三个方 
    面的 检查。如果任何一方面不匹配,Android都不会将该隐式Intent传递 
    给目标组件。接下来我们讲解这三方面检查的具体规则。

    隐式启动:

    Intent intent = new Intent();
    intent.setAction("com.anjoyo.myfirsttest");
    startActivity(intent);

    intent-filter配置:

    <activity android:name=".intentfilter.TestActivity">
        <intent-filter >
            <action android:name="com.anjoyo.myfirsttest"/>
            <category android:name="android.intent.category.DEFAULT"/>
        </intent-filter>
    </activity>

    补充

    1.作为一个程序为桌面程序

    复制代码
    <activity
        android:name=".intent.MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.HOME"/>
            <category android:name="android.intent.category.DEFAULT"/>
        </intent-filter>
    </activity>
    复制代码
    <category android:name="android.intent.category.HOME"/>回到桌面
    
    <category android:name="android.intent.category.LAUNCHER"/>作为应用的入口

    2.隐式Intent(Explicit Intents)和Intent Filter(Implicit Intents)


    进行比较时的三要素是Intent的动作、数据以及类别。 
    实际上,一个隐式Intent请求要能够传递给目标组件,必要通过这三个方面 
    的 检查。如果任何一方面不匹配,Android都不会将该隐式Intent传递给目 
    标组件。接下来我们讲解这三方面检查的具体规则。 
    1).动作测试 
    <intent-filter>元素中可以包括子元素<action>,比如:

    <intent-filter>
        <action android:name=”com.example.project.SHOW_CURRENT” />
        <action android:name=”com.example.project.SHOW_RECENT” />
        <action android:name=”com.example.project.SHOW_PENDING” />
    </intent-filter>

    一条<intent-filter>元素至少应该包含一个<action>,否则任何Intent 
    请求都不能和 该<intent-filter>匹配。 
    如果隐式启动一个Activity,那么还需要在<intent-filter>中加入 
     

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

    例子:

    复制代码
    <activity android:name="xxx"> 
        <intent-filter >
            <action android:name="com.anjoyo.mysecond"/>
            <category android:name="android.intent.category.DEFAULT"/>
        </intent-filter>
        <intent-filter >
            <action android:name="com.anjoyo.mysecond2"/>
            <action android:name="com.anjoyo.mysecond3"/>
            <category android:name="android.intent.category.DEFAULT"/>
        </intent-filter>
    </activity>
    复制代码

    action匹配规则:找到一个与隐式Intent的Action定义相同的Intent filter.

    2).类别测试 
    <intent-filter>元素可以包含<category>子元素,比如:

    <intent-filter>
        <category android:name=”android.Intent.Category.DEFAULT” />
        <category android:name=”android.Intent.Category.BROWSABLE” />
    </intent-filter>

    只有当Intent请求中所有的Category与组件中某一个IntentFilter的 
    <category>完全匹配时,才会让该Intent请求通过测试,IntentFilter 
    中多余的<category>声明并不会导致匹配失败。

    3).数据在<intent-filter>中的描述如下:

    <intent-filter>
        <data android:type=”video/mpeg” android:scheme=”http” . . . />
        <data android:type=”audio/mpeg” android:scheme=”http” . . . />
    </intent-filter>

    <data>元素指定了希望接受的Intent请求的数据URI和数据类型, 
    URI被分成三部分来进行匹配:scheme、authority和path。 
    其中,用setData()设定的Intent请求的URI数据类型和scheme必须 
    与IntentFilter中所指定的一致。若IntentFilter中还指定了 
    authority或path,它们也需要相匹配才会通过测试。

    如:http://www.baidu.com  http就是schema 
    tel:1390023232  tel就是schema 
    file:///mnt/sdcard/Picture/xx.jpg file就是schema

    例子:

    Intent intent = new Intent();
    intent.setAction(Intent.ACTION_CALL);
    intent.setData(Uri.parse("tel:123343"));
    startActivity(intent);
    复制代码
    <activity 
        android:name=".intent.ForthActivity">
        <intent-filter>
            <action android:name="android.intent.action.CALL"/>
            <category android:name="android.intent.category.DEFAULT"/>
            <data android:scheme="tel"/>
        </intent-filter>
    </activity>
    复制代码


    3. 
    1).向下一个Activity传递数据(使用Bundle和Intent.putExtras)

    Intent it = new Intent(Activity.Main.this, Activity2.class); 
    Bundle bundle=new Bundle(); 
    bundle.putString("name", "This is from MainActivity!"); 
    it.putExtras(bundle); 
    startActivity(it);


    对于数据的获取可以采用:

    Bundle bundle=getIntent().getExtras(); 
    String name=bundle.getString("name");

    2).向上一个Activity返回结果 
    (使用setResult,针对startActivityForResult(it,REQUEST_CODE)启动的Activity) 
       

    Intent intent=getIntent(); 
        Bundle bundle2=new Bundle(); 
        bundle2.putString("name", "This is from ShowMsg!"); 
        intent.putExtras(bundle2); 
        setResult(RESULT_OK, intent);

         
    回调上一个Activity的结果处理函数(onActivityResult)

    复制代码
    @Override 
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if(requestCode==REQUEST_CODE)
    { 
    if(resultCode==RESULT_CANCELED) 
        setTitle("cancle"); 
    else if (resultCode==RESULT_OK) 
    { 
        String temp=null; 
        Bundle (); 
        if(bundle!=null) 
            bundle=data.getExtras
        temp=bundle.getString("name"); 
        setTitle(temp); 
    } } }
    复制代码

    简单例子: 
    1,调用web浏览器

    Uri myBlogUri = Uri.parse(http://www.cmd100.com); 
     intent = new Intent(Intent.ACTION_VIEW, myBlogUri);

      2,地图

    Uri mapUri = Uri.parse("geo:38.899533,-77.036476"); 
     intent = new Intent(Intent.ACTION_VIEW, mapUri);

      3,调拨打电话界面

    Uri telUri = Uri.parse("tel:10086"); 
     intent = new Intent(Intent.ACTION_DIAL, telUri);


    4,直接拨打电话

    Uri callUri = Uri.parse("tel:10086"); 
     intent = new Intent(Intent.ACTION_CALL, callUri);

      5,卸载

    Uri uninstallUri = Uri.fromParts("package", "xxx", null); 
     intent = new Intent(Intent.ACTION_DELETE, uninstallUri);


    6,安装

    Uri installUri = Uri.fromParts("package", "xxx", null); 
     intent = new Intent(Intent.ACTION_PACKAGE_ADDED, installUri);


    7,播放

    Uri playUri = Uri.parse("file:///sdcard/download/everything.mp3"); 
     intent = new Intent(Intent.ACTION_VIEW, playUri);


    8,发邮件

    Uri emailUri = Uri.parse("mailto:xx@xxx.com"); 
     intent = new Intent(Intent.ACTION_SENDTO, emailUri);

      9,发邮件

    复制代码
    intent = new Intent(Intent.ACTION_SEND); 
     String[] tos = { "xx@xxx.com" }; 
     String[] ccs = { "xx@xxx.com" }; 
     intent.putExtra(Intent.EXTRA_EMAIL, tos); 
     intent.putExtra(Intent.EXTRA_CC, ccs);
     intent.putExtra(Intent.EXTRA_TEXT, "body"); 
     intent.putExtra(Intent.EXTRA_SUBJECT, "subject"); 
     intent.setType("message/rfc882"); 
     Intent.createChooser(intent, "Choose Email Client");
    复制代码


    10,发短信

    Uri smsUri = Uri.parse("tel:10086"); 
     intent = new Intent(Intent.ACTION_VIEW, smsUri); 
     intent.putExtra("sms_body", "hello~"); 
     intent.setType("vnd.android-dir/mms-sms");


    11,直接发邮件

    Uri smsToUri = Uri.parse("smsto://10086"); 
     intent = new Intent(Intent.ACTION_SENDTO, smsToUri); 
     intent.putExtra("sms_body", "hello");


    12,发彩信

    Uri mmsUri = Uri.parse("content://media/external/images/media/23");
     intent = new Intent(Intent.ACTION_SEND); 
     intent.putExtra("sms_body", "hello"); 
     intent.putExtra(Intent.EXTRA_STREAM, mmsUri); 
     intent.setType("image/png");


    用获取到的Intent直接调用startActivity(intent)就可以了。 

  • 相关阅读:
    sql压缩备份
    解决nodejs中的mysql错误 Error: ER_ACCESS_DENIED_ERROR: Access denied for user 'root'@'localhost'
    NodeJs创建新的项目和模块
    nodejsq发送formData的数据
    分析SQL语句的性能
    nest classvalidator验证修饰器中文文档
    STM8L不能通过代码设置ROP开启读保护
    uCOS邮箱的使用
    mysql忘记root密码了,怎么办
    01.mybatis
  • 原文地址:https://www.cnblogs.com/kevincode/p/3851732.html
Copyright © 2020-2023  润新知