电话被锁定时,MQTT Android服务无法正常工作

时间:2017-07-16 08:38:17

标签: android mqtt

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

当手机被锁定时,该服务无效,并且没有收到通知。

我已经看过要解决这个问题的事情,但它们非常耗电。这不是我想要的。

这个想法就像是对于Snapchat的whatsapp,当我收到消息时,他们会通知我。

Android服务是否适合我的问题?或者是其他更好的东西。如果服务是正确的,我该如何使用。

这就是我已经做过的事情:

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);
    }

1 个答案:

答案 0 :(得分:0)

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

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

如果FCM不是一个选项,您必须坚持使用MQTT,请考虑启动前台服务并处理唤醒锁定。我仍然会敦促你使用FCM而不是MQTT与前台服务和唤醒锁。