使用Android在AWS IoT服务上发布MQTT消息

时间:2017-03-10 15:34:19

标签: java android amazon-web-services mqtt aws-iot

我正在尝试使用 AWSIotMqttManager 在Android应用上发布amazon web服务IoT的mqtt消息,我已经使用this示例作为我的代码的基础。该应用程序说它可以成功连接到设备,但无法实际发布消息,这里有什么问题?

// Initialize the AWS Cognito credentials provider
        credentialsProvider = new CognitoCachingCredentialsProvider(
                getApplicationContext(), // context
                COGNITO_POOL_ID, // Identity Pool ID
                MY_REGION // Region
        );
        Region region = Region.getRegion(MY_REGION);

        //intialize unnqique clientid as client to iot aws
        Long tsLong = System.currentTimeMillis()/1000;
        clientId = tsLong.toString();
// MQTT Client
        mqttManager = new AWSIotMqttManager(clientId, CUSTOMER_SPECIFIC_ENDPOINT);
// The following block uses a Cognito credentials provider for authentication with AWS IoT.
        new Thread(new Runnable() {
            @Override
            public void run() {
                awsCredentials = credentialsProvider.getCredentials();

                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        bttnConnect.setEnabled(true);
                        Toast.makeText(WelcomePageActivity.this, "credentials ok?", Toast.LENGTH_SHORT).show();
                    }
                });
            }
        }).start();
//connection button onclick lisetner will connect to the mqtt protocol
        bttnConnect.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Log.d("LOG_TAG", "clientId = " + clientId);
                try {
                    mqttManager.connect(credentialsProvider, new AWSIotMqttClientStatusCallback() {
                        @Override
                        public void onStatusChanged(final AWSIotMqttClientStatus status,
                                                    final Throwable throwable) {
                            Log.d("LOG_TAG", "Status = " + String.valueOf(status));

                            runOnUiThread(new Runnable() {
                                @Override
                                public void run() {
                                    if (status == AWSIotMqttClientStatus.Connecting) {
                                        tvStatus.setText("Connecting...");

                                    } else if (status == AWSIotMqttClientStatus.Connected) {
                                        tvStatus.setText("Connected");

                                    } else if (status == AWSIotMqttClientStatus.Reconnecting) {
                                        if (throwable != null) {
                                            Log.e("LOG_TAG", "Connection error.", throwable);
                                        }
                                         tvStatus.setText("Reconnecting");
                                    } else if (status == AWSIotMqttClientStatus.ConnectionLost) {
                                        if (throwable != null) {
                                            Log.e("LOG_TAG", "Connection error.", throwable);
                                            throwable.printStackTrace();
                                        }
                                        tvStatus.setText("Disconnected");
                                    } else {
                                        tvStatus.setText("Disconnected");

                                    }
                                }
                            });
                        }
                    });

                } catch (final Exception e) {
                    Log.e("LOG_TAG", "Connection error.", e);
                    tvStatus.setText("Error! " + e.getMessage());
                }
            }
        });
       //publisj button
        ledbutton.setOnClickListener(new View.OnClickListener() {
            final String topic = "$aws/things/industech/shadow/update";
            final String msg = "{\"state\": {\"desired\": {\"ledBarStatus\": 1},\"reported\": {\"temperature\": 25,\"ledBarStatus\":1}}}";

            @Override
            public void onClick(View v) {
                try {
                   mqttManager.publishString(msg, topic, AWSIotMqttQos.QOS1);
                } catch (Exception e) {
                    Log.e("LOG_TAG", "Publish error.", e);
                }
            }
        });

日志:

/CognitoCachingCredentialsProvider: Loading credentials from SharedPreferences

D/CognitoCachingCredentialsProvider: Saving credentials to SharedPreferences

D/LOG_TAG: clientId = 1489081527

D/LOG_TAG: Status = Connecting

D/LOG_TAG: Status = Connected

D/LOG_TAG: Status = Reconnecting

D/LOG_TAG: Status = Connected

2 个答案:

答案 0 :(得分:0)

感谢您使用AWS IoT Device SDK。您是否能够使用您的凭据来运行AndroidPubSubSample程序,并且您是否能够成功订阅和发布消息?这是为了确保您拥有正确的凭据设置,例如正确的政策和权限。

此外,您可以订阅生命周期事件“$ aws / events /#”以查看订阅日志并发布。我可以成功地将您的JSON数据发布到$ aws / things /../更新主题,并通过硬编码主题和消息接受$ aws.things /.../ update / accepted。

如果您对使用AWS IoT Device SDK有更多疑问和问题,请随时在github repo上打开一个问题。对于Android SDK,您可以转到https://github.com/aws/aws-sdk-android

答案 1 :(得分:0)

我认为错误是因为您无法订阅某个主题。订阅使用" topicfilter"在IAM政策声明中,而发布和接收使用"主题"。示例中的策略不正确。工作IAM政策如下:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "iot:Connect"
            ],
            "Resource": [
                "*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iot:Publish",
                "iot:Receive"
            ],
            "Resource": [
                "arn:aws:iot:<your region>:<youracc>:topic/whatevertopic/*"
            ]
        },
        {
            "Effect": "Allow",
            "Action": [
                "iot:Subscribe"
            ],
            "Resource": [
                "arn:aws:iot:<your region>:<youracc>:topicfilter/whatevertopic/*"
            ]
        }
    ]
}