Dagger Module or !Module

 

With Module

 

Let’s say that we have a class  called “ClassA”:

public class ClassA {
  ClassA() {}
  //...
}

 

We want to make this class Singleton and use it in another class called “ClassB”.

First, we have to create a module in Dagger that Provides the instance of the ClassA.

@Module
public class AModule {

    @Singleton
    @Provides
    ClassA classA() {
        return new ClassA();
    }
}

 

Second, we expose the class using the Dagger component:

@Component(modules = {AModule.class, ...})
public interface AndroidComponent {
  ClassA provideClassA();
}

 

Finally, we can get the instance of the ClassA into the ClassB (and in every classes that need it) like this:

public class ClassB {
  ClassA mClassA;

  public ClassB() {
    mClassA = MyApplication.from(this)
        .getAndroidComponent()
        .provideClassA();
  }
  // ...
}

 

Pro: Easy to mock and provide a fake module instead

Cons: More boilerplate code to write

Without Module

 

@Singleton
public class ClassA {
  @Inject
  ClassA() {}
  //...
}

 

ClassA have to be injected into ClassB, so we do in our AndroidComponent:

@Component(modules = {...})
public interface AndroidComponent {
  void inject(ClassB classB);
}

 

ClassB is:

public class ClassB {
  @Inject ClassA mClassA;

  public ClassB() {
    MyApplication.from(this)
        .getAndroidComponent()
        .inject(this);
  }
  // ...
}

 

Here Dagger check into the ClassB what is annotated with @Inject (in our case is ClassA) and check if ClassA has a constructor annotated with @Inject.

 

Pro: Less code to write

Cons: Not mockable, so it is not easily testable.

Arduino and Android by Bluetooth

In this post, I am going to show how to let communicate an Android app with Arduino using bluetooth.

Hardware:

  • Arduino
  • HC-05 bluetooth module for Arduino
  • A led and a resistor
  • Android smartphone
Final result:

 

Note: Do not connect RX bluetooth module to RX’s Arduino pin and TX bluetooth module to TX’s Arduino pin. RX bluetooth module must be connected to TX’s Arduino pin and TX bluetooth module to RX’s Arduino pin.

 

Android app can be founded here: Android bluetooth project.

 

Arduino code
char data = 0;
void setup()
{
    Serial.begin(9600);   //Sets the baud for serial data transmission
    pinMode(13, OUTPUT);  //Sets digital pin 13 as output pin
}
void loop()
{
   if(Serial.available() > 0)      // Send data only when you receive data:
   {
      data = Serial.read();        //Read the incoming data & store into data
      Serial.print(data);          //Print Value inside data in Serial monitor
      Serial.print("\n");
      if(data == '1')
         digitalWrite(13, HIGH);   //If value is 1 then LED turns ON
      else if(data == '0')
         digitalWrite(13, LOW);    //If value is 0 then LED turns OFF
   }
}

 

Arduino circuite

HC-05 pins:

  • RX to TX’s Arduino pin
  • TX to RX’s Arduino pin
  • GND to GND
  • +5V to +5V
  • EN to 3.3V Arduino pin
On the breadboard: Arduino pin 13 to resistor, the other side of the resistor to the first pin of the LED, the other pin of the LED on GND

[Arduino] Let’s communicate…

Project purpose

I am going to use an Arduino with a screen shield and a pin-pad, connected to a MAC to run a script that publish an APK on Play Store.

Arduino generate a random code that it is displayed on screen shield, user has to type the code on pin-pad, if code is confirmed, he can press a button on screen shield that send a message to a MAC through the serial port, MAC read it and run the script to pushish the APK. In case of wrong code, Arduino re-generate a new code.

 

Hardware:

  • Arduino
  • Display shield
  • Pinpad
  • MAC

Software:

  • on MAC:
    • Script1: It is a script that keep listening the serial port until a specific “data” arrives. When data is received, based on the value of it, the script calls another script. In case of “bad data” display an error on screen, otherwise execute a bash command. Change ‘/dev/tty.usbmodem1411′ with your serial port

// script1.py

import serial
import deploy
arduino = serial.Serial('/dev/tty.usbmodem1411', 115200, timeout=.1)
while True:
       data = arduino.readline()[:-2] #the last bit gets rid of the new-line chars
       if data == "OK":
               deploy.publish(arduino)
               continue
       if data == "KO":
               deploy.error()
               continue
    • Script2: publish method is called when “good data” is received, it run a command that publish an APK to the store. If the publishing script FAILS or SUCCESSES, an error is written on serial port. In case of “bad data” on error is printed on screen

// script2.py

import subprocess
import os
def publish(ser):
       print '***CODE CONFIRMED***'
       os.chdir('path/to/where/you/need')
       proc = subprocess.Popen(['./gradlew', 'your-gradle-command'],stdout=subprocess.PIPE)
       while True:
               line = proc.stdout.readline()
               if line != '':
                       #the real code does filtering here
                       print line.rstrip()
                       if line.find("FAILED") >= 0:
                               ser.write( "Oops, error!")
                       if line.find("SUCCESSFUL") >= 0:
                               ser.write( "Woow published!")
               else:
                       break
def error():
       print '***ERROR***'
       print 'New code required'
Arduino code

 

#include <Keypad.h>
#include <LiquidCrystal.h>
// define some values used by the panel and buttons
int lcd_key     = 0;
int lcd_button  = 0;
#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5
int pinCode = -1;
int confirmPinCode = 0;
int multipler = 1;
bool isCodeConfirmed = false;
bool keypadActive = false;
String incomingByte = "";
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
const byte ROWS = 3; // Three rows
const byte COLS = 3; // Three columns
// Define the Keymap
char keys[ROWS][COLS] = {
 {'1','2','3'},
 {'4','5','6'},
 {'7','8','9'}
};
// Connect keypad ROW0, ROW1, ROW2 to these Arduino pins.
byte rowPins[ROWS] = { 2, A1, A2 };
// Connect keypad COL0, COL1 and COL2 to these Arduino pins.
byte colPins[COLS] = { A3, A4, A5 };
// Create the Keypad
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
int read_LCD_buttons() {
lcd_button = analogRead(0);      // read the value from the sensor
// my buttons when read are centered at these valies: 0, 144, 329, 504, 741
// we add approx 50 to those values and check to see if we are close
if (lcd_button > 1000) return btnNONE;
if (lcd_button < 50)   return btnRIGHT;
if (lcd_button < 250)  return btnUP;
if (lcd_button < 450)  return btnDOWN;
if (lcd_button < 650)  return btnLEFT;
if (lcd_button < 850)  return btnSELECT;
return btnNONE;  // when all others fail, return this...
}
void setup() {
 Serial.begin(115200);
 randomSeed(analogRead(1));
 // force analog pins to be digit
 pinMode(A1,INPUT);
 digitalWrite(A1,HIGH);
 pinMode(A2,INPUT);
 digitalWrite(A2,HIGH);
 pinMode(A3,INPUT);
 digitalWrite(A3,HIGH);
 pinMode(A4,INPUT);
 digitalWrite(A4,HIGH);
 pinMode(A5,INPUT);
 digitalWrite(A5,HIGH);
 lcd.begin(16, 2);
 lcd.clear();
 lcd.setCursor(0, 0);
 lcd.print("press LEFT");
 lcd.setCursor(0, 1);
 lcd.print("to start");
}
/*
* Generate code if not confirmed.
* Do not generate number with '0' because
* the keypad has no '0' number connected
*/
void generatePin() {
 if(!isCodeConfirmed) {
   pinCode = random(111, 999);
   String v = String(pinCode);
   // no zero check
   for(int i = 0; i< v.length(); i++) {
     if(v.charAt(i) == '0') {
       generatePin();
     }
   }
   delay(500);
   lcd.setCursor(0, 1);
   lcd.print(pinCode);
   keypadActive = true;
 }
}
void checkCodeConfirmation() {
 //String ll = String(confirmPinCode).length();
 //if(ll.length() < 3) return;
 if(String(confirmPinCode).length() < 3) return;
 if(confirmPinCode == pinCode) {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("*Code confirmed*");
    lcd.setCursor(0, 1);
    lcd.print("*RIGHT-> deploy*");
    isCodeConfirmed = true;
 } else {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("***Wrong code***");
    lcd.setCursor(0, 1);
    lcd.print("LEFT-> new code");
    Serial.println("KO");
    keypadActive = false;
 }
 confirmPinCode = 0;
 multipler = 1;
}
void waitingDeployResult() {
 while(true) {
   incomingByte = Serial.readString();
   if (incomingByte != "") {
     lcd.clear();
     lcd.setCursor(0, 0);
     lcd.print(incomingByte);
     break;
     }
 }
}
void loop() {
 lcd_key = read_LCD_buttons();  // read the buttons
 char key = kpd.getKey();
    /* keypad is activated only when pin-code is generated */
    if(keypadActive) {
       if(key) {
          confirmPinCode =  (confirmPinCode * multipler) + (key - '0');
          lcd.setCursor(4, 1);
          lcd.print(" -> " + String(confirmPinCode));
          if (multipler == 1) {
             multipler = multipler * 10;
          }
       }
    }
     // depending on which button was pushed, we perform an action
      switch (lcd_key) {
        case btnLEFT:
           lcd.clear();
           lcd.setCursor(0, 0);
           lcd.print("Activation pin");
           generatePin();
           delay(600);
           break;
      }
    checkCodeConfirmation();
    if(isCodeConfirmed) {
       bool deployed = false;
       while(true) {
         if(!deployed) {
             lcd_key = read_LCD_buttons();  // read the buttons
              switch (lcd_key) { // depending on which button was pushed, we perform an action
                case btnRIGHT:
                   Serial.println("OK");
                   lcd.clear();
                   lcd.setCursor(0, 0);
                   lcd.print("Waiting result..");
                   delay(600);
                   deployed = true;
                   waitingDeployResult();
                   break;
            }
         }
      }
   }
}

Time for demo

  • Connect Arduino at the serial port
  • Run ./python script1.py
  • Follow the instruction on display

Proxy on Android Emulator

Run the emulator and let’s configure the Access Point.

  1. To do this, you go to settings->more->cellular network->access point names and edit the existing Access Point (Edit proxy name and port number)
  2. Toggle Airplane mode on and off
Now you are able to use the proxy.

Dagger2, a visual approach

In this post I’m not going to explain what Dagger is, but I’m just showing a visual example of it is used inside an Android Application.

What we want to do

We want to use SharedPreferences inside our MainActivity

How

  1. Create SharedPreferences class
  2. Create a @Module that provides that class
  3. Create a @Component that injects the Modules into our Activity
  4. Let’s instantiate the Component inside out Application
  5. Let’s @Inject our MySharedPreferences into the Activiy and use it

See image for more details

[Unity] Coroutine, forever running

We are going to see how to instantiate Game Objects without freezing the game UI.

What we need to do is to create a Coroutine, it is just a method that has IEnumerator as a return type.

public class GameController : MonoBehaviour {

public GameObject hazard;
public float spawnWait;

void Start () {
    StartCoroutine (SpawnWaves ());
}

IEnumerator SpawnWaves () {
while(true) {

     Vector3 spawnPosition = new Vector3 (…);

     Quaternion spawnRotation = Quaternion.identity;

     Instantiate (hazard, spawnPosition, spawnRotation);

        yield return new WaitForSeconds (spawnWait);

   }
}
}

As you can see from the code, I also added yield return new WaitForSeconds () after instantiate the game object, so we can avoid to instantiate all of them at same time.

 

[Unity] Keep a gameObject into a specific area

If we have a gameObject that needs to move into a specific area, we can use the Mathf.Clamp(value, min, max), this check that the value we have is min < x < max.

In the example below, we take the gameObject position X and Z and said that must be inside a range.

    [...]

  Rigidbody rb;

  void Start() {
rb = GetComponent<Rigidbody>();
}

  void FixedUpdate() {

float moveHorizontal = Input.GetAxis (“Horizontal”);
float moveVertical = Input.GetAxis (“Vertical”);

Vector3 movement = new Vector3 (moveHorizontal, 0.0f, moveVertical);
rb.velocity = movement * speed;

rb.position = new Vector3 (
                  Mathf.Clamp(rb.position.x, boundary.xMin, boundary.xMax),
                 0.0f,
                 Mathf.Clamp(rb.position.z, boundary.zMin, boundary.zMax)
             );

}

[Unity] Serializable classes for a better interface

If we are going to have a long list of “public” params, so it looks something like this:

we can organize them by grouping into a class (in this case called Boundary), so we can have a better and clear game interface like this:

 

How to do it?

Just create a new class and remember to add [System.Serializable] on top of your class otherwise Unity is not able to recognise it and you are not going to see anything on the interface

[System.Serializable]
public class Boundary {
public float xMin, xMax, zMin, zMax;
}

public class PlayerController : MonoBehaviour {

public Boundary boundary;

[...]

// Use it like this: boundary.xMin, etc..

 

}

 

 

Android interface

How to communicate through an interface in Android between an activity and a custom view.

In this example we want to press a Button inside a custom-view and do something to another view on the activity layout.

 

Layout activity:

[...]
<com.savinoordine.CustomView
android:id="@+id/custom_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>

<View
android:id="@+id/view"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
[...]
// END ACTIVITY LAYOUT

Custom view Layout :

[...]
<Button
  android:id="@+id/buttom"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content" />
[...]
// END CUSTOM-VIEW LAYOUT

 

 

public class CustomView {
 private View mView;

 private void init() {
    mButton = (Button) findViewById(R.id.button);
 mButton.setOnClickListener(new OnClickListener() {
      @Override
      public void onClick(View v) {
      //when click is done, it is called the interface method that
      //it is implemented in activity (not in custom view) so view is shown up/more
        if (mOnButtonListener != null) {
            mOnButtonListener.onButtonPressed();
        }
    }
  });

    //set the listener
    public void setListener(OnButtonListener listener) {
      mOnButtonListener = listener;
    }

    //interface that communicate with the activity
    interface OnButtonListener {
      void onButtonPressed();
    }
  }
}

Inside the activity where the view has to be shown/other we have to implement the interface method.

[...] implements CustomView.OnButtonListener {

  //onCreate method
    mCustomView = (CustomView) findViewById(R.id.custom_view);
    mCustomView.setListener(this);
mView = (View) findViewById(R.id.view);

  //implement interface
  @Override
  public void onButtonPressed() {
   //do something with the mView
  }
}

Grant|Revoke permission with adb [Android M]

Hey there, Android M RC is almost out and one of the new feature is “manage permissions“, let’s see hot the grant or revoke a permission with adb. In this example, I am going to show how to revoke the camera permission at the Google Camera app.

First of all, let’s connect a phone on your computer and let’s see how many apps are installed:

>> ./adb shell pm list packages

You will get a list of package names:

[...]
com.google.android.GoogleCamera
[...]

 

Now we are going to get the list of all the permissions:

>> ./adb shell pm list permissions -d -g
[...]
group:android.permission-group.CAMERA
  permission:android.permission.CAMERA
[...]

And here how to revoke the permission:

>> ./adb shell pm revoke com.google.android.GoogleCamera  android.permission.CAMERA

and here how to grant it back:

>> ./adb shell pm grant com.google.android.GoogleCamera android.permission.CAMERA