开源 java android app 开发(八)通讯之Mqtt和Ble

【信息科学与工程学】【安全领域】第二百零五篇 漏洞治理 01 形式:RabbitMQ管理插件SSRF CVE-2026-57211(CVSSv4 8.3,Windows多插件可诱发SMB NTLM泄露)、管理API资源无限CWE-770 CVSSv4 5.3、管理UI存储XSS CVE-2026-57214/其他;用法:GET /cgi-bin/.%2e/%2e%2e/etc/passwd→读密文/源码→RCE。定量:CVSS 9.0;例:Spectre CVE-2017-5753、Meltdown CVE-2017-5754(CPU越界/未授权内核读); 阅读详情

 文章的目的为了记录使用java 进行android app 开发学习的经历。本职为嵌入式软件开发,公司安排开发app,临时学习,完成app的开发。开发流程和要点有些记忆模糊,赶紧记录,防止忘记。

    相关链接:

开源 java android app 开发(一)开发环境的搭建-优快云博客

开源 java android app 开发(二)工程文件结构-优快云博客

开源 java android app 开发(三)GUI界面布局和常用组件-优快云博客

开源 java android app 开发(四)GUI界面重要组件-优快云博客

开源 java android app 开发(五)文件和数据库存储-优快云博客

开源 java android app 开发(六)多媒体使用-优快云博客

开源 java android app 开发(七)通讯之Tcp和Http-优快云博客

开源 java android app 开发(八)通讯之Mqtt和Ble-优快云博客

开源 java android app 开发(九)后台之线程和服务-优快云博客

开源 java android app 开发(十)广播机制-优快云博客

开源 java android app 开发(十一)调试、发布-优快云博客

开源 java android app 开发(十二)封库.aar-优快云博客

开源 java android app 开发(十三)自定义绘图控件--游戏摇杆

开源 java android app 开发(十四)自定义绘图控件--波形图

开源 java android app 开发(十五)自定义绘图控件--仪表盘

开源 java android app 开发(十六)自定义绘图控件--圆环

推荐链接:

开源C# .net mvc 开发(一)WEB搭建_c#部署web程序-优快云博客

开源 C# .net mvc 开发(二)网站快速搭建_c#网站开发-优快云博客

开源 C# .net mvc 开发(三)WEB内外网访问(VS发布、IIS配置网站、花生壳外网穿刺访问)_c# mvc 域名下不可訪問內網,內網下可以訪問域名-优快云博客

开源 C# .net mvc 开发(四)工程结构、页面提交以及显示_c#工程结构-优快云博客

开源 C# .net mvc 开发(五)常用代码快速开发_c# mvc开发-优快云博客

本章节主要内容是安卓通讯协议的使用,通讯内容太多分为2章,本章内容为Mqtt和Ble

本章内容如下:

1.Mqtt协议通讯

2.Ble协议通讯

一、Mqtt协议通讯

MQTT(消息队列遥测传输)是ISO 标准(ISO/IEC PRF 20922)下基于发布订阅范式的消息协议。它工作在 TCP/IP协议之上,是为硬件性能低下的远程设备以及网络状况糟糕的情况下而设计的发布/订阅型消息协议,为此,它需要一个消息中间件 。

代码实现了连接mqtt服务器,实现按钮发送消息,接收消息后显示到editview。这里需要注意的是需要自建1个Mqtt服务器和另1个Mqtt的客户端才方便验证,服务器采用了Emqx,另1个客户端使用了MQTT.fx,具体使用内容太长此处不进行说明。

1.1.AndroidManifest.xml添加权限

<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />

1.2 添加依赖,位于src文件夹下的build.gradle文件中

implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.1.0'
implementation 'org.eclipse.paho:org.eclipse.paho.android.service:1.1.1'

1.3 Activity_main.xml界面代码

?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/drawer_layout"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:fitsSystemWindows="true"
    tools:openDrawer="start">


    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:orientation="vertical">

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:orientation="horizontal">

            <TextView
                android:id="@+id/textView2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="TextView" />

            <EditText
                android:id="@+id/editText2"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:ems="10"
                android:inputType="textPersonName"
                android:text="Name" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:orientation="horizontal">

            <Button
                android:id="@+id/button"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="Button" />
        </LinearLayout>
    </LinearLayout>
</android.support.v4.widget.DrawerLayout>

1.4  添加Mqtt服务类MqttService.java

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;

import org.eclipse.paho.android.service.MqttAndroidClient;
import org.eclipse.paho.client.mqttv3.IMqttActionListener;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.IMqttToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttConnectOptions;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttMessage;


public class MqttService extends Service{

        public static final String TAG = MqttService.class.getSimpleName();

        private static String host = "tcp://192.168.3.131:1883";
        private static String userName = "test";
        private static String passWord = "123456";
        private static String sendTopic = "test";      //要发布的主题
        private static String recTopic[] = {"recv1","recv2","recv3"};      //要订阅的主题
        //private static String recTopic ="null/null/Gateway/00:09:C0:FF:EC:48/05";
        private static String clientId = "androidId";//客户端标识
        private IGetMessageCallBack IGetMessageCallBack;


        private static MqttAndroidClient client;
        private MqttConnectOptions conOpt;



        @Override
        public void onCreate() {
            super.onCreate();
            Log.e(getClass().getName(), "onCreate");
            init();
        }
         //  主题是myTopic  消息质量等级 0  消息在服务器端不保存
        public static void publish(String msg){
            String topic = MqttService.sendTopic;
            try {
                if (client != null){
                    client.publish(topic, msg.getBytes(),0, false,null,null);
                    Log.i("Publish","pubish mes is"+" "+ msg);
                }
            } catch (MqttException e) {
                e.printStackTrace();
            }
        }

        private void init() {
            // 服务器地址(协议+地址+端口号)
            String uri = host;
            client = new MqttAndroidClient(this, uri, clientId);
            // 设置MQTT监听并且接受消息   Sets a callback listener to use for events that happen asynchronously.
            client.setCallback(mqttCallback);

            conOpt = new MqttConnectOptions();
            // 清除缓存
            conOpt.setCleanSession(true);
            // 设置超时时间,单位:秒
            conOpt.setConnectionTimeout(10);
            // 心跳包发送间隔,单位:秒
            conOpt.setKeepAliveInterval(20);
            // 用户名
            conOpt.setUserName(userName);
            // 密码
            conOpt.setPassword(passWord.toCharArray());     //将字符串转换为字符串数组

            // last will message
            boolean doConnect = true;
            String message = "{\"terminal_uid\":\"" + clientId + "\"}";
            Log.e(getClass().getName(), "message是:" + message);
            String topic = sendTopic;
            Integer qos = 0;
            Boolean retained = false;
            if ((!message.equals("")) || (!topic.equals(""))) {
                // 最后的遗嘱
                // MQTT本身就是为信号不稳定的网络设计的,所以难免一些客户端会无故的和Broker断开连接。
                //当客户端连接到Broker时,可以指定LWT,Broker会定期检测客户端是否有异常。
                //当客户端异常掉线时,Broker就往连接时指定的topic里推送当时指定的LWT消息。

                try {
                    conOpt.setWill(topic, message.getBytes(), qos.intValue(), retained.booleanValue());
                } catch (Exception e) {
                    Log.i(TAG, "Exception Occured", e);
                    doConnect = false;
                    iMqttActionListener.onFailure(null, e);
                }
            }

            if (doConnect) {
                //连接Mqtt服务器
                doClientConnection();
            }

        }


        @Override
        public void onDestroy() {
            stopSelf();
            try {
                client.disconnect();
            } catch (MqttException e) {
                e.printStackTrace();
            }
            super.onDestroy();
        }

        /** 连接MQTT服务器 */
        private void doClientConnection() {
            //是否连接服务器  网络连接是否正常      连接成功后订阅主题
            if (!client.isConnected() && isConnectIsNormal()) {
                try {
                    client.connect(conOpt, null, iMqttActionListener);
                } catch (MqttException e) {
                    e.printStackTrace();
                }
            }

        }

        // MQTT是否连接成功
        private IMqttActionListener iMqttActionListener = new IMqttActionListener() {

            @Override
            public void onSuccess(IMqttToken arg0) {
                Log.i(TAG, "连接成功 ");
                try {
                    // 订阅myTopic话题
                    for(int i=0;i<3;i++)
                    client.subscribe(recTopic[i],1);
                } catch (MqttException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onFailure(IMqttToken arg0, Throwable arg1) {
                arg1.printStackTrace();
                // 连接失败,重连
            }
        };

        // MQTT监听并且接受消息
        private MqttCallback mqttCallback = new MqttCallback() {

            @Override
            public void messageArrived(String topic, MqttMessage message) throws Exception {
                String str1 = new String(message.getPayload());
                if (IGetMessageCallBack != null){
                    //光敏
                    if(topic.equals(recTopic[0])){
                        IGetMessageCallBack.setMessage(str1+"lx");//调用activity中的setMessage();
                    }
                    //温度
                    else if(topic.equals(recTopic[1])){
                        IGetMessageCallBack.setMessage1(str1+"℃");//调用activity中的setMessage();
                    }
                    //湿度
                    else if(topic.equals(recTopic[2])){
                        IGetMessageCallBack.setMessage2(str1+"%");//调用activity中的setMessage();
                    }
                    //IGetMessageCallBack.setMessage(str1);//调用activity中的setMessage();
                }
                String str2 = topic + ";qos:" + message.getQos() + ";retained:" + message.isRetained();
                Log.i(TAG, "messageArrived:" + str1);
                Log.i(TAG, str2);
            }

            @Override
            public void deliveryComplete(IMqttDeliveryToken arg0) {

            }

            @Override
            public void connectionLost(Throwable arg0) {
                // 失去连接,重连
            }
        };

        /** 判断网络是否连接 */
        private boolean isConnectIsNormal() {
            ConnectivityManager connectivityManager = (ConnectivityManager) this.getApplicationContext()
                    .getSystemService(Context.CONNECTIVITY_SERVICE);
            NetworkInfo info = connectivityManager.getActiveNetworkInfo();
            if (info != null && info.isAvailable()) {
                String name = info.getTypeName();
                Log.i(TAG, "MQTT当前网络名称:" + name);
                return true;
            } else {
                Log.i(TAG, "MQTT 没有可用网络");
                return false;
            }
        }


        @Override
        public IBinder onBind(Intent intent) {
            Log.e(getClass().getName(), "onBind");
            return new CustomBinder();
        }

        public void setIGetMessageCallBack(IGetMessageCallBack IGetMessageCallBack){
            this.IGetMessageCallBack = IGetMessageCallBack;
        }

        public class CustomBinder extends Binder {
            //公开方法给activity调用
            public MqttService getService(){
                return MqttService.this;
            }
        }

}

1.5 添加mqtt连接类MyServiceConnection.java

public class MyServiceConnection implements ServiceConnection {

    private MqttService mqttService;
    private IGetMessageCallBack IGetMessageCallBack;

    @Override
    public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
        mqttService = ((MqttService.CustomBinder)iBinder).getService();
        mqttService.setIGetMessageCallBack(IGetMessageCallBack);
    }

    @Override
    public void onServiceDisconnected(ComponentName componentName) {

    }

    public MqttService getMqttService(){
        return mqttService;
    }

    public void setIGetMessageCallBack(IGetMessageCallBack IGetMessageCallBack){
        this.IGetMessageCallBack = IGetMessageCallBack;
    }
}

1.6 添加接口IGetMessageCallBack.java

public interface IGetMessageCallBack {
  public void setMessage(String message);
  public void setMessage1(String message);
  public void setMessage2(String message);
}

1.7 修改MainActivity.java代码

public class MainActivity extends AppCompatActivity implements IGetMessageCallBack {

    //    private TextView txt3,txt4,txt5;
    private String str[]={"","",""};
    private SimpleAdapter adapter;
    private EditText txt;
    private Button button;
    private ArrayList list,newlist;
    private ListView listView;
    private MyServiceConnection serviceConnection;
    int j = 0;
//    private MqttService mqttService;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
//        txt3 =  findViewById(R.id.txt3);
//        txt4 =  findViewById(R.id.txt4);
//        txt5 =  findViewById(R.id.txt5);

        button =  findViewById(R.id.button);
        txt  = findViewById(R.id.editText2);

        //initDataList();

        // key值数组,适配器通过key值取value,与列表项组件一一对应
        String[] from = { "img", "title", "content" };
        // 列表项组件Id 数组


        /**
         * SimpleAdapter(Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to)
         * context:activity界面类
         * data 数组内容是map的集合数据
         * resource 列表项文件
         * from map key值数组
         * to 列表项组件id数组      from与to一一对应,适配器绑定数据
         */
        /*
        adapter = new SimpleAdapter(this, list,
                R.layout.listview_item, from, to);

        listView.setAdapter(adapter);
         */

        serviceConnection = new MyServiceConnection();
        //MyServiceConnection类中定义的方法setIGetMessageCallBack
        serviceConnection.setIGetMessageCallBack(MainActivity.this);

        Intent intent = new Intent(this, MqttService.class);

        bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE);


        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                j++;
                if (j == 1) {
                    MqttService.publish("0");
                    //button.setBackgroundResource(R.mipmap.light3);
                } else if (j == 2) {
                    MqttService.publish("1");
                    //button.setBackgroundResource(R.mipmap.light);
                    j = 0;
                }
            }
        });
    }

    @Override
    public void setMessage(String message) {
        str[0]=message;
        txt.setText(message);
        //updateDataList();

    }
    @Override
    public void setMessage1(String message) {
        str[1]=message;
        //updateDataList();
    }

    @Override
    public void setMessage2(String message) {
        str[2]=message;
        //updateDataList();
    }

    @Override
    protected void onDestroy() {
        unbindService(serviceConnection);
        super.onDestroy();
    }

    /*
    private void initDataList() {
        //图片资源
        int img[] = {R.mipmap.weathy, R.mipmap.tem, R.mipmap.hum};
        String text[] = {"光敏","温度","湿度"};
        list = new ArrayList<Map<String, Object>>();
        for (int i = 0; i < 3; i++) {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("img", img[i]);
            map.put("title",text[i]);
            map.put("content", "0");
            list.add(map);
        }
    }

    private void updateDataList(){
        list.clear();
        int img[] = {R.mipmap.weathy, R.mipmap.tem, R.mipmap.hum};
        String text[] = {"光敏","温度","湿度"};
        newlist = new ArrayList<Map<String, Object>>();
        for (int i = 0; i < 3; i++) {
            Map<String, Object> map = new HashMap<String, Object>();
            map.put("img", img[i]);
            map.put("title",text[i]);
            map.put("content",str[i]);
            list.add(map);
        }
        //txt.setText(message);
        list.addAll(newlist);
        adapter.notifyDataSetChanged();
    }
    */

}

此处的显示图片未截图,后面再补

二、Ble的通讯在安卓中用于和设备连接,是物联网中的近距离通讯连接。

Ble通讯比较特别,需要先搜索,再选择连接,最后通讯。代码太多这里只做搜索ble显示到listview的处理。

2.1 在 AndroidManifest.xml 中添加以下权限:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.kaka.bluetoothble">

    <!--声明蓝牙权限-->
    <uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <uses-permission android:name="android.permission.BLUETOOTH_PRIVILEGED"
        tools:ignore="ProtectedPermissions" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/test"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/test"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"

        >
        <activity android:name=".MainActivity"
            android:screenOrientation="landscape"

            >
            <intent-filter>
                <action android:name="android.intent.action.MAIN"
                    android:screenOrientation="landscape"
                    />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

2.2 添加依赖,src文件夹下的build.gradle文件中

apply plugin: 'com.android.application'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.kaka.bluetoothble"
        minSdkVersion 18
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    compileOptions {
        sourceCompatibility = 1.8
        targetCompatibility = 1.8
    }
    buildToolsVersion = '28.0.3'
}

dependencies {
    implementation fileTree(dir: 'libs', include: ['*.jar'])
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    implementation 'com.tbruyelle.rxpermissions2:rxpermissions:0.9.5@aar'
    implementation "io.reactivex.rxjava2:rxjava:2.0.6"
    implementation "io.reactivex.rxjava2:rxandroid:2.0.1"
    implementation "com.blankj:utilcode:1.9.6"
}

2.3  创建 ListView 布局

在 res/layout/activity_main.xml 中创建一个 ListView:

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

    <ListView
        android:id="@+id/bleListView"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="#80000000" <!-- 设置半透明背景 -->
        android:divider="@android:color/transparent"
        android:dividerHeight="10dp"/></LinearLayout>

在 res/layout/list_item_ble.xml 中创建每个列表项的布局:

<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"
    android:background="#80000000"> <!-- 设置半透明背景 -->

    <TextView
        android:id="@+id/deviceName"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Device Name"
        android:textColor="#FFFFFF"
        android:textSize="18sp"/>

    <TextView
        android:id="@+id/deviceAddress"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Device Address"
        android:textColor="#FFFFFF"
        android:textSize="14sp"/></LinearLayout>

4. 创建 Adapter

在 MainActivity.java 中创建一个自定义的 Adapter 来填充 ListView:

import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

import java.util.ArrayList;

public class BleDeviceAdapter extends ArrayAdapter<BluetoothDevice> {

    private Context context;
    private ArrayList<BluetoothDevice> devices;

    public BleDeviceAdapter(Context context, ArrayList<BluetoothDevice> devices) {
        super(context, R.layout.list_item_ble, devices);
        this.context = context;
        this.devices = devices;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View rowView = inflater.inflate(R.layout.list_item_ble, parent, false);

        TextView deviceName = rowView.findViewById(R.id.deviceName);
        TextView deviceAddress = rowView.findViewById(R.id.deviceAddress);

        BluetoothDevice device = devices.get(position);
        deviceName.setText(device.getName());
        deviceAddress.setText(device.getAddress());

        return rowView;
    }
}

5.  在 MainActivity 中使用 Adapter

在 MainActivity.java 中设置 ListView 并使用 BleDeviceAdapter:

import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ArrayAdapter;
import android.widget.TextView;

import java.util.ArrayList;

public class BleDeviceAdapter extends ArrayAdapter<BluetoothDevice> {

    private Context context;
    private ArrayList<BluetoothDevice> devices;

    public BleDeviceAdapter(Context context, ArrayList<BluetoothDevice> devices) {
        super(context, R.layout.list_item_ble, devices);
        this.context = context;
        this.devices = devices;
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View rowView = inflater.inflate(R.layout.list_item_ble, parent, false);

        TextView deviceName = rowView.findViewById(R.id.deviceName);
        TextView deviceAddress = rowView.findViewById(R.id.deviceAddress);

        BluetoothDevice device = devices.get(position);
        deviceName.setText(device.getName());
        deviceAddress.setText(device.getAddress());

        return rowView;
    }
}

Android-MQTT-Websocket-Client: 实现物联网通信的Android MQTT框架 MQTT(Message Queuing Telemetry Transport)是一种轻量级的消息传输协议,专为物联网(IoT)环境设计。它通过发布/订阅消息模式,为连接受限的设备提供实时通信能力,广泛应用于低带宽、高延迟或不稳定的网络环境中。Paho Java客户端库是专门为了实现基于MQTT协议的消息通信而设计的开源Java库。它是由Eclipse基金会下的Paho项目所提供,旨在为开发者提供一套稳定、轻量、跨平台的消息通信工具。 阅读详情

相关推荐

MQTT Android后台服务实现

消息队列遥测传输(MQTT)是一种轻量级的消息传输协议,它在物联网(IoT)领域被广泛应用。MQTT由Andy Stanford-Clark和Arcom Control Systems在1999年发明,用于在带宽有限、网络连接不可靠的情况下,设备和服务器之间的通信。库是一个开源的MQTT客户端实现,为Java和Android应用提供了与MQTT消息代理服务器通信的API。Paho库的主要特点和优势如下:跨平台兼容性。

weixin_42527589的博客 1445

【亲测免费】 推荐开源项目:MqttAndroidClient - 简易、高效的安卓MQTT客户端

推荐开源项目:MqttAndroidClient - 简易、高效的安卓MQTT客户端 是一个轻量级的Android库,专门用于实现MQTT(Message Queuing Telemetry Transport)协议,为移动应用提供实时数据通信的能力。在物联网(IoT)和大数据时代,这种低延迟、高效率的数据传输协议变得至关重要。 项目简介 MQTT是一种发布/订阅模式的传输协议,适合资源有限的设备...

gitblog_00032的博客 1353

Android 实现mqtt客户端的例子

Android 实现mqtt客户端的例子, 开源库 org.eclipse.paho.client.mqttv3.jar

Android中MQTT的使用

最近在做关于Android端从ActiveMQ中取数据的应用。如果ActiveMQ中有数据,就往Android端推送。 ActiveMQ和MQTT ActiveMQ 是 Apache 出品,最流行的,强有力的开源消息总线。MQ英文名MessageQueue,中文名也就是大家用的消息队列,说白了就是一个消息的接受和转发的容器,可用于消息推送。ActiveMQ 是一个完全支持 JMS1.1 和 J...

Tomdogs的专栏 2471

AndroidMqtt源码

Mqtt源码

Monocle2拟时轨迹基因模块的GO富集解析

本文详细解析了如何对Monocle2拟时分析中得到的基因表达模块进行GO富集分析。通过从热图对象中提取聚类模块,并利用clusterProfiler等工具进行功能注释,将抽象的基因表达时序模式转化为可解释的生物学功能主题,如免疫应答、细胞外基质组织等,从而深入理解细胞命运转变的驱动机制。

gpt4scribbler的博客 500

【亲测免费】 Android MQTT Service 开源项目教程

Android MQTT Service 开源项目教程 项目介绍 Android MQTT Service 是一个专为Android平台设计的MQTT(Message Queuing Telemetry Transport)客户端服务库。它简化了Android设备与MQTT broker的通信过程,使得集成物联网(IoT)应用变得更加便捷高效。项目由Jesse Farebro开发并维护,提供了一...

gitblog_00564的博客 950

从DC到DCG:手把手教你搭建物理感知综合流程(含DEF文件处理避坑指南)

本文详细介绍了从Design Compiler(DC)过渡到DC Topographical(DCT)和DC Graphical(DCG)的完整操作框架,特别针对DEF文件处理提供避坑方案。通过环境准备、工具升级、DEF文件处理、DCG综合配置等步骤,帮助开发者高效应对28nm以下工艺节点的物理感知综合挑战,显著提升时序收敛效率。

weixin_27966471的博客 381

探秘未来能源管理:Bluetti MQTT 开源项目详解

探秘未来能源管理:Bluetti MQTT 开源项目详解 项目介绍 在寻求绿色能源解决方案的过程中,储能设备扮演了至关重要的角色。Bluetti MQTT 是一个创新的开源工具,它为 Bluetti 功率站提供了 MQTT 接口,使用户能轻松地监控并控制这些先进的储能系统。通过实时发布状态信息到 MQTT 主题,并接受命令以执行相应操作,这款工具开启了智能家居和物联网集成的新篇章。 项目技术分析 ...

gitblog_00057的博客 593

python爬取巨潮资讯网所有股票年报数据

爬虫获取巨潮资讯网数据

qq_42752524的博客 6117

从PCIe 3.0到6.0:为什么“阻抗一致性”比“绝对值”更重要?聊聊连接器与板材的选型影响

本文探讨了PCIe从3.0到6.0演进过程中,阻抗一致性相比绝对值的重要性,分析了连接器与板材选型对高速信号完整性的影响。随着速率提升至64GT/s,系统级阻抗控制和验证成为关键,文章提供了选型指南、验证方法论及工程实践建议,帮助工程师应对高速设计挑战。

weixin_42556197的博客 384

UniApp安卓原生插件开发指南与实战技巧

原生插件开发是跨平台框架中解决性能瓶颈和功能扩展的关键技术。通过原生代码与JavaScript的桥接,开发者可以突破Web容器的限制,直接调用平台特有API。这种技术特别适用于需要高性能计算或硬件交互的场景,如蓝牙通信、传感器数据采集等。UniApp作为基于Vue.js的跨平台解决方案,其原生插件机制支持Module和Component两种模式,分别对应功能扩展和原生UI嵌入。在实际开发中,合理处理线程通信、内存管理以及性能优化是保证插件质量的重点。本指南详细介绍了从环境搭建到插件发布的完整流程,并提供了蓝

weixin_34116110的博客 418

【前端圭臬】二:你知道的和不知道的 HTML

关于 HTML,说几个你可能不太关注的问题。

Evan 的博客 4758

Android面试题基础集锦总结《二》

Android面试题基础集锦总结《二》1、面试步骤2、面试准备2、简历投递时间3、面试技巧4、面试真题集锦5、面试总结面试资料导入 1、面试步骤 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。 2、面试准备 我们对Markdown编辑器进行了一些功能拓展与语法支持,除了标准的Markdown编辑器功能,我们增加了如下几点新功能,帮助你用它写博客: 2.1. 简历设计 2.1.1

郑敏 2691

笔试题-2023-紫光展锐-数字芯片设计【纯净题目版】

笔试题-2023-紫光展锐-数字芯片设计【纯净题目版】

w0shishabi的博客 2923

STC单片机 普通 I/O 口中断功能介绍和使用

STC32单片机 普通 I/O 口中断功能介绍和使用

perseverance51博客 3048

AI语音智能体架构解析(一)系统架构全景图

本文系统阐述了智能语音系统的四层架构:1)云端大模型(含ASR/NLU/LLM/TTS四大能力模块);2)智控台(设备管理/MCP协议/安全机制);3)AI语音终端(双芯片硬件/五层软件架构/全协议栈);4)用户端小程序。重点解析了MCP协议如何实现AI对物理设备的标准化控制,以及语音交互全链路12步数据流。系统采用TLS加密+License授权保障安全,通过多平台对接实现智能场景联动,为AIoT领域提供了一套完整的端云协同解决方案。

ajassi2000的博客 415

Matlab并行运算

今天搞了一下matlab的并行计算,效果好的出乎我的意料。 本来CPU就是双核,不过以前一直注重算法,没注意并行计算的问题。今天为了在8核的dell服务器上跑程序才专门看了一下。本身写的程序就很容易实现并行化,因为beamline之间并没有考虑相互作用。等于可以拆成n个线程并行,要是有550核的话,估计1ms就算完了。。。 先转下网上找到的资料。 一、Matlab并行计算原理梗概 Matl

wenyusuran的专栏 1万+

AI语音智能体架构解析(二)大模型(AI 的大脑)

本文整合了多个技术开发系列教程资源链接,涵盖AI应用、Python、ArkTS鸿蒙、Java安卓、C#.NET等领域的开发指南。重点介绍了大语言模型(LLM)在语音智能体中的核心作用,包括语音识别(ASR)、语义理解(NLU)、对话生成(LLM)和语音合成(TTS)四大功能模块,以及完整对话流程的实现。项目支持对接小智云、七牛云、酷旗云和讯飞云四大主流云平台,满足不同智能设备的开发需求。各技术栈教程从环境搭建到功能实现提供了系统化的学习路径,适合开发者快速掌握相关技术。

ajassi2000的博客 263

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Android 开源项目和文章集合(更新:2022.03.21)

1.再见SharedPreferences,你好MMKV! https://mp.weixin.qq.com/s/VBMDIE0QHXQAMuIjon-Fjg

z979451341的博客 24万+

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

Android Mqtt 开源框架 EasyMqttAndroidClient

EasyMqttAndroidClient 使Mqtt安卓客户端变的更简单、更好用 github地址:https://github.com/ZS-ZhangsShun/EasyMqttAndroidClient 简介 基于第三方开源框架Mqtt Android客户端封装的用于接收、发布推送消息的组件。 功能 1.支持消息的订阅与发布 2.支持服务器的连接与断开 3.支持连接状态的判断 ...

安卓开发-顺 的博客 9084

STM32F407中文手册

STM32f407中文手册 本参考手册面向应用开发人员,提供有关使用 STM32F405xx/07xx、STM32F415xx/17xx、 STM32F42xxx 和 STM32F43xxx 微控制器存储器与外设的完整信息。STM32F405xx/07xx、STM32F415xx/17xx、STM32F42xxx 和 STM32F43xxx 构成一个微 控制器系列,各产品具有不同的存储器大小、封装和外设。有关订购信息以及器件的机械与电气特性,请参见数据手册。有关 ARM Cortex™-M4F 内核的信息,请参见《Cortex™-M4F 技术参考手册》。

基于paho.mqtt.java的开源Android端MQTT框架 MqttAndroid

背景 现在最常用的Android端MQTT框架是 paho.mqtt.android。paho.mqtt.android作为对 paho.mqtt.java 的一层包装,具体实现逻辑有点臃肿。于是想着模仿 paho.mqtt.android,实现对 paho.mqtt.java 更加简单的包装。 简介 对 paho.mqtt.java 库进行了的简单包装,方便Android端使用。 Github地址:https://github.com/shiyinghan/MqttAndroid 使用方法 第一步:在pr

hanshiying007的博客 2813

Android开发之利用MQTT协议实现消息的即时推送

Android开发之利用MQTT协议实现消息的即时推送(一) 近来做项目,要用到消息的即时推送,一般情况下,在项目初期,本人都要对项目中遇到的各个问题进行了解剖析以及处理,由于前期的项目中没用到过即时消息推送,故本人查阅了很多资料,终于在经过一天的研究后,实现了基于MQTT协议的消息推送,现本人将研究的过程贴出,望各位大神批评指正,灰常感谢,♪(^∇^*) 实现消息的即时推送,网上给出

FlyingSnow2211的博客 5638

开源一个Android源生Mqtt客户端app + Mqtt云服务器测试

本文开源的app采用Android studio3.5开发 Mqtt服务器采用的是搭建在阿里云上的Mosquitto,下载链接在文章结尾 首先感谢优快云其他博主写的一些博客,我可以快速查到我所需要补充的知识,Android工程实现参考博客链接如下: https://blog.youkuaiyun.com/asjqkkkk/article/details/80714234 此博主的部分代码有问题 ...

Rookie Linux的博客 4840

Android 端实现mqtt消息接收

1为了搞这个MQTT百度收搜了很多资料都是用阿里云的MQTT 虽然好用但是不符合我项目的需求,阿里云的mqtt达到一定的数量就要另行收费。所以公司决定自己搭建服务器实现节省成本 第一步首先后台先搭建一个服务器 主要讲下Android如何使用MQTT通讯。用到的软件或者框架有: EMQ:https://www.emqx.io/cn/ org.eclipse.paho的MQTT通讯框架:https:/...

xieyaofeng的博客 6850

百度开源文心5.5 Flash Base:280B MoE 只激活 14B,4 步部署 + 3 个坑,微调还是等指令版

百度开源文心 5.5 Flash 基座权重:280B MoE 每 token 激活 14B,1M 上下文,同尺寸开源 Base 30 项基准多数领先。4 步部署(vLLM/SGLang completions 链路)+ 3 个高频坑 + 动手前 6 点核对清单,并给出微调 Base 还是等指令版的判断线。

weixin_50937681的博客 308
上一篇: 开源 java android app 开发(七)通讯之Tcp和Http
下一篇: 开源 java android app 开发(九)后台之线程和服务
ajassi2000
博客等级 码龄22年 2035粉丝 191原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值