MainActivity.java:
package itant.com.wifiserver;
import android.content.Context;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.StringBufferInputStream;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private TextView tv_status;
private TextView tv_content;
private boolean isClientConnected;
private static final int CLIENT_DISCONNECTED = 0;
private static final int CLIENT_CONNECTED = 1;
private static final int HOT_SPOT_READY = 2;
private static final int MSG_FROM_CLIENT = 3;
private WifiManager mWifiManager;
private Handler mServerHandler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
// TODO Auto-generated method stub
switch (msg.what) {
case CLIENT_DISCONNECTED:
// 断开
isClientConnected = false;
break;
case CLIENT_CONNECTED:
// 客户端连上了
tv_status.setText("已连接");
isClientConnected = true;
break;
case HOT_SPOT_READY:
// 热点创建成功,开启socket服务器端,监听客户端连接(监听断开)
new ServerThread().start();
break;
case MSG_FROM_CLIENT:
if (msg.obj != null) {
tv_content.setText(msg.obj.toString());
} else {
tv_content.setText("null" + System.currentTimeMillis());
}
break;
default:
break;
}
return true;
}
});
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mWifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
tv_status = (TextView) findViewById(R.id.tv_status);
tv_content = (TextView) findViewById(R.id.tv_content);
findViewById(R.id.btn_create_wifi).setOnClickListener(this);
findViewById(R.id.btn_send).setOnClickListener(this);
}
private void createWIFI(String hotSpotName, String password) {
if (mWifiManager.isWifiEnabled()) {
// 如果开启了WIFI,则将它关闭
mWifiManager.setWifiEnabled(false);
}
try{
WifiConfiguration wifiConfiguration = new WifiConfiguration();
//热点名称
wifiConfiguration.SSID = hotSpotName;
//热点密码
wifiConfiguration.preSharedKey = password;
wifiConfiguration.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
wifiConfiguration.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
wifiConfiguration.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
wifiConfiguration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
wifiConfiguration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
wifiConfiguration.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
wifiConfiguration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
wifiConfiguration.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
// 利用反射获取开启热点的方法创建热点
HttpTools.setWifiApEnabled(mWifiManager, wifiConfiguration, true);
final Method isHotSpotEnable = mWifiManager.getClass().getMethod("isWifiApEnabled");
// 每隔1.5秒查看热点是否创建成功
new Thread(new Runnable() {
@Override
public void run() {
// TODO Auto-generated method stub
while (true) {
try {
boolean hotSpotEnable = (boolean) isHotSpotEnable.invoke(mWifiManager);
if (hotSpotEnable) {
mServerHandler.sendEmptyMessage(HOT_SPOT_READY);
break;
}
Thread.sleep(1500);
} catch (Exception e) {
// TODO: handle exception
}
}
}
}).start();
}catch(Exception e){
e.printStackTrace();
}
}
private ServerSocket mServerSocket;
private boolean mIsServiceDestoryed = false;
/**往客户端发送文件的入口**/
private DataOutputStream mOutputStream;
@Override
public void onClick(View view) {
switch (view.getId()) {
case R.id.btn_create_wifi:
// 创建热点
String hotSpotName = "backup" + System.currentTimeMillis();
String password = "away6899";
createWIFI(hotSpotName, password);
break;
case R.id.btn_send:
if (!isClientConnected) {
Toast.makeText(this, "等待连接", Toast.LENGTH_SHORT).show();
return;
}
// 发送信息
String str = "hello moto";
try {
// 把文件名告诉客户端
//mOutputStream.writeUTF(app.getAppName() + ".apk");
//mOutputStream.flush();
byte[] strBytes = str.getBytes("UTF-8");
// 把长度诉客户端,否则不知道一个文件结尾在哪。千万不要直接传str.length()!!!因为我们采用的
// 是UTF-8编码,其长度是有所区别的,如果直接传str.length()很可能会导致传递的数据不完整!
mOutputStream.writeLong(strBytes.length);
mOutputStream.flush();
DataInputStream inputStream = new DataInputStream(new ByteArrayInputStream(strBytes));
byte buf[] = new byte[1024];
int len = -1;
while ((len = inputStream.read(buf)) != -1) {
mOutputStream.write(buf, 0, len);
}
mOutputStream.flush();
inputStream.close();
// 发送结束了
} catch (IOException e1) {
e1.printStackTrace();
}
Toast.makeText(this, "发送完毕", Toast.LENGTH_SHORT).show();
break;
}
}
/**
* Socket服务器端
* @author 詹子聪
*/
private class ServerThread extends Thread {
@Override
public void run() {
try {
mServerSocket = new ServerSocket(8688);
} catch (IOException e) {
System.err.println("establish tcp server failed, port:8688");
e.printStackTrace();
return;
}
while (!Thread.currentThread().isInterrupted()) {
try {
// 一个客户端连接上了
final Socket mClient = mServerSocket.accept();
mOutputStream = new DataOutputStream(mClient.getOutputStream());
mServerHandler.sendEmptyMessage(CLIENT_CONNECTED);
CommunicationThread commThread = new CommunicationThread(mClient);
new Thread(commThread).start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
@Override
protected void onDestroy() {
super.onDestroy();
mIsServiceDestoryed = true;
// 关闭流
if (mServerSocket != null) {
try {
if (mOutputStream != null) {
mOutputStream.close();
}
mServerSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
class CommunicationThread implements Runnable {
private Socket clientSocket;
private BufferedReader input;
public CommunicationThread(Socket clientSocket) {
this.clientSocket = clientSocket;
try {
this.input = new BufferedReader(new InputStreamReader(this.clientSocket.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
}
public void run() {
while (!Thread.currentThread().isInterrupted()) {
/*try {
String read = input.readLine();
System.out.println("获取到客户端的信息:" + read);
Message message = Message.obtain();
message.what = MSG_FROM_CLIENT;
message.obj = read;
mServerHandler.sendMessage(message);
} catch (IOException e) {
e.printStackTrace();
}*/
try {
// 接收客户端的消息和文件
DataInputStream inputStream = new DataInputStream(new BufferedInputStream(this.clientSocket.getInputStream()));
// 不断地监听,看客户端是否有东西过来
while (!MainActivity.this.isFinishing()) {
//String fileName = inputStream.readUTF();
long fileSize = inputStream.readLong();
ByteArrayOutputStream out = new ByteArrayOutputStream();
DataOutputStream outputStream = new DataOutputStream(
new BufferedOutputStream(out));
byte[] buffer = new byte[(int) fileSize];
int nIdx = 0;
int nTotalLen = buffer.length;
int nReadLen = 0;
while (nIdx < nTotalLen) {
// 从nIdx开始,想读nTotalLen - nIdx那么多,实际上这次读了nReadLen
nReadLen = inputStream.read(buffer, nIdx, nTotalLen - nIdx);
if (nReadLen > 0) {
outputStream.write(buffer, nIdx, nReadLen);
nIdx = nIdx + nReadLen;
} else {
break;
}
}
outputStream.close();
String str = out.toString();
Message message = Message.obtain();
message.obj = str;
message.what = MSG_FROM_CLIENT;
mServerHandler.sendMessage(message);
}
System.out.println("quit...");
this.clientSocket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<TextView
android:id="@+id/tv_status"
android:text="未连接"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/tv_content"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
<Button
android:id="@+id/btn_create_wifi"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="创建热点"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="@+id/btn_send"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="发送信息"
android:layout_marginTop="16dp"/>
</LinearLayout>
清单文件:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="itant.com.wifiserver">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- 文件存储 -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
HttpTools.java(和客户端的一样):
package itant.com.wifiserver;
import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.text.format.Formatter;
import java.lang.reflect.Method;
/**
* 网络请求相关辅助类
* @author jason.zhan
*
*/
public class HttpTools {
/**
* 判断是否有网络
* @param context
* @return
*/
public static boolean isNetworkConnected(Context context) {
if (context != null) {
ConnectivityManager mConnectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
if (mNetworkInfo != null) {
return mNetworkInfo.isAvailable();
}
}
return false;
}
public static boolean setWifiApEnabled(WifiManager wifiManager, WifiConfiguration wifiConfiguration, boolean enable) {
boolean invokeStatus = true;
try {
Method setupHotSpot = wifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
setupHotSpot.invoke(wifiManager, wifiConfiguration, enable);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
invokeStatus = false;
}
return invokeStatus;
}
/**
* 判断WiFi是否连接上了
* @param context
* @return
*/
public static boolean isWiFiConnected(Context context) {
if (context != null) {
ConnectivityManager mConnectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mNetworkInfo = mConnectivityManager.getActiveNetworkInfo();
if (mNetworkInfo != null) {
return (mNetworkInfo.getType() == ConnectivityManager.TYPE_WIFI);
}
}
return false;
}
/**
* 获取所连接的WiFi名称
* @param wifiManager
* @return
*/
public static String getConnectedWifiSsid(WifiManager wifiManager) {
return wifiManager.getConnectionInfo().getSSID();
}
/**
* @return (发送端)服务器IP地址,转换IP输出格式
*/
public static String getSenderIP(WifiManager wifiManager) {
//WifiInfo wifiInfo = wifiManager.getConnectionInfo();
//int ipAddress = wifiInfo.getIpAddress();
int ipAddress = wifiManager.getDhcpInfo().serverAddress;
return Formatter.formatIpAddress(ipAddress);
}
/*****************************供接收者使用***************************************/
// 加密类型,分为三种情况:1.没有密码 2.用WEP加密 3.用WPA加密,我们这里只用到了第3种
public static final int TYPE_NO_PASSWD = 1;
public static final int TYPE_WEP = 2;
public static final int TYPE_WPA = 3;
/**
* 连接信息生成配置对象
*/
public static WifiConfiguration createWifiInfo(String SSID, String password, int type) {
WifiConfiguration config = new WifiConfiguration();
config.SSID = SSID;
// 清除热点记录clearAll(SSID);
if (type == TYPE_NO_PASSWD) {
config.hiddenSSID = false;
config.status = WifiConfiguration.Status.ENABLED;
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
config.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
config.preSharedKey = null;
} else if (type == TYPE_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;
} else if (type == TYPE_WPA) {
config.preSharedKey = "\"" + password + "\"";
config.hiddenSSID = false;
config.priority = 10000;
config.status = WifiConfiguration.Status.ENABLED;
config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
config.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
}
return config;
}
/*****************************供接收者使用***************************************/
}