天天看点

五:基于XMPP的smack登录

    本篇写基于XMPP的登录。

1、需要准备一个asmack.jar包

      下载地址:

      http://download.csdn.net/detail/liaowx/7692091

2、新建一个Android工程,命名为IMTest,把下载的asmack包导入的项目中,我改了一下包名:org.hkby.lwx.activity和第一个MainActivity的名为LoginActivity.

3、打开上一篇下载的smack文档,看一下ConnectionConfiguration和XMPPConnection类,我就不解释了,代码里的注释已经很清楚了,ok,开始写代码。

4、登录界面

五:基于XMPP的smack登录

登录界面的xml代码:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".LoginActivity" >

    <ImageView
        android:id="@+id/im_headIcon"
        android:layout_width="120dp"
        android:layout_height="120dp"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:layout_marginTop="32dp"
        android:contentDescription="@string/description"
        android:src="@drawable/headicon" />

    <TextView
        android:id="@+id/tv_login_account"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/im_headIcon"
        android:layout_marginTop="34dp"
        android:layout_toLeftOf="@+id/im_headIcon"
        android:text="@string/account"
        android:textSize="20sp" />

    <EditText
        android:id="@+id/et_login_account"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/tv_login_account"
        android:layout_alignParentRight="true"
        android:layout_toRightOf="@+id/tv_login_account"
        android:ems="10"
        android:hint="@string/et_account"
        android:textSize="14sp" >


        <requestFocus />
    </EditText>

    <TextView
        android:id="@+id/tv_login_password"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/tv_login_account"
        android:layout_below="@+id/tv_login_account"
        android:layout_marginTop="26dp"
        android:text="@string/password"
        android:textSize="20sp" />

    <EditText
        android:id="@+id/et_login_password"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBottom="@+id/tv_login_password"
        android:layout_alignLeft="@+id/et_login_account"
        android:layout_alignParentRight="true"
        android:ems="10"
        android:hint="@string/et_password"
        android:inputType="textPassword"
        android:textSize="12sp" />

    <Button
        android:id="@+id/btn_login"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignLeft="@+id/tv_login_password"
        android:layout_below="@+id/tv_login_password"
        android:layout_marginTop="40dp"
        android:paddingLeft="30sp"
        android:paddingRight="30sp"
        android:text="@string/login"
        android:textSize="20sp" />

    <Button
        android:id="@+id/btn_register"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignBaseline="@+id/btn_login"
        android:layout_alignBottom="@+id/btn_login"
        android:layout_alignParentRight="true"
        android:layout_marginRight="20dp"
        android:paddingLeft="30sp"
        android:paddingRight="30sp"
        android:text="@string/register"
        android:textSize="20sp" />

</RelativeLayout>
           

5、values下string.xml的代码:

<?xml version="1.0" encoding="utf-8"?>
<resources>

    <string name="app_name">IMTest</string>
    <string name="action_settings">Settings</string>
    <string name="hello_world">Hello world!</string>
    <!-- login -->
    <string name="description">headIcon</string>
    <string name="account">账号:</string>
    <string name="et_account">请输入账号</string>
    <string name="password">密码:</string>
    <string name="et_password">请输入密码</string>
    <string name="login">登录</string>
    <string name="register">注册</string>
    <string name="isEmpty">账号或密码不能为空!</string>
    <string name="fail">登录失败!</string>
    <string name="success">登录成功!</string>

</resources>
           

6、登录的java代码,LoginActivity.java:

package org.hkby.lwx.activity;

import org.hkby.lwx.task.LoginTask;

import android.app.Activity;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
/**
 * Login
 * @author liaowuxing
 *
 */
public class LoginActivity extends Activity {
	/**
	 * Called when this activity is first created.
	 */
	private EditText et_acount, et_password;
	private Button btn_login, btn_register;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		//Remove the title bar
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_login);
		//Initialize the view
		initView();
		//Initialize the click
		initClick();
	}

	public void initView() {
		et_acount = (EditText) this.findViewById(R.id.et_login_account);
		et_password = (EditText) this.findViewById(R.id.et_login_password);
		btn_login = (Button) this.findViewById(R.id.btn_login);
		btn_register = (Button) this.findViewById(R.id.btn_register);
	}

	public void initClick() {
		//loginButton's ClickListener
		btn_login.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				String account = et_acount.getText().toString();
				String password = et_password.getText().toString();
				if (account.equals("") || password.equals("")) {
					Toast.makeText(LoginActivity.this, R.string.isEmpty,
							Toast.LENGTH_SHORT).show();
				} else {
					LoginTask loginTask = new LoginTask(LoginActivity.this);
					boolean isSuccess = loginTask.getExecute(account, password);
					if (isSuccess == true) {
						//save account
						SharedPreferences sp = getSharedPreferences("username",
								Activity.MODE_PRIVATE);
						Editor editor = sp.edit();
						editor.putString("account", account);
						editor.commit();
						//Enter the main interface
						Intent intent = new Intent();
						intent.setClass(LoginActivity.this, MainTabActivity.class);
						startActivity(intent);
					}else {
						Toast.makeText(LoginActivity.this, R.string.fail, Toast.LENGTH_SHORT).show();
					}
				}
			}
		});
		//registerButton's ClickListener
		btn_register.setOnClickListener(new OnClickListener() {

			@Override
			public void onClick(View v) {
				//Enter the register interface
				Intent intent = new Intent();
				intent.setClass(LoginActivity.this, RegistActivity.class);
				startActivity(intent);
			}
		});
	}
}
           

7、新建一个包org.hkby.lwx.task用于放异步任务,LoginTask.java代码:

<pre name="code" class="java">package org.hkby.lwx.task;

import java.util.concurrent.ExecutionException;

import org.hkby.lwx.common.XmppTool;

import android.content.Context;
import android.os.AsyncTask;
import android.widget.Toast;
/**
 * login AsyncTask
 * @author liaowuxing
 *
 */
public class LoginTask {
	private Context context;

	public LoginTask(Context context) {
		super();
		this.context = context;
	}
	
	public boolean getExecute(String account,String password){
		AsyncTask<String, Void, Boolean> async = new LoginAsync().execute(account,password);
		try {
			boolean isSuccess = async.get();
			return isSuccess;
		} catch (InterruptedException e) {
			e.printStackTrace();
			return false;
		} catch (ExecutionException e) {
			e.printStackTrace();
			return false;
		}
	}
	public class LoginAsync extends AsyncTask<String, Void, Boolean> {

		@Override
		protected Boolean doInBackground(String... params) {
			boolean isLogin = XmppTool.logins(params[0], params[1]);
			if (isLogin == true) {
				return true;
			}
			return false;
		}

		@Override
		protected void onPostExecute(Boolean result) {
			super.onPostExecute(result);
			if (result == true) {
				Toast.makeText(context, "登录成功!", Toast.LENGTH_SHORT)
						.show();
			} else {
				Toast.makeText(context,"登录失败!", Toast.LENGTH_SHORT)
						.show();
			}
		}
	}
}
           

8、新建一个包org.hkby.lwx.common用于放工具类,静态常量等,登录最关键的代码XmppTool.java,链接和登录到服务器。

package org.hkby.lwx.common;

import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;

/**
 * Xmpp Tool
 * 
 * @author liaowuxing
 * 
 */
public class XmppTool {

	private static XMPPConnection connection = null;

	/**
	 * open connection
	 */
	private static void openConnection() {
		try {
			if (null == connection || !connection.isAuthenticated()) {
				// Create the configuration for this new connection
				ConnectionConfiguration config = new ConnectionConfiguration(
						Constant.HOST, Constant.PORT);
				// Sets if the connection is going to use stream
				// compression.
				config.setCompressionEnabled(false);
				// Sets if the new connection about to be establish is going to
				// be debugged.
				config.setDebuggerEnabled(false);
				// Sets if the reconnection mechanism is allowed to be used.
				config.setReconnectionAllowed(true);
				// Sets if the enable security verification
				config.setSASLAuthenticationEnabled(false);
				// Sets the TLS security mode used when making the connection.
				config.setSecurityMode(ConnectionConfiguration.SecurityMode.disabled);
				// Sets if an initial available presence will be sent to the
				// server.
				config.setSendPresence(true);
				connection = new XMPPConnection(config);
				// Connect to the server
				connection.connect();
			}
		} catch (XMPPException xe) {
			xe.printStackTrace();
		}
	}

	/**
	 * create connection
	 * @return
	 */
	public static XMPPConnection getConnection() {
		if (connection == null) {
			openConnection();
		}
		return connection;
	}

	/**
	 * close connection
	 */
	public static void closeConnection() {
		if (connection != null) {
			if (connection.isConnected()) {
				//Disconnect from the server
				connection.disconnect();
				connection = null;
			}
		}
	}

	/**
	 * login
	 * @param username
	 * @param password
	 * @return
	 */
	public static boolean logins(String username, String password) {
		if (getConnection() == null) {
			return false;
		}
		try {
			//Log into the server
			getConnection().login(username, password);
			return true;
		} catch (XMPPException e) {
			e.printStackTrace();
		}
		return false;
	}
}
           

9、从登录界面跳转到主界面,暂时先不写,主界面我想用TabHost,所有命名为MainTabActivity.java,代码:

package org.hkby.lwx.activity;

import org.hkby.lwx.common.XmppTool;

import android.app.TabActivity;
import android.os.Bundle;
import android.view.Window;
/**
 * main 
 * @author liaowuxing
 *
 */
@SuppressWarnings("deprecation")
public class MainTabActivity extends TabActivity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// Remove the title bar
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		setContentView(R.layout.activity_maintab);
	}

	@Override
	public void onBackPressed() {
		super.onBackPressed();
		if (XmppTool.getConnection() != null) {
			XmppTool.closeConnection();
		}
	}
}
           

10、activity_maintab.xml代码:

<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@android:id/tabhost"
    android:layout_width="match_parent"
    android:layout_height="match_parent" >

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical" >

        <FrameLayout
            android:id="@android:id/tabcontent"
            android:layout_width="match_parent"
            android:layout_height="0dp"
            android:layout_weight="1" />

        <TabWidget
            android:id="@android:id/tabs"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:visibility="gone" />
    </LinearLayout>

</TabHost>
           

11、注册界面:RegistActivity.java,下回再写。

<pre name="code" class="java">package org.hkby.lwx.activity;

import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import android.widget.TextView;
/**
 * register
 * @author liaowuxing
 *
 */
public class RegistActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		// Remove the title bar
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		TextView tv_test = new TextView(RegistActivity.this);
		setContentView(tv_test);
	}
}
           

12、现在你只需要改Constant.java文件里的HOST改为你自己的主机ip就可以了。

package org.hkby.lwx.common;

public class Constant {
	//server host
	public static final String HOST = "192.168.1.105";
	//openfire server port
	public static final int PORT = 5222;
}
           

13、写完之后的结构是这样的:

五:基于XMPP的smack登录

14、ok,登陆写完了,测试一下,运行项目,登陆成功后,打开openfire,刷新一下,你会发现,你登陆的用户前面的小人变绿了。