版权说明:本文是基于开源LumaQQ下,开发者不直接参与QQ协议的分析工作,移植到Android平台纯粹是为了方便学习和研究之用,并且没有产生任何直接的经济效益,并且纯粹是个人的技术学习研究行为,与本人所在单位没有任何关系。此文的读者在使用过程产生的效益和涉及的法律责任与本人没有直接关系。如果影响到您或您的公司利益,敬请谅解并且与我联系,本人会第一时间作出处理。

你打开QQ首先要做的第一件事是什么?当然是登录,除非你选择了自动登录。今天让我们先实现一个简单的登录界面吧。

Lumaqq提供了一个QQClient类,QQ的客户端类,这个类为用户提供一个方便的接口,比如发送消息之类的,只需要调用一个 方法便可以完成了。我们的程序就是调用这个类来做相应的处理。

现在google提供的插件暂不提供拖拉控件来进行界面的设计,但提供了一个预览的界面来供你查看一下大概的样子,一切都在xml做界面的设计工作。我们的登陆界面大概是这个样子

丑是丑了点,但关键是能用,xml相应为

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:orientation="vertical" android:layout_width="fill_parent"
  4. android:layout_height="fill_parent">
  5. <TextView android:layout_width="fill_parent"
  6. android:layout_height="wrap_content" android:text="@string/qqname" />
  7. <EditText android:id="@+id/qqID" android:layout_width="fill_parent"
  8. android:layout_height="wrap_content" android:text="" android:numeric="integer" />
  9. <TextView android:layout_width="fill_parent"
  10. android:layout_height="wrap_content" android:text="@string/qqpwd" />
  11. <EditText android:id="@+id/qqPwd" android:layout_width="fill_parent"
  12. android:layout_height="wrap_content" android:text="" android:password="true" />
  13. <Button android:id="@+id/submit" android:layout_width="fill_parent"
  14. android:layout_height="wrap_content" android:text="@string/lumaqq_button_submit_text" />
  15. <TextView android:id="@+id/suggest" android:layout_width="fill_parent"
  16. android:layout_height="wrap_content" android:text="" />
  17. </LinearLayout>

界面设计好之后,登录的实现

  1. package com.android.lumaqqMe;
  2. import android.app.Activity;
  3. import android.os.Bundle;
  4. import android.os.Message;
  5. import android.view.View;
  6. import android.view.View.OnClickListener;
  7. import android.widget.Button;
  8. import android.widget.EditText;
  9. import android.widget.TextView;
  10. import android.os.Handler;
  11. import edu.tsinghua.lumaqq.qq.QQ;
  12. import edu.tsinghua.lumaqq.qq.QQClient;
  13. import edu.tsinghua.lumaqq.qq.Util;
  14. import edu.tsinghua.lumaqq.qq.beans.QQUser;
  15. import edu.tsinghua.lumaqq.qq.events.QQEvent;
  16. import edu.tsinghua.lumaqq.qq.events.IQQListener;
  17. import edu.tsinghua.lumaqq.qq.net.PortGateFactory;
  18. public class lumaqqMe extends Activity implements IQQListener {
  19. private static String message_box_wrong_qq = null;
  20. /** Called when the activity is first created. */
  21. @Override
  22. public void onCreate(Bundle savedInstanceState) {
  23. super.onCreate(savedInstanceState);
  24. setContentView(R.layout.main);
  25. findViews();
  26. setListeners();
  27. }
  28. private Button button_test;
  29. private EditText field_qqID;
  30. private EditText field_qqPwd;
  31. private TextView text_suggest;
  32. private QQClient client;
  33. private String resultStr;
  34. private void findViews() {
  35. button_test = (Button) findViewById(R.id.submit);
  36. field_qqID = (EditText) findViewById(R.id.qqID);
  37. field_qqPwd = (EditText) findViewById(R.id.qqPwd);
  38. text_suggest = (TextView) findViewById(R.id.suggest);
  39. message_box_wrong_qq = (String) getText(R.string.message_box_wrong_qq);
  40. }
  41. private void setListeners() {
  42. button_test.setOnClickListener(testLumaQQ);
  43. }
  44. private String validate() {
  45. if (Util.getInt(field_qqID.getText().toString(), -1) == -1)
  46. return message_box_wrong_qq;
  47. else
  48. return null;
  49. }
  50. private OnClickListener testLumaQQ = new OnClickListener() {
  51. @Override
  52. public void onClick(View v) {
  53. doOk();
  54. }
  55. };
  56. private void doOk() {
  57. String msg = validate();
  58. if (msg != null) {
  59. text_suggest.setText(message_box_wrong_qq);
  60. return;
  61. }
  62. int qqnum = Util.getInt(field_qqID.getText().toString(), -1);
  63. if (qqnum == -1)
  64. return;
  65. String qqpwd = field_qqPwd.getText().toString();
  66. client = new QQClient();
  67. client.setConnectionPoolFactory(new PortGateFactory());
  68. QQUser user = new QQUser(qqnum, qqpwd);
  69. // 设置参数
  70. client.addQQListener(this);
  71. user.setUdp(true);
  72. client.setUser(user);
  73. client.setLoginServer("sz.tencent.com");
  74. try {
  75. // 登录
  76. text_suggest.setText(R.string.message_box_submit_start);
  77. client.login();
  78. } catch (Exception e1) {
  79. text_suggest.setText(e1.getMessage());
  80. }
  81. }
  82. @Override
  83. public void qqEvent(QQEvent e) {
  84. // TODO Auto-generated method stub
  85. switch (e.type) {
  86. case QQEvent.LOGIN_OK:
  87. processLoginSuccess();
  88. break;
  89. case QQEvent.LOGIN_FAIL:
  90. processLoginFail(e);
  91. break;
  92. case QQEvent.LOGIN_UNKNOWN_ERROR:
  93. processLoginUnknownError();
  94. break;
  95. case QQEvent.IM_SEND_OK:
  96. processSendIMSuccess();
  97. break;
  98. case QQEvent.USER_STATUS_CHANGE_OK:
  99. processChangeStatusSuccess();
  100. break;
  101. case QQEvent.USER_STATUS_CHANGE_FAIL:
  102. processChangeStatusFail();
  103. break;
  104. case QQEvent.SYS_TIMEOUT:
  105. if (e.operation == QQ.QQ_CMD_SEND_IM)
  106. processSendIMFail();
  107. break;
  108. }
  109. }
  110. /**
  111. * 初始改变状态失败事件
  112. */
  113. private void processChangeStatusFail() {
  114. resultStr = getText(R.string.message_box_status_change_fail).toString();
  115. handler.sendEmptyMessage(0);
  116. client.logout();
  117. client.release();
  118. }
  119. /**
  120. * 处理改变状态成功事件
  121. */
  122. private void processChangeStatusSuccess() {
  123. resultStr = getText(R.string.message_box_status_change_ok).toString();
  124. handler.sendEmptyMessage(0);
  125. client.im_Send(3698107, Util.getBytes("hello,wo shi robot"));
  126. }
  127. /**
  128. * 处理发送消息失败事件
  129. */
  130. private void processSendIMFail() {
  131. resultStr = getText(R.string.message_box_sys_timeout).toString();
  132. handler.sendEmptyMessage(0);
  133. client.logout();
  134. client.release();
  135. }
  136. /**
  137. * 处理发送消息成功事件
  138. */
  139. private void processSendIMSuccess() {
  140. resultStr = getText(R.string.message_box_send_ok).toString();
  141. handler.sendEmptyMessage(0);
  142. client.logout();
  143. client.release();
  144. }
  145. /**
  146. * 处理登陆成功事件
  147. */
  148. private void processLoginSuccess() {
  149. if (!client.getUser().isLoggedIn()) {
  150. resultStr = getText(R.string.message_box_login_success).toString();
  151. handler.sendEmptyMessage(0);
  152. }
  153. }
  154. /**
  155. * 处理登陆密码错误事件
  156. *
  157. * @param e
  158. */
  159. private void processLoginFail(QQEvent e) {
  160. resultStr = getText(R.string.message_box_login_fail).toString();
  161. handler.sendEmptyMessage(0);
  162. }
  163. /**
  164. * 处理登陆未知错误事件
  165. */
  166. private void processLoginUnknownError() {
  167. resultStr = getText(R.string.message_box_unknown_error).toString();
  168. handler.sendEmptyMessage(0);
  169. }
  170. private Handler handler = new Handler() {
  171. @Override
  172. public void handleMessage(Message msg) {
  173. // TODO Auto-generated method stub
  174. text_suggest.setText(resultStr);
  175. super.handleMessage(msg);
  176. }
  177. };
  178. }

在Android中非UI线程,是不能触碰UI类的。解决方式是另起一个Handler,将改变UI的代码封装到里面,子线程来调用这个handler,完成工作之后发送一个消息到消息队列中,主线程在空闲的时候来更新UI的状态(大部分时间应该是即时的).

好了运行一下吧,输入QQ号和密码之后,点登录按钮就会看到登陆成功和发送消息成功的信息!

Lumaqq移植到Android-登录篇相关推荐

  1. Lumaqq移植到Android 之进阶篇

    版权说明:本文是基于开源LumaQQ下,开发者不直接参与QQ协议的分析工作,移植到Android平台纯粹是为了方便学习和研究之用,并且没有产生任何直接的经济效益,并且纯粹是个人的技术学习研究行为,与本 ...

  2. lumaQQ移植到Android之消息篇

    版权说明:本文是基于开源LumaQQ下,开发者不直接参与QQ协议的分析工作,移植到Android平台纯粹是为了方便学习和研究之用,并且没有产生任何直接的经济效益,并且纯粹是个人的技术学习研究行为,与本 ...

  3. lumaQQ移植到Android之重构篇

    版权说明:本文是基于开源LumaQQ下,开发者不直接参与QQ协议的分析工作,移植到Android平台纯粹是为了方便学习和研究之用,并且没有产生任何直接的经济效益,并且纯粹是个人的技术学习研究行为,与本 ...

  4. Android架构篇-1 项目组织架构

    Android架构篇-1 项目组织架构 模块化分层 1.结构清晰,各模块代码分离,符合高内聚低耦合,快速定位查找代码 2.团队协作开发灵活,互不影响,各模块完成后合并即可完成整体app 3.抽离公共层 ...

  5. Android登录拦截器实现方式(一)

    Android登录拦截器实现方式(一) 2015-08-04 22:12:01 标签:Android登录 拦截器 Interceptor 对于App端来说,如果能保证用户在登录后能自动延续登录前的操作 ...

  6. flappy bird游戏源代码揭秘和下载后续---移植到android真机上

    前言:         上一篇博客 flappy bird游戏源代码揭秘和下载,源码是运行在window或者mac系统上的,现在我们需要把代码移植到android真机上,让小鸟在手机里飞起来! ps: ...

  7. 将tensorflow训练好的模型移植到Android (MNIST手写数字识别)

    将tensorflow训练好的模型移植到Android (MNIST手写数字识别) [尊重原创,转载请注明出处]https://blog.csdn.net/guyuealian/article/det ...

  8. cocos2d-x移植android,Cocos2d-x Xcode 移植到 Android stutio

    在写这篇文章  此刻的我心已是伤痕累累 一直从事iOS开发工作  经常使用的开发工具也自然 是Xcode 要想移植到Android studio  首先下载安装 Android studio 进入官网 ...

  9. 【建议收藏】2020年中高级Android大厂面试秘籍,为你保驾护航金三银四,直通大厂(Android高级篇上)...

    前言 成为一名优秀的Android开发,需要一份完备的知识体系,在这里,让我们一起成长为自己所想的那样~. A awesome android expert interview questions a ...

最新文章

  1. C#操作NPOI插件的HSSFWorkBook,常见的那些坑
  2. 8. An Introduction to MCMC for Machine Learning (5)
  3. Ardino基础教程 21_最简单最快控制LCD1602
  4. 史上最详细、最完全的ipython使用教程,Python使用者必备!
  5. JDK1.8源码(二)——java.lang.Integer 类
  6. java split()方法_Java编程性能优化一些事儿
  7. 退出所有循环_Python学习之路9—循环的总结
  8. python交互模式下tab键自动补全
  9. oracle11g的用户名是什么,oracle11g默认用户名和密码
  10. Java获取字符串信息
  11. 2012年4月份第2周51Aspx源码发布详情
  12. PHP最高权限的获取
  13. php screw 密钥,php-screw php代码加密工具用法(整理)
  14. 【JavaLearn】(24)Session、Cookie、ServletContext、MVC开发模式、JSP九大内建对象及四个作用域、JSTL及EL表达式、过滤器、监听器
  15. 白度云下载到存储卡的视频看不了_苹果手机从百度网盘下载的视频如何保存到相册,还有不知道的吗?...
  16. 2010提升你幽默感的经典短句!
  17. linux进程等待wait()实例
  18. 【论文笔记】(VLDB 2020) A Benchmarking Study of Embedding-based Entity Alignment for Knowledge
  19. 使用Python爬取中国天气网天气数据
  20. Quartz 任务调度全攻略【转】

热门文章

  1. 信号与系统——信号的分解
  2. 从escrow.com购买域名的经验
  3. tps5430手把手教学
  4. 机器学习专题之概率论——雅可比式
  5. github大文件上传:使用LFS (以及如何将lfs从仓库中移除!)
  6. LeetCode-Python-362. 敲击计数器
  7. Website Watchman for Mac(mac网站内容监控工具)
  8. c51单片机汇编语言语法错误,关于c51单片机交通灯汇编程序怎么加一个紧急状态按键的问题...
  9. Microsoft自家的虚拟光驱 Virtual CD-ROM Control Panel for Wind
  10. 原因: java.lang.NoClassDefFoundError: helloworld/Helloworld (wrong name: Helloworld)