intent

一.Intent的介绍

Intent的中文意思是“意图,意向”,在Android中提供了Intent机制来协助应用间的交互与通讯,Intent负责对应用中一次操作的动作、动作涉及数据、附加数据进行描述,Android则根据此Intent的描述,负责找到对应的组件,将 Intent传递给调用的组件,并完成组件的调用。Intent不仅可用于应用程序之间,也可用于应用程序内部的Activity/Service之间的交互。因此,可以将Intent理解为不同组件之间通信的“媒介”专门提供组件互相调用的相关信息。

简单来说,Intent是系统各组件之间进行数据传递的数据负载者。当我们需要做一个调用动作,我们就可以通过Intent告诉Android系统来完成这个过程,Intent就是调用通知的一种操作。

二.Inten启动组件的方法

Intent可以启动一个Activity,也可以启动一个Service,还可以发起一个广播Broadcasts。

//启动一个Activity:
Context.startActivity(Intent intent);
//启动一个Service:
Context.startService(Intent service);
//绑定一个Service:
Context.bindService(Intent service, ServiceConnection conn, int flags);
//发送一个Broadcast:
Context.sendBroadcast(Intent intent);
Context.sendOrderedBroadcasts()
Context.sendStickyBroadcasts()

三.Intent的属性

Intent有以下几个属性:
动作(Action),数据(Data),分类(Category),类型(Type),组件(Compent)以及扩展信(Extra)。其中最常用的是Action属性和Data属性。

1.Intent的Action属性
Action是指Intent要完成的动作,是一个字符串常量。SDK中定义了一些标准的Action常量如下表所示。

ConstantTarget componentAction
ACTION_CALLactivityInitiate a phone call.
ACTION_EDITactivityDisplay data for the user to edit.
ACTION_MAINactivityStart up as the initial activity of a task, with no data input and no returned output.
ACTION_SYNCactivitySynchronize data on a server with data on the mobile device.
ACTION_BATTERY_LOWbroadcast receiverA warning that the battery is low.
ACTION_HEADSET_PLUGbroadcast receiverA headset has been plugged into the device, or unplugged from it.
ACTION_SCREEN_ONbroadcast receiverThe screen has been turned on.
ACTION_TIMEZONE_CHANGEDbroadcast receiverThe setting for the time zone has changed.

测试action:

  Intent intent = new Intent();                 
  intent.setAction(Intent.ACTION_GET_CONTENT);
  // 设置Intent Action属性                              
  intent.setType("vnd.android.cursor.item/phone");
  // 设置Intent Type 属性   
                                                                //主要是获取通讯录的内容  
 startActivity(intent); // 启动Activity  

2.Intent的Data属性
Intent的Data属性是执行动作的URI和MIME类型,不同的Action有不同的Data数据指定。比如:ACTION_EDIT Action应该和要编辑的文档URI Data匹配,ACTION_VIEW应用应该和要显示的URI匹配。

打开指定网页

    Intent intent = new Intent(Intent.ACTION_VIEW);  
    intent.setData(Uri.parse("http://www.google.com.hk"));  
    startActivity(intent);  

3.Intent的Category属性
Intent中的Category属性是一个执行动作Action的附加信息。比如:CATEGORY_HOME则表示放回到Home界面,ALTERNATIVE_CATEGORY表示当前的Intent是一系列的可选动作中的一个。下表是SDK文档中关于Category的信息。

几个常见的category如下:

Intent.CATEGORY_DEFAULT(android.intent.category.DEFAULT) 
//默认的category
Intent.CATEGORY_PREFERENCE(android.intent.category.PREFERENCE) //表示该目标Activity是一个首选项界面;
Intent.CATEGORY_BROWSABLE(android.intent.category.BROWSABLE)
//指定了此category后,在网页上点击图片或链接时,
//系统会考虑将此目标Activity列入可选列表,供用户选择以打开图片或链接。

在为Intent设置category时,应使用addCategory(String category)方法向Intent中添加指定的类别信息,来匹配声明了此类别的目标Activity。

ConstantMeaning
CATEGORY_BROWSABLEThe target activity can be safely invoked by the browser to display data referenced by a link — for example, an image or an e-mail message.
CATEGORY_GADGETThe activity can be embedded inside of another activity that hosts gadgets.
CATEGORY_HOMEThe activity displays the home screen, the first screen the user sees when the device is turned on or when the HOME key is pressed.
CATEGORY_LAUNCHERThe activity can be the initial activity of a task and is listed in the top-level application launcher.
CATEGORY_PREFERENCEThe target activity is a preference panel.

返回home:

Intent intent = new Intent();                 
                intent.setAction(Intent.ACTION_MAIN);// 添加Action属性                
                intent.addCategory(Intent.CATEGORY_HOME);// 添加Category属性              
                startActivity(intent);// 启动Activity

4.Intent的Type属性
Intent的Type属性显式指定Intent的数据类型(MIME)。一般Intent的数据类型能够根据数据本身进行判定,但是通过设置这个属性,可以强制采用显式指定的类型而不再进行推导。在使用Intent进行匹配时,我们可以使用setType(String type)或者setDataAndType(Uri data, String type)来设置mimeType。

常见的MIME类型(通用型):

名称格式MIME类型
超文本标记语言文本.htmltext/html
xml文档.xmltext/xml
XHTML文档.xhtmlapplication/xhtml+xml
普通文本.txttext/plain
RTF文本.rtfapplication/rtf
PDF文档.pdfapplication/pdf
Microsoft Word文件.wordapplication/msword
PNG图像.pngimage/png
GIF图形.gifimage/gif
JPEG图形.jpeg,.jpgimage/jpeg
au声音文件.auaudio/basic
MIDI音乐文件mid,.midiaudio/midi,audio/x-midi
RealAudio音乐文件.ra, .ramaudio/x-pn-realaudio
MPEG文件.mpg,.mpegvideo/mpeg
AVI文件.avivideo/x-msvideo
GZIP文件.gzapplication/x-gzip
TAR文件.tarapplication/x-tar
任意的二进制数据application/octet-stream

5.Intent的Compent属性
Intent的Compent属性指定Intent的的目标组件的类名称。通常 Android会根据Intent 中包含的其它属性的信息,比如action、data/type、category进行查找,最终找到一个与之匹配的目标组件。但是,如果 component这个属性有指定的话,将直接使用它指定的组件,而不再执行上述查找过程。指定了这个属性以后,Intent的其它所有属性都是可选的。

发送activity:

 Intent intent = new Intent();  
// ComponentName com = new ComponentName(MainActivity.this,MyActivity.class);//方法一
        ComponentName com = new ComponentName(  
                "com.example.testcomponent",  
                "com.example.testcomponent.MyActivity");//方法二
                //第二个参数为activity,但包名需要写全  
        intent.setComponent(com);  
        String s = "This is a Test.";  
        intent.putExtra("id", s);  
        startActivity(intent);  

接收activity:

text = (TextView)findViewById(R.id.text);  
Intent intent = getIntent();  
String str = intent.getStringExtra("id");  
ComponentName com = intent.getComponent();  
String pkgName = com.getPackageName();  
String className = com.getClassName();  
text.setText(str + "\n" + pkgName + "\n" + className);  

效果:

6.Intent的Extra属性
Intent的Extra属性是添加一些组件的附加信息。比如,如果我们要通过一个Activity来发送一个Email,就可以通过Extra属性来添加subject和body。

进行关键字搜索

    Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);  
    intent.putExtra(SearchManager.QUERY, "android");    //关键字  
    startActivity(intent);  

四.常见跳转:

打开相册:

void choosePhoto(){
     /**
      * 打开选择图片的界面
      */
     Intent intent = new Intent(Intent.ACTION_PICK);
     //或
     //Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
     intent.setType("image/*");//相片类型

//或
//Intent albumIntent = new Intent(Intent.ACTION_PICK, null);
//albumIntent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");

     startActivityForResult(intent, REQUEST_CODE_PICK_IMAGE);

 }

打开相机:

void takePhoto(){
    /**
     * 最后一个参数是文件夹的名称,可以随便起
     */
    File file=new File(Environment.getExternalStorageDirectory(),"拍照");
    if(!file.exists()){
        file.mkdir();
    }
    /**
     * 这里将时间作为不同照片的名称
     */
    output=new File(file,System.currentTimeMillis()+".jpg");

    /**
     * 如果该文件夹已经存在,则删除它,否则创建一个
     */
    try {
        if (output.exists()) {
            output.delete();
        }
        output.createNewFile();
    } catch (Exception e) {
        e.printStackTrace();
    }
    /**
     * 隐式打开拍照的Activity,并且传入CROP_PHOTO常量作为拍照结束后回调的标志
     * 将文件转化为uri
     */
    imageUri = Uri.fromFile(output);
    Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
    intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
    startActivityForResult(intent, CROP_PHOTO);

}

返回结果:

public void onActivityResult(int req, int res, Intent data) {
    switch (req) {
        /**
         * 拍照的请求标志
         */
        case CROP_PHOTO:
            if (res==RESULT_OK) {
                try {
                    /**
                     * 该uri就是照片文件夹对应的uri
                     */
                    Bitmap bit = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));
                    imageView.setImageBitmap(bit);
                } catch (Exception e) {
                    Toast.makeText(this,"程序崩溃",Toast.LENGTH_SHORT).show();
                }
            }
            else{
                Log.i("tag", "失败");
            }

            break;
        /**
         * 从相册中选取图片的请求标志
         */

        case REQUEST_CODE_PICK_IMAGE:
            if (res == RESULT_OK) {
                try {
                    /**
                     * 该uri是上一个Activity返回的
                     */
                    Uri uri = data.getData();
                    Bitmap bit = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri));
                    imageView.setImageBitmap(bit);
                } catch (Exception e) {
                    e.printStackTrace();
                    Log.d("tag",e.getMessage());
                    Toast.makeText(this,"程序崩溃",Toast.LENGTH_SHORT).show();
                }
            }
            else{
                Log.i("liang", "失败");
            }

            break;

        default:
            break;
    }
}

裁剪图片:

public void clipPhoto(Uri uri) {
    Intent intent = new Intent("com.android.camera.action.CROP");
    intent.setDataAndType(uri, "image/*");
    intent.putExtra("crop", "true");
    // aspectX aspectY 是宽高的比例,这里设置的是正方形(长宽比为1:1)
    intent.putExtra("aspectX", 1);
    intent.putExtra("aspectY", 1);
    // outputX outputY 是裁剪图片宽高
    intent.putExtra("outputX", 300);
    intent.putExtra("outputY", 300);
    intent.putExtra("return-data", true);
    startActivityForResult(intent, CUT_OK);
}

五.显式意图与隐式意图

Intent的相关属性:

Intent由以下各个组成部分:

  • component(组件):目的组件
  • action(动作):用来表现意图的行动
  • category(类别):用来表现动作的类别
  • data(数据):表示与动作要操纵的数据
  • type(数据类型):对于data范例的描写
  • extras(扩展信息):扩展信息
  • Flags(标志位):期望这个意图的运行模式
    Intent类型分为显式Intent(直接类型)、隐式Intent(间接类型)。官方建议使用隐式Intent。
    上述属性中,component属性为直接类型,其他均为间接类型。

相比与显式Intent,隐式Intnet则含蓄了许多,它并不明确指出我们想要启动哪一个活动,而是指定一系列更为抽象的action和category等信息,然后交由系统去分析这个Intent,并帮我们找出合适的活动去启动。

Intent寻找目标组件的两种方式:
显式Intent:通过指定Intent组件名称来实现的,它一般用在知道目标组件名称的前提下,一般是在相同的应用程序内部实现的。
隐式Intent:通过Intent Filter来实现的,它一般用在没有明确指出目标组件名称的前提下,一般是用于在不同应用程序之间。

显式Intent

一般情况下,一个Android应用程序中需要多个屏幕,即是多个Activity类,并且在这些Activity之间进行切换通过Intent机制来实现的。在同一个应用程序中切换Activity时,我们通常都知道要启动的Activity具体是哪一个,因此常用显式的Intent来实现的。

 //显示方式声明Intent,直接启动SecondActivity  
                Intent it = new Intent(MainActivity.this,SecondActivity.class);  
                //启动Activity  
                startActivity(it); 

隐式Intent

同一应用程序中的Activity切换,需要AndroidManifest.xml中增加Activity的声明,并设置对应的Intent Filter和Action,才能被Android的应用程序框架所匹配。

                // 实例化Intent  
                Intent it = new Intent();  
                //设置Intent的Action属性  
                it.setAction("com.android.activity.MY_ACTION");  
                // 启动Activity  
                startActivity(it);

Manifest.xml文件

<activity android:name=".MainActivity" 
                  android:label="@string/app_name"> 
            <intent-filter> 
                <action android:name="android.intent.action.MAIN" /> 
                <category android:name="android.intent.category.LAUNCHER" /> 
            </intent-filter> 
        </activity> 

        <activity android:name=".SecondActivity" >                 
        <intent-filter>   
            <action  android:name = "com.android.activity.MY_ACTION"  />   
            <category android:name = "android.intent.category.DEFAULT"  />   
         </intent-filter>       
        </activity>

对于显示Intent,Android不需要再去做解析,因为目标组件很明确。Android需要解析的是隐式Intent,通过解析,将Intent映射给可以处理该Intent的Activity,Service等。Intent的解析机制主要是通过查找已经注册在AndroidManifest.xml中的所有IntentFilter以及其中定义的Intent,最终找到匹配的Intent。

Intent常用调用代码

显示Web网页:

Uri uri = Uri.parse("http://www.android123.com.cn"); 
Intent it =new Intent(Intent.ACTION_VIEW,uri);
startActivity(it);

显示Google地图:

Uri uri = Uri.parse("geo:38.899533,-77.036476"); 
Intent it =new Intent(Intent.Action_VIEW,uri);
startActivity(it);

Maps路径规划:

Uri uri = Uri.parse("http://maps.google.com/maps?f=d&saddr=startLat%20startLng&daddr=endLat%20endLng&hl=en"); 
Intent it =new Intent(Intent.ACTION_VIEW,URI);
startActivity(it);

拨打电话:

Uri uri = Uri.parse("tel:xxxxxx"); 
Intent it =new Intent(Intent.ACTION_DIAL, uri); 
startActivity(it); 
Uri uri = Uri.parse("tel.xxxxxx"); 
Intent it =new Intent(Intent.ACTION_CALL,uri);

注意需要权限

<uses-permission id="android.permission.CALL_PHONE"/>

发送SMS/MMS

Intent it =new Intent(Intent.ACTION_VIEW); 
it.putExtra("sms_body", "android开发网欢迎您"); 
it.setType("vnd.android-dir/mms-sms"); 
startActivity(it);

发送短信

Uri uri = Uri.parse("smsto:10086"); 
Intent it =new Intent(Intent.ACTION_SENDTO, uri); 
it.putExtra("sms_body", "10086"); //正文为10086 
startActivity(it);

发送彩信

Uri uri = Uri.parse("content://media/external/images/media/10"); //该Uri根据实际情况修改,external代表外部存储即sdcard 
Intent it =new Intent(Intent.ACTION_SEND); 
it.putExtra("sms_body", "android123.com.cn"); 
it.putExtra(Intent.EXTRA_STREAM, uri); 
it.setType("image/png"); 
startActivity(it);

发送Email

Uri uri = Uri.parse("mailto:android123@163.com"); 
Intent it =new Intent(Intent.ACTION_SENDTO, uri); 
startActivity(it);
Intent it =new Intent(Intent.ACTION_SEND); 
it.putExtra(Intent.EXTRA_EMAIL, "android123@163.com"); 
it.putExtra(Intent.EXTRA_TEXT, "android开发网测试"); 
it.setType("text/plain"); 
startActivity(Intent.createChooser(it, "选择一个Email客户端"));
Intent it=new Intent(Intent.ACTION_SEND); 
String[] tos={"android123@163.com"}; //发送到 
String[] ccs={"ophone123@163.com"}; //抄送 
it.putExtra(Intent.EXTRA_EMAIL, tos); 
it.putExtra(Intent.EXTRA_CC, ccs); 
it.putExtra(Intent.EXTRA_TEXT, "正文"); 
it.putExtra(Intent.EXTRA_SUBJECT, "标题"); 
it.setType("message/rfc822"); //编码类型 
startActivity(Intent.createChooser(it, "选择一个Email客户端"));

Email添加附件

Intent it = new Intent(Intent.ACTION_SEND);  
it.putExtra(Intent.EXTRA_SUBJECT, "正文");  
it.putExtra(Intent.EXTRA_STREAM, "file:///sdcard/nobody.mp3"); //附件为sd卡上的nobody MP3文件  
sendIntent.setType("audio/mp3");  
startActivity(Intent.createChooser(it, "选择一个Email客户端"));

播放多媒体

Intent it = new Intent(Intent.ACTION_VIEW);  
Uri uri = Uri.parse("file:///sdcard/nobody.mp3");  
it.setDataAndType(uri, "audio/mp3");  
startActivity(it);  
Uri uri = Uri.withAppendedPath(MediaStore.Audio.Media.INTERNAL_CONTENT_URI, "1"); //从系统内部的MediaProvider索引中调用播放  
Intent it = new Intent(Intent.ACTION_VIEW, uri);  
startActivity(it);     

Uninstall卸载程序

Uri uri = Uri.fromParts("package", packageName, null); //packageName为包名,比如com.android123.apkInstaller  
Intent it = new Intent(Intent.ACTION_DELETE, uri);  
startActivity(it);

进入联系人界面

Intent intent = new Intent();  
intent.setAction(Intent.ACTION_VIEW);  
intent.setData(People.CONTENT_URI);  
startActivity(intent);

查看某个联系人,当然这里是 ACTION_VIEW ,如果为选择并返回 action 改为 ACTION_PICK ,当然处理intent 时返回需要用到 startActivityforResult

Uri personUri = ContentUris.withAppendedId(People.CONTENT_URI, ID);//最后的ID参数为联系人Provider中的数据库BaseID,即哪一行  
 Intent intent = new Intent();  
 intent.setAction(Intent.ACTION_VIEW);  
 intent.setData(personUri);  
startActivity(intent);

选择一个图片

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);   
intent.addCategory(Intent.CATEGORY_OPENABLE); 
intent.setType("image/*");  
startActivityForResult(intent, 0);

参考:

Android开发学习笔记:Intent的简介以及属性的详解

基础总结篇之九:Intent应用详解

Android拍照,相册选择图片以及Android6.0权限管理

开启照相或者是从本地相册选中一张图片以后先裁剪在保存并显示

Android开发学习笔记:浅谈显示Intent和隐式Intent

使用Camera有两种方式:通过Intent使用已有的app和通过Camera构建自己的app。
Android Camera系列开发 (一): 通过Intent拍照
Android Camera系列开发 (二)通过Intent录制视频
Android Camera系列开发 (三): 通过CameraAPI拍照
Android 分享功能代码

Intent中Component使用

intent的component属性的作用是什么,如何定义此属性

第十章:Intent详解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值