app.wz.MainActivity.java Source code

Java tutorial

Introduction

Here is the source code for app.wz.MainActivity.java

Source

/*
 * Copyright (C) 2014 Akexorcist
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package app.wz;

import android.app.Activity;
import android.app.AlertDialog;
import android.bluetooth.BluetoothAdapter;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.PowerManager;
import android.preference.PreferenceManager;
import android.text.Html;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ScrollView;
import android.widget.TextView;
import android.widget.Toast;

import app.akexorcist.bluetoothspp.BluetoothSPP;
import app.akexorcist.bluetoothspp.BluetoothState;
import app.akexorcist.bluetoothspp.DeviceList;
import app.akexorcist.bluetoothspp.BluetoothSPP.BluetoothConnectionListener;
import app.akexorcist.bluetoothspp.BluetoothSPP.OnDataReceivedListener;
import app.akexorcist.bluetoothspp.BluetoothSPP.AutoConnectionListener;
import app.akexorcist.bluetoothspp.BluetoothSPP.BluetoothConnectionListener;

import org.json.JSONException;
import org.json.JSONObject;
import org.shokai.firmata.ArduinoFirmata;

import java.text.DecimalFormat;

public class MainActivity extends Activity implements SensorEventListener {
    // device sensor manager
    private SensorManager mSensorManager;

    PowerManager powerManager;
    PowerManager.WakeLock wakeLock;

    WifiManager wifiManager;
    WifiManager.WifiLock lock;

    GlobalApp gb;
    SharedPreferences prefs;
    BluetoothSPP bt;
    ArduinoFirmata arduino;
    NeuroInterface neuro;

    ScrollView textScroll;
    TextView commStatus, pingStatus, textRead;
    EditText inputCmd, inputVal;

    MainActivity self;

    Menu menu;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        self = this;

        requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
        setProgressBarIndeterminateVisibility(false);

        setContentView(R.layout.layout_main);

        // initialize your android device sensor capabilities
        mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);

        powerManager = (PowerManager) getSystemService(POWER_SERVICE);
        wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "MyWakelockTag");

        wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
        lock = wifiManager.createWifiLock(WifiManager.WIFI_MODE_FULL, "LockTag");

        prefs = PreferenceManager.getDefaultSharedPreferences(this.getApplicationContext());

        textScroll = (ScrollView) findViewById(R.id.textScroll);
        textRead = (TextView) findViewById(R.id.textRead);

        commStatus = (TextView) findViewById(R.id.commStatus);
        pingStatus = (TextView) findViewById(R.id.pingStatus);
        inputCmd = (EditText) findViewById(R.id.inputCmd);
        inputVal = (EditText) findViewById(R.id.inputVal);

        gb = (GlobalApp) getApplication();

        gb.bt = new BluetoothSPP(this);
        bt = gb.bt;
        gb.arduino = new ArduinoFirmata(this, bt);
        arduino = gb.arduino;

        gb.neuro = new NeuroInterface(prefs, gb);

        neuro = gb.neuro;

        if (prefs.getBoolean("autoload", false)) {
            if (neuro.loadWeights(prefs.getString("last_save", ""))) {
                textRead.append("Restored Weights at Step " + neuro.count + "\n");
                textScroll.fullScroll(View.FOCUS_DOWN);
            }
        }

        if (!bt.isBluetoothAvailable()) {
            Toast.makeText(getApplicationContext(), "Bluetooth is not available", Toast.LENGTH_SHORT).show();
            finish();
        }

        bt.setOnDataReceivedListener(new OnDataReceivedListener() {
            public void onDataReceived(byte[] data, String message) {
                gb.lastResponseBT = System.currentTimeMillis();
                arduino.processInput(data);
            }
        });

        bt.setBluetoothConnectionListener(new BluetoothConnectionListener() {
            public void onDeviceDisconnected() {

                haltNeuro();

                commStatus.setText("Status : Not Connected");
                menu.clear();
                getMenuInflater().inflate(R.menu.connection, menu);
            }

            public void onDeviceConnectionFailed() {
                commStatus.setText("Status : Connection Failed");
            }

            public void onDeviceConnected(String name, String address) {
                commStatus.setText("Status : Connected to " + name);
                menu.clear();
                getMenuInflater().inflate(R.menu.disconnection, menu);
            }
        });

        //        bt.setAutoConnectionListener(new BluetoothSPP.AutoConnectionListener() {
        //            public void onNewConnection(String name, String address) {
        //                Log.i("Check", "New Connection - " + name + " - " + address);
        //            }
        //
        //            public void onAutoConnectionStarted() {
        //                Log.i("Check", "Auto connection started");
        //            }
        //        });

        if (!bt.isBluetoothEnabled()) {
            Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(intent, BluetoothState.REQUEST_ENABLE_BT);
        } else {
            if (!bt.isServiceAvailable()) {
                bt.setupService();
                bt.startService(BluetoothState.DEVICE_ANDROID);
                setup();
            }
        }

        refreshPing.start();
        neuroThread.start();

        new Thread() {
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    if (neuro.count > neuro.lastDisplay) {
                        neuro.lastDisplay = neuro.count;
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                if (!neuro.halt) {
                                    textRead.append(
                                            "P err:  " + (new DecimalFormat("0.000E0")).format(neuro.avg_error)
                                                    + "    O err:  "
                                                    + (new DecimalFormat("0.000E0")).format(neuro.avg_obj_error)
                                                    + "    stp:  " + neuro.count + "\n");

                                    textScroll.fullScroll(View.FOCUS_DOWN);
                                }
                            }
                        });
                    }
                }
            }
        }.start();

        new Thread() {
            public void run() {
                while (true) {
                    try {
                        Thread.sleep(10000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            if (textRead.length() > 20000)
                                textRead.setText("");
                        }
                    });
                }
            }
        }.start();

    }

    //    protected void onStart() {
    //        super.onStart();
    //        Handler handler = new Handler();
    //        handler.postDelayed(new Runnable() {
    //            @Override
    //            public void run() {
    //
    //                String adr = prefs.getString("lastBT", null);
    //
    //                //bt.autoConnect("wzPod");
    //                if(adr != null) {
    //                    //bt.connect(adr);
    //                }
    //            }
    //        }, 5000); // 5000ms delay
    //    }

    public boolean onCreateOptionsMenu(Menu menu) {
        this.menu = menu;
        getMenuInflater().inflate(R.menu.connection, menu);
        return true;
    }

    public boolean onOptionsItemSelected(MenuItem item) {
        int id = item.getItemId();

        if (id == R.id.menu_run_pause) {
            if (neuro.halt) {
                neuro.halt = false;
                setProgressBarIndeterminateVisibility(true);

                wakeLock.acquire();

                if (prefs.getBoolean("use_server", false))
                    lock.acquire();

                // for the system's orientation sensor registered listeners
                mSensorManager.registerListener(this, mSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION),
                        SensorManager.SENSOR_DELAY_GAME);

                synchronized (neuro) {
                    neuro.notify();
                }
            } else {

                haltNeuro();
            }
        } else {
            if (!neuro.halt) {
                haltNeuro();
            }
        }

        if (id == R.id.menu_device_connect) {
            bt.setDeviceTarget(BluetoothState.DEVICE_OTHER);
            /*
            if(bt.getServiceState() == BluetoothState.STATE_CONNECTED)
             bt.disconnect();*/
            Intent intent = new Intent(getApplicationContext(), DeviceList.class);
            startActivityForResult(intent, BluetoothState.REQUEST_CONNECT_DEVICE);
        } else if (id == R.id.reset_Neuro) {
            neuro.updatePrefs(true);
            textRead.append("Reset Neuro \n");
            textScroll.fullScroll(View.FOCUS_DOWN);
        } else if (id == R.id.menu_disconnect) {
            if (bt.getServiceState() == BluetoothState.STATE_CONNECTED)
                bt.disconnect();
        } else if (id == R.id.remote_control) {
            if (bt.getServiceState() == BluetoothState.STATE_CONNECTED) {
                Intent intent = new Intent(this, JoystickActivity.class);
                startActivity(intent);
            } else {
                Toast.makeText(getApplicationContext(), "Not Connected", Toast.LENGTH_SHORT).show();
            }
            return true;
        } else if (id == R.id.action_settings) {
            Intent intent = new Intent(this, SettingsActivity.class);
            startActivity(intent);
            return true;
        } else if (id == R.id.help) {
            LayoutInflater li = LayoutInflater.from(this);
            View view = li.inflate(R.layout.help, null);
            AlertDialog.Builder alert = new AlertDialog.Builder(this);
            alert.setView(view);
            alert.show();
        }
        return super.onOptionsItemSelected(item);
    }

    public void onDestroy() {
        super.onDestroy();
        bt.stopService();
    }

    public void setup() {
        Button btnSend = (Button) findViewById(R.id.btnSend);
        btnSend.setOnClickListener(new OnClickListener() {
            public void onClick(View v) {
                if (bt.getServiceState() == BluetoothState.STATE_CONNECTED && (inputCmd.getText().length() != 0)
                        && (inputVal.getText().length() != 0)) {
                    int cmd = Integer.parseInt(inputCmd.getText().toString());
                    int val = Integer.parseInt(inputVal.getText().toString());
                    arduino.analogWrite(cmd, val);
                    textRead.append("Sent Cmd:" + cmd + " Val:" + val + "\n");
                    textScroll.fullScroll(View.FOCUS_DOWN);
                } else {
                    Toast.makeText(getApplicationContext(), "Not Connected", Toast.LENGTH_SHORT).show();
                }
            }
        });
    }

    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode == BluetoothState.REQUEST_CONNECT_DEVICE) {
            if (resultCode == Activity.RESULT_OK) {
                commStatus.setText("Status : Connecting ... ");
                prefs.edit().putString("lastBT", data.getExtras().getString(BluetoothState.EXTRA_DEVICE_ADDRESS))
                        .commit();
                bt.connect(data);
                String adr = prefs.getString("lastBT", null);
                //
                //                if(adr != null) {
                //                    bt.connect(adr);
                //                }
            }

        } else if (requestCode == BluetoothState.REQUEST_ENABLE_BT) {
            if (resultCode == Activity.RESULT_OK) {
                bt.setupService();
                bt.startService(BluetoothState.DEVICE_ANDROID);
                setup();
            } else {
                Toast.makeText(getApplicationContext(), "Bluetooth was not enabled.", Toast.LENGTH_SHORT).show();
                finish();
            }
        }
    }

    @Override
    public void onResume() {
        super.onResume(); // Always call the superclass method first

        if (neuro.updatePrefs(false)) {
            textRead.append("Reset Neuro \n");
            textScroll.fullScroll(View.FOCUS_DOWN);
        }
    }

    Thread refreshPing = new Thread() {
        @Override
        public void run() {
            try {
                while (true) {
                    sleep(50);
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            if (bt.getServiceState() == BluetoothState.STATE_CONNECTED) {
                                int distance = arduino.analogRead(arduino.PING_REG);
                                if (System.currentTimeMillis() - gb.lastResponseBT > 200) {
                                    pingStatus.setText("Ping: No Response");
                                    haltNeuro();
                                } else {
                                    if (distance != 0) {
                                        final double decay = 0.3;
                                        neuro.pingDistance = (1 - decay) * neuro.pingDistance + decay * distance;
                                        pingStatus.setText("Ping: "
                                                + (new DecimalFormat("#")).format(neuro.pingDistance) + "cm");
                                    } else
                                        pingStatus.setText("Ping: >150cm");
                                }
                            } else {
                                pingStatus.setText("");
                            }
                        }
                    });
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    };

    Thread neuroThread = new Thread() {
        @Override
        public void run() {

            while (true) {

                synchronized (neuro) {
                    if (neuro.halt) {
                        try {
                            neuro.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }

                Log.i("main", Integer.toString(neuro.count));

                neuro.lastcount = neuro.count;

                boolean loopError;
                if (neuro.avg_error > Double.parseDouble(prefs.getString("error_threshold", "0.05")))
                    loopError = !neuro.explore();
                else
                    loopError = !neuro.advanceObjective();

                if (loopError && !neuro.halt) {
                    if (neuro.serverError != null) {
                        runOnUiThread(new Runnable() {
                            public void run() {
                                textRead.append("Server: " + neuro.serverError + "\n");
                                textScroll.fullScroll(View.FOCUS_DOWN);

                                if (!isNetworkConnected()) {
                                    textRead.append("No Network Connection\n");
                                    textScroll.fullScroll(View.FOCUS_DOWN);
                                    haltNeuro();
                                }
                            }
                        });
                    }
                } else {
                    if (neuro.count > neuro.lastcount) {
                        if (prefs.getBoolean("autosave", true) && neuro.count % 200 == 0 && neuro.count > 0)
                            neuro.saveWeights();

                        if (prefs.getBoolean("use_server", false)) {
                            JSONObject jsonObjSend = new JSONObject();

                            try {
                                // Add key/value pairs
                                jsonObjSend.put("iteration", neuro.count);
                                jsonObjSend.put("p_error", neuro.p_error);
                                jsonObjSend.put("o_error", neuro.o_error);
                                jsonObjSend.put("state", neuro.state);
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }

                            //Log.d("check","send JSON" );
                            // Send the HttpPostRequest and receive a JSONObject in return
                            String jsonObjRecv = HttpClient.SendHttpPost(
                                    prefs.getString("outputURL", getString(R.string.default_server_url)) + "/"
                                            + prefs.getString("ID", null) + "/error",
                                    jsonObjSend);

                            //Log.d("check",jsonObjRecv);
                        }
                    }
                    if (prefs.getBoolean("use_server", false)) {
                        try {
                            Thread.sleep(Integer.parseInt(prefs.getString("lag_delay", "0")));
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                }
            }
        }
    };

    public void onSensorChanged(SensorEvent event) {
        neuro.heading = event.values[0];
    }

    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        // not in use
    }

    private boolean isNetworkConnected() {
        ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo ni = cm.getActiveNetworkInfo();
        return (cm.getActiveNetworkInfo() != null);
    }

    public void haltNeuro() {

        setProgressBarIndeterminateVisibility(false);

        if (wakeLock.isHeld())
            wakeLock.release();
        if (lock.isHeld())
            lock.release();

        if (!neuro.halt) {
            neuro.halt = true;

            // to stop the listener and save battery
            mSensorManager.unregisterListener(self);

            textRead.append("Paused Neuro\n");
            textScroll.fullScroll(View.FOCUS_DOWN);
        }
    }
}