[Android基础]Intent

来源:互联网 发布:java简单课程设计 编辑:程序博客网 时间:2024/05/22 12:25

Intent的api:http://www.android-doc.com/reference/android/content/Intent.html


一.Intent的属性(详见api中Intent的Constants)

1.action,执行的动作,除了android提供的action,也可以自定义action(以包名为前缀),例如com.example.project.SHOW_COLOR

2.data,执行动作要操作的数据(以URI表示),例如content://contacts/1

3.category,被执行动作的附加信息

4.extras,附加信息


隐式Intent:

如果Intent明确指定了目标组件的类名称,则为显式Intent,否则为隐式Intent。对于隐式Intent,android会根据Intent中的信息(例如action,data,category)去查找目标组件。隐式Intent默认的category为android.intent.category.DEFAULT,所以,所有希望接收隐式Intent的目标组件都要有android.intent.category.DEFAULT这个属性。


二.Intent Filter

Intent Filter是用来描述组件能接收哪些Intent。如果是显式Intent,那么无需考虑Intent Filter,否则就要涉及到Intent Filter。

对于隐式Intent,仅当它能够通过组件的Intent Filter之一才能够传递给组件。

如果不声明Intent Filter,则只能通过显式调用。


android是通过action、data、category这三个属性来查找目标组件的。

例子:

<intent-filter>     <action android:name="android.intent.action.MAIN" />     <data android:mimeType="video/mpeg" android:scheme="http"/>     <category android:name="android.intent.category.LAUNCHER" /></intent-filter>

1.action检查

如果Intent指明了action,则目标组件的Intent Filter必须包含这个action,否则不能匹配。

如果Intent没有指明action,则通过检查。


2.category检查

如果Intent指明了category,则目标组件的Intent Filter必须包含这个category,否则不能匹配。

如果Intent没有指明category,则通过检查。


3.data检查

每个data元素指定数据类型(mimeType)和一个URI。URI有四个属性:scheme,host,port和path,对应于URI的格式如下:

scheme://host:port/path,其中称host:port为authority

例如一个URI为:content://com.demo.service:200/folder/1

当比较Intent和Intent Filter的URI时,以Intent Filter的URI为基础,看Intent的data的URI是否匹配。

如果Intent Filter仅指定scheme,所有有此scheme的URI都匹配;

如果Intent Filter指定scheme和authority,所有匹配scheme和authority的URI都通过检查,而不管它们的path;

如果四个属性都指定了,要全部匹配才能算是匹配。当然,Intent Filter中的path一般通过包含通配符来要求匹配path中的一部分。


mimeType属性指定数据的MIME类型。Intent和Intent Filter都可以用"*"通配符匹配子类型字段,例如“text/*”,“audio/*”表示任何子类型


MIME:

1.类型:

Text:用于标准化地表示的文本信息,文本消息可以是多种字符集和或者多种格式的;
Multipart:用于连接消息体的多个部分构成一个消息,这些部分可以是不同类型的数据;
Application:用于传输应用程序数据或者二进制数据;
Message:用于包装一个E-mail消息;
Image:用于传输静态图片数据;
Audio:用于传输音频或者音声数据;
Video:用于传输动态影像数据,可以是与音频编辑在一起的视频数据格式。


2.子类型:

text/plain(纯文本)
text/html(HTML文档)
application/xhtml+xml(XHTML文档)
image/gif(GIF图像)
image/jpeg(JPEG图像)【PHP中为:image/pjpeg】
image/png(PNG图像)【PHP中为:image/x-png】
video/mpeg(MPEG动画)
application/octet-stream(任意的二进制数据)
application/pdf(PDF文档)
application/msword(Microsoft Word文件)
application/vnd.wap.xhtml+xml (wap1.0+)
application/xhtml+xml (wap2.0+)
message/rfc822(RFC 822形式)
multipart/alternative(HTML邮件的HTML形式和纯文本形式,相同内容使用不同形式表示)
application/x-www-form-urlencoded(使用HTTP的POST方法提交的表单)
multipart/form-data(同上,但主要用于表单提交时伴随文件上传的场合)


3.文件类型——MIME类型的匹配表

//{后缀名, MIME类型}
{".3gp", "video/3gpp"},
{".apk", "application/vnd.android.package-archive"},
{".asf", "video/x-ms-asf"},
{".avi", "video/x-msvideo"},
{".bin", "application/octet-stream"},
{".bmp", "image/bmp"},
{".c", "text/plain"},
{".class", "application/octet-stream"},
{".conf", "text/plain"},
{".cpp", "text/plain"},
{".doc", "application/msword"},
{".exe", "application/octet-stream"},
{".gif", "image/gif"},
{".gtar", "application/x-gtar"},
{".gz", "application/x-gzip"},
{".h", "text/plain"},
{".htm", "text/html"},
{".html", "text/html"},
{".jar", "application/java-archive"},
{".java", "text/plain"},
{".jpeg", "image/jpeg"},
{".jpg", "image/jpeg"},
{".js", "application/x-javascript"},
{".log", "text/plain"},
{".m3u", "audio/x-mpegurl"},
{".m4a", "audio/mp4a-latm"},
{".m4b", "audio/mp4a-latm"},
{".m4p", "audio/mp4a-latm"},
{".m4u", "video/vnd.mpegurl"},
{".m4v", "video/x-m4v"}, 
{".mov", "video/quicktime"},
{".mp2", "audio/x-mpeg"},
{".mp3", "audio/x-mpeg"},
{".mp4", "video/mp4"},
{".mpc", "application/vnd.mpohun.certificate"}, 
{".mpe", "video/mpeg"}, 
{".mpeg", "video/mpeg"}, 
{".mpg", "video/mpeg"}, 
{".mpg4", "video/mp4"}, 
{".mpga", "audio/mpeg"},
{".msg", "application/vnd.ms-outlook"},
{".ogg", "audio/ogg"},
{".pdf", "application/pdf"},
{".png", "image/png"},
{".pps", "application/vnd.ms-powerpoint"},
{".ppt", "application/vnd.ms-powerpoint"},
{".prop", "text/plain"},
{".rar", "application/x-rar-compressed"},
{".rc", "text/plain"},
{".rmvb", "audio/x-pn-realaudio"},
{".rtf", "application/rtf"},
{".sh", "text/plain"},
{".tar", "application/x-tar"}, 
{".tgz", "application/x-compressed"}, 
{".txt", "text/plain"},
{".wav", "audio/x-wav"},
{".wma", "audio/x-ms-wma"},
{".wmv", "audio/x-ms-wmv"},
{".wps", "application/vnd.ms-works"},
//{".xml", "text/xml"},
{".xml", "text/plain"},
{".z", "application/x-compress"},
{".zip", "application/zip"},
{"", "*/*"} 




还要说明的是,如果一个Intent能够通过不止一个Activity或Service的Intent Filter,android系统将弹出一个Dialog要求用户选择哪个组件被激活。但是,如果没有符合的组件,将会抛出异常。


三.在Intent中传递数据

1.通过data属性

例如:

Intent intent = new Intent();intent.setAction(Intent.ACTION_VIEW);intent.setData(Uri.parse("http://www.baidu.com"));startActivity(intent);

但是data属性只能传递数据的URI地址,如果需要传递一些数据对象,就需要利用extra了。

2.通过extra属性(略)

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

一般情况下,会将Intent获取信息的代码放到onCreate方法中,但这样也会存在着一个隐患。默认情况下,当通过Intent获取一个Activity的时候,就算已经存在一个相同的正在运行的Activity,系统都会创建一个新的Activity实例并显示出来。为了不让Activity多次实例化,需要设置Activity的启动模式为单任务模式,如:

<activity    android:name=".Main2Activity"    android:launchMode="singleTask"    android:label="@string/title_activity_main2" ></activity>
这样,当Intent第一次启动activity时,activity实例化并调用onCreate();当Intent第二次启动activity时,activity不再实例化并调用onNewIntent()。因此,在单任务模式下,应该将Intent获取信息的代码放到onCreate()和onNewIntent()中。

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


四.在Intent中传递对象

要求对象要实现Parcelable接口

例子:

package com.example.testintent;import java.util.HashMap;import android.os.Parcel;import android.os.Parcelable;public class Student implements Parcelable {public String name;public HashMap<String, String> scores = new HashMap<String, String>();public Student(){name = "unknown";scores = null;}//返回id@Overridepublic int describeContents() {return 0;}//写入信息@Overridepublic void writeToParcel(Parcel dest, int flags) {dest.writeString(name);dest.writeMap(scores);}public static final Parcelable.Creator<Student> CREATOR = new Parcelable.Creator<Student>() {@Overridepublic Student createFromParcel(Parcel source) {Student student = new Student();student.name = source.readString();student.scores = source.readHashMap(HashMap.class.getClassLoader());return student;}@Overridepublic Student[] newArray(int size) {return new Student[size];}};}

package com.example.testintent;import java.util.ArrayList;import java.util.HashMap;import android.app.Activity;import android.content.Intent;import android.net.Uri;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;public class MainActivity extends Activity {@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);((Button) findViewById(R.id.next)).setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent();intent.setAction("com.example.testintent.ACTION1");Student student = new Student();HashMap<String, String> sc = new HashMap<String, String>();sc.put("english", "98");sc.put("computer", "59");student.name = "tom";student.scores = sc;ArrayList<Student> al = new ArrayList<Student>();al.add(student);intent.putParcelableArrayListExtra("a", al);Bundle bundle = new Bundle();bundle.putString("username", "android");intent.putExtra("b",bundle);startActivity(intent);}});}}

package com.example.testintent;import java.util.ArrayList;import java.util.Iterator;import java.util.Map;import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.util.Log;import android.view.Menu;import android.view.MenuItem;public class Main2Activity extends Activity {private String tag = getClass().getName();@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main2);Intent intent = getIntent();Bundle bundle = intent.getBundleExtra("b");Log.v(tag, bundle.getString("username"));ArrayList<Student> al = new ArrayList<Student>();al = intent.getParcelableArrayListExtra("a");if(al != null){Student student = (Student) al.get(0);Log.v(tag, student.name);Iterator iterator = student.scores.entrySet().iterator();while (iterator.hasNext()) {Map.Entry entry = (Map.Entry)iterator.next();String key = (String) entry.getKey();String value = (String) entry.getValue();Log.v(tag, key + "   " + value);}}}}

<activity    android:name=".Main2Activity"    android:label="@string/title_activity_main2" >    <intent-filter>        <action android:name="com.example.testintent.ACTION1" />        <category android:name="android.intent.category.DEFAULT" />    </intent-filter></activity>


五.实现Activity之间的协同

通过Intent,可以将数据传递给下一个Activity,那么,新启动的Activity如何将数据返回给之前的Activity呢?这时就需要startActivityForResult方法了。startActivityForResult方法将在回调方法onActivityResult中获取返回信息。

例子:


package com.example.testintent;import java.util.ArrayList;import java.util.HashMap;import android.app.Activity;import android.content.Intent;import android.net.Uri;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.TextView;public class MainActivity extends Activity {private int requestCode = 1;private TextView textView;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);textView = (TextView) findViewById(R.id.textView);((Button) findViewById(R.id.button)).setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent();intent.setAction("com.example.testintent.ACTION1");Bundle bundle = new Bundle();bundle.putString("content", (String)textView.getText());intent.putExtra("a", bundle);startActivityForResult(intent, requestCode);}});}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {if(requestCode == this.requestCode){if(resultCode == RESULT_OK){Bundle bundle = data.getBundleExtra("b");textView.setText(bundle.getString("newcontent"));}}}}

package com.example.testintent;import java.util.ArrayList;import java.util.Iterator;import java.util.Map;import android.app.Activity;import android.content.Intent;import android.os.Bundle;import android.util.Log;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.EditText;public class Main2Activity extends Activity {private EditText editText;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main2);editText = (EditText) findViewById(R.id.editText);Intent intent = getIntent();Bundle bundle = intent.getBundleExtra("a");editText.setText(bundle.getString("content"));((Button) findViewById(R.id.save)).setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {Intent intent = new Intent(Main2Activity.this, MainActivity.class);Bundle bundle = new Bundle();bundle.putString("newcontent", editText.getText().toString());intent.putExtra("b", bundle);setResult(RESULT_OK, intent);finish();}});        ((Button) findViewById(R.id.abort)).setOnClickListener(new OnClickListener() {@Overridepublic void onClick(View v) {setResult(RESULT_CANCELED);finish();}});}}

重点就是void onActivityResult(int requestCode, int resultCode, Intent data)了

第一个参数为请求代码,因为一个activity可能发出多个请求,可以通过请求代码进行区分;

第二个参数为结果代码,代表请求返回的结果类型;

第三个参数为返回的Intent对象,它携带了返回的数据信息。

0 0
原创粉丝点击