安卓中Intent

来源:互联网 发布:石家庄鸿搜网络怎么样 编辑:程序博客网 时间:2024/04/26 17:05

Intent学习

Intent属性的详解
         在android操作系统中,Intent(意图)主要用于激活系统组件、在组件之间传递数据。


Intent也可以实现调用Android系统内置的功能,例如拨打电话等。
Intent可以理解为组件之间的“连接器”,可以用于激活Activity、Service、BroadcastReceiver,但不用于激活Content Provider;


Intent与系统组件有密切的关系,但Intent不是系统组件,它由开发人员创建并维护。

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

 在Activity中,激活另一个Activity时可以在Intent对象中封装数据:

 Intent intent = new Intent(getApplicationContext(),SecondActivity.class);    intent.putExtra("name","Beckham");    startActivity(intent);    SecondActivity          Intent intent = getIntent();  String name = intent.getStringExtra("name");

 Intent的六个核心属性包括:
            Component Name:组件名称;
   Action:动作;
   Data:数据;
   Category:分类;
   Extra:附加信息;
   Flag:标志。
Component Name表示组建名称,使用Intent激活系统组件时,通过设置该属性的值来确定被激活的组件。
Component Name 属性的数据类型是ComponentName;
通过Intent的构造方法、setComponent()方法、setClass()方法、setClassName()方法均可以设置Component Name属性的值。


以下代码可以设置Component Name属性:

Intent intent = new Intent(getApplicationContext(),SecondActivity.class);

 Intent intent = new Intent();     intent.setClass(getApplicationContext(),SecondActivity.class);

 Intent intent = new Intent();     intent.setClassName(getApplicationContext(),"cn.com.tarena.demo.SecondActivity");

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

显示意图:再激活系统组件时,明确的指定了被激活的组件时,该Intent被称之为“显示意图”。


   Action
        Action表示动作,通常用于隐式激活组件,即不指定组建的名称。这样的Intent被称之为“隐式意图”;


Action属性的数据类型是String类型。
Android系统在Intent类中定义了一系列以ACTION_为前缀的常量,例如ACTION_DIAL,可用于激活系统的拨号程序。
通过setAction()方法可以设置Action属性的值。
Intent intent = new Intent();
intent.setAction(Intent.ACTION_DIAL);
startActivity(intent);
  Data
       Data表示数据,通常与Action属性匹配使用,用于指定某个动作所需要的,或被操作的数据。
       Data属性的数据类型是Uri类型,该类型的数据可以通过Uri.parse()将字符串转换得到。
       通过Intent的构造方法,setData()方法可以设置Data属性的值。


       以下代码可以设置Data属性:
          Intent intent = new Intent();
 intent.setAction(Intent.ACTION_DIAL);
 intent.setData(Uri.parse("tel://4956579367"));
 startActivity(intent);


 Intent intent = new Intent(Intent.ACTION_DIAL,Uri.parse("tel://567458675487654"));
 startActivity(intent);


 注意:不要使用Data属性封装与Action无关的数据。
 Data属性实际上包括Uri和Type这2部分,分别表示“通用资源标识符”和数据的“MIME类型”。
 通过setType()方法、setDataAndType()方法可以设置Type属性的值。
 Intent intent = new Intent();
 intent.setDataAndType(Uri.parse("file://mnt/scdard/demo.mp3"),"audio/mp3");
 Intent intent = new Intent();
 intent.setDataAndType(Uri.parse("file:///mnt/sdcard/demo.mp3"),"audio/mp3");


 Category
    Category表示分类,用于表示组件的类别,在Intent对象中,可以添加多个Category。
    Category的数据类型是String类型。
    涉及Category时,通常应用于隐式意图,且存在Intent Filter(意图过滤器),Intent与IntentFilter存在匹配关系时,才可以隐式激活组件。
    Android系统定义了一些以CATEGORY_为前缀的常量:
      CATEGORY_DEFAULT:默认的;
      CATEGORY_LAUNCHER:入口Activity的分类;
      CATEGORY_BROWSABLE:可被浏览器触发的分类;
      CATEGORY_HOME:显示HOME界面的分类;
Extra
    Extra表示附加信息,用于封装在组件之间传递的数据。
    Extra属性的数据类型是Bundle类型,其本质是操作一个key的类型固定为String和HashMap;
    通过putExtra()方法可将Bundle类型的数据设置为Extra属性的值。
    Intent类重载了多次putExtra()方法,用于附加不同类型的数据,并定义了匹配的get()方法,例如getStringExtra(),getIntExtra()等。
    对于获取基本值的get类型方法,都有第2个参数表示默认值,例如getIntExtra(String name,intdefaultValue),第2个参数仅当根据name参数获取值失败时
    作为该方法的返回值。


    使用Intent属性在组件之间传递数据:

  Intent intent = new Intent();       Bundle bundle = new Bundle();       bundle.putInt("id",9527);       bundle.putString("name","Beckham");       intent.putExtras(bundle);       Intent intent = new Intent();       intent.putExtra("id",9627);       intent.putExtra("name","Beckham");       数据接收方:          Intent intent = new Intent();  int id = intent.getIntExtra("id",-1);  String name = intent.getStringExtra("name");

Flag
  Flag表示标志,通常用于指定Intent对象的一些特殊意义,例如在Activity的Back Stack的处理中,通过设置Flag属性确定Activity归属于某个Task,或在广播中,设置是否仅动态注册的接收者才可以接收等。
  Flag属性的数据类型是Integer类型;
  通过setFlag()方法可以设置Flag属性的值。


 Intent实现的小案例:

 package com.example.intent;import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.widget.Button;import android.widget.EditText;public class MainActivity extends Activity {    private EditText editText1;    private EditText editText2;    private EditText editText3;    private Button button_submit;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);editText1 = (EditText)findViewById(R.id.editText1);editText2 = (EditText)findViewById(R.id.editText2);editText3 = (EditText)findViewById(R.id.editText3);button_submit = (Button)findViewById(R.id.button1);button_submit.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {// TODO Auto-generated method stubint id;String name;float salary;id = Integer.valueOf(editText1.getText().toString());name = editText2.getText().toString();salary = Float.valueOf(editText3.getText().toString());Intent intent = new Intent(getApplicationContext(),EmfoActivity.class);intent.putExtra("id", id);intent.putExtra("name", name);intent.putExtra("salary", salary);startActivity(intent);}});}}

布局:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    tools:context="${relativePackage}.${activityClass}" >    <TextView        android:id="@+id/textView1"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="请输入员工信息:"        android:textSize="23sp" />    <EditText        android:id="@+id/editText1"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_below="@+id/textView1"        android:layout_marginTop="25dp"        android:ems="10"        android:hint="请输入员工编号:" >        <requestFocus />    </EditText>    <EditText        android:id="@+id/editText2"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignRight="@+id/editText1"        android:layout_below="@+id/editText1"        android:layout_marginTop="40dp"        android:ems="10"        android:hint="请输入员姓名:" />    <RelativeLayout        android:id="@+id/relativeLayout1"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentRight="true"        android:layout_below="@+id/editText2"        android:gravity="center_horizontal" >    </RelativeLayout>    <EditText        android:id="@+id/editText3"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentLeft="true"        android:layout_centerVertical="true"        android:ems="10"        android:hint="请输入员工薪资:" />    <TextView        android:id="@+id/textView2"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignBottom="@+id/editText3"        android:layout_alignParentRight="true"        android:text="元/月"        android:textSize="18sp" />    <Button        android:id="@+id/button1"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_alignParentLeft="true"        android:layout_below="@+id/editText3"        android:layout_marginLeft="47dp"        android:layout_marginTop="76dp"        android:text="提交" /></RelativeLayout>

跳转到另一个界面:

 package com.example.intent;import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.widget.TextView;public class EmfoActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_emfo);Intent intent = getIntent();int id = intent.getIntExtra("id", -1);String name = intent.getStringExtra("name");float salary = intent.getFloatExtra("salary", -1f);  ((TextView)findViewById(R.id.tv_id)).setText("编号:"+ id);  ((TextView)findViewById(R.id.tv_name)).setText("姓名:"+ name);  ((TextView)findViewById(R.id.tv_salary)).setText("薪资:"+ salary + "元/月");}}

 界面的布局:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"     >    <TextView        android:id="@+id/title"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="员工的信息:"        android:textSize="23sp" />    <TextView        android:id="@+id/tv_id"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginTop="48dp"        android:ems="10" >    </TextView>    <TextView        android:id="@+id/tv_name"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginTop="38dp"        android:ems="10" />    <TextView        android:id="@+id/tv_salary"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_marginTop="38dp"        android:ems="10" /></LinearLayout>

 Intent与IntentFilter
 
 IntentFilter表示“意图过滤器”;
 IntentFilter用于使用隐式意图时过滤Intent,即对匹配的Intent“放行”,对不匹配的Intent“阻止”;


 通常在AndroidMainfest.xml文件中,系统组件的节点下配置IntentFilter,例如:
   <intent-filter>
      <action android:name="android.intent.action.MAIN"/>
      <category android:name="android.intent.category.LAUNCHER"/>
   </intent-filter>


 在一些应用场景中,也可能使用程序代码配置IntentFilter,例如在广播接收者在应用中。


 IntentFilter对Intent的以下属性是有效的:
     Action;
     Category;
     Data;
 过滤Action:每个IntentFilter可以添加多个Action。
  例如:
     <intent-filter>
         <action android:name="cn.com.edu.hpu.action.STUDY"/>
 <action android:name="cn.com.edu.hpu.action.CODING"/>
 <action android:name="cn.com.edu.hpu.action.EXERCISE"/>
     <intent-filter>


每个action节点中name属性的值可以由开发人员自行指定,在同一个Android设备中,action的值应该是不冲突的,
因此,该值通常以项目包名作为前缀。


每个IntentFilter都应该指定至少一个Action,否则它将阻止所有的Intent。
如果Intent对象本身没有指定Action属性,将不参与匹配校验。
如果Intent对象指定的Action属性与IntentFilter中任意一个Action匹配,则放行。


   每个IntentFilter可以添加多个Category。


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

与action节点相同,category节点中name属性的值也可以由开发人员自行指定,且应该是不会发生冲突的。
开发人员可以不为Intent对象指定Category,也可以指定多个Category。
android系统必然会为每个Intent对象添加默认的Category,即:
    android.intent.category.dEFAULT
  
再过滤规则中,Intent中的每个Category在IntentFilter中都能被找到,则放行,否则将阻止,
即方形的条件为:
   IntentFilter中有默认的Category,对比Intent中的Category,只能多,不能少。




    每个IntentFilter可以添加多个Data。

 <intent-filter>           <data         android:mimeType="video/mpeg" android:scheme="http" android:host="www.cn.edu.hpu.cn"/>           <data          android:mimeType="text/html"  android:scheme="http"/>      </intent-filter>

 在android:mimeType属性中指定MIME类型时,可以使用通配符,例如:text/*、video/*等。


    每个Uri的完整格式为:
        scheme://host:port/path
   在IntentFilter中配置Data时,以上属性都是可选的,但他们相互并不独立。


   关于Uri是否匹配:
       如果在IntentFilter中仅指定了scheme,则任意相同scheme的Uri均匹配,无视host、port、path部分;


       如果在IntentFilter中指定了完整的Uri各部分,则被要求被验证的Uri也完全匹配。


       如果Intent没有指定Uri和MIME,仅当IntentFilter也没有指定Uri和MIME时放行;
       如果Intent中指定了Uri,但没有指定MIME,且根据Uri无法推断MIME,仅当IntentFilter指定了相同的Uri且没有指定MIME时放行;


     IntentFilter可以指定Action、Category、Data来检验是否匹配,匹配的Intent将放行,否则将阻止;
     大致放行规则如下(通常设置的配置规则):
      关于Action:Intent对象中的Action(最多一个)在IntentFilter中可以被找到;
      关于Category:Intent对象中所有的Category在IntentFilter中都可以找到,且Intent对象中必然有android.intent.category.DEFAULT这个Category。




      自定义隐式意图激活Activity:
      使用隐式意图调用系统的拨号、呼叫程序。


      Action
         拨号Action:Intent.ACTION_DIAL
呼号Action:Intent。ACTION_CALL


Permission
         在Android系统中,敏感操作(涉及隐私的、安全的、可能产生费用的)都需要申请权限,且当应用程序被安装到设备上之前,会列举当前应用程序所申请的权限,
用户可以继续选择安装该应用程序,或不安装。


在开发过程中,每次部署应用程序时不会出现安装向导界面,亦不会提示应用程序所申请的权限。


所有权限通过在AndroidMainfest.xml文件中添加<uses-permission android:name="权限名称"/>节点实现申请,
该节点是根节点的直接子节点,且可以存在若干个。
通话权限为:
       <uses-permission android:name="android.permission.CALL_PHONE"/>


案例:

    

package com.example.intent;import android.app.Activity;import android.content.Intent;import android.net.Uri;import android.os.Bundle;import android.view.View;import android.widget.Button;import android.widget.EditText;public class MainActivity extends Activity {private EditText phone;private Button call,tell;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);phone = (EditText)findViewById(R.id.editText1);call=(Button)findViewById(R.id.call);tell = (Button)findViewById(R.id.tell);InnerOnClickListener listener = new InnerOnClickListener();tell.setOnClickListener(listener);call.setOnClickListener(listener);   }private class InnerOnClickListener implements View.OnClickListener{@Overridepublic void onClick(View v) {// TODO Auto-generated method stubIntent intent = new Intent();String phoneNumber = phone.getText().toString();intent.setData(Uri.parse("tel://" + phoneNumber));switch (v.getId()) {case R.id.tell:intent.setAction(Intent.ACTION_DIAL);break;            case R.id.call:            intent.setAction(Intent.ACTION_CALL);break;}startActivity(intent);}}}


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    xmlns:tools="http://schemas.android.com/tools"    android:layout_width="fill_parent"    android:layout_height="fill_parent"    android:orientation="vertical"    >       <EditText        android:id="@+id/editText1"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:layout_below="@+id/textView1"        android:layout_marginTop="25dp"        android:hint="请输入电话号码" />      <LinearLayout       android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    android:gravity="center"    >       <Button        android:id="@+id/tell"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:text="拨号" />    <Button        android:id="@+id/call"        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:text="呼叫" />    </LinearLayout></LinearLayout>


<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.example.intent"    android:versionCode="1"    android:versionName="1.0" >    <uses-sdk        android:minSdkVersion="14"        android:targetSdkVersion="14" /><uses-permission android:name="android.permission.CALL_PHONE"/>    <application        android:allowBackup="true"        android:icon="@drawable/ic_launcher"        android:label="@string/app_name"        android:theme="@style/AppTheme" >        <activity            android:name=".MainActivity"            android:label="@string/app_name" >            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>        <activity            android:name=".EmfoActivity"            android:label="@string/title_activity_emfo" >        </activity>    </application></manifest>


1 2