Android Things Raspberry Pi3 |
2016 Google Developer Preview Android Things. . preview-, .
IoT , . Live Typing . , Android Things, . , .
1: . , , . , . , , .
2: . . , , , . - .
, , , - , . , . . .
. ( , ). , . Awesome, ?
. ? ? ? ? . Doorbell Android Things. , , , . .
. Raspberry, , , . c Android Things CodeLab IT- , , Mobilatorium. , Google Cloud Vision FindFace Tensor Flow. , back-end, , . , Google Cloud Vision + Firebase Realtime Database, CodeLab.
, Raspberry Pi3, , - . , [ ] (https://vk.com/mobilatorium?w=wall-130802553_81%2Fall) Arduino. .
:
, . , 100-125$. Raspberry Pi3.
. , . , Android, , . Android Studio. , Dagger, RxJava, Retrofit, OkHttp, Timber ..
Android Things, Raspberry Pi3. .
Raspberry Pi . GPIO (General-purpose input/output) PWM (Pulse Width Modulation). .
, . , , . . , . , Google User Drivers, Android Framework Services. Android API . :
Android Things Raspberry Pi3. .
, , , Raspberry - HDMI-. , Android Things.
WiFi. Android Things IP- WiFi .
, , Raspberry adb .
$ adb connect Android.local
Android Studio. Android , , . Android Things , .
:
app/build.gradle
Android Things support library, API, Android SDK.
dependencies {
...
provided 'com.google.android.things:androidthings:0.4-devpreview'
...
}
Android, ( , Activity, Service, Intent, View, Button, Application, ContentProvider ).
. , , . .
...
...
Android Things , . Activity,
IOT_LAUCHER
AndroidManifest , Activity - . Android Studio .
...
...
dependencies {
...
compile 'com.google.android.things.contrib:driver-button:0.3'
...
}
- . , , .
import com.google.android.things.contrib.driver.button.Button;
public class ButtonWrapper {
private @Nullable Button mButton;
private @Nullable OnButtonClickListener mOnButtonClickListener;
public ButtonWrapper(final String gpioPin) {
try {
mButton = new Button(gpioPin, Button.LogicState.PRESSED_WHEN_HIGH);
mButton.setOnButtonEventListener(new Button.OnButtonEventListener() {
@Override
public void onButtonEvent(Button button, boolean pressed) {
if (pressed && mOnButtonClickListener != null) {
mOnButtonClickListener.onClick();
}
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
public void setOnButtonClickListener(@Nullable final OnButtonClickListener listener) {
mOnButtonClickListener = listener;
}
public void onDestroy() {
if (mButton == null) {
return;
}
try {
mButton.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
mButton = null;
}
}
public interface OnButtonClickListener {
public void onClick();
}
}
Activity. GPIO ("BCM4") Raspberry Pi3, .
public class MainActivity extends Activity {
private static final String GPIO_PIN_BUTTON = "BCM4";
private ButtonWrapper mButtonWrapper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
mButtonWrapper = new ButtonWrapper(GPIO_PIN_BUTTON);
mButtonWrapper.setOnButtonClickListener(new ButtonWrapper.OnButtonClickListener() {
@Override
public void onClick() {
Timber.d("BUTTON WAS CLICKED");
startTakingImage();
}
});
...
}
@Override
protected void onDestroy() {
super.onDestroy();
...
mButtonWrapper.onDestroy();
...
}
private void startTakingImage() {
// TODO take photo
...
}
}
NoIR Camera V2. 45$ , :
CSI (Camera Serial Interface). USB.
, . , Permissions, Dangerous Permissions, ( , ).
:
BCM20
) , ;BCM21
) ;BCM16
) . , . 1 , .
PeripheralManagerService
, , GPIO . . , com.google.android.things.pio.Gpio
, , java.io.IOException
. try-catch
.
public class LedWrapper {
private @Nullable Gpio mGpio;
public LedWrapper(String gpioPin) {
try {
PeripheralManagerService service = new PeripheralManagerService();
mGpio = service.openGpio(gpioPin);
mGpio.setDirection(Gpio.DIRECTION_OUT_INITIALLY_LOW);
} catch (IOException e) {
e.printStackTrace();
}
}
public void turnOn() {
if (mGpio == null) {
return;
}
try {
mGpio.setValue(true);
} catch (IOException e) {
e.printStackTrace();
}
}
public void turnOff() {
if (mGpio == null) {
return;
}
try {
mGpio.setValue(false);
} catch (IOException e) {
e.printStackTrace();
}
}
public void onDestroy() {
try {
mGpio.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
mGpio = null;
}
}
}
Activity .
public class MainActivity extends Activity {
private final static String GPIO_PIN_LED_GREEN = BCM21;
private LedWrapper mLedWrapper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
mLedWrapper = new LedWrapper(GPIO_PIN_LED_GREEN);
mLedWrapper.turnOff();
...
}
private void turnOn() {
mLedWrapper.turnOn();
}
@Override
protected void onDestroy() {
super.onDestroy();
...
mLedWrapper.onDestroy();
...
}
}
BCM6
, .
public class MotionWrapper {
private @Nullable Gpio mGpio;
private @Nullable MotionEventListener mMotionEventListener;
public MotionWrapper(String gpioPin) {
try {
mGpio = new PeripheralManagerService().openGpio(gpioPin);
} catch (IOException e) {
e.printStackTrace();
}
}
public void setMotionEventListener(@Nullable final MotionEventListener listener) {
mMotionEventListener = listener;
}
public void startup() {
try {
mGpio.setDirection(Gpio.DIRECTION_IN);
mGpio.setActiveType(Gpio.ACTIVE_HIGH);
mGpio.setEdgeTriggerType(Gpio.EDGE_RISING);
mGpio.registerGpioCallback(mCallback);
} catch (IOException e) {
e.printStackTrace();
}
}
public void shutdown() {
if (mGpio == null) {
return;
}
try {
mGpio.unregisterGpioCallback(mCallback);
mGpio.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public void onDestroy() {
try {
mGpio.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
mGpio = null;
}
}
private final GpioCallback mCallback = new GpioCallback() {
@Override
public boolean onGpioEdge(Gpio gpio) {
if (mMotionEventListener != null) {
mMotionEventListener.onMovement();
}
return true;
}
};
public interface MotionEventListener {
void onMovement();
}
}
public class MainActivity extends Activity {
private static final String GPIO_PIN_MOTION_SENSOR = "BCM6";
private MotionWrapper mMotionWrapper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
mMotionWrapper = new MotionWrapper(GPIO_PIN_MOTION_SENSOR);
mMotionWrapper.setMotionEventListener(new MotionWrapper.MotionEventListener() {
@Override
public void onMovement() {
startTakingPhotos();
}
});
mMotionWrapper.startup();
...
}
@Override
protected void onDestroy() {
super.onDestroy();
...
mMotionWrapper.shutdown();
mMotionWrapper.onDestroy();
...
}
private void startTakingPhotos() {
...
}
}
dependencies {
...
compile 'com.google.android.things.contrib:driver-pwmservo:0.2'
...
}
- PWM1
. PWM
, , , , . . - PWM-, .
public class ServoWrapper {
private static final float ANGLE_CLOSE = 0f;
private static final float ANGLE_OPEN = 180f;
private Servo mServo;
private Handler mHandler = new Handler();
public ServoWrapper(final String gpioPin) {
try {
mServo = new Servo(gpioPin);
mServo.setAngleRange(ANGLE_CLOSE, ANGLE_OPEN);
mServo.setEnabled(true);
} catch (IOException e) {
e.printStackTrace();
}
}
public void open(final long delayMillis) {
try {
mServo.setAngle(ANGLE_OPEN);
} catch (IOException e) {
e.printStackTrace();
}
mHandler.removeCallbacks(mMoveServoRunnable);
if (delayMillis > 0) {
mHandler.postDelayed(mMoveServoRunnable, delayMillis);
}
}
public void close() {
if (mServo == null) {
return;
}
try {
mServo.setAngle(ANGLE_CLOSE);
} catch (IOException e) {
e.printStackTrace();
}
}
public void onDestroy() {
mHandler.removeCallbacks(mMoveServoRunnable);
mMoveServoRunnable = null;
if (mServo != null) {
try {
mServo.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
mServo = null;
}
}
}
private Runnable mMoveServoRunnable = new Runnable() {
@Override
public void run() {
mHandler.removeCallbacks(this);
close();
}
};
}
public class MainActivity extends Activity {
private static final String GPIO_PIN_SERVO = "PWM1";
private ServoWrapper mServoWrapper;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
mServoWrapper = new ServoWrapper(GPIO_PIN_SERVO);
...
}
private void openDoor() {
...
mServoWrapper.open(DELAY_SERVO_MS);
...
}
@Override
protected void onDestroy() {
super.onDestroy();
...
mServoWrapper.onDestroy();
...
}
}
, . , . Light Dependent Resistors (LDR). .
, . , . app/build.gradle
.
dependencies {
...
compile 'com.google.android.things.contrib:driver-button:0.3'
...
}
. 10 . BCM25
.
, .
public class BrightrWrapper {
private @Nullable Button mLightDetector;
private @Nullable OnLightStateChangeListener mOnLightStateChangeListener;
public BrightrWrapper(final String gpioPin) {
try {
mLightDetector = new Button(gpioPin, Button.LogicState.PRESSED_WHEN_HIGH);
mLightDetector.setOnButtonEventListener(new Button.OnButtonEventListener() {
@Override
public void onButtonEvent(Button button, boolean isLighted) {
if (mOnLightStateChangeListener != null) {
mOnLightStateChangeListener.onLightStateChange(isLighted);
}
}
});
} catch (IOException e) {
e.printStackTrace();
}
}
public void setOnLightStateListener(@Nullable final OnLightStateChangeListener listener) {
mOnLightStateChangeListener = listener;
}
public void onDestroy() {
if (mLightDetector == null) {
return;
}
try {
mLightDetector.close();
} catch (IOException e) {
e.printStackTrace();
}
}
public interface OnLightStateChangeListener {
public void onLightStateChange(boolean isLighted);
}
}
public class MainActivity extends Activity {
private static final String GPIO_PIN_LIGHT_DETECTOR = "BCM25";
private BrightrWrapper mBrightrWrapper;
private boolean mIsTakePhotoAllowed = true;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
...
mBrightrWrapper = new BrightrWrapper(GPIO_PIN_LIGHT_DETECTOR);
mBrightrWrapper.setOnLightStateListener(new BrightrWrapper.OnLightStateChangeListener() {
@Override
public void onLightStateChange(final boolean isLighted) {
mIsTakePhotoAllowed = isLighted;
handleLightState();
}
});
...
}
private void handleLightState() {
if (mIsTakePhotoAllowed) {
...
} else {
...
}
}
@Override
protected void onDestroy() {
super.onDestroy();
...
mBrightrWrapper.onDestroy();
...
}
}
, - .
-
. , . .
, , . .
. , , , .
.
, , , . , . , . , . , . , .
IoT ? .
, BrailleBox Android Things. , . , .