使用android studio写一个Android的远程通信软件(APP),有通讯的发送和接收消息界面

news2024/12/30 2:30:11

以下是使用 Android Studio 基于 Java 语言编写一个简单的 Android APP 实现远程通信(这里以 TCP 通信为例)的代码示例,包含基本的通信界面以及发送和接收消息功能。

1. 创建项目

打开 Android Studio,新建一个 Empty Activity 的 Android 项目,填写好项目相关信息后等待项目构建完成。

2. 设计界面布局(activity_main.xml)

res/layout目录下的activity_main.xml文件中,设计如下简单布局,包含一个用于输入消息的编辑文本框、发送按钮以及一个用于显示接收消息的文本视图:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="16dp">

    <EditText
        android:id="@+id/editTextMessage"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:padding="16dp"
        android:layout_marginTop="16dp"
        android:layout_marginLeft="0dp"
        android:hint="输入要发送的消息" />

    <TextView
        android:id="@+id/textViewReceivedMessages"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="64dp"
        android:layout_marginLeft="0dp"
        android:text="接收的消息:" />

    <Button
        android:id="@+id/buttonSend"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginTop="100dp"
        android:layout_marginLeft="128dp"
        android:text="发送" />

</LinearLayout>

3. 编写远程通信及逻辑代码(MainActivity.java)

MainActivity.java文件中,添加以下代码来实现 TCP 通信以及相关的界面交互逻辑:

java

package com.example.myapplication;

import android.os.Bundle;

import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.graphics.Insets;
import androidx.core.view.ViewCompat;
import androidx.core.view.WindowInsetsCompat;

import androidx.appcompat.app.AppCompatActivity;
import java.io.FileOutputStream;
import java.io.OutputStream;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;

public class MainActivity extends AppCompatActivity {

    private EditText editTextMessage;
    private TextView textViewReceivedMessages;
    private Socket socket;
    private BufferedReader reader;
    private BufferedWriter writer;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        EdgeToEdge.enable(this);

        setContentView(R.layout.activity_main);

        editTextMessage = findViewById(R.id.editTextMessage);
        Button buttonSend = findViewById(R.id.buttonSend);
        textViewReceivedMessages = findViewById(R.id.textViewReceivedMessages);

        // 尝试连接服务器,这里假设服务器IP是192.168.0.100,端口是8888,根据实际情况修改
        new Thread(() -> {
            try {
                socket = new Socket("192.168.1.6", 8888);
                reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                writer = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
                // 开启线程接收服务器消息
                receiveMessages();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }).start();

        buttonSend.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String message = editTextMessage.getText().toString().trim();
                if (!message.isEmpty()) {
                    new Thread(() -> {
                        try {
                            writer.write(message + "\n");
                            writer.flush();
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }).start();
                }
            }
        });
    }

    private void receiveMessages() {
        try {
            while (true) {
                String receivedMessage = reader.readLine();
                if (receivedMessage!= null) {
                    runOnUiThread(() -> {
                        textViewReceivedMessages.append("\n" + receivedMessage);
                    });
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        try {
            if (socket!= null) {
                socket.close();
            }
            if (reader!= null) {
                reader.close();
            }
            if (writer!= null) {
                writer.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

代码解释如下:

  • onCreate方法中:
    • 首先通过findViewById方法找到界面布局中的各个控件。
    • 然后开启一个新线程去尝试连接远程服务器(IP 和端口按需修改),成功连接后获取输入输出流,并开启receiveMessages方法所在的线程用于接收服务器发来的消息。
    • 给发送按钮设置点击监听器,当点击按钮时,获取编辑文本框中的消息内容,若不为空则开启新线程将消息发送给服务器(注意要按协议添加换行符等规范格式,这里简单用\n分隔消息)。
  • receiveMessages方法:在一个循环中不断读取服务器发送过来的消息,每读取到一条消息,通过runOnUiThread方法将消息更新显示到界面的文本视图上(因为 Android 中涉及 UI 更新操作要在主线程执行)。
  • onDestroy方法:在 Activity 销毁时,关闭相关的套接字、输入输出流等资源,防止资源泄漏。

4. 添加网络权限

AndroidManifest.xml文件中,添加网络访问权限,确保 APP 可以进行网络通信:

xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.remotecommunicationapp">

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

    <application
       ...
    </application>

</manifest>

请注意:

  1. 上述代码中服务器的 IP 地址和端口号(示例中为192.168.0.1008888)要根据实际部署运行的服务器情况进行修改。
  2. 这只是一个简单的示例实现,实际应用中可以根据需求扩展功能,比如添加更多的界面交互、错误处理机制、加密通信等。还可以考虑使用更高级的网络通信框架来简化开发流程以及增强稳定性等。

运行这个 Android APP 后,在界面输入消息点击发送,就能将消息发送给对应的服务器,同时可以接收服务器返回的消息并显示在界面上。

界面

这里还需要要一个电脑做服务器,接受和发送消息

python

import socket

# 创建套接字对象
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 绑定IP地址和端口
server_address = ('192.168.1.6', 8888)
server_socket.bind(server_address)

# 监听连接
server_socket.listen(5)

print('Server is listening on {}:{}'.format(*server_address))

while True:
    # 接受客户端连接
    client_socket, client_address = server_socket.accept()
    print('Connected by', client_address)

    try:
        while True:
            # 接收客户端发送的数据
            data = client_socket.recv(1024)
            if data:
                print('Received data:', data.decode('utf-8'))
                # 发送响应数据给客户端,这里简单回复一个确认消息
                #client_socket.sendall('Message received successfully!'.encode('utf-8'))
                server_socket.sendall('Message received successfully!'.encode('utf-8'))
            else:
                break
    finally:
        # 关闭客户端连接套接字
        client_socket.close()

最终结果,我现在只能单向发送,一旦回复消息,就必然抛出异常。如有方法改正,还请指出!谢谢!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2255297.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

记录下nginx接口代理配置问题

其中api和api1是前面定义的upstream&#xff0c;ip相同只是端口不同。 一开始/api1/直接 像api一样 proxy_pass http://api1这样是不行的&#xff0c;因为会代理到 后端的 /api1/...接口&#xff0c;而后端实际接口地址是 /api/..... 所以必须像上面写法才能将外网的 /api…

【项目】基于PaddleOCR的文字检测识别项目

【项目】基于PaddleOCR的文字检测识别项目 简介安装与使用&#xff08;1&#xff09;Paddle环境安装&#xff08;2&#xff09;模型预测&#xff08;文本检测文本识别&#xff09;&#xff08;3&#xff09;文本检测识别模型训练&#xff08;4&#xff09;本地模型训练与预测&a…

mock.js介绍

mock.js http://mockjs.com/ 1、mock的介绍 *** 生成随机数据&#xff0c;拦截 Ajax 请求。** 通过随机数据&#xff0c;模拟各种场景&#xff1b;不需要修改既有代码&#xff0c;就可以拦截 Ajax 请求&#xff0c;返回模拟的响应数据&#xff1b;支持生成随机的文本、数字…

重磅升级:OpenAI o1模型上手实测,从芯片架构分析到象棋残局判断的全能表现

引言 昨日&#xff0c;在圣诞节系列发布会的第一天&#xff0c;OpenAI终于给我们带来了令人振奋的更新&#xff0c;这些更新有望塑造AI互动的未来。备受期待的OpenAI o1正式版的推出&#xff0c;标志着ChatGPT体验的重大进化&#xff0c;宣告了AI驱动应用新时代的开始。o1现已可…

DataSophon集成CMAK KafkaManager

本次集成基于DDP1.2.1 集成CMAK-3.0.0.6 设计的json和tar包我放网盘了. 通过网盘分享的文件&#xff1a;DDP集成CMAK 链接: https://pan.baidu.com/s/1BR70Ajj9FxvjBlsOX4Ivhw?pwdcpmc 提取码: cpmc CMAK github上提供了zip压缩包.将压缩包解压之后 在根目录下加入启动脚本…

【vivado】时序报告--best时序和worst时序

利用vivado进行开发时&#xff0c;生成best时序报告和worst时序报告。 best时序报告 slow选择min_max&#xff0c;fast选择none。 worst时序报告 fast选择min_max&#xff0c;slow选择none。

EasyMedia播放rtsprtmp视频流(flvhls)

学习链接 MisterZhang/EasyMedia - gitee地址 EasyMedia转码rtsp视频流flv格式&#xff0c;hls格式&#xff0c;H5页面播放flv流视频 EasyMedia播放rtsp视频流&#xff08;vue2、vue3皆可用&#xff09; EasyMedia转码rtsp视频流flv格式&#xff0c;hls格式&#xff0c;H5页…

Linux C/C++编程中的多线程编程基本概念

【图书推荐】《Linux C与C一线开发实践&#xff08;第2版&#xff09;》_linux c与c一线开发实践pdf-CSDN博客《Linux C与C一线开发实践&#xff08;第2版&#xff09;&#xff08;Linux技术丛书&#xff09;》(朱文伟&#xff0c;李建英)【摘要 书评 试读】- 京东图书 (jd.com…

FPGA工作原理、架构及底层资源

FPGA工作原理、架构及底层资源 文章目录 FPGA工作原理、架构及底层资源前言一、FPGA工作原理二、FPGA架构及底层资源 1.FPGA架构2.FPGA底层资源 2.1可编程输入/输出单元简称&#xff08;IOB&#xff09;2.2可配置逻辑块2.3丰富的布线资源2.4数字时钟管理模块(DCM)2.5嵌入式块 …

C语言程序设计P5-3【应用函数进行程序设计 | 第三节】——知识要点:函数的嵌套调用和递归调用

知识要点&#xff1a;函数的嵌套调用和递归调用 视频 目录 一、任务分析 二、必备知识与理论 三、任务实施 一、任务分析 本任务要求用递归法求 n!。 我们知道n!n(n-1)(n-2)……1n(n-1)!递归公式为&#xff1a; 1.上面公式分解为n!n(n-1)!&#xff0c;即将求n!的问题变为…

word实践:正文/标题/表图等的共用模板样式设置

说在前面 最近使用word新建文件很多&#xff0c;发现要给大毛病&#xff0c;每次新建一个word文件&#xff0c;标题/正文的字体、大小和间距都要重新设置一遍&#xff0c;而且每次设置这些样式都忘记了参数&#xff0c;今天记录一下&#xff0c;以便后续方便查看使用。现在就以…

【工具变量】上市公司企业劳动密集度数据(2008-2023年)

一、测算方式&#xff1a; 参考《数量经济技术经济研究》陈勇兵&#xff08;2023&#xff09;老师的做法&#xff0c;使用员工数量与销售收入的比值作为劳动密集度的度量标准* o/ b% C( e* U我们做的比他完善&#xff0c;分为四类大家可以做核心变量或者稳健性检验Labor1&…

YOLOv11修改推理图片的标签字体大小

先打开ultralytics/utils/plotting.py&#xff0c;并搜索font scale(vscode快捷键ctrlF): 在这行代码动手脚&#xff0c;例如调小分母就是把字改大&#xff1a; self.sf self.lw 完成&#xff0c;可以正常运行&#xff1a;

TCP Analysis Flags 之 TCP Spurious Retransmission

前言 默认情况下&#xff0c;Wireshark 的 TCP 解析器会跟踪每个 TCP 会话的状态&#xff0c;并在检测到问题或潜在问题时提供额外的信息。在第一次打开捕获文件时&#xff0c;会对每个 TCP 数据包进行一次分析&#xff0c;数据包按照它们在数据包列表中出现的顺序进行处理。可…

在paddle中安装python-bidi出错

翻看网上解决方式&#xff0c;是由于系统中缺少 Rust 及其包管理器 Cargo。python-bidi 依赖 Rust 来编译其扩展&#xff0c;如果没有安装 Rust 和 Cargo&#xff0c;安装过程将无法继续。 解决方式 curl --proto https --tlsv1.2 -sSf https://sh.rustup.rs | sh但是我的终端…

自动化测试工具Ranorex Studio(五十四)-CSV文件

CSV文件 你也可以通过选择CSV文件数据连接器来使用CSV文件为你的测试套件提供数据。在添加了CSV数据连接器后&#xff0c;管理数据源的对话框将被打开。 你可以在表色标示部分编辑数据连接器的名字&#xff0c;也可以在绿色标示的部分选择你要用的CSV文件。选择或者取消蓝色标示…

Flume基础概念

目录 作用组件构成ClientFlowAgentSourceSinkEvent 和Log4j的区别与定位事务传出流程输入到sourcesource端输入Channel 接收输入到SinkSink输出 作用 Flume可以从各种来源&#xff08;如日志文件、消息队列、网络数据、文件系统、数据库等&#xff09;收集数据&#xff0c;并将…

FPGA实战篇(IP核之MMCM/PLL实验)

1.MMCM/PLL IP 核简介 锁相环作为一种反馈控制电路&#xff0c;其特点是利用外部输入的参考信号控制环路内部震荡信号的频率和相位。因为锁相环可以实现输出信号频率对输入信号频率的自动跟踪&#xff0c;所以锁相环通常用于闭环跟踪电路。 锁相环在工作的过程中&#xff0c;当…

Numpy基础练习

import numpy as np 1.创建一个长度为10的一维全为0的ndarray对象,然后让第5个元素等于1 n np.zeros(10,dtypenp.int32) n[4] 12.创建一个元素从10到49的ndarray对象 n np.arrange(10,50)3.将第2题的所有元素位置反转 n[::-1]使用np.random.random创建一个10*10的ndarray对象…

Probabilistic Face Embeddings 论文阅读

Probabilistic Face Embeddings 论文阅读 Abstract1. Introduction2. Related Work3. Limitations of Deterministic Embeddings4. Probabilistic Face Embeddings4.1. Matching with PFEs4.2. Fusion with PFEs4.3. Learning 5. Experiments5.1. Experiments on Different Bas…