前言:通过重新翻看android入门书籍,才发现原来自己露掉了那么多基础知道。原以为有了C的基础,快速开发应该是没有问题的了,但没有遇到问题的时候还是海搜,只知道这么写能完成这个功能,但为什么要这么写还是不太清楚,看来还是要好好把基础打一打,把android基础看完以后,再看看JAVA的基础知识。关于这个问题,写两篇,这篇基础知识讲解,下一篇代码实战。
相关文章:
《intent详解(二)》
Intent被译作意图,其实还是很能传神的,Intent期望做到的,就是把实现者和调用者完全解耦,调用者专心将以意图描述清晰,发送出去,就可以梦想成真,达到目的。
这个解释还是有点不太好理解,下面还有一个:Intent是一种运行时绑定(run-time binding)机制,它能在程序运行过程中连接两个不同的组件。通过Intent,你的程序可以向Android表达某种请求或者意愿,Android会根据意愿的内容选择适当的组件来完成请求。比如,有一个Activity希望打开网页浏览器查看某一网页的内容,那么这个Activity只需要发出WEB_SEARCH_ACTION给Android,Android就会根据Intent的请求内容,查询各组件注册时声明的IntentFilter,找到网页浏览器的Activity来浏览网页。 这个解释好像理解起来就容易好多,我们通过intent传入某种意图,而android就会根据这种意图,自动寻找合适的activity来启动,如果有多个条件符合的activity,就以列表的方式让用户手动选择一个。
这两个概念刚开始不太好理解,先看两个通过intent启动activity的代码:
例一:
Intent intent = new Intent(); intent.setClass(Context packageContext, OtherActivity.class); startActivity(intent);例二:
Intent intent = new Intent(); intent.setAction(Intent.ACTION_NEW); startActivity(intent);从这两段代码中可以明显看出,同样是startActivity,但第一个明确指出是启动OtherActivity,而在第二个例子中,并没有明确指出要启动哪个activity!
这两种书写方式就分别是显示Intent(例一)、隐式Intent(例二);
有两种方式来显示的指示要启动的Activity:
方式一:(通过setClassName)
Intent intent = new Intent(); //表示希望启动com.example.test_permission包中的com.example.test_permission.MainActivity intent.setClassName("com.example.test_permission", "com.example.test_permission.MainActivity"); startActivity(intent);
Intent intent = new Intent(); intent.setClass(Context packageContext, OtherActivity.class); startActivity(intent);同样,setClass(Context packageContext, OtherActivity.class);是指启动packageContext包里的OtherActivity.class类;
上面我们讲了隐式intent是要靠系统自动去匹配并启动某个activity的。那系统是怎样匹配activity的呢,系统是怎样知道这个actitiy就是某个intent想要的呢。
某个activity能不能被某个intent激活,要看这个activity是不是符合这个intent的要求,而某个activity能被哪个intent激活是有定义的,定义就在AndroidManifest.xml
打开AndroidManifest.xml,找到任意一个activity,一般都能看到一段代码,举个例子,我随便复制一个,如下:
<activity android:name=".MainActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity>看这里有一对标签<intent-filter>……</intent-filter>
在<intent-filter>里有以下几个属性可以让intent来匹配:Action、Category、Data;下面逐一介绍:
该标识用来说明这个activity可以执行哪些动作,所以当隐式intent传递过来action时,如果跟这里<intent-filter>所列出的任意一个匹配的话,就说明这个activity是可以完成这个intent的意图的,可以将它激活!!!!
常用的Action如下所示:
ACTION_CALL activity 启动一个电话. ACTION_EDIT activity 显示用户编辑的数据. ACTION_MAIN activity 作为Task中第一个Activity启动 ACTION_SYNC activity 同步手机与数据服务器上的数据. ACTION_BATTERY_LOW broadcast receiver 电池电量过低警告. ACTION_HEADSET_PLUG broadcast receiver 插拔耳机警告 ACTION_SCREEN_ON broadcast receiver 屏幕变亮警告. ACTION_TIMEZONE_CHANGED broadcast receiver 改变时区警告.两条原则:
如果Intent请求或<intent-filter>中没有说明具体的Action类型,那么会出现下面两种情况。
即这个activity在哪个环境中才能被激活。不属于这个环境的,不能被激活。
常用的Category属性如下所示:
CATEGORY_DEFAULT:Android系统中默认的执行方式,按照普通Activity的执行方式执行。表示所有intent都可以激活它 CATEGORY_HOME:设置该组件为Home Activity。 CATEGORY_PREFERENCE:设置该组件为Preference。 CATEGORY_LAUNCHER:设置该组件为在当前应用程序启动器中优先级最高的Activity,通常为入口ACTION_MAIN配合使用。 CATEGORY_BROWSABLE:设置该组件可以使用浏览器启动。表示该activity只能用来浏览网页。 CATEGORY_GADGET:设置该组件可以内嵌到另外的Activity中。注意:
如果该activity想要通过隐式intent方式激活,那么不能没有任何category设置,至少包含一个android.intent.category.DEFAULT
在目标<data/>标签中包含了以下几种子元素,他们定义了url的匹配规则:
在XML中声明可以操作的data域应该是这样的:
<activity android:name=".TargetActivity"> <intent-filter> <action android:name="com.scott.intent.action.TARGET"/> <category android:name="android.intent.category.DEFAULT"/> <data android:scheme="scott" android:host="com.scott.intent.data" android:port="7788" android:path="/target"/> </intent-filter> </activity>注意:
这个标识比较特殊,它定义了执行此Activity时所需要的数据,也就是说,这些数据是必须的!!!!!所有如果其它条件都足以激活该Activity,但intent却没有传进来指定类型的Data时,就不能激活该activity!!!!
上面我们讲了一个Activity能被某隐式Intent唤醒的原则,只有这些全部匹配的intent才能唤醒这个Activity,下面我们就讲讲怎么向隐式intent传递这些参数,以便与activity匹配将向唤醒。
使用Intent的一个构造方法即可实现传递Action参数:
public Intent(String action) { mAction = action; }对于有如下声明的Activity:
<activity android:name=".TargetActivity"> <intent-filter> <action android:name="com.scott.intent.action.TARGET"/> <category android:name="android.intent.category.DEFAULT"/> </intent-filter> </activity>要激活这个Activity,就需要如下这样构造Intent:(直接向intent中传递action的name值)
public void gotoTargetActivity(View view) { Intent intent = new Intent("com.scott.intent.action.TARGET"); startActivity(intent); }这样就可以启动我们上面的这个activity了。
注意这里再次提醒,一个activity可以有多个action,只要有一个匹配就可以被启动。同样,如果仅指定某个action,而多个activity都具有这个action的话,系统会列出列表供用户选择执行哪一个activity.
有两种传递data的方式:
第一种:利用构造函数:
public Intent(String action, Uri uri) { mAction = action; mData = uri; }第二种:利用Intent::SetData(URI uri)
Intent intent = new Intent("com.scott.intent.action.name"); intent.setData(Uri.parse("scheme://host:port/parth")); startActivity(intent);举个例子: (改动下上面的action的例子)
<activity android:name=".TargetActivity"> <intent-filter> <action android:name="com.scott.intent.action.TARGET"/> <category android:name="android.intent.category.DEFAULT"/> <data android:scheme="scott" android:host="com.scott.intent.data" android:port="7788" android:path="/target"/> </intent-filter> </activity>这个时候如果要启动这个TargetActivity只指定action就不够了,我们需要为其设置data值,如下:
Intent intent = new Intent("com.scott.intent.action.TARGET"); intent.setData(Uri.parse("scott://com.scott.intent.data:7788/target")); startActivity(intent);此时,url中的每个部分和TargetActivity配置信息中全部一致才能跳转成功,否则就被系统拒绝。
注意:
不过有时候对path限定死了也不太好,比如我们有这样的url:(scott://com.scott.intent.data:7788/target/hello)(scott://com.scott.intent.data:7788/target/hi)
这个时候该怎么办呢?我们需要使用另外一个元素:android:pathPrefix,表示路径前缀。可通过putXX()和getXX()方法存取信息;也可以通过创建Bundle对象,再通过putExtras()和getExtras()方法来存取。
通过bundle对象传递
发送方
Intent intent = new Intent("com.scott.intent.action.TARGET"); Bundle bundle = new Bundle(); bundle.putInt("id", 0); bundle.putString("name", "scott"); intent.putExtras(bundle); startActivity(intent);接收方:
Bundle bundle = intent.getExtras(); int id = bundle.getInt("id"); String name = bundle.getString("name");
更多参数传递方法见《通过Intent传递类对象》
// 调用浏览器 Uri webViewUri = Uri.parse("http://blog.csdn.net/zuolongsnail"); Intent intent = new Intent(Intent.ACTION_VIEW, webViewUri); // 调用地图 Uri mapUri = Uri.parse("geo:100,100"); Intent intent = new Intent(Intent.ACTION_VIEW, mapUri); // 播放mp3 Uri playUri = Uri.parse("file:///sdcard/test.mp3"); Intent intent = new Intent(Intent.ACTION_VIEW, playUri); intent.setDataAndType(playUri, "audio/mp3"); // 调用拨打电话 Uri dialUri = Uri.parse("tel:10086"); Intent intent = new Intent(Intent.ACTION_DIAL, dialUri); // 直接拨打电话,需要加上权限<uses-permission id="android.permission.CALL_PHONE" /> Uri callUri = Uri.parse("tel:10086"); Intent intent = new Intent(Intent.ACTION_CALL, callUri); // 调用发邮件(这里要事先配置好的系统Email,否则是调不出发邮件界面的) Uri emailUri = Uri.parse("mailto:[email protected]"); Intent intent = new Intent(Intent.ACTION_SENDTO, emailUri); // 直接发邮件 Intent intent = new Intent(Intent.ACTION_SEND); String[] tos = { "[email protected]" }; String[] ccs = { "[email protected]" }; intent.putExtra(Intent.EXTRA_EMAIL, tos); intent.putExtra(Intent.EXTRA_CC, ccs); intent.putExtra(Intent.EXTRA_TEXT, "the email text"); intent.putExtra(Intent.EXTRA_SUBJECT, "subject"); intent.setType("text/plain"); Intent.createChooser(intent, "Choose Email Client"); // 发短信 Intent intent = new Intent(Intent.ACTION_VIEW); intent.putExtra("sms_body", "the sms text"); intent.setType("vnd.android-dir/mms-sms"); // 直接发短信 Uri smsToUri = Uri.parse("smsto:10086"); Intent intent = new Intent(Intent.ACTION_SENDTO, smsToUri); intent.putExtra("sms_body", "the sms text"); // 发彩信 Uri mmsUri = Uri.parse("content://media/external/images/media/23"); Intent intent = new Intent(Intent.ACTION_SEND); intent.putExtra("sms_body", "the sms text"); intent.putExtra(Intent.EXTRA_STREAM, mmsUri); intent.setType("image/png"); // 卸载应用 Uri uninstallUri = Uri.fromParts("package", "com.app.test", null); Intent intent = new Intent(Intent.ACTION_DELETE, uninstallUri); // 安装应用 Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(new File("/sdcard/test.apk"), "application/vnd.android.package-archive"); // 在Android Market中查找应用 Uri uri = Uri.parse("market://search?q=愤怒的小鸟"); Intent intent = new Intent(Intent.ACTION_VIEW, uri);
至此本文就结束了。
下一篇用简单的几个实例,来具体讲解隐式intent的匹配与调用原理。
参考文章 :
《Android中Intent组件详解》
《android Intent机制详解》
《基础总结篇之九:Intent应用详解》
《Intent详解》
《Intent总结》
《Intent中的四个重要属性——Action、Data、Category、Extras》
请大家尊重原创者版权,转载请标明出处:http://blog.csdn.net/harvic880925/article/details/38399723 不胜感激!!!!!!