Статьи

Вещи Android: создание облачного сервисного швейцара

Android Things позволяет создавать удивительные устройства IoT с простым кодом. В этом посте я покажу вам, как собрать кусочки, чтобы построить более сложный проект!

Это не будет полный учебник сверху вниз. Я оставлю вам много возможностей для расширения и настройки вашего устройства и приложения, чтобы вы могли изучить и узнать больше самостоятельно. Моя цель — получить удовольствие от работы с этой новой платформой разработки и показать вам, что для Android есть нечто большее, чем просто мигающие светодиоды.

Половина удовольствия от проекта Internet of Things — это «вещь». В этой статье я создам дверной звонок с подключением к облаку, который будет делать снимок, когда кто-то приближается, загружать это изображение в Firebase и запускать действие. Наш проект потребует несколько компонентов, прежде чем мы сможем начать:

  • Raspberry Pi 3B с Android-вещами на SIM-карте
  • Raspberry Pi камера
  • Детектор движения (компонент: HCSR501)

Кроме того, вы можете настроить свой проект в соответствии со своим собственным творческим стилем и повеселиться с ним. Для своего проекта я взял украшение скелета, которое сидело на моем крыльце с Хэллоуина, и использовал его в качестве оболочки для моего проекта — с просверленными глазами, чтобы держать камеру и детектор движения.

Скелет Android Things устройство

Я также добавил серводвигатель для перемещения челюсти, который плотно закрыт резинкой, и USB-динамик для поддержки преобразования текста в речь.

Схемы для простого настроенного умного дверного звонка

Вы можете начать этот проект, построив свою схему. Обязательно запомните, какой вывод вы используете для своего детектора движения и как вы подключаете любые дополнительные периферийные устройства, например, подключение модуля камеры к гнезду камеры на Raspberry Pi. С некоторыми изменениями конечный продукт каждого будет немного отличаться, и вы можете поделиться своим собственным готовым проектом IoT в разделе комментариев к этой статье. Для получения информации о подключении схемы см. Мое руководство по созданию вашего первого проекта .

  • Android SDK
    Android Things: ваш первый проект

Для этого проекта мы будем использовать два основных компонента: камеру и детектор движения. Начнем с рассмотрения детектора движения. Это потребует нового класса, который обрабатывает чтение цифровых сигналов с нашего вывода GPIO . При обнаружении движения будет вызван обратный вызов, который мы можем прослушивать в нашей MainActivity . Для получения дополнительной информации о GPIO, см. Мою статью о периферии Android Things .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
private GpioCallback mInterruptCallback = new GpioCallback() {
 
    @Override
    public boolean onGpioEdge(Gpio gpio) {
        try {
            if( gpio.getValue() != mLastState ) {
                mLastState = gpio.getValue();
                performMotionEvent(mLastState ? State.STATE_HIGH : State.STATE_LOW);
            }
 
        } catch( IOException e ) {
 
        }
 
        return true;
    }
};

Если вы следовали вместе с серией Android Things на Envato Tuts +, вы можете попробовать написать полный класс детекторов движения самостоятельно, так как это простой компонент цифрового ввода. Если вы хотите пропустить это, вы можете найти весь компонент, написанный в проекте для этого урока.

В своей Activity вы можете создать экземпляр компонента HCSR501 и связать с ним новый HCSR501.OnMotionDetectedEventListener .

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
private void initMotionDetection() {
    try {
        mMotionSensor = new HCSR501(BoardDefaults.getMotionDetectorPin());
        mMotionSensor.setOnMotionDetectedEventListener(this);
    } catch (IOException e) {
 
    }
}
 
@Override
public void onMotionDetectedEvent(HCSR501.State state) {
    if (state == HCSR501.State.STATE_HIGH) {
        performCustomActions();
    }
}

Как только ваш детектор движения заработает, самое время сделать снимок с помощью камеры Raspberry Pi.

Один из лучших способов быстро освоить новый инструмент или платформу — просмотреть пример кода, предоставленный создателями. В этом случае мы будем использовать класс, созданный Google для фотографирования с использованием Camera2 API. Если вы хотите узнать больше об Camera2 API, вы можете проверить наш полный видеокурс здесь, на Envato Tuts + .

  • Android SDK
    Делайте фотографии с помощью приложения для Android
    Ашраф Хатхибелагал

Вы можете найти весь исходный код для класса камеры в примере этого проекта, хотя основной метод, который вас заинтересует — это takePicture() . Этот метод возьмет изображение и вернет его к обратному вызову в вашем приложении.

01
02
03
04
05
06
07
08
09
10
11
12
public void takePicture() {
    if (mCameraDevice == null) {
        return;
    }
 
    try {
        mCameraDevice.createCaptureSession(
                Collections.singletonList(mImageReader.getSurface()),
                mSessionCallback,
                null);
    } catch (CameraAccessException cae) {}
}

Как только этот класс будет добавлен в ваш проект, вам нужно будет добавить интерфейс ImageReader.OnImageAvailableListener в свою Activity , инициализировать камеру с помощью onCreate() и прослушать все возвращенные результаты. Когда ваши результаты возвращаются в onImageAvailable() , вам нужно будет преобразовать их в byte массив для загрузки в Firebase.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
private void initCamera() {
    mCameraBackgroundThread = new HandlerThread(«CameraInputThread»);
    mCameraBackgroundThread.start();
    mCameraBackgroundHandler = new Handler(mCameraBackgroundThread.getLooper());
 
    mCamera = DoorbellCamera.getInstance();
    mCamera.initializeCamera(this, mCameraBackgroundHandler, this);
}
 
@Override
public void onImageAvailable(ImageReader imageReader) {
    Image image = imageReader.acquireLatestImage();
    ByteBuffer imageBuf = image.getPlanes()[0].getBuffer();
    final byte[] imageBytes = new byte[imageBuf.remaining()];
    imageBuf.get(imageBytes);
    image.close();
 
    onPictureTaken(imageBytes);
}

Теперь, когда у вас есть данные изображения, пришло время загрузить их в Firebase. Хотя я не буду вдаваться в подробности по настройке Firebase для вашего приложения, вы можете следовать этому руководству, чтобы начать работу . Мы будем использовать Firebase Storage для хранения наших изображений, хотя после того, как ваше приложение настроено для использования Firebase, вы можете выполнять дополнительные задачи, такие как хранение данных в базе данных Firebase для использования с сопутствующим приложением, которое уведомляет вас, когда кто-то находится у вас , Давайте обновим метод onPictureTaken() чтобы загрузить наше изображение.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
private void onPictureTaken(byte[] imageBytes) {
    if (imageBytes != null) {
        FirebaseStorage storage = FirebaseStorage.getInstance();
 
        StorageReference storageReference = storage.getReferenceFromUrl(FIREBASE_URL).child(System.currentTimeMillis() + «.png»);
 
        UploadTask uploadTask = storageReference.putBytes(imageBytes);
        uploadTask.addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception exception) {
            }
        }).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
            @Override
            public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
            }
        });
 
    }
}

Как только ваши изображения будут загружены, вы сможете увидеть их в Firebase Storage.

Изображения хранятся в Firebase Storage

Теперь, когда у вас есть все, что нужно для создания базовой функциональности вашего дверного звонка, пришло время по-настоящему сделать этот проект вашим. Ранее я упоминал, что сделал некоторые настройки, используя скелет с подвижной челюстью и возможностями преобразования текста в речь. Сервоприводы могут быть реализованы путем импорта библиотеки сервоприводов из Google и включения следующего кода в MainActivity для настройки и запуска сервоприводов.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
private final int MAX_MOUTH_MOVEMENT = 6;
int mouthCounter = MAX_MOUTH_MOVEMENT;
 
private Runnable mMoveServoRunnable = new Runnable() {
 
    private static final long DELAY_MS = 1000L;
 
    private double mAngle = Float.NEGATIVE_INFINITY;
 
    @Override
    public void run() {
        if (mServo == null || mouthCounter <= 0) {
            return;
        }
 
        try {
            if (mAngle <= mServo.getMinimumAngle()) {
                mAngle = mServo.getMaximumAngle();
            } else {
                mAngle = mServo.getMinimumAngle();
            }
            mServo.setAngle(mAngle);
 
            mouthCounter—;
            mServoHandler.postDelayed(this, DELAY_MS);
        } catch (IOException e) {
        }
    }
};
 
private void initServo() {
    try {
        mServo = new Servo(BoardDefaults.getServoPwmPin());
        mServo.setAngleRange(0f, 180f);
        mServo.setEnabled(true);
    } catch (IOException e) {
        Log.e(«Camera App», e.getMessage());
        return;
    }
}
 
private void moveMouth() {
    if (mServoHandler != null) {
        mServoHandler.removeCallbacks(mMoveServoRunnable);
    }
 
    mouthCounter = MAX_MOUTH_MOVEMENT;
    mServoHandler = new Handler();
    mServoHandler.post(mMoveServoRunnable);
}

Когда вы закончите с вашим приложением, вам также нужно будет разыменовать серводвигатель.

01
02
03
04
05
06
07
08
09
10
11
12
if (mServoHandler != null) {
    mServoHandler.removeCallbacks(mMoveServoRunnable);
}
 
if (mServo != null) {
    try {
        mServo.close();
    } catch (IOException e) {
    } finally {
        mServo = null;
    }
}

Удивительно, что текст в речь немного проще. Вам просто нужно инициализировать механизм преобразования текста в речь, например:

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
private void initTextToSpeech() {
 
    textToSpeech = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
        @Override
        public void onInit(int status) {
            if (status == TextToSpeech.SUCCESS) {
                textToSpeech.setLanguage(Locale.UK);
                textToSpeech.setOnUtteranceProgressListener(utteranceListener);
                textToSpeech.setPitch(0.3f);
            } else {
                textToSpeech = null;
            }
        }
    });
}

Вы можете играть с настройками, чтобы голос соответствовал вашему приложению. В приведенном выше примере я настроил тембр с низким, несколько роботизированным тоном и английским акцентом. Когда вы будете готовы к тому, что ваше устройство скажет что-то, вы можете вызвать speak() с помощью механизма преобразования текста в речь.

1
textToSpeech.speak(«Thanks for stopping by!», TextToSpeech.QUEUE_ADD, null, «skeletontts»);

На Raspberry Pi, если вы используете серводвигатель, вам необходимо убедиться, что ваш динамик подключен через порт USB, поскольку аналоговое вспомогательное соединение не может быть использовано, пока ваше устройство также создает сигнал ШИМ.

Я настоятельно рекомендую просмотреть примеры драйверов Google, чтобы увидеть, какое дополнительное оборудование вы можете добавить в свой проект, и проявить творческий подход к своему проекту. Большинство функций, доступных для Android, также поддерживаются в Android Things, включая поддержку сервисов Google Play и машинного обучения TensorFlow . Для небольшого вдохновения вот видео законченного проекта:

В этой статье я представил несколько новых инструментов, которые вы можете использовать для создания более сложных приложений IoT.

Это конец нашей серии статей о Android Things, поэтому я надеюсь, что вы многое узнали о платформе и использовали ее для создания удивительных проектов. Создание приложений — это одно, но возможность влиять на окружающий мир своими приложениями еще более увлекательна. Будьте изобретательны, создавайте замечательные вещи, и, прежде всего, получайте удовольствие!

Помните, что Envato Tuts + наполнен информацией о разработке Android, и вы можете найти много вдохновения здесь для вашего следующего приложения или проекта IoT.

  • Android вещи и машинное обучение

  • Как использовать Google Cloud Machine Learning Services для Android

  • Как звонить и использовать SMS в приложениях для Android

  • Датчики Android в глубине: приближение и гироскоп

  • Начало работы с Android VR и Google Cardboard: панорамные изображения

  • Создать голосовое приложение для Android