现在的位置: 首页 > 综合 > 正文

Android四大组件

2014年09月05日 ⁄ 综合 ⁄ 共 33775字 ⁄ 字号 评论关闭
文章目录

四大组件

 

一.Activity

1.ActivityTask的关系

1LaunchMode

------stantard:创建一个新的Activity实例,且压入Task栈顶,taskId与启动这个Activity的调用者的Taskid相同

------singleTopActivityManageServiceAMS)会查询Task栈顶是否为该要被启动的Activity,如果不是该Activity的实例,则新建一个新的Activity实例,压入栈顶,反之将直接原封不动调用栈顶的Activity实例

------singleTaskAMS查询Task中是否存在将被启动的Activity,如果存在则将此Activity位于栈中之前的所有Activity销毁,将此Activity置于栈顶,并调用ActivityonNewIntent()方法,如此时战中有A,B,C,D,如果此时要启动Activity B,那么将会销毁B之前的CD,并将B置于栈顶,此时栈状态时A,B,最后调用BonNewIntent()

------singleInstance:如果Task中已有一个该Activity实例,则直接调用其onNewIntent

否则将新建一个Activity实例,并为之创建一个与其所在apk进程不同的Taski,且该TaskId值不会再被其他的Activity所用。

2)Intent启动Activity的参数launchFlags

 

3)ManifesttaskAffinityallowTaskRparenting,clearTaskLaunch

-----allowTaskReparenting:标识Activity能否从启动的Task移动到有着affinityTask,默认为false。用于:Activity从启动到死亡都在Task中,如果Task消亡,想使得Activity移动到有affinityTask中,如将一个应用的Activity移动到另一个应用中的task

----alwaysRetainTaskState:标识ActivityTask的状态是否总是有系统保存,由于特定情况下系统会清理Task的状态,如果需要保存则需要设置为true

----clearTaskOnLaunch:标识是否从Task中清除出根Activity意外的其他Activity

2.判断Activity是否存在

调用PackageManager.queryIntentActivities(intent,flag)来获取是否存在指定IntentActivity

代码:

PackageManager packageManager = getPackageManager();

Intent intent = new Intent(“com.ccp.wj.doit.forcast”);

List<ResolveInfo>list = packageManager.queryIntentActivities(intent,PackageManager.GET_INTENT_FILTER)

 

 

二.BroadcastReceiver

BroadcastReceiver-----通过注册于Manifest文件中,可接收指定Action的广播,如短信,或其他程序发送的广播

抽象类,可继承得到一个Receiver,在onReceive()中处理事件

通过sendReceiver(new Intent(Action))发送广播

2.异步发送广播:

sendStickyBroadcast(intent)----intent将一直存在,直到使用removeStickyBroadcast(intent)

需要添加<user-permission>----android.permission.BROADCAST_STICKY

否则抛出安全异常

3.判断BroadcastReceiver是否存在

PackageManager packageManager = getPackageManager();

Intent intent = new Intent(“com.ccp.wj.doit.forcast.broadcast”);

List<ResolveInfo>list = packageManager.queryBroadcastReceivers(intent,PackageManager.GET_INTENT_FILTER)

 

三.Service----四大组件之一,继承自Context,后台运行组件

startService

1.生命周期:

startService()==>onCreate()==>onStart()==>Runing stopService()==>onDestroy()==>Stop Service

如果服务已运行则只调用onCreate(),服务未运行则按上述方式。

2.IPC通信

bindService:

1.生命周期:

bindService()==>onCreate()==>onBind()==>Running

onUnBind()==onDestroy()==>Stop Service

此种方式将ActivityService绑定在一起,Activity退出则Service 停止,此谓同生共死。其中onBind()返回一个IBinder类对象,客户端可由此回调Service的方法。

2.aidl支持的数据类型

Java原语(int, long, char, boolean)|String,Charsequece|List&Map

而如果需要在AIDL中使用其他AIDL接口类型,需要import,即使是在相同包结构下。AIDL允许传递实现Parcelable接口的类,需要先添加一个该类的aidl文件再由import引入。
    需要特别注意的是,对于非基本数据类型,也不是String和CharSequence类型的,需要有方向指示,包括in、out和inout,in表示由客户端设置,out表示由服务端设置,inout是两者均可设置。

 3.IPC不同进程之间远程通信(Remote

1)基于C/S(客户端/服务端)架构的

2)用途:调用其他程序的服务,如在本程序中调用google的翻译服务等

需配置Manifestservice标签android:process=":remote",代表在应用程序里,当需要该service时,会自动创建新的进程。而如果是android:process="remote",没有:分号的,则创建全局进程,不同的应用程序共享该进程。

服务端和客户端的aidl文件必须存在于相同的包名下才能通过协议正确的通信否则出现Binder invocation to an incorrect interface因为服务器端和客户端aidl文件的包名不同导致生成的java文件不同。

相关文件

1.aidl文件:定义了客户端可用的方法和数据的接口

package com.ccp.wj.doit.aidl;

interface  DoItAidl {
	void onDataChanged(String reflag,String notifyCity);
}

2.客户端:

创建AIDL接口

  注:使用Interface AIDLInterface{}

Service实现Stub,实现AIDL接口

注:声明IBinder mBinder  = new IBinder.Stub()

公开AIDL接口给客户端

注:在onBind()中返回IBinder对象

代码如下

public class DoItService extends Service{
	private static final String tag = "DoItService";
	private  Context mContext;
	private  DoItService mService;
	private DoItAidl.Stub mBinder = new DoItAidl.Stub(){
		@Override
		public void onDataChanged(String reflag,String notifyCity) throws RemoteException {
			// TODO Auto-generated method stub
			onDateChange(reflag,notifyCity);
		}
		
	};
	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
		Log.d(tag, "onCreate---startService");
	}	
	@Override
	public IBinder onBind(Intent intent) {
		// TODO Auto-generated method stub
		return mBinder;//返回Binder
	}

3.服务端:

声明AIDL对象--》实现ServiceConnection-》获取AIDL对象实例

    private static DoItAidl mBinder;
	String flag="",notifyCity = null;
	private ServiceConnection mSC = new ServiceConnection(){
		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {
			// TODO Auto-generated method stub
			//mService = (DoItService) ((DoItService.MyBinder) service).getService();//取得Service
			mBinder = DoItAidl.Stub.asInterface(service);//获取binder对象
				try {
					mBinder.onDataChanged(flag,notifyCity);
				} catch (RemoteException e) {
					// TODO Auto-generated catch block
					Log.e(tag, e.toString());
				}
		}
		@Override
		public void onServiceDisconnected(ComponentName name) {
			// TODO Auto-generated method stub
			
		}
		
	};

注:创建了AIDL接口后将会在gen/包名/AIDL.java生成相对应的java文件

其中与LocalService不同:

1.Ibinder对象:LocalServiceIBinder对象继承Binder类,IPC继承自AIDL接口中的Stub内部类


4.实现传递复杂数据,传递类

关于Parcelable

1.使用Parcelable可以实现比序列化更高效率

2.注意要继承自Parcelable接口的类写成JavaBean模式

3.关于writeToParcelablepar,flag)和createFromParcel(par)

    1writeToParcelable(par,flag)

Parcelable类打包成Parcel对象,有parcelwriteXXX()方法将类的属性写入Parcel中,打包之后通过IntentIPC传递。

    2createFromParcelpar

parcel中的类对象属性由par.getXXX()读出来,然后由类的setXXX()方法将属性赋予新的JavaBean对象

4.实现了Parcelable的类必须有一个Parcelable.Creator<T>CREATOR的字段

步骤

1.实现Parcelable接口得到Person类并重写相应的方法writeToParcel()和
Parcelable.Creator<MyParcelable>

2.添加一个Personaidl文件并要和Person类放在同一个包中,一定要同名

3.在主aidl中就可以引入Person类了,作为参数需在前加in/out/inout


1.实现Parcelable


package com.doit.aidl;
 
import android.os.Parcel;
import android.os.Parcelable;
import android.util.Log;
/**server
 * 实现IPC 传递由Parcelable实现的类对象,写为JavaBean
 * 重点:
 * 1.Parcelable.Creator<T>对象的实现
 * 2.createFromParcel()--反序列化化
 * 3.newArray()--创建一个Parcel的对象数组
 * 4.writeToParcel()--序列化对象
 * @author ChenChunPeng
 *
 */
public class Person implements Parcelable {
private  String name , sex;
private int age;
private static String tag="Person"; 
public Person(Parcel pl){ //构造函数,与Parcelable.Creator中的createFromParcel(source)对应
        readFromParcel(pl);
} 
@Override
public int describeContents() {
// TODO Auto-generated method stub
Log.d("Person--Server", "describeContents");
return 0;
}
public void setName(String name){
this.name = name;
}
public void setSex(String Sex){
this.sex = Sex;
}
public void setAge(int age){
this.age = age;
}
public String getName(){
return name;
}
public String getSex( ){
return sex;
}
public int getAge( ){
return age;
}
@Override
public void writeToParcel(Parcel par, int flag) {//此方法将类对象打包成Parcel
// TODO Auto-generated method stub
Log.d("Person--Server", "writeToParcel");
par.writeString(name);
par.writeString(sex);
par.writeInt(age);
}
public void readFromParcel(Parcel in) {
// TODO Auto-generated method stub
name = in.readString(); 
        sex = in.readString(); 
        age = in.readInt(); 
Log.d(tag, "readFromParcel");
}
public final static Parcelable.Creator<Person>CREATOR = new Parcelable.Creator<Person>() {
@Override
public Person createFromParcel(Parcel source) {
// TODO Auto-generated method stub
Log.d(tag+"CREATOR", "createFromParcel");
return new Person(source);
}
@Override
public Person[] newArray(int size) {
// TODO Auto-generated method stub
Log.d(tag+"CREATOR", "newArray");
return new Person[size];
}
};
}

2.添加同一个包下的相对应的aidl文件

package com.doit.aidl;

parcelable  Person;/*声明Person是一个ParcelableJavaBean,注意文件名必须和可Parcelable的类名一致*/

 

3.在aidl中引入

package com.ccp.myaidl.aidl;

import com.ccp.myaidl.aidl.Person;

interface AIDL {

 String getString();

 Person getPerson();

 void addPerson(in Person person);

}

 

4.需在客户端也添加相同的Person类和Person.aidl

序列化的过程:

        客户端向服务端发送对象     

              writeToParcel()--createFromParcel()

              将对象序列化--------|----获取对象进行反序列化

        服务端向客户端发送对象

              createFromParcel()--writeToParcel()

              反序列化-------------|序列化

 

注:如何将ServiceActivity绑定起来

ServiceConnection类是监控Service状态的一个类,bindServiceintentcon,flag)将调用ServiceConnection对象,将客户端和服务端连接起来,连接成功后将调用onServiceConnected()。

3.LocalService---service的方法可以被其他类所调用

1.原理

因为service不同于Activity等的类,可以实例化后随便调用其方法或属性等,所以需要将需要调用Service方法的ActivityService绑定起来,这样就可以由Activity直接调用Service的方法了。

2.步骤

服务端:

----继承自Service

----实现一个继承自Binder类的类,以便在onBind()方法中返回给调用者

public class MyBinder extends Binder{//供被调用的IBinder对象返回Service实例

public Service getService(){

return DoItService.this;

}

}

在onBind中返回Service实例

@Override

public IBinder onBind(Intent arg0) {

// TODO Auto-generated method stub

return mBinder;//返回Binder

}

 

客户端:

-----添加一个新的ServiceConnection对象并在其中的onServiceConnected中获取Binder对象,onServiceDisconneted做出相关操作

----调用bindServiceService与调用者连接起来

5.设置前台程序----挂载到通知栏,如qq

public void setForground() {

// TODO Auto-generated method stub

Notification notif = new Notification(R.drawable.ic_launcher,"DoIt",System.currentTimeMillis());

Intent i = new Intent(this,WeatherDetailActivity.class);

PendingIntent pi = PendingIntent.getActivity(this, 0, i, 0);

notif.setLatestEventInfo(this"DoIt""It is test", pi);

int id = 0x987;

try{

this.startForeground(id, notif);}catch(Exception e){Log.e(tag, e.toString());}

}

:

A)setLastEventInfo与(notif.contentViewcontentIntent)只可设置一种,否则其余无效。

B)如果要更新前台服务需先取消前台后在设置前台服务,否则可能不更新

6.判断Service是否存在

如果bindService(intent)返回结果是false则表示不存在

 

四.ContentProvider

 

一)ContentProvider

通过继承ContentProvider类,实现抽象方法

2.关于URI

[content://][shy.luo.providers.articles][/item][/123]

        |------A------|-----------------B-------------------|---C---|---D--|

        A组件称为Scheme,它固定为content://表示它后面的路径所表示的资源是由Content Provider来提供的。

        B组件称为Authority,它唯一地标识了一个特定的Content Provider,因此,这部分内容一般使用Content Provider所在的package来命名,使得它是唯一的。

        C组件称为资源路径,它表示所请求的资源的类型,这部分内容是可选的。如果我们自己所实现的Content Provider只提供一种类型的资源访问,那么这部分内部就可以忽略;如果我们自己实现的Content Provider同时提供了多种类型的资源访问,那么这部分内容就不可以忽略了。例如,我们有两种电脑资源可以提供给用户访问,一种是笔记本电脑,一种是平板电脑,我们就把分别它们定义为notebookpad;如果我们想进一步按照系统类型来进一步细分这两种电脑资源,对笔记本电脑来说,一种是安装了windows系统的,一种是安装了linux系统的,我们就分别把它们定义为notebook/windowsnotebook/linux;对平板电脑来说,一种是安装了ios系统的,一种是安装了android系统的,我们就分别把它们定义为pad/iospad/android

        D组件称为资源ID它表示所请求的是一个特定的资源,它通常是一个数字,对应前面我们所介绍的数据库表中的_id字段的内容,它唯一地标志了某一种资源下的一个特定的实例。继续以前面的电脑资源为例,如果我们请求的是编号为123的装了android系统的平板电脑,我们就把它定义为pad/android/123

3.关于MIME类型---URI对应

我们还需要定义URI对应的资源的MIME类型。每个MIME类型由两部分组成

大类别

具体类别

Vnd.android.cursor.item-------------单个资源 vnd.android.cursor.dir  -------------多个资源

vnd.[company name].[resource type]

例:vnd.[ccp.wj].[test]-Provider所在包名

           MIME类型示意图

4.URi匹配规则

        因为我们是根据URI来操作数据库的,不同的URI对应不同的操作,所以我们首先要定义好URI匹配规则,这样,当我们获得一个URI时,就能快速地判断出要如何去操作数据库。设置URI匹配规则的代码如下所示:

[java] view plaincopy

 

private static final UriMatcher uriMatcher;  

static {  

      uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);  

      uriMatcher.addURI(Articles.AUTHORITY, "item", Articles.ITEM);  

      uriMatcher.addURI(Articles.AUTHORITY, "item/#", Articles.ITEM_ID);  

      uriMatcher.addURI(Articles.AUTHORITY, "pos/#", Articles.ITEM_POS);  

}  

        在创建UriMatcher对象uriMatcher时,我们传给构造函数的参数为UriMatcher.NO_MATCH,它表示当uriMatcher不能匹配指定的URI时,就返回代码UriMatcher.NO_MATCH。接下来增加了三个匹配规则,分别是content://shy.luo.providers.articles/itemcontent://shy.luo.providers.articles/item/#content://shy.luo.providers.articles/pos/#,它们的匹配码分别是Articles.ITEMArticles.ITEM_IDArticles.ITEM_POS,其中,符号#表示匹配任何数字

 

 

二)ContentProvider

1.创建步骤

--继承ContentProviderOverrider getType()方法

--》提供供外部访问的Uri

     注:(1)格式:content//<Authority>/<DataPath>/<单独的行号>

      ---Authority:com.ccp.provider,

      ---DataType:可以随便自己定义如items/daries等等。

例:content://com.ccp.provider/items</1>返回所有内容<第一行>

--通过UriMatcher类的addUri配置不同的访问形式的uri,最后由其match解析uri

 注:UriMatcher就是为配置和解析ContentProvider中的Uri而存在

      (1addUriString authority,String path,int code)

--authority:Uri中的Authority

--path:Uri中的DataPath,如果UriDataPathitems则,pathitems

--code:调用match()方法时返回的代码,如果为1,则matchuri)返回1

      (2matchUri uri

--添加数据库并实现insertupdatedelete

--返回MIME类型

   --返回的是一般数据:重写getType()方法返回MIME类型

注:

所有项:vnd.android.cursor.dir/contentType||vnd.<companyNmae>.cursor.dir/contenttype

单独项:vnd.android.cursor.item/contentType

contentType:vnd.<name>.<type>

<name>:com.companyName

<type>:自定义的文件类型

   --返回的是文件如图片等则重写getStreamTypes()

--》在Manifest中注册

<provider android:name=”ProviderName”

 Android:authority=”Authority”>

判断ContentProvider是否存在

Uri uri = new Uri(“content://mobile.android....”);

Cursor cursor = getContentResolver().query(uri,selections,null,null,null);

if(cursor==null)

 

五.关于ContentResolver

1.如何获取:通过Context对象调用getContentResolver()函数获取

六.Intent

Intent为何物

Intent是程序与系统之间的通信员,程序通过Intent对象告诉系统我将要做什么,系统根据程序的intent来做出适当的事情。如我要使得蓝牙在200s内可见,我就可以用intentaction_found)来告诉系统我要蓝牙可见200s,系统知道了则打开蓝牙,使得可见200s

概述

自我体会:actiondata的关系--dataaction所要操作的数据,如ACTION_VIEW所对应的data表示我要看的data内容是什么,是图片image/* ,文本 text/plainACTION_SEND所对应的data表示我要发送的data内容是什么。

Android  分享信息 

今天调查了android系统的应用软件的分享功能,发送信息采用参数ACTION_SEND,如下代码 

private void shareWeather() {

// TODO Auto-generated method stub

Intent shareIntent = new Intent(Intent.ACTION_SEND);

String path;

if(FileUtils.isSdCardExists())

path = FileUtils.pathInside+"/ScreenShot";

else path=FileUtils.path+"ScreenShot" ;

shareIntent.setType("image/*");

shareIntent.putExtra(Intent.EXTRA_STREAM, path+WeatherDetailFragment.getCurPageCity()+".jpg");

shareIntent.putExtra(Intent.EXTRA_SUBJECT"来自Do天气");

startActivity(Intent.createChooser(shareIntent, "请选择分享方式"));

}

无法分享到我手机自带的人人网和旧版腾讯微博。。。 

     SetType()对发送的信息进行数据格式的封装,如果没找到这个数据格式就无法分享,      就那我目前的手机gti5508,其人人网的应用软件中,只有mimiType=image/*”数据格式,如果安装有上面的程序,则在我手机会过滤掉,因此上面的信息内容我无法分享到人人网。分析如下:  

原来是在每个应用软件的AndroidManifest.xml文件中,如下: 

<action      android:name="android.intent.action.SEND"      > 

</action> 

<data      android:mimeType="text/plain"      > 

</data> 

若有添加如上的data,那么可以采用上面的方法进行分享,根据调查,最近更新的人人网,新浪,腾讯,开心网都有这个,因此不会被过滤掉。。。  

分享功能可以实现。 

Intent 理论 

1、概述 

一个应用程序的三个核心组件——activitiesservicesbroadcast 

receivers,都是通过叫做intents的消息激活。Intent消息是一种同一或不同应用程序中的组件之间延迟运行时绑定的机制。intent本身(是一个Intent对象),是一个被动的数据结构保存一个将要执行的操作的抽象描述,或在广播的情况下,通常是某事已经发生且正在宣告。对于这三种组件,有独立的传送intent的机制: 

· 

Activity:一个intent对象传递给Context.startActivity()

Activity.startActivityForRestult()去启动一个活动或使一个已存在的活动去做新的事情。  

· Service:一个intent对象传递给Context.startService()去初始化一个service或传递一个新的指令给正在运行的service。类似的,一个intent可以传递给Context.bindService()去建立调用组件和目标服务之间的连接。  

· Broadcast Receiver:一个intent对象传递给任何广播方法(如Context.sendBroadcast()Context.sendOrderedBroadcast()

Context.sendStickyBroadcast()),都将传递到所有感兴趣的广播接收者。  

在每种情况下,Android系统查找合适的activityservicebroadcast 

receivers来响应意图,如果有必要的话,初始化他们。这些消息系统之间没有重叠,即广播意图仅会传递给广播接收者,而不会传递活动或服务,反之亦然。 下面首先描述intent对象,然后介绍Androidintent映射到相应组件的规则——如何解决哪个组件应该接收intent消息。对于没有指定目标组件名字的intent,这个处理过程包括按照intent filters匹配每个潜在的目标对象。

 2Intent对象 

一个Intent对象是一个捆信息,包含对intent有兴趣的组件的信息(如要执行的动作和要作用的数据)、Android系统有兴趣的信息(如处理intent组件的分类信息和如何启动目标活动的指令)。下面列出它的主要信息: 

2.1、组件名字 

处理intent的组件的名字。这个字段是一个ComponentName 象——是目标组件的完全限定类名(如"com.example.project.app.FreneticActivity")和应用程序所在的包在清单 文件中的名字(如"com.example.project")的组合。其中组件名字中的包部分不必一定和清单文件中的包名一样。 

组件名字是可选的,如果设置了,intent对象传递到指定类的实例;如果没有设置,Android使用intent中的其它信息来定位合适的目标组件(见下面的Intent解析)。组件的名字通过setComponent()setClass()setClassName()设置,通过getComponent()读取。

 2.2、动作 

一个字符串命名的动作将被执行,或在广播intent中,已发生动作且正被报告。Intent类定义了一些动作常量,如下: 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.  

查看更多的动作请参考Intent类。其它的动作定义在Android API中,我们还可以定义自己的动作字符串一再我们的应用程序中激活组件。自定义动作字符串应该包含应用程序报名前缀,如"com.example.project.SHOW_COLOR"  作很大程度上决定了剩下的intent如何构建,特别是数据(data)和附加(extras)字段,就像一个方法名决定了参数和返回值。正是这个原因, 应该尽可能明确指定动作,并紧密关联到其它intent字段。换句话说,应该定义你的组件能够处理的Intent对象的整个协议,而不仅仅是单独地定义一 个动作。 一个intent对象的动作通过setAction()方法设置,通过getAction()方法读取。

 2.3、数据 

 据(data)是将作用于其上的数据的URI和数据的MIME类型。不同的动作有不同的数据规格。例如,如果动作字段是ACTION_EDIT,数据字段 将包含将显示用于编辑的文档的URI;如果动作是ACTION_CALL,数据字段将是一个tel:URI和将拨打的号码;如果动作是 ACTION_VIEW,数据字段是一个http:URI,接收活动将被调用去下载和显示URI指向的数据。 

当匹配一个intent到一个能够处理数据的组件,通常知道数据的类型(它的MIME类型)和它的URI很重要。例如,一个组件能够显示图像数据,不应该被调用去播放一个音频文件。 

在许多情况下,数据类型能够从URI中推测,特别是content:URIs,它表示位于设备上的数据且被内容提供者(content provider)控制。但是类型也能够显示地设置,setData()方法指定数据的URIsetType()指定MIME类型,setDataAndType()指定数据的URIMIME类型。通过getData()读取URIgetType()读取类型。 2.4、种类 

此外,还包含关于应该处理intent的组件类型信息。可以在一个Intent对象中指定任意数量的种类描述。Intent类定义的一些种类常量,如下这些: 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.  更多的种类常量请参考Intent类。 

addCategory()方法添加一个种类到Intent对象中,removeCategory()方法删除一个之前添加的种类,getCategories()方法获取Intent对象中的所有种类。 2.5、附加信息 

 外的键值对信息应该传递到组件处理intent。就像动作关联的特定种类的数据URIs,也关联到某些特定的附加信息。例如,一个 ACTION_TIMEZONE_CHANGE intent有一个"time-zone"的附加信息,标识新的时区,ACTION_HEADSET_PLUG有一个"state"附加信息,标识头部现 在是否塞满或未塞满;有一个"name"附加信息,标识头部的类型。如果你自定义了一个SHOW_COLOR动作,颜色值将可以设置在附加的键值对中。 

Intent对象有一系列的put()方法用于插入各种附加数据和一系列的get()用于读取数据。这些方法与Bundle对象的方法类似,实际上,附加信息可以作为一个Bundle使用putExtras()getExtras()安装和读取。 2.6、标志 

有各种各样的标志,许多指示Android系统如何去启动一个活动(例如,活动应该属于那个任务)和启动之后如何对待它(例如,它是否属于最近的活动列表)。所有这些标志都定义在Intent类中。 

3Intent解析 Intent可以分为两组: 

· 

显式intent:通过名字指定目标组件。因为开发者通常不知道其它应用程序的组件名字,显式intent通常用于应用程序内部消息,如一个活动启动从属的服务或启动一个姐妹活动。  · 隐式intent:并不指定目标的名字(组件名字字段是空的)。隐式intent经常用于激活其它应用程序中的组件。  

Android传递一个显式intent到一个指定目标类的实例。Intent对象中只用组件名字内容去决定哪个组件应该获得这个intent,而不用其他内容。  intent需要另外一种不同的策略。由于缺省指定目标,Android系统必须查找一个最适合的组件(一些组件)去处理intent——一个活动或服 务去执行请求动作,或一组广播接收者去响应广播声明。这是通过比较Intent对象的内容和intent过滤器(intent filters)来完成的。intent过滤器关联到潜在的接收intent的组件。过滤器声明组件的能力和界定它能处理的intents,它们打开组件 接收声明的intent类型的隐式intents。如果一个组件没有任何intent过滤器,它仅能接收显示的intents,而声明了intent过滤 器的组件可以接收显示和隐式的intents 

只有当一个Intent对象的下面三个方面都符合一个intent过滤器:actiondata(包括URI和数据类型)、category,才被考虑。附加信息和标志在解析哪个组件接收intent中不起作用。

 3.1Intent过滤器 

 动、服务、广播接收者为了告知系统能够处理哪些隐式intent,它们可以有一个或多个intent过滤器。每个过滤器描述组件的一种能力,即乐意接收的 一组intent。实际上,它筛掉不想要的intents,也仅仅是不想要的隐式intents。一个显式intent总是能够传递到它的目标组件,不管 它包含什么;不考虑过滤器。但是一个隐式intent,仅当它能够通过组件的过滤器之一才能够传递给它。 一个组件的能够做的每一工作有独立的过滤器。例如,记事本中的NoteEditer活动有两个过滤器,一个是启动一个指定的记录,用户可以查看和编辑;另一个是启动一个新的、空的记录,用户能够填充并保存。 

一个intent过滤器是一个IntentFilter类的实例。因为Android系统在启动一个组件之前必须知道它的能力,但是intent过滤器通常不在java代码中设置,而是在应用程序的清单文件(AndroidManifest.xml)中以<intent-filter>元素设置。但有一个例外,广播接收者的过滤器通过调用Context.registerReceiver()动态地注册,它直接创建一个IntentFilter对象。  个过滤器有对应于Intent对象的动作、数据、种类的字段。过滤器要检测隐式intent的所有这三个字段,其中任何一个失败,Android系统都不 会传递intent给组件。然而,因为一个组件可以有多个intent过滤器,一个intent通不过组件的过滤器检测,其它的过滤器可能通过检测。

 3.1.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对象仅是单个动作,但是一个过滤器可以列出不止一个。这个列表不能够为空,一个过滤器必须至少包含一个<action>子元素,否则它将阻塞所有的intents 

要通过检测,Intent对象中指定的动作必须匹配过滤器的动作列表中的一个。如果对象或过滤器没有指定一个动作,结果将如下: 

· 

如果过滤器没有指定动作,没有一个Intent将匹配,所有的intent将检测失败,即没有intent能够通过过滤器。  

· 如果Intent对象没有指定动作,将自动通过检查(只要过滤器至少有一个过滤器,否则就是上面的情况了)  

3.1.2、种类检测 

类似的,清单文件中的<intent-filter>元素以<category>子元素列出种类,例如: 

<intent-filter . . . > 

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

</intent-filter> 

注意本文前面两个表格列举的动作和种类常量不在清单文件中使用,而是使用全字符串值。例如,例子中所示 "android.intent.category.BROWSABLE"字符串对应于本文前面提到的BROWSABLE常量。类似 的,

"android.intent.action.EDIT"字符串对应于ACTION_EDIT常量。 

对于一个intent要通过种类检测,intent对象中的每个种类必须匹配过滤器中的一个。即过滤器能够列出额外的种类,但是intent对象中的种类都必须能够在过滤器中找到,只有一个种类在过滤器列表中没有,就算种类检测失败! 因此,原则上如果一个intent对象中没有种类(即种类字段为空)应该总是通过种类测试,而不管过滤器中有什么种类。但是有个例外,Android对待所有传递给Context.startActivity() 隐式intent好像它们至少包含

"android.intent.category.DEFAULT"(对应CATEGORY_DEFAULT常量)。 因此,活动想要接收隐式intent必须要在intent过滤器中包含"android.intent.category.DEFAULT" 

注意:"android.intent.action.MAIN"  "android.intent.category.LAUNCHER"设置,它们分别标记活动开始新的任务和带到启动列表界面。它们可以包 "android.intent.category.DEFAULT"到种类列表,也可以不包含。 

3.1.3、数据检测 

类似的,清单文件中的<intent-filter>元素以<data>子元素列出数据,

例如

 <intent-filter . . . > 

    <data android:mimeType="video/mpeg" android:scheme="http" . . . />      <data android:mimeType="audio/mpeg" android:scheme="http" . . . />     . . . 

</intent-filter> 

每个<data>元素指定一个URI和数据类型(MIME类型)。它有四个属性schemehostportpath对应于URI的每个部分:  scheme://host:port/path  例如,下面的URI  

content://com.example.project:200/folder/subfolder/etc  

schemecontenthost"com.example.project"port200path "folder/subfolder/etc"hostport一起构成URI的凭据(authority),如果host没有指定,port也被 忽略。 这四个属性都是可选的,但它们之间并不都是完全独立的。要让authority有意义,scheme必须也要指定。要让path有意义,schemeauthority也都必须要指定。 

当比较intent对象和过滤器的URI时,仅仅比较过滤器中出现的URI属性。例如,如果一个过滤器仅指定了scheme,所有有此scheme URIs都匹配过滤器;如果一个过滤器指定了schemeauthority,但没有指定path,所有匹配schemeauthority URIs都通过检测,而不管它们的path;如果四个属性都指定了,要都匹配才能算是匹配。然而,过滤器中的path可以包含通配符来要求匹配path 的一部分。 

<data>元素的type属性指定数据的MIME类型。Intent对象和过滤器都可以用"*"通配符匹配子类型字段,例如"text/*""audio/*"表示任何子类型。 数据检测既要检测URI,也要检测数据类型。规则如下: 

· 

一个Intent对象既不包含URI,也不包含数据类型:仅当过滤器也不指定任何URIs和数据类型时,才不能通过检测;否则都能通过。  

· 一个Intent对象包含URI,但不包含数据类型:仅当过滤器也不指定数据类型,同时它们的URI匹配,才能通过检测。例如,mailto:tel:都不指定实际数据。  

· 一个Intent对象包含数据类型,但不包含URI:仅当过滤也只包含数据类型且与Intent相同,才通过检测。  

· 一个Intent对象既包含URI,也包含数据类型(或数据类型能够从URI推断出):数据类型部分,只有与过滤器中之一匹配才算通过;URI部分,它的URI要出现在过滤器中,或者它有content:file: URI,又或者过滤器没有指定URI。换句话说,如果它的过滤器仅列出了数据类型,组件假定支持content:file:   

如果一个Intent能够通过不止一个活动或服务的过滤器,用户可能会被问那个组件被激活。如果没有目标找到,会产生一个异常。

 3.2、通用情况 上面最后一条规则表明组件能够从文件或内容提供者获取本地数据。因此,它们的过滤器仅列出数据类型且不必明确指出content:file: scheme的名字。这是一种典型的情况,一个<data>元素像下面这样:  <data android:mimeType="image/*" /> 

告诉Android这个组件能够从内容提供者获取image数据并显示它。因为大部分可用数据由内容提供者(content provider)分发,过滤器指定一个数据类型但没有指定URI或许最通用。 

另一种通用配置是过滤器指定一个scheme和一个数据类型。例如,一个<data>元素像下面这样: 

<data android:scheme="http" android:type="video/*" /> 

告诉Android这个组件能够从网络获取视频数据并显示它。考虑,当用户点击一个web页面上的link,浏览器应用程序会做什么?它首先会试图 去显示数据(如果link是一个HTML页面,就能显示)。如果它不能显示数据,它将把一个隐式Intent加到scheme和数据类型,去启动一个能够 做此工作的活动。如果没有接收者,它将请求下载管理者去下载数据。这将在内容提供者的控制下完成,因此一个潜在的大活动池(他们的过滤器仅有数据类型)能 够响应。 

大部分应用程序能启动新的活动,而不引用任何特别的数据。活动有指定

"android.intent.action.MAIN"的动作的过滤器,能 够启动应用程序。如果它们出现在应用程序启动列表中,它们也指定"android.intent.category.LAUNCHER"种类: 

<intent-filter . . . > 

    <action android:name="code android.intent.action.MAIN" /> 

<category android:name="code android.intent.category.LAUNCHER" /> </intent-filter>

 3.3、使用intent匹配 

Intents对照着Intent过滤器匹配,不仅去发现一个目标组件去激活,而且去发现设备上的组件的其他信息。例如,Android系统填充应 用程序启动列表,最高层屏幕显示用户能够启动的应用程序:是通过查找所有的包含指定了"android.intent.action.MAIN"的动作 

"android.intent.category.LAUNCHER"种类的过滤器的活动,然后在启动列表中显示这些活动的图标和标签。类似的,它通 过查找有

"android.intent.category.HOME"过滤器的活动发掘主菜单。 

我们的应用程序也可以类似的使用这种Intent匹配方式。PackageManager有一组query()方法返回能够接收特定intent的所有组件,一组resolve()方法决定最适合的组件响应intent。例如,queryIntentActivities()返回一组能够给执行指定的intent参数的所有活动,类似的queryIntentServices()返回一组服务。这两个方法都不激活组件,它们仅列出所有能够响应的组件。对应广播接收者也有类似的方法——queryBroadcastReceivers()

 

1.ACTION:

常用解释

ACTION_VIEW:表示打开一个与视图’看‘相关的,比如我在外部打开txt文档,所选择的应用就是一个view

ACTION_SEND:表示与发送有关,如发送短信,邮件,发送qq空间心情,发微博,这是因为相关的应用在相应的IntentFilter中添加了相应的DATAMIME数据类型。

ACTION_EDIT

2.DATA:添加了相应的data即MIMI数据类型就可以让用户在外部打开相应的文件时,让本身应用可被选中。

Intent打开其他应用

1.打开网页(借助第三方软件)

startActivity(new Intent(Intent.ACTION_VIEW),url);//打开指定url的网页

2.打开闹钟设置

Intent(“android.intent.action.SET_ALARM”)

注:需要添加

<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>,因为时钟程序设置了<permission标签>

3.发送邮件

 

4.打电话

Intent(Intent.ACTION_CALL,Uri.parse(“tel:12345667”));

5.将号码传入拨号 程序

Intent(Intent.ACTION_DIAL,Uri.parse(“tel:12344”));

6.调用拨号程序

Intent(“com.android.phone.action.TOUCH_DIALER”);

注:添加权限<uses-permission id="android.permission.CALL_PHONE" />

 

7.查看联系人

Intent“com.android.contacts.action.LIST_CONTACTS”);

8.显示设置界面

Intent(“android.settings.SETTINGS”);

9.WIFI设置

Intent(‘android.settings.WIFI_SETTINGS’)

10.打开地图具体位置

Uri uri = Uri.parse("geo:38.899533,-77.036476");

Intent it = new Intent(Intent.Action_VIEW,uri);

startActivity(it); 

 

11.显示路径

Uri uri = 

Uri.parse("http://maps.google.com/maps?f=d&saddr=startLat%20startLng&daddr=endLat%20endLng&hl=en");

Intent it = new Intent(Intent.ACTION_VIEW,URI);

startActivity(it);

 

12.发送短信-调用短信程序

Intent it = new Intent(Intent.ACTION_VIEW);   

it.putExtra("sms_body", "The SMS text");   

it.setType("vnd.android-dir/mms-sms");   

startActivity(it);  

 

13.发送短信

Uri uri = Uri.parse("smsto:0800000123");   

Intent it = new Intent(Intent.ACTION_SENDTO, uri);   

it.putExtra("sms_body", "The SMS text");   

startActivity(it);  

 

14.发送彩信

Uri uri = Uri.parse("content://media/external/images/media/23");   

Intent it = new Intent(Intent.ACTION_SEND);   

it.putExtra("sms_body", "some text");   

it.putExtra(Intent.EXTRA_STREAM, uri);   

it.setType("image/png");   

startActivity(it); 

 

15.发送邮件 

1)基本

    Uri uri = Uri.parse("mailto:xxx@abc.com");

Intent it = new Intent(Intent.ACTION_SENDTO, uri);

startActivity(it);

2)发送具有内容的邮件

Intent it = new Intent(Intent.ACTION_SEND);   

it.putExtra(Intent.EXTRA_EMAIL, new{"me@abc.com"});   

it.putExtra(Intent.EXTRA_TEXT, "The email body text");   

it.setType("text/plain");   

startActivity(Intent.createChooser(it, "Choose Email Client"));  

 

Intent it=new Intent(Intent.ACTION_SEND);     

String[] tos={"me@abc.com"};     

String[] ccs={"you@abc.com"};    //注意是数组形式 

it.putExtra(Intent.EXTRA_EMAIL, tos);     

it.putExtra(Intent.EXTRA_CC, ccs);     

it.putExtra(Intent.EXTRA_TEXT, "The email body text");     

it.putExtra(Intent.EXTRA_SUBJECT, "The email subject text");     

it.setType("message/rfc822");     

startActivity(Intent.createChooser(it, "Choose Email Client"));   

 

 

4)添加附件

    Intent it = new Intent(Intent.ACTION_SEND);   

it.putExtra(Intent.EXTRA_SUBJECT, "The email subject text");   

it.putExtra(Intent.EXTRA_STREAM, "file:///sdcard/mysong.mp3");   

sendIntent.setType("audio/mp3”);

startActivity(Intent.createChooser(it, "Choose Email Client"));  

 

注:Intent.createChooser()的效果就是出现一个选择对话框,选择合适的程序

 

16.GooglePlay中搜索应用

1)根据id搜索

   Uri uri = Uri.parse("market://detail?id = “应用id”");

Intent it = new Intent(Intent.ACTION_VIEW, uri);

startActivity(it);

 

2)根据程序名字搜索

Uri uri = Uri.parse("market://search?q = “应用名”");

Intent it = new Intent(Intent.ACTION_SENDTO, uri);

startActivity(it);

 

 

17.打开安装界面

Intent i = new Intent(Intent.ACTION_VIEW);

String apkPath = “/sdcard/XXX.apk”;

i.setDataAndType(Uri.parse(“file://”+apkPaht),”application/vnd.android.package-archive”);

startActivity(i);

18.发送图片

private void shareWeather() {

// TODO Auto-generated method stub

Intent shareIntent = new Intent(Intent.ACTION_SEND);

String path = null;

if(FileUtils.isSdCardExists())

path = FileUtils.pathInside+"ScreenShot/";

else path=FileUtils.path+"ScreenShot/" ;

//path = path+WeatherDetailFragment.getCurPageCity()+".jpg";

//File file = new File(path);

//path = file.getAbsolutePath();

Uri uri = Uri.fromFile(file);

shareIntent.setType("text/*");

shareIntent.setType("image/*");

//shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); 

shareIntent.putExtra(Intent.EXTRA_STREAM, uri);

shareIntent.putExtra(Intent.EXTRA_SUBJECT"来自Do天气");

startActivity(Intent.createChooser(shareIntent, "请选择分享方式"));

}

注:file变量为图片的具体路径,通过UrifromFile()来获取它的Uri变量

 

 

PendingIntent相关

1.如何获取PendingIntent

PendingIntent pi = PendingIntent.getBroadcast();//获取一个PendingIntent将发送一个广播

= PendingIntent.getActivity();//将启动一个Intent

=PendingIntent.getService();//将启动一个Service

注:

当在屏幕上有多个widget时,无论在哪个widget上点击,响应事件的总是最后一个widget,原因就是PendingIntent传值时出现了错误,每次添加的新PendingIntent把原来的PendingIntent的替换掉了、

PendingIntent pi = PendintIntent.getBroadcast(context, 0, intent,0);

我们固定把第二个参数设置了为0.而第二个参数表示的是requestCode表示发送器的私有请求码,相当于pendingIntent的一个IdPendingIntent会根据这个请求码来判断是否存在相同的PendingIntent,如果存在则替换,所以出现了以上情况。

建议PendingIntent pendingIntent = PendingIntent.getBroadcast(context,appWidgetId,intent,0);

 

 七.Intent与其余组件的关系

可有Intent对象转到目的Activity

1.步骤:

(1)声明Intent对象

(2)调用setClass()设置转向目的地

//如果为用new IntentMainActivity.this,ShowActivity.class

(3)向目的Activity传递数据:

---------可直接调用intent.putExtra(key,Value)

----------亦可由Bundle类来装载需传递数据

(4)启动intent:调用startActivityintent---不需要返回结果

调用startActivityForResultintentREQUEST_CODE);有返回结果,并

  且与onActivityResult相互关联:返回结果之后由系统自动调用此函数来处理相关

5setResultRESULT_OK,intent;//startActivityForResult()设置返回结果,用于                     onActivityResult(int requestCode, int resultCode, Intent data) 中第二个参
数resultCode的判断;

代码如下:

@Override
public void onClick(View v) {
// TODO Auto-generated method stub
dispToast("new activity");
Intent intent= new Intent();
        intent.setClass(MainActivity.this,ShowActivity.class);
Bundle bundle = new Bundle();
bundle.putString("name", "ccc");
intent.putExtras(bundle);
startActivityForResult(intent,REQUEST_CODE);
//startActivity(intent);
setResult(RESULT_OK,intent);
}
//onActivity
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
super.onActivityResult(requestCode, resultCode, data);
Toast.makeText(this,"for Result",Toast.LENGTH_SHORT).show();
if(requestCode==REQUEST_CODE ){
if(resultCode == RESULT_CANCELED){
setTitle("Cancel");
}
if(resultCode == RESULT_OK){
String temp;
Bundle bundle = data.getExtras();
temp = bundle.getString("name");
setTitle(temp);
}
}
}
 
}

(二)调用外部程序的方法

1.使用action

Intent intent =new Intent();

intent.setAction(com.test.action.PLAYER)

startActivity(intent);

 

注:B程序中的AndroidManifest.xml中启动Activityintent-filter

<intent-filter

action android:name="android.intent.action.MAIN"

action android:name="com.test.action.PLAYER"

category android:name="android.intent.category.DEFAULT"必须,否则无效

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

 

2.使用包名和类名

Intent intent =new Intent();

intent.setClassName(包名,类名)

startActivity(intent);

注:

打开qq

//intent.setClassName("com.tencent.mobileqq""com.tencent.mobileqq.activity.SplashActivity");

intent.setClassName(arg1,arg2)中的arg1是被调用程序B的包名,arg2B程序中目的activity的完整类名。

 

3.使用ComponentName

Intent intent =new Intent();         

ComponentName comp=new ComponentName(包名,类名);

//打开qq

intent.setComponent("com.tencent.mobileqq", "com.tencent.mobileqq.activity.SplashActivity");

intent.setComponent(comp); 

startActivity(intent);

 

注:B程序(被调用)中的AndroidManifest.xml中启动Activityintent-filter不需要特别加入其它信息,如下即可:

<intent-filter 

action android:name="android.intent.action.MAIN"

category android:name="android.intent.category.LAUNCHER">

<.intent-filter>

 

4.示例

A)打开系统闹钟设置界面

1)因为时钟程序设置了

<permission android:name = com.android.alarm.permission.SET_ALARM>的限制,所以需要添加一个<uses-permission android:name = “com.android.alarm.permission.SET_ALARM”>

 

2)Intentaction隐式调用时钟的Activity

Intent intent = new Intent();

intent.setAction("android.intent.action.SET_ALARM");

startActivity(intent);

 

 

 

 

 

(三)使得Activity被其他程序所调用

但是如果你的程序可以实现某些功能,这些功能能够被其他程序使用,那么你的程序需要准备好响应其他程序的请求。例如,如果你做了一个可以分享信息和照片给朋友的社交程序,你最好让你的程序支持ACTION_SEND意图,以便用户可以在其他程序启动一个“分享”功能,并且运行你的程序去执行这个功能。

要让其他程序可以运行你的activity,你需要在相应的元素中添加一个元素。

当你的程序安装到设备中时,系统会识别你的intent过滤器,并把这些信息添加到一个内部intent支持目录,这个目录包含所有安装好的程序所支持的intent。当程序调用startActivity()或者startActivityForResult(),并使用隐式intent时,系统会查找能够响应这个intentactivity

添加一个Intent过滤器

为了合理定义你的activity能够处理的intent,每个添加的过滤器必须尽可能详细的指明功能类型和activity支持的数据。

如果activity包含的intent过滤器符合下面所有的Intent对象的条件,系统会发送一个给定的intentactivity

Action

动作执行的字符串名称,通常使用一个平台指定值,如ACTION_SEND或者ACTION_VIEW

使用intent过滤器的元素指定。值必须是完整的动作名称,而不仅仅是API常数。

Data

intent相关联的数据描述。

使用元素指定。这个元素可以使用一个或者多个属性,你可以指定只是MIME type,只是URI prefix,只是URI scheme,或者一个他们的组合体和其他可以接受的数据类型。

提示:如果你不详细的声明数据Uri(例如activity不是处理URI,而是其他附加数据),你应该仅指明一个Android:mimeType属性去声明你的activity可以处理的数据类型,比如text/plain或者image/jpeg

Category

提供一个额外的方式去描述一个activity可以处理的intent,通常是关于用户开始的手势或者位置。这里有很多系统支持的分类,但是大部分不常用。所有隐式的intent都是默认定义了CATEGORY_DEFAULT分类。

使用元素指定。

在你的intent过滤器中,你可以在内部使用XML声明你的activity可以接受的条件。

例如,这里有一个intent过滤器,它能处理ACTION_SEND Intent,数据必须是文本或者图像:

<activityandroid:name="ShareActivity">

<intent-filter>

<actionandroid:name="android.intent.action.SEND"/>

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

<dataandroid:mimeType="text/plain"/>

<dataandroid:mimeType="image/*"/>

</intent-filter>

</activity>

每个intent只能指定一个动作和一个数据类型,但是在<intent-filter>中声明多个<action>,<category>, <data>是允许的。

如果两对动作和数据是相互独立的,你应该创建两个独立的intent过滤器去指定哪个动作接收哪个数据类型。

例如,假如你的activity使用ACTION_SENDACTION_SENDTO处理文本和图像。这种情况下,你必须定义两个独立的intent过滤器,因为ACTION_SENDTO intent必须使用Uri数据去指定收件人的地址,使用send或者sendto执行URI方案。例如:

<activityandroid:name="ShareActivity">

<!-- filter for sending text; accepts SENDTO action with sms URI schemes -->

<intent-filter>

<actionandroid:name="android.intent.action.SENDTO"/>

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

<dataandroid:scheme="sms"/>

<dataandroid:scheme="smsto"/>

</intent-filter>

<!-- filter for sending text or images; accepts SEND action and text or image data -->

<intent-filter>

<actionandroid:name="android.intent.action.SEND"/>

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

<dataandroid:mimeType="image/*"/>

<dataandroid:mimeType="text/plain"/>

</intent-filter>

</activity>

提示:为了接收隐式的intent,你必须包括CATEGORY_DEFAULT分类在intent过滤器中。startActivty()startActivityForResult()处理所有包含了CATEGORY_DEFAULT分类的intent。如果不声明,那么隐式的intent不会匹配你的activity

更多关于发送和接收ACTION_SEND意图执行分享动作的信息,可以查看 Receiving Content from Other Apps

在你的Activity中处理Intent

为了决定在activity中执行什么动作,你需要读取intent

当你启动activity时,调用getIntent()去接收Intent。你可以在activity生命周期的任何时候调用,但是通常是在onCreate()或者onStart()中。

例如:

@Override

protectedvoidonCreate(BundlesavedInstanceState){

super.onCreate(savedInstanceState);setContentView(R.layout.main);

// Get the intent that started this activity

Intentintent =getIntent();

Uridata =intent.getData();

// 基于intent类决定做什么

if(intent.getType().indexOf("image/")!=-1){

// 使用图片类型处理intent ...

}elseif(intent.getType().equals("text/plain")){

// 使用文本类型处理intent ...

}

}

返回一个结果

如果你想返回一个结果给调用你的activity,调用setResult()去指定结果代码和结果Intent。当你的操作完成,用户需要返回到原来的activity,你需要调用finish()去关闭你的activity。例如:

// Create intent to deliver some kind of result data

Intentresult =newIntent("com.example.RESULT_ACTION",Uri.parse("content://result_uri");

setResult(Activity.RESULT_OK,result);

finish();

你必须指定一个结果代码,通常是RESULT_OK或者RESULT_CANCELED。需要的话还可以附加数据到intent中。

提示:RESULT_CANCELED是默认的,如果用户在完成动作前,或者是设置结果前按返回按钮,那么原来的activity会接收到“canceled”结果。

如果你只是需要返回一个整形去指定多个操作中的一个,你可以设置结果代码为任何大于0的数。如果是使用结果代码发送一个数,你不需要包含Intent,你可以调用setResult()接收一个唯一的结果代码,例如:

setResult(RESULT_COLOR_RED);

finish();

这种情况下,可能只有少数可能的结果,所有结果代码是一个本地定义的整数。在自己的程序中可以运行良好,因为这个结果代码可以被定义成公共的常量。

提示:不用判断你的activity是通过startActivity()还是startActivityForResult()启动的。只要调用setResult()就可以返回一个结果。如果原来的activity是通过startActivityForResult()调用的,系统就会发送你提供给setResult()的结果。startActivity()调用的话,结果会被忽略。

 

抱歉!评论已关闭.