Intents and Intent Filters
2015-03-06 15:33
295 查看
Android API Guides
1. Intents 和Intent Filters
to start an ActivitystartActivity or startActivityForResults
to start a service
startService or bindService
to deliever a broadcast
sendBroadcast, sendOrderedBroadcast or sendStickyBroadcast
1.1 Intent Types
Explicit intents指定请求组件的全限定名,就包名+类名。
Implicit intents
申明通用的动作去执行,允许其他App处理该动作。
1.2 Building Intent
Component name是决定该Intent是否为Explicit Intent,可通过
set Component(), setClass(), setClassName(), 或者是作为Intent()的构造器的参数。若没指定该参数,则系统使用一下item进行匹配。其中Service必须指定Component Name。
Action
是一个String字符串,指定通用动作去执行,如View or Pick。该字段通常能够决定Intent的其他字段如何构造,尤其是在data域和extras域。可自定义Action,但更推荐使用系统提供的。以下为常用的Action, ACTION_VIEW(使用地图显示地址或使用相册显示图片),ACTION_SEND(使用其他App共享数据,诸如电子邮件或者社交网络共享).
可以通过setAction(),或者Intent的构造器进行指定。定义自己的ACTION,请加上包名,如下
static final String ACTION_TIMETR***EL = "com.example.action.TIMETR***EL";
Data
使用URI指定MIME类型的数据,通常需要指定数据类型。但是使用
content: URI的URI数据,可不指定类型,因为系统可识别出该数据位于设备上,并且受到ContentProvider控制,因此MIME类型就变为可见。
指定方式为
setData(), setType() or setDataAndType(),其中setData和setType不可同时使用,若需要,请使用setDataAndType()。
Category
一个String,包含可处理该Intent的组件种类。每个Intent可包含任意数量的Category,但大部分的Intent都不需要,通常设置为
android.intent.category.DEFAULT。常见的Category:
CATEGORY_BROWSABLE和
CATEGORY_LAUNCHER。前者表示该数据可为浏览器打开,后者表示该Activity是一个任务的初始Activity,并且将会被显示在Launcher里。可用’addCategory()’来指定该项。
Tip 以上介绍的component name, action, data, 和category限定了一个intent的特性,Android系统可知道如何决定一个组件来处理或启动。
Extras
携带键值对信息,KV来完成特定的Action。可通过putExtras(K, V),或者创建一个Bundle携带所有的KVP,然后putExtras到Intent。指定自己的Extras Key,务必加上包名,如
static final String EXTRA_GIGAWATTS = "com.example.EXTRA_GIGAWATTS";
FLAG
定义Intent的元素据metadata,可指导Android系统如何启动一个Activity(task所属),或者启动后如何对待(是否属于其他已经启动的Activity)
1.2 Examples
Explicit Intent[code]// Executed in an Activity, so 'this' is the Context // The fileUrl is a string URL, such as "http://www.example.com/image.png" Intent downloadIntent = new Intent(this, DownloadService.class); downloadIntent.setData(Uri.parse(fileUrl)); startService(downloadIntent);
Implicit Intent
模糊的Intent,可能会没有App响应,导致App Crash。因此可通过resolveActitvity()来验证是否有Activity响应,然后再决定是否启动Activity。
[code]// Create the text message with a string Intent sendIntent = new Intent(); sendIntent.setAction(Intent.ACTION_SEND); sendIntent.putExtra(Intent.EXTRA_TEXT, textMessage); sendIntent.setType(HTTP.PLAIN_TEXT_TYPE); // "text/plain" MIME type // Verify that the intent will resolve to an activity if (sendIntent.resolveActivity(getPackageManager()) != null) { startActivity(sendIntent); }
若有多个App响应,则显示列表对话框以供用户选择,如果只有一个App响应,则直接启动。
- 强制出现App选择器
如分享文件或者数据到各种App,ACTION_SEND。可使用Intent的creatChooser来操作,如下:
[code]Intent intent = new Intent(Intent.ACTION_SEND); ... // Always use string resources for UI text. // This says something like "Share this photo with" String title = getResources().getString(R.string.chooser_title); // Create intent to show chooser Intent chooser = Intent.createChooser(intent, title); // Verify the intent will resolve to at least one activity if (sendIntent.resolveActivity(getPackageManager()) != null) { startActivity(sendIntent); }
1.3 Receiving an Implicit Intent
在Manifest文件中申明< intent-filters >标签,通过action, data, and category等字段制定Intent可接受的类型。一个Explicit Intent无视组件所申明的接受Intent类型,直接传递过去。
不同job应申明不同的< intent-filters >,可包括action, data, and category3个字段。
-action, 指定可接受的intetn action。
-data,可接受的数据类型,URI (scheme, host, port, path, etc.) and MIME type。
-category,必须是一个Action的string值。
Tip: 为了收到Implicit Intents,必须设定
CATEGORY_DEFAULT。这样, startActivity() and startActivityForResult() 才可调用,否则没有任何Implicit可启动该Activity。
举例:
[code]<activity android:name="ShareActivity"> <intent-filter> <action android:name="android.intent.action.SEND"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="text/plain"/> </intent-filter> </activity>
只有三个item都通过验证,Android才会传递Intent给该Activity。对于Broadcast Receiver,可通过
registerReceiver()or
unregisterReceiver()动态绑定。
- Example Filters
[code]<activity android:name="MainActivity"> <!-- This activity is the main entry, should appear in app launcher --> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <activity android:name="ShareActivity"> <!-- This activity handles "SEND" actions with text data --> <intent-filter> <action android:name="android.intent.action.SEND"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="text/plain"/> </intent-filter> <!-- This activity also handles "SEND" and "SEND_MULTIPLE" with media data --> <intent-filter> <action android:name="android.intent.action.SEND"/> <action android:name="android.intent.action.SEND_MULTIPLE"/> <category android:name="android.intent.category.DEFAULT"/> <data android:mimeType="application/vnd.google.panorama360+jpg"/> <data android:mimeType="image/*"/> <data android:mimeType="video/*"/> </intent-filter> </activity>
1.4 Using a Pending Intent
它是对Intent的包装器,主要用途是给予其他App权限获取本进程的数据。主要用途如下:Notification Manager
AppWidget
AlarmManager
由于每个Intent都是为特定的组件设计的,因此PendingIntent也同样。
PendingIntent.getActivity(),启动Activtiy
PendingIntent.getService(),启动Service
PendingIntent.getBroadcast(), 启动BroadcastReceiver()。
1.5 Intent Resolution
Android 系统匹配最优的组件的算法,基于以下三方面的匹配测试:The intent action
The intent data (both URI and data type)
The intent category
其中data的URI 结构和MIME 类型。
URI:
<scheme>://<host>:<port>/<path>
ex:
content://com.example.project:200/folder/subfolder/etc
这4个元素是线性依赖的:
If a scheme is not specified, the host is ignored.
If a host is not specified, the port is ignored.
If both the scheme and host are not specified, the path is ignored.
PackageManager 可以调用以下几个方法列出可接受该Intent的组件
queryIntentActivities(), 返回所有相似的Activity
queryIntentServices(),返回相似的所有Service
queryIntentBroadcastReceivers(), 返回所有
1.6 Common Intents
1 AlarmClock
Action: ACTION_SET_ALARMExtras:….
ex:
[code]public void createAlarm(String message, int hour, int minutes) { Intent intent = new Intent(AlarmClock.ACTION_SET_ALARM) .putExtra(AlarmClock.EXTRA_MESSAGE, message) .putExtra(AlarmClock.EXTRA_HOUR, hour) .putExtra(AlarmClock.EXTRA_MINUTES, minutes); if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } }
并其需要使用权限:
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
相应的Intent-Filter
[code]<activity ...> <intent-filter> <action android:name="android.intent.action.SET_ALARM" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
2 Timer
Action:ACTION_SET_TIMERExtras:。。。
e.g.
[code]public void startTimer(String message, int seconds) { Intent intent = new Intent(AlarmClock.ACTION_SET_TIMER) .putExtra(AlarmClock.EXTRA_MESSAGE, message) .putExtra(AlarmClock.EXTRA_LENGTH, seconds) .putExtra(AlarmClock.EXTRA_SKIP_UI, true); if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } }
Permission:
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />
Intent-Filter:
[code]<activity ...> <intent-filter> <action android:name="android.intent.action.SET_TIMER" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
3 显示所有Alarms
Action:ACTION_SHOW_ALARMS4 添加Calendar Event
Action:ACTION_INSERTData URI:Events.CONTENT_URI
MIME Type: “vnd.android.cursor.dir/event”
Extras: 。。。
4 拍摄照片或摄制录像
Action:ACTION_IMAGE_CAPTURE or ACTION_VIDEO_CAPTUREExtras:EXTRA_OUTPUT
使用
onActivityResult()接收返回数据:
[code]static final int REQUEST_IMAGE_CAPTURE = 1; static final Uri mLocationForPhotos; public void capturePhoto(String targetFilename) { Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.withAppendedPath(mLocationForPhotos, targetFilename); if (intent.resolveActivity(getPackageManager()) != null) { startActivityForResult(intent, REQUEST_IMAGE_CAPTURE); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) { Bitmap thumbnail = data.getParcelable("data"); // Do other work with full size photo saved in mLocationForPhotos ... } }
相应的Intent-Filter
[code]<activity ...> <intent-filter> <action android:name="android.media.action.IMAGE_CAPTURE" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
5 Start a camera app in still image mode
Action: INTENT_ACTION_STILL_IMAGE_CAMERA6 Start a camera app in video mode
Action: INTENT_ACTION_VIDEO_CAMERA7 选择一个联系人
Action:ACTION_PICKMIME Type:Contacts.CONTENT_TYPE
e.g.:
[code]static final int REQUEST_SELECT_CONTACT = 1; public void selectContact() { Intent intent = new Intent(Intent.ACTION_PICK); intent.setType(ContactsContract.Contacts.CONTENT_TYPE); if (intent.resolveActivity(getPackageManager()) != null) { startActivityForResult(intent, REQUEST_SELECT_CONTACT); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_SELECT_CONTACT && resultCode == RESULT_OK) { Uri contactUri = data.getData(); // Do something with the selected contact at contactUri ... } }
8 选择特定的联系人
Action: ACTION_PICKMIME Type:
CommonDataKinds.Phone.CONTENT_TYPE。Pick from contacts with a phone number.
CommonDataKinds.Email.CONTENT_TYPE,Pick from contacts with an email address.
CommonDataKinds.StructuredPostal.CONTENT_TYPE,Pick from contacts with a postal address.
[code]static final int REQUEST_SELECT_PHONE_NUMBER = 1; public void selectContact() { // Start an activity for the user to pick a phone number from contacts Intent intent = new Intent(Intent.ACTION_PICK); intent.setType(CommonDataKinds.Phone.CONTENT_TYPE); if (intent.resolveActivity(getPackageManager()) != null) { startActivityForResult(intent, REQUEST_SELECT_PHONE_NUMBER); } } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_SELECT_PHONE_NUMBER && resultCode == RESULT_OK) { // Get the URI and query the content provider for the phone number Uri contactUri = data.getData(); String[] projection = new String[]{CommonDataKinds.Phone.NUMBER}; Cursor cursor = getContentResolver().query(contactUri, projection, null, null, null); // If the cursor returned is valid, get the phone number if (cursor != null && cursor.moveToFirst()) { int numberIndex = cursor.getColumnIndex(CommonDataKinds.Phone.NUMBER); String number = cursor.getString(numberIndex); // Do something with the phone number ... } } }
9 显示一个联系人
ACTION_PICK返回的contactURI,然后使用ACTION_VIEW查看。直接访问联系人列表,需要READ_CONTACTS权限
[code]public void viewContact(Uri contactUri) { Intent intent = new Intent(Intent.ACTION_VIEW, contactUri); if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } }
10 编辑一个联系人
Action:ACTION_EDITURI: 之前ACTION_PICK返回的contactURI。
Extras:ContactsContract.Intents.Insert中定义的条目都可编辑
[code]public void editContact(Uri contactUri, String email) { Intent intent = new Intent(Intent.ACTION_EDIT); intent.setData(contactUri); intent.putExtra(Intents.Insert.EMAIL, email); if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } }
11 插入一个联系人
Action:ACTION_INSERTMIME Type:Contacts.CONTENT_TYPE
Extras:One or more of the extras defined in ContactsContract.Intents.Insert.
e.g.:
[code]public void insertContact(String name, String email) { Intent intent = new Intent(Intent.ACTION_INSERT); intent.setType(Contacts.CONTENT_TYPE); intent.putExtra(Intents.Insert.NAME, name); intent.putExtra(Intents.Insert.EMAIL, email); if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } }
12 Email
13 File Storage
14 Fitness
15 Local Actions
16 Maps, show a location on a map
Action: ACTION_VIEWURI: geo:latitude,longtitude
e.g.:
[code]public void showMap(Uri geoLocation) { Intent intent = new Intent(Intent.ACTION_VIEW); intent.setData(geoLocation); if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } }
intent filter:
[code]<activity ...> <intent-filter> <action android:name="android.intent.action.VIEW" /> <data android:scheme="geo" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
17 MUSIC or VIDEO
Action: ACTION_VIEWData URI Scheme:
file:
content:
http:
MIME Type:
“audio/*”
“application/ogg”
“application/x-ogg”
“application/itunes” Or any other that your app may require.
example intent filter:
[code]<activity ...> <intent-filter> <action android:name="android.intent.action.VIEW" /> <data android:type="audio/*" /> <data android:type="application/ogg" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
18 Phone
Action: ACTION_DIAL , ACTION_CALL其中ACTION_DIAL,需要传输一个号码,然后跳转到拨打界面,需要点击拨打按钮。
而ACTION_CALL,需要传输一个号码,然后直接开始拨打,但是需要权限
<uses-permission android:name="android.permission.CALL_PHONE" />
Data URI Scheme:’tel:< phone-number>,voicemail:< phone-number>’
e.g.:
[code]public void dialPhoneNumber(String phoneNumber) { Intent intent = new Intent(Intent.ACTION_DIAL); intent.setData(Uri.parse("tel:" + phoneNumber)); if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } }
19 Settings
Action:ACTION_SETTINGS ACTION_WIRELESS_SETTINGS
ACTION_AIRPLANE_MODE_SETTINGS ACTION_WIFI_SETTINGS
ACTION_APN_SETTINGS ACTION_BLUETOOTH_SETTINGS ACTION_DATE_SETTINGS
ACTION_LOCALE_SETTINGS ACTION_INPUT_METHOD_SETTINGS
ACTION_DISPLAY_SETTINGS ACTION_SECURITY_SETTINGS
ACTION_LOCATION_SOURCE_SETTINGS ACTION_INTERNAL_STORAGE_SETTINGS
ACTION_MEMORY_CARD_SETTINGS
20 Text Messaging
Action: ACTION_SENDTO, ACTION_SEND, ACTION_SEND_MULTIPLEData URI Scheme:
[code]sms:<phone_number> smsto:<phone_number> mms:<phone_number> mmsto:<phone_number>
MIME Type:
PLAIN_TEXT_TYPE (“text/plain”)
“image/*”
“video/*”
Extras:
“subject”,’sms_body’,’EXTRA_STREAM’
e.g.:
[code]public void composeMmsMessage(String message, Uri attachment) { Intent intent = new Intent(Intent.ACTION_SENDTO); intent.setType(HTTP.PLAIN_TEXT_TYPE); intent.putExtra("sms_body", message); intent.putExtra(Intent.EXTRA_STREAM, attachment); if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } }
若想要确保intent被短信应用处理,使用 ACTION_SENDTO,并且设置data schmem为‘smsto:’.
相应的Intent-filter
[code]<activity ...> <intent-filter> <action android:name="android.intent.action.SEND" /> <data android:type="text/plain" /> <data android:type="image/*" /> <category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
21. WebBrowser
加载网址- Action: ACTION_VIEW
- Data URI Scheme:
http:< URL>
https:< URL>
- MIME Type:
PLAIN_TEXT_TYPE (“text/plain”)
“text/html”
“application/xhtml+xml”
“application/vnd.wap.xhtml+xml”
Web查询
Action: ACTION_WEB_SEARCH
Extras:SearchManager.QUERY The search string.
[code]public void searchWeb(String query) { Intent intent = new Intent(Intent.ACTION_SEARCH); intent.putExtra(SearchManager.QUERY, query); if (intent.resolveActivity(getPackageManager()) != null) { startActivity(intent); } }
22 Verify Intents with the Android Debug Bridge
Set up an Android device for development, or use a virtual device.Install a version of your app that handles the intents you want to support.
Fire an intent using adb:
adb shell am start -a <ACTION> -t <MIME_TYPE> -d <DATA> \ -e <EXTRA_NAME> <EXTRA_VALUE> -n <ACTIVITY>
For example:
adb shell am start -a android.intent.action.DIAL \ -d tel:555-5555 -n org.example.MyApp/.MyActivity
If you defined the required intent filters, your app should handle the intent.
相关文章推荐
- Intents and Intent Filters
- Android API Guides 之 App Components(2) - Intents and Intent Filters - Common Intents
- Develop系列-API Guides-应用组件-Intents and Intent Filters
- Intents and Intent Filters
- Android系列教程之十:Intents and Intent Filters(一)
- Android 中的Intents and Intent Filters
- Intents and Intent Filters
- Android API Guides学习1——Intents and Intent Filters
- Android系列教程之十一:Intents and Intent Filters(二)
- 意图和意图过滤器Intents and Intent Filters
- Intents and Intent Filters(一)
- android-Intents and Intent Filters and Common Intents
- Android Intents and Intent Filters
- Intents and Intent Filters
- Intents and Intent Filters概述
- Android系列教程之十二:Intents and Intent Filters(三)
- Intents and Intent Filters用法
- 意图和意图过滤器Intents and Intent Filters
- Intents and Intent Filters
- Intents and Intent Filters详解