任务 6.2 云笔记 - 用户认证(5)

2018-05-15  本文已影响0人  jingz课程

六、编写用户数据获取模块

通常应用程序应当提供用户个人信息和配置模块以浏览、编辑个人配置,或者退出登录状态。
我们编写一个简单的个人信息模块,能够根据当前登录的用户账号从服务器端查询用户信息并显示,并且提供注销操作。具体设计如下:

编写服务端查询页面

回到DreamWeaver(以下简称DW),创建新页面,命名为user_info.php,仍然保存到simple_note目录下。页面代码如下:

<?
session_start();
include( "conn.php" );
$email = $_POST[ "email" ];

// 在数据库中查询与email和密码完全匹配的记录
$sql = "SELECT * FROM `user` WHERE `email`='$email'";
$result = mysql_query( $sql );
$num_rows = mysql_num_rows( $result );
// 将用JSON返回登录结果
header( 'Content-type: text/json' );

if ( $num_rows == 1 ) {
    // 查询成功
    $row = mysql_fetch_array( $result );
    // 生成含有结果信息的JSON    
    $ret = array(
        "code" => "1",
        "msg" => "OK",
        "email" => $row[ 'email' ],
        "personalSign" => $row[ 'sign' ]
    );
    echo json_encode( $ret, JSON_UNESCAPED_UNICODE );
} else {
        // 不存在对应用户信息,返回出错信息
    $ret = array(
        "code" => "0",
        "msg" => "No such a user",
        "email" => $row[ 'email' ]
    );
    echo json_encode( $ret, JSON_UNESCAPED_UNICODE );
}

?>

创建用户信息页面

新建名为UserInfoActivity的新页面:

配置其对应的布局文件activity_user_info.xml如下:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".UserInfoActivity">

    <!--登出按钮-->
    <Button
        android:id="@+id/btn_logout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="16dp"
        android:layout_marginEnd="16dp"
        android:layout_marginStart="16dp"
        android:text="登出账户"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

    <!--Email信息-->
    <TextView
        android:id="@+id/tv_email"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="100dp"
        android:text="a@abc.com"
        android:textColor="@color/black"
        android:textSize="24sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <!--个人签名-->
    <TextView
        android:id="@+id/tv_personal_sign"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="8dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="24dp"
        android:text="Personal sign"
        android:textSize="18sp"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toBottomOf="@+id/tv_email" />

    <!--加载等待动画-->
    <ProgressBar
        android:id="@+id/load_progress"
        style="?android:attr/progressBarStyleLarge"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:visibility="gone"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>

回到UserInfoActivity类中,为其添加成员变量如下:

    // 等待动画
    private ProgressBar mProgressBar;
    // Email文本
    private TextView mEmailView;
    // 个人签名文本
    private TextView mPersonalSignView;
    // 登出按钮
    private Button mLogoutView;

    private Handler mHandler = new Handler();

修改onCreate()方法:

        mProgressBar = findViewById(R.id.load_progress);
        mEmailView = findViewById(R.id.tv_email);
        mPersonalSignView = findViewById(R.id.tv_personal_sign);
        mLogoutView = findViewById(R.id.btn_logout);
        // 执行登出
        mLogoutView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                onLogout();
            }
        });
        // 从服务器加载用户信息
        loadUserInfo();

基于okhttp3框架实现loadUserInfo()函数:

    private void loadUserInfo() {
        String email = Utils.getUserEmail(this);
        // 当前并没有登录,跳转到登录页面
        if (TextUtils.isEmpty(email)) {
            Intent intent = new Intent(this, LoginActivity.class);
            startActivity(intent);
            finish();
            return;
        }

        OkHttpClient client = new OkHttpClient();
        FormBody.Builder fb = new FormBody.Builder();
        FormBody formBody = fb.add("email", email)
                .build();
        Request request = new Request.Builder()
                .url(HttpHelper.getUserInfoUrl())
                .post(formBody)
                .build();

        showProgress(true);

        client.newCall(request).enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        showProgress(false);
                        Toast.makeText(UserInfoActivity.this, R.string.error_check_network, Toast.LENGTH_SHORT).show();
                    }
                });
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                ...
            }
        });
    }

在onResponse()回调函数中编写下面的代码:

                final String rsp = response.body().string();
                mHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        showProgress(false);
                        try {
                            JSONObject jo = new JSONObject(rsp);
                            int code = jo.optInt("code", 0);
                            String email = jo.optString("email");
                            String personalSign = jo.optString("personalSign");
                            if (code == 1) {
                                // 查询成功,设置当前要显示的各个字段
                                mEmailView.setText(email);
                                mPersonalSignView.setText(personalSign);
                            } else {
                                // 查询失败,关闭页面退出
                                finish();
                                return;
                            }
                        } catch (JSONException e) {
                            e.printStackTrace();
                        }
                    }
                });

下面实现登出功能,这里简单的处理,就是将之前登录后保存的账户设置为空即可:

    private void onLogout() {
        Utils.saveUserEmail(this, "");
        finish();
    }

还要实现控制等待动画显示与隐藏的showProgress()函数:

    private void showProgress(final boolean show) {
        mProgressBar.setVisibility(show ? View.VISIBLE : View.GONE);
    }

为笔记列表页ActionBar添加用户信息项

将以下图标文件放置到res/drawable-xxhdpi目录中:

ic_person.png

进入到笔记列表页对应的菜单资源文件menu_note_list.xml中,增加菜单项menu_item_user如下:

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/menu_item_notebook"
        android:title="@string/notebook"
        android:icon="@drawable/ic_notebook"
        app:showAsAction="always"/>

    <!--新增用户信息项-->
    <item
        android:id="@+id/menu_item_user"
        android:title="@string/user_info"
        android:icon="@drawable/ic_person"
        app:showAsAction="always"/>
</menu>

需要新增的字符串:

    <string name="user_info">用户信息</string>

回到笔记列表页,找到onOptionsItemSelected()方法,为其添加代码,在点击用户信息图标时打开用户信息页面:

            case R.id.menu_item_user:
                intent = new Intent(this, UserInfoActivity.class);
                startActivity(intent);
                return true;

运行程序,效果如下:

上一篇下一篇

猜你喜欢

热点阅读