- Intent对象可以实现页面的跳转
- Intent对象可以启动Service
- Intent对象可以发送广播
-
CompenentName:Intent目标组件的名称,它是一个ComponentName对象,由目标组件的完全限定类名和组件所在应用程序配置文件中的包名组合而成
如果设置,Intent对象会被发送给指定类的实例;如果没有,会使用Intent中其他信息来决定目标组件名可以使用setComponent()、setClass()或setClassName()方法设置,使用getComponent()
-
Action:动作,是一个字符串,用来表示要执行的动作,在广播中,Action用来表示已经发生即将报告的动作
在Intent类中,定义了一系列动作常量,目标组件包括Activity和Broadcast两类
- 标准Activity中intent的action:最常用的是ACTION_MAIN和ACTION_EDIT
- 广播Intent的action同窗使用Context.registerReceiver()方法或者配置文件中的receiver标签
使用时,要转换为相关字符串信息,将ACTION_MAIN转换为android.intent.action.MAIN
-
data:表示操作数据的URI和MIME类型。不同action与不同类型的数据孤帆匹配
例如能够显示图片数据的组件不应来播放音频,但是类型信息要显式地设置到Intent对象
-
setData()方法仅能指定数据的URI
-
setType()方法仅能指定数据的MIME类型
-
setDataAndType()方法可以同时设置URI和MIME类型
-
使用getData()方法可以读取URI,使用getType()方法可以读取MIME类型
-
-
Category:种类,字符串类型,包含了Intent组件类型的附加信息,在Intent对象中可以增加任意多个种类描述,定义了一些种类常量
以上清单文件设置为主页Activity设置页面,其中就有action和category两个属性,MAIN表示主页,LAUNCHER表示显示在最上层
-
Extras:一组键值对,包含传递给处理Intent组件的额外信息,通过putXXX和getXXX来使用
这些方法和Bundle对象有些类似
-
Flags:整数类型,用来表示不同来源的标记,多数用于指示Android系统如何启动Activity,以及启动后如何对待
所有的标记都定义在Intent类中
实现了一个简单的intent传值
IntentActivity
package com.thundersoft.session4;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Typeface;
import android.os.Bundle;
import android.text.InputType;
import android.view.View;
import android.view.inputmethod.EditorInfo;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import androidx.annotation.Nullable;
public class IntentActivity extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout linearLayout = new LinearLayout(this);
linearLayout.setOrientation(LinearLayout.VERTICAL);
setContentView(linearLayout);
EditText username = new EditText(this);
EditText password = new EditText(this);
Button submit = new Button(this);
submit.setText("提交");
username.setHint("用户名");
password.setHint("密码");
password.setInputType(InputType.TYPE_CLASS_NUMBER|InputType.TYPE_NUMBER_VARIATION_PASSWORD);
linearLayout.addView(username);
linearLayout.addView(password);
linearLayout.addView(submit);
submit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.putExtra("com.thundersoft.USERNAME",username.getText().toString());
intent.putExtra("com.thundersoft.PASSWORD",password.getText().toString());
intent.setClass(IntentActivity.this,MainActivity.class);
startActivity(intent);
}
});
}
}
MainActivity
package com.thundersoft.session4;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.Nullable;
public class MainActivity extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout linearLayout = new LinearLayout(this);
setContentView(linearLayout);
TextView textView = new TextView(this);
Intent intent = getIntent();
String username = intent.getStringExtra("com.thundersoft.USERNAME");
String password = intent.getStringExtra("com.thundersoft.PASSWORD");
textView.setText("用户名:"+username+",密码:"+password);
linearLayout.addView(textView);
}
}
这里使用intent.putExtra来进行传值,之前一直是使用的bundle传值,利用intent的putExtras方法
网上查阅之后发现bundle在多个页面直接传值效率更高,而intent的适用面更广
4.intent回到homeHomeActivity
package com.thundersoft.session4;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import androidx.annotation.Nullable;
public class HomeActivity extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout linearLayout = new LinearLayout(this);
setContentView(linearLayout);
Button button = new Button(this);
button.setText("Home");
linearLayout.addView(button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
// 设置动作和种类
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
startActivity(intent);
}
});
}
}
二、Intent使用
1.显示和隐式intent
显示intent
intent = new intent(FirstActivity.this,SecondActivity.class); startactivity(intent);
隐式intent
intent = new intent();
intent.setAction("com.thundersoft.session4.activitytest.ACTION_START");
startactivity(intent);
隐式intent只能在设置了intent过滤器之后才可以使用
但是显示在任何时候都可以使用
2.Intent过滤器intent过滤器设置在intent-filter中,但是不提供java的设置方式,只能使用该标签存在于清单文件内
在清单文件中,调用Context.registerReceiver()方法动态注册BroadcastReceiver的过滤器
对于隐式intent,过滤器通过三个方面来进行操作,动作数据和分类,只有通过了全部的条件,intent就会发送给有这些条件的组件
-
Action
intent-filter内至少应该包含一个action过滤标签,否则将阻塞所有的intent
-
category
在过滤器中可以添加额外的种类,但是不能删除原来的种类
默认需要添加android.intent.category.DEFAULT
-
data
data可以过滤scheme、host、port、path
样式分别是shceme://host:port/path
例如content:// com.example.project: 200 /folder/subfolder/etc
后面的属性如果要指定,一定要确定前面的属性,前面的属性具有统一性,比如制定了一种scheme,那么它的后面不管是什么样都能被过滤
-
type
使用“ * ”通配符包含子类型,不如“text/ * ”
intent对象必须至少指定URI或者数据类型且过滤器要有相同的指定才能通过
3.预定义动作实例ActionActivity
package com.thundersoft.session4;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import androidx.annotation.Nullable;
public class ActionActivity extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout linearLayout = new LinearLayout(this);
Button button = new Button(this);
button.setText("预定义intent点击");
linearLayout.addView(button);
setContentView(linearLayout);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
startActivity(intent);
}
});
}
}
BctionActivity
package com.thundersoft.session4;
import android.app.Activity;
import android.os.Bundle;
import android.widget.LinearLayout;
import android.widget.TextView;
import androidx.annotation.Nullable;
public class BctionActivity extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout linearLayout = new LinearLayout(this);
setContentView(linearLayout);
TextView textView = new TextView(this);
textView.setText("使用预定义动作的隐式intent");
linearLayout.addView(textView);
}
}
清单文件如下
这里过滤器过滤的action为ACTION_VIEW
左右包含其的组件都会被调用
其中android:exported="true"是sdk版本是31是必须要加载时的属性,它表示
当前Activity是否可以被另一个Application的组件启动:true允许被启动;false不允许被启动。
4.自定义动作实例设置action如下
intent.setAction("action_test");
xml如下即可
点击直接进行跳转,因为只有结果页面符合过滤器标准,所以没有选择界面
三、Intent实例 1.url跳转实例package com.thundersoft.session4;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import androidx.annotation.Nullable;
public class TestActivity extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout linearLayout = new LinearLayout(this);
setContentView(linearLayout);
Button button = new Button(this);
button.setText("start uri test");
linearLayout.addView(button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Uri parse = Uri.parse("http://www.baidu.com");
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
intent.setData(parse);
startActivity(intent);
}
});
}
}
2.电话拨打实例
package com.thundersoft.session4;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import androidx.annotation.Nullable;
public class Test2Activity extends Activity {
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout linearLayout = new LinearLayout(this);
EditText editText = new EditText(this);
editText.setHint("输入电话号码");
final String s = editText.getText().toString();
Button button = new Button(this);
button.setText("拨打");
linearLayout.addView(editText);
linearLayout.addView(button);
linearLayout.setOrientation(LinearLayout.VERTICAL);
setContentView(linearLayout);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_CALL);
intent.setData(Uri.parse("tel:" + s));
startActivity(intent);
}
});
}
}
以及在清单文件中的电话权限
如果是虚拟机,还需要再设置内添加权限
四、实践 1.要求实现一个登录页面,提供记住密码和用户名功能,登陆后显示列表视图必须包含登录用户名,且点击列表会显示点击那一项
登录后主界面列表选择第一个选项后,显示一组图片,图片加载完成前需要显示进度条,加载完成后,长按某一个图片弹出提示框是否删除,如果确定就不再显示该图片
登录后主界面列表选择第二个选项后,跳转到另一个Activity,并且传过去一个字符串,在新的Activity中包含2个Fragment,左边的Fragment类似手机设置,含一个亮度设置选项,点击后右边的Fragment显示具体的亮度设置界面
(以上是Android 五 当中的实践要求)
在之前的基础上,登录后主界面列表选择第三个选项后,跳转到另一个Activity,并且传过去int/byte/Serializable等多种类型的数据,在新的Activity中显示传入的数据,检查是否所传所有类型的数据都正确接收,同时在Activity启动的时候开始监听android.net.conn.CONNECTIVITY_CHANGE,Activity退出后不再监听,当网络状态改变的时候提示用户网络状态改变情况。
2.代码实现MainActivity需要改动的部分
if (index == 3){
User user = new User();
user.setName(name);
user.setPwd(pwd);
Intent intent = new Intent();
intent.putExtra("int",aInt)
.putExtra("byte",aByte)
.putExtra("ser",user);
intent.setClass(MainActivity.this,WebListenerActivity.class);
startActivity(intent);
}
这之中将login的name和pwd拿了过来
String name = "";
String pwd = "";
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 拿到数据
Intent intent = getIntent();
name = intent.getStringExtra("name");
pwd = intent.getStringExtra("pwd");
....
因为要传递序列化对象,这里新建了一个实体类
由于题目要求是传递serializable数据,于是最开始的创建实体类 implement Serializeble
但是总是出现,Parcelable encountered IOException writing serializable object异常,网上搜索后发现实体类里的其他自定义成员变量也需要实现serializable接口,可是String源码里也已经是实现了,实在没有办法只能继承Parcelable接口
package com.thundersoft.login;
import android.os.Parcel;
import android.os.Parcelable;
public class User implements Parcelable {
private String pwd;
private String name;
public User() {
}
public User(Parcel in) {
pwd = in.readString();;
name = in.readString();
}
//接口描述,默认为0即可
@Override
public int describeContents() {
return 0;
}
//將数据写入Parcel容器,由Parcel容器保存,以便从parcel容器获取数据
@Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(pwd);
dest.writeString(name);
}
//静态的Parcelable.Creator接口
public static final Parcelable.Creator CREATOR = new Parcelable.Creator(){
//实现从Parcel容器中读取传递数据值,封装成Parcelable对象返回逻辑层
@Override
public User createFromParcel(Parcel source) {
return new User(source);
}
//仅一句话即可(return new T[size]),供外部类反序列化本类数组使用。
@Override
public User[] newArray(int size) {
return new User[size];
}
};
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
传输过去的界面代码如下
WebListenerActivity.java
package com.thundersoft.login;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.view.Gravity;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.Nullable;
public class WebListenerActivity extends Activity {
private NetworkChange networkChange;
private final static String ACTION_CHANGE = "android.net.conn.CONNECTIVITY_CHANGE";
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LinearLayout linearLayout = new LinearLayout(this);
linearLayout.setOrientation(LinearLayout.VERTICAL);
linearLayout.setGravity(Gravity.CENTER);
setContentView(linearLayout);
TextView textView1 = new TextView(this);
TextView textView2 = new TextView(this);
TextView textView3 = new TextView(this);
Intent intent = getIntent();
int aInt = intent.getIntExtra("int",0);
byte aByte = intent.getByteExtra("byte", (byte) 0);
User user = intent.getParcelableExtra("ser");
textView1.setText("int数据为:"+aInt);
textView2.setText("byte数据为:"+aByte);
textView3.setText("Serializable数据为:name:"+user.getName()+" pwd:"+user.getPwd());
textView1.setTextSize(20);
textView2.setTextSize(20);
textView3.setTextSize(20);
linearLayout.addView(textView1);
linearLayout.addView(textView2);
linearLayout.addView(textView3);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ACTION_CHANGE);
networkChange = new NetworkChange();
registerReceiver(networkChange,intentFilter);
}
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(networkChange);
}
class NetworkChange extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();//获取网络状态
if (activeNetworkInfo != null && activeNetworkInfo.isAvailable()) {
Toast.makeText(WebListenerActivity.this, "已连网!", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(WebListenerActivity.this, "已断网!", Toast.LENGTH_LONG).show();
}
}
}
}
- 传值问题:intent通过intent.getParcelableExtra拿到序列化对象进行操作
- 网络监听问题:通过广播,将对象和过滤器一起注册,具体原理后期会学到



