一、标题栏控件 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() 隐藏标题栏
二、环信异常的错误码
本文介绍环信即时通讯 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>
一些简单的说明:?
- EaseTitleBar 在最开始就有讲解,就是一个简单的标题列使用。
- 如何设置密码的 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();
});
}
});
}
}
上面的注释细节说的清楚,说点其他需要了解的。
- 注册失败后:通过返回的异常 HyphenateException e 来进行相应的提醒操作
- 登录失败后:会返回一个 int 的状态码和一个 String 的错误信息(详情看本章第二节)
3.3 创建用户账号信息数据库
目的是为了:用户登录成功后将用户信息保存到本地
主要分为以下四个步骤:
- 创建用户bean类
- 创建用户账号数据库
- 创建表类
- 创建数据库操作类
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;
}
}
|