2017-07-16 68 views
0

我正嘗試創建一個Android服務,當手機收到MQTT消息時使用通知。MQTT Android服務在電話鎖定時不工作

手機被鎖定時,該服務無法正常工作,並且未收到通知。

我已經看過要解決這個問題的東西,但它們非常耗電。這不是我想要的。

這個想法就像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++; 
} 

}

而且ofcource一個活動,它啓動服務:

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

回答

0

MQTT將需要服務器持續連接這將固有地消耗電池。只有當您想在UI激活時訂閱主題時,MQTT纔會是更好的選擇。

更好的選擇是探索FCM(Firebase雲消息傳遞)。

如果FCM不是一個選項,並且您必須堅持使用MQTT,請考慮啓動前臺服務並處理喚醒鎖。我仍然會敦促你使用FCM而不是MQTT來處理前臺服務和喚醒鎖。

+0

謝謝!我會嘗試 –