手机锁定时MQTT Android服务不工作

手机锁定时MQTT Android服务不工作,android,mqtt,Android,Mqtt,我正在尝试创建一个Android服务,它在手机收到MQTT消息时使用通知 当手机被锁定时,服务将不工作,并且不会收到通知 我已经研究过解决这个问题的方法,但是它们非常消耗电池。这不是我想要的 这个想法就像snapchat的whatsapp,当我收到消息时,他们会通知我 安卓服务是解决我问题的正确方法吗?或者是其他更好的东西。如果服务是正确的,我应该使用什么呢 这是我已经做过的: import android.app.Notification; import android.app.Notific

我正在尝试创建一个Android服务,它在手机收到MQTT消息时使用通知

当手机被锁定时,服务将不工作,并且不会收到通知

我已经研究过解决这个问题的方法,但是它们非常消耗电池。这不是我想要的

这个想法就像snapchat的whatsapp,当我收到消息时,他们会通知我

安卓服务是解决我问题的正确方法吗?或者是其他更好的东西。如果服务是正确的,我应该使用什么呢

这是我已经做过的:

import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.os.IBinder;
import android.os.Vibrator;
import android.provider.Settings;
import android.support.annotation.IntDef;
import android.support.v7.app.NotificationCompat;
import android.util.Log;
import android.widget.Toast;

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.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.MqttSecurityException;

public class MQTTService extends Service {
    private static final String TAG = "MQTTService";
    MqttAndroidClient client;
    NotificationManager mNotificationManger;
    int mNotificationID = 0;

   public MQTTService() {
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int 
 startId) {
        Log.i(TAG, "onStartCommand methode called");

        Runnable r = new Runnable() {
            @Override
            public void run() {
            initMqtt();
            Log.i(TAG, "start init");
            client.setCallback(new MqttCallback() {
                @Override
                public void connectionLost(Throwable cause) {

                }

                @Override
                public void messageArrived(String topic, MqttMessage message) throws Exception {
//                     Toast.makeText(getApplicationContext(), 
"MQTT Message:\n" + new String(message.getPayload()), 
 Toast.LENGTH_SHORT).show();
                        notifyNotifications(topic, new 
 String(message.getPayload()));
                    }

                @Override
                public void deliveryComplete(IMqttDeliveryToken token) {

                }
            });
        }
    };

    Thread backgroundThread = new Thread(r);
    backgroundThread.start();
    return Service.START_STICKY;
}

@Override
public void onDestroy() {
    Log.i(TAG, "onDestroy methode called");
}

@Override
public IBinder onBind(Intent intent) {
    return null;
}

public void initMqtt()
{
    Log.i(TAG, "start init");
    String clientId = MqttClient.generateClientId();
    client = new MqttAndroidClient(this.getApplicationContext(), "tcp://192.168.2.128:1883", clientId);
    Log.i(TAG, "client created");
    try{
        MqttConnectOptions options = new MqttConnectOptions();
        options.setMqttVersion(MqttConnectOptions.MQTT_VERSION_3_1);
        options.setCleanSession(true);
        client.connect(options, null, new IMqttActionListener() {
            @Override
            public void onSuccess(IMqttToken asyncActionToken) {
                Log.i(TAG, "connect succes");
                subscribe();
            }

            @Override
            public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                Log.i(TAG, "connect failed");
            }
        });
    }catch (MqttException e)
    {
        e.printStackTrace();
        Log.i(TAG, "connect failed exception");
    }
}

public void subscribe()
{
    String topic = "test_mqtt";
    int qos = 1;
    try{
        IMqttToken subToken = client.subscribe(topic, qos);
        subToken.setActionCallback(new IMqttActionListener() {
            @Override
            public void onSuccess(IMqttToken asyncActionToken) {
                Log.i(TAG, "subscribe succes");
                Toast.makeText(getApplicationContext(), "subscribe succes", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
                Log.i(TAG, "subscribe failed");
            }
        });
    } catch (MqttSecurityException e) {
        e.printStackTrace();
        Log.i(TAG, "subscribe failed exception security");
    } catch (MqttException e) {
        Log.i(TAG, "subscribe failed exception");
        e.printStackTrace();
    }
}

public void notifyNotifications(String topic, String message)
{
    NotificationCompat.Builder mBuilder =
            (NotificationCompat.Builder) new NotificationCompat.Builder(getApplicationContext())
            .setSmallIcon(R.drawable.icon)
            .setContentTitle(topic)
            .setContentText(message)
            .setAutoCancel(true)
            .setVibrate(new long[]{1000,1000})
            .setLights(Color.RED, 3000, 3000)
            .setSound(Settings.System.DEFAULT_NOTIFICATION_URI);

    Notification note = mBuilder.build();
    note.defaults |= Notification.DEFAULT_VIBRATE;
    note.defaults |= Notification.DEFAULT_SOUND;

    mNotificationManger = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

    mNotificationManger.notify(mNotificationID, mBuilder.build());
    mNotificationID++;
}
}

以及用于启动服务的“资源”活动:

 @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        notifyNotifications("start", "start service");
        Intent i = new Intent(this, MQTTService.class);
        startService(i);
    }

MQTT将需要与服务器的持久连接,这将固有地消耗电池。只有当您想在UI处于活动状态时订阅主题时,MQTT才是更好的选择

更好的选择是探索FCM(Firebase云消息传递)


如果FCM不是一个选项,你必须坚持MQTT,考虑启动前台服务并处理唤醒锁。我仍然建议您使用FCM,而不是带有前台服务和唤醒锁的MQTT。

谢谢!我会试试的