How to solve Android 12 cannot use MqttAndroidClient

2.8k Views Asked by At

In my Android Studio, I would like to connect the Mqtt Android client to my laptop host (in the same machine). I make it similar to this guide

https://www.hivemq.com/blog/mqtt-client-library-enyclopedia-paho-android-service/

Then, I found that the Android 12 (API 32 in my case) may not support the org.eclipse.paho:org.eclipse.paho.android.service:1.1.1 dependency. So, I followed this solution below, by imported the serviceLibrary-release.aar library from github provided instead. (The problem appear in this link was the same of my case)

Android paho mqtt crashes Android 12 - Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE

After that, I ran into another error.

error: constructor MqttAndroidClient in class MqttAndroidClient cannot be applied to given types;
                MqttAndroidClient client = new MqttAndroidClient(MainActivity.this, "tcp://10.0.2.2:1883", clientId);
                                           ^
  required: Context,String,String,Ack
  found: MainActivity,String,String
  reason: actual and formal argument lists differ in length

So I'm not sure that the library from the solution above can be applied to my old code, or, do I need to modify some code?

Here is my code and the gradle file.

repositories

maven {
    url "https://repo.eclipse.org/content/repositories/paho-releases/"
}

Dependencies

implementation files('libs/serviceLibrary-release.aar')
implementation 'org.eclipse.paho:org.eclipse.paho.client.mqttv3:1.2.5'

Android Manifest (Added permission below)

<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<service android:name="info.mqtt.android.service.MqttService"/>

Main Activity

import info.mqtt.android.service.MqttAndroidClient;
public class MainActivity extends AppCompatActivity {

    private Button buttonConnect;

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

        buttonConnect = findViewById(R.id.buttonConnect);
        buttonConnect.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String clientId = MqttClient.generateClientId();
                Toast.makeText(MainActivity.this, clientId, Toast.LENGTH_SHORT).show();

                MqttAndroidClient client = new MqttAndroidClient(MainActivity.this, "tcp://10.0.2.2:1883", clientId);

                try {
                    IMqttToken token = client.connect();
                    token.setActionCallback(new IMqttActionListener() {
                        @Override
                        public void onSuccess(IMqttToken asyncActionToken) {
                            Log.d("Debug", "onSuccess");
                            Toast.makeText(MainActivity.this, "onSuccess", Toast.LENGTH_SHORT).show();
                        }

                        @Override
                        public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                            Log.d("Debug", "onFailure");
                            Toast.makeText(MainActivity.this, "onFailure", Toast.LENGTH_SHORT).show();
                            exception.printStackTrace();
                        }
                    });
                } catch (MqttException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}

The error appear in this line (when the button is clicked)

MqttAndroidClient client = new MqttAndroidClient(MainActivity.this, "tcp://10.0.2.2:1883", clientId);

From the error message prompted above. I think that's because the constructor's parameter of this class require a type Ack also, but I have no idea on that.

1

There are 1 best solutions below

5
On BEST ANSWER

From output you provided, it seems you only need to specify Ack as the last parameter of your constructor. It's acknowledgment that you received a message. According to official description, there is two modes available.

First, MqttAndroidClient.Ack.AUTO_ACK, which acknowledge automatically as soon as you received a message.

And then you have MqttAndroidClient.Ack.MANUAL_ACK, which requires you to manually acknowledge by doing MqttAndroidClient.acknowledgeMessage(String)

You can test it simply by adding the auto for now, and if it's ok then you can manually acknowledge yourself with custom rules.