将Android作为服务端,与其他手机APP通讯并传输文件

一、感谢2个开源库

androidasync

implementation 'com.koushikdutta.async:androidasync:3.1.0'
//  大佬的README.md写的是下面这个,这个有bug:只能用http去请求,如果用https请求服务端APP会闪退,issues里建议升级为3.1.0
compile 'com.koushikdutta.async:androidasync:2.+'

okhttp

implementation 'com.squareup.okhttp3:okhttp:4.0.0'

二、搭建服务端APP

  AsyncHttpServer mServer = new AsyncHttpServer();
   
   // Post接口files
  mServer.post("/files", (request, response) -> {
            final MultipartFormDataBody body = request.getBody();
            body.setMultipartCallback(part -> {
            // http里每带一个Part都会走这个回调
                if (part.isFile()) {
                //  文件
                    body.setDataCallback((DataEmitter emitter, ByteBufferList bb) -> {
                        Log.i("TAG", "File: " + bb.getAllByteArray().clone().length);
                        // 这里做对接受的文件进行文件存储
                        bb.recycle();
                    });
                } else {
                    // 非文件
                    if (body.getDataCallback() == null) {
                        body.setDataCallback((DataEmitter emitter, ByteBufferList bb) -> {
                            bb.recycle();
                        });
                    }
                }
            });
            request.setEndCallback(ex -> {
            // 接口请求结束回调
                response.code(666);
                response.send("收到");
                response.end();
            });
        });
		
		// 端口
        mServer.listen(5000);

....
// 关闭服务器
 mServer.stop();

三、用androidasync库做客户端网络请求至服务端

public void asyncHttpPost() {
		// localhost为服务端IP地址
        AsyncHttpPost post = new AsyncHttpPost("http://localhost:5000/files");
        MultipartFormDataBody body = new MultipartFormDataBody();
    	// 加入2个文件Part ,批量或单个文件, 我这边测试用多个
        body.addFilePart("my-file", new File("/storage/emulated/0/xinxin/logininfo/logininfo.ini"));
        body.addFilePart("my-file2", new File("/storage/emulated/0/xinxin/logininfo/logininfo.ini"));
        post.setBody(body);
        AsyncHttpClient.getDefaultInstance().executeString(post, new AsyncHttpClient.StringCallback() {
            @Override
            public void onCompleted(Exception ex, AsyncHttpResponse source, String result) {
                if (ex != null) {
                    ex.printStackTrace();
                    return;
                }
                Log.i("TAG", "onCompleted: " + result);
            }
        });
    }

四、用okhttp库做客户端网络请求至服务端

 public void okhttpHttpPost() {
        OkHttpClient okHttpClient = new OkHttpClient.Builder()
                .connectTimeout(10, TimeUnit.SECONDS)       //设置连接超时
                .readTimeout(10, TimeUnit.SECONDS)          //设置读超时
                .writeTimeout(10, TimeUnit.SECONDS)          //设置写超时
                .retryOnConnectionFailure(true)
                .build();
		// 批量或单个文件, 我这边测试用多个
        File file1 = new File("/storage/emulated/0/xinxin/logininfo/logininfo.ini");
        File file2 = new File("/storage/emulated/0/xinxin/logininfo/logininfo.ini");

        //使用MultipartBody上传多个文件
        MultipartBody multipartBody = new MultipartBody.Builder()
                .addFormDataPart("file1", file1.getName(), RequestBody.create(MediaType.parse("multipart/form-data"), file1))
                .addFormDataPart("file2", file1.getName(), RequestBody.create(MediaType.parse("multipart/form-data"), file2))
                .build();
                // IP是你的服务端IP
        Request request = new Request.Builder().url("http://"+IP+":5000/files")
                .post(multipartBody)
                .addHeader("Connection", "close")
                .build();

        Call call = okHttpClient.newCall(request);
        call.enqueue(new Callback() {
            @Override
            public void onFailure(Call call, IOException e) {
                e.printStackTrace();
                Log.i("TAG", "onFailure: ");
            }

            @Override
            public void onResponse(Call call, Response response) throws IOException {
                Log.i("TAG", "onResponse: ");
                if (response.isSuccessful()) {//判断是否返回成功
                    Log.i("TAG", "Get异步请求" + response.body().string());
                }
            }
        });
    }

五、获取Ip地址-服务端IP地址

try {
            for (Enumeration<NetworkInterface> mEnumeration = NetworkInterface
                    .getNetworkInterfaces(); mEnumeration.hasMoreElements(); ) {
                NetworkInterface mInf = mEnumeration.nextElement();
                for (Enumeration<InetAddress> IpAddress = mInf
                        .getInetAddresses(); IpAddress
                             .hasMoreElements(); ) {
                    InetAddress inetAddress = IpAddress.nextElement();
                    if (!inetAddress.isLoopbackAddress()
                            && inetAddress instanceof Inet4Address
                    ) {
                        if (!inetAddress.getHostAddress().equals("null")
                                && inetAddress.getHostAddress() != null) {
                            //  displayName的类型有:eth0是有线网络地址,wlan0是无线网络,ap0是热点
                              if (mInf.getDisplayName().equals("eth0")) {
                                System.out.println("这是本机有线网络:" + inetAddress
                                        .getHostAddress());
                            } else if (mInf.getDisplayName().equals("ap0")) {
                                System.out.println("这是本机热点:" + inetAddress
                                        .getHostAddress());
                            } else if (mInf.getDisplayName().equals("wlan0")) {
                                System.out.println("这是本机wifi:" + inetAddress
                                        .getHostAddress());
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

六、题外

正常来说运用场景很局限。留笔自记。有空记录蓝牙Socket传输。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值