news 2026/4/29 16:34:42

Android手把手编写儿童手机远程监控App之UUID

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Android手把手编写儿童手机远程监控App之UUID

概述

上节完成嘟宝MQTT消息的推送、订阅,以及医嘱消息的实现。至此嘟宝完成基本功能,包括:

  • 响应Andorid开机消息,实现自启动
  • 启动前台服务。在前台服务启动MQTT连接
  • MQTT实现医嘱消息、订阅消息、推送消息功能。
    嘟宝作为后台程序,没有登录、注册功能。后台服务器仅有EMQX、Coturn服务程序,无任何后台开发。如何在众多嘟宝中区别是每一个。
    UUID,个人识别码。通用唯一标识符,Universally Unique Identifier。唯一标识信息由128位数字组成,32个十六进制字符组成的字符串(带连字符分隔)。它的设计目标是在无需集中管理的情况下,生成在全球范围内几乎不会重复的ID,如:3f29c9b2-9c2a-4c1f-8c7d-6e2b7a1f9a0d

嘟宝在建立MQTT连接之前,需要指明clientID。将clientID用uuid作为嘟宝id,就不会出现重复的嘟宝连接。如下之前用0001做测试

String url="tcp://192.168.1.20:1883";String dubaoID="0001";client=newMqttClient(url,"dubao_server"+dubaoID,newMemoryPersistence());

andorid 生成uuid

  • 新建一个uuid类
  • uuid类中添加createUUID创建一个uuid
  • 在MainActivity创建一个按钮生成uuid
    类uuid源码
package com.zilong.dubao;import java.util.UUID;public classuuid{public StringcreateUUID(){String s="";s=UUID.randomUUID().toString();returns;}}

MainActivity源码

package com.zilong.dubao;import androidx.appcompat.app.AppCompatActivity;import android.os.Bundle;import android.widget.Button;import android.widget.Toast;public classMainActivityextendsAppCompatActivity{@Override protected voidonCreate(Bundle savedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Button startbtn=findViewById(R.id.sendbtn);startbtn.setOnClickListener(v->{uuid u=newuuid();String s=u.createUUID();Toast.makeText(this,s,Toast.LENGTH_SHORT).show();});}}

运行查看效果

每次生成的uuid,都是唯一值

uuid存储

uuid在嘟宝app首次启动后生成,先于MQTT连接之前。启动后检查嘟宝有没有被存储在本地。

  • 若有从本地读取,返回本地uuid
  • 若没有创建新uuid,存储本地
    Andorid数据存储,有很多种方式,轻量级的使用SharedPreferences,对于复杂数据可以使用SQLite 数据库等
  • SharedPreferences:以 键值对 (Key-Value) 形式存储轻量级的简单数据,常用于保存应用设置
  • 文件存储, Android 的 openFileInput() / openFileOutput() 方法,将数据以字节流的形式写入设备的文件系统。
  • SQLite 数据库:Android 内置的轻量级关系型数据库,适合存储结构化、复杂且相互关联的数据
  • Content Provider:虽然常被称为四大组件之一,但它也提供了一种跨应用数据共享的存储接口
    使用SharedPreferences存储uuid。
    uuid类源码
package com.zilong.dubao;import static android.content.Context.MODE_PRIVATE;import android.content.Context;import android.content.SharedPreferences;import java.util.UUID;public classuuid{private StringcreateUUID(){String s="";s=UUID.randomUUID().toString();returns;}public Stringgetuuid(Context context){SharedPreferences preferences=context.getSharedPreferences("uuid",MODE_PRIVATE);String uuid=preferences.getString("id","");if(uuid.equals("")){uuid=createUUID();SharedPreferences.Editor editor=context.getSharedPreferences("uuid",MODE_PRIVATE).edit();editor.putString("id",uuid);editor.apply();returnuuid;}returnuuid;}}

运行效果

生成的uuid实现mqtt连接

uuid用于mqtt连接,完成嘟宝唯一身份标识。

  • 在前台服务中获取uuid
  • 初始化mqtt连接时,修改connect参数,传入uuid值
    前台服务代码
package com.zilong.dubao;import android.app.Notification;import android.app.NotificationChannel;import android.app.NotificationManager;import android.app.PendingIntent;import android.app.Service;import android.content.Intent;import android.os.Build;import android.os.IBinder;import android.widget.Toast;import androidx.core.app.NotificationCompat;public classMyServiceextendsService{MyMqttClient myMqttClient;publicMyService(){}@Override public voidonCreate(){super.onCreate();createNotificationChannel();uuid u=newuuid();String uuid=u.getuuid(this);myMqttClient=newMyMqttClient();myMqttClient.connect(uuid);}@Override public intonStartCommand(Intent intent,int flags,int startId){returnsuper.onStartCommand(intent,flags,startId);}@Override public voidonDestroy(){myMqttClient.colse();super.onDestroy();}@Override public IBinderonBind(Intent intent){// TODO: Return the communication channel to the service.thrownewUnsupportedOperationException("Not yet implemented");}private voidcreateNotificationChannel(){NotificationChannel channel=newNotificationChannel("DUBAO","嘟宝安心守护孩子安全",NotificationManager.IMPORTANCE_LOW);NotificationManager manager=getSystemService(NotificationManager.class);manager.createNotificationChannel(channel);Intent intent=newIntent(this,MainActivity.class);PendingIntent pendingIntent=PendingIntent.getActivity(this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT|PendingIntent.FLAG_IMMUTABLE);Notification notification=newNotificationCompat.Builder(this,"DUBAO").setContentTitle("嘟宝").setContentText("嘟宝安心守护孩子安全...").setSmallIcon(android.R.drawable.ic_menu_info_details).setContentIntent(pendingIntent).setOngoing(true)// 不可滑动删除.build();startForeground(10001,notification);}}

MyMqttClient代码

package com.zilong.dubao;import android.os.Handler;import android.os.HandlerThread;import android.util.Log;import android.widget.Toast;import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;import org.eclipse.paho.client.mqttv3.MqttCallbackExtended;import org.eclipse.paho.client.mqttv3.MqttClient;import org.eclipse.paho.client.mqttv3.MqttConnectOptions;import org.eclipse.paho.client.mqttv3.MqttException;import org.eclipse.paho.client.mqttv3.MqttMessage;import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;import java.nio.charset.StandardCharsets;public classMyMqttClient{private Handler mWorkHandler;private MqttClient client;private MqttConnectOptions connOpts;MyMqttClient(){HandlerThread handlerThread=newHandlerThread("worker");handlerThread.start();mWorkHandler=newHandler(handlerThread.getLooper());}public voidconnect(String uuid){mWorkHandler.post(()->{_connect(uuid);});}private MqttCallbackExtended callbackExtendedallback=newMqttCallbackExtended(){@Override public voidconnectComplete(boolean reconnect,String serverURI){Log.d("mqtt","connectComplete");try{client.subscribe("/duma/#");}catch(MqttException e){e.printStackTrace();}}@Override public voidconnectionLost(Throwable cause){Log.d("mqtt","connectionLost");}@Override public voidmessageArrived(String topic,MqttMessage message)throws Exception{String s=newString(message.getPayload());Log.d("mqtt","主题是:"+topic);Log.d("mqtt","内容是::"+s);}@Override public voiddeliveryComplete(IMqttDeliveryToken token){}};protected void_connect(String uuid){try{String url="tcp://"+MyConfig.mqttip+":"+MyConfig.mqttport;String dubaoID=uuid;client=newMqttClient(url,"dubao_server"+dubaoID,newMemoryPersistence());connOpts=newMqttConnectOptions();connOpts.setCleanSession(true);// 重连接是否清理会话connOpts.setConnectionTimeout(10);connOpts.setKeepAliveInterval(60);//心跳间隔(秒)connOpts.setAutomaticReconnect(true);String s="嘟宝异常掉线了";connOpts.setWill("/dubao/will",s.getBytes(StandardCharsets.UTF_8),0,false);client.setCallback(callbackExtendedallback);_connectionMQTTServer();}catch(MqttException e){e.printStackTrace();}}protected void_connectionMQTTServer(){while(true){try{client.connect(connOpts);break;}catch(MqttException e){Log.d("mqtt","连接失败");e.printStackTrace();}try{Thread.sleep(5*1000);Log.d("mqtt","准备重新连接");}catch(InterruptedException e){e.printStackTrace();}}}public voidpublish(String topic,String msg){publish(topic,msg,0,false);}public voidpublish(String topic,String msg,int qos,boolean retained){mWorkHandler.post(()->{try{MqttMessage message=newMqttMessage(msg.getBytes(StandardCharsets.UTF_8));message.setQos(qos);message.setRetained(retained);client.publish(topic,message);}catch(MqttException e){e.printStackTrace();}});}public voidcolse(){mWorkHandler.post(()->{try{client.disconnect();client.close();}catch(MqttException e){e.printStackTrace();}});}}

至此完成MQTT连接,剩下的发布、订阅消息数据格式定义。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/29 16:28:55

3步快速上手Ryujinx:在PC上完美运行Switch游戏的完整指南

3步快速上手Ryujinx:在PC上完美运行Switch游戏的完整指南 【免费下载链接】Ryujinx 用 C# 编写的实验性 Nintendo Switch 模拟器 项目地址: https://gitcode.com/GitHub_Trending/ry/Ryujinx 想要在电脑上畅玩《塞尔达传说:旷野之息》或《马里奥赛…

作者头像 李华
网站建设 2026/4/29 16:27:23

云代理商:云端部署的Hermes Agent 如何接入钉钉?

在混合云与人工智能原生协同的时代背景下,Hermes Agent 作为一款跨平台的开源 AI 智能体框架,正在成为企业智能化协作的关键枢纽。本文重点探讨其在云环境中的部署实施,详细解析其与钉钉平台对接的完整流程,兼顾安全防护与实用落地…

作者头像 李华
网站建设 2026/4/29 16:19:52

净化富文本:如何去除多余的空格

在编写富文本编辑器或者处理用户输入的文本内容时,我们经常会遇到一些格式化问题。例如,用户可能会不小心输入大量的非断行空格( ),这不仅影响阅读体验,还可能影响页面的布局。今天我们来讨论一下如何使用 DOMPurify 和原生 JavaScript 方法来清理这些多余的空格。 背景…

作者头像 李华