Android基于环信实现聊天功能(三)——登录注册界面

一、标题栏控件 EaseTitleBar 使用

在 xml 中声明标题栏控件,可以在 xml 直接设置标题内容,左右图片,在 Java 文件中亦可以设置这些属性以及相关的点击事件。

<com.hyphenate.easeui.widget.EaseTitleBar
    android:id="@+id/title_bar"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    app:titleBarLeftImage="@drawable/ease_mm_title_back" 
    //该控件在xml中也有很多属性(图片、文本、toolbar)
/> 

titleBar = (EaseTitleBar) findViewById(R.id.title_bar);
titleBar.setTitle("张建国");
titleBar.setRightImageResource(R.drawable.ease_mm_title_remove);

可以调用 fragment 里的 hideTitleBar() 隐藏标题栏

限定符和类型 方法和说明
static float dip2px(android.content.Context context, float value)

dip to px

android.widget.RelativeLayout getLeftLayout() 
android.widget.ImageView getRightImage() 
android.widget.RelativeLayout getRightLayout() 
android.widget.TextView getRightText() 
android.widget.TextView getTitle() 
Toolbar getToolbar() 
void onClick(android.view.View v) 
protected void onSizeChanged(int w, int h, int oldw, int oldh) 
void setBackgroundColor(int color) 
void setLeftImageResource(int resId) 
void setLeftLayoutClickListener(android.view.View.OnClickListener listener) 
void setLeftLayoutVisibility(int visibility) 
void setOnBackPressListener(EaseTitleBar.OnBackPressListener listener)

设置返回按钮的点击事件

void setOnRightClickListener(EaseTitleBar.OnRightClickListener listener)

设置右侧更多的点击事件

void setRightImageResource(int resId) 
void setRightLayoutClickListener(android.view.View.OnClickListener listener) 
void setRightLayoutVisibility(int visibility) 
void setRightTitle(java.lang.String title) 
void setRightTitleResource(int title) 
void setTitle(java.lang.String title) 
void setTitlePosition(EaseTitleBar.TitlePosition position)

设置标题位置

void setToolbarCustomColor(int colorId) 
void setToolbarCustomColorDefault(int colorId) 
static float sp2px(android.content.Context context, float value)

sp to px

二、环信异常的错误码

本文介绍环信即时通讯 Android SDK 中接口调用或者回调中的错误码。可以根据具体错误码判断具体错误原因。

Android 中错误码的类为 EMError。

错误码 错误信息 描述 可能原因
0 EM_NO_ERROR 操作成功 提示操作成功。
1 GENERAL_ERROR 默认未区分类型的错误 提示 SDK 内部未正确初始化,或者请求服务器时未识别出具体原因的错误。
2 NETWORK_ERROR 网络错误 无网络服务时会回调此错误,表示 SDK 与服务器的连接已断开。
4 EXCEED_SERVICE_LIMIT 超过服务限制 超过服务版本的数量限制,比如创建的用户 ID 数量超过购买服务的限制时提示该错误。
5 SERVICE_ARREARAGES 服务欠费 该错误码已废弃。
100 INVALID_APP_KEY App Key 不合法 用户的 App Key 格式不正确。
101 INVALID_USER_NAME 用户 ID 不正确 一般是用户 ID 为空时提示该错误,比如使用邀请好友 API 时 username 参数为空字符。
102 INVALID_PASSWORD 用户密码不正确 登录时提供的密码为空或不正确。
103 INVALID_URL URL 不正确 该错误码已废弃。
104 INVALID_TOKEN 用户 token 不正确 登录时提供的 token 为空或不正确。
105 USER_NAME_TOO_LONG 用户名过长 用户名长度限制 64 个字节。
108 TOKEN_EXPIRED 声网 token 已过期 超出声网 token 有效期时间。
109 TOKEN_WILL_EXPIRE 声网 token 即将过期 超出声网 token 有效期一半时间时会开始回调此错误码。
200 USER_ALREADY_LOGIN 用户已经登录 同一个用户 ID 已经登录。
201 USER_NOT_LOGIN 用户未登录 如果未登录成功时发送消息,或者使用群组操作的 API,SDK 会提示该错误。
202 USER_AUTHENTICATION_FAILED 用户鉴权失败 一般是 token 鉴权失败或者 token 已经过期。
203 USER_ALREADY_EXIST 用户已经存在 注册用户 ID 时如果该 ID 已经存在会提示该错误。
204 USER_NOT_FOUND 用户不存在 比如登录或者获取用户会话列表时用户 ID 不存在。
205 USER_ILLEGAL_ARGUMENT 用户参数不正确 比如创建用户 ID 时不符合格式要求, 或者更新用户属性时用户参数为空等。
206 USER_LOGIN_ANOTHER_DEVICE 用户在其他设备登录 如果未开启多设备登录,则在其他设备登录会将当前登录的设备踢下线,用户会收到此错误。
207 USER_REMOVED 用户已经被注销 如果登录用户被从管理后台删除 ID 则会收到此错误。
208 USER_REG_FAILED 用户注册失败 注册用户 ID 时失败,比如未开启开放注册功能等原因。
209 PUSH_UPDATECONFIGS_FAILED 更新推送配置错误 用户更新推送昵称,设置免推送配置时失败。
210 USER_PERMISSION_DENIED 用户无权限 例如如果用户被封禁,发送消息时会提示该错误。
211 USER_BINDDEVICETOKEN_FAILED 用户更新推送 token 错误 该错误码已废弃。
212 USER_UNBIND_DEVICETOKEN_FAILED 用户更新推送 token 错误 该错误码已废弃。
213 USER_BIND_ANOTHER_DEVICE 用户已经在另外设备登录 如果用户设置为先登录的设备优先,则后登录设备登录失败并提示该错误。
214 USER_LOGIN_TOO_MANY_DEVICES 用户登录设备数超过限制 用户同一 ID 登录设备数量超过限制提示该错误。
215 USER_MUTED 用户在群组聊天室中被禁言 用户被禁言后发送消息时提示该错误。
216 USER_KICKED_BY_CHANGE_PASSWORD 用户密码更新 当前登录的用户密码被修改后,当前登录会断开并提示该错误。
217 USER_KICKED_BY_OTHER_DEVICE 用户被踢下线 开启多设备后,如果用户在其他设备上通过调用 API 或者管理后台将当前设备登录的 ID 强制退出登录,SDK 会提示该错误。
218 USER_ALREADY_LOGIN_ANOTHER 其他用户已登录 SDK 未退出登录前又被使用不同的账户登录。
219 USER_MUTED_BY_ADMIN 用户被禁言 用户在当前 app key 被禁言后发送消息时提示该错误。
220 USER_DEVICE_CHANGED 用户登录设备与上次不一致 用户登录设备与上次登录设备不一致,需要用户重新登录,注意:默认会允许用户登录,踢掉另一个设备上的登录,此 error 在打开不踢掉另外设备上的登录开关后才会生效。
221 USER_NOT_ON_ROSTER 非好友禁止发消息 开通非好友禁止发消息后,非好友间发消息提示此错误。若要开通该功能,请联系商务咨询。
300 SERVER_NOT_REACHABLE 请求服务失败 发送或撤回消息时,如果 SDK 与消息服务器未保持连接,会返回该错误;操作群组、好友等请求时,如果因网络连接太差而不成功,也会返回该错误。
301 SERVER_TIMEOUT 请求服务超时 如果调用 API 在特定时间内服务器未响应则返回该错误,一般是 30 秒或者 60 秒。
302 SERVER_BUSY 服务器忙碌 服务器当前忙碌会返回该错误,建议稍后再尝试请求。
303 SERVER_UNKNOWN_ERROR 服务请求的通用错误码 当请求服务器未成功时的默认错误,该错误发生情况较多,需要根据日志进一步排查。
304 SERVER_GET_DNSLIST_FAILED 获取服务器配置信息错误 SDK 获取当前应用的服务器配置时失败。
305 SERVER_SERVICE_RESTRICTED 当前 app 被禁用 如果 app 因为某种原因被禁用时会返回该错误。
400 FILE_NOT_FOUND 文件未找到 当用户获取不到日志文件,或者下载附件失败时提示该错误。
401 FILE_INVALID 文件异常 当上传消息附件或者群组共享文件时可能会提示该错误。
402 FILE_UPLOAD_FAILED 上传文件错误 上传消息附件失败时提示该错误。
403 FILE_DOWNLOAD_FAILED 下载文件错误 下载消息附件失败时提示该错误。
404 FILE_DELETE_FAILED 删除文件错误 通过 API 获取日志文件时会将旧的日志文件删除,如果删除失败提示该错误。
405 FILE_TOO_LARGE 文件太大 消息附件或群共享文件超过文件大小限制时提示该错误。
406 FILE_CONTENT_IMPROPER 文件内容不合规 消息附件或群共享文件内容不合规时提示该错误。
500 MESSAGE_INVALID 消息异常错误 如果要发送的消息为空,或者消息 ID 为空,或者消息的发送方 ID 与当前登录 ID 不同则会提示该错误。
501 MESSAGE_INCLUDE_ILLEGAL_CONTENT 消息含有非法内容 如果消息被过滤系统识别为非法消息时返回该错误。
502 MESSAGE_SEND_TRAFFIC_LIMIT 消息限流 发送消息过快时提示该错误,建议降低频率或者减少消息内容的大小。
503 MESSAGE_ENCRYPTION_ERROR 消息加密错误 该错误码已废弃。
504 MESSAGE_RECALL_TIME_LIMIT 消息撤回超时错误 如果超过消息撤回允许的时间尝试撤回时提示该错误。
505 SERVICE_NOT_ENABLED 服务未开启 尝试使用某些未开通的功能时提示该错误。
506 MESSAGE_EXPIRED 消息已过期 发送群组回执时如果已经超过时间限制 (默认 3 天) 会提示该错误。
507 MESSAGE_ILLEGAL_WHITELIST 用户未在白名单中 如果群组聊天室开启全员禁言,且用户未在白名单中发送消息时提示该错误。
508 MESSAGE_EXTERNAL_LOGIC_BLOCKED 消息执行发送前回调,被用户自己的逻辑拦截 发送的消息被用户自己的服务器定义的规则拦截掉时提示该错误。
600 GROUP_INVALID_ID 群组 ID 异常 使用群组相关 API,提供的群组 ID 为空时提示该错误。
601 GROUP_ALREADY_JOINED 已在该群组中 调用加入群组的 API 时如果已经在该群组中则提示该错误。
602 GROUP_NOT_JOINED 未加入该群组 尝试在未加入的群组中发送消息或进行群组操作时提示该错误。
603 GROUP_PERMISSION_DENIED 无权限的群组操作 没有权限进行群组操作,比如群组成员不能设置群组管理员。
604 GROUP_MEMBERS_FULL 群组已满 群组已经达到人数上限。
605 GROUP_NOT_EXIST 群组不存在 尝试对不存在的群组进行操作时提示该错误。
700 CHATROOM_INVALID_ID 聊天室 ID 异常 使用聊天室相关 API,提供的聊天室 ID 为空时提示该错误。
701 CHATROOM_ALREADY_JOINED 已在该聊天室中 调用加入聊天室的 API 时如果已经在该聊天室中则提示该错误。
702 CHATROOM_NOT_JOINED 未加入该聊天室 尝试在未加入的聊天室中发送消息或进行聊天室操作时提示该错误。
703 CHATROOM_PERMISSION_DENIED 无权限的聊天室操作 没有权限进行聊天室操作,比如聊天室成员不能设置聊天室管理员。
704 CHATROOM_MEMBERS_FULL 聊天室已满 聊天室已经达到人数上限。
705 CHATROOM_NOT_EXIST 聊天室不存在 尝试对不存在的聊天室进行操作时提示该错误。
900 PUSH_NOT_SUPPORT 第三方推送不支持 如果用户配置的第三方推送在当前设备上不支持,会提示该错误。
901 PUSH_BIND_FAILED 绑定第三方推送 token 失败 如果将第三方推送 token 上传到服务器失败时会返回该错误。
902 PUSH_UNBIND_FAILED 解绑第三方推送 token 失败 如果解绑第三方推送 token 失败会提示该错误。

三、登录注册界面

效果演示:

登录界面主要分为四个步骤:

  • 页面布局
  • 环信注册
  • 创建用户账号信息数据库
  • 环信登录

3.1 登录界面布局:activity_login.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
    android:orientation="vertical"
    tools:context=".controller.activity.LoginActivity">

    <com.hyphenate.easeui.widget.EaseTitleBar
        android:id="@+id/login_titleBar"
        android:layout_width="wrap_content"
        android:layout_height="60dp"
        android:background="@color/blue"
        app:titleBarTitleTextSize="30dp"
        app:titleBarTitleTextColor="@color/black"
        app:titleBarTitle="登录"
        >
    </com.hyphenate.easeui.widget.EaseTitleBar>

    <TextView
        android:layout_marginTop="40dp"
        android:layout_marginBottom="40dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="环信 SDK"
        android:textSize="40sp"
        android:layout_gravity="center"
        />

     <LinearLayout
         android:layout_margin="20dp"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:orientation="horizontal">
         <TextView
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:textSize="25sp"
             android:text="用户名:"/>

         <EditText
             android:id="@+id/login_name"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"/>

     </LinearLayout>

    <LinearLayout
        android:layout_marginLeft="20dp"
        android:layout_marginRight="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textSize="25sp"
            android:text="密    码:"/>

        <EditText
            android:id="@+id/login_password"
            android:inputType="textPassword"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"/>

    </LinearLayout>


    <CheckBox
        android:id="@+id/checkbox_password"
        android:layout_marginEnd="20dp"
        android:layout_gravity="end"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="显示密码"/>

    <LinearLayout
        android:layout_margin="20dp"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:id="@+id/bt_register"
            android:text="注册"
            android:layout_marginEnd="10dp"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"/>

        <Button
            android:id="@+id/bt_login"
            android:text="登录"
            android:layout_marginStart="10dp"
            android:layout_weight="1"
            android:layout_width="0dp"
            android:layout_height="wrap_content"/>

    </LinearLayout>

</LinearLayout>

一些简单的说明: 

  1. EaseTitleBar 在最开始就有讲解,就是一个简单的标题列使用。
  2. 如何设置密码的 EditText 显示加密:
  • 早期:使用android:password="true"  已经弃用
  • 目前:使用android:inputType="textPassword"
//EditText控件inputType的使用

//文本类型,多为大写、小写和数字符号。  
android:inputType="none"//输入普通字符 
android:inputType="text"//输入普通字符 
android:inputType="textCapCharacters"//输入普通字符 
android:inputType="textCapWords"//单词首字母大小 
android:inputType="textCapSentences"//仅第一个字母大小 
android:inputType="textAutoCorrect"//前两个自动完成 
android:inputType="textAutoComplete"//前两个自动完成 
android:inputType="textMultiLine"//多行输入 
android:inputType="textImeMultiLine"//输入法多行(不一定支持) 
android:inputType="textNoSuggestions"//不提示 
android:inputType="textUri"//URI格式 
android:inputType="textEmailAddress"//电子邮件地址格式 
android:inputType="textEmailSubject"//邮件主题格式 
android:inputType="textShortMessage"//短消息格式 
android:inputType="textLongMessage"//长消息格式 
android:inputType="textPersonName"//人名格式 
android:inputType="textPostalAddress"//邮政格式 
android:inputType="textPassword"//密码格式 
android:inputType="textVisiblePassword"//密码可见格式 
android:inputType="textWebEditText"//作为网页表单的文本格式 
android:inputType="textFilter"//文本筛选格式 
android:inputType="textPhonetic"//拼音输入格式 

//数值类型 
android:inputType="number"//数字格式 
android:inputType="numberSigned"//有符号数字格式 
android:inputType="numberDecimal"//可以带小数点的浮点格式 
android:inputType="phone"//拨号键盘 
android:inputType="datetime"//日期+时间格式 
android:inputType="date"//日期键盘 
android:inputType="time"//时间键盘

3.2 登录注册功能实现:LoginActivity.java

主要实现了一下四个功能:

  • 浅试了一下EaseTitleBar
  • 实现点击ChecBox显示密码的功能
  • 注册的业务逻辑
  • 登录的业务逻辑
public class LoginActivity extends Activity {

    private EaseTitleBar easeTitleBar;
    private EditText et_name,et_pwd;
    private CheckBox checkBox;
    private Button bt_register,bt_login;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_login);

        //初始化控件
        initView();
        //初始化监听
        initListener();
        //尝试玩弄一下EaseTitleBar
        initEaseTitleBar();
        //实现点击显示密码功能
        initPwdShow();
    }

    //实现点击显示密码功能
    private void initPwdShow() {

        checkBox.setOnCheckedChangeListener((buttonView, isChecked) -> {
            if(checkBox.isChecked()){
                et_pwd.setTransformationMethod(HideReturnsTransformationMethod.getInstance()); //如果被选中则显示密码
            }else {

                et_pwd.setTransformationMethod(PasswordTransformationMethod.getInstance()); //如果没选中CheckBox则隐藏密码
            }
            et_pwd.setSelection(et_pwd.getText().length());   //TextView默认光标在最左端,这里控制光标在最右端
        });

    }

    //尝试玩弄一下EaseTitleBar
    private void initEaseTitleBar() {
        //可以看具体的文档
        easeTitleBar.setTitle("杨文杰");
    }

    //初始化控件
    private void initView() {
        easeTitleBar = (EaseTitleBar) findViewById(R.id.login_titleBar);
        et_name = (EditText) findViewById(R.id.login_name);
        et_pwd = (EditText) findViewById(R.id.login_password);
        checkBox = (CheckBox) findViewById(R.id.checkbox_password);
        bt_register = (Button) findViewById(R.id.bt_register);
        bt_login = (Button) findViewById(R.id.bt_login);
    }

    //初始化监听
    private void initListener() {
        bt_register.setOnClickListener(v -> {
            //注册的业务逻辑
            regist();
        });


        bt_login.setOnClickListener(v->{
            //登录的业务逻辑
            login();
        });
    }


    //登录的业务逻辑
    private void login() {
        // 1.获取输入的用户名和密码
        String loginName = et_name.getText().toString();
        String loginPwd = et_pwd.getText().toString();


        // 2.校验输入的用户名和密码
        if(TextUtils.isEmpty(loginName)||TextUtils.isEmpty(loginPwd)){
            Toast.makeText(LoginActivity.this,"输入的用户名和密码不可以为空",Toast.LENGTH_SHORT).show();
            return;
        }
        // 3.登录逻辑处理
        Model.getInstance().getGlobalThreadPool().execute(() -> {
            //去环信服务器登录
            EMClient.getInstance().login(loginName, loginPwd, new EMCallBack() {
                //登录成功后的处理

                @Override
                public void onSuccess() {
                    //对模型层数据的处理
                    Model.getInstance().loginSuccess();
                    //保存用户账户信息到本地数据库
                    Model.getInstance().getUserAccountDao().addAccount(new UserInfo(loginName));

                    runOnUiThread(() -> {
                        //提示登录成功
                        Toast.makeText(LoginActivity.this, "登录成功", Toast.LENGTH_SHORT).show();
                        //跳转到主界面
                        Intent intent = new Intent(LoginActivity.this,MainActivity.class);
                        startActivity(intent);
                        //登录成功后,登录界面就可以销毁了。
                        finish();
                    });
                    
                }

                //登录失败的处理
                @Override
                public void onError(int code, String error) {
                    runOnUiThread(() -> {
                        //提示登录失败
                        Toast.makeText(LoginActivity.this, "登录失败"+error+code, Toast.LENGTH_SHORT).show();

                    });

                }

                //登录过程中的处理
                @Override
                public void onProgress(int progress, String status) {

                }
            });
        });
    }

    //注册的业务逻辑
    private void regist() {
        // 1.获取输入的用户名和密码
        String registName = et_name.getText().toString();
        String registPwd = et_pwd.getText().toString();
        // 2.校验输入的用户名和密码
        if(TextUtils.isEmpty(registName)||TextUtils.isEmpty(registPwd)){
            Toast.makeText(LoginActivity.this,"输入的用户名和密码不可以为空",Toast.LENGTH_SHORT).show();
            //防止进行以下逻辑
            return;
        }

        // 3.去服务器去注册账号(目前直接去环信的服务器,后期会使用app的服务器)
        Model.getInstance().getGlobalThreadPool().execute(() -> {
            try {
                //去环信服务器注册账号
                EMClient.getInstance().createAccount(registName,registPwd);
                //注册成功,更新UI弹出吐司(显然要去子线程中更新UI)
                runOnUiThread(() -> {
                    Toast.makeText(LoginActivity.this, "注册成功", Toast.LENGTH_SHORT).show();
                });
            } catch (HyphenateException e) {
                e.printStackTrace();
                runOnUiThread(() -> {
                    Toast.makeText(LoginActivity.this, "注册失败"+e, Toast.LENGTH_SHORT).show();
                });
            }
        });
    }
}

上面的注释细节说的清楚,说点其他需要了解的。

  1. 注册失败后:通过返回的异常 HyphenateException e 来进行相应的提醒操作
  2. 登录失败后:会返回一个 int 的状态码和一个 String 的错误信息(详情看本章第二节)

3.3 创建用户账号信息数据库

目的是为了:用户登录成功后将用户信息保存到本地

主要分为以下四个步骤:

  1. 创建用户bean类
  2. 创建用户账号数据库
  3. 创建表类
  4. 创建数据库操作类

3.3.1 创建用户bean类 UserInfo.java

//用户账号信息的bean
public class UserInfo {

    private String name;// 用户名称
    private String huanxingID;// 环信ID
    private String nick;// 用户的名称
    private String photo;// 用户头像

    //无参构造器
    public UserInfo() {
    }

    //构造器
    public UserInfo(String name) {
        this.name = name;
        this.huanxingID = name;
        this.nick = name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getHuanxingID() {
        return huanxingID;
    }

    public void setHuanxingID(String huanxingID) {
        this.huanxingID = huanxingID;
    }

    public String getNick() {
        return nick;
    }

    public void setNick(String nick) {
        this.nick = nick;
    }

    public String getPhoto() {
        return photo;
    }

    public void setPhoto(String photo) {
        this.photo = photo;
    }

    @Override
    public String toString() {
        return "UserInfo{" +
                "name='" + name + '\'' +
                ", huanxingID='" + huanxingID + '\'' +
                ", nick='" + nick + '\'' +
                ", photo='" + photo + '\'' +
                '}';
    }
}

这里很粗糙的传入了一个name参数的构造器,是为了方便之后的操作。

3.3.2 创建用户账号数据库 UserAccountDB.java

public class UserAccountDB extends SQLiteOpenHelper {
    //构造
    public UserAccountDB(@Nullable Context context) {
        super(context, "account.db", null, 1);
    }

    //数据库创建的时候调用
    @Override
    public void onCreate(SQLiteDatabase db) {
        //创建创建数据库表的语句
        db.execSQL(UserAccountTable.CREATE_TAB);
    }

    //数据库更新的时候调用(版本号)
    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {

    }
}

3.3.3 创建表类 UserAccountTable.java

这里创建一个表类:在后面你就会发现有大大地好处。

public class UserAccountTable {
    public static final String TAB_NAME = "tab_account";
    public static final String COL_NAME = "name";
    public static final String COL_HXID = "huanxingID";
    public static final String COL_NICK = "nick";
    public static final String COL_PHOTO = "photo";

    public static final String CREATE_TAB = "create table "
            + TAB_NAME +" ("
            + COL_HXID +" text primary key,"
            + COL_NAME +" text,"
            + COL_NICK +" text,"
            + COL_PHOTO +" text);";

}

注意这里的CREATE_TAB代表的是一个sql语句,不要在写的时候出错。

3.3.3 创建数据库操作类 UserAccountDao.java

//用户账号数据的操作类
public class UserAccountDao {

    private final UserAccountDB mHelper;

    public UserAccountDao(Context context) {
        mHelper =  new UserAccountDB(context);
    }

    //添加用户到数据库
    public void addAccount(UserInfo user){
        //获取数据库对象
        SQLiteDatabase db = mHelper.getWritableDatabase();
        //执行添加操作
        ContentValues values=new ContentValues();
        values.put(UserAccountTable.COL_HXID,user.getHuanxingID());
        values.put(UserAccountTable.COL_NAME,user.getName());
        values.put(UserAccountTable.COL_NICK,user.getNick());
        values.put(UserAccountTable.COL_PHOTO,user.getPhoto());

        db.replace(UserAccountTable.TAB_NAME,null,values);
    }

    //根据环信id获取所有用户信息
    public UserInfo getAccountByHxId(String huanxingID){
        //获取数据库对象
        SQLiteDatabase db= mHelper.getReadableDatabase();
        //执行查询语句
        String sql = "select * from " + UserAccountTable.TAB_NAME+" where "+UserAccountTable.COL_HXID+"=?";
        Cursor cursor = db.rawQuery(sql, new String[]{huanxingID});

        UserInfo  userInfo=null;
        if(cursor.moveToNext()){
            userInfo = new UserInfo();

            //封装对象
            userInfo.setHuanxingID(cursor.getString(cursor.getColumnIndex(UserAccountTable.COL_HXID)));
            userInfo.setName(cursor.getString(cursor.getColumnIndex(UserAccountTable.COL_NAME)));
            userInfo.setNick(cursor.getString(cursor.getColumnIndex(UserAccountTable.COL_NICK)));
            userInfo.setPhoto(cursor.getString(cursor.getColumnIndex(UserAccountTable.COL_PHOTO)));
        }

        //关闭资源
        cursor.close();
        //返回数据
        return userInfo;
    }

}

猜你喜欢

转载自blog.csdn.net/indeedes/article/details/124598881
今日推荐