Android studio 呼叫盒app

一、权限文件

0.gradle切换国内源

#Fri Nov 08 15:46:05 CST 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https://mirrors.cloud.tencent.com/gradle/gradle-8.4-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

1.添加仅测试声明,针对vivo手机安装不上app

android.injected.testOnly=false

 2.添加弹窗块的代码

    implementation("androidx.appcompat:appcompat:1.6.1")

3.申请使用网络权限

    <!-- 申请网络权限 --><uses-permission android:name="android.permission.INTERNET"/>

 

 二、前端UI布局

1.activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"android:layout_width="match_parent"android:layout_height="match_parent"><!-- 按钮和灯的布局 --><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="vertical"android:layout_centerInParent="true"><!-- 按钮1 --><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="horizontal"android:gravity="center_vertical"android:layout_marginBottom="16dp"><Viewandroid:id="@+id/light1"android:layout_width="30dp"android:layout_height="30dp"android:layout_marginEnd="10dp"android:background="@android:color/darker_gray" /><Buttonandroid:id="@+id/button1"android:layout_width="150dp"android:layout_height="50dp"android:text="1"android:backgroundTint="@android:color/darker_gray"android:textColor="@android:color/white" /></LinearLayout><!-- 按钮2 --><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="horizontal"android:gravity="center_vertical"android:layout_marginBottom="16dp"><Viewandroid:id="@+id/light2"android:layout_width="30dp"android:layout_height="30dp"android:layout_marginEnd="10dp"android:background="@android:color/darker_gray" /><Buttonandroid:id="@+id/button2"android:layout_width="150dp"android:layout_height="50dp"android:text="2"android:backgroundTint="@android:color/darker_gray"android:textColor="@android:color/white" /></LinearLayout><!-- 按钮3 --><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="horizontal"android:gravity="center_vertical"android:layout_marginBottom="16dp"><Viewandroid:id="@+id/light3"android:layout_width="30dp"android:layout_height="30dp"android:layout_marginEnd="10dp"android:background="@android:color/darker_gray" /><Buttonandroid:id="@+id/button3"android:layout_width="150dp"android:layout_height="50dp"android:text="3"android:backgroundTint="@android:color/darker_gray"android:textColor="@android:color/white" /></LinearLayout><!-- 按钮4 --><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="horizontal"android:gravity="center_vertical"><Viewandroid:id="@+id/light4"android:layout_width="30dp"android:layout_height="30dp"android:layout_marginEnd="10dp"android:background="@android:color/darker_gray" /><Buttonandroid:id="@+id/button4"android:layout_width="150dp"android:layout_height="50dp"android:text="4"android:backgroundTint="@android:color/darker_gray"android:textColor="@android:color/white" /></LinearLayout></LinearLayout><!-- 设置按钮 --><Buttonandroid:id="@+id/settingsButton"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="设置"android:backgroundTint="@android:color/darker_gray"android:textColor="@android:color/white"android:layout_alignParentBottom="true"android:layout_centerHorizontal="true"android:layout_marginBottom="16dp" />
</RelativeLayout>

2.dialog_settings.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="wrap_content"android:orientation="vertical"android:padding="16dp"><!-- 目标 IP --><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="目标 IP:" /><EditTextandroid:id="@+id/targetIp"android:layout_width="match_parent"android:layout_height="wrap_content"android:hint="请输入目标 IP"android:inputType="text" /><!-- 目标端口 --><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="目标端口:"android:layout_marginTop="8dp" /><EditTextandroid:id="@+id/targetPort"android:layout_width="match_parent"android:layout_height="wrap_content"android:hint="请输入目标端口"android:inputType="number" /><!-- 本地端口 --><TextViewandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:text="本地端口:"android:layout_marginTop="8dp" /><EditTextandroid:id="@+id/localPort"android:layout_width="match_parent"android:layout_height="wrap_content"android:hint="请输入本地端口"android:inputType="number" />
</LinearLayout>

三、后端文件

MainActivity.java

package com.example.fl;import android.app.AlertDialog;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;import androidx.appcompat.app.AppCompatActivity;import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;public class MainActivity extends AppCompatActivity {private String targetIp = "192.168.0.229"; // 默认目标 IPprivate int targetPort = 10000; // 默认目标端口private int localPort = 55555; // 默认本地端口49200-65535private DatagramSocket socket;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);// 从 SharedPreferences 中读取保存的设置SharedPreferences preferences = getSharedPreferences("UDPSettings", MODE_PRIVATE);targetIp = preferences.getString("targetIp", "192.168.0.229"); // 默认值targetPort = preferences.getInt("targetPort", 10000); // 默认值localPort = preferences.getInt("localPort", 55555); // 默认值initializeSocket();setupButtonAndLight(R.id.button1, R.id.light1, "1");setupButtonAndLight(R.id.button2, R.id.light2, "2");setupButtonAndLight(R.id.button3, R.id.light3, "3");setupButtonAndLight(R.id.button4, R.id.light4, "4");Button settingsButton = findViewById(R.id.settingsButton);settingsButton.setOnClickListener(v -> openSettingsDialog());}private void initializeSocket() {try {if (socket != null && !socket.isClosed()) {socket.close();}socket = new DatagramSocket(localPort);new Thread(this::receiveUDPMessage).start();} catch (Exception e) {e.printStackTrace();Toast.makeText(this, "Socket 初始化失败,请检查本地端口设置", Toast.LENGTH_SHORT).show();}}private void setupButtonAndLight(int buttonId, int lightId, String message) {Button button = findViewById(buttonId);View light = findViewById(lightId);button.setOnClickListener(v -> {sendUDPMessage(message, success -> {if (success) {runOnUiThread(() -> light.setBackgroundColor(getResources().getColor(android.R.color.holo_green_light)));} else {runOnUiThread(() -> Toast.makeText(this, "发送失败", Toast.LENGTH_SHORT).show());}});});}private void sendUDPMessage(String message, UDPResponseCallback callback) {new Thread(() -> {boolean success = false;try {InetAddress address = InetAddress.getByName(targetIp);DatagramPacket packet = new DatagramPacket(message.getBytes(), message.length(), address, targetPort);socket.send(packet);success = true;} catch (Exception e) {e.printStackTrace();}callback.onResponse(success);}).start();}private void receiveUDPMessage() {byte[] buffer = new byte[1024];while (true) {try {DatagramPacket packet = new DatagramPacket(buffer, buffer.length);socket.receive(packet);String received = new String(packet.getData(), 0, packet.getLength());runOnUiThread(() -> handleReceivedMessage(received));} catch (Exception e) {e.printStackTrace();}}}private void handleReceivedMessage(String message) {int lightId;switch (message) {case "1":lightId = R.id.light1;break;case "2":lightId = R.id.light2;break;case "3":lightId = R.id.light3;break;case "4":lightId = R.id.light4;break;default:return;}View light = findViewById(lightId);light.setBackgroundColor(getResources().getColor(android.R.color.darker_gray));}private void openSettingsDialog() {View dialogView = LayoutInflater.from(this).inflate(R.layout.dialog_settings, null);EditText ipInput = dialogView.findViewById(R.id.targetIp);EditText portInput = dialogView.findViewById(R.id.targetPort);EditText localPortInput = dialogView.findViewById(R.id.localPort);// 获取 SharedPreferences 保存的数据SharedPreferences preferences = getSharedPreferences("UDPSettings", MODE_PRIVATE);ipInput.setText(preferences.getString("targetIp", targetIp));portInput.setText(String.valueOf(preferences.getInt("targetPort", targetPort)));localPortInput.setText(String.valueOf(preferences.getInt("localPort", localPort)));new AlertDialog.Builder(this).setTitle("设置目标和本地端口").setView(dialogView).setPositiveButton("保存", (dialog, which) -> {targetIp = ipInput.getText().toString();targetPort = Integer.parseInt(portInput.getText().toString());localPort = Integer.parseInt(localPortInput.getText().toString());// 保存设置到 SharedPreferencesSharedPreferences.Editor editor = preferences.edit();editor.putString("targetIp", targetIp);editor.putInt("targetPort", targetPort);editor.putInt("localPort", localPort);editor.apply();initializeSocket(); // 更新本地端口后重新初始化 SocketToast.makeText(this, "设置已保存", Toast.LENGTH_SHORT).show();}).setNegativeButton("取消", null).show();}// 定义回调接口private interface UDPResponseCallback {void onResponse(boolean success);}
}

四、实现效果

app按下1234 绿色led亮  目标设备收到数据

回传本地IP和端口 1

led1 灯灭

链接: https://pan.baidu.com/s/1x46I-dhMG_2mRchokZ0xiA?pwd=ktam 提取码: ktam 

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

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

相关文章

[Admin] Dashboard Filter for Mix Report Types

Background RevOps team has built a dashboard for sales team to track team members’ performance, but they’re blocked by how to provide a manager view based on sales’ hierarchy. Therefore, they seek for dev team’s help to clear their blocker. From foll…

2024年人工智能技术赋能网络安全应用测试:广东盈世在钓鱼邮件识别场景荣获第三名!

近期&#xff0c;2024年国家网络安全宣传周“网络安全技术高峰论坛主论坛暨粤港澳大湾区网络安全大会”在广州成功举办。会上&#xff0c;国家计算机网络应急技术处理协调中心公布了“2024年人工智能技术赋能网络安全应用测试结果”。结果显示&#xff0c;广东盈世计算机科技有…

Java进阶四-异常,File

异常 概念&#xff1a;代表程序出现的问题。 目的&#xff1a;程序出现了异常我们应该如何处理。 最高父类&#xff1a;Exception 异常分为两类 编译时异常&#xff1a;没有继承RuntimeException的异常,直接继承与Exception,编译阶段就会错误提示。运行时异常:RuntimeExc…

ERROR TypeError: AutoImport is not a function

TypeError: AutoImport is not a function 原因&#xff1a;unplugin-auto-import 插件版本问题 Vue3基于Webpack&#xff0c;在vue.config.js中配置 当unplugin-vue-components版本小于0.26.0时&#xff0c;使用以下写法 const { defineConfig } require("vue/cli-se…

Elasticsearch:更好的二进制量化(BBQ)对比乘积量化(PQ)

作者&#xff1a;来自 Elastic Benjamin Trent 为什么我们选择花时间研究更好的二进制量化而不是在 Lucene 和 Elasticsearch 中进行生产量化。 我们一直在逐步使 Elasticsearch 和 Lucene 的向量搜索变得更快、更实惠。我们的主要重点不仅是通过 SIMD 提高搜索速度&#xff0…

检查课程是否有效

文章目录 概要整体架构流程技术细节小结 概要 这是一个微服务内部接口&#xff0c;当用户学习课程时&#xff0c;可能需要播放课程视频。此时提供视频播放功能的媒资系统就需要校验用户是否有播放视频的资格。所以&#xff0c;开发媒资服务&#xff08;tj-media&#xff09;的…

红外遥控报警器设计(模电课设)

一、设计要求 利用NE555p芯片设计制作报警器。要求当有人遮挡红外光时发出报警信号&#xff0c;无人遮挡红外光时报警器不工作&#xff0c;即不发声。 二、元器件 555芯片&#xff1a;NE555P 集成运放&#xff1a;LM358 三级管&#xff1a;2N1711 蜂鸣器&#xff1a;HY-30…

Spring MVC——针对实习面试

目录 Spring MVC什么是Spring MVC&#xff1f;简单介绍下你对Spring MVC的理解&#xff1f;Spring MVC的优点有哪些&#xff1f;Spring MVC的主要组件有哪些&#xff1f;Spring MVC的工作原理或流程是怎样的&#xff1f;Spring MVC常用注解有哪些&#xff1f; Spring MVC 什么是…

机器学习(贝叶斯算法,决策树)

朴素贝叶斯分类 贝叶斯分类理论 假设现有两个数据集&#xff0c;分为两类 我们现在用p1(x,y)表示数据点(x,y)属于类别1(图中红色圆点表示的类别)的概率&#xff0c;用p2(x,y)表示数据点(x,y)属于类别2(图中蓝色三角形表示的类别)的概率&#xff0c;那么对于一个新数据点(x,y)…

题目讲解18 有效的括号

原题链接&#xff1a; 20. 有效的括号 - 力扣&#xff08;LeetCode&#xff09; 思路分析&#xff1a; 第一步&#xff1a;先搭建一个数据结构——栈。 typedef char STDataType; typedef struct Stack {STDataType* arr;int top, capacity; } Stack;//初始化 void StackIn…

HarmonyOS笔记5:ArkUI框架的Navigation导航组件

ArkUI框架的Navigation导航组件 在移动应用中需要在不同的页面进行切换跳转。这种切换和跳转有两种方式&#xff1a;页面路由和Navigation组件实现导航。HarmonyOS推荐使用Navigation实现页面跳转。在本文中在HarmonyOS 5.0.0 Release SDK (API Version 12 Release)版本下&…

【C++】第九节:list

1、list的介绍及使用 1.1 list的介绍 list - C 参考 1.2 list的使用 1.2.1 list的构造 void TestList1() {list<int> l1; // 构造空的l1list<int> l2(4, 100); // l2中包含4个值为100的元素list<int> l3(l2.begin(), l2.end()); // 用l2的[begin(),end())…

Idea中创建和联系MySQL等数据库

备注&#xff1a;电脑中要已下好自己需要的MySQL数据库软件 MySQL社区版下载链接&#xff1a; https://dev.mysql.com/downloads/installer/ 优点&#xff1a; 1.相比与在命令行中管理数据库&#xff0c;idea提供了图形化管理&#xff0c;简单明了&#xff1b; 2.便于与后端…

Linux_shell脚本if语句详细教程

前言 在 Linux Shell 脚本中&#xff0c;if 语句用于基于条件执行命令或代码块。它的基本语法结构如下&#xff1a; if 条件; then# 如果条件为真时执行的代码 elif 另一个条件; then# 如果另一个条件为真时执行的代码 else# 如果所有条件都不成立时执行的代码 fi一、if 语句…

Python自学之Colormaps指南

目录 1.色彩映射表&#xff08;Colormaps&#xff09;是什么&#xff1f; 2.Matplotlib中的色彩映射表类型 2.1同色渐变&#xff08;Sequential Colormaps&#xff09; 2.2双色渐变&#xff08;Divergence Colormaps&#xff09; 2.3定性色彩&#xff08;Qualitative Col…

利用redis的key失效监听器KeyExpirationEventMessageListener作任务定时提醒功能

某需求&#xff1a; 要求在任务截止日期的前3天时&#xff0c;系统自动给用户发一条消息提醒。 用定时任务的话感觉很不舒服。间隔时间不好弄。不能精准卡到那个点。 由于系统简单&#xff0c;没有使用消息列队&#xff0c;也不能使用延时队列来做。 用Timer的话开销还挺大的&a…

从视频帧生成点云数据、使用PointNet++模型提取特征,并将特征保存下来的完整实现。

文件地址 https://github.com/yanx27/Pointnet_Pointnet2_pytorch?spm5176.28103460.0.0.21a95d27ollfze Pointnet_Pointnet2_pytorch\log\classification\pointnet2_ssg_wo_normals文件夹改名为Pointnet_Pointnet2_pytorch\log\classification\pointnet2_cls_ssg "E:…

高效工具推荐:基于WebGPU的Whisper Web结合内网穿透远程使用指南

文章目录 前言1.本地部署Whisper Web1.1 安装git1.2 安装Node.js1.3 运行项目 2. Whisper Web使用介绍3. 安装Cpolar内网穿透4. 配置公网地址5. 公网访问测试6. 配置固定公网地址 前言 OpenAI开源的 Whisper 语音转文本模型效果都说还不错&#xff0c;今天就给大家推荐 GitHub…

大数据学习16之Spark-Core

1. 概述 1.1.简介 Apache Spark 是专门为大规模数据处理而设计的快速通用的计算引擎。 一种类似 Hadoop MapReduce 的通用并行计算框架&#xff0c;它拥有MapReduce的优点&#xff0c;不同于MR的是Job中间结果可以缓存在内存中&#xff0c;从而不需要读取HDFS&#xff0c;减少…

Go语言跨平台桌面应用开发新纪元:LCL、CEF与Webview全解析

开篇寄语 在Go语言的广阔生态中&#xff0c;桌面应用开发一直是一个备受关注的领域。今天&#xff0c;我将为大家介绍三款基于Go语言的跨平台桌面应用开发框架——LCL、CEF与Webview&#xff0c;它们分别拥有独特的魅力和广泛的应用场景。通过这三款框架&#xff0c;你将能够轻…