引言:为什么要手机连电脑?(分享踩过的坑:MySQL远程授权、防火墙、Android明文流量)

由于之前想着开发手机软件,思考了一些连接的问题之后,便尝试用手机连接电脑。

目录

1.用JDBC+MySQL(失败)

2.网页的数据传输,就用电脑作为服务器,使用了Node.js+HTTP APL(成功)

3.运行结果展示:​


1.用JDBC+MySQL(失败)

想法:Android里用mysql-connector-java,像Java后端一样连接数据库。

遇到的阻碍:

1.公钥检索错误:MySQL8.0要求allowPublickeyRetrieval=true,加了又报超时。

2.网络超时:手机和电脑连接的是同一个WiFi,却连接不到3306(数据库端口)。

   我关掉了Windows防火墙->还是超时。

   当然应该关掉路由器的"AP隔离"(不清楚,不是自家路由)。

   使用热点->还是超时(热点也许有AP隔离,实际上确实有隔离)。

   用电脑telnet自己的3306是通的???,手机telnet电脑IP不通,意识到需要添加些代码,来输出 错误原因。

3.Android驱动缺失:

    NoClassDefFoundError:Failed resolution of: Lcom/mysql/cj/MysqlType-就算加了依赖,Android的dex也也会因为java版本冲突而失效。

4.明文流量禁令:Android 9+默认禁止HTTP明文,需要usesCleartextTraffic="true",解决了,依然没用。

结论:JDBC 直连 MySQL 在局域网环境下几乎不可行。主要原因包括:驱动体积过大、Android 兼容性问题突出、以及网络层面的限制——无论是路由器还是手机热点,大多默认开启了客户端隔离,且没有提供关闭选项。

5.显示的错误信息

2.使用 Node.js + HTTP API(客户端-服务器架构)(成功,手机热点,无线wifi都成功,这套架构之所以在手机热点和普通 WiFi 下都能成功,是因为它不依赖设备之间的直接 TCP 连接,从而绕开了热点或路由器可能开启的客户端隔离限制)

实施步骤

  1. 写一个 server.js,连接本地 MySQL,暴露 /data 接口。

  2. 电脑运行 node server.js,监听 3000 端口。

  3. 手机端用 http://电脑IP:3000/data 发送 GET 请求,解析 JSON 展示。

遇到的阻碍及解决

  • Node.js 模块缺失Cannot find module 'mysql2' → 执行 npm install express mysql2

  • 防火墙挡路:“原本担心防火墙会拦截 3000 端口,但检查发现 Windows 防火墙已经自动为 Node.js 创建了入站规则,因此手机可以顺利访问(很久前运行类似 node server.js的命令,让防火墙放权)。”。

  • 手机访问不了 IP:发现电脑 IP 变了(动态 IP)→ 给电脑设置静态 IP,或在 App 里加个 IP 输入框。

  • 明文流量又被拦:记得在 AndroidManifest.xml 加 android:usesCleartextTraffic="true"

最终结果:手机浏览器直接访问 http://192.168.1.105:3000/data 能看到 JSON 数据,App 里也能正常显示。

执行步骤如下:

node init 产生package.json文件,node install express mysql,生成package-lock.json文件和node_modules文件夹,创建server.js文件为后端文件,

server.js文件代码如下:

const express = require('express');

const mysql = require('mysql2');

const app = express();



const db = mysql.createConnection({

    host: 'localhost',

    user: 'user,

    password: 'password',

    database: 'serial_data'

});



db.connect();



app.get('/data', (req, res) => {

    db.query('SELECT id, port_name, raw_text, temperature, humidity, light_intensity, receive_time FROM serial_receive_data ORDER BY id DESC LIMIT 20',

        (err, results) => {

            if (err) {

                res.status(500).json({ error: err.message });

            } else {

                res.json(results);

            }

        });

});



app.listen(3000, () => {

    console.log('API server running on http://0.0.0.0:3000');

});

node server.js运行后端。

手机上运行用Android Studio编写的程序。

主要文件为MainActivity.java(主程序文件),build.gradle(项目配置文件),AndroidManifest.xml(项目配置文件)。

MainActivity.java代码如下:

package com.example.serialdataviewer;

import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;

public class MainActivity extends AppCompatActivity {

    private TextView textView;
    private Handler handler = new Handler(Looper.getMainLooper());

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        textView = new TextView(this);
        textView.setText("正在加载数据...");
        textView.setTextSize(16);
        textView.setPadding(50, 50, 50, 50);
        setContentView(textView);

        new Thread(this::fetchData).start();
    }

    private void fetchData() {
        HttpURLConnection conn = null;
        try {
            String ip = "192.168.40.82"; // 你的电脑 IP
            URL url = new URL("http://" + ip + ":3000/data");
            conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            conn.setConnectTimeout(5000);
            conn.setReadTimeout(5000);
            int responseCode = conn.getResponseCode();
            if (responseCode == 200) {
                InputStream is = conn.getInputStream();
                BufferedReader reader = new BufferedReader(new InputStreamReader(is, "UTF-8"));
                StringBuilder sb = new StringBuilder();
                String line;
                while ((line = reader.readLine()) != null) sb.append(line);
                reader.close();
                String json = sb.toString();
                // 解析 JSON
                JSONArray array = new JSONArray(json);
                StringBuilder display = new StringBuilder();
                display.append("===== 串口数据记录 =====\n\n");
                for (int i = 0; i < array.length(); i++) {
                    JSONObject obj = array.getJSONObject(i);
                    display.append("ID: ").append(obj.getInt("id")).append("\n");
                    display.append("串口: ").append(obj.getString("port_name")).append("\n");
                    display.append("数据: ").append(obj.getString("raw_text")).append("\n");
                    display.append("温度: ").append(obj.optDouble("temperature")).append("°C\n");
                    display.append("湿度: ").append(obj.optDouble("humidity")).append("%\n");
                    display.append("光照: ").append(obj.optDouble("light_intensity")).append("\n");
                    display.append("时间: ").append(obj.getString("receive_time")).append("\n");
                    display.append("----------------------\n");
                }
                final String result = display.toString();
                handler.post(() -> textView.setText(result));
            } else {
                handler.post(() -> textView.setText("HTTP 错误: " + responseCode));
            }
        } catch (Exception e) {
            final String errMsg = "请求失败: " + e.getMessage();
            handler.post(() -> textView.setText(errMsg));
            e.printStackTrace();
        } finally {
            if (conn != null) conn.disconnect();
        }
    }
}

AndroidManifest.xml的application标签里添加android:usesCleartextTraffic="true",并且在 <manifest> 标签下添加

<uses-permission android:name="android.permission.INTERNET" />

3.运行结果展示:

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐