史上最全Andriod手机热点Socket通信--基于Android 9

本文详细介绍了在Android 9系统中,两台设备如何通过开启热点实现Socket通信。内容涵盖开启热点、获取热点IP、建立ServerSocket以及客户端连接的注意事项,强调了在获取IP过程中遇到的问题及解决方案。
摘要由CSDN通过智能技术生成

前言
关于开启热点,手机间通信,网上有很多相关的例子,但几乎所有的例子只在开启热点和进行socket连接部分有比较详细的描叙,实际上,这其中还有很多重要的细节,例如热点的IP如何获得, socket连接如何保证连接上等?

正文
两个Android手机要想相互间通信,可以通过蓝牙,也可以通过WIFI,相对而已WIFI的速度更快,但两个手机必须连接同一WIFI源才行。如果没有WIF源呢?Android 9提供了一个叫LocalOnlyHotspot的东西,其中一个手机开启热点,另一手机连接此热点,然后就可以通过socket通信。
实际上,这整个过程可以划分为三个独立部分开启热点、启动ServerSocket、连接热点并连接socket。但下面我是按相关技术的要点进行分段描叙的。

  1. 开启热点,获得热点名称,密码
    这部分在网上有很多介绍,我就直接贴代码了:
private void startHotApp(final Intent intent) {
   
        final WifiManager manager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        if (manager!= null && Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
   
            manager.startLocalOnlyHotspot(new WifiManager.LocalOnlyHotspotCallback() {
   
                @Override
                public void onStarted(WifiManager.LocalOnlyHotspotReservation reservation) {
   
                    super.onStarted(reservation);
                    sReservation = reservation;
                    PendingIntent pendingIntent = intent.getParcelableExtra("pendingIntent");
                    Intent data = new Intent();
                    data.putExtra(Constants.KEY_SSID, reservation.getWifiConfiguration().SSID);
                    data.putExtra(Constants.KEY_PRESHARE, reservation.getWifiConfiguration().preSharedKey);
                    final String ipAddress = getLocalIpAddress();
                    data.putExtra(Constants.KEY_IP, ipAddress);
                    try {
   
                        DebugLog.info("pendingIntent.send:" + ipAddress);
                        if(pendingIntent != null) {
   
                            pendingIntent.send(HotService.this, 200, data);
                        }
                    } catch (PendingIntent.CanceledException e) {
   
                        e.printStackTrace();
                    }
                }

                @Override
                public void onStopped() {
   
                    super.onStopped();
                }

                @Override
                public void onFailed(int reason) {
   
                    super.onFailed(reason);
                }
            }, null);
        }
    }
  1. 获得热点的IP
    这部分我要重点说说,网上很多通过WifiManager或者读取本地文件等方式来获取手机IP,其实都是不对的,我们手机连接别人的热点,才能通过这种方式获得IP,而我们手机自己开启的热点,这种方式要么获得的一直是0,要么就不对,可能是以前手机连接他人的热点形成的ip。
    首先,我们来看看热点IP是如何生成的:
    源代码网址:
    http://androidxref.com/9.0.0_r3/xref/frameworks/base/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java
198    // TODO: Refactor this in terms of calls to InterfaceController.
199    private boolean configureIPv4(boolean enabled) {
   
200        if (VDBG) Log.d(TAG, "configureIPv4(" + enabled + ")");
201
202        // TODO: Replace this hard-coded information with dynamically selected
203        // config passed down to us by a higher layer IP-coordinating element.
204        String ipAsString = null;
205        int prefixLen = 0;
206        if (mInterfaceType == ConnectivityManager.TETHERING_USB) {
   
207            ipAsString = USB_NEAR_IFACE_ADDR;
208            prefixLen = USB_PREFIX_LENGTH
Android Studio中进行socket通信可以使用Java的Socket类。下面是一个简单的示例代码,演示如何在Android应用中使用socket进行通信: 1. 在AndroidManifest.xml文件中添加网络权限: ```xml <uses-permission android:name="android.permission.INTERNET" /> ``` 2. 在需要进行socket通信的Activity或Fragment中,创建一个新的线程用于处理socket连接和通信: ```java import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.io.PrintWriter; import java.net.Socket; public class SocketThread extends Thread { private Socket socket; private BufferedReader reader; private PrintWriter writer; @Override public void run() { try { // 创建socket连接 socket = new Socket("服务器IP地址", 端口号); // 获取输入输出流 reader = new BufferedReader(new InputStreamReader(socket.getInputStream())); writer = new PrintWriter(socket.getOutputStream(), true); // 发送数据 writer.println("Hello Server!"); // 接收数据 String response = reader.readLine(); if (response != null) { // 处理服务器返回的数据 } // 关闭连接 socket.close(); } catch (IOException e) { e.printStackTrace(); } } } ``` 3. 在需要使用socket的地方创建并启动该线程: ```java SocketThread socketThread = new SocketThread(); socketThread.start(); ``` 在实际应用中,你需要根据你的具体需求进行修改和完善。例如,可以在UI线程中更新UI界面,使用更复杂的数据交换协议等。同时,为了避免在主线程中进行网络请求,你还可以考虑使用异步任务或者其他线程池来执行socket通信操作。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值