package io.trygvis.soilmoisture; import android.app.ActionBar; import android.app.Activity; import android.app.Fragment; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.os.Bundle; import android.os.IBinder; import android.util.Log; import android.view.LayoutInflater; import android.view.Menu; import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; import io.trygvis.android.LocalBinder; import io.trygvis.android.Optional; import static io.trygvis.soilmoisture.SoilMoistureService.SoilMoistureListener; public class SensorActivity extends Activity { private final static String TAG = SensorActivity.class.getSimpleName(); public static final String EXTRA_ADDRESS = "address"; public static final String EXTRA_NUMBER = "number"; private final Context context = this; private String address; private int number; private ServiceConnection serviceConnection; private SoilMoistureService soilMoistureService; private SensorSoilMoistureListener serviceListener = new SensorSoilMoistureListener(); private SmDevice device; private SmSensor sensor; @Override protected void onCreate(Bundle savedInstanceState) { Log.d(TAG, "onCreate"); super.onCreate(savedInstanceState); setContentView(R.layout.activity_sensor); address = getIntent().getStringExtra(EXTRA_ADDRESS); number = getIntent().getIntExtra(EXTRA_NUMBER, -1); if (savedInstanceState == null) { getFragmentManager().beginTransaction() .add(R.id.container, new SensorFragment()) .commit(); } ActionBar actionBar = getActionBar(); if (actionBar != null) { actionBar.setTitle(number + ": " + address); } serviceConnection = new ServiceConnection() { @SuppressWarnings("unchecked") @Override public void onServiceConnected(ComponentName componentName, IBinder service) { Log.i(TAG, "onServiceConnected"); soilMoistureService = ((LocalBinder) service).getService(); registerReceiver(serviceListener, SoilMoistureListener.INTENT_FILTER); device = soilMoistureService.getDevice(address); Optional o = device.getSensorByNumber(number); if (!o.isPresent()) { Toast.makeText(context, "Could not find sensor #" + number + " on device " + address, Toast.LENGTH_LONG).show(); finish(); } sensor = o.get(); // Schedule an updated reading of the relevant values. refreshSensorValues(); runOnUiThread(SensorActivity.this::initializeView); } @Override public void onServiceDisconnected(ComponentName componentName) { Log.i(TAG, "onServiceDisconnected"); soilMoistureService = null; } }; bindService(new Intent(this, DefaultSoilMoistureService.class), serviceConnection, BIND_AUTO_CREATE); } @Override protected void onDestroy() { super.onDestroy(); if (serviceConnection != null) { sensor = null; device = null; unbindService(serviceConnection); } } @Override protected void onResume() { Log.i(TAG, "onResume"); super.onResume(); registerReceiver(serviceListener, SoilMoistureListener.INTENT_FILTER); } @Override protected void onPause() { Log.i(TAG, "onPause"); super.onPause(); unregisterReceiver(serviceListener); } private void refreshSensorValues() { if (sensor == null) { Log.d(TAG, "refreshSensorValues: not connected to service"); return; } sensor.readCurrentValue(); sensor.readWarningValue(); } public void initializeView() { // current value, last updated // sync to cloud } @Override public boolean onCreateOptionsMenu(Menu menu) { getMenuInflater().inflate(R.menu.menu_sensor, 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); } /** * A placeholder fragment containing a simple view. */ public static class SensorFragment extends Fragment { private SensorActivity sensorActivity; private TextView currentValue; private TextView warningValue; @Override public void onAttach(Activity activity) { Log.i(TAG, "onAttach"); super.onAttach(activity); sensorActivity = (SensorActivity) activity; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_sensor, container, false); currentValue = (TextView) rootView.findViewById(R.id.current_value); warningValue = (TextView) rootView.findViewById(R.id.warning_value); Button button = (Button) rootView.findViewById(R.id.button_refresh); button.setOnClickListener(v -> sensorActivity.refreshSensorValues()); update(); return rootView; } public void update() { SmSensor sensor = sensorActivity.sensor; if (sensor == null) { return; } Integer v = sensor.getLastValue(); currentValue.setText(v != null ? v.toString() : ""); Integer w = sensor.getWarningValue(); warningValue.setText(w != null ? w.toString() : ""); } } private class SensorSoilMoistureListener extends SoilMoistureListener { @Override public void onNewSample(String address, int sensor) { if(!address.equals(SensorActivity.this.address) || sensor != SensorActivity.this.number) { return; } SensorFragment sensorFragment = (SensorFragment) getFragmentManager().findFragmentById(R.id.container); sensorFragment.update(); } @Override public void onDevicePropertyUpdated(String address) { Log.i(TAG, "onDevicePropertyUpdated"); if (!address.equals(SensorActivity.this.address)) { return; } SensorFragment sensorFragment = (SensorFragment) getFragmentManager().findFragmentById(R.id.container); sensorFragment.update(); } } }