MQTT Android в режиме «Доза» (Android 7.0)

Я использую библиотеку Android Eclipse Paho Mqtt для отправки ссылки на аудиофайл, который будет загружен и воспроизведен сразу. Он отлично работает, пока не попадет в режим «Дозировка». Я уже пробовал использовать белый список и несколько других решений, например: https://github.com/eclipse/paho.mqtt.android/issues/226 .

Вот мой MQTT-сервис:

class MqttManagerService : Service() { var client: MqttAndroidClient? = null var options = MqttConnectOptions() var TAG = "MQTT" var saveMessage = "" var serviceRunningNotification: Notification? = null private var _instance: MqttManagerService? = null var handler = Handler() var runnableCode: Runnable = object : Runnable { override fun run() { if (_instance == null) { return } if (client!!.isConnected()) { val now = Date() val json = JSONObject() try { json.put("d", now.toString()) json.put("s", now.getTime()) } catch (e: JSONException) { e.printStackTrace() } var bundle = Bundle() bundle.putString("Ping", "Ping") bundle.putString(TOPIC, TOPICPING) publish(bundle) handler.postDelayed(this, 10000) } else { //Ĺog.d("mq not connected.") } } } override fun onCreate() { super.onCreate() options = createMqttConnectOptions() client = createMqttAndroidClient() this.connect(client, options) val notification = Notification.Builder(this@MqttManagerService) .setTicker("") .setContentTitle("Emergency") .setContentText("ready") .setSmallIcon(R.mipmap.roteskreuz) .notification startForeground(1337, notification) } override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int { _instance = this; if (intent != null) { if (intent.extras != null) { if (TOPIC in intent.extras.keySet()) { val extras = intent.extras as Bundle publish(extras) } if (SUBSCRIBE in intent.extras.keySet()) { setSubscription(intent.extras.getString(SUBSCRIBE)) } if (DISCONNECT in intent.extras.keySet()) { disconnect() } } } return Service.START_REDELIVER_INTENT } override fun onBind(intent: Intent): IBinder? { if (client!!.isConnected() == false) { this.connectToken() } return null } override fun onTaskRemoved(rootIntent: Intent?) { restartServiceInBG(); super.onTaskRemoved(rootIntent) } override fun onDestroy() { super.onDestroy() this.connect(client, options) } // -------------------------------------------- MQTT-Stuff -------------------------------------------------------------- private fun createMqttConnectOptions(): MqttConnectOptions { //create and return options options.setUserName(USERNAME) options.setPassword(PASSWORD.toCharArray()) options.setCleanSession(false) return options } private fun createMqttAndroidClient(): MqttAndroidClient { //create and return client client = MqttAndroidClient(this, MQTTHOST, clientId) return client as MqttAndroidClient } fun connect(client: MqttAndroidClient?, options: MqttConnectOptions) { try { if (!client!!.isConnected) { connectToken() client.setCallback(object : MqttCallback { override fun connectionLost(cause: Throwable) { connectToken() client!!.unregisterResources() if (null != cause) { Log.d(TAG, "connection lost: " + cause.message + " ") Log.e(TAG, "connectionLost: ", cause) } if (_instance!!.applicationContext == null) { stopForeground(true) //vibrate(100L) } object : CountDownTimer(2000, 1000) { override fun onTick(millisUntilFinished: Long) {} override fun onFinish() { restartServiceInBG() } }.start() } @Throws(Exception::class) override fun messageArrived(topic: String, message: MqttMessage) { val messageJson = JSONObject(String(message.payload)) // receive only other messages if (saveMessage != message.toString()) { if (messageJson.getString(CLIENTID) != client.clientId) { if (messageJson.getString(TOPIC) == TOPICEMERGENCy) { // val intent = Intent(applicationContext, IncomingEmergency::class.java) intent.putExtra(INCOMINGEMERGENCYCALL, messageJson.get(LINK).toString()) saveMessage = message.toString() intent.putExtra(MESSAGE, saveMessage) startActivity(intent) } if (messageJson.getString(TOPIC) == TOPICCASE) { val intent = Intent(applicationContext, EingehenderNotruf::class.java) intent.putExtra(INCOMINGNEWBLOODVALUE, INCOMINGNEWBLOODVALUE) saveMessage = message.toString() intent.putExtra(MESSAGE, saveMessage) startActivity(intent) } } } } override fun deliveryComplete(token: IMqttDeliveryToken) { } }) } } catch (e: MqttException) { } } private fun setSubscription(topic: String) { try { client!!.subscribe(topic, 0) } catch (e: MqttException) { e.printStackTrace() } } fun connectToken() { var not_connected = true var counter = 0 while (not_connected && counter <= 5) { try { val token = client!!.connect(options) //on successful connection, publish or subscribe as usual token.actionCallback = object : IMqttActionListener { override fun onSuccess(asyncActionToken: IMqttToken) { setSubscription(TOPICEMERGENCY) not_connected = false handler.post(runnableCode) } override fun onFailure(asyncActionToken: IMqttToken, exception: Throwable) { } } } catch (e: MqttException) { } counter++ } } fun disconnect() { var not_connected = true var counter = 0 while (not_connected && counter <= 5) { try { val token = client!!.disconnect() token.actionCallback = object : IMqttActionListener { override fun onSuccess(asyncActionToken: IMqttToken) { not_connected = false } override fun onFailure(asyncActionToken: IMqttToken, exception: Throwable) { Toast.makeText(applicationContext, "could not disconnect", Toast.LENGTH_LONG).show() } } } catch (e: MqttException) { e.printStackTrace() } counter++ } } private fun publish(bundle: Bundle) { try { val messageJson = JSONObject() messageJson.put(CLIENTID, client!!.clientId) val topic = bundle.get(TOPIC) as String for (key in bundle.keySet()) { messageJson.put(key, bundle[key]) } client!!.publish(topic, messageJson.toString(0).toByteArray(), 0, false) } catch (e: MqttException) { e.printStackTrace() } } fun restartServiceInBG() { // restart the service with a notification val notificationIntent = Intent(applicationContext, this.javaClass) notificationIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP or Intent.FLAG_ACTIVITY_SINGLE_TOP) val pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0) serviceRunningNotification = Notification.Builder(this) .setContentTitle("Service") // ConextText part bugs, Notification maysay disconnected despite valid connection and vice versa .setContentText(if (client!!.isConnected()) "Connected" else "Disconnected") .setSmallIcon(R.drawable.abc_ic_star_black_16dp) .setContentIntent(pendingIntent) .setTicker("ticker ?") .addAction(R.drawable.abc_ic_star_black_36dp, "Open", PendingIntent.getActivity(baseContext, 0, Intent("android.intent.category.LAUNCHER").setClassName("com.package", "com.package.MainActivity"), PendingIntent.FLAG_UPDATE_CURRENT)) .build() startForeground(10, serviceRunningNotification) connectToken() } companion object { internal var MQTTHOST = "tcp:/" //TODO: change username and password internal var USERNAME = "12345" internal var PASSWORD = "12345" internal val clientId = MqttClient.generateClientId() internal val TOPICEMERGENCY = "Topic1" internal val LINK = "LINK" internal val CLIENTID = "CLIENTID" internal val TOPIC = "TOPIC" internal val SUBSCRIBE = "SUBSCRIBE" internal val INCOMINGEMERGENCYCALL = "INCOMINGCALL" internal val DISCONNECT = "DISCONNECT" internal val TOPICCASE = "UPDATECASES" internal val INCOMINGNEWBLOODVALUE = "INCOMINGNEWBLOODVALUE" internal val MESSAGE = "MESSAGE" internal val TOPICPING = "PING" } }