Android Open Source - nxt-remote-controller Controller Activity






From Project

Back to project page nxt-remote-controller.

License

The source code is released under:

MIT License

If you think the Android project nxt-remote-controller listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *  Copyright (c) 2014 EgaTuts & Esa Garca - All Rights Reserved                 *
 *                                                                                 *
 *  Open-source code licensed under the MIT License (the "License").               *
 *                                                                                 *
 *  Permission is hereby granted, free of charge, to any person obtaining a copy   *
 *  of this software and associated documentation files (the "Software"), to deal  *
 *  in the Software without restriction, including without limitation the rights   *
 *  to use, copy, modify, merge, publish, distribute, sublicense, and/or sell      *
 *  copies of the Software, and to permit persons to whom the Software is          *
 *  furnished to do so, subject to the following conditions:                       *
 *                                                                                 *
 *  The above copyright notice and this permission notice shall be included in     *
 *  all copies or substantial portions of the Software.                            *
 *                                                                                 *
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR     *
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,       *
 *  FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL THE    *
 *  AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER         *
 *  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,  *
 *  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN      *
 *  THE SOFTWARE.                                                                  *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
//w ww .  j av  a 2s  . c  o  m
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
 *  You can find the entire project at:                                                                                                                              *
 *                                                                                                                                                                   *
 *    https://github.com/Egatuts/nxt-remote-controller                                                                                                               *
 *                                                                                                                                                                   *
 *  And the corresponding file at:                                                                                                                                   *
 *                                                                                                                                                                   *
 *    https://github.com/Egatuts/nxt-remote-controller/blob/master/Android%20App/app/src/main/java/git/egatuts/nxtremotecontroller/activity/ControllerActivity.java  *
 * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
package git.egatuts.nxtremotecontroller.activity;

import android.app.AlertDialog;
import android.bluetooth.BluetoothSocket;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.res.ColorStateList;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Shader;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.PaintDrawable;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.StateListDrawable;
import android.graphics.drawable.shapes.RectShape;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.FragmentTabHost;
import android.support.v7.widget.Toolbar;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.TabHost;
import android.widget.TextView;

import java.io.IOError;
import java.io.IOException;

import git.egatuts.nxtremotecontroller.GlobalUtils;
import git.egatuts.nxtremotecontroller.R;
import git.egatuts.nxtremotecontroller.bluetooth.NXTConnector;
import git.egatuts.nxtremotecontroller.device.PairedDevice;
import git.egatuts.nxtremotecontroller.fragment.LocalControllerFragment;
import git.egatuts.nxtremotecontroller.fragment.OnlineControllerFragment;
import git.egatuts.nxtremotecontroller.views.BaseIndeterminateProgressDialog;

/*
 *  Main activity that is created to handle a BluetoothSocket and control locally and remotely the NXT robot.
 *  Uses the TabHost and TabWidget APIs and gets some theme attributes to customize
 *  the appearance of the tabs, because drawables can't access theme attributes :(
 */
public class ControllerActivity extends BaseActivity implements ActivityPendingTransition {

  private PairedDevice device;
  private PaintDrawable tabSelected;
  private PaintDrawable tabSelectedAndPressed;
  private FragmentTabHost tabHost;
  private StateListDrawable tabDrawableList;
  private ColorStateList tabColorList;
  private NXTConnector connector;
  private Handler handler;
  private AlertDialog.Builder builder;
  private boolean firstTime = true;
  private boolean aborted;

  /*
   *  Getter and setter for the NXTConnector.
   */
  public void setConnector (NXTConnector connector) {
    this.connector = connector;
  }

  public NXTConnector getConnector () {
    return this.connector;
  }

  /*
   *  This method returns the view of a new tab using the backgrounds created in the onCreate method.
   */
  public View createTabView (Context context, int resId, String text) {
    View view = LayoutInflater.from(context).inflate(resId, null);
    TextView title = (TextView) view.findViewById(R.id.tab_title);
    title.setText(text);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
      title.setBackground(this.tabDrawableList.getConstantState().newDrawable());
    } else {
      title.setBackgroundDrawable(this.tabDrawableList.getConstantState().newDrawable());
    }
    title.setTextColor(this.tabColorList);
    return view;
  }

  public View createTabView (Context context, int resId, int text) {
    return this.createTabView(context, resId, this.getGlobalUtils().getStringResource(text));
  }

  public View createTabView (int resId, String text) {
    return this.createTabView(this, resId, text);
  }

  public View createTabView (int resId, int text) {
    return this.createTabView(this, resId, text);
  }

  /*
   *  Method used to add a tab view and add it to the tab host.
   */
  public void addTab (FragmentTabHost tabHost, View tabView, String spec, Class<?> defClass) {
    TabHost.TabSpec tabSpec = tabHost.newTabSpec(spec).setIndicator(tabView);
    tabHost.addTab(tabSpec, defClass, null);
  }

  public void addTab (FragmentTabHost tabHost, View tabView, int resId, Class<?> defClass) {
    this.addTab(tabHost, tabView, this.getGlobalUtils().getStringResource(resId), defClass);
  }

  public void addTab (View tabView, String spec, Class<?> defClass) {
    this.addTab(this.tabHost, tabView, spec, defClass);
  }

  public void addTab (View tabView, int resId, Class<?> defClass) {
    this.addTab(this.tabHost, tabView, resId, defClass);
  }

  /*
   *  We set the backward transition.
   */
  @Override
  public int[] onForward (Intent intent) {
    return new int[] {};
  }

  @Override
  public int[] onBackward () {
    return new int[] { R.anim.controller_transition_back_in, R.anim.controller_transition_back_out };
  }

  /*
   *  We enable support for our custom transitions.
   */
  @Override
  public void finish () {
    super.finish(this);
  }

  /*
   *  We kill the threads on back press.
   */
  @Override
  public void onBackPressed () {
    this.connector.closeAllThreads();
    super.onBackPressed();
  }

  /*
   *  We close the socket on destroy.
   */
  @Override
  public void onDestroy () {
    BluetoothSocket socket = this.connector.getSocket();
    if (socket != null) {
      try {
        this.connector.getSocket().close();
      } catch (IOException e) {
        e.printStackTrace();
      }
    }
    super.onDestroy();
  }

  /*
   *  When the activity is created we enable the toolbar and the TabHost.
   */
  @Override
  public void onCreate (Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    super.setActiveTheme(super.getPreferenceTheme());
    super.setContentView(R.layout.controller_layout);
    toolbar = (Toolbar) this.findViewById(R.id.toolbar);
    super.setSupportToolbar();
    toolbar.setNavigationOnClickListener(new View.OnClickListener() {
      @Override
      public void onClick (View v) {
        ControllerActivity.this.onBackPressed();
      }
    });

    /*
     *  We get the device from the extra data of the intent.
     */
    this.device = this.getIntent().getParcelableExtra("device");

    /*
     *  We create the final variables we will use in the listeners, etc.
     */
    final ControllerActivity self = this;
    final GlobalUtils utils = this.getGlobalUtils();

    /*
     *  We create the AlertDialog.Builder we will show to ask the user to reconnect with the device.
     */
    this.builder = utils.createAlertDialog(
            utils.getStringResource(R.string.connecting_reconnect_title),
            utils.format(R.string.connecting_reconnect_message, this.device.getName())
    ).setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() {
      @Override
      public void onClick (DialogInterface dialog, int which) {
        self.finish();
      }
    }).setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() {
      @Override
      public void onClick (DialogInterface dialog, int which) {
        self.resume();
      }
    });

    /*
     *  Now we define the progress dialog we will show while we are connecting with the device.
     *  When the progress dialog has been cancelled it means the connection process has been cancelled.
     *  But on dismiss we have to check if the connection failed or it succeed.
     */
    this.progressDialog = this.getLongProgressDialog();
    this.progressDialog.setOnCancelListener(new DialogInterface.OnCancelListener() {
      @Override
      public void onCancel (DialogInterface dialog) {
        self.aborted = true;
        utils.showToast(R.string.connecting_aborted);
        self.connector.closeConnectThread();
        self.finish();
      }
    });

    /*
     *  Now we declare the handler that will handle (so obviously) the messages
     *  sent by the threads that are in the background connecting with the device.
     */
    this.handler = new Handler () {
      @Override
      public void handleMessage (Message msg) {
        if ((self.connector.getConnectThread() == null || self.aborted) && self.connector.getConnectedThread() == null) {
          return;
        }
        int category = msg.what;
        int state;
        int error;
        if (category == NXTConnector.WHAT_CHANGE_STATE) {
          progressDialog.show();
          state = msg.arg1;
          error = msg.arg2;
          if (NXTConnector.isPreparingConnection(state)) {
            progressDialog.setText(R.string.connecting_preparing_connection);
          } else if (NXTConnector.isCreatingSocket(state)) {
            progressDialog.setText(R.string.connecting_creating_socket);
          } else if (NXTConnector.isConnecting(state)) {
            progressDialog.setText(R.string.connecting_connecting);
          } else if (NXTConnector.isConnected(state)) {
            progressDialog.dismiss();
            utils.showToast(R.string.connecting_connected, device.getName());
            self.connected();
          }
        } else if (category == NXTConnector.WHAT_ERROR_ENCOUNTERED) {
          progressDialog.dismiss();
          self.connector.closeAllThreads();
          error = msg.arg1;
          state = msg.arg2;
          boolean notReconnect = false;
          if (NXTConnector.connectionClosed(state, error)) {
            utils.showToast(R.string.connecting_connection_closed);
            notReconnect = true;
            ControllerActivity.this.finish();
          } else if (NXTConnector.connectionLost(state, error)) {
            utils.showToast(R.string.connecting_connection_lost);
            if (!self.connector.getBluetoothUtils().isEnabled()) {
              notReconnect = true;
              ControllerActivity.this.finish();
            }
          } else if (NXTConnector.connectionSocketFailed(state, error)) {
            utils.showToast(R.string.connecting_socket_error);
          } else if (NXTConnector.connectionRequestFailed(state, error)) {
            utils.showToast(R.string.connecting_request_failed);
          } else if (NXTConnector.connectionUnexpectedFailed(state, error)) {
            utils.showToast(R.string.connecting_unexpected_error);
          }
          if (!notReconnect) {
            self.builder.show();
          }
        }
      }
    };

    /*
     *  Now we create the connector with the device and the handler
     *  which we will use to connect and send messages to the robot.
     */
    this.connector = new NXTConnector(this, this.device, this.handler);

    /*
     *  We set the title with the device name.
     */
    String title = utils.getStringResource(R.string.controller_window_title);
    this.setTitle(title + this.device.getName());

    /*
     *  We set the colors we will use with the drawables used in the tabs.
     */
    final int underlineColor = utils.getAttribute(R.attr.toolbar_color);
    final int backgroundColor = utils.getAttribute(R.attr.toolbar_background);
    final int lightBackgroundColor = GlobalUtils.mixColors(backgroundColor, 0x55FFFFFF);

    /*
     *  Now we create the drawables used in all the states of the tabs and then we assign
     *  them to a StateListDrawable to add it to the tabs.
     */
    ShapeDrawable.ShaderFactory tabSelectedFactory = new ShapeDrawable.ShaderFactory() {
      @Override
      public Shader resize (int width, int height) {
        return new LinearGradient(
                0, 0,       /* Origin of the background (top left corner) */
                0, height,  /* End of the background (bottom left corner) */
                new int[] {
                        backgroundColor, backgroundColor,  /* The first gradient doesn't change color so it's like a rectangle shape */
                        underlineColor, underlineColor     /* The same for the second one */
                },
                new float[] {
                        0, 51f / 55f,  /* The first background covers 51dp out of 55dp */
                        51f / 55f, 1   /* And the second one takes the rest of the space */
                },
                Shader.TileMode.REPEAT  /* The repeat mode doesn't mind but this would look prettier in case of error */
        );
      }
    };
    PaintDrawable tabSel = new PaintDrawable();
    tabSel.setShape(new RectShape());
    tabSel.setShaderFactory(tabSelectedFactory);

    ShapeDrawable.ShaderFactory tabSelectedAndPressedFactory = new ShapeDrawable.ShaderFactory() {
      @Override
      public Shader resize (int width, int height) {
        return new LinearGradient(
                0, 0,       /* Origin of the background (top left corner) */
                0, height,  /* End of the background (bottom left corner) */
                new int[]{
                        lightBackgroundColor, lightBackgroundColor,  /* The first gradient doesn't change color so it's like a rectangle shape */
                        underlineColor, underlineColor               /* The same for the second one */
                },
                new float[]{
                        0, 51f / 55f,  /* The first background covers 51dp out of 55dp */
                        51f / 55f, 1   /* And the second one takes the rest of the space */
                },
                Shader.TileMode.REPEAT  /* The repeat mode doesn't mind but this would look prettier in case of error */
        );
      }
    };
    PaintDrawable tabSelAndPress = new PaintDrawable();
    tabSelAndPress.setShape(new RectShape());
    tabSelAndPress.setShaderFactory(tabSelectedAndPressedFactory);

    /*
     *  Now we create the states lists for the drawables and the colors.
     */
    StateListDrawable drawableList = new StateListDrawable();
    drawableList.addState(new int[] { -android.R.attr.state_selected, android.R.attr.state_pressed }, new ColorDrawable(lightBackgroundColor));
    drawableList.addState(new int[] { -android.R.attr.state_selected, android.R.attr.state_pressed, android.R.attr.state_focused }, new ColorDrawable(lightBackgroundColor));
    drawableList.addState(new int[] { android.R.attr.state_selected, -android.R.attr.state_pressed }, tabSel);
    drawableList.addState(new int[] { android.R.attr.state_selected, -android.R.attr.state_pressed, -android.R.attr.state_focused }, tabSel);
    drawableList.addState(new int[] { android.R.attr.state_selected, android.R.attr.state_pressed }, tabSelAndPress);
    drawableList.addState(new int[] { android.R.attr.state_selected, android.R.attr.state_pressed, android.R.attr.state_focused }, tabSelAndPress);
    drawableList.addState(new int[] {}, new ColorDrawable(backgroundColor));

    int darkColor = utils.getAttribute(R.attr.toolbar_color);
    int lightColor = Color.argb(0xAA, Color.red(darkColor), Color.green(darkColor), Color.blue(darkColor));
    int[][] states = new int[][]{
            new int[] { -android.R.attr.state_selected, android.R.attr.state_pressed },
            new int[] { -android.R.attr.state_selected, android.R.attr.state_pressed, android.R.attr.state_focused },
            new int[] { android.R.attr.state_selected, -android.R.attr.state_pressed },
            new int[] { android.R.attr.state_selected, -android.R.attr.state_pressed, -android.R.attr.state_focused },
            new int[] { android.R.attr.state_selected, android.R.attr.state_pressed},
            new int[] { android.R.attr.state_selected, android.R.attr.state_pressed, android.R.attr.state_focused },
            new int[] { -android.R.attr.state_selected, -android.R.attr.state_pressed, -android.R.attr.state_focused },
            new int[] {}
    };
    int[] colors = new int[] {
            lightColor,  /* Text color when pressed and not selected */
            lightColor,  /* Text color when pressed (with focused fallback) */
            darkColor,   /* Text color when selected and not pressed */
            darkColor,   /* Text color when selected and not pressed (with focused fallback) */
            darkColor,   /* Text color when selected and pressed */
            darkColor,   /* Text color when selected and pressed (with focused fallback) */
            lightColor,  /* Normal color when not pressed, selected or focused */
            lightColor   /* Default text color */
    };
    ColorStateList colorList = new ColorStateList(states, colors);

    /*
     *  We assign the drawable and the list to the activity instance to be accessible everywhere.
     */
    this.tabSelected = tabSel;
    this.tabSelectedAndPressed = tabSelAndPress;
    this.tabDrawableList = drawableList;
    this.tabColorList = colorList;

    /*
     *  Now we setup the tab host and add the tabs to the view.
     */
    this.tabHost = (FragmentTabHost) this.findViewById(R.id.tabhost);
    this.tabHost.setup(this, super.fragmentManager, R.id.tabcontent);
    this.tabHost.getTabWidget().setDividerDrawable(null);
    this.addTab(
            this.createTabView(R.layout.controller_tab, R.string.controller_tab_local_title),
            R.string.controller_tab_local_spec,
            LocalControllerFragment.class);
    this.addTab(
            this.createTabView(R.layout.controller_tab, R.string.controller_tab_online_title),
            R.string.controller_tab_online_spec,
            OnlineControllerFragment.class);
  }

  /*
   *  This method is used to resume the activity.
   */
  private void resume () {
    this.connector.startConnectThread();
  }

  /*
   *  This method is used to maintain the connection.
   */
  private void connected () {
    this.connector.stopConnectThread();
    this.connector.startConnectedThread();
  }

  /*
   *  When the activity is resumed check if there is an active connection, if exists we resume it.
   */
  @Override
  public void onResume () {
    super.onResume();
    if (this.firstTime) {
      this.firstTime = false;
      this.resume();
    }
  }

}




Java Source Code List

.OldPadControllerFragment.java
com.andexert.library.ApplicationTest.java
com.andexert.library.RippleView.java
com.andexert.rippleeffect.ApplicationTest.java
com.andexert.rippleeffect.CustomAdapter.java
com.andexert.rippleeffect.MainActivity.java
com.andexert.rippleeffect.OnTapListener.java
com.gc.materialdesign.utils.Utils.java
com.gc.materialdesign.views.ButtonFlat.java
com.gc.materialdesign.views.ButtonFloatSmall.java
com.gc.materialdesign.views.ButtonFloat.java
com.gc.materialdesign.views.ButtonIcon.java
com.gc.materialdesign.views.ButtonRectangle.java
com.gc.materialdesign.views.Button.java
com.gc.materialdesign.views.Card.java
com.gc.materialdesign.views.CheckBox.java
com.gc.materialdesign.views.CustomView.java
com.gc.materialdesign.views.LayoutRipple.java
com.gc.materialdesign.views.ProgressBarCircularIndeterminate.java
com.gc.materialdesign.views.ProgressBarDeterminate.java
com.gc.materialdesign.views.ProgressBarIndeterminateDeterminate.java
com.gc.materialdesign.views.ProgressBarIndeterminate.java
com.gc.materialdesign.views.RippleView.java
com.gc.materialdesign.views.ScrollView.java
com.gc.materialdesign.views.Slider.java
com.gc.materialdesign.views.Switch.java
com.gc.materialdesign.widgets.ColorSelector.java
com.gc.materialdesign.widgets.Dialog.java
com.gc.materialdesign.widgets.SnackBar.java
git.egatuts.nxtremotecontroller.ApplicationTest.java
git.egatuts.nxtremotecontroller.GlobalUtils.java
git.egatuts.nxtremotecontroller.activity.ActivityPendingTransition.java
git.egatuts.nxtremotecontroller.activity.BaseActivity.java
git.egatuts.nxtremotecontroller.activity.ControllerActivity.java
git.egatuts.nxtremotecontroller.activity.DefaultActivityPendingTransition.java
git.egatuts.nxtremotecontroller.activity.MainActivity.java
git.egatuts.nxtremotecontroller.activity.SettingsActivity.java
git.egatuts.nxtremotecontroller.bluetooth.BluetoothConstants.java
git.egatuts.nxtremotecontroller.bluetooth.BluetoothUtils.java
git.egatuts.nxtremotecontroller.bluetooth.NXTConnector.java
git.egatuts.nxtremotecontroller.device.PairedDeviceAdapter.java
git.egatuts.nxtremotecontroller.device.PairedDeviceItemClickListener.java
git.egatuts.nxtremotecontroller.device.PairedDeviceViewHolder.java
git.egatuts.nxtremotecontroller.device.PairedDevice.java
git.egatuts.nxtremotecontroller.exception.SocketCreationException.java
git.egatuts.nxtremotecontroller.fragment.ActivityBaseFragment.java
git.egatuts.nxtremotecontroller.fragment.BaseFragment.java
git.egatuts.nxtremotecontroller.fragment.BluetoothFragment.java
git.egatuts.nxtremotecontroller.fragment.ControllerBaseFragment.java
git.egatuts.nxtremotecontroller.fragment.DefaultFragmentPendingTransition.java
git.egatuts.nxtremotecontroller.fragment.FragmentPendingTransition.java
git.egatuts.nxtremotecontroller.fragment.HomeFragment.java
git.egatuts.nxtremotecontroller.fragment.LocalControllerFragment.java
git.egatuts.nxtremotecontroller.fragment.OnlineControllerFragment.java
git.egatuts.nxtremotecontroller.fragment.ScanFragment.java
git.egatuts.nxtremotecontroller.fragment.SettingsFragment.java
git.egatuts.nxtremotecontroller.listener.AnimationEndListener.java
git.egatuts.nxtremotecontroller.listener.AppKillerListener.java
git.egatuts.nxtremotecontroller.listener.BaseListener.java
git.egatuts.nxtremotecontroller.listener.BluetoothDiscoveryListener.java
git.egatuts.nxtremotecontroller.listener.BluetoothEnableListener.java
git.egatuts.nxtremotecontroller.listener.BluetoothPairingListener.java
git.egatuts.nxtremotecontroller.navigation.DrawerItemViewHolder.java
git.egatuts.nxtremotecontroller.navigation.DrawerItem.java
git.egatuts.nxtremotecontroller.navigation.NavigationDrawerAdapter.java
git.egatuts.nxtremotecontroller.navigation.NavigationDrawerCallback.java
git.egatuts.nxtremotecontroller.navigation.NavigationDrawerFragment.java
git.egatuts.nxtremotecontroller.preference.PreferencesUtils.java
git.egatuts.nxtremotecontroller.receiver.AppKillerReceiver.java
git.egatuts.nxtremotecontroller.receiver.BaseReceiver.java
git.egatuts.nxtremotecontroller.receiver.BluetoothDiscoveryReceiver.java
git.egatuts.nxtremotecontroller.receiver.BluetoothEnableReceiver.java
git.egatuts.nxtremotecontroller.receiver.BluetoothPairingReceiver.java
git.egatuts.nxtremotecontroller.thread.BaseThread.java
git.egatuts.nxtremotecontroller.thread.ConnectThread.java
git.egatuts.nxtremotecontroller.thread.ConnectedThread.java
git.egatuts.nxtremotecontroller.views.BaseIndeterminateProgressDialog.java
git.egatuts.nxtremotecontroller.views.BaseProgressDialog.java
git.egatuts.nxtremotecontroller.views.JoystickView.java
git.egatuts.nxtremotecontroller.views.LongIndeterminateProgressDialog.java
git.egatuts.nxtremotecontroller.views.ShortIndeterminateProgressDialog.java