关于Intent

public class Intent implements Parcelable, Cloneable{
}
public class IntentFilter implements Parcelable{
}

<intent-filter>
     <action android:name= "com.cmri.rcs.action.Show_contacts" />
     <category android:name= "android. intent.category.DEFAULT" />
</intent-filter>

Intent intent =  new Intent ( this , LoginActivity.  class);
intent.setAction(URLHandler. ACTION_LOGIN_OUT);
intent.setFlags(Intent . FLAG_ACTIVITY_NEW_TASK |Intent . FLAG_ACTIVITY_CLEAR_TASK );
this.startActivity(intent);

Intent intent =  new Intent (MediaStore. ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore. EXTRA_OUTPUT, cameraFileUri);
startActivityForResult( intent, CORP_FROM_CAMERA);

Intent intent =  new Intent (CircleMainActivity. this, CirclePersonalActivity. class);
intent.putExtra("uid", item. uid);
CircleMainActivity.  this.startActivity(intent);

IntentFilter notifyFilter =  new IntentFilter();
notifyFilter.addAction(Constants.  UPDATE_CIRCLE_ACTION);
this.registerReceiver(mUpdateReceiver , notifyFilter);

IntentFilter intentFilter =  new IntentFilter ();
intentFilter .addAction(MtcCliCallback. MTC_CLI_REG_ERR_DEACTED);
registerReceiver( broadcastReceiver, intentFilter);

startServicenew Intent(getApplicationContext(), RcsService. class));

bindServicenew Intent( this , DLService. class), mConnection,
                           Context.  BIND_AUTO_CREATE);

Intent broadcastIntent =  new Intent();
broadcastIntent.setAction(RcsService.  LOGIN_STATE_CHANGED);
sendBroadcast( broadcastIntent);

几种创建Intent的方法:
public Intent(String action);
public Intent(String action, Uri uri);
public Intent(Context packageContext, Class<?> cls);
public Intent(String action, Uri uri, Context packageContext, Class<?> cls)

什么是Action?
public Intent setAction(String action) {
        mAction = action != null ? action.intern() : null;
        return this;
    }

action是怎么定义的?
        <activity
            android:name= ".desktop.MainTabActivity"
            android:launchMode= "singleTask"
            android:screenOrientation= "portrait"
            android:theme= "@android:style/Theme.NoTitleBar"
            android:windowSoftInputMode= "stateAlwaysHidden|adjustPan" >
            <intent-filter>
                <action android:name= "android.intent.action.MAIN" />
                <category android:name= "android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

intent的flag:

FLAG_ACTIVITY_NEW_TASK
if set, this activity will become the start of a new task on this history stack. A task (from the activity that started it to the next task activity) defines an atomic group of activities that the user can move to. Tasks can be moved to the foreground and background; all of the activities inside of a particular task always remain in the same order. See  Tasks and Back Stack for more information about tasks.
这个activity会变成一个新的task的起始activity,一个task定义了一组activity。 task可以被放到前台和后台。(??????)
This flag is generally used by activities that want to present a "launcher" style behavior: they give the user a list of separate things that can be done, which otherwise run completely independently of the activity launching them.

When using this flag, if a task is already running for the activity you are now starting, then a new activity will not be started; instead, the current task will simply be brought to the front of the screen with the state it was last in. See FLAG_ACTIVITY_MULTIPLE_TASK for a flag to disable this behavior.
如果这个activity已经有一个task在运行,没有新activity会被创建,而是当前的task会被拿到前台。
This flag can not be used when the caller is requesting a result from the activity being launched.

Constant Value: 268435456 (0x10000000)

In addition to these primary attributes, there are a number of secondary attributes that you can also include with an intent:
  • category -- Gives additional information about the action to execute. For example, CATEGORY_LAUNCHER means it should appear in the Launcher as a top-level application, while CATEGORY_ALTERNATIVE means it should be included in a list of alternative actions the user can perform on a piece of data.
  • type -- Specifies an explicit type (a MIME type) of the intent data. Normally the type is inferred from the data itself. By setting this attribute, you disable that evaluation and force an explicit type.
  • component -- Specifies an explicit name of a component class to use for the intent. Normally this is determined by looking at the other information in the intent (the action, data/type, and categories) and matching that with a component that can handle it. If this attribute is set then none of the evaluation is performed, and this component is used exactly as is. By specifying this attribute, all of the other Intent attributes become optional.
  • extras -- This is a Bundle of any additional information. This can be used to provide extended information to the component. For example, if we have a action to send an e-mail message, we could also include extra pieces of data here to supply a subject, body, etc.
type:确定一个明确的名字of这个Intent
component:一个显示的组件名字。
extras:一组附加的信息

Here are some examples of other operations you can specify as intents using these additional parameters:
There are a variety of standard Intent action and category constants defined in the Intent class, but applications can also define their own. These strings use java style scoping, to ensure they are unique -- for example, the standard ACTION_VIEW is called "android.intent.action.VIEW".

Put together, the set of actions, data types, categories, and extra data defines a language for the system allowing for the expression of phrases such as "call john smith's cell". As applications are added to the system, they can extend this language by adding new actions, types, and categories, or they can modify the behavior of existing phrases by supplying their own activities that handle them.

public static final String CATEGORY_DEFAULT

Since:  API Level 1

Set if the activity should be an option for the default action (center press) to perform on a piece of data. Setting this will hide from the user any activities without it set when performing an action on some data. Note that this is normal -not- set in the Intent when initiating an action -- it is for use in intent filters specified in packages.

Constant Value: "android.intent.category.DEFAULT"

要想正确寻址到一个Activity,必须 act 和 data 都一致才可以。

android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.INSERT dat=content://com.google.provider.NotePad/notes/3 }

触发系统打电话界面:

Intent intent =  new  Intent(Intent.  ACTION_CALL , Uri.parse(  "tel:"
                           +  mNumber ));

              startActivity(intent);

intent中的data,都是用URI表示的

如本地的
content://com.duguhome.providers.sample/1

private void cropFromPicture() {
       Intent intent =  new Intent(Intent. ACTION_GET_CONTENTnull);
              intent. setType("image/*");
              intent.putExtra( "crop", "true" );
              intent.putExtra( "aspectX", 2);
              intent.putExtra( "aspectY", 1);
              intent.putExtra( "outputX", 600);
              intent.putExtra( "outputY", 300);
              intent.putExtra( "scale",  true );
              intent.putExtra( "return-data",  false );
              intent.putExtra(MediaStore.  EXTRA_OUTPUT, cameraFileUri );
              intent.putExtra( "outputFormat", Bitmap.CompressFormat. JPEG .toString());
              intent.putExtra( "noFaceDetection",  false ); // no face detection
              startActivityForResult(intent, CORP_FROM_PICTURE);
    }

type

public Intent setType (String type)

Since:  API Level 1

Set an explicit MIME data type.

This is used to create intents that only specify a type and not data, for example to indicate the type of data to return.

This method automatically clears any data that was previously set (for example by  setData(Uri)).

Note: MIME type matching in the Android framework is case-sensitive, unlike formal RFC MIME types. As a result, you should always write your MIME types with lower case letters, or use normalizeMimeType(String) or setTypeAndNormalize(String) to ensure that it is converted to lower case.

Parameters

type

The MIME type of the data being handled by this intent.

Returns
  • Returns the same Intent object, for chaining multiple calls into a single statement.
例子,text/plain表示文本类型,image/*表示图片

如果需要同时设置 data和type,就要用setDataandType函数

Category,范畴

一个约束条件

setClass
明确指定了Component,此时intent就变成了单纯的信息和数据的载体

setClass( Context packageContext,  Class<?> cls)
Convenience for calling  setComponent(ComponentName) with the name returned by a  Class object.

setClassName( Context packageContext,  String className)
Convenience for calling  setComponent(ComponentName) with an explicit class name.

public Intent setComponent (ComponentName component)

Extras
这是一个bundle对象

bundle实现了序列化,可以在进程间传递。
public final class Bundle implements Parcelable, Cloneable {}


模糊匹配的Intent,将请求者和实现者解耦合,提高了系统的灵活性。
IntentFilter组件是各个组件用来描述其功能的,表示它能接受的Intent请求的范围。

Intent Filter------里面的多个Action和Category项是或的关系,满足一个即可找到该组件。

而data和type不确定。
例子:

Intent Filter里的data项是这么写的
< data android:mimeType = "vnd.android.cursor.item/vnd.google.note" />

意图匹配算法,在intentFilter中的match函数:
算Intent和IntentFilter的匹配程度的,返回值

 public final int match(String action, String type, String scheme,
            Uri data, Set<String> categories, String logTag) {
        if (action != null && !matchAction(action)) {
            if (false) Log.v(
                logTag, "No matching action " + action + " for " + this);
            return NO_MATCH_ACTION;
        }

        int dataMatch = matchData(type, scheme, data);
        if (dataMatch < 0) {
            if (false) {
                if (dataMatch == NO_MATCH_TYPE) {
                    Log.v(logTag, "No matching type " + type
                          + " for " + this);
                }
                if (dataMatch == NO_MATCH_DATA) {
                    Log.v(logTag, "No matching scheme/path " + data
                          + " for " + this);
                }
            }
            return dataMatch;
        }

        String categoryMismatch = matchCategories(categories);
        if (categoryMismatch != null) {
            if (false) {
                Log.v(logTag, "No matching category " + categoryMismatch + " for " + this);
            }
            return NO_MATCH_CATEGORY;
        }

        // It would be nice to treat container activities as more
        // important than ones that can be embedded, but this is not the way...
        if (false) {
            if (categories != null) {
                dataMatch -= mCategories.size() - categories.size();
            }
        }

        return dataMatch;
    }

配置界面组件时,如果期望该组件能作为通用的功能组件被调用,必须显性的添加 Intent.CATEGORY_DEFAULT这个分类。

若有多个Intent Filter对象都匹配时,怎么办?核心机制是对IntentFilter做基于优先级的排序。
你可以拦截系统的短信页面,怎么办呢?提高自己的第三方的短信页面的优先级,然后拦截系统启动短信页面的intent,再abortBroadcast,如下:

public void onReceive(Context context, Intent intent){
     if(IsBlockedSms(intent)){
          abortBroadcast();
     }
}

若不同的Intent Filter对象优先级一致,按照组件名字的字母顺序依次调用。

算法是如何实现的呢?
因为IntentFilter实在太多----这就是个查找的过程,为了降低查找的时间复杂度,使用了Hash表。

还有就是缓存---就是将匹配记录存储下来,然后当遇到相同的请求时,直接返回结果。
最终也可以让用户来选择用哪个界面。
用户可以设置默认组件,但是若想绕过默认组件,可以通过Intent.createChooser自定义组件选择列表。

activity.startActivity(Intent.createChooser(intent,R.string.xxxx));

可以通过 PackageManager.queryIntentActivities函数,获得与Intent相匹配的的所有备选组件列表。
!!!!

在组件和触发器中也能应用

Service,系统默认选优先级最高的,不会让用户选。

Context.sendBroadcast
Intent intent2 =  new Intent( Intent.  ACTION_MEDIA_SCANNER_SCAN_FILE);
        intent2.setData( cameraFileUri );
        sendBroadcast (intent2);

收到广播后,组件管理服务会构造所有匹配的触发器组件,并发的执行操作。。。。

< receiver android:name = ".publicaccounts.push.AlarmReceiver" >
            < intent-filter>
                < action android:name = "com.cmri.ercs.push.alarm.action" />
            </ intent-filter>
        </ receiver>

Context.sendOrderedBroadcast进行有序广播时,需要按照IntentFilter的优先级进行排序,逐一构造和处理。。。

怎样将BroadcastReceiver对象和IntentFilter绑定????

registerReceiver(receiver,filter);

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值