Android开发学习笔记:Intent的简介以及属性的详解
2011-08-08 17:20:48
原创作品,允许转载,转载时请务必以超链接形式标明文章
原始出处 、作者信息和本声明。否则将追究法律责任。
http://liangruijun.blog.51cto.com/3061169/634411
一.Intent的介绍
Intent的中文意思是“意图,意向”,在Android中提供了Intent机制来协助应用间的交互与通讯,Intent负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述,Android则根据此Intent的描述,负责找到对应的组件,将 Intent传递给调用的组件,并完成组件的调用。Intent不仅可用于应用程序之间,也可用于应用程序内部的Activity/Service之间的交互。因此,可以将Intent理解为不同组件之间通信的“媒介”专门提供组件互相调用的相关信息。
二.Inten启动组件的方法
Intent可以启动一个Activity,也可以启动一个Service,还可以发起一个广播Broadcasts。具体方法如下:
组件名称
方法名称
Activity
startActvity( )
startActivity( )
Service
startService( )
bindService( )
Broadcasts
sendBroadcasts( )
sendOrderedBroadcasts( )
sendStickyBroadcasts( )
三.Intent的属性
Intent有以下几个属性:
动作(Action),数据(Data),分类(Category),类型(Type),组件(Compent)以及扩展信(Extra)。其中最常用的是Action属性和Data属性。
1.Intent的Action属性
Action是指Intent要完成的动作,是一个字符串常量。SDK中定义了一些标准的Action常量如下表所示。
Constant
Target component
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.
下面是一个测试Action常量的例子:
main.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="@string/hello"
- />
- <Button
- android:text="测试Action属性"
- android:id="@+id/getBtn"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- />
- </LinearLayout>
strings.xml
- <?xml version="1.0" encoding="utf-8"?>
- <resources>
- <string name="hello">测试Action属性</string>
- <string name="app_name">IntentActionDemo</string>
- </resources>
MainActivity.java
- package com.android.action.activity;
-
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
-
- public class MainActivity extends Activity {
- private Button getBtn;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
-
- getBtn=(Button)findViewById(R.id.getBtn);
- getBtn.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent intent = new Intent();
- intent.setAction(Intent.ACTION_GET_CONTENT);// 设置Intent Action属性
- intent.setType("vnd.android.cursor.item/phone");// 设置Intent Type 属性
- //主要是获取通讯录的内容
- startActivity(intent); // 启动Activity
- }
- });
- }
- }
效果图:
2.Intent的Data属性
Intent的Data属性是执行动作的URI和MIME类型,不同的Action有不同的Data数据指定。比如:ACTION_EDIT Action应该和要编辑的文档URI Data匹配,ACTION_VIEW应用应该和要显示的URI匹配。
3.Intent的Category属性
Intent中的Category属性是一个执行动作Action的附加信息。比如:CATEGORY_HOME则表示放回到Home界面,ALTERNATIVE_CATEGORY表示当前的Intent是一系列的可选动作中的一个。下表是SDK文档中关于Category的信息。
Constant
Meaning
CATEGORY_BROWSABLE
The target activity can be safely invoked by the browser to display data referenced by a link — for example, an image or an e-mail message.
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
The target activity is a preference panel.
下面是一个回到Home界面的例子:
main.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical" android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="测试Intent Category"
- />
- <Button
- android:id="@+id/Button1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="转到Home界面"
- />
- </LinearLayout>
strings.xml
- <?xml version="1.0" encoding="utf-8"?>
- <resources>
- <string name="hello">Hello World, MainActivity!</string>
- <string name="app_name">IntentCategoryDemo</string>
- </resources>
MainActivity.java
- package com.android.category.activity;
-
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
-
- public class MainActivity extends Activity {
- private Button btn;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
-
- btn = (Button)findViewById(R.id.Button1);
- btn.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent intent = new Intent();
- intent.setAction(Intent.ACTION_MAIN);// 添加Action属性
- intent.addCategory(Intent.CATEGORY_HOME);// 添加Category属性
- startActivity(intent);// 启动Activity
- }
- });
- }
- }
效果图:
4.Intent的Type属性
Intent的Type属性显式指定Intent的数据类型(MIME)。一般Intent的数据类型能够根据数据本身进行判定,但是通过设置这个属性,可以强制采用显式指定的类型而不再进行推导。
5.Intent的Compent属性
Intent的Compent属性指定Intent的的目标组件的类名称。通常 Android会根据Intent 中包含的其它属性的信息,比如action、data/type、category进行查找,最终找到一个与之匹配的目标组件。但是,如果 component这个属性有指定的话,将直接使用它指定的组件,而不再执行上述查找过程。指定了这个属性以后,Intent的其它所有属性都是可选的。
6.Intent的Extra属性
Intent的Extra属性是添加一些组件的附加信息。比如,如果我们要通过一个Activity来发送一个Email,就可以通过Extra属性来添加subject和body。
下面的例子在第一个Activity的EditText输入用户名,该年龄保存在Intent的Extras属性中。当单击Button时,会在第二个Activity中显示用户名。
first.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="请输入用户名"
- />
- <EditText
- android:id="@+id/EditText1"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- />
- <Button
- android:id="@+id/Button1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="测试Extras属性"
- />
- </LinearLayout>
second.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <TextView
- android:id="@+id/TextView1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- />
- </LinearLayout>
strings.xml
- <?xml version="1.0" encoding="utf-8"?>
- <resources>
- <string name="hello">Hello World, FirstActivity!</string>
- <string name="app_name">IntentExtrasDemo</string>
- </resources>
FirstActivity.java
- package com.android.extras.activity;
-
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.EditText;
-
- public class FirstActivity extends Activity {
- private Button btn;
- private EditText etx;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.first);
-
- btn = (Button)findViewById(R.id.Button1);
- etx = (EditText)findViewById(R.id.EditText1);
-
- btn.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent intent = new Intent();
- //设置Intent的class属性,跳转到SecondActivity
- intent.setClass(FirstActivity.this, SecondActivity.class);
- //为intent添加额外的信息
- intent.putExtra("useName", etx.getText().toString());
- //启动Activity
- startActivity(intent);
- }
- });
- }
- }
SecondActivity.java
- package com.android.extras.activity;
-
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.widget.TextView;
-
- public class SecondActivity extends Activity {
- private TextView tv;
-
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- //设置当前的Activity的界面布局
- setContentView(R.layout.second);
- //获得Intent
- Intent intent = this.getIntent();
- tv = (TextView)findViewById(R.id.TextView1);
- //从Intent获得额外信息,设置为TextView的文本
- tv.setText(intent.getStringExtra("useName"));
- }
- }
注意:在添加第二个Activity SecondActivity的时候,要在AndroidManifest.xml里面添加上SecondActivity,具体如下,即是在15行</activity>的后面添加上16~18行的代码。如果不这样做,就会在模拟器上出现错误。
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.extras.activity"
- android:versionCode="1"
- android:versionName="1.0">
- <uses-sdk android:minSdkVersion="10" />
-
- <application android:icon="@drawable/icon" android:label="@string/app_name">
- <activity android:name=".FirstActivity"
- 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=".SecondActivity"
- android:label="@string/app_name">
- </activity>
- </application>
- </manifest>
效果图:
本文出自 “IT的点点滴滴” 博客,请务必保留此出处http://liangruijun.blog.51cto.com/3061169/634411
一.Intent的介绍
Intent的中文意思是“意图,意向”,在Android中提供了Intent机制来协助应用间的交互与通讯,Intent负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述,Android则根据此Intent的描述,负责找到对应的组件,将 Intent传递给调用的组件,并完成组件的调用。Intent不仅可用于应用程序之间,也可用于应用程序内部的Activity/Service之间的交互。因此,可以将Intent理解为不同组件之间通信的“媒介”专门提供组件互相调用的相关信息。
二.Inten启动组件的方法
Intent可以启动一个Activity,也可以启动一个Service,还可以发起一个广播Broadcasts。具体方法如下:
组件名称 | 方法名称 |
Activity | startActvity( ) startActivity( ) |
Service | startService( ) bindService( ) |
Broadcasts | sendBroadcasts( ) sendOrderedBroadcasts( ) sendStickyBroadcasts( ) |
三.Intent的属性
Intent有以下几个属性:
动作(Action),数据(Data),分类(Category),类型(Type),组件(Compent)以及扩展信(Extra)。其中最常用的是Action属性和Data属性。
1.Intent的Action属性
Action是指Intent要完成的动作,是一个字符串常量。SDK中定义了一些标准的Action常量如下表所示。
Constant | Target component | 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. |
下面是一个测试Action常量的例子:
main.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="@string/hello"
- />
- <Button
- android:text="测试Action属性"
- android:id="@+id/getBtn"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- />
- </LinearLayout>
strings.xml
- <?xml version="1.0" encoding="utf-8"?>
- <resources>
- <string name="hello">测试Action属性</string>
- <string name="app_name">IntentActionDemo</string>
- </resources>
MainActivity.java
- package com.android.action.activity;
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- public class MainActivity extends Activity {
- private Button getBtn;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- getBtn=(Button)findViewById(R.id.getBtn);
- getBtn.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent intent = new Intent();
- intent.setAction(Intent.ACTION_GET_CONTENT);// 设置Intent Action属性
- intent.setType("vnd.android.cursor.item/phone");// 设置Intent Type 属性
- //主要是获取通讯录的内容
- startActivity(intent); // 启动Activity
- }
- });
- }
- }
效果图:
2.Intent的Data属性
Intent的Data属性是执行动作的URI和MIME类型,不同的Action有不同的Data数据指定。比如:ACTION_EDIT Action应该和要编辑的文档URI Data匹配,ACTION_VIEW应用应该和要显示的URI匹配。
3.Intent的Category属性
Intent中的Category属性是一个执行动作Action的附加信息。比如:CATEGORY_HOME则表示放回到Home界面,ALTERNATIVE_CATEGORY表示当前的Intent是一系列的可选动作中的一个。下表是SDK文档中关于Category的信息。
Constant | Meaning |
CATEGORY_BROWSABLE | The target activity can be safely invoked by the browser to display data referenced by a link — for example, an image or an e-mail message. |
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 | The target activity is a preference panel. |
下面是一个回到Home界面的例子:
main.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical" android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <TextView
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- android:text="测试Intent Category"
- />
- <Button
- android:id="@+id/Button1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="转到Home界面"
- />
- </LinearLayout>
strings.xml
- <?xml version="1.0" encoding="utf-8"?>
- <resources>
- <string name="hello">Hello World, MainActivity!</string>
- <string name="app_name">IntentCategoryDemo</string>
- </resources>
MainActivity.java
- package com.android.category.activity;
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- public class MainActivity extends Activity {
- private Button btn;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- btn = (Button)findViewById(R.id.Button1);
- btn.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent intent = new Intent();
- intent.setAction(Intent.ACTION_MAIN);// 添加Action属性
- intent.addCategory(Intent.CATEGORY_HOME);// 添加Category属性
- startActivity(intent);// 启动Activity
- }
- });
- }
- }
效果图:
4.Intent的Type属性
Intent的Type属性显式指定Intent的数据类型(MIME)。一般Intent的数据类型能够根据数据本身进行判定,但是通过设置这个属性,可以强制采用显式指定的类型而不再进行推导。
5.Intent的Compent属性
Intent的Compent属性指定Intent的的目标组件的类名称。通常 Android会根据Intent 中包含的其它属性的信息,比如action、data/type、category进行查找,最终找到一个与之匹配的目标组件。但是,如果 component这个属性有指定的话,将直接使用它指定的组件,而不再执行上述查找过程。指定了这个属性以后,Intent的其它所有属性都是可选的。
6.Intent的Extra属性
Intent的Extra属性是添加一些组件的附加信息。比如,如果我们要通过一个Activity来发送一个Email,就可以通过Extra属性来添加subject和body。
下面的例子在第一个Activity的EditText输入用户名,该年龄保存在Intent的Extras属性中。当单击Button时,会在第二个Activity中显示用户名。
first.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <TextView
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="请输入用户名"
- />
- <EditText
- android:id="@+id/EditText1"
- android:layout_width="fill_parent"
- android:layout_height="wrap_content"
- />
- <Button
- android:id="@+id/Button1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:text="测试Extras属性"
- />
- </LinearLayout>
second.xml
- <?xml version="1.0" encoding="utf-8"?>
- <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
- android:orientation="vertical"
- android:layout_width="fill_parent"
- android:layout_height="fill_parent"
- >
- <TextView
- android:id="@+id/TextView1"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- />
- </LinearLayout>
strings.xml
- <?xml version="1.0" encoding="utf-8"?>
- <resources>
- <string name="hello">Hello World, FirstActivity!</string>
- <string name="app_name">IntentExtrasDemo</string>
- </resources>
FirstActivity.java
- package com.android.extras.activity;
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.EditText;
- public class FirstActivity extends Activity {
- private Button btn;
- private EditText etx;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.first);
- btn = (Button)findViewById(R.id.Button1);
- etx = (EditText)findViewById(R.id.EditText1);
- btn.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent intent = new Intent();
- //设置Intent的class属性,跳转到SecondActivity
- intent.setClass(FirstActivity.this, SecondActivity.class);
- //为intent添加额外的信息
- intent.putExtra("useName", etx.getText().toString());
- //启动Activity
- startActivity(intent);
- }
- });
- }
- }
SecondActivity.java
- package com.android.extras.activity;
- import android.app.Activity;
- import android.content.Intent;
- import android.os.Bundle;
- import android.widget.TextView;
- public class SecondActivity extends Activity {
- private TextView tv;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- //设置当前的Activity的界面布局
- setContentView(R.layout.second);
- //获得Intent
- Intent intent = this.getIntent();
- tv = (TextView)findViewById(R.id.TextView1);
- //从Intent获得额外信息,设置为TextView的文本
- tv.setText(intent.getStringExtra("useName"));
- }
- }
注意:在添加第二个Activity SecondActivity的时候,要在AndroidManifest.xml里面添加上SecondActivity,具体如下,即是在15行</activity>的后面添加上16~18行的代码。如果不这样做,就会在模拟器上出现错误。
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.extras.activity"
- android:versionCode="1"
- android:versionName="1.0">
- <uses-sdk android:minSdkVersion="10" />
- <application android:icon="@drawable/icon" android:label="@string/app_name">
- <activity android:name=".FirstActivity"
- 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=".SecondActivity"
- android:label="@string/app_name">
- </activity>
- </application>
- </manifest>
效果图:
本文出自 “IT的点点滴滴” 博客,请务必保留此出处http://liangruijun.blog.51cto.com/3061169/634411
1111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111
1111111111111111111111111111111111111111111111111111111111111
http://blog.csdn.net/think_soft/article/details/7559560
2222222222222222222222222222222222222222222222222222222
222222222222222222222222222222222222222222222222222222222
2222222222222222222222222222222222222222222222222222222222222
Intent中的四个重要属性——Action、Data、Category、Extras
Intent作为联系各Activity之间的纽带,其作用并不仅仅只限于简单的数据传递。通过其自带的属性,其实可以方便的完成很多较为复杂的操作。例如直接调用拨号功能、直接自动调用合适的程序打开不同类型的文件等等。诸如此类,都可以通过设置Intent属性来完成。
Intent主要有以下四个重要属性,它们分别为:
Action:Action属性的值为一个字符串,它代表了系统中已经定义了一系列常用的动作。通过setAction()方法或在清单文件AndroidManifest.xml中设置。默认为:DEFAULT。
Data:Data通常是URI格式定义的操作数据。例如:tel:// 。通过setData()方法设置。
Category:Category属性用于指定当前动作(Action)被执行的环境。通过addCategory()方法或在清单文件AndroidManifest.xml中设置。默认为:CATEGORY_DEFAULT。
Extras:Extras属性主要用于传递目标组件所需要的额外的数据。通过putExtras()方法设置。
四个属性各自的常用值如下所示:
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)。
Category:
CATEGORY_DEFAULT:Android系统中默认的执行方式,按照普通Activity的执行方式执行。
CATEGORY_HOME:设置该组件为Home Activity。
CATEGORY_PREFERENCE:设置该组件为Preference。
CATEGORY_LAUNCHER:设置该组件为在当前应用程序启动器中优先级最高的Activity,通常为入口ACTION_MAIN配合使用。
CATEGORY_BROWSABLE:设置该组件可以使用浏览器启动。
CATEGORY_GADGET:设置该组件可以内嵌到另外的Activity中。
Extras:
EXTRA_BCC:存放邮件密送人地址的字符串数组。
EXTRA_CC:存放邮件抄送人地址的字符串数组。
EXTRA_EMAIL:存放邮件地址的字符串数组。
EXTRA_SUBJECT:存放邮件主题字符串。
EXTRA_TEXT:存放邮件内容。
EXTRA_KEY_EVENT:以KeyEvent对象方式存放触发Intent的按键。
EXTRA_PHONE_NUMBER:存放调用ACTION_CALL时的电话号码。
Data:
tel://:号码数据格式,后跟电话号码。
mailto://:邮件数据格式,后跟邮件收件人地址。
smsto://:短息数据格式,后跟短信接收号码。
content://:内容数据格式,后跟需要读取的内容。
file://:文件数据格式,后跟文件路径。
market://search?q=pname:pkgname:市场数据格式,在Google Market里搜索包名为pkgname的应用。
geo://latitude,longitude:经纬数据格式,在地图上显示经纬度指定的位置。
在intent-filter中指定data属性的实际目的是:要求接收的Intent中的data必须符合intent-filter中指定的data属性,这样达到反向限定Intent的作用。
例如:在AndroidManifest.xml 中进行如下设置:
那么启动该Activity的Intent必须进行如下设置:
data属性解析:android:scheme、android:host、android:port、android:path、android:mimeType
data的前四个属性构成了URI的组成部分,mimeType设置了数据的类型
data元素组成的URI模型如下:
scheme://host:port/path
举例说明:
URI file://com.android.jony.test:520/mnt/sdcard
scheme-->file:
host-->com.android.jony.test
port-->520
path-->mnt/sdcard
其中host和port为URI的authority,如果没有指定host,port将被忽略
data的各属性并不是独立的,data的各属性构成了URI的整个组成部分。要使authority(host和port)有意义,必须指定scheme;要使path有意义,必须使scheme和authority(host和port)有意义。
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)在AndroidMainfest.xml 中对每一个Activity都做了说明——intent-filter,intent-filter声明了需要接收怎样的Intent,当发送的Intent和intent-filter中定义的相符合,就会启动相应的Activity;
(2)当有多个Activity符合发送的Intent时,Android系统会列出所有满足Intent的Activity,用户可以通过选择进行相关的操作;
(3)在一个Activity的intent-filter中可以有多个action、多个category、多个data,这样可以有多种组合与Intent进行匹配。注意:如果在一个Activity中有多个Intent进行匹配的时候,建议使用多个intent-filter与Intent进行匹配。猜测:这样应该可以提高Intent的匹配速度。
(4)data属性,这是一个进行反向限制Intent的操作,要求Intent的data必须是intent-filter中声明的数据之一(应为在一个intent-filter中可以设置多个data)。注意:如果要启动目标Activity,但是指定的data数据类型与Activity中data数据类型不匹配,将会造成ActivityNotFoundException异常。
备注:再次感谢原文作者的辛勤劳动
思路一:
你的service 启一个大小为1*1的窗口 放到角落
这个窗口 可以监听on key的
思路二:
开机时创建一个新的进程,实际上就是Linux里面的进程操作。可以使用NDK开发,用C或者C++新建一个进程来运行自己的服务,并提高进程优先级,避免被清理掉(我猜测QQ和微信的推送服务,或许是这么实现的)。
思路三:
这个需求必须修改底层才可实现,我现在的做法是修改底层,在按键按下时发送广播,这样在service或者activity都可捕获到按键信息
app中对于HOME键广播事件的接收 首先,自定义一个BroadcastReceiver: [java] view plaincopy class HomeKeyEventBroadCastReceiver extends BroadcastReceiver { static final String SYSTEM_REASON = "reason"; static final String SYSTEM_HOME_KEY = "homekey";//home key static final String SYSTEM_RECENT_APPS = "recentapps";//long home key @Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); if (action.equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) { String reason = intent.getStringExtra(SYSTEM_REASON); if (reason != null) { if (reason.equals(SYSTEM_HOME_KEY)) { // home key处理点 } else if (reason.equals(SYSTEM_RECENT_APPS)) { // long home key处理点 } } } } } 其次,生成且注册之 [java] view plaincopy receiver = new HomeKeyEventBroadCastReceiver(); registerReceiver(receiver, new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)); 这样,我们就可以在app中进行HOME键的处理了!
=====================================================================================
将到Android中Home键的监听,很多人第一反应时重写相应Activity的onKeyDown()方法,监听当按下的键的keyCode为KEYCODE_HOME时,进行自己的相应的处理。如:
- @Override
- public boolean onKeyDown(int keyCode, KeyEvent event) {
- if (keyCode == KeyEvent.KEYCODE_HOME) {
- stopService(mIntentService);
- return true;
- }
- return super.onKeyDown(keyCode, event);
- }
1.新建一个监听Home键的Listener
- public class HomeListener {
- static final String TAG = "HomeListener";
- private Context mContext;
- private IntentFilter mFilter;
- private OnHomePressedListener mListener;
- private InnerRecevier mRecevier;
- // 回调接口
- public interface OnHomePressedListener {
- public void onHomePressed();
- public void onHomeLongPressed();
- }
- public HomeListener(Context context) {
- mContext = context;
- mFilter = new IntentFilter(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
- }
- /**
- * 设置监听
- *
- * @param listener
- */
- public void setOnHomePressedListener(OnHomePressedListener listener) {
- mListener = listener;
- mRecevier = new InnerRecevier();
- }
- /**
- * 开始监听,注册广播
- */
- public void startWatch() {
- if (mRecevier != null) {
- mContext.registerReceiver(mRecevier, mFilter);
- }
- }
- /**
- * 停止监听,注销广播
- */
- public void stopWatch() {
- if (mRecevier != null) {
- mContext.unregisterReceiver(mRecevier);
- }
- }
- class InnerRecevier extends BroadcastReceiver{
- final String SYSTEM_DIALOG_REASON_KEY = "reason";
- final String SYSTEM_DIALOG_REASON_GLOBAL_ACTIONS = "globalactions";
- final String SYSTEM_DIALOG_REASON_RECENT_APPS = "recentapps";
- final String SYSTEM_DIALOG_REASON_HOME_KEY = "homekey";
- @Override
- public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
- if (action.equals(Intent.ACTION_CLOSE_SYSTEM_DIALOGS)) {
- String reason = intent.getStringExtra(SYSTEM_DIALOG_REASON_KEY);
- if (reason != null) {
- // Log.e(TAG, "action:" + action + ",reason:" + reason);
- if (mListener != null) {
- if (reason.equals(SYSTEM_DIALOG_REASON_HOME_KEY)) {
- // 短按home键
- mListener.onHomePressed();
- } else if (reason
- .equals(SYSTEM_DIALOG_REASON_RECENT_APPS)) {
- // 长按home键
- mListener.onHomeLongPressed();
- }
- }
- }
- }
- }
- }
- }
2.在使用的类的onCreate方法中注册Home键的监听
- /**
- * 注册Home键的监听
- */
- private void registerHomeListener() {
- mHomeWatcher = new HomeListener(this);
- mHomeWatcher.setOnHomePressedListener(new OnHomePressedListener() {
- @Override
- public void onHomePressed() {
- //TODO 进行点击Home键的处理
- Log.i("xsl", "0000000000000");
- stopService(mIntentService);
- }
- @Override
- public void onHomeLongPressed() {
- //TODO 进行长按Home键的处理
- Log.i("xsl", "0000000000000");
- }
- });
- mHomeWatcher.startWatch();
- }
3. 在使用的类的onPause方法中停止监听
- mHomeWatcher.stopWatch();
====================================================================================
- package com.billhoo.study;
- import android.app.Activity;
- import android.os.Bundle;
- public class BootTestActivity extends Activity {
- /** Called when the activity is first created. */
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.main);
- }
- }
- package com.billhoo.study;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- public class BootCompletedReceiver extends BroadcastReceiver {
- @Override
- public void onReceive(Context context, Intent intent) {
- if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED))
- {
- Intent newIntent = new Intent(context, BootTestActivity.class);
- newIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); //注意,必须添加这个标记,否则启动会失败
- context.startActivity(newIntent);
- }
- }
- }
- <receiver android:name=".BootCompletedReceiver">
- <intent-filter>
- <action android:name="android.intent.action.BOOT_COMPLETED" />
- </intent-filter>
- </receiver>
- <!-- permissions -->
- <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.billhoo.study" android:versionCode="1"
- android:versionName="1.0">
- <uses-sdk android:minSdkVersion="4" />
- <!-- permissions -->
- <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
- <application android:icon="@drawable/icon" android:label="@string/app_name">
- <!-- activities -->
- <activity android:name=".BootTestActivity" android:label="@string/app_name">
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- <!-- receivers -->
- <receiver android:name=".BootCompletedReceiver">
- <intent-filter>
- <action android:name="android.intent.action.BOOT_COMPLETED" />
- </intent-filter>
- </receiver>
- </application>
- </manifest>
typedef void* cookie_type;
template<typename TR, typename T1, typename T2>
class CEvent
{
public:
typedef TR return_type;
typedef T1 first_type;
typedef T2 second_type;
typedef std::function<return_type (first_type, second_type)> handler_type;
~CEvent()
{
Clear();
}
return_type operator()(first_type p1, second_type p2)
{
return_type ret = return_type();
size_t size = _handlers.size();
for(size_t i=0; i<size; ++i)
{
ret = _handlers[i]-> operator()(p1, p2);
}
return ret;
}
cookie_type AddHandler(std::function<return_type (first_type, second_type)> h)
{
CEventHandler*p = new(nothrow) CEventHandler(h);
if(p != nullptr) _handlers.push_back(p);
return (cookie_type)p;
}
template<typename class_type, typename class_fun>
cookie_type AddHandler(class_type* pThis, class_fun f)
{
CEventHandler* p = new(nothrow) CEventHandler(pThis, f);
if(p != nullptr) _handlers.push_back(p);
return (cookie_type)p;
}
void RemoveHandler(cookie_type cookie)
{
CEventHandler* p = (CEventHandler*)cookie;
auto itr = std::find(_handlers.begin(), _handlers.end(), p);
if(itr != _handlers.end())
{
_handlers.erase(itr);
delete p;
}
else
{
assert( false);
}
}
void Clear()
{
if(!_handlers.empty())
{
int n = _handlers.size();
std::for_each(_handlers.begin(), _handlers.end(), [](CEventHandler* p)
{
assert(p != nullptr);
delete p;
});
_handlers.clear();
}
}
private:
class CEventHandler
{
public:
CEventHandler(handler_type h)
{
_handler = h;
assert(_handler != nullptr);
}
template<typename class_type, typename class_fun>
CEventHandler(class_type* pThis, class_fun object_function)
{
using namespace std::placeholders;
_handler = std::bind(object_function, pThis, _1, _2);
assert(_handler != nullptr);
}
return_type operator()(first_type p1, second_type p2)
{
return_type ret = return_type();
assert(_handler != nullptr);
if(_handler != nullptr) ret = _handler(p1, p2);
return ret;
}
handler_type _handler;
};
private:
std::vector<CEventHandler*> _handlers;
};
}
大概实现思想是我们通过一个内置的 CEventHandler 类来封装处理函数,我们可以通过AddHandler来添加事件处理函数,添加时会返回一个Cookie,我们可以通过该Cookie来RemoveHandler, 下面是测试代码:
#include <iostream>
#include "event1.h"
using namespace std;
class CObjectX
{
};
class CClickEventArgs: public CObjectX
{
};
class CButton: public CObjectX
{
public:
void FireClick()
{
CClickEventArgs args;
OnClicked( this, args);
}
Common::CEvent< int, CObjectX*, CClickEventArgs&> OnClicked;
};
class CMyClass
{
public:
int OnBtuttonClicked(CObjectX* pButton, CClickEventArgs& args)
{
cout << "CMyClass: Receive button clicked event" << endl;
return 1;
}
};
int OnBtuttonClicked_C_fun(CObjectX* pButton, CClickEventArgs& args)
{
cout << "C Style Function: Receive button clicked event" << endl;
return 1;
}
class CMyFunObj
{
public:
int operator()(CObjectX* pButton, CClickEventArgs& args)
{
cout << "Functor: Receive button clicked event" << endl;
return 1;
}
};
int _tmain( int argc, _TCHAR* argv[])
{
using namespace std::placeholders;
CButton btn;
CMyClass obj;
Common::cookie_type c1 = btn.OnClicked.AddHandler(&obj, &CMyClass::OnBtuttonClicked);
Common::cookie_type c2 = btn.OnClicked.AddHandler(OnBtuttonClicked_C_fun);
CMyFunObj functor;
Common::cookie_type c3 = btn.OnClicked.AddHandler(functor);
btn.FireClick();
btn.OnClicked.RemoveHandler(c2);
std::cout << endl;
btn.FireClick();
system("pause");
return 0;
}
以下是测试结果:
可以看到, 我们在普通C函数, 类成员函数和仿函数(functor)中都测试通过。
另外对于事件函数返回值为void的情况,会编译出错,我们需要偏特化一下:
class CEvent< void, T1, T2>
{
public:
typedef void return_type;
typedef T1 first_type;
typedef T2 second_type;
typedef std::function<return_type (first_type, second_type)> handler_type;
~CEvent()
{
Clear();
}
return_type operator()(first_type p1, second_type p2)
{
size_t size = _handlers.size();
for(size_t i=0; i<size; ++i)
{
_handlers[i]-> operator()(p1, p2);
}
}
cookie_type AddHandler(std::function<return_type (first_type, second_type)> h)
{
CEventHandler*p = new(nothrow) CEventHandler(h);
if(p != nullptr) _handlers.push_back(p);
return (cookie_type)p;
}
template<typename class_type, typename class_fun>
cookie_type AddHandler(class_type* pThis, class_fun f)
{
CEventHandler* p = new(nothrow) CEventHandler(pThis, f);
if(p != nullptr) _handlers.push_back(p);
return (cookie_type)p;
}
void RemoveHandler(cookie_type cookie)
{
CEventHandler* p = (CEventHandler*)cookie;
auto itr = std::find(_handlers.begin(), _handlers.end(), p);
if(itr != _handlers.end())
{
_handlers.erase(itr);
delete p;
}
else
{
assert( false);
}
}
void Clear()
{
if(!_handlers.empty())
{
int n = _handlers.size();
std::for_each(_handlers.begin(), _handlers.end(), [](CEventHandler* p)
{
assert(p != nullptr);
delete p;
});
_handlers.clear();
}
}
private:
class CEventHandler
{
public:
CEventHandler(handler_type h)
{
_handler = h;
assert(_handler != nullptr);
}
template<typename class_type, typename class_fun>
CEventHandler(class_type* pThis, class_fun object_function)
{
using namespace std::placeholders;
_handler = std::bind(object_function, pThis, _1, _2);
assert(_handler != nullptr);
}
return_type operator()(first_type p1, second_type p2)
{
assert(_handler != nullptr);
if(_handler != nullptr) _handler(p1, p2);
}
handler_type _handler;
};
private:
std::vector<CEventHandler*> _handlers;
};
最后谈一下在写这个代码中遇到的问题:
(1)不知道你能不能发现下面代码的问题, 我在写代码时就栽在这里了:
vector < int *> v;
v.push_back(p1);
int * p2 = new int ( 2 );
v.push_back(p2);
// 尝试删除所有值为p1的项
//由该代码想到=>v.erase(std::remove(v.begin(), v.end(), p1), v.end());
//错误代码:
auto itr = remove(v.begin(), v.end(), p1);
for_each(itr, v.end(), []( int * p){delete p;});
v.erase(itr, v.end());
//正确代码:
v.erase(remove_if(v.begin(), v.end(), [](int*p)->bool {if(p==p1) {delete p; return true;} else return false}), v.end());
(2)我们想把cookei_type放到类里面去, 类似这样:
2 class CEvent
3 {
4 public :
5 typedef TR return_type;
6 typedef T1 first_type;
7 typedef T2 second_type;
8 typedef void * cookie_type;
可发现要这样使用:
注:上面的代码还没有经过真正商业使用,如果有问题欢迎指出。