Intent 分为显式Intent和隐式Intent
2.3.1显式Intent
Intent intent = new Intent(FirstActivity.this,SecondActivity.class);
startActivity(intent);
2.3.2隐式Intent
代码中
Intent intent = new Intent("co.example.hanwei.test.ACTION_A");
intent.addCategory("android.intent.category.MY_CATEGORY");
startActivity(intent);
在<action>标签中我们指明了当前活动可以响应”co.example.hanwei.test.ACTION_A“这个 action,而< category>标签则包含了一些附加信息,更精确地指明了当前的活动能够响应的 Intent中还可能带有的 category。
只有< action>和< category>中的内容同时能够匹配上 Intent中指定的 action和 category时,这个活动才能响应该 Intent。
前面不是说要< action>和< category>同时匹配上才能响应的吗?怎么没看到哪里有指定category呢?这是因为 android. intent, category. DEFAULT是一种默认的 category,在调用 startActivity()方法的时候会自动将这个 category添加到 Intent中。
每个 Intent中只能指定一个 action,但却能指定多个 category。目前我们的 Intent中只有一个默认的 category,那么现在再来增加一个吧。
AndroidManifest.xml中
<activity android:name=".SecondActivity">
<intent-filter>
<action android:name="co.example.hanwei.test.ACTION_A"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.MY_CATEGORY"/>
</intent-filter>
</activity>
在代码中使用addCategory()添加category,同事也要在清单文件中添加相对应的category,否则会报错。
2.3.3更多隐式Intent的用法
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse("http://www.baidu.com"));
startActivity(intent);
打开系统浏览器访问网址
与此对应,我们还可以在< intent- filter>标签中再配置一一个<data>标签,用于更精确地指定当前活动能够响应什么类型的数据。<data>标签中主要可以配置以下内容:
android: scheme。用于指定数据的协议部分,如上例中的htp部分。
android:host。用于指定数据的主机名部分,如上例中的wwW.baidu.com部分
android:port。用于指定数据的端口部分,一般紧随在主机名之后
android:path。用于指定主机名和端口之后的部分,如一段网址中跟在域名之后的内容。
android: mimeType。用于指定可以处理的数据类型,允许使用通配符的方式进行指定。
只有<data>标签中指定的内容和 Intent中携带的Data完全一致时,当前活动才能够响应该Intent。不过一般在<data>标签中都不会指定过多的内容,如上面浏览器示例中,其实只需要指定 android: scheme为htp,就可以响应所有的htp协议的 Intent了。
<intent-filter>
<action android:name="co.example.hanwei.test.ACTION_A"/>
<category android:name="android.intent.category.DEFAULT"/>
<category android:name="android.intent.category.MY_CATEGORY"/>
<data android:scheme="http"
</intent-filter>
2.3.4向下一个活动传递数据
String data = "2018年7月18日";
Intent intent = new Intent("co.example.hanwei.test.ACTION_A");
intent.putExtra("extra_data",data);
startActivity(intent);
传递方通过putExtra()方法传递了一个字符串,该方法接收两个参数,第一个是键,用于后面Intent中取值,第二个参数是需要传递的数据
Intent intent = getIntent();
String data = intent.getStringExtra("extra_data");
Toast.makeText(SecondActivity.this,data,Toast.LENGTH_SHORT).show();
接收方通过getIntent()方法获取用于启动接收方活动的Intent然后调用getStringExtra()方法传入相应的键值,取出传递的数据。getStringExtra()方法并不固定,跟随传入的数据类型而变化。
2.3.5返回数据给上一个活动
activity还有一个startActivityForResult()用于启动活动的同时,还具备在活动销毁的时候能够返回一个结果给上一个活动。
Intent intent = new Intent("co.example.hanwei.test.ACTION_A");
startActivityForResult(intent,5);
使用startActivityForResult()来启动下一个活动,请求码只要是一个唯一值就可以了,这里传入了5。
我们在第二个活动中给点击事件添加返回数据的逻辑:
String data = "2018年7月18日";
Intent intent = new Intent();
intent.putExtra("data_return",data);
setResult(RESULT_OK,intent);
finish();
调用setResult()非常重要,专门用于想上一个活动返回数据,此方法接受两个参数,,第一个参数用于向上一个活动返回处理结果,一般使用RESULT_OK或者RESUIT_CANCELED,第二个就是把带有数据的Intent传递回去,,然后调用finish()来销毁活动。
我们是用startActivityForResult()来启动当第二个活动,当这个活动销毁后会回调上一个活动的onActivityResult(),所以我们要在第一个活动中重写这个方法来得到返回数据。
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode){
case 5:
if (resultCode == RESULT_OK){
String returndata = data.getStringExtra("data_return");
Toast.makeText(FirstActivity.this,returndata,Toast.LENGTH_SHORT).show();
}
break;
default:
}
}
onActivityResult()有三个参数requestCode:启动活动时传入的请求码 resultCode:活动返回的处理结果data:携带者返回数据的Intent。
再由另一种可能,在第二个活动中,可能是按返回键,回到第一个活动,我们在第二果活动中重写onBreakPressed()方法:
@Override
public void onBackPressed() {
String data = "2018年7月18日";
Intent intent = new Intent();
intent.putExtra("data_return",data);
setResult(RESULT_OK,intent);
finish();
}