Lumaqq移植到Android 之进阶篇

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

 

我们继续Lumaqq的移植旅程。今天将设计一个比较复杂的界面,来深入了解AndroidUI设计。

登录成功之后,我们就可以向QQ服务器发出各种请求,例如得到好友列表,得到分组信息,系统消息什么的。这方面Lumaqq给我们提供了很大的便利性,他把各种复杂的网络请求,分析数据包给封装了起来,例如请求好友列表可以使用QQClient类的user_GetList(),然后通过QQEvent的事件QQEvent.FRIEND_GET_LIST_OK就可以方便的得到好友列表信息了。

Android的程序设计有两个关键概念,一个称为Activity,一个称为Intent。一个应用程序可能由一组Activities组成,之间的通信请求通过Intent传递。每一个Activity代表一个用户所能看到的屏幕。这方面的知识网上有很多,看SDK也能很好的理解,程序员杂志在081月刊也有文章来介绍,我就不多说什么废话啦。

我们现在的Lumaqq由两个Activity组成,一个是QQLogin,它功能是提供登录界面。作为Sub Activity,由主Activity启动调用。另一个是主Activity,功能是提供系统菜单,处理各种QQEnent,显示好友列表。

  1. QQLogin类
  2. public class QQLogin extends Activity {
  3.     @Override
  4.     protected void onCreate(Bundle savedInstanceState) {
  5.         // TODO Auto-generated method stub
  6.         super.onCreate(savedInstanceState);
  7.         setContentView(R.layout.main);
  8.         findViews();
  9.         setListeners();
  10.     }
  11.     private Button button_test;
  12.     private EditText field_qqID;
  13.     private EditText field_qqPwd;
  14.     private void findViews() {
  15.         button_test = (Button) findViewById(R.id.submit);
  16.         field_qqID = (EditText) findViewById(R.id.qqID);
  17.         field_qqPwd = (EditText) findViewById(R.id.qqPwd);
  18.     }
  19.     private void setListeners() {
  20.         button_test.setOnClickListener(testLumaQQ);
  21.     }
  22.     private OnClickListener testLumaQQ = new OnClickListener() {
  23.         @Override
  24.         public void onClick(View v) {
  25.             // TODO Auto-generated method stub
  26.             // Bundle数据容器类,类似于key/value键值对,但比之更强大
  27.             Bundle myBundle = new Bundle();
  28.             myBundle.putInt("qqNum", Util.getInt(field_qqID.getText().toString(), -1));
  29.             myBundle.putString("qqPwd", field_qqPwd.getText().toString());
  30.             Intent mIntent = new Intent();
  31.          mIntent.putExtras(myBundle);
  32.          setResult(RESULT_OK, mIntent);
  33.          finish();
  34.         }
  35.     };
  36. }
 

Activity lumaqqMe,我们的主Activity继承自ListActivity,这个提供了一个ListView和一些函数,让我们很方便的添加一个列表进去。

  1. public class lumaqqMe extends ListActivity implements IQQListener {
  2.     /** Called when the activity is first created. */
  3.     @Override
  4.     public void onCreate(Bundle savedInstanceState) {
  5.         super.onCreate(savedInstanceState);
  6.         setContentView(R.layout.list);
  7.         //设置系统菜单
  8.         getListView().setOnCreateContextMenuListener(this);
  9.         //初始化
  10.         initialize();
  11.     }
  12.     private QQClient client;
  13.     private String resultStr;
  14.     private List<String> UserList;
  15.  //Sub Activity Code
  16.     private static final int ACTIVITY_LOGIN = 1000;
  17.  //菜单ID
  18.     public static final int LOGIN_ID = Menu.FIRST;
  19.     public static final int EXIT_ID = Menu.FIRST + 1;
  20.     private void initialize() {
  21.         client = new QQClient();
  22.         resultStr = "";
  23.         UserList = new ArrayList<String>();
  24.     }
  25.  //检查登录,如果已登录就返回
  26.     private void checkLogin(int qq, String pwd) {
  27.         if (client.isLogging())
  28.             return;
  29.         client.setConnectionPoolFactory(new PortGateFactory());
  30.         QQUser user = new QQUser(qq, pwd);
  31.         // 设置参数
  32.         client.addQQListener(this);
  33.         user.setUdp(true);
  34.         client.setUser(user);
  35.         client.setLoginServer("sz.tencent.com");
  36.         try {
  37.             // 登录
  38.             client.login();
  39.         } catch (Exception e1) {
  40.         }
  41.     }
  42.     @Override
  43.     public void qqEvent(QQEvent e) {
  44.         // TODO Auto-generated method stub
  45.         switch (e.type) {
  46.         case QQEvent.LOGIN_OK:
  47.             processLoginSuccess();
  48.             break;
  49.         case QQEvent.LOGIN_FAIL:
  50.             processLoginFail(e);
  51.             break;
  52.         case QQEvent.LOGIN_UNKNOWN_ERROR:
  53.             processLoginUnknownError();
  54.             break;
  55.         case QQEvent.IM_SEND_OK:
  56.             processSendIMSuccess();
  57.             break;
  58.         case QQEvent.USER_STATUS_CHANGE_OK:
  59.             processChangeStatusSuccess();
  60.             break;
  61.         case QQEvent.USER_STATUS_CHANGE_FAIL:
  62.             processChangeStatusFail();
  63.             break;
  64.         case QQEvent.SYS_TIMEOUT:
  65.             switch (e.operation) {
  66.             case QQ.QQ_CMD_GET_FRIEND_LIST:
  67.                 processGetFriendListTimeout(e);
  68.             case QQ.QQ_CMD_SEND_IM:
  69.                 processSendIMFail();
  70.             }
  71.             break;
  72.         case QQEvent.FRIEND_GET_LIST_OK:
  73.             processGetFriendListSuccess(e);
  74.             break;
  75.         }
  76.     }
  77.     /**
  78.      * 处理得到好友列表超时事件,我们简单得重发超时的包
  79.      * 
  80.      * @param e
  81.      *            QQEvent
  82.      */
  83.     private void processGetFriendListTimeout(QQEvent e) {
  84.         client.sendPacket((OutPacket) e.getSource());
  85.     }
  86.     /**
  87.      * 初始改变状态失败事件
  88.      */
  89.     private void processChangeStatusFail() {
  90.         resultStr = getText(R.string.message_box_status_change_fail).toString();
  91.         handler.sendEmptyMessage(0);
  92.         client.logout();
  93.         client.release();
  94.     }
  95.     /**
  96.      * 处理改变状态成功事件
  97.      */
  98.     private void processChangeStatusSuccess() {
  99.         resultStr = getText(R.string.message_box_status_change_ok).toString();
  100.         handler.sendEmptyMessage(0);
  101.         //请求好友列表
  102.         client.user_GetList();
  103.     }
  104.     /**
  105.      * 处理发送消息失败事件
  106.      */
  107.     private void processSendIMFail() {
  108.         resultStr = getText(R.string.message_box_sys_timeout).toString();
  109.         handler.sendEmptyMessage(0);
  110.         client.logout();
  111.         client.release();
  112.     }
  113.     /**
  114.      * 处理发送消息成功事件
  115.      */
  116.     private void processSendIMSuccess() {
  117.         resultStr = getText(R.string.message_box_send_ok).toString();
  118.         handler.sendEmptyMessage(0);
  119.         client.logout();
  120.         client.release();
  121.     }
  122.     /**
  123.      * 处理登陆成功事件
  124.      */
  125.     private void processLoginSuccess() {
  126.         if (!client.getUser().isLoggedIn()) {
  127.             resultStr = getText(R.string.message_box_login_success).toString();
  128.             handler.sendEmptyMessage(0);
  129.         }
  130.     }
  131.     /**
  132.      * 处理登陆密码错误事件
  133.      * 
  134.      * @param e
  135.      */
  136.     private void processLoginFail(QQEvent e) {
  137.         resultStr = getText(R.string.message_box_login_fail).toString();
  138.         handler.sendEmptyMessage(0);
  139.     }
  140.     /**
  141.      * 处理登陆未知错误事件
  142.      */
  143.     private void processLoginUnknownError() {
  144.         resultStr = getText(R.string.message_box_unknown_error).toString();
  145.         handler.sendEmptyMessage(0);
  146.     }
  147.     /**
  148.      * 处理得到好友列表成功事件
  149.      */
  150.     private void processGetFriendListSuccess(QQEvent e) {
  151.         GetFriendListReplyPacket packet = (GetFriendListReplyPacket)e.getSource();
  152.         for (QQFriend friend : packet.friends) {
  153.             UserList.add(friend.nick);
  154.         }
  155.         // 如果是得到好友列表结束事件,返回
  156.         if (packet.position == QQ.QQ_POSITION_FRIEND_LIST_END) {
  157.             handler1.sendEmptyMessage(0);
  158.         } else
  159.             client.user_GetList(packet.position);
  160.     }
  161.     private Handler handler = new Handler() {
  162.         @Override
  163.         public void handleMessage(Message msg) {
  164.             // TODO Auto-generated method stub
  165.             new AlertDialog.Builder(lumaqqMe.this).setPositiveButton("ok",
  166.                     new DialogInterface.OnClickListener() {
  167.                         @Override
  168.                         public void onClick(DialogInterface dialog, int which) {
  169.                             // TODO Auto-generated method stub
  170.                         }
  171.                     }).setMessage(resultStr).show();
  172.             super.handleMessage(msg);
  173.         }
  174.     };
  175.     private Handler handler1 = new Handler() {
  176.         @Override
  177.         public void handleMessage(Message msg) {
  178.             // TODO Auto-generated method stub
  179.             ArrayAdapter<String> adapter = new ArrayAdapter<String>(
  180.                     lumaqqMe.this, android.R.layout.simple_list_item_1,
  181.                     UserList);
  182.             setListAdapter(adapter);
  183.             super.handleMessage(msg);
  184.         }
  185.     };
  186.     @Override
  187.     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  188.         // TODO Auto-generated method stub
  189.         super.onActivityResult(requestCode, resultCode, data);
  190.         Bundle bundle = data.getExtras();
  191.         if (requestCode == ACTIVITY_LOGIN) {
  192.             if (resultCode == RESULT_OK) {
  193.                 int qqnum = bundle.getInt("qqNum");
  194.                 String qqpwd = bundle.getString("qqPwd");
  195.                 checkLogin(qqnum, qqpwd);
  196.             }
  197.         }
  198.     }
  199.     @Override
  200.     public boolean onCreateOptionsMenu(Menu menu) {
  201.         // TODO Auto-generated method stub
  202.         boolean result = super.onCreateOptionsMenu(menu);
  203.         menu.add(0, LOGIN_ID, 0, R.string.menu_login);
  204.         menu.add(0, EXIT_ID, 0, R.string.menu_exit);
  205.         return result;
  206.     }
  207.     @Override
  208.     public boolean onMenuItemSelected(int featureId, MenuItem item) {
  209.         // TODO Auto-generated method stub
  210.         switch (item.getItemId()) {
  211.         case LOGIN_ID:
  212.             startActivityForResult(new Intent(this, QQLogin.class),
  213.                     ACTIVITY_LOGIN);
  214.             return true;
  215.         case EXIT_ID:
  216.             client.logout();
  217.             client.release();
  218.             finish();
  219.             return true;
  220.         }
  221.         return super.onMenuItemSelected(featureId, item);
  222.     }
  223. }
 

让我们来看看界面大概什么样吧。

主界面

登录界面

登录成功之后得到好友列表

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值