Intent深入学习
启动活动有一种是startActivityForResult,这个需要掌握。
启动服务,总是使用显式意图。
intent filter表示这个组件可能要接受的意图的类型。也就说,意图有type??什么意思,如果不指定intent filter,只能显示启动了。
建立一个意图:
Component name:在显示意图,表示明确启动的类,使用setComponent,setClass,setClassName来设置,所以见过setClass设置的,
如果不加,就是隐式意图了。
Action:要执行的动作,比如ACTION_VIEW ACTION_SEND,一般可以作为被其他活动或应用启动,一般是定义在<intent-filter>中的
Data:在sunshine内容提供器的时候看到过,
Intent intent = new Intent(getApplicationContext(), DetailActivity.class) .setData(itemUir); startActivity(intent);
在DetailActivity的OnCreate中:getIntent().getData()获得保存的这个Uri,用来查询具体的信息。
@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_detail); if (savedInstanceState == null) { Bundle arguments = new Bundle(); arguments.putParcelable(DetailFragment.DETAIL_URI, getIntent().getData()); DetailFragment fragment = new DetailFragment(); fragment.setArguments(arguments); getSupportFragmentManager().beginTransaction() .add(R.id.weather_detail_container, fragment) .commit(); } }
Category:和Action一起定义在<intent-filter>中,二者组合出现。
Extras:传递额外的信息,这个也常用。
Flags:没用到还
一般定义的话,最多就是这样了:或者最简单,连<intent-filter>都没有,都比较简单,不过用起来也不简单啊。
<activity android:name=".app.IsolatedService$Controller" android:label="@string/activity_isolated_service_controller" android:launchMode="singleTop" android:enabled="@bool/atLeastJellyBean"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.SAMPLE_CODE" /> </intent-filter> </activity>
使用隐式意图注意:
为了确保有一个能响应,先测试下:
// Create the text message with a string Intent sendIntent = new Intent(); sendIntent.setAction(Intent.ACTION_SEND); sendIntent.putExtra(Intent.EXTRA_TEXT, textMessage); sendIntent.setType("text/plain"); // Verify that the intent will resolve to an activity if (sendIntent.resolveActivity(getPackageManager()) != null) { startActivity(sendIntent); }
使用createChooser,展示标题,让用户选择
Intent sendIntent = 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 the chooser dialog Intent chooser = Intent.createChooser(sendIntent, title); // Verify the original intent will resolve to at least one activity if (sendIntent.resolveActivity(getPackageManager()) != null) { startActivity(chooser); }
intent-filer
<intent-filter>元素指定了接收的intent的type,以action,data和category为基础。
下面是一个例子:
<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>
如果intent要传递给组件,必须通过三个测试。一个组件可能有多个(?怎么定义)filter,所以只要通过一个就行。
服务不需要定义<intent-filter>.
对所有的活动,必须在Manifest文件中定义所有的intent filter。对于broadcast receiver可以动态注册通过调用registerReceiver。取消注册,
调用unregisterReceiver。
如果不想让其他应用访问我们的组件,使用intent-filter不是最安全是方式,应该是设置为exported=false才行。
下面这个例子:
<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>
- The
ACTION_MAIN
action indicates this is the main entry point and does not expect any intent data. - The
CATEGORY_LAUNCHER
category indicates that this activity's icon should be placed in the system's app launcher. If the<activity>
element does not specify an icon withicon
, then the system uses the icon from the<application>
element.
Note: The MIME type,application/vnd.google.panorama360+jpg
, is a special data type that specifiespanoramic photos, which you can handle with the
Googlepanorama APIs.
使用Pending Intent
一个Pending intent是一个intent的包装。基本是目的是给外部应用授予权限使用他包含的intent就像是从我们应用自己的进程执行的一样。主要使用情况:
- Declare an intent to be executed when the user performs an action with your
Notification (the Android system's
NotificationManager
executes theIntent
). - Declare an intent to be executed when the user performs an action with your
App Widget (the Home screen app executes the
Intent
). - Declare an intent to be executed at a specified time in the future (the Android system's
AlarmManager
executes theIntent
).
PendingIntent.getActivity()for an
Intentthat starts an
Activity.
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(getContext()) .setSmallIcon(iconId) .setContentText(contentText) .setContentTitle(title); Intent resultIntent = new Intent(context, MainActivity.class); TaskStackBuilder stackBuilder = TaskStackBuilder.create(getContext()); stackBuilder.addParentStack(MainActivity.class); stackBuilder.addNextIntent(resultIntent); PendingIntent resultPendingIntent = stackBuilder.getPendingIntent( 0, PendingIntent.FLAG_UPDATE_CURRENT ); mBuilder.setContentIntent(resultPendingIntent); NotificationManager notificationManager = (NotificationManager) getContext().getSystemService(Context.NOTIFICATION_SERVICE); notificationManager.notify(WEATHER_NOTIFICATION_ID, mBuilder.build());
第二个是使用app widget执行动作?这个还没见过? 第三是指定一个在将来时间执行的intent,系统的AlarmManager执行这个intent sunshine用过的一个广播:
PendingIntent.getBroadcast()for a
Intentthat starts an
BroadcastReceiver.
Intent alarmIntent = new Intent(getActivity(), SunShineService.AlarmReceiver.class); alarmIntent.putExtra(SunShineService.LOCATION_QUERY_EXTRA, location); PendingIntent pi = PendingIntent.getBroadcast(getActivity(), 0, alarmIntent, PendingIntent.FLAG_ONE_SHOT); AlarmManager am = (AlarmManager)getActivity().getSystemService(Context.ALARM_SERVICE); am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + 5000, pi);同理启动服务:
PendingIntent.getService()for an
Intentthat starts a
Service.
Intent 解析
Action Test 可以定义0或多个action 如果一个<intent-filter>不包含任何action,那么所有的intent都匹配失败;但是一个intent如果没有指定action,那么他会通过测试(只要 这个intent-filter包含至少一个action)Category Test
可以定义0或多个action
intent只要通过一个Category就过了,如果intent不指定Category,总是通过测试,无论定义的什么Category。
官方说是有一个默认的Category:
"android.intent.category.DEFAULT",我们必须指定,
也就说,如果要隐式启动还是要指定的?但是感觉没指定也可以啊,可能是显式的问题?官方不会说错的。
注意了,默认给一个"android.intent.category.DEFAULT"。
Data test
暂时没遇到,有时间在看
To specify accepted intent data, an intent filter can declare zero or more
<data>elements. For example:
<intent-filter> <data android:mimeType="video/mpeg" android:scheme="http" ... /> <data android:mimeType="audio/mpeg" android:scheme="http" ... /> ... </intent-filter>
Each
<data>element can specify a URI structure and a data type (MIME media type). There are separateattributes —
scheme,
host,
port,and
path— for each part of the URI:
<scheme>://<host>:<port>/<path>
For example:
content://com.example.project:200/folder/subfolder/etc
In this URI, the scheme is
content, the host is
com.example.project,the port is
200, and the path is
folder/subfolder/etc.
Each of these attributes is optional in a
<data>element,but there are linear dependencies:
- 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.
When the URI in an intent is compared to a URI specification in a filter,it's compared only to the parts of the URI included in the filter. For example:
- If a filter specifies only a scheme, all URIs with that scheme matchthe filter.
- If a filter specifies a scheme and an authority but no path, all URIswith the same scheme and authority pass the filter, regardless of their paths.
- If a filter specifies a scheme, an authority, and a path, only URIs with the same scheme,authority, and path pass the filter.
Note: A path specification cancontain a wildcard asterisk (*) to require only a partial match of the path name.
The data test compares both the URI and the MIME type in the intent to a URIand MIME type specified in the filter. The rules are as follows:
- An intent that contains neither a URI nor a MIME type passes thetest only if the filter does not specify any URIs or MIME types.
- An intent that contains a URI but no MIME type (neither explicit nor inferable from theURI) passes the test only if its URI matches the filter's URI formatand the filter likewise does not specify a MIME type.
- An intent that contains a MIME type but not a URI passes the testonly if the filter lists the same MIME type and does not specify a URI format.
- An intent that contains both a URI and a MIME type (either explicit or inferable from theURI) passes the MIME type part of the test only if thattype matches a type listed in the filter. It passes the URI part of the testeither if its URI matches a URI in
the filter or if it has a
content:
orfile:
URI and the filter does not specify a URI. In other words,a component is presumed to supportcontent:
andfile:
data ifits filter lists only a MIME type.
This last rule, rule (d), reflects the expectationthat components are able to get local data from a file or content provider.Therefore, their filters can list just a data type and do not need to explicitlyname the
content:and
file:schemes.This is a typical case. A
<data>elementlike the following, for example, tells Android that the component can get image data from a contentprovider and display it:
<intent-filter> <data android:mimeType="image/*" /> ... </intent-filter>
Because most available data is dispensed by content providers, filters thatspecify a data type but not a URI are perhaps the most common.
Another common configuration is filters with a scheme and a data type. Forexample, a
<data>element like the following tells Android thatthe component can retrieve video data from the network in order to perform the action:
<intent-filter> <data android:scheme="http" android:type="video/*" /> ... </intent-filter>
Intent matching
Intent匹配intent filter不仅仅发现激活的目标组件,也可以找到设备上一系列复合intent条件的组件。PackageManager有一写query..()方法查询 返回所有接收一个特定intent的的组件,一些resolve...()方法,决定响应intent最好的组件。 对于活动queryIntentActivities()对于服务
queryIntentServices()对于广播
queryBroadcastReceivers()APIdemo使用了活动的,对这些查出来复合条件的挨个分类,这样一个类就可以显示,这设计很棒。
Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); mainIntent.addCategory(Intent.CATEGORY_SAMPLE_CODE); PackageManager pm = getPackageManager(); List<ResolveInfo> list = pm.queryIntentActivities(mainIntent, 0);
- Android Service学习之IntentService 深入分析
- Android Service学习之IntentService 深入分析
- Android Service学习之IntentService 深入分析
- 深入学习Intent和任务
- 从零开始--系统深入学习android(实践-让我们开始写代码-Android框架学习-4.Intents和Intent Filters)
- Android Service学习之IntentService 深入分析
- Android Service学习之IntentService 深入分析
- 第 23 章 深入学习 intent 和任务 (选讲)
- Android Service学习之IntentService 深入分析
- Android Service学习之IntentService 深入分析
- Android Service学习之IntentService 深入分析
- Android Service学习之IntentService 深入分析
- Android Service学习之IntentService 深入分析
- Android Service学习之IntentService 深入分析
- 深入学习Android中的Intent
- Android Service学习之IntentService 深入分析
- Android Service学习之IntentService 深入分析
- Android Service学习之IntentService 深入分析
- Android Service学习之IntentService 深入分析
- Android Service学习之IntentService 深入分析