启动活动有一种是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-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>
ACTION_MAIN
action indicates this is the main entry point and does not expect any intent data. 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 with icon
, 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.
NotificationManager
executes the Intent
). Intent
). AlarmManager
executes the Intent
). PendingIntent.getActivity()
for an
Intent
that 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());
PendingIntent.getBroadcast()
for a
Intent
that 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
Intent
that starts a
Service
.
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:
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:
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:
content:
or file:
URI and the filter does not specify a URI. In other words,a component is presumed to support content:
and file:
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>
queryIntentActivities()
queryIntentServices()
queryBroadcastReceivers()
Intent mainIntent = new Intent(Intent.ACTION_MAIN, null); mainIntent.addCategory(Intent.CATEGORY_SAMPLE_CODE); PackageManager pm = getPackageManager(); List<ResolveInfo> list = pm.queryIntentActivities(mainIntent, 0);