Android Open Source - MSMBle Control Light Activity






From Project

Back to project page MSMBle.

License

The source code is released under:

Created by Javier Montaner (twitter: @tumaku_) during M-week (February 2014) of MakeSpaceMadrid http://www.makespacemadrid.org @ 2014 Javier Montaner Licensed under the MIT Open Source License htt...

If you think the Android project MSMBle listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Created by Javier Montaner  (twitter: @tumaku_) during M-week (February 2014) of MakeSpaceMadrid
 * http://www.makespacemadrid.org// w ww. j  av  a 2 s . c  o  m
 * @ 2014 Javier Montaner
 * 
 * Licensed under the MIT Open Source License 
 * http://opensource.org/licenses/MIT
 * 
 * Many thanks to Yeelight (special mention to Daping Liu) and Double Encore (Dave Smith)
 * for their support and shared knowlegde
 * 
 * Based on the API released by Yeelight:
 * http://www.yeelight.com/en_US/info/download
 * 
 * Based on the code created by Dave Smith (Double Encore):
 * https://github.com/devunwired/accessory-samples/tree/master/BluetoothGatt
 * http://www.doubleencore.com/2013/12/bluetooth-smart-for-android/
 * 
 * 
 * Scan Bluetooth Low Energy devices and their services and characteristics.
 * If the Yeelight Service is found, an activity can be launched to control colour and intensity of Yeelight Blue bulb
 * 
 * Tested on a Nexus 7 (2013)
 * 
 */
package com.tumaku.msmble;

import java.util.List;


import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffColorFilter;
import android.graphics.Typeface;
import android.media.ToneGenerator;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.SeekBar.OnSeekBarChangeListener;

public class ControlLightActivity extends Activity implements OnSeekBarChangeListener {
  
  private final static int STATE2_CONNECT=0;
  private final static int STATE2_SEARCH_SERVICES=1;
  private final static int STATE2_READ=2;
  private final static int STATE2_WRITE=3; 
  private final static int STATE2_DISCONNECT=4;
      
  private SeekBar mSeekBarRed;
  private SeekBar mSeekBarGreen;
  private SeekBar mSeekBarBlue;
  private SeekBar mSeekBarIntensity;
  private TextView mTextRed;
  private TextView mTextGreen;
  private TextView mTextBlue;
  private TextView mTextIntensity;
  private TextView mTextInfo;
  private Button mButtonRead;
  private Button mButtonReset;

  private TextView mTextColourSample;
  private Context mContext;
  private YeelightBLEBroadcastReceiver mBroadcastReceiver;
  private String mDeviceAddress;
  private int mState2=0;
  
  private TumakuBLE  mTumakuBLE=null;
  private String  mControlString="128,128,128,100,,,";

  @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.light_control);           
        mContext=this;
        mBroadcastReceiver= new YeelightBLEBroadcastReceiver();
        mDeviceAddress=getIntent().getStringExtra(TumakuBLE.EXTRA_ADDRESS);
        if (mDeviceAddress==null) {
            if (Constant.DEBUG) Log.i("JMG","No device address received to start ControlLight Activity");
          finish();
        }
        //mTumakuBLE= TumakuBLE.getInstance(mContext);
    mTumakuBLE=((TumakuBLEApplication)getApplication()).getTumakuBLEInstance(this);
        mTumakuBLE.setDeviceAddress(mDeviceAddress);
        mSeekBarRed = (SeekBar) findViewById(R.id.seekBarRed);
        mSeekBarRed.setOnSeekBarChangeListener(this);
        mSeekBarRed.getProgressDrawable().setColorFilter(new PorterDuffColorFilter(Color.RED, PorterDuff.Mode.OVERLAY));
        mSeekBarGreen = (SeekBar) findViewById(R.id.seekBarGreen);
        mSeekBarGreen.setOnSeekBarChangeListener(this);
        mSeekBarGreen.getProgressDrawable().setColorFilter(new PorterDuffColorFilter(Color.GREEN, PorterDuff.Mode.OVERLAY));
        mSeekBarBlue = (SeekBar) findViewById(R.id.seekBarBlue);
        mSeekBarBlue.setOnSeekBarChangeListener(this);
        mSeekBarBlue.getProgressDrawable().setColorFilter(new PorterDuffColorFilter(Color.BLUE, PorterDuff.Mode.OVERLAY));
        mSeekBarIntensity = (SeekBar) findViewById(R.id.seekBarIntensity);
        mSeekBarIntensity.setOnSeekBarChangeListener(this);
        mSeekBarIntensity.getProgressDrawable().setColorFilter(new PorterDuffColorFilter(Color.BLACK, PorterDuff.Mode.MULTIPLY));
        mTextRed = (TextView) findViewById(R.id.textRed);
        mTextGreen = (TextView) findViewById(R.id.textGreen);
        mTextBlue = (TextView) findViewById(R.id.textBlue);
        mTextIntensity = (TextView) findViewById(R.id.textIntensity);
        mTextColourSample = (TextView) findViewById(R.id.colourSample);
        mTextRed.setTypeface(null, Typeface.BOLD);
        mTextGreen.setTypeface(null, Typeface.BOLD);
        mTextBlue.setTypeface(null, Typeface.BOLD);
        mTextIntensity.setTypeface(null, Typeface.BOLD);
        mTextInfo=(TextView) findViewById(R.id.textInfo);
        mButtonRead= (Button) findViewById(R.id.buttonRead);
        mButtonReset= (Button) findViewById(R.id.buttonReset);
        restoreValues();
        
        mButtonRead.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
              if (mState2>=STATE2_READ) {
                mState2=STATE2_READ;
                nextState2();  
              }
            }
        });

        mButtonReset.setOnClickListener(new View.OnClickListener() {
            public void onClick(View v) {
                  mState2=STATE2_CONNECT;
                   mTumakuBLE.resetTumakuBLE();
                mTumakuBLE.setDeviceAddress(mDeviceAddress);
               updateInfoText("Reset connection to device");
                nextState2();  
            }
        });
  
  }
  
  @Override
  public void onResume(){
    super.onResume();
    IntentFilter filter = new IntentFilter(TumakuBLE.WRITE_SUCCESS);
    filter.addAction(TumakuBLE.READ_SUCCESS);    
    filter.addAction(TumakuBLE.DEVICE_CONNECTED);    
    filter.addAction(TumakuBLE.DEVICE_DISCONNECTED);    
    filter.addAction(TumakuBLE.SERVICES_DISCOVERED);    
    this.registerReceiver(mBroadcastReceiver, filter);
    if (mTumakuBLE.isConnected()){
      mState2=STATE2_WRITE;
      nextState2();
       updateInfoText("Resume connection to device");
    } else {
      mState2=STATE2_CONNECT;
      nextState2();
       updateInfoText("Start connection to device");
    }
    
  }
  
  @Override
  public void onStop(){
    super.onStop();
    storeValues();
        this.unregisterReceiver(this.mBroadcastReceiver);
  }
  
  @Override
  public void onDestroy(){
    super.onDestroy();
        //mTumakuBLE.disconnect();
  }
  
    @Override
  public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
     updateDisplay();
     if (mState2>=STATE2_READ) {
       mState2=STATE2_WRITE;
       nextState2();
     }
  }
  
  @Override
  public void onStartTrackingTouch(SeekBar arg0) {
    // TODO Auto-generated method stub
  }
  
  @Override
  public void onStopTrackingTouch(SeekBar arg0) {
    storeValues();
    updateDisplay();
      // mState2=STATE2_READ;
      // nextState2();
  }
  
    
    protected void nextState2(){
      switch(mState2) {         
         case (STATE2_CONNECT):
             if (Constant.DEBUG) Log.i("JMG","State Connected");
             mTumakuBLE.connect();
             break;
         case(STATE2_SEARCH_SERVICES):
             if (Constant.DEBUG) Log.i("JMG","State Search Services");
           mTumakuBLE.discoverServices();
             break;         
         case(STATE2_READ):
             if (Constant.DEBUG) Log.i("JMG","State Read");
              mTumakuBLE.read(TumakuBLE.YEELIGHT_SERVICE,TumakuBLE.CHARACTERISTIC_CONTROL);
           break;
         case(STATE2_WRITE):
             if (Constant.DEBUG) Log.i("JMG","State Write");
              mTumakuBLE.write(TumakuBLE.YEELIGHT_SERVICE,TumakuBLE.CHARACTERISTIC_CONTROL,mControlString);
           break;
         case(STATE2_DISCONNECT):
             if (Constant.DEBUG) Log.i("JMG","State Disconect");
             // mTumakuBLE.disconnect();
           
           break;
         default:
           
      }      
      
    }
    
  
  protected void updateInfoText(String text) {
    mTextInfo.setText(text);
  }
  
  
    private void restoreValues() {
      SharedPreferences settings = getSharedPreferences(getString(R.string.prefsFile), 0);        
      int redValue= settings.getInt(getString(R.string.red),0);
      int greenValue= settings.getInt(getString(R.string.green),0);
      int blueValue= settings.getInt(getString(R.string.blue),0);
      int intensityValue= settings.getInt(getString(R.string.intensity),0);
      
      mSeekBarRed.setProgress(redValue);
      mSeekBarGreen.setProgress(greenValue);
      mSeekBarBlue.setProgress(blueValue);
      mSeekBarIntensity.setProgress(intensityValue);
      updateDisplay();
    }
  
    private void storeValues(){
      SharedPreferences settings = getSharedPreferences(getString(R.string.prefsFile), 0);
      SharedPreferences.Editor editor = settings.edit();
      editor.putInt(getString(R.string.red),mSeekBarRed.getProgress());
      editor.putInt(getString(R.string.green),mSeekBarGreen.getProgress());
      editor.putInt(getString(R.string.blue),mSeekBarBlue.getProgress());
      editor.putInt(getString(R.string.intensity),mSeekBarIntensity.getProgress());
      editor.commit();
    }
    
    
    private  void updateDisplay(){
        mTextRed.setText(getString(R.string.red)+": "+ mSeekBarRed.getProgress());
     mTextGreen.setText(getString(R.string.green)+": "+ mSeekBarGreen.getProgress());
     mTextBlue.setText(getString(R.string.blue)+": "+ mSeekBarBlue.getProgress());
     mTextIntensity.setText(getString(R.string.intensity)+": "+ mSeekBarIntensity.getProgress());
       mTextColourSample.setBackgroundColor(
          Color.rgb(mSeekBarRed.getProgress(),mSeekBarGreen.getProgress(),mSeekBarBlue.getProgress()));
       mControlString=threeDigits(mSeekBarRed.getProgress())+","+threeDigits(mSeekBarGreen.getProgress())+","+
           threeDigits(mSeekBarBlue.getProgress())+","+threeDigits(mSeekBarIntensity.getProgress())+","+",,";
       mControlString=generateControLString();
    }
    
    private String generateControLString() {
      String result=""+mSeekBarRed.getProgress()+","+mSeekBarGreen.getProgress()+","+mSeekBarBlue.getProgress()+","
          +mSeekBarIntensity.getProgress()+",";
        while (result.length()<18){result+=",";}
      return result;
    }
   
    private String threeDigits(int value) {
      if (value <0) value=-value;
      if (value>255) value%=256;
      if (value<10) return ("00"+value);
      if (value<100) return ("0"+value);
      return (""+ value);
    }
    
    
    private class YeelightBLEBroadcastReceiver extends BroadcastReceiver {
    //YeelightCallBack.WRITE_SUCCESS);
    //YeelightCallBack.READ_SUCCESS);    
    //YeelightCallBack.DEVICE_CONNECTED);    

       @Override
       public void onReceive(Context context, Intent intent) {
           if (intent.getAction().equals(TumakuBLE.DEVICE_CONNECTED)) {
           if (Constant.DEBUG) Log.i("JMG","DEVICE_CONNECTED message received");
           
             updateInfoText("Received connection event");
             mState2=STATE2_SEARCH_SERVICES;
             nextState2();
             return;
           }
           if (intent.getAction().equals(TumakuBLE.DEVICE_DISCONNECTED)) {
           if (Constant.DEBUG) Log.i("JMG","DEVICE_DISCONNECTED message received");
           //This is an unexpected device disconnect situation generated by Android BLE stack
           //Usually happens on the service discovery step :-(
           //Try to reconnect
           String fullReset=intent.getStringExtra(TumakuBLE.EXTRA_FULL_RESET);
           if (fullReset!=null){
             if (Constant.DEBUG) Log.i("JMG","DEVICE_DISCONNECTED message received with full reset flag");
             Toast.makeText(mContext, "Unrecoverable BT error received. Launching full reset", Toast.LENGTH_SHORT).show();    
               mState2=STATE2_CONNECT;
                mTumakuBLE.resetTumakuBLE();
                mTumakuBLE.setDeviceAddress(mDeviceAddress);
                mTumakuBLE.setup();
               nextState2();
               return;             
           } else {                      
             if (mState2!=STATE2_CONNECT){
               Toast.makeText(mContext, "Device disconnected unexpectedly. Reconnecting.", Toast.LENGTH_SHORT).show();    
                 mState2=STATE2_CONNECT;
                  mTumakuBLE.resetTumakuBLE();
                  mTumakuBLE.setDeviceAddress(mDeviceAddress);
                 nextState2();
                 return;
             }
           }
           }
           if (intent.getAction().equals(TumakuBLE.SERVICES_DISCOVERED)) {
           if (Constant.DEBUG) Log.i("JMG","SERVICES_DISCOVERED message received");
           
             updateInfoText("Received services discovered event");
             mState2=STATE2_WRITE;
             nextState2();
             return;
           }

           if (intent.getAction().equals(TumakuBLE.READ_SUCCESS)) {
           if (Constant.DEBUG) Log.i("JMG","READ_SUCCESS message received");
           String readValue= intent.getStringExtra(TumakuBLE.EXTRA_VALUE);
           if (readValue==null) updateInfoText("Received Read Success Event but no value in Intent"  );
           else updateInfoText("Received Read Success Event: " + readValue);
             //mState2=STATE2_DISCONNECT;
             //nextState2();
             return;
           }

           if (intent.getAction().equals(TumakuBLE.WRITE_SUCCESS)) {
           if (Constant.DEBUG) Log.i("JMG","WRITE_SUCCESS message received");
             updateInfoText("Received Write Success Event");
             //mState2=STATE2_READ;             
             //nextState2();
             return;
           }       
       }
       
    }
}




Java Source Code List

com.tumaku.msmble.BLEduinoUartActivity.java
com.tumaku.msmble.Constant.java
com.tumaku.msmble.ControlLightActivity.java
com.tumaku.msmble.DeviceActivity.java
com.tumaku.msmble.HM10Activity.java
com.tumaku.msmble.MainActivity.java
com.tumaku.msmble.SensorTagActivity.java
com.tumaku.msmble.ServiceActivity.java
com.tumaku.msmble.TethercellActivity.java
com.tumaku.msmble.TumakuBLEApplication.java
com.tumaku.msmble.TumakuBLE.java