您的位置:首页 > 其它

安卓中Intent

2015-12-23 13:01 429 查看
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;
	@Override
	protected 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() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				int 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 {

	@Override
	protected 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;
	@Override
	protected 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{

		@Override
		public void onClick(View v) {
			// TODO Auto-generated method stub
			Intent 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>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: