【android学习】重要组件-Intent

1,概念

意图,意向。
在android中用Intent机制来协助应用间的交互与通讯。
Intent负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述,Android则根据此Intent的描述,负责找到对应的组件,将 Intent传递给调用的组件,并完成组件的调用。
Intent不仅可用于应用程序之间,也可用于应用程序内部的Activity/Service之间的交互。

1)优点

减少组件间的耦合。
使用Intent可以激活Android应用的三个核心组件:活动、服务和广播接收器。

2)Intent可传递数据类型

可序列化的对象。

3)分类

①显式意图

调用Intent.setComponent()或Intent.setClass()方法明确指定了组件名的Intent为显式意图,显式意图明确指定了Intent应该传递给哪个组件。

指明明确的activity路径:

Intent intent=new Intent(this,TestActivity.class);
intent.setData(Uri.parse(fileUrl));
startActivity(intent);
Intent intent=new Intent();
intent.setClassName(context.getPackageName(),
”com.google.sample.TestActivity”);
startActivity(intent);
Intent intent=new Intetn();
intent.setComponent(new ComponentName(context.getPackageName(),
"com.google.sample.TestActivity"));
startActivity(intent);

②隐式意图

没有明确指定组件名的Intent为隐式意图。 Android系统会根据隐式意图中设置的动作(action)、类别(category)、数据(URI和数据类型)找到最合适的组件来处理这个意图。

通过这种方式来启动发送短信的activity:

Intent intent=new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_TEXT,textMessage);
intent.setType("text/plain");
startActivity(intent);

2,场景

1)启动一个Activity

①切换当前界面到NcActivity.class

Intent intent = new Intent(mContext, NcActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);  
startActivity(intent);

②读取APK存储路径并自动安装

Intent intent = new Intent(Intent.ACTION_VIEW);
// 设置intent的data和Type属性。
intent.setDataAndType(
FileUtils.getUriFromFile(Url.apkPath + Url.apkName),
"application/vnd.android.package-archive");
startActivity(intent);

2)启动一个Service

①startService方法

serviceIntent = new Intent(this, HttpService.class);
startService(serviceIntent);
stopService(serviceIntent);

②bindService方法

3)发起一个广播Broadcasts

①sendBroadcasts方法

            Intent intent = new Intent();
            intent.setAction("cn.login");

            Bundle bundle = new Bundle();
            bundle.putString("username", userName);
            bundle.putString("password",Password);
            bundle.putString("server", Server);
            bundle.putInt("port", Port);
            intent.putExtras(bundle);

            sendBroadcast(intent);

②sendOrderedBroadcasts方法

③sendStickyBroadcasts方法

4)传递数据

注意:
Intent传递数据大小的限制大概在1M左右,超过这个限制就会静默崩溃。处理方式:
进程内:EventBus,文件缓存、磁盘缓存。
进程间:通过ContentProvider进行进程数据共享和传递。

①数据跳转

Intent intent = new Intent(this, BActivity.class);
intent.putExtra("Intent_msg","传送数据的信息");//字符串
intent.putExtra("mInt",4);//int
intent.putExtra("person_data", person); //传递对象 Person implements Serializable
intent.startActivity(intent);

BActivity接收数据:

Intent intent = getIntent();
String msg = intent.getStringExtra("Intent_msg");
int i = intent.getIntExtra("mInt", 0);
Person person = (Person) getIntent().getSerializableExtra("person_data");  

②Bundle绑定数据跳转

Intent intent = new Intent();
Bundle bundle = new Bundle();
bundle.putString("username","小明");
bundle.putString("userpsw","123456");
intent.putExtras(bundle);
intent.setClass(this, BActivity.class);  
startActivity(intent);

获取Intent对象,取得Bundle中的数据:

Intent intent = getIntent();
Bundle bundle = intent.getExtras();
String username = bundle.getString("username");
intent.setClass(this, BActivity.class);  

③数据返回跳转

使用startActivityForResult,AActivity跳转至BActivity,BActivity返回信息给AActivity。
注意:
所有需要传递或接收的 Activity 不允许设置launchmode="SingleTask"属性,或只能设为标准模式,否则系统将在 startActivityForResult() 后,还没等到被调用的 Activity 返回,就直接调用 onActivityResult()。

i>AActivity:

Intent intent = new Intent();
intent.setClass(this, BActivity.class);  
startActivityForResult(intent,reqest_code);//reqest_code为请求码

在onActivityResult方法中接收并处理返回的信息。其中,参数:
–requestCode 请求码,即调用startActivityForResult() 传递过去的值
–resultCode 结果码,结果码用于标识返回数据来自哪个新Activity

protected void onActivityResult(int requestCode,int resultCode,Intent data){

    switch(requestCode){//requestCode为回传的标记
        case OK:
            Bundle b = data.getExtras();//data为BActivity中回传的Intent
            String msg = b.getString("responeMsg");
            break;
        default:break;
    }
}

如果是在Fragment中接收数据,则为:

public class b extends Fragment{ 

***
@Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
        case 1:
            if (resultCode != Activity.RESULT_OK) {
                return;
            }
            break;

        default:
            break;
        }

    }
***
}

ii>BActivity:

        Intent mIntent = new Intent();  
        mIntent.putExtra("change01", "1000");  
        // 设置结果,并进行传送  
        this.setResult(resultCode, mIntent);  

④传递bitmap

Bitmap bmp=((BitmapDrawable)order_con_pic.getDrawable()).getBitmap();  
Intent intent=new Intent(A.this,B.class);  
ByteArrayOutputStream baos=new ByteArrayOutputStream();  
bmp.compress(Bitmap.CompressFormat.PNG, 100, baos);  
byte [] bitmapByte =baos.toByteArray();  
intent.putExtra("bitmap", bitmapByte);  
startActivity(intent);  
Intent intent=getIntent();  
        if(intent !=null)  
        {  
            byte [] bis=intent.getByteArrayExtra("bitmap");  
            Bitmap bitmap=BitmapFactory.decodeByteArray(bis, 0, bis.length);  
            imageView.setImageBitmap(bitmap);  
        }  

bimap保存:

public void saveMyBitmap(String bitName,Bitmap mBitmap) throws IOException {  
        File f = new File("/sdcard/Note/" + bitName);  
        if(!f.exists())  
            f.mkdirs();//如果没有这个文件夹的话,会报file not found错误  
        f=new File("/sdcard/Note/"+bitName+".png");  
        f.createNewFile();  
        try {  
            FileOutputStream out = new FileOutputStream(f);  
             mBitmap.compress(Bitmap.CompressFormat.PNG, 100, out);  
             out.flush();  
             out.close();  
        } catch (FileNotFoundException e) {  
                Log.i(TAG,e.toString());  
        }  

    }  

5)显示用户数据

详细见下文action讲解。

用于在浏览器浏览这个网址:

Intent intent = new Intent(Intent.ACTION.VIEW,Uri.parse("http://mail.google.com"))

打开系统拍照


    /**
     * 拍照
     */
    public void takePhoto() {
        Intent openCameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

        File vFile = FileUtil.getImageFile();

        Uri cameraUri = Uri.fromFile(vFile);
        openCameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, cameraUri);
        ((Activity) context).startActivityForResult(openCameraIntent, Variable.TAKE_PICTURE);
    }
package com.luo.util;

import java.io.File;

import android.os.Environment;

public class FileUtil {

    public static String ImagePath = ""; 
    public static File getImageFile(){
        File vFile = new File(Environment.getExternalStorageDirectory() + "/myimage/",
                String.valueOf(System.currentTimeMillis()) + ".jpg");
        if (!vFile.exists()) {
            File vDirPath = vFile.getParentFile();
            vDirPath.mkdirs();
        } else {
            if (vFile.exists()) {
                vFile.delete();
            }
        }
        ImagePath = vFile.getPath();

        return vFile;
    }
}

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        switch (requestCode) {
        case Variable.TAKE_PICTURE:
            String path = FileUtil.ImagePath;
            List<ImageBean> mData = new ArrayList<ImageBean>(); 

            if (mData.size() < Variable.MAX_IMAGE_SIZE && resultCode == -1 && !TextUtils.isEmpty(path)) {
                ImageBean item = new ImageBean();
                item.sourcePath = path;
                mData.add(item);
            }

            initData(mData);
            initview();
            break;
        }
    }

默认情况下,即不需要指定intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);照相机有自己默认的存储路径,拍摄的照片将返回一个缩略图。如果想访问原始图片,可以通过dat extra能够得到原始图片位置。
如果指定了目标uri,data就没有数据,如果没有指定uri,则data就返回有数据!

3,属性:

1)动作(Action)

指Intent要完成的动作,是一个字符串常量。

①Intent.ACTION_MAIN

标识Activity为一个程序的开始。

<activity android:name=".Main" 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.ACTION_VIEW

用于显示用户的数据。根据用户的数据类型打开相应的Activity。

//浏览器 
Uri uri = Uri.parse("http://www.google.com");
//拨号程序 
Uri uri =Uri.parse("tel:1232333");  
//打开地图定位
Uri uri=Uri.parse("geo:39.899533,116.036476"); 
//路径规划 
Uri uri = Uri.parse("http://maps.google.com/maps?f=dsaddr=startLat%20startLng&daddr=endLat%20endLng&hl=en"); 


Intent intent = new Intent(Intent.ACTION_VIEW,uri);
startActivity(intent );

播放视频:

Intent intent = new Intent(Intent.ACTION_VIEW);
Uri uri = Uri.parse("file:///sdcard/media.mp4"); 
intent.setDataAndType(uri, "video/*"); 
startActivity(intent);

调用发送短信的程序:

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.putExtra("sms_body", "信息内容..."); 
intent.setType("vnd.android-dir/mms-sms"); 
startActivity(intent );

显示应用详细列表 :

Uri uri = Uri.parse("market://details?id=app_id");         
Intent it = new Intent(Intent.ACTION_VIEW, uri);         
startActivity(it);   

③Intent.ACTION_BUG_REPORT

显示Dug报告。

④Intent.Action_CALL_BUTTON

相当于用户按下“拨号”键。显示为“通话记录”。

Intent intent = new Intent(Intent.ACTION_CALL_BUTTON);
startActivity(intent);

⑤Intent.ACTION_CHOOSER

显示一个activity选择器,允许用户在进程之前选择他们想要的。

⑥Intent.ACTION_GET_CONTENT

允许用户选择特殊种类的数据,并返回(特殊种类的数据:照一张相片或录一段音)
输入:Type
输出:URI

int requestCode = 1001;
Intent intent = new Intent(Intent.ACTION_GET_CONTENT); 
intent.setType("image/*"); // 查看类型,如果是其他类型,比如视频则替换成 video/*,或 */*
Intent wrapperIntent = Intent.createChooser(intent, null);
startActivityForResult(wrapperIntent, requestCode);
//选择图片 requestCode 返回的标识
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(contentType);//查看类型 String IMAGE_UNSPECIFIED = "image/*";
Intent wrapperIntent = Intent.createChooser(intent, null);
((Activity) context).startActivityForResult(wrapperIntent, requestCode);
//添加音频
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(contentType);//String VIDEO_UNSPECIFIED = "video/*";
Intent wrapperIntent = Intent.createChooser(intent, null);
((Activity) context).startActivityForResult(wrapperIntent, requestCode);
//拍摄视频 
int durationLimit = getVideoCaptureDurationLimit(); //SystemProperties.getInt("ro.media.enc.lprof.duration", 60);
Intent intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);
intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 0);
intent.putExtra(MediaStore.EXTRA_SIZE_LIMIT, sizeLimit);
intent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, durationLimit);
startActivityForResult(intent, REQUEST_CODE_TAKE_VIDEO);
//视频
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(contentType); //String VIDEO_UNSPECIFIED = "video/*";
Intent wrapperIntent = Intent.createChooser(intent, null);
((Activity) context).startActivityForResult(wrapperIntent, requestCode);
//录音
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType(ContentType.AUDIO_AMR); //String AUDIO_AMR = "audio/amr";
intent.setClassName("com.android.soundrecorder","com.android.soundrecorder.SoundRecorder");
((Activity) context).startActivityForResult(intent, requestCode);
//拍照 REQUEST_CODE_TAKE_PICTURE 为返回的标识
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); //"android.media.action.IMAGE_CAPTURE";
intent.putExtra(MediaStore.EXTRA_OUTPUT, Mms.ScrapSpace.CONTENT_URI); // output,Uri.parse("content://mms/scrapSpace");
startActivityForResult(intent, REQUEST_CODE_TAKE_PICTURE);

⑦Intent.Action.DIAL

调用拨号面板,添加指定的电话号码。

打开Android的拨号UI。如果没有设置数据,则打开一个空的UI,如果设置数据,action.DIAL则通过调用getData()获取电话号码。
输入:电话号码,数据格式为:tel:+phone number

Intent intent=new Intent(); 
intent.setAction(Intent.ACTION_DIAL); 
intent.setData(Uri.parse("tel:1800010001");
startActivity(intent);

⑧Intent.Action_CALL

呼叫指定的电话号码。
输入:电话号码,数据格式为:tel:+phone number

Intent intent=new Intent(); 
intent.setAction(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:1800010001");
startActivity(intent);

⑨Intent.ACTION_SENDTO、Intent.ACTION_SEND

ACTION_SEND 传递数据,被传送的数据没有指定,接收的action请求用户发数据
ACTION_SENDTO 发送一跳信息到指定的某人

//发送短信息 
Uri uri = Uri.parse("smsto:13200100001"); 
Intent intent = new Intent(Intent.ACTION_SENDTO, uri); 
intent .putExtra("sms_body", "信息内容..."); 
startActivity(intent );
//发送彩信,设备会提示选择合适的程序发送 Uri uri = Uri.parse("content://media/external/images/media/23");
//设备中的资源(图像或其他资源) 
Intent intent = new Intent(Intent.ACTION_SEND); 
intent.putExtra("sms_body", "内容"); 
intent.putExtra(Intent.EXTRA_STREAM, uri); 
intent.setType("image/png"); 
startActivity(it);
//Email Intent intent=new Intent(Intent.ACTION_SEND); 
String[] tos={"android1@163.com"}; 
String[] ccs={"you@yahoo.com"}; 
intent.putExtra(Intent.EXTRA_EMAIL, tos); 
intent.putExtra(Intent.EXTRA_CC, ccs);
 intent.putExtra(Intent.EXTRA_TEXT, "The email body text"); 
intent.putExtra(Intent.EXTRA_SUBJECT, "The email subject text"); 
intent.setType("message/rfc822"); 
startActivity(Intent.createChooser(intent, "Choose Email Client"));

⑩Intent.ACTION_ANSWER

处理呼入的电话。

⑪ Intent.Action.ALL_APPS

列出所有的应用

⑫Intent.ACTION_ATTACH_DATA

用于指定一些数据应该附属于一些其他的地方,例如,图片数据应该附属于联系人

⑬Intent.ACTION_WEB_SEARCH

从google搜索内容 :

Intent intent = new Intent(); 
intent.setAction(Intent.ACTION_WEB_SEARCH); 
intent.putExtra(SearchManager.QUERY,"searchString") 
startActivity(intent); 

⑭Intent.ACTION_DELETE

卸载。

Uri uri = Uri.fromParts("package", strPackageName, null);    
Intent it = new Intent(Intent.ACTION_DELETE, uri);    
startActivity(it);

⑮Intent.ACTION_PACKAGE_ADDED

安装。

Uri installUri = Uri.fromParts("package", "xxx", null); 
returnIt = new Intent(Intent.ACTION_PACKAGE_ADDED, installUri); 

⑯ Intent.ACTION_INSERT_OR_EDIT

调用系统编辑添加联系人:

Intent intent = new Intent(Intent.ACTION_INSERT_OR_EDIT); 
            intent.setType(People.CONTENT_ITEM_TYPE); 
            intent.putExtra(Contacts.Intents.Insert.NAME, "My Name"); 
            intent.putExtra(Contacts.Intents.Insert.PHONE, "+1234567890"); 
            intent.putExtra(Contacts.Intents.Insert.PHONE_TYPE, Contacts.PhonesColumns.TYPE_MOBILE); 
            intent.putExtra(Contacts.Intents.Insert.EMAIL, "com@com.com"); 
            intent.putExtra(Contacts.Intents.Insert.EMAIL_TYPE,                    Contacts.ContactMethodsColumns.TYPE_WORK); 
            startActivity(intent); 

ACTION_INSERT:插入一条空项目到已给的容器 。
ACTION_EDIT:访问已给的数据,提供明确的可编辑

⑰其他

ACTION_RUN 运行数据
ACTION_SYNC 同步执行一个数据
ACTION_PICK_ACTIVITY 为已知的Intent选择一个Activity,返回选中的类
ACTION_PICK 从数据中选择一个子项目,并返回你所选中的项目
ACTION_FACTORY_TEST 工场测试的主要进入点

2)数据(Data)

执行动作的URI和MIME(或mimeType)类型,不同的Action又不同的Data数据指定。

MIME(或mimeType)指媒体类型,如:image/jpeg、audio/mpeg4-generic和video/*等,可以表示图片、文本、视频等。

3)类别(Category)

执行动作Action的附加信息。

4)数据类型(Type)

指定Intent的数据类型(MIME)。
一般的Intent的数据类型根据数据本身判定,通过设置这个属性,强制采用显示指定类型。

5)组件(Compent)

指定Intent的目标组件的类名称。
通常android会根据Intent中包含的其它属性的信息进行查找,最终找到一个与之相配的目标组件。通过设置这个属性,将直接使用它指定的组件。

6)扩展信(Extras)

添加一些组件的附加信息。
比如用Activity发送Email,可以通过此属性来添加subject和body。

举例:传递参数(用于2个activity)
i>在发送Intent的activity中,添加键值对:

intent.putExtra("NAME","luo");

ii>在接受Intent的activity中,取值:

Intent intent = getIntent();
String Str_name = intent.getStringExtra("NAME");

iii>传递列表

intent.putExtra(
VariableUtil.EXTRA_IMAGE_LIST,
(Serializable) new ArrayList<ImageItem>selectedImgs.values()));  
intent.getSerializableExtra(VariableUtil.EXTRA_IMAGE_LIST);

4,Intent解析机制

通过查找已注册在AndroidManifest.xml中的所有IntentFilter及其中定义的Intent,最终找到匹配的Intent。
在这个解析过程中,Android是通过Intent的action、type和category三个属性来进行判断的。
1)如果Intent指定了action,则目标组件的IntentFilter的action列表中就必须包含这个action,否则不能匹配。
2)如果Intent没有提供type,系统将从data中得到数据类型。和action一样,目标组件的数据类型列表中必须包含Intent的数据类型,否则不能匹配。
3)如果Intent中的数据不是content类型的URI,而且Intent也没有明确指定它的type,将根据Intent中数据的scheme 如 http: 或者mailto:进行匹配。(Intent的scheme必须出现在目标组件的scheme列表中)
4)如果Intent指定了一个或多个category,这些类别必须全部出现在组件的类别列表中。如Intent中包含了两个类别:LAUNCHER_CATEGORY和ALTERNATIVE_CATEGORY,解析得到的目标组件必须至少包含这两个类别。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值