简体   繁体   English

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

[英]Using Android To Publish MQTT Messages on AWS IoT Services

I am trying to publish a mqtt message using AWSIotMqttManager with amazon web services IoT on an android app, i have follow used this example as a base to my code. 我试图在Android应用程序上使用AWSIotMqttManager和amazon web服务IoT发布mqtt消息,我已经按照这个例子作为我的代码的基础。 The app says it can successfully connect to the device but fails to actually publish a message, what is wrong here? 该应用程序说它可以成功连接到设备但无法实际发布消息,这里有什么问题?

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

The Log: 日志:

/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

Thanks for using AWS IoT Device SDK. 感谢您使用AWS IoT Device SDK。 Are you able to use your credentials to run the AndroidPubSubSample program and are you able to successfully subscribe and publish messages? 您是否能够使用您的凭据来运行AndroidPubSubSample程序,并且您是否能够成功订阅和发布消息? This is to make sure you have the right credentials setup eg correct Policies and permissions attached. 这是为了确保您拥有正确的凭据设置,例如正确的策略和权限。

In addition, you can subscribe to life cycle events "$aws/events/#" to see the log of your subscription and publish. 此外,您可以订阅生命周期事件“$ aws / events /#”以查看订阅日志并发布。 I could successfully publish your JSON data to $aws/things/../update topics and got accepted on $aws.things/.../update/accepted by hardcoding topic and message. 我可以成功地将您的JSON数据发布到$ aws / things /../更新主题,并通过硬编码主题和消息接受$ aws.things /.../ update / accepted。

If you have more questions and issues about using AWS IoT Device SDK, feel free to open an issue on the github repo. 如果您对使用AWS IoT Device SDK有更多疑问和问题,请随时在github repo上打开一个问题。 For Android SDK specifically, you can go to https://github.com/aws/aws-sdk-android 对于Android SDK,您可以访问https://github.com/aws/aws-sdk-android

I believe the error is because you couldn't subscribe to a topic. 我认为错误是因为您无法订阅主题。 Subscribe uses "topicfilter" in the IAM Policy statement whereas Publish and Receive uses "topic". 订阅在IAM策略语句中使用“topicfilter”,而Publish and Receive使用“topic”。 The policy in the example is incorrect. 示例中的策略不正确。 The working IAM Policy is as follows: 工作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/*"
            ]
        }
    ]
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM