0

I have an app I in which I connect to io.adafruit and subscribe and publish topics. The app was running fine until I updated Android Studio to version 12 and now I keep getting the following error and crash

2022-10-10 15:17:53.905 14953-15048/com.example.mqttkotlinsample D/AlarmPingSender: Register alarmreceiver to MqttServiceMqttService.pingSender.
    
    --------- beginning of crash
2022-10-10 15:17:53.907 14953-15048/com.example.mqttkotlinsample E/AndroidRuntime: FATAL EXCEPTION: MQTT Rec: 
    Process: com.example.mqttkotlinsample, PID: 14953
    java.lang.IllegalArgumentException: com.example.mqttkotlinsample: Targeting S+ (version 31 and above) requires that one of FLAG_IMMUTABLE or FLAG_MUTABLE be specified when creating a PendingIntent.
    Strongly consider using FLAG_IMMUTABLE, only use FLAG_MUTABLE if some functionality depends on the PendingIntent being mutable, e.g. if it needs to be used with inline replies or bubbles.
        at android.app.PendingIntent.checkFlags(PendingIntent.java:401)
        at android.app.PendingIntent.getBroadcastAsUser(PendingIntent.java:671)
        at android.app.PendingIntent.getBroadcast(PendingIntent.java:658)
        at org.eclipse.paho.android.service.AlarmPingSender.start(AlarmPingSender.java:76)
        at org.eclipse.paho.client.mqttv3.internal.ClientState.connected(ClientState.java:1209)
        at org.eclipse.paho.client.mqttv3.internal.ClientState.notifyReceivedAck(ClientState.java:1045)
        at org.eclipse.paho.client.mqttv3.internal.CommsReceiver.run(CommsReceiver.java:151)
        at java.lang.Thread.run(Thread.java:1012)
2022-10-10 15:17:53.994 14953-14953/com.example.mqttkotlinsample D/com.example.mqttkotlinsample.MQTTClient$defaultCbDisconnect$1: Disconnected
2022-10-10 15:17:53.994 14953-14953/com.example.mqttkotlinsample D/com.example.mqttkotlinsample.ClientFragment$onViewCreated$2: Connection lost null

By looking at the log and using break points I've concluded I where I need to put the PendingIntent but I do not know how to write it.

can someone help me out.

here is my code;

package com.example.mqttkotlinsample


import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.webkit.WebView
import android.widget.ImageButton
import androidx.activity.OnBackPressedCallback
import androidx.fragment.app.Fragment
import androidx.navigation.fragment.findNavController
import org.eclipse.paho.client.mqttv3.*

class ClientFragment : Fragment() {

    private lateinit var mqttClient : MQTTClient

    override fun onCreate(savedInstanceState: Bundle?) {
        Log.d(this.javaClass.name, "LAUNCHED!!!!!!!!!!!!!!!!!!!")
        super.onCreate(savedInstanceState)

activity?.onBackPressedDispatcher?.addCallback(this, object : OnBackPressedCallback(true) {

            override fun handleOnBackPressed() {

if (mqttClient.isConnected()) {

                    Log.d(this.javaClass.name, "CALLBACK!!!!!!!!!!!!!!!!!!!")

                   // Disconnect from MQTT Broker
                    mqttClient.disconnect(object : IMqttActionListener {
                        override fun onSuccess(asyncActionToken: IMqttToken?) {

                            Log.d(this.javaClass.name, "Disconnected")

                        }

                        override fun onFailure(asyncActionToken: IMqttToken?, exception: Throwable?) {

                            Log.d(this.javaClass.name, "Failed to disconnect")
                        }
                    })
                } else {

                    Log.d(this.javaClass.name, "Impossible to disconnect, no server connected")
                }
            }
        })
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?

): View? {

// Inflate the layout for this fragment
        return inflater.inflate(R.layout.fragment_client, container, false)
}

override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        val serverURI   = arguments?.getString(MQTT_SERVER_URI_KEY)
        val clientId    = arguments?.getString(MQTT_CLIENT_ID_KEY)
        val username    = arguments?.getString(MQTT_USERNAME_KEY)
        val pwd         = arguments?.getString(MQTT_PWD_KEY)
        val cameraip    = arguments?.getString(MQTT_CAMERAIP_KEY)

        // Check if passed arguments are valid
        val camerasite = StringBuilder().append("").append("http://").append(cameraip).append("/").append(username).append("/1").toString()
        val webView = view.findViewById<View>(R.id.webView) as WebView
        webView.loadUrl(camerasite)
       if (

           serverURI   != null    &&
            clientId    != null    &&
            username    != null    &&
            pwd         != null        ) {

           Log.d(this.javaClass.name, "TRYING!!!!!!!!!!!!!!!!!!!")
            // Open MQTT Broker communication
           mqttClient = MQTTClient(context, serverURI, clientId)

           Log.d(this.javaClass.name, "FLAG!!!!!!!!!!!!!!!!!!!")
              
          // Get arguments passed by ConnectFragment


           Log.d("serverURI",serverURI)
           Log.d("clientID",clientId)
           Log.d("username",username)
           Log.d("pwd",pwd)
           Log.d("camera",camerasite)
// Connect and login to MQTT Broker
           mqttClient.connect( username,
                pwd,

                object : IMqttActionListener {

 override fun onSuccess(asyncActionToken: IMqttToken?) {

//THIS IS WHERE I HAVE DETERMINED THE PENDINGINTENT NEEDS TO GO!

}

                    override fun onFailure(asyncActionToken: IMqttToken?, exception: Throwable?) {
                        Log.d(this.javaClass.name, "Connection failure: ${exception.toString()}")
}
},

                object : MqttCallback {


                    override fun messageArrived(topic: String?, message: MqttMessage?) {
 }

                    override fun connectionLost(cause: Throwable?) {
                        Log.d(this.javaClass.name, "Connection lost ${cause.toString()}")
                    }

                    override fun deliveryComplete(token: IMqttDeliveryToken?) {

                        Log.d(this.javaClass.name, "Delivery complete")
                    }
                })
}
David Wasser
  • 93,459
  • 16
  • 209
  • 274
user1114881
  • 731
  • 1
  • 12
  • 25
  • See https://stackoverflow.com/questions/69783824/targeting-s-version-31-and-above-requires-that-one-of-flag-immutable-or-flag – David Wasser Oct 12 '22 at 09:43
  • Removed tag `android-studio` as this question has nothing to do with the Android Studio product. – David Wasser Oct 12 '22 at 09:43
  • 1
    I am assuming by your post that I should contact eclipse.paho and ask them to update their service package to deal with the new PendingIntent requirements. I will do this. – user1114881 Oct 12 '22 at 16:39
  • Yes, either that or they already have and you need to update to the latest version. – David Wasser Oct 12 '22 at 17:39
  • 1
    I got this to work by going to https://github.com/eclipse/paho.mqtt.android and clicking on issues as was suggested. They haven't updated the latest version but there was a solution. Somewhat involved but I finally got it going. I hope someone updates it to make it work. Thanks for steering me in the right direction. – user1114881 Oct 14 '22 at 19:26
  • Hey, glad you got it to work! Maybe you can provide an answer here that will help other developers with this problem. – David Wasser Oct 15 '22 at 18:26
  • I am still trying to get rid of various warnings. But as I said if you go to the link and click on the issues you will see the solution. It involves copying and pasting the various pages of the library into your project inside a folder. Then you can change the code inside the AlarmPingSender page. There are a few other changes (errors) I had to address. Could be specific to my project. Then like I said I am cleaning up warning. One sticky on is the 'androidx.localbroadcastmanager.content.LocalBroadcastManager' is deprecated warning. It is a good solution but takes some work. good luck. – user1114881 Oct 18 '22 at 21:40

0 Answers0