Android NFC自动连接Wifi网络进行Socket TCP通信

    最近在做一个Android的项目,程序还是只是一个试验品,但是关键点已经实现了,很多东西都是取自网络,现在分享一下:

【AndroidManifest.xml】:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.rengh.android.test"
    android:versionCode="1"
    android:versionName="1.0" >

<!-- 权限申请,第一个是NFC相关;然后是两个wifi和两个网络部分的权限,最后一个INTERNET是创建Socket需要的权限; --> <uses-permission android:name="android.permission.NFC" /> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="18" /> <application android:allowBackup="true" android:icon="@drawable/ic_launcher" android:label="@string/app_name" android:theme="@style/AppTheme" > <activity android:name="com.rengh.android.test.MainActivity" android:label="@string/app_name" android:launchMode="singleTop" android:multiprocess="true" android:screenOrientation="portrait" android:stateNotNeeded="true" android:theme="@android:style/Theme.NoTitleBar" > <!-- portrait是限制为竖屏 --> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter>
<!-- NDEF过滤;优先级高;用来注册,告诉系统能够处理扫描到的NDEF消息; --> <intent-filter> <action android:name="android.nfc.action.NDEF_DISCOVERED" /> <category android:name="android.intent.category.DEFAULT" /> <data android:mimeType="text/plain" /> </intent-filter>
</activity> </application> </manifest>

【MainActivity.java】处理NFC消息自动连接Wifi:

package com.rengh.android.test;

import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.nfc.NdefMessage;
import android.nfc.NfcAdapter;
import android.nfc.tech.NfcF;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Parcelable;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.IntentFilter.MalformedMimeTypeException;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

/* 继承 Activity类,继承Button.OnClickListener接口;*/
@SuppressLint({ "ShowToast", "HandlerLeak" })
public class MainActivity extends Activity implements Button.OnClickListener {
    /*
     * i*命名的整型变量代表主界面底部三个按钮被按下的次数; startActivityTime为时间值,单位毫秒;
     */
    private int iAll = 0, iDefault = 0, iWhere = 0, startActivityTime = 2000;
    /* 定义各个界面的按钮; */
    private Button btnAll, btnDefault, btnWhere, btnToOneActivity,
            btnOneToMainActivity, btnController, btnOneToSocketActivity;
    /* 定义主界面的三个TextView组件; */
    private TextView textView_all, textView_default, textView_where;
    /* 定义当前设备的NfcAdapter; */
    private NfcAdapter mNfcAdapter;
    /* */
    private IntentFilter[] intentFiltersArray;
    /* */
    private PendingIntent pendingIntent;
    /* */
    private String[][] techListsArray;
    /* 定义从NFC标签读取到的字符串; */
    private String nfcStr = null;
    private String fenGeFu = "\\*";
    /*
     * 定义Socket通信界面上的两个文本框,一个由用户输入信息, 一个显示服务器发送的消息;
     */
    EditText inputText;
    TextView showText;
    /* 定义Socket通信界面上的一个按钮; */
    Button btnSendText, btnToMainActivity;
    /* 定义Socket通信用到的Handler对象 */
    Handler handler;
    /* 定义与服务器通信的子线程; */
    ClientThread clientThread;
    int isWifiEnableStatue = 0, isWifiConnectedStatue = 0, nfcStatue;
    public static int socketStatue = 0;

    /**
     * 默认配置,测试时使用!!!
     */
    String mSSID = "RhkySocket", mPASSWORD = "flamingoeda";
    int mTYPE = 3;
    String deviceName = "Test-PC", ipAdress = "192.168.1.109";
    int post = 30000;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.start);

        /*
         * 在显示开始界面的情况下后台启动主界面, 直到过了startActivityTime时间后显示主界面;
         */
        Handler x = new Handler();
        x.postDelayed(new defaultStartApp(), startActivityTime);

        /* NFC相关; */
        nfcManager();

        /* 记录使用前wifi的状态; */
        if (isWifiEnabled()) {
            isWifiEnableStatue = -1;
        }
        if (isWifiConnect()) {
            isWifiConnectedStatue = -1;
        }

        nfcStatue = 0;
    }

    /* 手动启动本程序调用,后台加载主界面; */
    class defaultStartApp implements Runnable {
        public void run() {
            setContentView(R.layout.main);
            /* 设置layout_main.xml布局中的按钮和TextView控件; */
            setMainActivityButtonAndTextView();

            /*
             * 无NFC手机测试wifi自动连接使用,需要更改初始值为所用路由器无线信息;
             */
            // AutoWifi(mSSID, mPASSWORD, mTYPE);
            // connectedSocketServer(deviceName, ipAdress, post);
        }
    }

    /*
     * nfc启动程序时调用,根据读取到的信息,后台运行连接wifi网络操作。 不后台运行的话会导致开始界面加载失败;
     */
    class nfcStartApp implements Runnable {
        public void run() {
            sendConfigToAutoWifi(nfcStr);
            /*
             * 将无线网络名称str[0]、无线网络密码str[1]、 无线加密类型str[2],传递给AutoWifi方法;
             */
            AutoWifi(mSSID, mPASSWORD, mTYPE);
            connectedSocketServer(deviceName, ipAdress, post);
        }
    }

    /* NFC标签读取; */
    protected void nfcManager() {
        mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
        if (mNfcAdapter == null) {
            Toast.makeText(this, "本设备不支持NFC功能", Toast.LENGTH_LONG).show();
        }
        pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this,
                getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);

        IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
        try {
            ndef.addDataType("*/*");
        } catch (MalformedMimeTypeException e) {
            throw new RuntimeException("fail", e);
        }
        intentFiltersArray = new IntentFilter[] { ndef, };
        techListsArray = new String[][] { new String[] { NfcF.class.getName() } };
    }

    @Override
    public void onResume() {
        super.onResume();
        /* 启用nfc前台调度,保证程序开启状态下优先处理nfc包含的消息; */
        if (mNfcAdapter != null) {
            mNfcAdapter.enableForegroundDispatch(this, pendingIntent,
                    intentFiltersArray, techListsArray);
        }
        /* 能够将intent从外部传递到程序; */
        if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())
                && (nfcStatue == 0)) {
            // 调用ndef消息的处理方法;
            processIntent(getIntent());
        }
    }

    /* 有新的intent时调用; */
    @Override
    public void onNewIntent(Intent intent) {
        /* 调用ndef消息的处理方法; */
        processIntent(intent);
    }

    /* 定义ndef消息的处理方法; */
    private void processIntent(Intent intent) {
        Parcelable[] rawMsgs = intent
                .getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
        NdefMessage msg = (NdefMessage) rawMsgs[0];
        /* 提取NdefMessage消息的正文赋给字符串nfcStr; */
        nfcStr = new String(msg.getRecords()[0].getPayload());
        /* 后台调用nfcStartApp()方法,分析读到的消息并开始wifi连接; */
        Handler x = new Handler();
        x.postDelayed(new nfcStartApp(), startActivityTime);
    }

    /* 将nfc读到的消息分解后传递给AutoWifi方法进行自动连接; */
    public void sendConfigToAutoWifi(String nfcStr) {
        /*
         * nfcStr = "Ren-gh_ren.gh.1989_3_A1_192.168.1.253_30000";
         * 代表含义依次为:无线网络名称, 无线网络密码, 无线加密方式,设备名称,设备IP,设备端口号;
         * 将nfcStr字符串分解为多个字符串存到str字符串数组里;
         */
        String str[];
        str = nfcStr.split(fenGeFu);
        mSSID = str[0];
        mPASSWORD = str[1];
        mTYPE = Integer.valueOf(str[2]);
        deviceName = str[3];
        ipAdress = str[4];
        post = Integer.valueOf(str[5]);
        /* 清空nfcStr字符串 */
        nfcStr = "";
        ++nfcStatue;
    }

    /* 根据传递过来的三个无线网络参数连接wifi网络; */
    private void AutoWifi(String ssid, String passwd, Integer type) {
        /*
         * 创建对象,打开wifi功能,等到wifi启动完成后将传递来的wifi网络添加进Network,
         * 然后等待连接诶成功后,传递设备名称,设备IP,设备端口号给connectedSocketServer方法,
         * 用来连接远程Socket服务器;Integer.valueOf(str[5])是将字符串转换为整型;
         */
        /**
         * 定义AutoWifiConfig对象,通过该对象对wifi进行操作; WifiConfig myWifi = new
         * WifiConfig(this); 不能用作全局,不然会出现刷nfc连接wifi,连接到socket,再刷nfc时程序卡死的情况;
         */
        WifiConfig myWifi = new WifiConfig(this);
        Boolean b;
        if (!isWifiEnabled()) {
            isWifiEnableStatue = 1;
            myWifi.openWifi();
            do {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                b = isWifiEnabled();
            } while (!b);
        }
        if (!isWifiConnect() || !myWifi.getSSID().equals(ssid)) {
            myWifi.addNetwork(myWifi.CreateWifiInfo(ssid, passwd, type));
            do {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                b = isWifiConnect();
            } while (!b);
            isWifiConnectedStatue = 1;
        }
    }

    /* 检查wifi是否可用;是则返回true; */
    public boolean isWifiEnabled() {
        ConnectivityManager connManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
        NetworkInfo mWifi = connManager
                .getNetworkInfo(ConnectivityManager.TYPE_WIFI);
        return mWifi.isAvailable();
    }

    /* 检查wifi是否连接成功;成功则返回true; */
    public boolean isWifiConnect() {
        ConnectivityManager connManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
        NetworkInfo mWifi = connManager
                .getNetworkInfo(ConnectivityManager.TYPE_WIFI);
        return mWifi.isConnected();
    }

    /* 根据第二和第三个参数连接远程设备的Socket服务器; */
    public void connectedSocketServer(String deviceName, String ipAdress,
            int post) {
        /* 加载socket通信的界面; */
        setContentView(R.layout.socket);

        inputText = (EditText) findViewById(R.id.inputText);
        btnSendText = (Button) findViewById(R.id.btnSendText);
        showText = (TextView) findViewById(R.id.showText);
        btnToMainActivity = (Button) findViewById(R.id.btnSocketToMainActivity);
        btnToMainActivity.setOnClickListener(this);

        handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                // 如果消息来自于子线程
                if (msg.what == 0x123) {
                    String recvString = msg.obj.toString();
                    if (!recvString.equals("0x123 close")) {
                        // 将读取的内容最佳显示在文本框中
                        showText.append(recvString + "\n");
                    }
                }
            }
        };

        clientThread = new ClientThread(handler, ipAdress, post);
        // 客户端启动ClientThread线程创建网络连接、读取来自服务器的数据
        new Thread(clientThread).start();

        btnSendText.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                /*
                 * 当用户按下发送按钮后,判断用户输入的字符串不是空或 无意义的空格、TAB制表符的时候才进行处理;
                 * String.trim().isEmpty()去掉前导空白和后导空白,再判断
                 * 是否为空;非空时将用户输入的数据封装成Message发送给子 线程的Handler;
                 */
                try {
                    String sendString = inputText.getText().toString();
                    if (!sendString.trim().isEmpty()) {
                        Message msg = new Message();
                        msg.what = 0x345;
                        msg.obj = sendString;
                        clientThread.recvHandler.sendMessage(msg);
                        // 清空input文本框
                        inputText.setText("");
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    @Override
    public void onPause() {
        super.onPause();
        if (mNfcAdapter != null) {
            /* 适时关闭前台调用,避免资源被占用; */
            mNfcAdapter.disableForegroundDispatch(this);
        }
    }

    /* 设置TextView和按钮,为按钮监听事件, */
    private void setMainActivityButtonAndTextView() {
        /* 所有展览点按钮监听; */
        btnAll = (Button) findViewById(R.id.btnAll);
        btnAll.setOnClickListener(this);
        /* 推荐展览点 按钮监听; */
        btnDefault = (Button) findViewById(R.id.btnDefault);
        btnDefault.setOnClickListener(this);
        /* 您的位置 按钮监听; */
        btnWhere = (Button) findViewById(R.id.btnWhere);
        btnWhere.setOnClickListener(this);
        /* 下一页界面按钮监听; */
        btnToOneActivity = (Button) findViewById(R.id.btnToOneActivity);
        btnToOneActivity.setOnClickListener(this);
        /* 关联界面布局中的文本显示框; */
        textView_all = (TextView) findViewById(R.id.textView_all);
        textView_default = (TextView) findViewById(R.id.textView_default);
        textView_where = (TextView) findViewById(R.id.textView_where);
    }

    /* 关联one.xml界面布局中的“回到首页”按钮,设置监听事件; */
    private void setOneActivityButtonAndTextView() {
        btnOneToMainActivity = (Button) findViewById(R.id.btnOneToMainActivity);
        btnOneToMainActivity.setOnClickListener(this);
        btnOneToSocketActivity = (Button) findViewById(R.id.btnOneToSocketActivity);
        btnOneToSocketActivity.setOnClickListener(this);
        btnController = (Button) findViewById(R.id.btnController);
        btnController.setOnClickListener(this);
    }

    /* 按钮点击事件处理方法; */
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.btnAll:
            textView_all.setText("所有展品" + iAll++);
            break;
        case R.id.btnDefault:
            textView_default.setText("推荐展品" + iDefault++);
            break;
        case R.id.btnWhere:
            textView_where.setText("我的位置" + iWhere++);
            break;
        case R.id.btnToOneActivity:
            setContentView(R.layout.one);
            /* 设置one.xml布局中的按钮和TextView控件; */
            setOneActivityButtonAndTextView();
            break;
        case R.id.btnOneToMainActivity:
            setContentView(R.layout.main);
            /* 设置layout_main.xml布局中的按钮和TextView控件; */
            setMainActivityButtonAndTextView();
            break;
        case R.id.btnOneToSocketActivity:
            connectedSocketServer(deviceName, ipAdress, post);
            break;
        case R.id.btnController:
            break;
        case R.id.btnSocketToMainActivity:
            setContentView(R.layout.main);
            /* 设置layout_main.xml布局中的按钮和TextView控件; */
            setMainActivityButtonAndTextView();
            break;
        default:
            break;
        }
    }

    /* 返回键的监听事件; */
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
            /*
             * WifiConfig myWifi; myWifi = new WifiConfig(this);
             * if(isWifiEnableStatue == 1) { myWifi.removeWifiNetwork();
             * myWifi.closeWifi(); } // 如果wifi已连接,断开wifi连接并退出
             * if(isWifiConnectedStatue == 1) { myWifi.removeWifiNetwork();
             * myWifi.disconnectWifi(); }
             */
            finish();
            return true;
        }
        return super.onKeyDown(keyCode, event);
    }
}


【WifiConfig.java】一个别人封装的wifi操作的类,一开始加密网络连接不上,现在已经修改好,可以连接认证类型为WPA-PSK和WPA2-PSK的Wifi网络,无密码的依然可以连接,WEP认证方式的网络很少有人用,所以没有测试,代码如下:

package com.rengh.android.test;

import java.util.List;

import android.annotation.SuppressLint;
import android.content.Context;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.WifiLock;

@SuppressLint("UseValueOf")
public class WifiConfig {
    // 定义WifiManager对象
    private WifiManager mWifiManager;
    // 定义WifiInfo对象
    private WifiInfo mWifiInfo;
    // 扫描出的网络连接列表
    private List<ScanResult> mWifiList;
    // 网络连接列表
    private List<WifiConfiguration> mWifiConfiguration;
    // 定义一个WifiLock
    WifiLock mWifiLock;

    // 构造器
    public WifiConfig(Context context) {
        // 取得WifiManager对象
        mWifiManager = (WifiManager) context
                .getSystemService(Context.WIFI_SERVICE);
        // 取得WifiInfo对象
        mWifiInfo = mWifiManager.getConnectionInfo();
    }

    // 打开WIFI
    public void openWifi() {
        if (!mWifiManager.isWifiEnabled()) {
            mWifiManager.setWifiEnabled(true);
        }
    }

    // 关闭WIFI
    public void closeWifi() {
        if (mWifiManager.isWifiEnabled()) {
            mWifiManager.setWifiEnabled(false);
        }
    }

    // 检查当前WIFI状态
    public int checkState() {
        return mWifiManager.getWifiState();
    }

    // 锁定WifiLock
    public void acquireWifiLock() {
        mWifiLock.acquire();
    }

    // 解锁WifiLock
    public void releaseWifiLock() {
        // 判断时候锁定
        if (mWifiLock.isHeld()) {
            mWifiLock.acquire();
        }
    }

    // 创建一个WifiLock
    public void creatWifiLock() {
        mWifiLock = mWifiManager.createWifiLock("Test");
    }

    // 得到配置好的网络
    public List<WifiConfiguration> getConfiguration() {
        return mWifiConfiguration;
    }

    // 指定配置好的网络进行连接
    public void connectConfiguration(int index) {
        // 索引大于配置好的网络索引返回
        if (index > mWifiConfiguration.size()) {
            return;
        }
        // 连接配置好的指定ID的网络
        mWifiManager.enableNetwork(mWifiConfiguration.get(index).networkId,
                true);
    }

    public void startScan() {
        mWifiManager.startScan();
        // 得到扫描结果
        mWifiList = mWifiManager.getScanResults();
        // 得到配置好的网络连接
        mWifiConfiguration = mWifiManager.getConfiguredNetworks();
    }

    // 得到网络列表
    public List<ScanResult> getWifiList() {
        return mWifiList;
    }

    // 查看扫描结果
    public StringBuilder lookUpScan() {
        StringBuilder stringBuilder = new StringBuilder();
        for (int i = 0; i < mWifiList.size(); i++) {
            stringBuilder
                    .append("Index_" + new Integer(i + 1).toString() + ":");
            // 将ScanResult信息转换成一个字符串包
            // 其中把包括:BSSID、SSID、capabilities、frequency、level
            stringBuilder.append((mWifiList.get(i)).toString());
            stringBuilder.append("/n");
        }
        return stringBuilder;
    }

    // 得到MAC地址
    public String getMacAddress() {
        return (mWifiInfo == null) ? "NULL" : mWifiInfo.getMacAddress();
    }

    // 得到接入点的SSID
    public String getSSID() {
        return (mWifiInfo == null) ? "NULL" : mWifiInfo.getSSID();
    }

    // 得到IP地址
    public int getIPAddress() {
        return (mWifiInfo == null) ? 0 : mWifiInfo.getIpAddress();
    }

    // 得到连接的ID
    public int getNetworkId() {
        return (mWifiInfo == null) ? 0 : mWifiInfo.getNetworkId();
    }

    public void removeWifiNetwork() {
        mWifiManager.removeNetwork(getNetworkId());
    }

    // 得到WifiInfo的所有信息包
    public String getWifiInfo() {
        return (mWifiInfo == null) ? "NULL" : mWifiInfo.toString();
    }

    // 添加一个网络并连接
    public void addNetwork(WifiConfiguration wcg) {
        int wcgID = mWifiManager.addNetwork(wcg);
        boolean b = mWifiManager.enableNetwork(wcgID, true);
        System.out.println("a--" + wcgID);
        System.out.println("b--" + b);
    }

    // 断开指定ID的网络
    public void disconnectWifi(int netId) {
        mWifiManager.disableNetwork(netId);
        mWifiManager.disconnect();
    }

    // 断开网络
    public void disconnectWifi() {
        mWifiManager.disconnect();
    }

    public WifiConfiguration CreateWifiInfo(String SSID, String Password,
            int Type) {
        WifiConfiguration config = new WifiConfiguration();
        config.allowedAuthAlgorithms.clear();
        config.allowedGroupCiphers.clear();
        config.allowedKeyManagement.clear();
        config.allowedPairwiseCiphers.clear();
        config.allowedProtocols.clear();
        config.SSID = "\"" + SSID + "\"";

        WifiConfiguration tempConfig = this.IsExsits(SSID);
        if (tempConfig != null) {
            mWifiManager.removeNetwork(tempConfig.networkId);
        }

        if (Type == 1) // WIFICIPHER_NOPASS
        {
            config.wepKeys[0] = "";
            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
            config.wepTxKeyIndex = 0;
        }
        if (Type == 2) // WIFICIPHER_WEP
        {
            config.hiddenSSID = true;
            config.wepKeys[0] = "\"" + Password + "\"";
            config.allowedAuthAlgorithms
                    .set(WifiConfiguration.AuthAlgorithm.SHARED);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
            config.allowedGroupCiphers
                    .set(WifiConfiguration.GroupCipher.WEP104);
            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
            config.wepTxKeyIndex = 0;
        }
        if (Type == 3) // WIFICIPHER_WPA
        {
            config.preSharedKey = "\"" + Password + "\"";
            config.hiddenSSID = true;
            config.allowedAuthAlgorithms
                    .set(WifiConfiguration.AuthAlgorithm.OPEN);
            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
            config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
            config.allowedPairwiseCiphers
                    .set(WifiConfiguration.PairwiseCipher.CCMP);
            config.status = WifiConfiguration.Status.ENABLED;
            config.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
        }
        return config;
    }

    public WifiConfiguration IsExsits(String SSID) {
        List<WifiConfiguration> existingConfigs = mWifiManager
                .getConfiguredNetworks();
        for (WifiConfiguration existingConfig : existingConfigs) {
            if (existingConfig.SSID.equals("\"" + SSID + "\"")) {
                return existingConfig;
            }
        }
        return null;
    }
}


【ClientThread.java】Socket通信的线程类,用来连接Socket服务器,发送和接受消息给UI线程:

package com.rengh.android.test;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.Socket;
import java.net.SocketException;
import java.net.SocketTimeoutException;

import android.annotation.SuppressLint;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;

@SuppressLint("HandlerLeak")
public class ClientThread implements Runnable {
    public static Socket s;
    // 定义向UI线程发送消息的Handler对象
    private Handler handler;
    // 定义接收UI线程消息的Handler对象
    Handler recvHandler;
    // 该线程处理的Socket对应的输入输出刘
    BufferedReader br = null;
    OutputStream os = null;

    String strSsid;
    String ipAdress;
    Integer post;

    public ClientThread(Handler handler, String ipAdress, Integer post) {
        this.handler = handler;
        this.ipAdress = ipAdress;
        this.post = post;
    }

    public void run() {
        try {
            s = new Socket(ipAdress, post);
            br = new BufferedReader(new InputStreamReader(s.getInputStream()));
            os = s.getOutputStream();

            MainActivity.socketStatue = 1;

            // 启动一条子线程来读取服务器相应的数据
            new Thread() {
                public void run() {
                    String content = null;
                    // 不断读取Socket输入流中的内容
                    try {
                        while ((content = br.readLine()) != null) {
                            // 每当读取到来自服务器的数据后,发送消息通知程序界面显示该数据
                            Message msg = new Message();
                            msg.what = 0x123;
                            msg.obj = content;
                            handler.sendMessage(msg);
                        }
                    } catch (SocketException e) {
                        System.out.println("Socket Reset!");
                        try {
                            s.close();
                            System.out.println("Socket closed!");
                        } catch (IOException e1) {
                            e1.printStackTrace();
                        }
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }.start();
            // 为当前线程初始化Looper
            Looper.prepare();
            // 创建revHandler对象
            recvHandler = new Handler() {
                public void handleMessage(Message msg) {
                    // 接收到UI线程中用户输入的数据
                    if (msg.what == 0x345) {
                        // 将用户在文本框内输入的内容写入网络
                        try {
                            os.write((msg.obj.toString() + "\r\n")
                                    .getBytes("utf-8"));
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            };
            // 启动Looper
            Looper.loop();
        } catch (SocketTimeoutException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

 

posted @ 2013-10-17 22:07  挽风阁  阅读(1845)  评论(0编辑  收藏  举报