├── .idea
└── vcs.xml
├── README.md
├── Screenshots
├── 1.gif
├── 2.gif
├── 3.gif
├── tcp.gif
├── tcp.png
├── tcp2.png
├── udp.gif
└── wifi.png
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── java
│ └── com
│ │ └── bao
│ │ └── wifidemo
│ │ ├── activity
│ │ ├── BaseActivity.java
│ │ ├── MainActivity.kt
│ │ ├── TcpClientActivity.java
│ │ ├── TcpServerActivity.java
│ │ ├── WifiControlActivity.java
│ │ ├── WifiTcpActivity.kt
│ │ └── WifiUdpActivity.java
│ │ ├── application
│ │ └── BaseApplication.kt
│ │ ├── receiver
│ │ └── WifiBroadcastReceiver.java
│ │ ├── socket
│ │ ├── ClientLastly.java
│ │ └── ServerLastly.java
│ │ └── utils
│ │ ├── CheckPermission.java
│ │ ├── Constants.kt
│ │ └── WifiControlUtils.java
│ └── res
│ ├── drawable-v24
│ └── ic_launcher_foreground.xml
│ ├── drawable
│ ├── ic_down.xml
│ └── ic_launcher_background.xml
│ ├── layout
│ ├── global_black_line.xml
│ ├── global_black_vertical_line.xml
│ ├── main_activity.xml
│ ├── tcp_client_activity.xml
│ ├── tcp_server_activity.xml
│ ├── wifi_control_activity.xml
│ ├── wifi_tcp_activity.xml
│ └── wifi_udp_activity.xml
│ ├── mipmap-anydpi-v26
│ ├── ic_launcher.xml
│ └── ic_launcher_round.xml
│ ├── mipmap-hdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-mdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xxhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ ├── mipmap-xxxhdpi
│ ├── ic_launcher.png
│ └── ic_launcher_round.png
│ └── values
│ ├── colors.xml
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ └── gradle-wrapper.properties
├── local.properties
└── settings.gradle
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # WifiDemo
2 | Android Wifi控制、TCP、UDP通信,6.0以上适配
3 |
4 | [详细文档](https://www.jianshu.com/p/572ac573e4b8)
5 |
6 | 
7 |
8 | 
9 |
10 | 对于6.0以上,如果你要连接不是自己创建的配置,只需要在mWifiManager.getConfiguredNetworks(),翻出以前连接过的的Wifi 配置,获取对应的netId,就能重新连接上。
11 |
12 | 如果以前连接过的 Wifi 密码改了,但是名称没变,你是连不上的,也没权限去修改密码和删除(可能就是为了安全吧),你就要手动去处理这个Wifi 信息了。
13 |
14 | APP没有权限删除之前的连接过的 Wifi ,包括APP以前本身创建的 Wifi(先创建了,重装或者更新后,都不算是自己创建了)。
15 |
16 | 对于从来都没连接过的 Wifi,或者是删除过的 Wifi(相当于没连接过),和以前一样,只要用 SSID (Wifi名)、密码、加密方式创建新的 WifiConfiguration,无密码的就是要 SSID;然后 mWifiManager.enableNetwork 就连上了。
17 |
18 | ```
19 | /**
20 | * 连接指定wifi
21 | * 6.0以上版本,直接查找时候有连接过,连接过的拿出wifiConfiguration用
22 | * 不要去创建新的wifiConfiguration,否者失败
23 | */
24 | public void addNetWork(String SSID, String password, int Type)
25 | {
26 | int netId = -1;
27 | /*先执行删除wifi操作,1.如果删除的成功说明这个wifi配置是由本APP配置出来的;
28 | 2.这样可以避免密码错误之后,同名字的wifi配置存在,无法连接;
29 | 3.wifi直接连接成功过,不删除也能用, netId = getExitsWifiConfig(SSID).networkId;*/
30 | if (removeWifi(SSID))
31 | {
32 | //移除成功,就新建一个
33 | netId = mWifiManager.addNetwork(createWifiInfo(SSID, password, Type));
34 | } else
35 | {
36 | //删除不成功,要么这个wifi配置以前就存在过,要么是还没连接过的
37 | if (getExitsWifiConfig(SSID) != null)
38 | {
39 | //这个wifi是连接过的,如果这个wifi在连接之后改了密码,那就只能手动去删除了
40 | netId = getExitsWifiConfig(SSID).networkId;
41 | } else
42 | {
43 | //没连接过的,新建一个wifi配置
44 | netId = mWifiManager.addNetwork(createWifiInfo(SSID, password, Type));
45 | }
46 | }
47 |
48 | //这个方法的第一个参数是需要连接wifi网络的networkId,第二个参数是指连接当前wifi网络是否需要断开其他网络
49 | //无论是否连接上,都返回true。。。。
50 | mWifiManager.enableNetwork(netId, true);
51 | }
52 |
53 | /**
54 | * 获取配置过的wifiConfiguration
55 | */
56 | public WifiConfiguration getExitsWifiConfig(String SSID)
57 | {
58 | wifiConfigurationList = mWifiManager.getConfiguredNetworks();
59 | for (WifiConfiguration wifiConfiguration : wifiConfigurationList)
60 | {
61 | if (wifiConfiguration.SSID.equals("\"" + SSID + "\""))
62 | {
63 | return wifiConfiguration;
64 | }
65 | }
66 | return null;
67 | }
68 |
69 | /**
70 | * 移除wifi,因为权限,无法移除的时候,需要手动去翻wifi列表删除
71 | * 注意:!!!只能移除自己应用创建的wifi。
72 | * 删除掉app,再安装的,都不算自己应用,具体看removeNetwork源码
73 | *
74 | * @param netId wifi的id
75 | */
76 | public boolean removeWifi(int netId)
77 | {
78 | return mWifiManager.removeNetwork(netId);
79 | }
80 |
81 | /**
82 | * 移除wifi
83 | *
84 | * @param SSID wifi名
85 | */
86 | public boolean removeWifi(String SSID)
87 | {
88 | if (getExitsWifiConfig(SSID) != null)
89 | {
90 | return removeWifi(getExitsWifiConfig(SSID).networkId);
91 | } else
92 | {
93 | return false;
94 | }
95 | }
96 | ```
97 |
98 |
99 |
100 |
101 |
--------------------------------------------------------------------------------
/Screenshots/1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Goodbao/WifiDemo/db531872e7087bac8916eccb1340e6af56e03a4c/Screenshots/1.gif
--------------------------------------------------------------------------------
/Screenshots/2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Goodbao/WifiDemo/db531872e7087bac8916eccb1340e6af56e03a4c/Screenshots/2.gif
--------------------------------------------------------------------------------
/Screenshots/3.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Goodbao/WifiDemo/db531872e7087bac8916eccb1340e6af56e03a4c/Screenshots/3.gif
--------------------------------------------------------------------------------
/Screenshots/tcp.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Goodbao/WifiDemo/db531872e7087bac8916eccb1340e6af56e03a4c/Screenshots/tcp.gif
--------------------------------------------------------------------------------
/Screenshots/tcp.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Goodbao/WifiDemo/db531872e7087bac8916eccb1340e6af56e03a4c/Screenshots/tcp.png
--------------------------------------------------------------------------------
/Screenshots/tcp2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Goodbao/WifiDemo/db531872e7087bac8916eccb1340e6af56e03a4c/Screenshots/tcp2.png
--------------------------------------------------------------------------------
/Screenshots/udp.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Goodbao/WifiDemo/db531872e7087bac8916eccb1340e6af56e03a4c/Screenshots/udp.gif
--------------------------------------------------------------------------------
/Screenshots/wifi.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Goodbao/WifiDemo/db531872e7087bac8916eccb1340e6af56e03a4c/Screenshots/wifi.png
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 | apply plugin: 'kotlin-android'
3 |
4 | android {
5 | compileSdkVersion 27
6 | defaultConfig {
7 | applicationId "com.bao.wifidemo"
8 | minSdkVersion 21
9 | targetSdkVersion 27
10 | versionCode 1
11 | versionName "1.0"
12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | ext.support_version = '27.0.2'
23 | dependencies {
24 | implementation fileTree(include: ['*.jar'], dir: 'libs')
25 | implementation "com.android.support:appcompat-v7:${support_version}"
26 | implementation "com.android.support:recyclerview-v7:${support_version}"
27 | implementation "com.android.support:design:${support_version}"
28 | implementation 'com.android.support.constraint:constraint-layout:1.0.2'
29 | //butterknife
30 | compile 'com.jakewharton:butterknife:8.8.1'
31 | annotationProcessor 'com.jakewharton:butterknife-compiler:8.8.1'
32 | //动态权限
33 | compile 'com.yanzhenjie:permission:1.1.2'
34 | //工具大全
35 | compile 'com.blankj:utilcode:1.13.1'
36 | //kotlin
37 | compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
38 | //优化RecyclerView.Adapter
39 | compile 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.34'
40 | }
41 | repositories {
42 | mavenCentral()
43 | }
44 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # You can control the set of applied configuration files using the
3 | # proguardFiles setting in build.gradle.
4 | #
5 | # For more details, see
6 | # http://developer.android.com/guide/developing/tools/proguard.html
7 |
8 | # If your project uses WebView with JS, uncomment the following
9 | # and specify the fully qualified class name to the JavaScript interface
10 | # class:
11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12 | # public *;
13 | #}
14 |
15 | # Uncomment this to preserve the line number information for
16 | # debugging stack traces.
17 | #-keepattributes SourceFile,LineNumberTable
18 |
19 | # If you keep the line number information, uncomment this to
20 | # hide the original source file name.
21 | #-renamesourcefileattribute SourceFile
22 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
36 |
37 |
41 |
42 |
46 |
47 |
51 |
52 |
56 |
57 |
58 |
59 |
--------------------------------------------------------------------------------
/app/src/main/java/com/bao/wifidemo/activity/BaseActivity.java:
--------------------------------------------------------------------------------
1 | package com.bao.wifidemo.activity;
2 |
3 | import android.content.Intent;
4 | import android.content.res.Configuration;
5 | import android.content.res.Resources;
6 | import android.os.Bundle;
7 | import android.support.annotation.Nullable;
8 | import android.support.v7.app.AppCompatActivity;
9 | import android.view.inputmethod.InputMethodManager;
10 |
11 | import com.bao.wifidemo.utils.Constants;
12 | import com.bao.wifidemo.utils.WifiControlUtils;
13 | import com.blankj.utilcode.util.AppUtils;
14 |
15 | import butterknife.ButterKnife;
16 |
17 | /**
18 | * Created by bao on 2018/3/26.
19 | */
20 | public abstract class BaseActivity extends AppCompatActivity {
21 |
22 |
23 | private WifiControlUtils wifiControlUtils;
24 |
25 | @Override
26 | protected void onCreate(@Nullable Bundle savedInstanceState) {
27 | super.onCreate(savedInstanceState);
28 | setContentView();
29 | ButterKnife.bind(this);
30 | init();
31 | loadData();
32 |
33 |
34 | wifiControlUtils = new WifiControlUtils(this);
35 | }
36 |
37 |
38 | public abstract void setContentView();
39 |
40 | /**
41 | * 初始化工作
42 | */
43 | public abstract void init();
44 |
45 | /**
46 | * 加载数据
47 | */
48 | public abstract void loadData();
49 |
50 | @Override
51 | protected void onResume() {
52 | super.onResume();
53 |
54 | if (AppUtils.isAppForeground()) {
55 | //连接指定wifi
56 | wifiControlUtils.addNetWork(Constants.INSTANCE.getWIFI_NAME(), Constants.INSTANCE.getWIFI_PWD(), WifiControlUtils.WIFI_CIPHER_WAP);
57 | }
58 | }
59 |
60 | @Override
61 | protected void onPause() {
62 | super.onPause();
63 | if (!AppUtils.isAppForeground()) {
64 | //移除指定wifi
65 | wifiControlUtils.removeWifi(Constants.INSTANCE.getWIFI_NAME());
66 | }
67 | }
68 |
69 |
70 | /**
71 | * 隐藏软件盘
72 | */
73 | public void hideSoftInput() {
74 | InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
75 | if (getCurrentFocus() != null) {
76 | imm.hideSoftInputFromWindow(getCurrentFocus().getWindowToken(), 0);
77 | }
78 | }
79 |
80 | /**
81 | * 显示软键盘
82 | */
83 | public void showInputMethod() {
84 | if (getCurrentFocus() != null) {
85 | InputMethodManager imm = (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
86 | imm.showSoftInputFromInputMethod(getCurrentFocus().getWindowToken(), 0);
87 | }
88 | }
89 |
90 | /**
91 | * 防止快速点击
92 | */
93 | private boolean fastClick() {
94 | long lastClick = 0;
95 | if (System.currentTimeMillis() - lastClick <= 1000) {
96 | return false;
97 | }
98 | lastClick = System.currentTimeMillis();
99 | return true;
100 | }
101 |
102 | /**
103 | * 跳转activity,不带参数
104 | *
105 | * @param clz 跳转的activity
106 | */
107 | public void startActivity(Class> clz) {
108 | startActivity(new Intent(this, clz));
109 | }
110 |
111 | /**
112 | * 跳转activity,带参数
113 | *
114 | * @param clz 跳转的activity
115 | * @param bundle 传递的参数
116 | */
117 | public void startActivity(Class> clz, Bundle bundle) {
118 | Intent intent = new Intent(this, clz);
119 | if (bundle != null) {
120 | intent.putExtras(bundle);
121 | }
122 | startActivity(intent);
123 | }
124 |
125 |
126 | /**
127 | * 字体大小不跟系统设置
128 | */
129 | @Override
130 | public Resources getResources() {
131 | Resources res = super.getResources();
132 | if (res.getConfiguration().fontScale != 1) {
133 | //非默认值
134 | Configuration newConfig = new Configuration();
135 | newConfig.setToDefaults();
136 | //设置默认
137 | res.updateConfiguration(newConfig, res.getDisplayMetrics());
138 | }
139 | return res;
140 | }
141 |
142 |
143 | @Override
144 | protected void onDestroy() {
145 | ButterKnife.bind(this).unbind();
146 | super.onDestroy();
147 | }
148 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/bao/wifidemo/activity/MainActivity.kt:
--------------------------------------------------------------------------------
1 | package com.bao.wifidemo.activity
2 |
3 | import android.content.Intent
4 | import android.os.Bundle
5 | import android.support.v7.app.AppCompatActivity
6 | import android.view.View
7 | import android.widget.TextView
8 | import com.bao.wifidemo.R
9 | import com.bao.wifidemo.utils.CheckPermission
10 |
11 | class MainActivity : AppCompatActivity(), View.OnClickListener {
12 |
13 | private var checkPermission: CheckPermission? = null
14 |
15 | override fun onCreate(savedInstanceState: Bundle?) {
16 | super.onCreate(savedInstanceState)
17 | setContentView(R.layout.main_activity)
18 |
19 | checkPermission = object : CheckPermission(this@MainActivity) {
20 | override fun permissionSuccess() {
21 | //权限申请成功
22 | }
23 | }
24 |
25 | checkPermission!!.permission(CheckPermission.REQUEST_CODE_PERMISSION_LOCATION)
26 |
27 | findViewById(R.id.tv_wifi_control).setOnClickListener(this@MainActivity)
28 | findViewById(R.id.tv_wifi_tcp).setOnClickListener(this@MainActivity)
29 | findViewById(R.id.tv_wifi_udp).setOnClickListener(this@MainActivity)
30 | }
31 |
32 | override fun onClick(view: View?) {
33 | when (view!!.id) {
34 | R.id.tv_wifi_control -> {
35 | startActivity(WifiControlActivity::class.java)
36 | }
37 |
38 | R.id.tv_wifi_tcp -> {
39 | startActivity(WifiTcpActivity::class.java)
40 | }
41 |
42 | R.id.tv_wifi_udp -> {
43 | startActivity(WifiUdpActivity::class.java)
44 | }
45 | }
46 | }
47 |
48 | private fun startActivity(activity: Class<*>) {
49 | startActivity(Intent(this@MainActivity, activity))
50 | }
51 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/bao/wifidemo/activity/TcpClientActivity.java:
--------------------------------------------------------------------------------
1 | package com.bao.wifidemo.activity;
2 |
3 | import android.os.Bundle;
4 | import android.os.Handler;
5 | import android.os.Message;
6 | import android.support.annotation.Nullable;
7 | import android.support.v7.app.AppCompatActivity;
8 | import android.view.View;
9 | import android.widget.Button;
10 | import android.widget.EditText;
11 | import android.widget.TextView;
12 |
13 | import com.bao.wifidemo.R;
14 | import com.bao.wifidemo.socket.ClientLastly;
15 |
16 | import butterknife.BindView;
17 | import butterknife.ButterKnife;
18 | import butterknife.OnClick;
19 |
20 | /**
21 | * Created by bao on 2018/3/22.
22 | * tcp客户端
23 | */
24 |
25 | public class TcpClientActivity extends AppCompatActivity
26 | {
27 | @BindView(R.id.et_message)
28 | EditText etMessage;
29 | @BindView(R.id.btn_send)
30 | Button btnSend;
31 | @BindView(R.id.tv_message)
32 | TextView tvMessage;
33 |
34 | private ClientLastly client;
35 | private StringBuffer receiveData = new StringBuffer();
36 | private Handler handler = new Handler(new Handler.Callback()
37 | {
38 | @Override
39 | public boolean handleMessage(Message msg)
40 | {
41 | if (msg.arg1 == ClientLastly.CLIENT_ARG)
42 | {
43 | receiveData.append("接收到:"+(String) msg.obj);
44 | //收到数据
45 | tvMessage.setText(receiveData);
46 | receiveData.append("\r\n");
47 | }
48 | return false;
49 | }
50 | });
51 |
52 | @Override
53 | protected void onCreate(@Nullable Bundle savedInstanceState)
54 | {
55 | super.onCreate(savedInstanceState);
56 | setContentView(R.layout.tcp_client_activity);
57 | ButterKnife.bind(this);
58 |
59 | client = new ClientLastly(handler,getIntent().getStringExtra(WifiTcpActivity.Companion.getHOST_IP()));
60 | new Thread(client).start();
61 | }
62 |
63 | @OnClick({R.id.btn_send})
64 | public void onViewClicked(View view)
65 | {
66 | switch (view.getId())
67 | {
68 | case R.id.btn_send:
69 | new Thread(new Runnable()
70 | {
71 | @Override
72 | public void run()
73 | {
74 | client.send(etMessage.getText().toString());
75 | }
76 | }).start();
77 | etMessage.setText("");
78 | break;
79 | }
80 | }
81 |
82 | @Override
83 | protected void onDestroy()
84 | {
85 | client.close();
86 | super.onDestroy();
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/app/src/main/java/com/bao/wifidemo/activity/TcpServerActivity.java:
--------------------------------------------------------------------------------
1 | package com.bao.wifidemo.activity;
2 |
3 | import android.os.Bundle;
4 | import android.os.Handler;
5 | import android.os.Message;
6 | import android.support.annotation.Nullable;
7 | import android.support.v7.app.AppCompatActivity;
8 | import android.widget.Button;
9 | import android.widget.EditText;
10 | import android.widget.TextView;
11 |
12 | import com.bao.wifidemo.R;
13 | import com.bao.wifidemo.socket.ServerLastly;
14 |
15 | import butterknife.BindView;
16 | import butterknife.ButterKnife;
17 | import butterknife.OnClick;
18 |
19 | /**
20 | * Created by bao on 2018/3/22.
21 | * tcp服务器端
22 | */
23 |
24 | public class TcpServerActivity extends AppCompatActivity
25 | {
26 | @BindView(R.id.et_message)
27 | EditText etMessage;
28 | @BindView(R.id.btn_send)
29 | Button btnSend;
30 | @BindView(R.id.tv_message)
31 | TextView tvMessage;
32 |
33 | private ServerLastly server;
34 | private StringBuffer receiveData = new StringBuffer();
35 | private Handler handler = new Handler(new Handler.Callback()
36 | {
37 | @Override
38 | public boolean handleMessage(Message msg)
39 | {
40 | if (msg.arg1 == ServerLastly.SERVER_ARG)
41 | {
42 | receiveData.append("接收到:"+(String) msg.obj);
43 | tvMessage.setText(receiveData);
44 | receiveData.append("\r\n");
45 | }
46 | return false;
47 | }
48 | });
49 |
50 |
51 | @Override
52 | protected void onCreate(@Nullable Bundle savedInstanceState)
53 | {
54 | super.onCreate(savedInstanceState);
55 | setContentView(R.layout.tcp_server_activity);
56 | ButterKnife.bind(this);
57 |
58 | server = new ServerLastly(handler);
59 | new Thread(server).start();
60 | }
61 |
62 | @OnClick(R.id.btn_send)
63 | public void onViewClicked()
64 | {
65 | new Thread(new Runnable()
66 | {
67 | @Override
68 | public void run()
69 | {
70 | server.send(etMessage.getText().toString());
71 | }
72 | }).start();
73 | etMessage.setText("");
74 | }
75 |
76 | @Override
77 | protected void onDestroy()
78 | {
79 | server.close();
80 | super.onDestroy();
81 | }
82 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/bao/wifidemo/activity/WifiControlActivity.java:
--------------------------------------------------------------------------------
1 | package com.bao.wifidemo.activity;
2 |
3 | import android.content.IntentFilter;
4 | import android.net.wifi.ScanResult;
5 | import android.net.wifi.WifiInfo;
6 | import android.net.wifi.WifiManager;
7 | import android.os.Bundle;
8 | import android.support.annotation.Nullable;
9 | import android.support.v7.app.AppCompatActivity;
10 | import android.view.View;
11 | import android.widget.EditText;
12 | import android.widget.TextView;
13 |
14 | import com.bao.wifidemo.R;
15 | import com.bao.wifidemo.receiver.WifiBroadcastReceiver;
16 | import com.bao.wifidemo.utils.Constants;
17 | import com.bao.wifidemo.utils.WifiControlUtils;
18 | import com.blankj.utilcode.util.ToastUtils;
19 |
20 | import butterknife.BindView;
21 | import butterknife.ButterKnife;
22 | import butterknife.OnClick;
23 |
24 | /**
25 | * Created by bao on 2018/3/21.
26 | * wifi控制Activity
27 | */
28 | public class WifiControlActivity extends AppCompatActivity {
29 | @BindView(R.id.tv_open_wifi)
30 | TextView tvOpenWifi;
31 | @BindView(R.id.tv_close_wifi)
32 | TextView tvCloseWifi;
33 | @BindView(R.id.tv_scan_wifi)
34 | TextView tvScanWifi;
35 | @BindView(R.id.tv_wifi_info)
36 | TextView tvWifiInfo;
37 | @BindView(R.id.et_wifi_name)
38 | EditText etWifiName;
39 | @BindView(R.id.et_wifi_pwd)
40 | EditText etWifiPwd;
41 | @BindView(R.id.tv_connection_wifi)
42 | TextView tvConnectionWifi;
43 | @BindView(R.id.tv_disconnection_wifi)
44 | TextView tvDisconnectionWifi;
45 | @BindView(R.id.tv_delete_wifi)
46 | TextView tvDeleteWifi;
47 | @BindView(R.id.tv_wifi_message)
48 | TextView tvWifiMessage;
49 |
50 | private WifiBroadcastReceiver wifiBroadcastReceiver;
51 | private WifiControlUtils wifiControlUtils;
52 |
53 | private WifiInfo wifiInfo;
54 |
55 | @Override
56 | protected void onCreate(@Nullable Bundle savedInstanceState) {
57 | super.onCreate(savedInstanceState);
58 | setContentView(R.layout.wifi_control_activity);
59 | ButterKnife.bind(this);
60 |
61 | //动态注册wifi状态广播
62 | wifiBroadcastReceiver = new WifiBroadcastReceiver();
63 | IntentFilter intentFilter = new IntentFilter();
64 | intentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
65 | intentFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
66 | intentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
67 | registerReceiver(wifiBroadcastReceiver, intentFilter);
68 |
69 | wifiControlUtils = new WifiControlUtils(this);
70 | wifiInfo = wifiControlUtils.getWifiInfo();
71 | }
72 |
73 |
74 | @Override
75 | protected void onResume() {
76 | super.onResume();
77 | //连接指定wifi
78 | wifiControlUtils.addNetWork(Constants.INSTANCE.getWIFI_NAME(), Constants.INSTANCE.getWIFI_PWD(), WifiControlUtils.WIFI_CIPHER_WAP);
79 | }
80 |
81 | @Override
82 | protected void onPause() {
83 | super.onPause();
84 | //移除指定wifi
85 | wifiControlUtils.removeWifi(Constants.INSTANCE.getWIFI_NAME());
86 | wifiControlUtils.addNetWork(wifiInfo.getSSID());
87 | }
88 |
89 |
90 | @OnClick({R.id.tv_open_wifi, R.id.tv_close_wifi, R.id.tv_scan_wifi
91 | , R.id.tv_connection_wifi, R.id.tv_disconnection_wifi, R.id.tv_delete_wifi
92 | , R.id.tv_wifi_message, R.id.tv_wifi_info})
93 | public void onViewClicked(View view) {
94 | switch (view.getId()) {
95 | case R.id.tv_open_wifi:
96 | wifiControlUtils.openWifi();
97 | break;
98 | case R.id.tv_close_wifi:
99 | wifiControlUtils.closeWifi();
100 | break;
101 | case R.id.tv_scan_wifi:
102 | wifiControlUtils.scanWifi();
103 | ToastUtils.showShort("扫描到" + wifiControlUtils.getWifiList().size() + "个wifi");
104 | StringBuilder stringBuilder = new StringBuilder();
105 |
106 | stringBuilder.append("上一次连接的wifi:");
107 | stringBuilder.append(wifiInfo.getSSID());
108 | stringBuilder.append(":");
109 | stringBuilder.append(wifiInfo.getBSSID());
110 | stringBuilder.append(" 强度:" + wifiInfo.getRssi());
111 | stringBuilder.append("\n\n");
112 |
113 | for (ScanResult scanResult : wifiControlUtils.getWifiList()) {
114 | stringBuilder.append(scanResult.SSID);
115 | stringBuilder.append(":");
116 | stringBuilder.append(scanResult.BSSID);
117 | stringBuilder.append(" 强度:" + scanResult.level);
118 | stringBuilder.append("\n\n");
119 | }
120 | tvWifiMessage.setText(stringBuilder.toString());
121 | break;
122 | case R.id.tv_wifi_info:
123 | tvWifiMessage.setText(wifiControlUtils.getWifiInfo().toString());
124 | break;
125 | case R.id.tv_connection_wifi:
126 | wifiControlUtils.addNetWork(etWifiName.getText().toString(), etWifiPwd.getText().toString(), WifiControlUtils.WIFI_CIPHER_WAP);
127 | break;
128 | case R.id.tv_disconnection_wifi:
129 | wifiControlUtils.disconnectWifi(etWifiName.getText().toString());
130 | break;
131 | case R.id.tv_delete_wifi:
132 | if (!wifiControlUtils.removeWifi(etWifiName.getText().toString())) {
133 | ToastUtils.showShort(R.string.unable_remove);
134 | }
135 | break;
136 | case R.id.tv_wifi_message:
137 | tvWifiMessage.setText(wifiControlUtils.getWifiInfo().toString());
138 | break;
139 | }
140 | }
141 |
142 | @Override
143 | protected void onDestroy() {
144 | super.onDestroy();
145 | //注销广播
146 | unregisterReceiver(wifiBroadcastReceiver);
147 | }
148 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/bao/wifidemo/activity/WifiTcpActivity.kt:
--------------------------------------------------------------------------------
1 | package com.bao.wifidemo.activity
2 |
3 | import android.content.Intent
4 | import android.os.Bundle
5 | import android.support.v7.app.AppCompatActivity
6 | import android.view.View
7 | import android.widget.EditText
8 | import android.widget.TextView
9 | import com.bao.wifidemo.R
10 | import com.blankj.utilcode.util.NetworkUtils
11 | import com.blankj.utilcode.util.ToastUtils
12 |
13 | /**
14 | * Created by bao on 2018/3/21.
15 | * Tcp通信Activity
16 | */
17 | class WifiTcpActivity : AppCompatActivity(), View.OnClickListener {
18 |
19 | companion object {
20 | val HOST_IP = "ip"
21 | }
22 |
23 | private var et_server_ip: EditText? = null
24 |
25 | override fun onCreate(savedInstanceState: Bundle?) {
26 | super.onCreate(savedInstanceState)
27 | setContentView(R.layout.wifi_tcp_activity)
28 |
29 |
30 | et_server_ip = findViewById(R.id.et_server_ip)
31 | findViewById(R.id.tv_tcp_server).setOnClickListener(this@WifiTcpActivity)
32 | findViewById(R.id.tv_tcp_client).setOnClickListener(this@WifiTcpActivity)
33 |
34 | //toast本机ip地址
35 | ToastUtils.showLong(NetworkUtils.getIPAddress(true))
36 | }
37 |
38 | override fun onClick(view: View?) {
39 | when (view!!.id) {
40 | R.id.tv_tcp_server -> {
41 | startActivity(Intent(this@WifiTcpActivity, TcpServerActivity::class.java))
42 | }
43 | R.id.tv_tcp_client -> {
44 | var intent = Intent(this@WifiTcpActivity, TcpClientActivity::class.java)
45 | intent.putExtra(HOST_IP, et_server_ip!!.text.toString())
46 | startActivity(intent)
47 | }
48 | }
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/app/src/main/java/com/bao/wifidemo/activity/WifiUdpActivity.java:
--------------------------------------------------------------------------------
1 | package com.bao.wifidemo.activity;
2 |
3 | import android.os.Bundle;
4 | import android.support.annotation.Nullable;
5 | import android.support.v7.app.AppCompatActivity;
6 | import android.text.TextUtils;
7 | import android.util.Log;
8 | import android.view.View;
9 | import android.widget.Button;
10 | import android.widget.TextView;
11 |
12 | import com.bao.wifidemo.R;
13 | import com.bao.wifidemo.utils.Constants;
14 | import com.blankj.utilcode.util.LogUtils;
15 |
16 | import java.io.BufferedReader;
17 | import java.io.IOException;
18 | import java.io.InputStreamReader;
19 | import java.net.DatagramPacket;
20 | import java.net.InetAddress;
21 | import java.net.MulticastSocket;
22 | import java.net.NetworkInterface;
23 | import java.net.ServerSocket;
24 | import java.net.Socket;
25 | import java.net.SocketException;
26 | import java.util.Enumeration;
27 | import java.util.concurrent.BlockingQueue;
28 | import java.util.concurrent.LinkedBlockingQueue;
29 | import java.util.concurrent.ThreadPoolExecutor;
30 | import java.util.concurrent.TimeUnit;
31 |
32 | import butterknife.BindView;
33 | import butterknife.ButterKnife;
34 | import butterknife.OnClick;
35 |
36 | /**
37 | * Created by bao on 2018/3/21.
38 | * Udp通信Activity
39 | * 测试端口号20001,接收端口号4001,ip:224.0.0.1
40 | */
41 | public class WifiUdpActivity extends AppCompatActivity {
42 | @BindView(R.id.btn_start)
43 | Button btnStart;
44 | @BindView(R.id.btn_stop)
45 | Button btnStop;
46 | @BindView(R.id.tv_send_information)
47 | TextView tvSendInformation;
48 | @BindView(R.id.tv_receive_information)
49 | TextView tvReceiveInformation;
50 |
51 | /* 用于 udpReceiveAndTcpSend 的3个变量 */
52 | private Socket socket = null;
53 | private MulticastSocket multicastSocket = null;
54 | private DatagramPacket datagramPacket;
55 |
56 | private TcpReceive tcpReceive;
57 | private UdpReceiveAndtcpSend udpReceiveAndtcpSend;
58 | private ThreadPoolExecutor threadPoolExecutor;
59 |
60 | @Override
61 | protected void onCreate(@Nullable Bundle savedInstanceState) {
62 | super.onCreate(savedInstanceState);
63 | setContentView(R.layout.wifi_udp_activity);
64 | ButterKnife.bind(this);
65 |
66 |
67 | tvSendInformation.append("\n\n");
68 | tvReceiveInformation.append("\n\n");
69 | /* 开一个线程接收tcp 连接*/
70 | tcpReceive = new TcpReceive();
71 | /* 开一个线程 接收udp多播 并 发送tcp 连接*/
72 | udpReceiveAndtcpSend = new UdpReceiveAndtcpSend();
73 |
74 | int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors();
75 | int KEEP_ALIVE_TIME = 1;
76 | TimeUnit KEEP_ALIVE_TIME_UNIT = TimeUnit.SECONDS;
77 | BlockingQueue blockingQueue = new LinkedBlockingQueue();
78 | threadPoolExecutor = new ThreadPoolExecutor(NUMBER_OF_CORES
79 | , NUMBER_OF_CORES * 2
80 | , KEEP_ALIVE_TIME
81 | , KEEP_ALIVE_TIME_UNIT
82 | , blockingQueue);
83 |
84 |
85 | threadPoolExecutor.execute(tcpReceive);
86 | threadPoolExecutor.execute(udpReceiveAndtcpSend);
87 | }
88 |
89 | @OnClick({R.id.btn_start, R.id.btn_stop})
90 | public void onViewClicked(View view) {
91 | switch (view.getId()) {
92 | case R.id.btn_start:
93 | /* 新开一个线程 发送 udp 多播 */
94 | UdpBroadCast udpBroadCast = new UdpBroadCast("hi ~!" + System.getProperty("http.agent"));
95 | threadPoolExecutor.execute(udpBroadCast);
96 | break;
97 | case R.id.btn_stop:
98 | break;
99 | }
100 | }
101 |
102 |
103 | /**
104 | * 发送udp多播
105 | */
106 | private class UdpBroadCast extends Thread {
107 | MulticastSocket sender = null;
108 | DatagramPacket datagramPacket1 = null;
109 | InetAddress group = null;
110 |
111 | byte[] data = new byte[1024];
112 |
113 | public UdpBroadCast(String dataString) {
114 | data = dataString.getBytes();
115 | }
116 |
117 | @Override
118 | public void run() {
119 | try {
120 | sender = new MulticastSocket();
121 | //ip
122 | group = InetAddress.getByName(Constants.INSTANCE.getHOST_ADDRESS());
123 | //端口号
124 | datagramPacket1 = new DatagramPacket(data, data.length, group, Constants.INSTANCE.getHOST_PORT());
125 | sender.send(datagramPacket1);
126 | sender.close();
127 | } catch (IOException e) {
128 | e.printStackTrace();
129 | }
130 | }
131 | }
132 |
133 | /**
134 | * 接收udp多播 并 发送tcp 连接
135 | */
136 | private class UdpReceiveAndtcpSend extends Thread {
137 | @Override
138 | public void run() {
139 | byte[] data = new byte[1024];
140 | try {
141 | InetAddress groupAddress = InetAddress.getByName(Constants.INSTANCE.getHOST_ADDRESS());
142 | multicastSocket = new MulticastSocket(Constants.INSTANCE.getHOST_PORT());
143 | multicastSocket.joinGroup(groupAddress);
144 | } catch (Exception e) {
145 | e.printStackTrace();
146 | }
147 |
148 | while (true) {
149 | try {
150 | datagramPacket = new DatagramPacket(data, data.length);
151 | if (multicastSocket != null)
152 | multicastSocket.receive(datagramPacket);
153 | } catch (Exception e) {
154 | e.printStackTrace();
155 | }
156 |
157 | if (datagramPacket.getAddress() != null) {
158 | final String quest_ip = datagramPacket.getAddress().toString();
159 |
160 | /* 若udp包的ip地址 是 本机的ip地址的话,丢掉这个包(不处理)*/
161 |
162 | //String host_ip = getLocalIPAddress();
163 |
164 | String host_ip = getLocalHostIp();
165 |
166 | LogUtils.d("host_ip: -------------------- " + host_ip);
167 | LogUtils.d("quest_ip: -------------------- " + quest_ip.substring(1));
168 |
169 | if (!TextUtils.isEmpty(host_ip) && host_ip.equals(quest_ip.substring(1))) {
170 | continue;
171 | }
172 |
173 | final String codeString = new String(data, 0, datagramPacket.getLength());
174 |
175 | tvReceiveInformation.post(new Runnable() {
176 | @Override
177 | public void run() {
178 | tvReceiveInformation.append("收到来自: \n" + quest_ip.substring(1) + "\n" + "的udp请求\n");
179 | tvReceiveInformation.append("请求内容: " + codeString + "\n\n");
180 | }
181 | });
182 | try {
183 | final String target_ip = datagramPacket.getAddress().toString().substring(1);
184 | tvSendInformation.post(new Runnable() {
185 | @Override
186 | public void run() {
187 | tvSendInformation.append("发送tcp请求到: \n" + target_ip + "\n");
188 | }
189 | });
190 | socket = new Socket(target_ip, Constants.INSTANCE.getPHONE_PORT());
191 | } catch (IOException e) {
192 | e.printStackTrace();
193 | } finally {
194 |
195 | try {
196 | if (socket != null)
197 | socket.close();
198 | } catch (IOException e) {
199 | e.printStackTrace();
200 | }
201 | }
202 | }
203 | }
204 | }
205 | }
206 |
207 |
208 | /**
209 | * 接收tcp连接
210 | */
211 | private class TcpReceive extends Thread {
212 | ServerSocket serverSocket;
213 | Socket socket;
214 | BufferedReader in;
215 | String source_address;
216 |
217 | @Override
218 | public void run() {
219 | while (true) {
220 | serverSocket = null;
221 | socket = null;
222 | in = null;
223 | try {
224 | serverSocket = new ServerSocket(Constants.INSTANCE.getPHONE_PORT());
225 | socket = serverSocket.accept();
226 | if (socket != null) {
227 | in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
228 | StringBuilder sb = new StringBuilder();
229 | sb.append(socket.getInetAddress().getHostAddress());
230 |
231 | String line = null;
232 | while ((line = in.readLine()) != null) {
233 | sb.append(line);
234 | }
235 |
236 | source_address = sb.toString().trim();
237 | tvReceiveInformation.post(new Runnable() {
238 | @Override
239 | public void run() {
240 | tvReceiveInformation.append("收到来自: " + "\n" + source_address + "\n" + "的tcp请求\n\n");
241 | }
242 | });
243 | }
244 | } catch (IOException e1) {
245 | e1.printStackTrace();
246 | } finally {
247 | try {
248 | if (in != null)
249 | in.close();
250 | if (socket != null)
251 | socket.close();
252 | if (serverSocket != null)
253 | serverSocket.close();
254 | } catch (IOException e) {
255 | e.printStackTrace();
256 | }
257 | }
258 | }
259 | }
260 | }
261 |
262 | public String getLocalHostIp() {
263 | String ipaddress = "";
264 | try {
265 | Enumeration en = NetworkInterface
266 | .getNetworkInterfaces();
267 | // 遍历所用的网络接口
268 | while (en.hasMoreElements()) {
269 | // 得到每一个网络接口绑定的所有ip
270 | NetworkInterface nif = en.nextElement();
271 | Enumeration inet = nif.getInetAddresses();
272 | // 遍历每一个接口绑定的所有ip
273 | while (inet.hasMoreElements()) {
274 | InetAddress ip = inet.nextElement();
275 | if (!ip.isLoopbackAddress()) {
276 | return ip.getHostAddress();
277 | }
278 | }
279 | }
280 | } catch (SocketException e) {
281 | Log.e("feige", "获取本地ip地址失败");
282 | e.printStackTrace();
283 | }
284 | return ipaddress;
285 | }
286 |
287 |
288 | @Override
289 | protected void onDestroy() {
290 | //关闭 多播socket multicastSocket
291 | multicastSocket.close();
292 | threadPoolExecutor.shutdownNow();
293 | super.onDestroy();
294 | }
295 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/bao/wifidemo/application/BaseApplication.kt:
--------------------------------------------------------------------------------
1 | package com.bao.wifidemo.application
2 |
3 | import android.app.Application
4 | import com.blankj.utilcode.util.LogUtils
5 | import com.blankj.utilcode.util.Utils
6 |
7 | /**
8 | * 尝试一下下kotlin,O(∩_∩)O哈哈~
9 | */
10 | class BaseApplication : Application() {
11 |
12 | /**
13 | * 相当于下面这段代码,Kotlin里get,set方法可以不用写,默认就有
14 | * private static BaseApplication instance;
15 |
16 | public static BaseApplication getInstance()
17 | {
18 | return instance;
19 | }
20 | */
21 | companion object {
22 | var instance: BaseApplication? = null
23 | }
24 |
25 |
26 | override fun onCreate() {
27 | super.onCreate()
28 | instance = this
29 | //超级强大的工具类:https://github.com/Blankj/AndroidUtilCode/blob/master/utilcode/README-CN.md
30 | Utils.init(this)
31 | LogUtils.getConfig().setGlobalTag("bao")
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/java/com/bao/wifidemo/receiver/WifiBroadcastReceiver.java:
--------------------------------------------------------------------------------
1 | package com.bao.wifidemo.receiver;
2 |
3 | import android.content.BroadcastReceiver;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.net.NetworkInfo;
7 | import android.net.wifi.SupplicantState;
8 | import android.net.wifi.WifiManager;
9 |
10 | import com.bao.wifidemo.R;
11 | import com.bao.wifidemo.utils.WifiControlUtils;
12 | import com.blankj.utilcode.util.LogUtils;
13 | import com.blankj.utilcode.util.ToastUtils;
14 |
15 | /**
16 | * Created by bao on 2018/3/21.
17 | * wifi状态广播
18 | */
19 | public class WifiBroadcastReceiver extends BroadcastReceiver
20 | {
21 | private WifiControlUtils wifiControlUtils;
22 |
23 | @Override
24 | public void onReceive(Context context, Intent intent)
25 | {
26 | wifiControlUtils = new WifiControlUtils(context);
27 |
28 | //wifi正在改变状态
29 | if (WifiManager.WIFI_STATE_CHANGED_ACTION.equals(intent.getAction()))
30 | {
31 | //获取wifi状态
32 | int wifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_DISABLING);
33 | switch (wifiState)
34 | {
35 | case WifiManager.WIFI_STATE_DISABLED:
36 | //wifi已经关闭
37 | LogUtils.d(context.getString(R.string.wifi_state_disabled));
38 | ToastUtils.showShort(context.getString(R.string.wifi_state_disabled));
39 | break;
40 | case WifiManager.WIFI_STATE_DISABLING:
41 | //wifi正在关闭
42 | LogUtils.d(context.getString(R.string.wifi_state_disabling));
43 | ToastUtils.showShort(context.getString(R.string.wifi_state_disabling));
44 | break;
45 | case WifiManager.WIFI_STATE_ENABLED:
46 | //wifi已经开启
47 | LogUtils.d(context.getString(R.string.wifi_state_enabled));
48 | ToastUtils.showShort(context.getString(R.string.wifi_state_enabled));
49 | break;
50 | case WifiManager.WIFI_STATE_ENABLING:
51 | //wifi正在开启
52 | LogUtils.d(context.getString(R.string.wifi_state_enabling));
53 | ToastUtils.showShort(context.getString(R.string.wifi_state_enabling));
54 | break;
55 | }
56 | } else if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(intent.getAction()))
57 | {
58 | //网络状态改变
59 | NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
60 | if (NetworkInfo.State.DISCONNECTED.equals(info.getState()))
61 | {
62 | //wifi网络连接断开
63 | } else if (NetworkInfo.State.CONNECTED.equals(info.getState()))
64 | {
65 | //获取当前网络,wifi名称
66 | ToastUtils.showLong(context.getString(R.string.wifi_connected, wifiControlUtils.getWifiInfo().getSSID()));
67 | }
68 | } else if (WifiManager.SUPPLICANT_STATE_CHANGED_ACTION.equals(intent.getAction()))
69 | {
70 | //wifi密码错误广播
71 | SupplicantState netNewState = intent.getParcelableExtra(WifiManager.EXTRA_NEW_STATE);
72 | //错误码
73 | int netConnectErrorCode = intent.getIntExtra(WifiManager.EXTRA_SUPPLICANT_ERROR, WifiManager.ERROR_AUTHENTICATING);
74 | }
75 | }
76 | }
77 |
--------------------------------------------------------------------------------
/app/src/main/java/com/bao/wifidemo/socket/ClientLastly.java:
--------------------------------------------------------------------------------
1 | package com.bao.wifidemo.socket;
2 |
3 | import android.os.Handler;
4 | import android.os.Message;
5 | import android.text.TextUtils;
6 |
7 | import com.bao.wifidemo.utils.Constants;
8 | import com.blankj.utilcode.util.LogUtils;
9 |
10 | import java.io.BufferedReader;
11 | import java.io.IOException;
12 | import java.io.InputStreamReader;
13 | import java.io.PrintWriter;
14 | import java.net.Socket;
15 |
16 | /**
17 | * 通过socket实现
18 | *
19 | * @author Administrator
20 | */
21 | public class ClientLastly implements Runnable {
22 | private static final String TAG = "tcp_client";
23 | public static final int CLIENT_ARG = 0x12;
24 | //超时时间,如果60S没通信,就会断开
25 | private int timeout = 60000;
26 | private Socket clientSocket;
27 | private PrintWriter printWriter;
28 | private BufferedReader bufferedReader;
29 |
30 | Handler handler;
31 | private String server_ip;
32 |
33 | public ClientLastly(Handler handler, String server_ip) {
34 | this.handler = handler;
35 | this.server_ip = server_ip;
36 | // try {
37 | // //连接服务器
38 | // clientSocket=new Socket("localhost", 8888);
39 | // Log.i(TAG, "Client=======连接服务器成功=========");
40 | // clientSocket.setSoTimeout(timeout);
41 | // printWriter=new PrintWriter(clientSocket.getOutputStream());
42 | // bufferedReader=new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
43 | // } catch (IOException e) {
44 | // // TODO Auto-generated catch block
45 | // e.printStackTrace();
46 | // }
47 | }
48 |
49 | //发数据
50 | public void send(String data) {
51 | LogUtils.dTag(TAG, "客户端发送:" + data);
52 | if (printWriter != null) {
53 | printWriter.println(data);
54 | printWriter.flush();
55 | }
56 | }
57 |
58 |
59 | //接收据
60 | @Override
61 | public void run() {
62 | try {
63 | //连接服务器
64 | clientSocket = new Socket(server_ip, Constants.INSTANCE.getHOST_PORT());
65 | LogUtils.dTag(TAG, "=======连接服务器成功=========");
66 | clientSocket.setSoTimeout(timeout);
67 | printWriter = new PrintWriter(clientSocket.getOutputStream());
68 | bufferedReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
69 | } catch (IOException e) {
70 | // TODO Auto-generated catch block
71 | e.printStackTrace();
72 | }
73 |
74 | try {
75 | if (bufferedReader != null && !TextUtils.isEmpty(bufferedReader.readLine())) {
76 | String result = "";
77 | while ((result = bufferedReader.readLine()) != null) {
78 | LogUtils.dTag(TAG, "客户端接到的数据为:" + result);
79 | //将数据带回acitvity显示
80 | Message msg = handler.obtainMessage();
81 | msg.arg1 = CLIENT_ARG;
82 | msg.obj = result;
83 | handler.sendMessage(msg);
84 | }
85 | }
86 | } catch (IOException e) {
87 | // TODO Auto-generated catch block
88 | e.printStackTrace();
89 | }
90 | }
91 |
92 | public void close() {
93 | try {
94 | if (printWriter != null) {
95 | printWriter.close();
96 | }
97 | if (bufferedReader != null) {
98 | bufferedReader.close();
99 | }
100 | if (clientSocket != null) {
101 | clientSocket.close();
102 | }
103 | } catch (IOException e) {
104 | // TODO Auto-generated catch block
105 | e.printStackTrace();
106 | }
107 | }
108 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/bao/wifidemo/socket/ServerLastly.java:
--------------------------------------------------------------------------------
1 | package com.bao.wifidemo.socket;
2 |
3 | import android.os.Handler;
4 | import android.os.Message;
5 | import android.text.TextUtils;
6 |
7 | import com.bao.wifidemo.utils.Constants;
8 | import com.blankj.utilcode.util.LogUtils;
9 |
10 | import java.io.BufferedReader;
11 | import java.io.IOException;
12 | import java.io.InputStreamReader;
13 | import java.io.PrintWriter;
14 | import java.net.InetAddress;
15 | import java.net.ServerSocket;
16 | import java.net.Socket;
17 |
18 | /**
19 | * 通过Socket实现
20 | *
21 | * @author Administrator
22 | */
23 | public class ServerLastly implements Runnable {
24 | private static final String TAG = "tcp_server";
25 | public static final int SERVER_ARG = 0x11;
26 | private ServerSocket serverSocket;
27 | private Socket clientSocket;
28 | private PrintWriter printWriter;
29 | private BufferedReader bufferedReader;
30 |
31 | private Handler handler;
32 |
33 | /**
34 | * 此处不将连接代码写在构造方法中的原因:
35 | * 我在activity的onCreate()中创建示例,如果将连接代码 写在构造方法中,服务端会一直等待客户端连接,界面没有去描绘,会一直出现白屏。
36 | * 直到客户端连接上了,界面才会描绘出来。原因是构造方法阻塞了主线程,要另开一个线程。在这里我将它写在了run()中。
37 | */
38 | public ServerLastly(Handler handler) {
39 | this.handler = handler;
40 | // Log.i(TAG, "Server=======打开服务=========");
41 | // try {
42 | // serverSocket=new ServerSocket(8888);
43 | // clientSocket=serverSocket.accept();
44 | // Log.i(TAG, "Server=======客户端连接成功=========");
45 | // InetAddress inetAddress=clientSocket.getInetAddress();
46 | // String ip=inetAddress.getHostAddress();
47 | // Log.i(TAG, "===客户端ID为:"+ip);
48 | // printWriter=new PrintWriter(clientSocket.getOutputStream());
49 | // bufferedReader=new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
50 | //
51 | // } catch (IOException e) {
52 | // // TODO Auto-generated catch block
53 | // e.printStackTrace();
54 | // }
55 | }
56 |
57 | //发数据
58 | public void send(String data) {
59 | LogUtils.dTag(TAG, "服务端发送:" + data);
60 | if (printWriter != null) {
61 | printWriter.println(data);
62 | printWriter.flush();
63 | }
64 | }
65 |
66 | //接数据
67 | @Override
68 | public void run() {
69 | LogUtils.dTag(TAG, "=======打开服务=========");
70 | try {
71 | serverSocket = new ServerSocket(Constants.INSTANCE.getHOST_PORT());
72 | clientSocket = serverSocket.accept();
73 | LogUtils.dTag(TAG, "======客户端连接成功=========");
74 | InetAddress inetAddress = clientSocket.getInetAddress();
75 | String ip = inetAddress.getHostAddress();
76 | LogUtils.dTag(TAG, "客户端ID为:" + ip);
77 | printWriter = new PrintWriter(clientSocket.getOutputStream());
78 | bufferedReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));
79 |
80 | } catch (IOException e) {
81 | // TODO Auto-generated catch block
82 | e.printStackTrace();
83 | }
84 |
85 |
86 | try {
87 | if (bufferedReader != null &&!TextUtils.isEmpty(bufferedReader.readLine())) {
88 | String result = "";
89 | while ((result = bufferedReader.readLine()) != null) {
90 | LogUtils.dTag(TAG, "服务端接到的数据为:" + result);
91 | //把数据带回activity显示
92 | Message msg = handler.obtainMessage();
93 | msg.obj = result;
94 | msg.arg1 = SERVER_ARG;
95 | handler.sendMessage(msg);
96 | }
97 | }
98 | } catch (IOException e) {
99 | // TODO Auto-generated catch block
100 | e.printStackTrace();
101 | }
102 | }
103 |
104 | public void close() {
105 | try {
106 | if (printWriter != null) {
107 | printWriter.close();
108 | }
109 | if (bufferedReader != null) {
110 | bufferedReader.close();
111 | }
112 | if (clientSocket != null) {
113 | clientSocket.close();
114 | }
115 | if (serverSocket != null) {
116 | serverSocket.close();
117 | }
118 | } catch (IOException e) {
119 | // TODO Auto-generated catch block
120 | e.printStackTrace();
121 | }
122 | }
123 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/bao/wifidemo/utils/CheckPermission.java:
--------------------------------------------------------------------------------
1 | package com.bao.wifidemo.utils;
2 |
3 | import android.Manifest;
4 | import android.app.Activity;
5 | import android.content.DialogInterface;
6 | import android.os.Build;
7 | import android.support.annotation.NonNull;
8 |
9 | import com.bao.wifidemo.R;
10 | import com.yanzhenjie.permission.AndPermission;
11 | import com.yanzhenjie.permission.PermissionListener;
12 | import com.yanzhenjie.permission.Rationale;
13 | import com.yanzhenjie.permission.RationaleListener;
14 |
15 | import java.util.List;
16 |
17 | /**
18 | * Created by solexit04 on 2017/7/6.
19 | * 动态权限
20 | */
21 |
22 | public abstract class CheckPermission
23 | {
24 | private Activity activity;
25 |
26 | public CheckPermission(Activity activity)
27 | {
28 | this.activity = activity;
29 | }
30 |
31 | //存储
32 | public static final int REQUEST_CODE_PERMISSION_STORAGE = 100;
33 | //相机
34 | public static final int REQUEST_CODE_PERMISSION_CAMERA = 101;
35 | //日历
36 | public static final int REQUEST_CODE_PERMISSION_CALENDAR = 102;
37 | //定位
38 | public static final int REQUEST_CODE_PERMISSION_LOCATION = 103;
39 | //短信
40 | public static final int REQUEST_CODE_PERMISSION_SMS = 104;
41 | //联系人
42 | public static final int REQUEST_CODE_PERMISSION_CONTACTS = 105;
43 | //打电话,手机状态
44 | public static final int REQUEST_CODE_PERMISSION_PHONE = 106;
45 | //麦克风
46 | public static final int REQUEST_CODE_PERMISSION_MICROPHONE = 107;
47 | //传感器
48 | public static final int REQUEST_CODE_PERMISSION_SENSORS = 108;
49 | //综合
50 | public static final int REQUEST_CODE_PERMISSION_OTHER = 109;
51 |
52 | /**
53 | * 检测权限
54 | */
55 | public void permission(int permissionType)
56 | {
57 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
58 | {
59 | switch (permissionType)
60 | {
61 | case REQUEST_CODE_PERMISSION_LOCATION:
62 | AndPermission.with(activity)
63 | .requestCode(REQUEST_CODE_PERMISSION_LOCATION)
64 | .permission(Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.CHANGE_WIFI_STATE)
65 | .callback(permissionListener)
66 | // rationale作用是:用户拒绝一次权限,再次申请时先征求用户同意,再打开授权对话框;
67 | // 这样避免用户勾选不再提示,导致以后无法申请权限。
68 | // 你也可以不设置。
69 | .rationale(new RationaleListener()
70 | {
71 | @Override
72 | public void showRequestPermissionRationale(int requestCode, Rationale rationale)
73 | {
74 | // 这里的对话框可以自定义,只要调用rationale.resume()就可以继续申请。
75 | AndPermission.rationaleDialog(activity, rationale)
76 | .show();
77 | }
78 | })
79 | .start();
80 | break;
81 | }
82 | }
83 | }
84 |
85 | /**
86 | * 回调监听。
87 | */
88 | private PermissionListener permissionListener = new PermissionListener()
89 | {
90 | @Override
91 | public void onSucceed(int requestCode, @NonNull List grantPermissions)
92 | {
93 | permissionSuccess();
94 | }
95 |
96 | @Override
97 | public void onFailed(int requestCode, @NonNull List deniedPermissions)
98 | {
99 | permissionError();
100 | String title = activity.getString(R.string.permission_request_error);
101 | String message = "我们需要的一些权限被您拒绝或者系统发生错误申请失败,请您到设置页面手动授权,否则功能无法正常使用!";
102 | switch (requestCode)
103 | {
104 | case REQUEST_CODE_PERMISSION_LOCATION:
105 | message = activity.getString(R.string.permission_location);
106 | break;
107 | }
108 |
109 | // 用户否勾选了不再提示并且拒绝了权限,那么提示用户到设置中授权。
110 | if (AndPermission.hasAlwaysDeniedPermission(activity, deniedPermissions))
111 | {
112 | // 第二种:用自定义的提示语。
113 | AndPermission.defaultSettingDialog(activity, requestCode)
114 | .setTitle(title)
115 | .setMessage(message)
116 | .setPositiveButton(activity.getString(R.string.setting))
117 | .setNegativeButton(activity.getString(R.string.cancel), new DialogInterface.OnClickListener()
118 | {
119 | @Override
120 | public void onClick(DialogInterface dialog, int which)
121 | {
122 | negativeButton();
123 | }
124 | })
125 | .show();
126 | }
127 | }
128 | };
129 |
130 | /**
131 | * 权限申请成功
132 | */
133 | public abstract void permissionSuccess();
134 |
135 | /**
136 | * 权限申请失败
137 | */
138 | public void permissionError()
139 | {
140 | }
141 |
142 | /**
143 | * 取消按钮
144 | */
145 | public void negativeButton()
146 | {
147 | activity.finish();
148 | }
149 | }
150 |
--------------------------------------------------------------------------------
/app/src/main/java/com/bao/wifidemo/utils/Constants.kt:
--------------------------------------------------------------------------------
1 | package com.bao.wifidemo.utils
2 |
3 | object Constants {
4 | val HOST_ADDRESS = "255.255.255.255"
5 |
6 | val HOST_PORT = 20001
7 | val PHONE_PORT = 4001
8 |
9 | val WIFI_NAME = "bao_phone"
10 | val WIFI_PWD = "baozi888888"
11 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/bao/wifidemo/utils/WifiControlUtils.java:
--------------------------------------------------------------------------------
1 | package com.bao.wifidemo.utils;
2 |
3 | import android.content.Context;
4 | import android.net.wifi.ScanResult;
5 | import android.net.wifi.WifiConfiguration;
6 | import android.net.wifi.WifiInfo;
7 | import android.net.wifi.WifiManager;
8 |
9 | import com.blankj.utilcode.util.ToastUtils;
10 |
11 | import java.lang.reflect.InvocationTargetException;
12 | import java.lang.reflect.Method;
13 | import java.util.List;
14 |
15 | /**
16 | * Created by bao on 2018/3/21.
17 | * wifi控制工具
18 | */
19 | public class WifiControlUtils {
20 | //无密码
21 | static final public int WIFI_CIPHER_NPW = 0;
22 | //WEP加密
23 | static final public int WIFI_CIPHER_WEP = 1;
24 | //WAP加密
25 | static final public int WIFI_CIPHER_WAP = 2;
26 |
27 | private WifiManager mWifiManager;
28 | //能够阻止wifi进入睡眠状态,使wifi一直处于活跃状态
29 | private WifiManager.WifiLock mWifiLock;
30 | //扫描出的wifi列表
31 | private List wifiList;
32 | //已连接过的wifi列表
33 | private List wifiConfigurationList;
34 |
35 |
36 | public WifiControlUtils(Context context) {
37 | //获取wifiManager对象
38 | mWifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
39 | }
40 |
41 | /**
42 | * 打开wifi
43 | */
44 | public void openWifi() {
45 | if (!mWifiManager.isWifiEnabled()) {
46 | mWifiManager.setWifiEnabled(true);
47 | scanWifi();
48 | }
49 | }
50 |
51 | /**
52 | * 关闭wifi
53 | */
54 | public void closeWifi() {
55 | if (mWifiManager.isWifiEnabled()) {
56 | mWifiManager.setWifiEnabled(false);
57 | }
58 | }
59 |
60 | /**
61 | * 获取wifi连接信息
62 | **/
63 | public WifiInfo getWifiInfo() {
64 | if (mWifiManager != null) {
65 | return mWifiManager.getConnectionInfo();
66 | }
67 | return null;
68 | }
69 |
70 |
71 | /**
72 | * 搜索wifi
73 | */
74 | public void scanWifi() {
75 | mWifiManager.startScan();
76 | //得到扫描结果
77 | wifiList = mWifiManager.getScanResults();
78 | //得到配置过的网络
79 | wifiConfigurationList = mWifiManager.getConfiguredNetworks();
80 | }
81 |
82 | /**
83 | * 获取连接过的wifi
84 | */
85 | public List getWifiConfigurationList() {
86 | //得到配置过的网络
87 | wifiConfigurationList = mWifiManager.getConfiguredNetworks();
88 | return wifiConfigurationList;
89 | }
90 |
91 | /**
92 | * 获取扫描wifi的列表
93 | * 同名字的wifi可以出现多个,比如公司里面的wifi都叫同一个名字,但是由不同的路由器发出来的
94 | */
95 | public List getWifiList() {
96 | //得到扫描结果
97 | wifiList = mWifiManager.getScanResults();
98 | return wifiList;
99 | }
100 |
101 | /**
102 | * 创建一个WifiLock
103 | **/
104 | public void createWifiLock() {
105 | mWifiLock = this.mWifiManager.createWifiLock("testLock");
106 | }
107 |
108 | /**
109 | * 锁定WifiLock,当下载大文件时需要锁定
110 | **/
111 | public void acquireWifiLock() {
112 | mWifiLock.acquire();
113 | }
114 |
115 | /**
116 | * 解锁WifiLock
117 | **/
118 | public void releaseWifilock() {
119 | if (mWifiLock.isHeld()) {
120 | //判断时候锁定
121 | mWifiLock.acquire();
122 | }
123 | }
124 |
125 | public void addNetWork(String SSID) {
126 | int netId = -1;
127 | if (getExitsWifiConfig(SSID) != null) {
128 | //这个wifi是连接过的,如果这个wifi在连接之后改了密码,那就只能手动去删除了
129 | netId = getExitsWifiConfig(SSID).networkId;
130 | //这个方法的第一个参数是需要连接wifi网络的networkId,第二个参数是指连接当前wifi网络是否需要断开其他网络
131 | //无论是否连接上,都返回true。。。。
132 | mWifiManager.enableNetwork(netId, true);
133 | }
134 | }
135 |
136 | /**
137 | * 连接指定wifi
138 | * 6.0以上版本,直接查找时候有连接过,连接过的拿出wifiConfiguration用
139 | * 不要去创建新的wifiConfiguration,否者失败
140 | */
141 | public void addNetWork(String SSID, String password, int Type) {
142 | int netId = -1;
143 | /*先执行删除wifi操作,1.如果删除的成功说明这个wifi配置是由本APP配置出来的;
144 | 2.这样可以避免密码错误之后,同名字的wifi配置存在,无法连接;
145 | 3.wifi直接连接成功过,不删除也能用, netId = getExitsWifiConfig(SSID).networkId;*/
146 | if (removeWifi(SSID)) {
147 | //移除成功,就新建一个
148 | netId = mWifiManager.addNetwork(createWifiInfo(SSID, password, Type));
149 | } else {
150 | //删除不成功,要么这个wifi配置以前就存在过,要么是还没连接过的
151 | if (getExitsWifiConfig(SSID) != null) {
152 | //这个wifi是连接过的,如果这个wifi在连接之后改了密码,那就只能手动去删除了
153 | netId = getExitsWifiConfig(SSID).networkId;
154 | } else {
155 | //没连接过的,新建一个wifi配置
156 | netId = mWifiManager.addNetwork(createWifiInfo(SSID, password, Type));
157 | }
158 | }
159 |
160 | //这个方法的第一个参数是需要连接wifi网络的networkId,第二个参数是指连接当前wifi网络是否需要断开其他网络
161 | //无论是否连接上,都返回true。。。。
162 | mWifiManager.enableNetwork(netId, true);
163 | }
164 |
165 | /**
166 | * 获取配置过的wifiConfiguration
167 | */
168 | public WifiConfiguration getExitsWifiConfig(String SSID) {
169 | wifiConfigurationList = mWifiManager.getConfiguredNetworks();
170 | for (WifiConfiguration wifiConfiguration : wifiConfigurationList) {
171 | if (wifiConfiguration.SSID.equals("\"" + SSID + "\"")) {
172 | return wifiConfiguration;
173 | }
174 | }
175 | return null;
176 | }
177 |
178 | /**
179 | * 移除wifi,因为权限,无法移除的时候,需要手动去翻wifi列表删除
180 | * 注意:!!!只能移除自己应用创建的wifi。
181 | * 删除掉app,再安装的,都不算自己应用,具体看removeNetwork源码
182 | *
183 | * @param netId wifi的id
184 | */
185 | public boolean removeWifi(int netId) {
186 | return mWifiManager.removeNetwork(netId);
187 | }
188 |
189 | /**
190 | * 移除wifi
191 | *
192 | * @param SSID wifi名
193 | */
194 | public boolean removeWifi(String SSID) {
195 | if (getExitsWifiConfig(SSID) != null) {
196 | return removeWifi(getExitsWifiConfig(SSID).networkId);
197 | } else {
198 | return false;
199 | }
200 | }
201 |
202 | /**
203 | * 断开指定ID的网络
204 | *
205 | * @param netId 网络id
206 | */
207 | public void disconnectWifi(int netId) {
208 | mWifiManager.disableNetwork(netId);
209 | mWifiManager.disconnect();
210 | }
211 |
212 | /**
213 | * 断开指定SSID的网络
214 | *
215 | * @param SSID wifi名
216 | */
217 | public void disconnectWifi(String SSID) {
218 | if (getExitsWifiConfig(SSID) != null) {
219 | disconnectWifi(getExitsWifiConfig(SSID).networkId);
220 | }
221 | }
222 |
223 |
224 | /**
225 | * 创建一个wifiConfiguration
226 | *
227 | * @param SSID wifi名称
228 | * @param password wifi密码
229 | * @param Type 加密类型
230 | * @return
231 | */
232 | public WifiConfiguration createWifiInfo(String SSID, String password, int Type) {
233 | WifiConfiguration config = new WifiConfiguration();
234 | config.allowedAuthAlgorithms.clear();
235 | config.allowedGroupCiphers.clear();
236 | config.allowedKeyManagement.clear();
237 | config.allowedPairwiseCiphers.clear();
238 | config.allowedProtocols.clear();
239 | config.SSID = "\"" + SSID + "\"";
240 |
241 | //如果有相同配置的,就先删除
242 | WifiConfiguration tempConfig = getExitsWifiConfig(SSID);
243 | if (tempConfig != null) {
244 | mWifiManager.removeNetwork(tempConfig.networkId);
245 | mWifiManager.saveConfiguration();
246 | }
247 |
248 | //无密码
249 | if (Type == WIFI_CIPHER_NPW) {
250 | //config.wepKeys[0] = "";
251 | config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
252 | //config.wepTxKeyIndex = 0;
253 | }
254 | //WEP加密
255 | else if (Type == WIFI_CIPHER_WEP) {
256 | config.hiddenSSID = true;
257 | config.wepKeys[0] = "\"" + password + "\"";
258 | config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
259 | config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
260 | config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
261 | config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
262 | config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
263 | config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
264 | config.wepTxKeyIndex = 0;
265 | }
266 | //WPA加密
267 | else if (Type == WIFI_CIPHER_WAP) //WIFICIPHER_WPA
268 | {
269 | config.preSharedKey = "\"" + password + "\"";
270 | config.hiddenSSID = true;
271 | config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
272 | config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
273 | config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
274 | config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
275 | //config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
276 | config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
277 | config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
278 | config.status = WifiConfiguration.Status.ENABLED;
279 | }
280 | return config;
281 | }
282 | }
--------------------------------------------------------------------------------
/app/src/main/res/drawable-v24/ic_launcher_foreground.xml:
--------------------------------------------------------------------------------
1 |
7 |
12 |
13 |
19 |
22 |
25 |
26 |
27 |
28 |
34 |
35 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_down.xml:
--------------------------------------------------------------------------------
1 |
6 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable/ic_launcher_background.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
10 |
15 |
20 |
25 |
30 |
35 |
40 |
45 |
50 |
55 |
60 |
65 |
70 |
75 |
80 |
85 |
90 |
95 |
100 |
105 |
110 |
115 |
120 |
125 |
130 |
135 |
140 |
145 |
150 |
155 |
160 |
165 |
170 |
171 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/global_black_line.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/global_black_vertical_line.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/main_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
7 |
8 |
17 |
18 |
19 |
20 |
29 |
30 |
31 |
32 |
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/tcp_client_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
17 |
18 |
22 |
23 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/tcp_server_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
17 |
18 |
22 |
23 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/wifi_control_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
11 |
12 |
21 |
22 |
23 |
24 |
33 |
34 |
35 |
36 |
45 |
46 |
47 |
48 |
57 |
58 |
59 |
60 |
61 |
62 |
71 |
72 |
73 |
74 |
83 |
84 |
85 |
86 |
90 |
91 |
100 |
101 |
102 |
103 |
112 |
113 |
114 |
115 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
134 |
135 |
140 |
141 |
142 |
143 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/wifi_tcp_activity.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 |
7 |
12 |
13 |
22 |
23 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/wifi_udp_activity.xml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
11 |
12 |
17 |
18 |
24 |
25 |
26 |
30 |
31 |
36 |
37 |
44 |
45 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Goodbao/WifiDemo/db531872e7087bac8916eccb1340e6af56e03a4c/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Goodbao/WifiDemo/db531872e7087bac8916eccb1340e6af56e03a4c/app/src/main/res/mipmap-hdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Goodbao/WifiDemo/db531872e7087bac8916eccb1340e6af56e03a4c/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Goodbao/WifiDemo/db531872e7087bac8916eccb1340e6af56e03a4c/app/src/main/res/mipmap-mdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Goodbao/WifiDemo/db531872e7087bac8916eccb1340e6af56e03a4c/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Goodbao/WifiDemo/db531872e7087bac8916eccb1340e6af56e03a4c/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Goodbao/WifiDemo/db531872e7087bac8916eccb1340e6af56e03a4c/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Goodbao/WifiDemo/db531872e7087bac8916eccb1340e6af56e03a4c/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Goodbao/WifiDemo/db531872e7087bac8916eccb1340e6af56e03a4c/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/Goodbao/WifiDemo/db531872e7087bac8916eccb1340e6af56e03a4c/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
8 | #4d4d4d
9 |
10 |
11 | #181818
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 15sp
6 | 15dp
7 |
8 |
9 | 15sp
10 | 15dp
11 |
12 |
13 | 15sp
14 | 15dp
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | WifiDemo
3 |
4 |
5 | wifi控制
6 | wifi_tcp通信
7 | wifi_udp通信
8 | 打开wifi
9 | 关闭wifi
10 | 搜索wifi
11 | 连接
12 | 断开
13 | 创建ap热点
14 | 关闭ap热点
15 | 删除
16 | wifi名称
17 | wifi密码
18 | wifi信息
19 | wifi已经关闭
20 | wifi正在关闭
21 | wifi已开启
22 | wifi正在开启
23 | 已连接到wifi:%s
24 | 无法删除,请到wifi设置页面,手动删除
25 | wifi验证失败,可能是密码错误
26 | 发送
27 | 终止
28 | 接收
29 | 建立连接
30 |
31 | 取消
32 | 确定
33 | 设置
34 |
35 |
36 | 先开启TCP_Server
37 | 再开启TCP_Client
38 |
39 |
40 | "申请权限失败"
41 | APP正常运行需要定位权限,被您拒绝或者系统发生错误申请失败,请您到权限设置页面手动授权,否则功能无法正常使用!
42 |
43 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | ext.kotlin_version = '1.2.30'
5 |
6 | repositories {
7 | google()
8 | jcenter()
9 | }
10 | dependencies {
11 | classpath 'com.android.tools.build:gradle:3.1.2'
12 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
13 |
14 | // NOTE: Do not place your application dependencies here; they belong
15 | // in the individual module build.gradle files
16 | }
17 | }
18 |
19 | allprojects {
20 | repositories {
21 | google()
22 | jcenter()
23 | }
24 | }
25 |
26 | task clean(type: Delete) {
27 | delete rootProject.buildDir
28 | }
29 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Fri Jul 20 08:18:48 CST 2018
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
7 |
--------------------------------------------------------------------------------
/local.properties:
--------------------------------------------------------------------------------
1 | ## This file must *NOT* be checked into Version Control Systems,
2 | # as it contains information specific to your local configuration.
3 | #
4 | # Location of the SDK. This is only used by Gradle.
5 | # For customization when using a Version Control System, please read the
6 | # header note.
7 | #Fri Sep 28 11:14:23 CST 2018
8 | sdk.dir=/Users/wuyanhua/Library/Android/sdk
9 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------