- 浏览: 12894058 次
- 性别:
- 来自: 大连
文章分类
最新评论
-
sanrenxing_1:
GoEasy 实时推送支持IE6-IE11及大多数主流浏览器的 ...
WindowsPhone消息推送服务 -
张砚辉:
两侧照片绕Y轴旋转后有锯齿,请问锯齿解决方案,很长时间没解决
自定义带倒影和偏转的超炫Gallery -
knight_black_bob:
能不能把你自己的博客整理下分类下,写了这么多 ,都不知道怎么查 ...
Android_View,ViewGroup,Window之间的关系 -
jeasonyoung:
你这个代码实现在iOS8下应该是滑不动的
UISlider 滑块控件—IOS开发 -
wx_hello:
如果能写个可运行的java程序,不胜感激。。。
rs232串口通信原理
Android开发之Intent、广播和接收
Android开发之Intent、广播和接收
/*
* Android开发之Intent、广播和接收
*
* Created on: 2011-8-15
* Author: blueeagle
* Email: liujiaxiang@gmail.com
*/
Intent
Intent是一种消息传递机制,它可以声明执行某个动作的意图,并且通常是跟一段特定的数据一起进行声明的。
Intent支持Android设备上可用的仁义两个应用程序组件之间的交互,不管它们是哪个应用程序的一部分都是如此。这就把一个相互独立的组件集合变成了一个互联的系统。
Intent最常见的一个用法是显示地(通过指定要加载的类)或隐式地(通过请求对一组数据执行某个动作)启动新活动。
Intent也可以用来在系统范围内广播消息。任何应用程序都可以注册一个广播接收器来监听和相应这些广播的Intent。这样就可以基于内部的、系统的或者第三方的应用程序事件,创建事件驱动的应用程序。
Android使用广播Intent来公布系统事件,例如,网络连接状态或者电池电量的改变。本地Android应用程序(例如拨号程序,SMS管理器)可以简单地注册监听特定的广播Itent的组件——例如,“来电”或者“接受SMS消息”,并作出相应的响应。
使用Intent来启动活动,有两种方式:
1. 显示地启动新的活动
这个是我们比较常用的,跳转Activity的时候会用到。例如:
Intent intent = new Intent(); intent.setClass(WelcomeView.this, OAMainView.class); startActivity(intent);
2. 隐式的Intent和延时的运行时绑定。
当使用这个新的隐式Intent来启动一个活动时,Android将在运行时把它解析为最适合在指定的数据类型上执行动作的类。
例如:如果希望让用户从应用程序中打电话,那么不必实现一个新的拨号程序,而可以用一个隐式的Intent来请求一个在电话号码上执行的动作,如下面代码:
Intent intent = new Intent(Intent.ACTION_DIAL,Uri.parse("tel:777-8888")); startActivity(intent);
Android会解析这个Intent,并启动一个新的活动,该活动会提供对这个电话号码进行拨号的动作。
下面介绍,从活动返回结果的相关内容。
关于StartActivity与StartActivityForResult:前者启动活动的时候,启动的活动与其父活动是不相关的,而后者的不同在于后者除了用来确定启动哪个活动的Intent之外,还需要传入一个request码。也就是说,后者启动的子Activity将带着这个码进行工作,这个码就好像是这个子Activity的一个标识。当然,当这个子活动返回结果的时候,这个码就起到了至关重要的作用。
例如我们启动一个有码的Intent。(呃,看到有码,我突然邪恶了)
private static final int SUB_ACTIVITY = 1; Intent intent = new Intent(); intent.setClass(WelcomeView.this, OAMainView.class); startActivityForResult(intent,SUB_ACTIVITY);
这个和常规的activity一样,这种有码的子activity也可以被显示或者隐式的调用。
例如,调用系统的联系人列表,然后在系统的联系人列表里选择一项后返回。
Intent intent = new Intent(Intent.ACTION_PICK,Uri.parse("content://contacts/people")); startActivityForResult(intent,SUB_ACTIVITY);
当子Activity可以关闭的时候,则在调用finish之前调用setResult,并向调用它的父Activity返回一个结果。
setResult方法有两个参数,分别是:结果码和代表Intent结果的有效内容。
结果码是运行子活动的结果——一般情况下是Activity.RESULT_OK、Activity.RESULT_CANCELED。在某些情况下,程序开发人员可能希望使用自己的响应码来处理应用程序特定的选择。setResult支持任意整数值。
当一个子活动关闭的时候,会触发其父活动的onActivityResult事件处理程序。通过重写这个方法,来处理从子活动返回的结果。onActivityResult接收多个参数:
请求码:用来启动返回子活动。
结果码:用来说明结果。
使用Intent Filter 来为隐式Intent提供服务。
Intent Filter 用来注册活动、服务和广播接收器并对一个动作或者一类特定的数据进行处理。使用IntentFilter,应用程序组件会告诉Android,他们可以为其他地方的动作请求服务,包括相同应用程序的组件以及本地或者第三方的应用程序组件。
要把一个应用程序组件注册为Intent处理程序,可以使用组件的清单结点中的intent-filter标签。
通过在Intent Filter结点内使用标签,可以指定一个组件所支持的动作、分类和数据。
如下Intent Filter的例子:
<activity android:name=”.mytestActivity” android:label=”test”> <intent-filter> <action android:name=”com.blueeagle.intent.action.MY_TEST”> </action> <category android:name=”android.intent.category.DEFAULT”/> <category android:name=”android.intent.category.ALTERNATIVE_SELECTED” /> <data android:mimeType=”vnd.android.cursor.dir/*”/> </intent-filter> </activity>
下面来说明一下这些东西都是干什么用的:(摘抄自Android高级编程)
❑ action
使用android:name特性来指定对响应的动作名。动作名必须是独一无二的字符串,所以,一个好的习惯是使用基于Java包的命名方式的命名系统。
❑category
使用android:category属性用来指定在什么样的环境下动作才被响应。每个Intent Filter标签可以包含多个category标签。你可以指定自定义的种类或使用Android提供的标准值,如下所示:
❑ALTERNATIVE
一个Intent Filter的用途是使用动作来帮忙填入上下文菜单。ALTERNATIVE种类指定,在某种数据类型的项目上可以替代默认执行的动作。例如,一个联系人的默认动作时浏览它,替代的可能是去编辑或删除它。
❑SELECTED_ALTERNATIVE
与ALTERNATIVE类似,但ALTERNATIVE总是使用下面所述的Intent解析来指向单一的动作。SELECTED_ALTERNATIVE在需要一个可能性列表时使用。
❑BROWSABLE
指定在浏览器中的动作。当Intent在浏览器中被引发,都会被指定成BROWSABLE种类。
❑DEFAULT
设置这个种类来让组件成为Intent Filter中定义的data的默认动作。这对使用显式Intent启动的Activity来说也是必要的。
❑GADGET
通过设置GADGET种类,你可以指定这个Activity可以嵌入到其他的Activity来允许。
❑HOME
HOME Activity是设备启动(登陆屏幕)时显示的第一个Activity。通过指定Intent Filter为HOME种类而不指定动作的话,你正在将其设为本地home画面的替代。
❑LAUNCHER
使用这个种类来让一个Activity作为应用程序的启动项。
❑data
data标签允许你指定组件能作用的数据的匹配;如果你的组件能处理多个的话,你可以包含多个条件。你可以使用下面属性的任意组合来指定组件支持的数据:
❑android:host
指定一个有效的主机名(例如,com.google)。
❑android:mimetype
允许你设定组件能处理的数据类型。例如,<type android:value=”vnd.android.cursor.dir/*”/>能匹配任何Android游标。
❑android:path
有效地URI路径值(例如,/transport/boats/)。
❑android:port
特定主机上的有效端口。
❑android:scheme
需要一个特殊的图示(例如,content或http)。
对Intent Filter匹配做出响应
当一个应用程序组件通过一个隐式的Intent启动的时候,它需要找到要执行的动作,以及执行这个动作所依赖的数据。
可以调用getIntent方法,来提取用来启动一个组件的Intent。
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Intent intent = getIntent();
使用getData和getAction方法来查找Intent的数据和动作。使用类型安全的get<type>Extra方法来提取存储在它的附件Bundle中的额外信息。
String dataPath = intent.getData().toString(); String action = intent.getAction();
白话文
上面说的我自己看着都晕,说点白话文吧。其实这个Intent Filter为隐式的Intent提供服务主要的流程如下:
启动一个Activity这个Activity可以认为是一个父Activity—>然后new一个Intent,这个new的intent需要有一个动作,而这个动作列表,Android都已经给你了,你也可以自己定义。一般情况下的动作有:(我们以ACTION_PICK作为例子)
ACTION_ANSWER:打开一个处理来电的活动,目前这个动作是由本地电话拨号程序进行处理的。
ACTION_CALL:打开一个电话拨号程序,并立即使用URI所提供的号码,拨打一个电话。通常,如果可能的话,使用Dial_Action是一种更好的方式。
ACTION_PICK:启动一个子活动,它可以让你从URI数据中得到一个条目。当关闭的时候,它应该向条目中返回一个执行得到的数据URI。这个活动的启动要跟取的数据有关,例如,传递content://contacts/people将会调用本地联系人列表。
New完这个Intent以后,就可以利用StartActivityForResult(intent,REQUIRE_CODE)
其中第二个参数为请求码。就是开启另外一个Activity的请求码。先不管这码什么用,就知道这个码随着startActivityForResult函数一起传给了新new的那个intent了。
必要的,在AndroidManifest.xml文件里要添加一个新的Intent Filter
<intent-filter> <action android:name="android.intent.action.PICK" /> <category android:name="android.intent.category.DEFAULT" /> <data android:path = "contacts" android:scheme="content"/> </intent-filter>
接下来就是写子Activity了。创建一个子Activity,这里就是为什么时候是隐式的原因:(我的理解是这样)
用getIntent()来找一个intent,然后用getData()来找一个intent的数据。
然后经过一系列操作以后,就用SetResult(Activity.RESULT_OK,outData);以及结束代码来结束这个子Activity,结束的时候,将把Activity.RESULT_OK传给父的Activity。
在父Activity中,则通过重载onActivityResult这个函数,来处理子Activity返回回去的结果。
完成测试以后需要添加一个阅读权限。
<uses-permission android:name="android.permission.READ_CONTACTS"/>
多的不说了,上源码:
ContactPicker.java
package com.blueeagle; import android.app.Activity; import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.provider.Contacts.People; import android.view.View; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ListView; import android.widget.SimpleCursorAdapter;/*
* Android开发之Intent、广播和接收
*
* Created on: 2011-8-15
* Author: blueeagle
* Email: liujiaxiang@gmail.com
*/ public class ContactPicker extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Intent intent = new Intent(); intent = getIntent(); String dataPath = intent.getData().toString(); String action = intent.getAction(); String[] from = new String[]{People.NAME}; final Uri data = Uri.parse(dataPath+"people/"); final Cursor c = managedQuery(data,null,null,null,null); int[] to = new int[] {R.id.itemTextView}; SimpleCursorAdapter myadapter = new SimpleCursorAdapter(this,R.layout.listitemlayout,c,from,to); ListView lv = (ListView)findViewById(R.id.contactListView); lv.setAdapter(myadapter); lv.setOnItemClickListener(new OnItemClickListener(){ public void onItemClick(AdapterView<?>parent,View view ,int pos,long id){ c.moveToPosition(pos); int rowId = c.getInt(c.getColumnIndexOrThrow("_id")); Uri outURI = Uri.parse(data.toString()+rowId); Intent outData = new Intent(); outData.setData(outURI); setResult(Activity.RESULT_OK,outData); finish(); } }); }
ContactPickerTest.java
package com.blueeagle; import android.app.Activity; import android.content.Intent; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.provider.Contacts.People; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.TextView;/*
* Android开发之Intent、广播和接收
*
* Created on: 2011-8-15
* Author: blueeagle
* Email: liujiaxiang@gmail.com
*/
public class ContactPickerTest extends Activity { /** Called when the activity is first created. */ public static final int PICK_CONTACT = 1; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.contentpicktester); Button myButton = (Button)findViewById(R.id.pick_content_button); myButton.setOnClickListener(new OnClickListener(){ public void onClick(View view){ Intent intent = new Intent(Intent.ACTION_DIAL,Uri.parse("content://contacts/")); startActivityForResult(intent,PICK_CONTACT); } }); } @Override public void onActivityResult(int reqCode,int resCode,Intent data){ super.onActivityResult(reqCode, resCode, data); switch(reqCode){ case(PICK_CONTACT):{ if(resCode == Activity.RESULT_OK){ Uri contactData = data.getData(); Cursor c = managedQuery(contactData,null,null,null,null); c.moveToFirst(); String name; name = c.getString(c.getColumnIndexOrThrow(People.NAME)); TextView tv; tv = (TextView)findViewById(R.id.selected_contact_textView); tv.setText(name); } break; } } } } }
Listitemlayout.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/itemTextView" android:layout_width="fill_parent" android:layout_height="wrap_content" android:padding="10px" android:textSize="16px" android:textColor="#FFF" /> </LinearLayout> Contentpicktester.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:id="@+id/selected_contact_textView" /> <Button android:id="@+id/pick_content_button" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="Pick Contact" /> </LinearLayout> 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" > <ListView android:id="@+id/contactListView" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.blueeagle" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="8" /> <application android:icon="@drawable/icon" android:label="@string/app_name"> <activity android:name=".ContactPicker" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.DIAL" /> <category android:name="android.intent.category.DEFAULT" /> <data android:path = "contacts" android:scheme="content"/> </intent-filter> </activity> <activity android:name=".ContactPickerTest" android:label="Cotent Pick Tester"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> <uses-permission android:name="android.permission.READ_CONTACTS"/> </manifest>
使用Intent Filter作为插件和扩展
Android还可以让未来的包对现有的应用程序提供新的功能。并且可以使用IntentFilter在运行时动态地填充菜单。
这就是所谓的插件模型。这样它们就可以通过新的应用程序组件来充分利用现在还没有实现的功能,而不用修改或者重新编译项目。
使用Intent 来广播事件
广播事件处理机制是系统级别的,可以通过构建Intent对象,然后调用sendBroadcast方法将广播发出。事件的接受是通过一个继承自BroadcastReceiver的类来实现的。继承后重写onReceiver()方法,在该方法中相应时间。
Intent可以作为不同进程间传递数据和事件的媒介。
例如:当来电,来信息,网络状态发生变化,电池电量发生变化的时候。Android会将这些信息广播出去。广播的这个过程,就是用Intent的过程。然后,比如我们开发一个监听电池电量变化的应用程序。这个程序注册了针对电池电量变化这一广播的接受。即Broadcast Receiver,那么就可以进行处理,比如接收到电池电量的信息后,以百分比的形式显示出来。
程序主动广播Intent是一个比较简单的过程,只需要构建一个Intent,然后把需要广播的数据写进去,调用sendBroadcast方法进行广播就可以了。
网上对于广播和接收写的例子较多,但是不够彻底。自定义广播事件的DEMO更是难以实现。系统自己的广播比较好解决。如何自定义自己的广播事件呢?
首先,先定义广播:
建立一个工程,作为广播的工程,以后的工程都可以接受这个工程广播的数据。
广播工程代码如下:
MyBroadcast.java
package com.todd; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.View; import android.widget.Button;/*
* Android开发之Intent、广播和接收
*
* Created on: 2011-8-15
* Author: blueeagle
* Email: liujiaxiang@gmail.com
*/
public class MyBroadcast extends Activity { public static final String NEW_BROADCAST = "com.todd.NEW_BROADCAST"; /* 这个静态常量字符串可以自己随便定义,代表自定义的action*/ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); Button mybutton = (Button)findViewById(R.id.mybutton); mybutton.setOnClickListener(new Button.OnClickListener() { public void onClick(View v) { Intent myIntent = new Intent(NEW_BROADCAST); myIntent.putExtra("MSG", "地瓜地瓜,我是土豆!"); myIntent.setAction(NEW_BROADCAST); sendBroadcast(myIntent); } }); } }
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" > <Button android:id="@+id/mybutton" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="发送广播" /> </LinearLayout>
然后再建立一个工程,作为接收的工程,这个工程负责接收广播工程广播出来的数据。
代码如下:
Intent_Receiver.java
package com.receiver; import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.widget.Toast;/*
* Android开发之Intent、广播和接收
*
* Created on: 2011-8-15
* Author: blueeagle
* Email: liujiaxiang@gmail.com
*/
public class Intent_Receiver extends BroadcastReceiver { /** Called when the activity is first created. */ @Override public void onReceive(Context context, Intent intent) { // TODO Auto-generated method stub String message = intent.getExtras().getString("MSG"); Toast.makeText(context, message, Toast.LENGTH_LONG).show(); System.out.println(message); } }
到这里还不算完。需要有一个注册的过程。注册的过程,就是让接收工程知道我要接收来自哪一个Intent的数据。
在androidmanifest.xml中注册如下:
<receiver android:name=".Intent_Receiver"> <intent-filter> <action android:name="com.todd.NEW_BROADCAST" /> </intent-filter> </receiver>
这样就把"com.todd.NEW_BROADCAST"动作注册到了接收工程中。如此,接收工程完毕。
但是这样就结束了吗?还没有。如果此时编译后,广播工程没有任何问题,但是接收工程会出错,classcast的错误。这是因为,我们在编译接收工程的时候,没有给接收工程一个Activity用于显示接收的信息。因此,我们需要定义一个Activity.
代码如下:
IntentRes.java
package com.receiver;
import android.app.Activity; import android.os.Bundle;
/*
* Android开发之Intent、广播和接收
*
* Created on: 2011-8-15
* Author: blueeagle
* Email: liujiaxiang@gmail.com
*/
public class IntentRes extends Activity { /** Called when the activity is first created. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); } }
当然,在相应的AndroidManifest.xml文件中要修改,写为:
<activity android:name=".IntentRes" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>
至此,就完成了广播和接收。他们位于不同的工程中。
相关推荐
一、广播发送者&广播接收者介绍 1.广播接收者 广播接收者简单地说就是接收广播意图的Java类,此Java类继承BroadcastReceiver类,重写: public void onReceive(Context context,Intent intent),其中intent可以获得...
恢复已经停止的更新下载。 'android.server.checkin.FOTA_RESTART' 通过 OTA 下载并安装操作系统更新。 'android.server.checkin.FOTA_UPDATE' 用户按下了'Media Button'。...'android.intent.action.PACKAGE_ADDED'
BOOT_COMPLETED_ACTION 在系统启动后,这个动作被广播一次(只有一次) "android.intent.action.BOOT_COMPLETED" CALL_FORWARDING_STATE_CHANGED_ACTION 语音电话的呼叫转移状态已经改变 "android.intent.action.CFF" ...
接收系统的时间流逝的广播,屏幕开启关闭的广播,电量改变的广播。这些广播在清单文件里注册时,看不到效果。在这个例子中通过在一个服务里面用代码注册的方式,成功接收了这些广播。
Intent的另一种用途是发送广播消息,应用程序和Android系统都可以使用Intent发送广播消息,广播消息的内容是可以与应用程序密切相关的数据信息,也可以是Android的系统信息,例如网络连接变化、电池电量变化、接收的...
主要介绍了Android中的广播和广播接收器代码实例,本文讲解了定义一个广播接收器、发送广播,定义好action标志、用Intent发送、注册只接收指定action的广播接收器、取消该广播接收器等操作代码实例,需要的朋友可以...
Android开发-Intent基础使用Intent用途Intent两种类型及使用方法 Intent用途 1.启动Activity 将Intent对象传递给startActivity()方法或startActivityForResult()方法以启动一个Activity,该Intent对象包含了要启动的...
嵌入式Android项目设计与开发 第五章 广播 ——自定义广播 自定义广播 自定义广播概念: 它是编程人员自己定制的广播。需要告诉系统该广播的“频道”是多少,其实就是描述什么样的过滤器能接受该广播。 过滤器通常由...
《Android开发案例驱动教程》 配套代码。 注: 由于第12,13,14章代码太大,无法上传到一个包中。 这三节代码会放到其他压缩包中。 作者:关东升,赵志荣 Java或C++程序员转变成为Android程序员 采用案例驱动模式...
然后在这个广播接收者接收到信息之后马上启动一个service public void onReceive Context context Intent intent { Log v "MyBrocast onReceive" "testtttttttttttt" ; if intent getAction ...
对于了解Android程序设计的人都知道,广播是Android开发中的一个重要的功能,在Android里面有各式各样的广播,比如:电池的状态变化、信号的强弱状态、电话的接听和短信的接收等等,今天本文就来给大家简单介绍一下...
的 Android SDK 提供了在 Android 平台上使用 JaVa 语言进行 Android 应用开发必须的工具和 API 接口。 特性 • 应用程序框架 支持组件的重用与替换 • Dalvik Dalvik Dalvik Dalvik 虚拟机 专为移动设备优化 • ...
接收系统广播实现查看电池电量,这里用到了 Intent.ACTION_BATTERY_CHANGED 事件
本文实例讲述了Android编程四大组件之BroadcastReceiver(广播接收者)用法。分享给大家供大家参考,具体如下: 这里介绍如何创建广播、如何发送一个无序广播和有序广播、以及监听短信以及监听呼出电话(当我们发短信和...
开机启动后,当系统发出android.intent.action.BOOT_COMPLETED广播时,接收该广播,并自动启动一个后台service。
用于异步接收广播Intent,广播Intent的发送是通过调用Context.sendBroadcast()、广播接收者(BroadcastReceiver)用于异步接收广播Intent,广播Intent的发送是通过调用Context.sendBroadcast()、Context....
【实验要求】 1、 练习使用静态方法和动态方法注册广播接收器 2、 练习发送广播消息的方法 3、 完成实验报告 二、实验内容 1、 新建 Android 应用程序项目 BroadcastTest; 2、 业务逻辑代码与界面布局文件如下: 1)...