瀏覽代碼

wifi扫描-连接

JianXin 1 年之前
父節點
當前提交
3c7cd1f845

+ 1 - 0
android/app/build.gradle

@@ -57,3 +57,4 @@ android {
 flutter {
     source '../..'
 }
+

+ 7 - 1
android/app/src/main/AndroidManifest.xml

@@ -1,6 +1,12 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="com.example.smartledz_wifi_test">
-   <application
+
+    <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_FINE_LOCATION" />
+    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
+
+    <application
         android:label="smartledz_wifi_test"
         android:name="${applicationName}"
         android:icon="@mipmap/ic_launcher">

+ 122 - 0
android/app/src/main/java/com/example/smartledz_wifi_test/MainActivity.java

@@ -1,6 +1,128 @@
 package com.example.smartledz_wifi_test;
 
+import android.Manifest;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.PackageManager;
+import android.net.wifi.ScanResult;
+import android.net.wifi.WifiManager;
+import android.os.Build;
+import android.os.Bundle;
+import android.widget.ArrayAdapter;
+
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+import androidx.core.app.ActivityCompat;
+import androidx.core.content.ContextCompat;
+
+import com.example.smartledz_wifi_test.plugin.EventChannelPlugin;
+import com.example.smartledz_wifi_test.plugin.WifiPlugin;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
 import io.flutter.embedding.android.FlutterActivity;
+import io.flutter.embedding.engine.FlutterEngine;
+import io.flutter.plugins.GeneratedPluginRegistrant;
 
 public class MainActivity extends FlutterActivity {
+
+
+    public static WifiManager wifiManager;
+
+    private static final int PERMISSIONS_REQUEST_CODE = 1;
+    private BroadcastReceiver wifiScanReceiver;
+
+    @Override
+    protected void onCreate(@Nullable Bundle savedInstanceState) {
+        wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
+        // 检查并请求定位权限
+        checkAndRequestPermissions();
+        // 注册Wi-Fi扫描广播接收器
+        registerWifiScanReceiver();
+        // 检查并启用Wi-Fi
+        if (!wifiManager.isWifiEnabled()) {
+            wifiManager.setWifiEnabled(true);
+        }
+        super.onCreate(savedInstanceState);
+    }
+
+    private BroadcastReceiver mReceiver =new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (intent.getAction().equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
+                List<ScanResult> results = wifiManager.getScanResults();
+                if (results !=null) {
+                    System.out.println("results size");
+                    System.out.println(results.size());
+                }
+            }
+        }
+    };
+
+    @Override
+    public void configureFlutterEngine(@NonNull FlutterEngine flutterEngine) {
+        //插件实例的注册...
+        // telink-sdk插件
+        flutterEngine.getPlugins().add(new WifiPlugin());
+        // 通知插件
+        flutterEngine.getPlugins().add(EventChannelPlugin.getInstance());
+        //这个是必写,别删除!!
+        GeneratedPluginRegistrant.registerWith(flutterEngine);
+    }
+
+    private void scanWifiList() {
+        List<ScanResult> scanResults = wifiManager.getScanResults();
+//        System.out.println("获取扫描列表");
+//        System.out.println(scanResults);
+//        System.out.println("-----------------------------");
+        List<Map<String,String>> wifiList = new ArrayList<>();
+        for (ScanResult scanResult : scanResults) {
+            if(!scanResult.SSID.equals("endo-lighting")){
+                continue;
+            }
+            Map<String,String> wifi = new HashMap<>();
+            wifi.put("ssid",scanResult.SSID);
+            wifi.put("bssid",scanResult.BSSID);
+            wifi.put("level", String.valueOf(scanResult.level));
+            wifiList.add(wifi);
+        }
+        JSONObject response = new JSONObject();
+        try {
+            response.put("cmd","scanResult");
+            response.put("data",wifiList);
+        } catch (JSONException e) {
+            throw new RuntimeException(e);
+        }
+        EventChannelPlugin.getInstance().sendEventData(response.toString());
+    }
+
+    private void checkAndRequestPermissions() {
+        int permissionCheck = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
+        if (permissionCheck != PackageManager.PERMISSION_GRANTED) {
+            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSIONS_REQUEST_CODE);
+        }
+    }
+
+    private void registerWifiScanReceiver() {
+        wifiScanReceiver = new BroadcastReceiver() {
+            @Override
+            public void onReceive(Context context, Intent intent) {
+                if (intent.getAction().equals(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION)) {
+                    scanWifiList();
+                }
+            }
+        };
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
+        registerReceiver(wifiScanReceiver, intentFilter);
+    }
+
 }

+ 69 - 0
android/app/src/main/java/com/example/smartledz_wifi_test/plugin/EventChannelPlugin.java

@@ -0,0 +1,69 @@
+package com.example.smartledz_wifi_test.plugin;
+
+import androidx.annotation.NonNull;
+
+import io.flutter.embedding.engine.plugins.FlutterPlugin;
+import io.flutter.plugin.common.EventChannel;
+
+public class EventChannelPlugin implements FlutterPlugin, EventChannel.StreamHandler{
+
+    public static final String CHANNEL_NAME = "native_event_channel";
+    private EventChannel eventChannel;
+    private EventChannel.EventSink eventSink;
+
+    private static volatile EventChannelPlugin instance;
+
+    private EventChannelPlugin() {
+    }
+
+    public static EventChannelPlugin getInstance() {
+        if (instance == null) {
+            synchronized (EventChannelPlugin.class) {
+                if (instance == null) {
+                    instance = new EventChannelPlugin();
+                }
+            }
+        }
+        return instance;
+    }
+
+    /**
+     * 处理设置事件流的请求。
+     *
+     * @param arguments 流配置参数,可能为空。
+     * @param events    用于向flutter接收器发射事件。
+     */
+    @Override
+    public void onListen(Object arguments, EventChannel.EventSink events) {
+        this.eventSink = events;
+    }
+
+    /**
+     * 处理请求以删除最近创建的事件流。
+     *
+     * @param arguments 流配置参数,可能为空。
+     */
+    @Override
+    public void onCancel(Object arguments) {
+
+    }
+
+    public void sendEventData(Object data) {
+//        System.out.printf("通知数据:"+data.toString());
+        if (eventSink != null) {
+            eventSink.success(data);
+        }
+    }
+
+    @Override
+    public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
+        eventChannel = new EventChannel(binding.getBinaryMessenger(), CHANNEL_NAME);
+        eventChannel.setStreamHandler(this);
+    }
+
+    @Override
+    public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
+        eventSink.endOfStream();
+        eventChannel.setStreamHandler(null);
+    }
+}

+ 74 - 0
android/app/src/main/java/com/example/smartledz_wifi_test/plugin/WifiPlugin.java

@@ -0,0 +1,74 @@
+package com.example.smartledz_wifi_test.plugin;
+
+
+import android.net.wifi.WifiConfiguration;
+
+import androidx.annotation.NonNull;
+
+
+import com.example.smartledz_wifi_test.MainActivity;
+
+import io.flutter.embedding.engine.plugins.FlutterPlugin;
+import io.flutter.plugin.common.MethodChannel;
+
+public class WifiPlugin implements FlutterPlugin {
+
+    // 插件名称
+    public static final String channelName = "com.vanstone.WifiPlugin";
+
+    private static final int PERMISSIONS_REQUEST_CODE = 101;
+
+
+    @Override
+    public void onAttachedToEngine(@NonNull FlutterPlugin.FlutterPluginBinding binding) {
+        //可以利用binding对象获取到Android中需要的Context对象
+//        Context applicationContext = binding.getApplicationContext();
+
+
+        //设置channel名称,之后flutter中也要一样
+        MethodChannel channel = new MethodChannel(binding.getFlutterEngine().getDartExecutor(), channelName);
+
+        //把当前的MethodCallHandler设置
+        channel.setMethodCallHandler((call, result) -> {
+            String method = call.method;
+            switch (method) {
+                case "startScan":
+                    startScan();
+//                    System.out.println("-------------------");
+//                    System.out.println(scanResults);
+//                    System.out.println("-------------------");
+                    break;
+                case "connect":
+                    String ssid = call.argument("ssid");
+                    String bssid = call.argument("bssid");
+                    String password = call.argument("password");
+                    connect(ssid, bssid, password);
+//                    result.success(connect(mac));
+                    break;
+            }
+        });
+    }
+
+    @Override
+    public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
+
+    }
+
+
+    private void startScan() {
+        MainActivity.wifiManager.startScan(); // 触发Wi-Fi扫描
+    }
+
+    // 连接wifi
+    private void connect(String ssid, String bssid, String pwd) {
+        WifiConfiguration wifiConfig = new WifiConfiguration();
+        wifiConfig.SSID = "\"" + ssid + "\"";
+        wifiConfig.BSSID = bssid;
+        wifiConfig.preSharedKey = "\"" + pwd + "\"";
+        int networkId = MainActivity.wifiManager.addNetwork(wifiConfig);
+        MainActivity.wifiManager.disconnect();
+        MainActivity.wifiManager.enableNetwork(networkId, true);
+        MainActivity.wifiManager.reconnect();
+    }
+
+}

+ 2 - 0
lib/main.dart

@@ -1,4 +1,5 @@
 import 'package:flutter/material.dart';
+import 'package:smartledz_wifi_test/plugin/wifi_plugin.dart';
 
 void main() {
   runApp(const MyApp());
@@ -51,6 +52,7 @@ class _MyHomePageState extends State<MyHomePage> {
   int _counter = 0;
 
   void _incrementCounter() {
+    WiFiPlugin.startScan();
     setState(() {
       // This call to setState tells the Flutter framework that something has
       // changed in this State, which causes it to rerun the build method below

+ 26 - 0
lib/plugin/wifi_plugin.dart

@@ -0,0 +1,26 @@
+
+import 'package:flutter/services.dart';
+import 'package:permission_handler/permission_handler.dart';
+
+class WiFiPlugin {
+
+    static const MethodChannel _channel = MethodChannel("com.vanstone.WifiPlugin");
+
+    static Future<bool> requestPermissions() async {
+      bool locationGranted = await Permission.location.request().isGranted;
+      bool wifiGranted = await Permission.manageExternalStorage.request().isGranted;
+      bool storeGranted = await Permission.storage.request().isGranted;
+      return locationGranted && wifiGranted && storeGranted;
+    }
+
+
+    // 扫描wifi
+    static Future<void> startScan() async {
+        return await _channel.invokeMethod("startScan");
+    }
+
+    // 连接wifi
+    static Future<void> connect() async {
+      return await _channel.invokeMethod("connect");
+    }
+}

+ 49 - 0
pubspec.lock

@@ -123,6 +123,54 @@ packages:
       url: "https://pub.flutter-io.cn"
     source: hosted
     version: "1.8.2"
+  permission_handler:
+    dependency: "direct main"
+    description:
+      name: permission_handler
+      sha256: "1b6b3e73f0bcbc856548bbdfb1c33084a401c4f143e220629a9055233d76c331"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "10.3.0"
+  permission_handler_android:
+    dependency: transitive
+    description:
+      name: permission_handler_android
+      sha256: "8f6a95ccbca13766882f95d32684d7c9bfe6c45650c32bedba948ef1c6a4ddf7"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "10.2.3"
+  permission_handler_apple:
+    dependency: transitive
+    description:
+      name: permission_handler_apple
+      sha256: "08dcb6ce628ac0b257e429944b4c652c2a4e6af725bdf12b498daa2c6b2b1edb"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "9.1.0"
+  permission_handler_platform_interface:
+    dependency: transitive
+    description:
+      name: permission_handler_platform_interface
+      sha256: de20a5c3269229c1ae2e5a6b822f6cb59578b23e8255c93fbeebfc82116e6b11
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "3.10.0"
+  permission_handler_windows:
+    dependency: transitive
+    description:
+      name: permission_handler_windows
+      sha256: f67cab14b4328574938ecea2db3475dad7af7ead6afab6338772c5f88963e38b
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "0.1.2"
+  plugin_platform_interface:
+    dependency: transitive
+    description:
+      name: plugin_platform_interface
+      sha256: "6a2128648c854906c53fa8e33986fc0247a1116122f9534dd20e3ab9e16a32bc"
+      url: "https://pub.flutter-io.cn"
+    source: hosted
+    version: "2.1.4"
   sky_engine:
     dependency: transitive
     description: flutter
@@ -186,3 +234,4 @@ packages:
     version: "2.1.4"
 sdks:
   dart: ">=2.19.5 <3.0.0"
+  flutter: ">=2.8.0"

+ 1 - 0
pubspec.yaml

@@ -35,6 +35,7 @@ dependencies:
   # The following adds the Cupertino Icons font to your application.
   # Use with the CupertinoIcons class for iOS style icons.
   cupertino_icons: ^1.0.2
+  permission_handler: ^10.3.0
 
 dev_dependencies:
   flutter_test: