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做测试

clike 复制代码
 String url= "tcp://192.168.1.20:1883";
 String dubaoID="0001";
 client=new MqttClient(url, "dubao_server"+dubaoID, new MemoryPersistence());

andorid 生成uuid

  • 新建一个uuid类
  • uuid类中添加createUUID创建一个uuid
  • 在MainActivity创建一个按钮生成uuid 类uuid源码
clike 复制代码
package com.zilong.dubao;

import java.util.UUID;

public class uuid {
    public String createUUID(){
        String s="";
        s=UUID.randomUUID().toString();
        return s;

    }
}

MainActivity源码

clike 复制代码
package com.zilong.dubao;

import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button startbtn=findViewById(R.id.sendbtn);
        startbtn.setOnClickListener(v->{
           uuid u=new uuid();
           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类源码
clike 复制代码
package com.zilong.dubao;

import static android.content.Context.MODE_PRIVATE;

import android.content.Context;
import android.content.SharedPreferences;

import java.util.UUID;

public class uuid {
    private String createUUID(){
        String s="";
        s=UUID.randomUUID().toString();
        return s;

    }
    public String getuuid(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();
            return uuid;
        }
        return uuid;



    }
}

运行效果

生成的uuid实现mqtt连接

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

  • 在前台服务中获取uuid
  • 初始化mqtt连接时,修改connect参数,传入uuid值 前台服务代码
clike 复制代码
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 class MyService extends Service {
    MyMqttClient myMqttClient;
    public MyService() {
    }


    @Override
    public void onCreate() {
        super.onCreate();
        createNotificationChannel();
        uuid u=new uuid();
        String uuid= u.getuuid(this);
        myMqttClient=new MyMqttClient();
        myMqttClient.connect(uuid);

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);

    }

    @Override
    public void onDestroy() {

        myMqttClient.colse();
        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    }


    private void createNotificationChannel() {
        NotificationChannel channel = new NotificationChannel(
                "DUBAO",
                "嘟宝安心守护孩子安全",
                NotificationManager.IMPORTANCE_LOW
        );
        NotificationManager manager = getSystemService(NotificationManager.class);
        manager.createNotificationChannel(channel);

        Intent intent = new Intent(this, MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(
                this, 0, intent,
                PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE
        );

        Notification notification= new NotificationCompat.Builder(this, "DUBAO")
                .setContentTitle("嘟宝")
                .setContentText("嘟宝安心守护孩子安全...")
                .setSmallIcon(android.R.drawable.ic_menu_info_details)
                .setContentIntent(pendingIntent)
                .setOngoing(true)  // 不可滑动删除
                .build();
        startForeground(10001, notification);
    }
}

MyMqttClient代码

clike 复制代码
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 class MyMqttClient {
    private Handler mWorkHandler;
    private MqttClient client;
    private MqttConnectOptions connOpts;
    MyMqttClient(){
        HandlerThread handlerThread = new HandlerThread("worker");
        handlerThread.start();
        mWorkHandler = new Handler(handlerThread.getLooper());
    }

    public void connect(String uuid) {
        mWorkHandler.post(()->{
            _connect(uuid);

        });

    }
    private MqttCallbackExtended callbackExtendedallback =new MqttCallbackExtended() {
        @Override
        public void connectComplete(boolean reconnect, String serverURI) {
            Log.d("mqtt","connectComplete");
            try {
                client.subscribe("/duma/#");
            } catch (MqttException e) {
                e.printStackTrace();
            }


        }

        @Override
        public void connectionLost(Throwable cause) {
            Log.d("mqtt","connectionLost");

        }

        @Override
        public void messageArrived(String topic, MqttMessage message) throws Exception {
            String s=new String(message.getPayload());
            Log.d("mqtt","主题是:"+topic);
            Log.d("mqtt","内容是::"+s);
        }

        @Override
        public void deliveryComplete(IMqttDeliveryToken token) {

        }
    };

    protected void _connect(String uuid){
        try {
            String url= "tcp://"+MyConfig.mqttip+":"+MyConfig.mqttport;
            String dubaoID=uuid;
            client=new MqttClient(url, "dubao_server"+dubaoID, new MemoryPersistence());
            connOpts=new MqttConnectOptions();
            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 void publish(String topic,String msg){
        publish(topic,msg,0,false);
    }
    public void publish(String topic,String msg,int qos,boolean retained){
        mWorkHandler.post(()->{
            try {
                MqttMessage message=new MqttMessage(msg.getBytes(StandardCharsets.UTF_8));
                message.setQos(qos);
                message.setRetained(retained);
                client.publish(topic,message);
            } catch (MqttException e) {
                e.printStackTrace();
            }

        });
    }
    public void colse(){
        mWorkHandler.post(()->{
            try {
                client.disconnect();
                client.close();
            } catch (MqttException e) {
                e.printStackTrace();
            }

        });

    }

}

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

相关推荐
dalancon1 小时前
Android OomAdjuster流程
android
河婆墟邓紫棋1 小时前
MIUI中的权限
android·github
我命由我123453 小时前
Java 开发 - CountDownLatch 不需要手动关闭
android·java·开发语言·jvm·kotlin·android studio·android-studio
众少成多积小致巨3 小时前
GNU Make 核心指南
android·c++
凛_Lin~~3 小时前
安卓进程保活方案记录(双重fork+文件锁+手搓parcel)
android·安卓
海天鹰3 小时前
安卓相机:获取最近拍摄的照片缩略图做相册按钮图标
android
tongyiixiaohuang3 小时前
技术案例分享:金蝶云星空客户数据同步到MySQL的实现
android·数据库·mysql
小羊子说4 小时前
Android ANR 原理浅析
android·性能优化·车载系统
Be for thing4 小时前
Android Studio 常用快捷键总结
android·学习