【Android】安卓四大组件之Activity(一)

【Android】安卓四大组件之Activity(一)

前言

Activity是Android学习中的一个重要组件,想要对其进行系统的了解可以分为几块内容,这一大章节的内容是有关于activity之间的页面跳转和数据传递,之后还有activity中的生命周期讲解。

1、认识AndroidManifest.xml

一个Manifest.xml最外层用manifest标签包裹,下面可以是application,当然我们之前也学过uses-permission,可以与application同级

application中设置属性,allowBackup是允许备份,icon是app图标,label是app的名字,roundIcon是圆角app图标,supportsRtl是声明你的application是否愿意支持从右到左(原来RTL就是right-to-left 的缩写...)的布局。theme当然就是主题啦!

Rtl到底是个啥玩意?有没有在QQ中见过使用阿拉伯语的,使用这些语言都是从右向左读的,所以需要从右向左适配。就是这样!

activity就是这次学习的重点,是一个活动,也可以当作不同的活跃页面(大致理解),我们app中不同的界面就可以通过activity之间的跳转实现!

至于intent-filter,就是一个意图过滤器,其中的action就是activity进行的一个action,而category可以理解为这个意图的类别,我们APP的主界面的category就是LAUNCHER

【Android】安卓四大组件之Activity(一)

2、如何实现activity之间的跳转?

我们可以使用startActivity()方法或者startActivityForResult()方法来跳转页面,这一小节就只讲startActivityintent配合使用进行数据单项传递,在第4小节回讲到如何使用startActivityForResult进行数据回传

2.1 通过显式Intent来跳转同一个APP中的activity

显式Intent:按照名称(完全限定了类名)来指定要启动的组件。

可以看到下面的xml中注册了两个activity分别对应两个activity类

<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Hello">
<activity
android:name=".QQLoginActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".QQLoginSuccessActivity"/>
</application>

需要注意的是,创建显式Intent启动Activity,系统将立刻启动Intent对象中指定的应用组件。

那么我来实际操作一个例子看看显式Intent如何跳转!

我们写一个登录页面的跳转测试用例,如果登录成功,就跳转到另一个activity页面中显示登录的信息!

第一个页面:登录界面xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:background="@mipmap/bk"> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="70dp"
android:padding="30dp"
android:orientation="vertical"> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="@mipmap/ic_launcher_round"
android:text="QQ"
android:textSize="40sp"/>
<EditText
android:id="@+id/et_account"
android:layout_marginTop="25dp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:textColor="@color/white"
android:hint="QQ号/手机号/邮箱"/> <EditText
android:password="true"
android:id="@+id/et_pwd"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:hint="密码"
android:textColor="@color/white"
tools:ignore="Deprecated" /> <Button
android:id="@+id/bt_login"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="登陆"
android:textSize="20sp"/> <RelativeLayout
android:layout_marginTop="15dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="忘记密码"
android:textSize="16dp"
android:textColor="#87C6F8"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:text="新用户注册"
android:textSize="16dp" android:textColor="#87C6F8"/> </RelativeLayout> </LinearLayout> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="50dp"
android:text="登录即代表阅读并同意服务条款"
android:textColor="#CCCFCF"
android:textSize="20sp" /> </RelativeLayout>

对应的activity java类

package top.woodwhale.hello;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast; import androidx.annotation.Nullable; public class QQLoginActivity extends Activity implements View.OnClickListener { private EditText account;
private EditText passwd;
private Button login; @Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.qq_login_layout);
initViews();
} private void initViews() {
account = this.findViewById(R.id.et_account);
passwd = this.findViewById(R.id.et_pwd);
login = this.findViewById(R.id.bt_login);
// 添加监听器
login.setOnClickListener(this);
} @Override
public void onClick(View v) {
if (v == login && login != null) {
String ac = account.getText().toString();
String pwd = passwd.getText().toString();
if (TextUtils.isEmpty(ac)) {
Toast.makeText(this, "账号不能为空", Toast.LENGTH_SHORT).show();
return;
}
if (TextUtils.isEmpty(pwd)) {
Toast.makeText(this,"密码不能为空", Toast.LENGTH_SHORT).show();
return;
}
// 如果都填写正确,那么跳转
Intent intent = new Intent(this,QQLoginSuccessActivity.class);
intent.putExtra("ac",ac);
intent.putExtra("pwd",pwd);
// 当前act跳转到目的act中,也就是登录成功界面
this.startActivity(intent);
}
}
}

这一部分是跳转实现的代码:

【Android】安卓四大组件之Activity(一)

new一个intent,然后如果需要设置键值对信息,就使用putExtra()方法设置键值对,最后调用当前activity类中的startActivity()方法跳转到下一个activity中!

第二个页面:登录成功xml

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"> <Button
android:id="@+id/bt_ac_and_pwd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:text="账号:*** 密码:###"/> </FrameLayout>

对应的activity java类

package top.woodwhale.hello;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button; import androidx.annotation.Nullable; public class QQLoginSuccessActivity extends Activity { private Button btn; @Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.frame_layout); Intent intent = getIntent();
String ac = intent.getStringExtra("ac");
String pwd = intent.getStringExtra("pwd");
btn = findViewById(R.id.bt_ac_and_pwd);
btn.setText(btn.getText().toString().replace("***",ac).replace("###",pwd));
}
}

这里通过getStringExtra()方法获取之前activity中我们设置的键值对

【Android】安卓四大组件之Activity(一)

测试效果:

【Android】安卓四大组件之Activity(一)

效果完成!

2.2 通过隐式Intent来跳转同一个APP中的activity

隐式Intent:不会指定特定的组件,而是会声明要执行的组件,从而允许其他应用中的组件来处理它。

举个例子,我们现在要调用一个app中的另一个页面,使用隐式意图的方式,可以这样:

// 隐式意图进行跳转
Intent intent = new Intent();
intent.setAction("top.woodwhale.qqlogin.LOGIN_INFO");
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.putExtra("ac",ac);
intent.putExtra("pwd",pwd);
this.startActivity(intent);

使用setAction()的方法,将action设置了,这里的action是什么呢?

我们看看最开始的manifest.xml

<activity
android:name=".QQLoginActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity> <activity android:name=".QQLoginSuccessActivity">
<intent-filter>
<action android:name="top.woodwhale.qqlogin.LOGIN_INFO"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>

这里我们与显式意图不同,我们变更了QQLoginSuccessActivity这个activity中的<intent-filter>,也就是意图过滤器,我们在其中的action中设置了一个nametop.woodwhale.qqlogin.LOGIN_INFO,而与我们java代码中的intent.setAction("top.woodwhale.qqlogin.LOGIN_INFO");对应!并且category也是一样,使用的是DEFAULT,也与intent.addCategory(Intent.CATEGORY_DEFAULT);对应。

通过这样的intent的设置方式,我们其实就是将这个Intent对象设置成为了QQLoginSuccessActivity这个activity!

2.3 通过显式Intent跳转到其他APP

我们在使用浏览器访问知乎、csdn等网页的时候,是不是会让我们跳转到APP内使用?其实这就是不同app之间的跳转,也就是通过浏览器这个app跳转到了csdn这个app

上述的跳转操作也可以通过Intent实现,我们首先用显式Intent实现:

比如我现在点击登录,需要跳转到Chrome这个app中,那么显式Intent需要知道Chrome这个app的packageName和一个activity的className。我们可以使用logcat来抓取这两个String值,如下图所示:

首先选择system_process系统进程,在搜索cmp也就是ComponentName 的缩写。然后在avd上打开Chrome,logcat就可以抓取到啦

【Android】安卓四大组件之Activity(一)

那么我们跳转的核心代码就是:

Intent intent = new Intent();
intent.setClassName("com.android.chrome","com.google.android.apps.chrome.Main");
this.startActivity(intent);

当然,你也可以这样,通过ComponentName作为中间件

Intent intent = new Intent();
ComponentName cmp = new ComponentName("com.android.chrome","com.google.android.apps.chrome.Main");
intent.setComponent(cmp);
this.startActivity(intent);

测试一下

【Android】安卓四大组件之Activity(一)

2.4 通过隐式Intent跳转到其他APP

一般跳转到其他APP都是使用隐式Intent来完成的,而Intent类中已经很多的常量给我们选择APP

比如Intent.ACTION_DIAL就是电话拨号action,而我们使用setData()方法,给一个tel的值,那么就会拨号这个号码,注意setData中传递的参数是Uri类型的,需要使用Uri.parse()方法转化一下格式

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

那么这样的效果就是如下图所示:

【Android】安卓四大组件之Activity(一)

2.5 对Intent的总结:

显式Intent的常见方法:

  • setClass( Context packageContext, Class ClassNmae.class), 此方法不能实现跨应用调用
  • setClass( String packageName, String classname ), 此方法能够实现跨应用调用
  • setComponent(ComponentName component),此方法能够实现跨应用调用

隐式Intent的常见方法:

  • setAction(String action)
  • addCategory(String category)
  • setData(Uri data)

当然,Intent用的最多的是putExtra()方法,可以传递Extra的数据!

总结一下,隐式Intent和显式Intent的区别是什么呢?

  • 显式Intent需要给出指定的class,也就是限定了类名
  • 隐式Intent需要给出action、category,可以隐式的调用其他activity

说的直白一点:隐式Intent通过给出的action和category来与特定的activity对应起来,而显式Intent就是指定了一个activity.class

那么,什么情况用什么Intent呢?

  • 显示Intent一般用来完成同一个APP之间的跳转
  • 隐式Intent一般用来完成调用其他APP
  • 上述并非绝对,显示Intent也能完成不同APP跳转,隐式Intent也能完成同一个APP内的跳转

3、activity之间的数据如何单向传递?

这里说的传递数据就是分为两种,一种普通数据,另一种是对象数据

对于activity之间的数据传递,都是通过Intent中的putExtra()方法实现,或者setData()方法实现

putExtra其实就是将一个键值对放入了intent对象中,取出这个值就通过getXXXExtra()方法就可以实现

setData其实是给了在intent-filter中设置的data属性一个数据

下面我们就来讲讲这两种方式如何传递数据!

3.1 putExtra()方法传递

3.1.1 普通数据传输

对于普通的数据类型:

// 隐式意图进行跳转
String ac = account.getText().toString();
String pwd = passwd.getText().toString();
Intent intent = new Intent();
intent.setAction("top.woodwhale.qqlogin.LOGIN_INFO");
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.putExtra("ac",ac);
intent.putExtra("pwd",pwd);
this.startActivity(intent);

我们传递了两个String的数据,在上述隐式intent的目标LOGIN_INFO的activity类中,可以这样接收数据,通过getStringExtra()方法

Intent intent = getIntent();
String ac = intent.getStringExtra("ac");
String pwd = intent.getStringExtra("pwd");
btn = findViewById(R.id.bt_ac_and_pwd);
btn.setText(btn.getText().toString().replace("***",ac).replace("###",pwd));

同理,可以putExtra各种普通数据——int、boolean等等

3.1.2 对象数据传输

对于传递对象,在putExtra()方法中有两个重载方法可以实现:

putExtra(String name, Parcelable value)

putExtra(String name, Serializable value)

【Android】安卓四大组件之Activity(一)

这两个方法的第二个参数就有讲究了。

首先,说说Serializable,这个是Java中的序列化类,它是JDK1.1就诞生的接口,用于标识可序列化,在非安卓程序中也是非常常见的存在。

所谓序列化就是一种压缩,可以理解成一个对象压缩成JSON的那种形式,只不过在JVM中处理肯定不是JSON的格式

序列化之后的对象可以通过反序列化得到原来的对象

我们对该接口的描述进行翻译一下:

【Android】安卓四大组件之Activity(一)

【Android】安卓四大组件之Activity(一)

【Android】安卓四大组件之Activity(一)

其次,就是这个没见过的Parcelable,这个类是Google自己实现的,也是用来进行压缩内存的,效率方面比Serializable高。

我们对这个接口的描述进行翻译:

【Android】安卓四大组件之Activity(一)

【Android】安卓四大组件之Activity(一)

所以如果我们需要对一个对象进行activity之间的传递,可以让这个对象所属的类使用上述两种接口之一,就好啦!

我们这里使用Pracelable接口实现一个User类

package top.woodwhale.hello;

import android.os.Parcel;
import android.os.Parcelable; public class User implements Parcelable {
String username;
String password; public User(String username, String password) {
this.username = username;
this.password = password;
} public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public String getPassword() {
return password;
} public void setPassword(String password) {
this.password = password;
} protected User(Parcel in) {
username = in.readString();
password = in.readString();
} public static final Creator<User> CREATOR = new Creator<User>() {
@Override
public User createFromParcel(Parcel in) {
return new User(in);
} @Override
public User[] newArray(int size) {
return new User[size];
}
}; @Override
public int describeContents() {
return 0;
} @Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(username);
dest.writeString(password);
}
}

我们对一个activity进行传输一个user对象:

// 隐式意图进行跳转
Intent intent = new Intent();
intent.setAction("top.woodwhale.qqlogin.LOGIN_INFO");
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.putExtra("user1",new User("woodwhale","1234567"));
this.startActivity(intent);

我们需要传递的activity类如下:

public class QQLoginSuccessActivity extends Activity {

    private Button btn;

    @Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.frame_layout); Intent intent = getIntent();
User user1 = intent.getParcelableExtra("user1");
String ac = user1.getUsername();
String pwd = user1.getPassword();
btn = findViewById(R.id.bt_ac_and_pwd);
btn.setText(btn.getText().toString().replace("***",ac).replace("###",pwd));
}
}

效果如下:

【Android】安卓四大组件之Activity(一)

3.2 intent-filter中设置data

还记不记得,在上面的隐式Intent跳转电话拨打电话例子中提到了——Intent对象有一个setData(Uri data)的方法呢?这里的set后的的data为什么可以设置和获取到呢

其实,在manifest.xml中的activity的intent-filter中,除了常见的actioncategory,还有一个data标签,可以用来设置intent对象中传输的data,还有不同的数据形式,我们这里就使用scheme就可以了

<activity android:name=".QQLoginSuccessActivity">
<intent-filter>
<action android:name="top.woodwhale.qqlogin.LOGIN_INFO"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:scheme="ac"/>
</intent-filter>
</activity>

只要设置了如上的data标签,我们给指向QQLoginSuccessActivity的intent对象,使用intent.setData(Uri.parse("ac:1008611"));这样的方法,就可以给这个intent传递ac的数据。

那么在QQLoginSuccessActivity,如何接受ac的数据呢?

使用intent.getData()就可以返回一个Uri对象,toString()一下就可以得到ac了

部分核心代码:

登录activity

 // 隐式意图进行跳转
Intent intent = new Intent();
intent.setAction("top.woodwhale.qqlogin.LOGIN_INFO");
intent.addCategory(Intent.CATEGORY_DEFAULT);
intent.setData(Uri.parse("ac:"+ac));
intent.putExtra("pwd",pwd);
this.startActivity(intent);
this.finish();

登录成功activity

Intent intent = getIntent();
String pwd = intent.getData().toString();
btn = findViewById(R.id.bt_ac_and_pwd);
btn.setText(pwd);

效果如下:

【Android】安卓四大组件之Activity(一)

4、activity之间的数据如何回传(双向传递)?

与单向传递信息不同,双向信息的传递也很常见,这就好比我们访问页面,访问之后页面会返回一个状态码,根据这个状态码我们可以知道访问的结果是什么,例如200就是访问成功,404就是找不到资源...

而在不同的activity之间,我们也可以进行数据回传,即——可以将第一个activity页面的数据传递给第二个activity进行处理,而第二个activity处理完的结果可以返回给第一个activity进行使用!

那么如何进行数据回传呢?我们可以使用自己重写的onActivityResult()方法,在其中判断requestCode来判断是哪个页面的回传,并且通过传递来的resultCode和intent对象,进行不同情况的数据读取。

4.1 登录信息返回的例子

举个例子:

我们现在需要验证自己登录的账号是否是管理员或账号,管理员账号密码分别是root123456,如果登录的账号和密码出现不匹配,就不是管理员。

如果登陆后是管理员,返回界面会弹出一个Taost,显示你是管理员!,否则弹出你不是管理员!

那么如何实现代码呢?

我们的QQLoginActivity,也就是登录页面

public class QQLoginActivity extends Activity implements View.OnClickListener {

    private static final String TAG = "QQLoginActivity";
private EditText account;
private EditText passwd;
private Button login; @Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.qq_login_layout);
initViews();
} private void initViews() {
account = this.findViewById(R.id.et_account);
passwd = this.findViewById(R.id.et_pwd);
login = this.findViewById(R.id.bt_login);
// 添加监听器
login.setOnClickListener(this);
} @Override
public void onClick(View v) {
if (v == login && login != null) {
String ac = account.getText().toString();
String pwd = passwd.getText().toString();
if (TextUtils.isEmpty(ac)) {
Toast.makeText(this, "账号不能为空", Toast.LENGTH_SHORT).show();
return;
}
if (TextUtils.isEmpty(pwd)) {
Toast.makeText(this,"密码不能为空", Toast.LENGTH_SHORT).show();
return;
} // 显式Intent
Intent intent = new Intent(this,QQLoginSuccessActivity.class);
intent.putExtra("ac",ac);
intent.putExtra("pwd",pwd);
// 传给 QQLoginSuccessActivity 这个activity的请求码是 1
this.startActivityForResult(intent,1);
// ...
// 我们可以给不同的activity设置不同的请求码,最后通过请求码判断是哪个act传回的数据
}
} @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// 从当前activity跳转到其他activity的请求码
if (requestCode == 1) {
Log.i(TAG,"从QQLoginSuccessActivity回传");
if (resultCode == 0) {
Log.i(TAG,"登录失败");
Toast.makeText(this, data.getStringExtra("fail"), Toast.LENGTH_SHORT).show();
} else if (resultCode == 1) {
Log.i(TAG,"登录成功");
Toast.makeText(this, data.getStringExtra("success"), Toast.LENGTH_SHORT).show();
}
}
}
}

我们的QQLoginSuccessActivity,也就是登录成功页面

public class QQLoginSuccessActivity extends Activity implements View.OnClickListener {

    private Button btn;
private String ac;
private String pwd; @Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.frame_layout);
initButtonOnclick();
} private void initButtonOnclick() {
Intent intent = getIntent();
ac = intent.getStringExtra("ac");
pwd = intent.getStringExtra("pwd");
btn = findViewById(R.id.bt_ac_and_pwd);
btn.setText(btn.getText().toString().replace("***", ac).replace("###", pwd)); btn.setOnClickListener(this);
} @Override
public void onClick(View v) {
Intent retIntent = new Intent();
if (ac.equals("root") && pwd.equals("123456")) {
retIntent.putExtra("fail","你是管理员!");
// 将信息回传
setResult(0,retIntent);
} else {
retIntent.putExtra("success","你不是管理员!");
// 将信息回传
setResult(1,retIntent);
} // 关闭当前页面
finish();
}
}

核心代码我们来分析一下:

首先是QQLoginActivity页面的startActivityForResult,设置了一个传递过去的intent,又设置了一个requestCode为1,表明我们对QQLoginSuccessActivity的请求码是1,我们传递了一个ac和pwd的String类型。

【Android】安卓四大组件之Activity(一)

跳转到QQLoginSuccessActivity页面后,我们点击按钮设置了回传信息,不同状态返回不同的信息

【Android】安卓四大组件之Activity(一)

返回后在QQLoginActivity执行我们重写onActivityResult()方法,判断requestCode,如果是1,那么就是给QQLoginSuccessActivity的请求返回,而返回结果是resultCode,如果是0,那么登陆失败,反之成功。

【Android】安卓四大组件之Activity(一)

效果如下:

【Android】安卓四大组件之Activity(一)

4.2 拍摄图片返回的例子

我们先带入一个场景——使用QQ或者微信的时候,点击“拍摄”选项,会调出一个相机进行拍照,然后将拍完的照片发送给好友。

那么这其实也是一个常见的信息回传,首先调用系统相册拍摄相片,之后再将拍摄好的相片进行一个回传发送

我们现在来模拟一下这样的场景——点击一个按钮调用系统的相机,如果拍照成功,就返回并且在原来的页面显示我们拍摄的相片,如果失败就Taost一个取消或者失败的反馈。

首先建立layout布局页面xml,非常的简单的布局

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"> <ImageView
android:id="@+id/iv_pic"
android:layout_width="match_parent"
android:layout_height="match_parent"/> <TextView
android:id="@+id/tv_photograph"
android:layout_width="60dp"
android:height="60dp"
android:layout_centerInParent="true"
android:layout_alignParentBottom="true"
android:layout_marginBottom="40dp"
android:layout_height="wrap_content"
android:background="@drawable/selector_orange_bg"/> </RelativeLayout>

我们的拍照按钮使用了一个selector,效果就是按下按钮会带灰色,有明显的按压效果,这种效果的实现我在之前的《【Android】安卓中的布局与事件》中有写过。

然后就是在manifest中注册一个activity

<activity android:name=".study.test.CameraActivity" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

然后就是CameraActivity类的代码

import ...;

public class CameraActivity extends Activity implements View.OnClickListener {

    private static final int REQUEST_CODE_FOR_PIC = 1;
private static final String TAG = "CameraActivity";
private TextView photo;
private ImageView pic; @Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera); photo = this.findViewById(R.id.tv_photograph);
pic = this.findViewById(R.id.iv_pic);
photo.setOnClickListener(this);
} @Override
public void onClick(View v) {
// 拍照的按钮被点击之后,需要跳转到系统的相机APP,然后回传图片
Intent intent = new Intent();
// 设置action是系统相机
intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE);
intent.addCategory(Intent.CATEGORY_DEFAULT);
// 需要使用startActivityForResult()方法
startActivityForResult(intent, REQUEST_CODE_FOR_PIC);
} @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_FOR_PIC) {
// 成功返回
if (resultCode == Activity.RESULT_OK && data != null) {
Bitmap bitmap = data.getParcelableExtra("data");
if (bitmap != null) {
pic.setImageBitmap(bitmap);
Toast.makeText(this, "拍照成功!", Toast.LENGTH_SHORT).show();
}
}
// 取消或者失败
else if (resultCode == Activity.RESULT_CANCELED) {
Toast.makeText(this, "您取消了拍照!", Toast.LENGTH_SHORT).show();
}
}
}
}

效果如下:

取消拍照:

【Android】安卓四大组件之Activity(一)

拍照成功:

【Android】安卓四大组件之Activity(一)

至于用以上方法为何拍摄出来的图片是模糊的缩略图,可以看这篇文章来理解:Android调用系统相机拍照,其中还给出了如何拍一张正常的图片进行回显。

后话

对于activity的初步认识到此结束了,其中涉及到的页面跳转和数据传递都是重点,看懂代码和会写代码是两码事,在看完其中的例子之后,不妨自己动手写一写代码,能给自己带来新的认识!

上一篇:Android开发之使用广播监听网络状态变化


下一篇:linux 新建用户、用户组 以及为新用户分配权限的基本操作