Android中最重要的特征之一就是可以利用一个带有action的intent 使当前app跳转到其它app, 例如我们的app有一个地址想要显示在地图上,我们并不需要在app中创建一个activity来显示地图,而是使用intention来发出查看地址的请求, Android系统会启动能显示地图的程序来呈现该地址。
一 . 建立隐式Intent
隐式Intention并不需要声明组建的具体类名, 而是声明一个需要启动的action, 这个action指定了我们想要做的事情, 同时Intent会在发送action的同时附带一些数据, 数据的具体类型取决于我们想要创建的intent, 比如uri类型或者其他类型的数据。
启动一个带有电话号码的Intent
Uri number = Uri.parse("tel:5551234"); Intent callIntent = new Intent(Intent.ACTION_DIAL, number);查看地图
Uri location = Uri.parse ("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California"); // Or map point based on latitude/longitude // Uri location = Uri.parse("geo:37.422219,-122.08364?z=14"); // z param is zoom level Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);查看网页
Uri url = new Uri(“http://www.baidu.com”) Intent intent = new Intent(Intent.ACTION_VIEW, url);发送一个带附件的enail
Intent emailIntent = new Intent(Intent.ACTION_SEND); // The intent does not have a URI, so declare the "text/plain" MIME type emailIntent.setType(HTTP.PLAIN_TEXT_TYPE); emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"[email protected]"}); // recipients emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Email subject"); emailIntent.putExtra(Intent.EXTRA_TEXT, "Email message text");
二 . 验证是否有app去接收这个Intent
为了验证是否有合适的activity会响应这个intent, 需要执行queryIntentActivities()来获得所有接收这个intent的activity集合。若返回的List非空我们才可以安全的使用这个Intent。例如 :
PackageManager manager = new PackageManager(); List<ResolveInfo> activities = manager.queryIntentActivity(intent, 0); Boolean isSafety = activities.size() > 0;使用Intent启动activity
Uri location = Uri.parse ("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California"); Intent mapIntent = new Intent(Intent.ACTION_VIEW, location); PackageManager packageManager = getPackageManager(); List<ResolveInfo> activities = packageManager.queryIntentActivities(mapIntent, 0); boolean isIntentSafe = activities.size() > 0; if (isIntentSafe) { startActivity(mapIntent); }
三 . 显示分享app的选择界面
当以startActivity()的形式传递一个Intent并且多个app可以handle时,用户可以在弹出dialog界面时选择启动的app,为了显示chooser, 需要使用createChooser()来创建intent
Intent intent = new Intent(Intent.ACTION_SEND); ………… Intent chooser = Intent.createChooser(intent, “Title”); startActivity(chooser);
四 . 接收Activity返回的结果
启动另外一个Activity并不一定是单向的,我们可以启动另外一个Activity然后接收一个返回的result,我们需要使用startActivityForResult();当然被启动的activity需要指定返回的result, 它需要把这个result作为一个Intent对象返回activity需要在onActivityResult()的回调方法里面去接收result;
该方法有三个参数, 1.通过startActivity传递的request code, 2.Activity指定的result code,如果操作成功则是RESULT_OK,如果没有成功或者中途返回则是返回RESULT_CANCELED, 3.包含了result数据的intent。
final int request = 0x000; Intent intent = new Intent(Intent.ACTION_DIAL, Uri.parse("tel:123456")); startActivityForResult(intent, request); protected void onActivityResult(int requestCode, int resultCode, Intent intent){ if(requestCode == request){ if(resultCode == RESULT_OK){ /** * doing something */ } } }
五 . Intent过滤
如果我们的app的功能对别的app也有用,那么其应该做好响应的准备。例如,如果创建了一个social app,它可以分享messages 或者 photos 给好友,那么最好我们的app能够接收ACTION_SEND
的intent,这样当用户在其他app触发分享功能的时候,我们的app能够出现在待选对话框。
通过在manifest文件下的<activity>标签下添加<intent-filter>属性,其它的app就能启动我们的activity。当app被安装到设备上时,系统可以识别Intent filter并把这些信息记录下来,当其它app使用隐式Intent执行startActivity或者startActivityForResult时系统可以自动查出那些可以响应该intent的activtiy
Action : 一个想要执行的动作的名称。通常是系统已经定义好的值,如ACTION_SEND
或ACTION_VIEW
。 在intent filter中通过<action>
指定它的值,值的类型必须为字符串
Data : Intent附带数据的描述。在intent filter中通过<data>
指定它的值,可以使用一个或者多个属性,我们可以只定义MIME type或者是只指定URI prefix,也可以只定义一个URI scheme,或者是他们综合使用。
Category :提供一个附加的方法来标识这个activity能够handle的intent。通常与用户的手势或者是启动位置有关。系统有支持几种不同的categories,但是大多数都很少用到。而且,所有的implicitintents都默认是CATEGORY_DEFAULT类型的。在intentfilter中用<category>指定它的值。
返回result
如果要返回一个result给启动的那个activity ,仅仅需要执行setResult(),通过一个resultCode和result intent,操作完成之后用户需要返回原来的activityt通过执行finish()返回到原来的activity。
Intent result =
newIntent(
"com.example.RESULT_ACTION", Uri.parse(
"content://result_uri");
setResult(Activity.RESULT_OK, result);
finish();
如果只想返回一个
int
来表示返回的
result
,只需要在
setResult()
中传入数据就可以了
setResult(R.xxx)