美好的一天,我真的需要帮助,因为这是一个令人头痛的问题。代码看起来很好但是当我点击订阅按钮时,应用程序将崩溃。
这是我的机器人清单:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.generalsteinacoz.realmqttclient" >
<uses-permission android:name="android.permission.INTERNET">
</uses-permission>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".FirstActivity"
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=".MQTTService"/>
</application>
</manifest>
这是主Activity(即UI)的代码
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import com.example.generalsteinacoz.realmqttclient.MQTTService;
public class FirstActivity extends Activity {
EditText edt_host, edt_port, editTopicSub;
TextView txt_message;
Button btnSub;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_first);
edt_host = (EditText) findViewById(R.id.edt_host);
edt_port = (EditText) findViewById(R.id.edt_port);
editTopicSub = (EditText) findViewById(R.id.edt_sub);
btnSub = (Button) findViewById(R.id.btnSave_sub);
txt_message = (TextView) findViewById(R.id.txt_messageBody);
onClick_Btn_Sub();
}
public void getMessage(String mess){
txt_message.setText(mess);
}
public String setTopic(){
String mainTopic = editTopicSub.getText().toString();
return mainTopic;
}
public String setbrokerPort(){
String mainBrokerPort = edt_host.getText()+":"+ edt_port.getText().toString();
return mainBrokerPort;
}
public void onClick_Btn_Sub(){
btnSub.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startService(new Intent("MQTTService"));
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_first, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
这是服务类的代码
import org.eclipse.paho.client.mqttv3.IMqttAsyncClient;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.IMqttToken;
import org.eclipse.paho.client.mqttv3.MqttAsyncClient;
import org.eclipse.paho.client.mqttv3.MqttCallback;
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;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import com.example.generalsteinacoz.realmqttclient.FirstActivity;
import android.annotation.SuppressLint;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.res.Configuration;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Binder;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
public class MQTTService extends Service {
FirstActivity fa = new FirstActivity();
private static final String TAG = "MQTTService";
private static boolean hasWifi = false;
private static boolean hasMmobile = false;
private Thread thread;
private ConnectivityManager mConnMan;
private volatile IMqttAsyncClient mqttClient;
private String deviceId;
class MQTTBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
IMqttToken token;
boolean hasConnectivity = false;
boolean hasChanged = false;
NetworkInfo infos[] = mConnMan.getAllNetworkInfo();
for (int i = 0; i < infos.length; i++){
if (infos[i].getTypeName().equalsIgnoreCase("MOBILE")){
if((infos[i].isConnected() != hasMmobile)){
hasChanged = true;
hasMmobile = infos[i].isConnected();
}
Log.d(TAG, infos[i].getTypeName() + " is " + infos[i].isConnected());
} else if ( infos[i].getTypeName().equalsIgnoreCase("WIFI") ){
if((infos[i].isConnected() != hasWifi)){
hasChanged = true;
hasWifi = infos[i].isConnected();
}
Log.d(TAG, infos[i].getTypeName() + " is " + infos[i].isConnected());
}
}
hasConnectivity = hasMmobile || hasWifi;
Log.v(TAG, "hasConn: " + hasConnectivity + " hasChange: " + hasChanged + " - "+(mqttClient == null || !mqttClient.isConnected()));
if (hasConnectivity && hasChanged && (mqttClient == null || !mqttClient.isConnected())) {
doConnect();
} else if (!hasConnectivity && mqttClient != null && mqttClient.isConnected()) {
Log.d(TAG, "doDisconnect()");
try {
token = mqttClient.disconnect();
token.waitForCompletion(1000);
} catch (MqttException e) {
e.printStackTrace();
}
}
}
};
public class MQTTBinder extends Binder {
public MQTTService getService(){
return MQTTService.this;
}
}
@Override
public void onCreate() {
IntentFilter intentf = new IntentFilter();
setClientID();
intentf.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(new MQTTBroadcastReceiver(), new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
mConnMan = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
}
@Override
public void onConfigurationChanged(Configuration newConfig) {
Log.d(TAG, "onConfigurationChanged()");
android.os.Debug.waitForDebugger();
super.onConfigurationChanged(newConfig);
}
private void setClientID(){
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiInfo wInfo = wifiManager.getConnectionInfo();
deviceId = wInfo.getMacAddress();
if(deviceId == null){
deviceId = MqttAsyncClient.generateClientId();
}
}
private void doConnect(){
Log.d(TAG, "doConnect()");
IMqttToken token;
MqttConnectOptions options = new MqttConnectOptions();
options.setCleanSession(true);
try {
// mqttClient = new MqttAsyncClient(fa.setbrokerPort(), deviceId, new MemoryPersistence());
mqttClient = new MqttAsyncClient("tcp://iot.eclipse.org:1883", deviceId, new MemoryPersistence());
token = mqttClient.connect();
token.waitForCompletion(3500);
mqttClient.setCallback(new MqttEventCallback());
token = mqttClient.subscribe("#", 0);
//token = mqttClient.subscribe(fa.setTopic(), 0);
token.waitForCompletion(5000);
} catch (MqttSecurityException e) {
e.printStackTrace();
} catch (MqttException e) {
switch (e.getReasonCode()) {
case MqttException.REASON_CODE_BROKER_UNAVAILABLE:
case MqttException.REASON_CODE_CLIENT_TIMEOUT:
case MqttException.REASON_CODE_CONNECTION_LOST:
case MqttException.REASON_CODE_SERVER_CONNECT_ERROR:
Log.v(TAG, "c" +e.getMessage());
e.printStackTrace();
break;
case MqttException.REASON_CODE_FAILED_AUTHENTICATION:
Intent i = new Intent("RAISEALLARM");
i.putExtra("ALLARM", e);
Log.e(TAG, "b"+ e.getMessage());
break;
default:
Log.e(TAG, "a" + e.getMessage());
}
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.v(TAG, "onStartCommand()");
return START_STICKY;
}
private class MqttEventCallback implements MqttCallback {
@Override
public void connectionLost(Throwable arg0) {
}
@Override
public void deliveryComplete(IMqttDeliveryToken arg0) {
}
@Override
@SuppressLint("NewApi")
public void messageArrived(String topic, final MqttMessage msg) throws Exception {
Log.i(TAG, "Message arrived from topic" + topic);
Handler h = new Handler(getMainLooper());
h.post(new Runnable() {
@Override
public void run() {
Intent launchA = new Intent(MQTTService.this, FirstActivity.class);
launchA.putExtra("message", msg.getPayload());
//TODO write somethinkg that has some sense
if(Build.VERSION.SDK_INT >= 11){
launchA.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK|Intent.FLAG_ACTIVITY_REORDER_TO_F RONT|Intent.FLAG_ACTIVITY_NO_ANIMATION);
} /*else {
launchA.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}*/
startActivity(launchA);
Toast.makeText(getApplicationContext(), "MQTT Message:\n" + new String(msg.getPayload()), Toast.LENGTH_SHORT).show();
fa.getMessage(msg.getPayload().toString());
}
});
}
}
public String getThread(){
return Long.valueOf(thread.getId()).toString();
}
@Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "onBind called");
return null;
}
}