美文网首页
任务 6.2 云笔记 - 用户认证(5)

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

作者: jingz课程 | 来源:发表于2018-05-15 08:34 被阅读0次

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

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

    • 前置条件:用户已登录
    • 用户点击笔记列表页面ActionBar上的用户图标,进入用户信息页面
    • 用户信息页面展示用户email地址和个人签名
    • 用户信息页面提供登出按钮
    • 用户点击登出按钮后,APP清除登录数据,同时切换到登录页面

    编写服务端查询页面

    回到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;
    

    运行程序,效果如下:

    相关文章

      网友评论

          本文标题:任务 6.2 云笔记 - 用户认证(5)

          本文链接:https://www.haomeiwen.com/subject/kxoddftx.html