import android.content.SharedPreferences;
import android.os.Handler;
import android.support.annotation.Nullable;
+import android.support.annotation.StringRes;
+import android.support.v4.app.DialogFragment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.widget.TextView;
import org.eclipse.paho.android.service.MqttAndroidClient;
import org.eclipse.paho.client.mqttv3.IMqttActionListener;
private CtFwSDisplay mCdl; // set in onCreate
private CtFwSCallbacksMQTT mCtfwscbs ; // set in onCreate
+ private TextView mTvSU; // set in onCreate
+ private TextView mTvSS; // set in onCreate
+ private void setServerStateText(@StringRes final int resid) {
+ mTvSS.post(new Runnable() {
+ @Override
+ public void run() { mTvSS.setText(resid); }
+ });
+ }
+
+ // We'll use this common callback object for our subscriptions below
+ final IMqttActionListener subal = new IMqttActionListener() {
+ @Override
+ public void onSuccess(IMqttToken asyncActionToken) {
+ Log.d("CtFwS", "Sub OK: " + asyncActionToken);
+ }
+
+ @Override
+ public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
+ Log.e("CtFws", "Sub Fail: " + asyncActionToken, exception);
+ }
+ };
+
private synchronized void doMqtt(@Nullable String server) {
// Hang up on an existing connection, if we have one
synchronized (this) {
if (mMqc != null) {
- mMqc.close();
+ try { mMqc.disconnect(); } catch (MqttException me) { ; }
}
mMqc = null;
mCgs.configured = false;
}
// If that's all we were told to do, we're done
- if (server == null) { return ; }
+ if (server == null) {
+ Log.d("CtFwS", "doMqtt null");
+ mTvSU.setText(R.string.string_null);
+ return;
+ }
+ Log.d("CtFwS", "doMqtt not null:" + server);
- // We'll use this common callback object for our subscriptions below
- final IMqttActionListener subal = new IMqttActionListener() {
- @Override
- public void onSuccess(IMqttToken asyncActionToken) {
- Log.d("CtFwS", "Sub OK: " + asyncActionToken);
- }
-
- @Override
- public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
- Log.e("CtFws", "Sub Fail: " + asyncActionToken, exception);
- }
- };
+ mTvSU.setText(server);
// Make our MQTT client and grab callbacks on *everything in sight*
- final MqttAndroidClient mqc = new MqttAndroidClient(this,server, mqttClientId);
+ final MqttAndroidClient mqc = new MqttAndroidClient(this,server,mqttClientId);
mqc.setCallback(new MqttCallbackExtended() {
@Override
public void connectComplete(boolean reconnect, String serverURI) {
mqc.subscribe(p+"flags" , 2, null, subal, mCtfwscbs.onFlags);
mqc.subscribe(p+"message" , 2, null, subal, mCtfwscbs.onMessage);
mqc.subscribe(p+"message/player", 2, null, subal, mCtfwscbs.onPlayerMessage);
+ setServerStateText(R.string.mqtt_subbed);
} catch (MqttException e) {
Log.e("CtFwS", "Exn Sub", e);
}
@Override
public void connectionLost(Throwable cause) {
Log.d("CtFwS", "Conn Lost", cause);
+ setServerStateText(R.string.mqtt_disconn);
}
@Override
// react to messages sent to us. Have we lost the thread yet?
try {
MqttConnectOptions mco = new MqttConnectOptions();
+ mco.setCleanSession(true);
mco.setAutomaticReconnect(true);
mco.setKeepAliveInterval(180); // seconds
@Override
public void onSuccess(IMqttToken asyncActionToken) {
Log.d("CtFwS", "Conn OK 1");
+ setServerStateText(R.string.mqtt_conn);
+ mCdl.clearMsgs();
}
@Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
Log.e("CtFws", "Conn Fail", exception);
+ setServerStateText(R.string.mqtt_disconn);
+ mCdl.clearMsgs();
}
});
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
switch(key) {
case "server":
- doMqtt(sharedPreferences.getString("server",null));
+ String s = sharedPreferences.getString(key,null);
+ if (s != null) { doMqtt(s); }
break;
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
+ String defserver = "tcp://nwf1.xen.prgmr.com:1883";
+
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
+ mTvSU = (TextView) findViewById(R.id.tv_mqtt_server_uri);
+ mTvSS = (TextView) findViewById(R.id.tv_mqtt_state);
+
mCdl = new CtFwSDisplay(this, new Handler(), mCgs);
mCtfwscbs = new CtFwSCallbacksMQTT(mCdl, mCgs);
- // TODO There really should be a UI thing for changing the server; we're all
- // set for when-/if-ever that happens.
+ SharedPreferences sp = getPreferences(MODE_PRIVATE);
+ if (sp.getString("server", null) == null) {
+ sp.edit().putString("server", defserver).apply();
+ }
+ if (BuildConfig.DEBUG && sp.getString("server", null) == null) {
+ throw new AssertionError("Shared Preferences not sticking!");
+ }
+
+ synchronized(this) {
+ sp.registerOnSharedPreferenceChangeListener(mOSPCL);
+ doMqtt(sp.getString("server", defserver));
+ }
+ }
- getPreferences(MODE_PRIVATE).registerOnSharedPreferenceChangeListener(mOSPCL);
- doMqtt(getPreferences(MODE_PRIVATE).getString("server","tcp://nwf1.xen.prgmr.com:1883"));
+ @Override
+ public boolean onOptionsItemSelected(MenuItem mi) {
+ switch(mi.getItemId()) {
+ case R.id.menu_mqtt :
+ DialogFragment d =
+ StringSettingDialogFragment.newInstance(
+ R.layout.server_dialog, R.id.server_text, "server");
+ d.show(getSupportFragmentManager(),"serverdialog");
+ return true;
+ default:
+ return super.onOptionsItemSelected(mi);
+ }
+ }
+
+ @Override
+ public boolean onCreateOptionsMenu(Menu menu) {
+ MenuInflater mi = getMenuInflater();
+ mi.inflate(R.menu.mainmenu, menu);
+ return true;
}
}
--- /dev/null
+package com.acmetensortoys.ctfwstimer;
+
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.SharedPreferences;
+import android.os.Bundle;
+import android.support.annotation.NonNull;
+import android.support.v4.app.DialogFragment;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.TextView;
+
+public class StringSettingDialogFragment extends DialogFragment
+ implements SharedPreferences.OnSharedPreferenceChangeListener
+{
+ private final static String ARG_LRES_IX = "lres"; // layout id
+ private final static String ARG_VRES_IX = "vres"; // text view id
+ private final static String ARG_PREF_IX = "pref"; // preference name
+
+ private TextView mTv;
+
+ public static StringSettingDialogFragment newInstance(int lres, int vres, String pref) {
+ StringSettingDialogFragment ssdf = new StringSettingDialogFragment();
+ Bundle args = new Bundle();
+ args.putInt (ARG_LRES_IX, lres);
+ args.putInt (ARG_VRES_IX, vres);
+ args.putString(ARG_PREF_IX, pref);
+ ssdf.setArguments(args);
+ return ssdf;
+ }
+
+ @NonNull @Override
+ public Dialog onCreateDialog(Bundle savedInstanceState) {
+ Bundle a = getArguments();
+ AlertDialog.Builder adb = new AlertDialog.Builder(getActivity());
+ LayoutInflater li = getActivity().getLayoutInflater();
+ View v = li.inflate(a.getInt(ARG_LRES_IX), null);
+
+ mTv = (TextView)v.findViewById(a.getInt(ARG_VRES_IX));
+ final SharedPreferences sp = getActivity().getPreferences(Context.MODE_PRIVATE);
+ sp.registerOnSharedPreferenceChangeListener(this);
+ onSharedPreferenceChanged(sp,a.getString(ARG_PREF_IX));
+
+ adb.setView(v)
+ .setPositiveButton(R.string.dialog_ok, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ sp.edit().putString("server", mTv.getText().toString()).apply();
+ }
+ })
+ .setNegativeButton(R.string.dialog_cancel, new DialogInterface.OnClickListener() {
+ @Override
+ public void onClick(DialogInterface dialog, int which) {
+ // NOP
+ }
+ });
+ return adb.create();
+ }
+
+ @Override
+ public void onSharedPreferenceChanged(SharedPreferences sp, String p) {
+ if (p != null && getArguments().getString(ARG_PREF_IX).equals(p)) {
+ mTv.setText(sp.getString(p, ""));
+ }
+ }
+}
android:inputType="none"
android:ems="10"
android:id="@+id/msgs"
- android:maxLines="10"
- android:minLines="1"
+ android:lines="10"
android:scrollbars="vertical"
android:gravity="bottom" />
+
+ </LinearLayout>
+
+ <LinearLayout
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center"
+ android:text="@string/mqtt_header" />
+
+ <TableLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:stretchColumns="1">
+
+ <TableRow
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/menutext_mqtt_label"
+ android:gravity="center" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:id="@+id/tv_mqtt_server_uri"
+ android:gravity="center" />
+ </TableRow>
+
+ <TableRow
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:text="@string/mqtt_state_label"
+ android:gravity="center" />
+
+ <TextView
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:id="@+id/tv_mqtt_state"
+ android:gravity="center" />
+
+ </TableRow>
+
+ </TableLayout>
</LinearLayout>
<!--