com.bq.robotic.robopad.RoboPad.java Source code

Java tutorial

Introduction

Here is the source code for com.bq.robotic.robopad.RoboPad.java

Source

/*
* This file is part of the RoboPad
*
* Copyright (C) 2013 Mundo Reader S.L.
* 
* Date: February 2014
* Author: Estefana Sarasola Elvira <estefania.sarasola@bq.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/

package com.bq.robotic.robopad;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.Interpolator;
import android.widget.ImageButton;

import com.bq.robotic.droid2ino.activities.BaseBluetoothSendOnlyActivity;
import com.bq.robotic.droid2ino.utils.Droid2InoConstants;
import com.bq.robotic.robopad.fragments.BeetleFragment;
import com.bq.robotic.robopad.fragments.CrabFragment;
import com.bq.robotic.robopad.fragments.EvolutionFragment;
import com.bq.robotic.robopad.fragments.GenericRobotFragment;
import com.bq.robotic.robopad.fragments.PollywogFragment;
import com.bq.robotic.robopad.fragments.RhinoFragment;
import com.bq.robotic.robopad.fragments.RobotFragment;
import com.bq.robotic.robopad.utils.RoboPadConstants;
import com.bq.robotic.robopad.utils.RoboPadConstants.robotType;
import com.bq.robotic.robopad.listeners.RobotListener;

/**
 * Main activity of the app that contains the different fragments to show to the user 
 */

public class RoboPad extends BaseBluetoothSendOnlyActivity implements RobotListener {

    // Debugging
    private static final String LOG_TAG = "RoboPad";

    private static final String SAVE_FRAGMENT_STATE_KEY = "current_fragment_key";
    private FragmentManager mFragmentManager;

    private ImageButton connectButton;
    private ImageButton disconnectButton;

    private Animation anim;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_robopad);

        robotType robotTypeSelected = (robotType) getIntent()
                .getSerializableExtra(RoboPadConstants.ROBOT_SELECTED_KEY);

        mFragmentManager = getSupportFragmentManager();

        connectButton = (ImageButton) findViewById(R.id.connect_button);
        disconnectButton = (ImageButton) findViewById(R.id.disconnect_button);
        anim = AnimationUtils.loadAnimation(this, R.anim.bluetooth_spiner);

        // If we're being restored from a previous state,
        // then we don't need to do anything and should return or else
        // we could end up with overlapping fragments.
        if (savedInstanceState != null) {
            return;
        }

        // Show the selected robot fragment
        FragmentTransaction ft = mFragmentManager.beginTransaction();
        switch (robotTypeSelected) {

        case POLLYWOG:
            ft.replace(R.id.game_pad_container, new PollywogFragment());
            break;

        case BEETLE:
            ft.replace(R.id.game_pad_container, new BeetleFragment());
            break;

        case EVOLUTION:
            ft.replace(R.id.game_pad_container, new EvolutionFragment());
            break;

        case RHINO:
            ft.replace(R.id.game_pad_container, new RhinoFragment());
            break;

        case CRAB:
            ft.replace(R.id.game_pad_container, new CrabFragment());
            break;

        case GENERIC_ROBOT:
            ft.replace(R.id.game_pad_container, new GenericRobotFragment());
            break;

        }

        ft.commit();

    }

    @Override
    protected void onPause() {
        super.onPause();
        // Store values between instances here
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        SharedPreferences.Editor editor = preferences.edit();

        editor.putBoolean(RoboPadConstants.WAS_ENABLING_BLUETOOTH_ALLOWED_KEY, wasEnableBluetoothAllowed); // value to store
        // Commit to storage
        editor.commit();
    }

    @Override
    protected void onStart() {
        super.onStart();
        // Store values between instances here
        SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
        wasEnableBluetoothAllowed = preferences.getBoolean(RoboPadConstants.WAS_ENABLING_BLUETOOTH_ALLOWED_KEY,
                false);
    }

    /**
     * Callback for the changes of the bluetooth connection status
     * 
     * @param connectionState The state of the bluetooth connection
     */
    @Override
    public void onConnectionStatusUpdate(int connectionState) {
        switch (connectionState) {
        case Droid2InoConstants.STATE_CONNECTED:
            ((RobotFragment) mFragmentManager.findFragmentById(R.id.game_pad_container)).onBluetoothConnected();

            // If connected is because the Bluetooth enabling was allowed
            break;

        case Droid2InoConstants.STATE_CONNECTING:
            break;

        case Droid2InoConstants.STATE_LISTEN:
        case Droid2InoConstants.STATE_NONE:
            if (mFragmentManager.findFragmentById(R.id.game_pad_container) != null) {
                ((RobotFragment) mFragmentManager.findFragmentById(R.id.game_pad_container))
                        .onBluetoothDisconnected();
            }
            break;
        }
        changeViewsVisibility(connectionState);
    }

    /**
     * Change the visibility of some views as the connect/disconnect button depending on the
     * bluetooth connection state The state of the bluetooth connection
     *
     * @param connectionState the state of the current bluetooth connection
     */
    private void changeViewsVisibility(int connectionState) {

        switch (connectionState) {

        case Droid2InoConstants.STATE_CONNECTED:
            findViewById(R.id.bluetooth_spinner_view).setVisibility(View.INVISIBLE);
            findViewById(R.id.bluetooth_spinner_view).clearAnimation();

            connectButton.setVisibility(View.GONE);
            disconnectButton.setVisibility(View.VISIBLE);
            break;

        case Droid2InoConstants.STATE_CONNECTING:

            if (anim != null) {
                anim.setInterpolator(new Interpolator() {
                    private final int frameCount = 8;

                    @Override
                    public float getInterpolation(float input) {
                        return (float) Math.floor(input * frameCount) / frameCount;
                    }
                });

                findViewById(R.id.bluetooth_spinner_view).setVisibility(View.VISIBLE);
                findViewById(R.id.bluetooth_spinner_view).startAnimation(anim);
            } else {
                Log.e(LOG_TAG, "Anim null!!!");
            }

            break;

        case Droid2InoConstants.STATE_LISTEN:
        case Droid2InoConstants.STATE_NONE:
            findViewById(R.id.bluetooth_spinner_view).setVisibility(View.INVISIBLE);
            findViewById(R.id.bluetooth_spinner_view).clearAnimation();

            connectButton.setVisibility(View.VISIBLE);
            disconnectButton.setVisibility(View.GONE);

            break;
        }
    }

    /**
     * Callback for the connect and disconnect buttons
     * @param v view pressed
     */
    public void onChangeConnection(View v) {

        switch (v.getId()) {

        case R.id.connect_button:
            requestDeviceConnection();
            break;

        case R.id.disconnect_button:
            stopBluetoothConnection();
            break;
        }
    }

    /**
     * Needed to override the callback when the user clicks the back button because if the activity
     * has an active Bluetooth connection with a robot, the user must confirm that want to loose that
     * connection
     */
    @Override
    public void onBackPressed() {

        if (!isConnectedWithoutToast()) {
            super.onBackPressed();

        } else {

            // Show a dialog to confirm that the user wants to choose a new robot type
            // and to inform that the connection with the current robot will be lost
            new AlertDialog.Builder(this).setMessage(getResources().getString(R.string.exit_robot_control_dialog))
                    .setTitle(R.string.exit_robot_control_dialog_title).setCancelable(true)
                    .setNegativeButton(android.R.string.no, null)
                    .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {

                        @Override
                        public void onClick(DialogInterface dialog, int which) {
                            stopBluetoothConnection();

                            RoboPad.super.onBackPressed();
                        }
                    })

                    .create().show();

        }

    }

    @Override
    public void onSaveInstanceState(Bundle outState) {

        //Save the fragment's instance
        mFragmentManager.putFragment(outState, SAVE_FRAGMENT_STATE_KEY,
                mFragmentManager.findFragmentById(R.id.game_pad_container));

        super.onSaveInstanceState(outState);

    }

    /**************************************************************************************
     **************************   ROBOTLISTENER CALLBACKS   *******************************
     **************************************************************************************/

    /**
     * Callback from the RobotFragment for checking if the device is connected to an Arduino 
     * through the bluetooth connection.
     * If the device is not connected it warns the user of it through a Toast.
     * 
     * @return true if is connected or false if not
     */
    @Override
    public boolean onCheckIsConnected() {
        return isConnected();
    }

    /**
     * Callback from the RobotFragment for checking if the device is connected to an Arduino 
     * through the bluetooth connection
     * without the warning toast if is not connected. 
     * 
     * @return true if is connected or false if not
     */
    public boolean onCheckIsConnectedWithoutToast() {
        return isConnectedWithoutToast();
    }

    /**
     * Callback from the RobotFragment for sending a message to the Arduino through the bluetooth 
     * connection. 
     * 
     * @param message to be send to the Arduino
     */
    @Override
    public void onSendMessage(String message) {
        //      Log.e(LOG_TAG, "message to send to arduino: " + message);
        sendMessage(message);
    }

}