Освой программирование играючи

Сайт Александра Климова

Шкодим

/* Моя кошка замечательно разбирается в программировании. Стоит мне объяснить проблему ей - и все становится ясно. */
John Robbins, Debugging Applications, Microsoft Press, 2000

Sphero

Sphero - интерактивная игрушка, управляемая с телефона.

Статья устарела. Я баловался игрушкой в 2015 году. Там многое поменялось, да и сами производители забросили развитие библиотеки.

На сайте производителя есть специальный раздел для разработчиков, в котором можно найти SDK для разных платформ. На текущий момент (май 2015) для Android используется код, написанный под Eclipse. Мне не удалось нормально подружить код с Android Studio, постоянно вылезали косяки. Также на Гитхабе имеется ветка бета-версии SDK. Я использовал бету-версию, которая у меня заработала.

Я покажу базовый пример для первого знакомства.

Сначала скачиваем файл библиотеки RobotLibrary.jar. Напоминаю, что речь идёт о бета-версии номер 3. Текущая версия 2.0 у меня не работала.

Файл библиотеки копируем в папку libs проекта и прописываем зависимость в Gradle:


compile files('libs/RobotLibrary.jar')

В манифесте пропишем разрешения для работы с Bluetooth:


<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />

В макет экрана активности добавим три кнопки. Две из них будут менять цвет, а третья будет двигать шарик.


<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/entire_view"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical">

    <Button
        android:id="@+id/buttonGreen"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentTop="true"
        android:layout_centerHorizontal="true"
        android:onClick="onClick"
        android:text="Green" />

    <Button
        android:id="@+id/buttonBlue"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignStart="@+id/buttonGreen"
        android:layout_below="@+id/buttonGreen"
        android:layout_marginTop="57dp"
        android:onClick="onClick"
        android:text="Blue" />

    <Button
        android:id="@+id/buttonMove"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_centerHorizontal="true"
        android:layout_centerVertical="true"
        android:onClick="onClick"
        android:text="Move" />

</RelativeLayout>

Осталось написать код. Код состоит из двух частей. Первая часть - обнаружить устройство и спариться с ним. Вторая часть - отдавать команды. У разработчика есть два типа роботов - Sphero и Ollie, которые можно использовать в одной программе. Но они имеют разных набор команд и методов. Поэтому, если вы пишите универсальную программу, то нужно отдельно определить каждого робота и работать с нужным типом. Я убрал все проверки if, которые попадались в документации.


package ru.alexanderklimov.sphero;

import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;

import android.util.Log;
import android.view.View;

import com.orbotix.ConvenienceRobot;
import com.orbotix.Sphero;
import com.orbotix.classic.DiscoveryAgentClassic;
import com.orbotix.classic.RobotClassic;
import com.orbotix.common.DiscoveryAgent;
import com.orbotix.common.DiscoveryAgentEventListener;
import com.orbotix.common.DiscoveryException;
import com.orbotix.common.Robot;
import com.orbotix.common.RobotChangedStateListener;

import java.util.List;

public class MainActivity extends ActionBarActivity implements
        DiscoveryAgentEventListener,
        RobotChangedStateListener{

    private static final String TAG = "Sphero";

    private DiscoveryAgent mCurrentDiscoveryAgent;
    private ConvenienceRobot mRobot;


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

    @Override
    protected void onStart() {
        super.onStart();
        mCurrentDiscoveryAgent = DiscoveryAgentClassic.getInstance();
        mCurrentDiscoveryAgent.addRobotStateListener(this);
        startDiscovery();
    }

    @Override
    public void onStop() {
        super.onStop();
        mRobot.disconnect();
    }

    /**
     * Invoked when the discovery agent finds a new available robot, or updates and already available robot
     * @param robots The list of all robots, connected or not, known to the discovery agent currently
     */
    @Override
    public void handleRobotsAvailable(List<Robot> robots) {
        // Here we need to know which version of the discovery agent we are using, if we are to use Sphero, we need to
        // treat Spheros a little bit differently.
        if (mCurrentDiscoveryAgent instanceof DiscoveryAgentClassic) {
            // If we are using the classic discovery agent, and therefore using Sphero, we'll just connect to the first
            // one available that we get. Note that "available" in classic means paired to the phone and turned on.
            mCurrentDiscoveryAgent.connect(robots.get(0));
        }
    }

    @Override
    public void changedState(Robot robot, RobotChangedStateNotificationType type) {
        switch (type) {
            case Connecting:
                Log.i(TAG, "Connecting");
                break;
            case FailedConnect:
                Log.i(TAG, "FailedConnect");
                break;
            case Online:
                // Bluetooth Classic (Sphero)
                Log.i(TAG, "Online");
                if (robot instanceof RobotClassic) {
                    mRobot = new Sphero(robot);
                    mRobot.setLed(0f, 0f, 1f);
                }
                break;
            case Disconnected:
                Log.i(TAG, "Disconnecting");
                break;
        }
    }

    /**
     * Starts discovery on the set discovery agent and look for robots
     */
    private void startDiscovery() {
        try {
            // You first need to set up so that the discovery agent will notify you when it finds robots.
            // To do this, you need to implement the DiscoveryAgentEventListener interface (or declare
            // it anonymously) and then register it on the discovery agent with DiscoveryAgent#addDiscoveryListener()
            mCurrentDiscoveryAgent.addDiscoveryListener(this);
            // Second, you need to make sure that you are notified when a robot changes state. To do this,
            // implement RobotChangedStateListener (or declare it anonymously) and use
            // DiscoveryAgent#addRobotStateListener()
            mCurrentDiscoveryAgent.addRobotStateListener(this);
            // Then to start looking for a Sphero, you use DiscoveryAgent#startDiscovery()
            // You do need to handle the discovery exception. This can occur in cases where the user has
            // Bluetooth off, or when the discovery cannot be started for some other reason.
            mCurrentDiscoveryAgent.startDiscovery(this);
        } catch (DiscoveryException e) {
            Log.e(TAG, "Could not start discovery. Reason: " + e.getMessage());
            e.printStackTrace();
        }
    }

    public void onClick(View view) {
        switch (view.getId()){
            case R.id.buttonBlue:
                mRobot.setLed(0f, 0f, 1f);
                break;
            case R.id.buttonGreen:
                mRobot.setLed(0f, 1f, 0f);
                break;
            case R.id.buttonMove:
                mRobot.drive((float) 5, (float) 5);
                break;
        }
    }
}

Два слушателя DiscoveryAgentEventListener и RobotChangedStateListener помогают обнаружить и управлять шариком. За обнаружение отвечает класс DiscoveryAgent, который связан с Bluetooth. После успешного обнаружения в методе changedState() срабатывает тип Online, в котором мы можем посветить шарик нужным цветом, чтобы стало понятно, что мы соединились с шариком и можем отдавать ему команды.

По щелчку кнопок мы меняем цвета с синего на зелёный, используя формат RGB. Есть и другие методы управления цветом.

Третья кнопка заставляет шарик двигаться при помощи метода drive().

Остальные возможности изучайте самостоятельно.

Реклама