マイナー・マイナー

隠れた名作の発掘が生きがい。

AndroidのMQTTクライアントを導入する


スポンサードリンク

AndroidでMQTTのPublisher/Subscriberを実装する場合、Paho Android Serviceライブラリを利用するのが便利そうです。このライブラリを利用したMQTTクライアントの作成手順をメモしました。


事前準備
android API 19が必要のため、あらかじめSDKマネージャでインスールしておきます。導入には下記の2つのjarファイルが必要なので、まずはこれらを準備します。


org.eclipse.paho.client.mqttv3-1.0.1.jar
下記の場所にあるようなので、ダウンロードします。

curl -O https://repo.eclipse.org/content/repositories/paho-releases/org/eclipse/paho/org.eclipse.paho.client.mqttv3/1.0.1/org.eclipse.paho.client.mqttv3-1.0.1.jar


org.eclipse.paho.android.service.jar
探しても見つからなかったため、ソースファイルから作成します。

git clone http://git.eclipse.org/gitroot/paho/org.eclipse.paho.mqtt.java.git


cloneしてきたプロジェクトをeclipseにインポートし、まずandroid API 19のライブラリ(android.jar)のある場所にパスを通しておきます。そして、プロジェクト直下にlibsディレクトリを作って、そこに下記のjarファイルをコピーします。

  • org.eclipse.paho.client.mqttv3-1.0.1.jar
  • support-v4-r7.jar


support-v4-r7.jarはどこかから入手してくるか、もしくはpom.xmlのparentのエラーをなくしてmavenの依存ライブラリより入手します。

修正前

...
     <parent>
          <groupId>org.eclipse.paho</groupId>
          <artifactId>android-service-parent</artifactId>
          <version>1.0.1</version>
     </parent>

     <artifactId>org.eclipse.paho.android.service</artifactId>
     <packaging>jar</packaging>
...


修正後

...
     <groupId>org.eclipse.paho</groupId>
     <version>1.0.1</version>
     <artifactId>org.eclipse.paho.android.service</artifactId>
...

※org.eclipse.pahoのdependencyでエラーが出るけれど、support-v4-r7.jarが入手できていれば良いです。


続いてexportjar.xmlをAnt実行します。androidjarのパスがうまく指定されずにエラーとなっていたので、androidjarのパスをうまく指定するように上書きして実行しました。

修正前

<property name="androidjar" value="${sdk.dir}/platforms/android-${androidAPILevel}"/>


修正後

<property name="androidjar" value="/Applications/adt-bundle-mac/sdk/platforms/android-${androidAPILevel}"/>

プロジェクト直下にdistディレクトリが作成され、そこにorg.eclipse.paho.android.service.jarが作成されていれば成功です。


サンプルコード作成
適当なプロジェクトを作成し、そこのlibsディレクトリに下記jarをコピーします。


AndroidManifestを開き、Paho Android Serviceを利用するのに必要なPermissionとServiceを追加します。Main Activityは"MQTTMainActivity"としました。

AndroidManifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.mqttsample"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="21" />

    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
   
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity android:name="MQTTMainActivity" android:label="@string/app_name">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <service android:name="org.eclipse.paho.android.service.MqttService" >
        </service>
    </application>

</manifest>


MQTTMainActivityを次のよう書きました。onCreateでMQTTサーバに接続し、onPauseでpublishするコードです。

MQTTMainActivity.java

package com.example.mqttsample;

import org.eclipse.paho.android.service.MqttAndroidClient;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.eclipse.paho.client.mqttv3.MqttPersistenceException;

import android.app.Activity;
import android.os.Bundle;

public class MQTTMainActivity extends Activity {
     MqttAndroidClient mqttAndroidClient;
    
     @Override
     public void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          mqttAndroidClient = new MqttAndroidClient(this, "tcp://xxx.xxx.xxx.xxx:1883", "piyo"); // (1)
          try {
               mqttAndroidClient.connect();  // (2)
          } catch (MqttException e) {
               e.printStackTrace();
          }
     }
    
     @Override
     public void onPause() {
          super.onPause();
          try {
               mqttAndroidClient.publish("topic/hoge", "hello world".getBytes(), 0, false); // (3)
          } catch (MqttPersistenceException e) {
               e.printStackTrace();
          } catch (MqttException e) {
               e.printStackTrace();
          }
     }
}


(1) MqttAndroidClientのインスタンス作成時に引数としてContext、Server URI、Client IDを指定しています。Server URIはMQTTサーバのURLです。

(2) サーバに接続します。connectメソッドの引数には接続オプションやコールバッククラスを指定することもできます。

(3) MQTTサーバにpublishします。引数はそれぞれ、Topic、メッセージ、QoS、Retainです。


実行確認
MQTTの挙動をMacで確認する - マイナー・マイナーの手順を参考にBrokerとSubscriberを起動しておきます。そしてMQTTMainActivityを起動し、アプリがバックグラウンド状態になるたびにSubscriberのコンソールに"hello world"が表示されることを確認します。