http://my.eoe.cn/android_zyz/archive/3394.html
第一步:编写实体类User、FCMessage、Sex,参考足迹一里面的实体类
第二步:编写登陆界面(参考QQ)login.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/login_bg"
android:orientation="vertical" >
<!-- 头像 -->
<ImageButton
android:id="@+id/login_head"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="50dp"
android:background="#00000000"
android:src="@drawable/login_default_avatar" />
<!-- 账号 -->
<AutoCompleteTextView
android:id="@+id/login_account"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/login_head"
android:layout_centerHorizontal="true"
android:layout_marginBottom="-4dp"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:layout_marginTop="10dp" />
<!-- 密码 -->
<EditText
android:id="@+id/login_pwd"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/login_account"
android:layout_centerHorizontal="true"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:layout_marginTop="-4dp"
android:hint="@string/login_pwd_hint"
android:inputType="textPassword" />
<!-- 登陆按钮 -->
<Button
android:id="@+id/login_btn_logining"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/login_pwd"
android:layout_centerHorizontal="true"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:background="@drawable/login_button_nor"
android:text="@string/btn_login" />
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@id/login_btn_logining"
android:layout_centerHorizontal="true"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:layout_marginTop="5dp" >
<!-- 取回密码 -->
<Button
android:id="@+id/login_btn_getbackpwd"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentLeft="true"
android:layout_marginLeft="20dp"
android:background="#00000000"
android:text="@string/get_pwd"
android:textColor="#ffffff"
android:textSize="15sp" />
<!-- 登录设置 -->
<Button
android:id="@+id/login_btn_setlogin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_marginRight="20dp"
android:background="#00000000"
android:text="@string/set_login"
android:textColor="#ffffff"
android:textSize="15sp" />
</RelativeLayout>
<!-- 跳转注册界面 -->
<Button
android:id="@+id/login_btn_to_register"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginLeft="30dp"
android:layout_marginRight="30dp"
android:background="@drawable/login_btn_register"
android:text="@string/btn_register" />
</RelativeLayout>
|
效果图:
第三步:编写java代码类LoginActivity
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 |
package com.durian.fc;
import java.util.ArrayList;
import java.util.List;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.Toast;
import com.durian.fc.entity.User;
import com.durian.fc.service.FCClient;
public class LoginActivity extends Activity {
// 用户的头像
private ImageButton userHead;
// 用户的账号
private AutoCompleteTextView userAccount;
// 用户密码
private EditText userPwd;
// 登陆按钮、取回密码按钮、登录设置按钮、注册登录按钮
private Button btnLogining, btnGetBackPwd, btnSetLogin, btnToRegister;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.login);
//初始化界面控件
initView();
//添加监听响应事件
addListener();
}
/**
* 初始化所有控件
*/
private void initView() {
userHead = (ImageButton) findViewById(R.id.login_head);
userAccount = (AutoCompleteTextView) findViewById(R.id.login_account);
userPwd = (EditText) findViewById(R.id.login_pwd);
btnLogining = (Button) findViewById(R.id.login_btn_logining);
btnGetBackPwd = (Button) findViewById(R.id.login_btn_getbackpwd);
btnSetLogin = (Button) findViewById(R.id.login_btn_setlogin);
btnToRegister = (Button) findViewById(R.id.login_btn_to_register);
}
private void addListener() {
//添加登陆按钮监听事件
btnLogining.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
//获取用户输入的账号
int account = Integer
.parseInt(userAccount.getText().toString());
//获取用户输入的密码
String password = userPwd.getText().toString();
//调用登录方法
login(account, password);
}
});
}
/**
* 登录方法
* 该方法用于将用户输入的账号和密码发送到服务端,并对服务端返回的数据进行处理
* @param account 账号
* @param password 密码
*/
protected void login(int account, String password) {
//创建一个用户,用于向服务端发送数据时,存放的实体
User user = new User();
user.setAccount(account);
user.setPassword(password);
user.setOperation("login");
//调用服务方法,向服务端发送数据,如果服务端返回true表示登陆成功,false表示登录失败
boolean b = new FCClient().sendLoginInfo(user);
if (b) {//如果登陆成功
try {
// 发送一个要求返回在线好友的请求的message
// --- <span style="white-space:pre"> </span>
} catch (Exception e) {
e.printStackTrace();
}
Intent intent = new Intent(this, TestActivity.class);
//new一个Bundle对象,并将要传递的数据传入
Bundle bundle = new Bundle();
bundle.putInt("account", account);
bundle.putString("password", password);
//将bundle对象assign给Intent
intent.putExtras(bundle);
//开启跳转
startActivity(intent);
} else {//登录失败,通过Toast向用户提示登录失败
Toast.makeText(this, "登录失败,不告诉你为什么...", Toast.LENGTH_LONG).show();
}
}
}
|
第四步:编写一个客户端的service业务类
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
package com.durian.fc.service;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.OptionalDataException;
import java.io.Serializable;
import java.io.StreamCorruptedException;
import java.net.InetSocketAddress;
import java.net.Socket;
import android.util.Log;
import com.durian.fc.entity.FCMessage;
public class FCClient implements Serializable{
public Socket s;
/**
* 向服务器发送数据
*/
public boolean sendLoginInfo(Object obj){
boolean b = false;
try {
try {
//设置服务端的dstName和dstPost
s = new Socket("192.168.1.101", 9999);
} catch (IOException e) {
e.printStackTrace();
//连接服务器超时
return false;
}
//输出发送
ObjectOutputStream oos = new ObjectOutputStream(s.getOutputStream());
oos.writeObject(obj);
//接收服务端的响应
ObjectInputStream ois = new ObjectInputStream(s.getInputStream());
FCMessage msg = (FCMessage)ois.readObject();
//如果服务端返回SUCCESS时
if(FCMessage.SUCCESS.equals(msg.getType())){
//创建一个该账号和服务器保持连接的线程
//待定
b = true;
}else if(FCMessage.FAIL.equals(msg.getType())){
b = false;
}
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
return b;
}
}
|
第五步:编写一个用于表示登陆成功的界面test.xml布局
1 2 3 4 5 6 7 8 9 10 11 |
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/tv_test"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="欢迎"/>
</LinearLayout>
|
第六步:编写相应的java代码TestActivity
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
package com.durian.fc;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;
public class TestActivity extends Activity {
private TextView tvTest;
@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
//初始化界面
initView();
//初始化数据
initData();
}
private void initData() {
//获取从上一个界面传递过来的数据
Bundle bundle = this.getIntent().getExtras();
//定义一个字符串用于显示用户的信息账号
String text = tvTest.getText().toString();
text = text + bundle.getInt("account") + "登陆";
//设置TextView显示的文本信息
tvTest.setText(text);
}
private void initView() {
//通过id获取组件的实例
tvTest = (TextView)findViewById(R.id.tv_test);
}
}
|
第七步:在AndroidManifest.xml定义新的Activity:TestActivity,并添加一个INTERNET的权限
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.durian.fc"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="10" />
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@android:style/Theme.NoTitleBar" >
<activity
android:name="com.durian.fc.LoginActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="MainActivity"/>
<activity android:name="TestActivity"/>
</application>
</manifest>
|
第八步:测试
服务端开启socket,运行LoginServerTest类
运行安装客户端到虚拟机
登录失败时
登陆成功时
至此,客户端与服务端之间的socket就可以实现登录功能!!!