Giter Club home page Giter Club logo

mi-band's Introduction

This repository is no longer maintained.

Due to personal issues, this project is no longer maintained. You can still use it. Also you can see this awesome projects:

  • Pangliang with his library I started with mine
  • Gadgetbridge I got all the activities part and some command ideas from them

Mi Band

Sweet and simple Android implementation to control some aspects of your Xiaomi Mi Band.

  • Connect and Disconnect
  • Start vibration (with pre defined and customs values)
  • Change led's colors (with pre defined and customs values)
  • Get battery info
  • Sync with your Mi Band (steps, slept hours, etc)
  • Real time step counter

Usage

Mi-Band is ultra simple to use! just follow this 1 step:

  1. In your app's dependencies add the library:

     dependencies {
         compile 'com.betomaluje.miband:app:1.0.4'
     }
    

that's it! You're ready!

Note: this is thanks to the new Android Studio that uses jCenter instead of MavenCentral. To see this, you can open your main build.gradle file, and under the repositories you should see jcenter(). If not, add this as a repository

   allprojects {
       repositories {
            mavenCentral()
            maven {
                url 'https://dl.bintray.com/betomaluje/maven/'
            }
        }
    }

Now, to start testing you can use this library in activities, fragments an even services! As an alternative you can use the pre defined MiBandService

  1. Define your Mi Band variable (globaly or localy, it doesn't matter because it's a Singleton) and pass it the current Context variable:

     MiBand miBand = MiBand.getInstance(MyActivity.this);
    
  2. Now, to toggle connection you can use

     if (!miBand.isConnected()) {
         miBand.connect(new ActionCallback() {
             @Override
             public void onSuccess(Object data) {
                 Log.d(TAG, "Connected with Mi Band!");
                 //show SnackBar/Toast or something
             }
    
             @Override
             public void onFail(int errorCode, String msg) {
                 Log.d(TAG, "Connection failed: " + msg);
             }
         });
     } else {
         miBand.disconnect();
     }
    

Actions

Now the fun part: sending commands to your band.

Vibration

For vibration you can use the following methods:

    //to vibrate using the default band color
    miBand.startVibration(VibrationMode.VIBRATION_WITH_LED);
    
    //to vibrate until you manually stop it
    miBand.startVibration(VibrationMode.VIBRATION_UNTIL_CALL_STOP);
    
    //to vibrate without the led
    miBand.startVibration(VibrationMode.VIBRATION_WITHOUT_LED);
    
    //to stop vibration
    miBand.stopVibration();

Also there's a custom vibration method

    miBand.customVibration(times, on_time, off_time);

where times is an int value to determine how many times will vibrate(I recommend to use between 1-3 times only) and on_time is the time in milliseconds that each vibration will be On (not more than 500 milliseconds) and off_time is the pause between each consecutive vibration

LED Color

To change the LED color, you can use

    miBand.setLedColor(color);

where color is an int value representing the color you want

For convenience, there's a ColorPickerDialog class to help choose the int value of a color

    new ColorPickerDialog(MyActivity.this, 255, new ColorPickerDialog.OnColorSelectedListener() {
        @Override
        public void onColorSelected(int rgb) {
            Log.i(TAG, "selected color: " + rgb);
            miBand.setLedColor(rgb);
        }
    }).show();

or you can use

    miBand.setLedColor(flash_time, color, pause_time);

where flash_time is an int value to determine how many times will the led flash (I recommend using 1-3 values only) and color is the int value of the color and pause_time is the pause in milliseconds between each flash

Battery Info

To get the battery information just use

    miBand.getBatteryInfo(new ActionCallback() {
        @Override
        public void onSuccess(final Object data) {
            BatteryInfo battery = (BatteryInfo) data;
            //get the cycle count, the level and other information
            Log.e(TAG, "Battery: " + battery.toString());
        }

        @Override
        public void onFail(int errorCode, String msg) {
            Log.e(TAG, "Fail battery: " + msg);
        }
    });

Syncronization

To sync data with yor Mi Band use

    miBand.startListeningSync();

this will start the sync process. Also you can

    if (miBand.isSyncNotification())
        miBand.stopListeningSync();

After you are finished syncing with the band, you can access the information using

    Calendar before = Calendar.getInstance();
    //7 days before
    before.add(Calendar.DAY_OF_WEEK, -7);
    long temp = before.getTimeInMillis() / 1000;
    before.setTimeInMillis(temp);

    Calendar today = Calendar.getInstance();
    //now
    today.setTimeInMillis(System.currentTimeMillis() / 1000);

    //use DateUtils to display the time in the format "yyyy-MM-dd HH:mm:ss"
    Log.i(TAG, "data from " + DateUtils.convertString(before) + " to " + DateUtils.convertString(today));

    //all our data is stored in ActivitySQLite as ActivityData objects
    ArrayList<ActivityData> allActivities = ActivitySQLite.getInstance(ActivitiesChartActivity.this)
            .getActivitySamples((int) before.getTimeInMillis(), (int) today.getTimeInMillis());

to get the sleeping data use

    ActivitySQLite.getInstance(MySleepActivity.this).getSleepSamples(int timestamp_from, int timestamp_to)

and to get the activity data use

    ActivitySQLite.getInstance(MyActivitiesActivity.this).getActivitySamples(int timestamp_from, int timestamp_to)

to get ALL the data use

    ActivitySQLite.getInstance(MyAllActivity.this).getAllActivitiesSamples(int timestamp_from, int timestamp_to)

Activities example

    Calendar before = Calendar.getInstance();
    //7 days before
    before.add(Calendar.DAY_OF_WEEK, -7);
    long temp = before.getTimeInMillis() / 1000;
    before.setTimeInMillis(temp);

    Calendar today = Calendar.getInstance();
    //now
    today.setTimeInMillis(System.currentTimeMillis() / 1000);

    //use DateUtils to display the time in the format "yyyy-MM-dd HH:mm:ss"
    Log.i(TAG, "data from " + DateUtils.convertString(before) + " to " + DateUtils.convertString(today));

    //all our data is stored in ActivitySQLite as ActivityData objects
    ArrayList<ActivityData> allActivities = ActivitySQLite.getInstance(ActivitiesChartActivity.this)
            .getActivitySamples((int) before.getTimeInMillis(), (int) today.getTimeInMillis());
            
    float movement_divisor = 180.0f;

    float value;

    String dateString = "";
    for (ActivityData ad : allActivities) {

        Calendar date = Calendar.getInstance();
        date.setTimeInMillis(ad.getTimestamp() * 1000L);

        dateString = DateUtils.convertString(date);

        Log.i(TAG, "date " + dateString);
        Log.i(TAG, "steps " + ad.getSteps());

        short movement = ad.getIntensity();

        byte steps = ad.getSteps();
        if (steps != 0) {
            // I'm not sure using steps for this is actually a good idea
            movement = steps;
        }
        
        //the value
        value = ((float) movement) / movement_divisor;
    }

Sleeping example

    Calendar before = Calendar.getInstance();
    //7 days before
    before.add(Calendar.DAY_OF_WEEK, -7);
    long temp = before.getTimeInMillis() / 1000;
    before.setTimeInMillis(temp);

    Calendar today = Calendar.getInstance();
    //now
    today.setTimeInMillis(System.currentTimeMillis() / 1000);

    //use DateUtils to display the time in the format "yyyy-MM-dd HH:mm:ss"
    Log.i(TAG, "data from " + DateUtils.convertString(before) + " to " + DateUtils.convertString(today));

    ArrayList<ActivityData> allActivities = ActivitySQLite.getInstance(SleepChartActivity.this)
            .getSleepSamples((int) before.getTimeInMillis(), (int) today.getTimeInMillis());

    float movement_divisor = 180.0f;

    float value;

    String dateString = "";
    for (ActivityData ad : allActivities) {

        Calendar date = Calendar.getInstance();
        date.setTimeInMillis(ad.getTimestamp() * 1000L);

        dateString = DateUtils.convertString(date);

        Log.i(TAG, "date " + dateString);
        Log.i(TAG, "steps " + ad.getSteps());

        value = ((float) ad.getIntensity()) / movement_divisor;

        switch (ad.getType()) {
            case ActivityData.TYPE_DEEP_SLEEP:
                //DEEP SLEEP TYPE. Only here we need to adjust the value
                value += ActivityData.Y_VALUE_DEEP_SLEEP;
                doSomethingWithDeepSleep(value);
                break;
            case ActivityData.TYPE_LIGHT_SLEEP:
                //LIGHT SLEEP TYPE
                doSomethingWithLightSleep(value);
                break;
            default:
                //UNKNOWN TYPE
                doSomethingWithUnknownSleep(value);
                break;
        }
    }

Also you can track the "Sleep comparison"

    private void refreshSleepAmounts(List<ActivityData> samples) {
        ActivityAnalysis analysis = new ActivityAnalysis();
        ActivityAmounts amounts = analysis.calculateActivityAmounts(samples);
        
        float hoursOfSleep = amounts.getTotalSeconds() / (float) (60 * 60);
        
         Log.i(TAG, "hoursOfSleep " + hoursOfSleep + " h");
        
        for (ActivityAmount amount : amounts.getAmounts()) {
            Log.i(TAG, "name " + amount.getName());
            Log.i(TAG, "total seconds " + amount.getTotalSeconds());
            Log.i(TAG, "kind " + amount.getActivityKind());
        }
    }

Known issues

First time connection

The first time you connect with your Mi Band please be patient. It takes around 45 seconds. After this time, if you can't connect to it, try the following

  1. Try disconnecting and again connecting to Bluetooth
  2. Uninstall and install again your app

Mi Fit app incompatibility

If you also have the Mi Fit app installed, you may lose some information on the syncing because Mi Fit and your app will be "fighting" to sync the Mi Band data. Once the Mi Band data is synced, it will be "deleted" from the band and lost forever.

Also the pairing process may ocurr several times each time you switch from apps because you will lose th pairing info from each app.

Nevertheless you can still send commands to the Mi Band if you are using both apps. It's not mandatory to uninstall Mi Fit to use this library.

Acknowledge

Thanks to

  1. Pangliang with his library I started with mine
  2. Gadgetbridge I got all the activities part and some command ideas from them

Contribute

Contributions are welcome, be it feedback, bugreports, documentation, translation, research or code. Feel free to work on any of the open issues; just leave a comment that you're working on one to avoid duplicated work.

mi-band's People

Contributors

betomaluje avatar bryant1410 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mi-band's Issues

Create plugin for cordova?

Hello, I'm having a hard time, I have an android application made in Cordova and I need to integrate, can you help me?

Invalid parameters UserInfo.create(UserInfo.java:74)

Hi,

I've tried very simple application (single button -> on click vibrate) but unfortunatelly it does not work.

git: https://github.com/MrTheodor/MiWatch

Here is what I noticed on logcat:

10-07 21:16:16.269 11983-12273/pl.jkrajniak.miwatch W/BluetoothGatt﹕ Unhandled exception in callback
java.lang.IllegalArgumentException: Invalid parameters
at com.betomaluje.miband.model.UserInfo.create(UserInfo.java:74)
at com.betomaluje.miband.model.UserInfo.getSavedUser(UserInfo.java:277)
at com.betomaluje.miband.MiBand$1.onSuccess(MiBand.java:54)
at com.betomaluje.miband.bluetooth.BTConnectionManager$3.onServicesDiscovered(BTConnectionManager.java:319)
at android.bluetooth.BluetoothGatt$1.onSearchComplete(BluetoothGatt.java:305)
at android.bluetooth.IBluetoothGattCallback$Stub.onTransact(IBluetoothGattCallback.java:217)
at android.os.Binder.execTransact(Binder.java:446)

Mi Band 2

Hello everyone,
I would like to build an app for Mi Band 2, with notifications of the apps on the mi band screen, also with features presents in this lib. but I didn't found an api for that. How this lib works on Mi Band 2?

Why not differ "TYPE_ACTIVITY" into walk and run?

Hello first of all.
I got my Mi Band last week, sniffed the bluetooth traffic between the official app and the Mi Band a little bit, and my final search if there are already projects trying to build a better alternative app brought me here.
Your project looks very promising after my first look at the well structured code. I'll take a deeper look hopefully at this weekend.

However, what i've noticed so far: The official App not only differs between Light Sleep and Deep Sleep, but also between steps run and steps walked.
You currently have the two Sleep types implemented, but only one type for activity which i think contains up to three different kind of activity: Walked, Run and last but not least the normal accelerometer data.

Custom vibration doesnt' work - Protocol problem?

Does anyone know how can I implement custom vibration? There are some protocol changes there, but I can't find what they are.
I changed service from fee0 to 1802 and other vibrations are working now, but there is another problem with service and protocol with custom vibration.

Anyone know how to fix that?

Sync fail: data null

I'm testing the example app on Nexus 4 with Android 5.1.1. It manages to connect to my Mi Band (original version with color LEDs), blink with LEDs, vibrate, but fails to sync data.

Logcat:

I/BTConnectionManager( 3020): trying to connect
I/BTConnectionManager( 3020): connecting...
D/BluetoothGatt( 3020): connect() - device: 88:0F:10:92:xx:xx, auto: false
D/BluetoothGatt( 3020): registerApp()
D/BluetoothGatt( 3020): registerApp() - UUID=ba833154-5870-4379-8396-e55b971348fa
D/BtGatt.GattService(31894): registerClient() - UUID=ba833154-5870-4379-8396-e55b971348fa
D/BtGatt.GattService(31894): onClientRegistered() - UUID=ba833154-5870-4379-8396-e55b971348fa, clientIf=6
D/BluetoothGatt( 3020): onClientRegistered() - status=0 clientIf=6
D/BtGatt.GattService(31894): clientConnect() - address=88:0F:10:92:xx:xx, isDirect=true
D/btif_config(31894): btif_get_address_type: Device [88:0f:10:92:xx:xx] address type 0
D/btif_config(31894): btif_get_device_type: Device [88:0f:10:92:xx:xx] type 2
D/ACDB-LOADER(  189): ACDB -> send_afe_cal
W/bt-btif (31894): info:x0
D/        (31894): remote version info [88:0f:10:92:xx:xx]: 0, 0, 0
D/BtGatt.GattService(31894): onConnected() - clientIf=6, connId=6, address=88:0F:10:92:xx:xx
D/btif_config(31894): btif_get_device_type: Device [88:0f:10:92:xx:xx] type 2
D/BluetoothGatt( 3020): onClientConnectionState() - status=0 clientIf=6 device=88:0F:10:92:xx:xx
D/BluetoothGatt( 3020): discoverServices() - device: 88:0F:10:92:xx:xx
D/BtGatt.GattService(31894): discoverServices() - address=88:0F:10:92:xx:xx, connId=6
D/BtGatt.GattService(31894): onSearchCompleted() - connId=6, status=0
D/BluetoothGatt( 3020): onSearchComplete() = Device=88:0F:10:92:xx:xx Status=0
I/BTConnectionManager( 3020): Stopping discovery
E/miband-android( 3020): Fail: No bluetooth devices
E/MainNormalActivity( 3020): Fail: No bluetooth devices
D/MainNormalActivity( 3020): not found
D/miband-android( 3020): Connection success, now pair: true
D/MainNormalActivity( 3020): Connected with Mi Band!
I/ActivityManager(  552): START u0 {cmp=com.betomaluje.android.miband.example/.activities.ActivitiesChartActivity} from uid 10061 on display 0
V/WindowManager(  552): addAppToken: AppWindowToken{1fa1572f token=Token{51e310e ActivityRecord{2f86db09 u0 com.betomaluje.android.miband.example/.activities.ActivitiesChartActivity t442}}} to stack=1 task=442 at 2
D/ACDB-LOADER(  189): ACDB -> send_afe_cal
I/AppCompatViewInflater( 3020): app:theme is now deprecated. Please move to using android:theme instead.
V/WindowManager(  552): Adding window Window{25391ec5 u0 com.betomaluje.android.miband.example/com.betomaluje.android.miband.example.activities.ActivitiesChartActivity} at 6 of 12 (after Window{32bd9837 u0 com.betomaluje.android.miband.example/com.betomaluje.android.miband.example.activities.MainNormalActivity})
I/ActivityManager(  552): Displayed com.betomaluje.android.miband.example/.activities.ActivitiesChartActivity: +161ms
I/ActivityManager(  552): START u0 {cmp=com.betomaluje.android.miband.example/.activities.ActivitiesChartActivity} from uid 10061 on display 0
V/WindowManager(  552): addAppToken: AppWindowToken{32fef9be token=Token{89f9879 ActivityRecord{11d6e140 u0 com.betomaluje.android.miband.example/.activities.ActivitiesChartActivity t442}}} to stack=1 task=442 at 2
D/ACDB-LOADER(  189): ACDB -> send_afe_cal
I/AppCompatViewInflater( 3020): app:theme is now deprecated. Please move to using android:theme instead.
V/WindowManager(  552): Adding window Window{26e8d16c u0 com.betomaluje.android.miband.example/com.betomaluje.android.miband.example.activities.ActivitiesChartActivity} at 6 of 12 (after Window{32bd9837 u0 com.betomaluje.android.miband.example/com.betomaluje.android.miband.example.activities.MainNormalActivity})
I/ActivityManager(  552): Displayed com.betomaluje.android.miband.example/.activities.ActivitiesChartActivity: +133ms
D/BluetoothGatt( 3020): setCharacteristicNotification() - uuid: 0000ff03-0000-1000-8000-00805f9b34fb enable: true
D/BtGatt.GattService(31894): registerForNotification() - address=88:0F:10:92:xx:xx enable: true
D/BtGatt.GattService(31894): onRegisterForNotifications() - address=null, status=0, registered=1, charUuid=0000ff03-0000-1000-8000-00805f9b34fb
D/BluetoothGatt( 3020): setCharacteristicNotification() - uuid: 0000ff06-0000-1000-8000-00805f9b34fb enable: true
D/BtGatt.GattService(31894): registerForNotification() - address=88:0F:10:92:xx:xx enable: true
D/BtGatt.GattService(31894): onRegisterForNotifications() - address=null, status=0, registered=1, charUuid=0000ff06-0000-1000-8000-00805f9b34fb
D/BluetoothGatt( 3020): setCharacteristicNotification() - uuid: 0000ff07-0000-1000-8000-00805f9b34fb enable: true
D/BtGatt.GattService(31894): registerForNotification() - address=88:0F:10:92:xx:xx enable: true
D/BtGatt.GattService(31894): onRegisterForNotifications() - address=null, status=0, registered=1, charUuid=0000ff07-0000-1000-8000-00805f9b34fb
D/BluetoothGatt( 3020): setCharacteristicNotification() - uuid: 0000ff0c-0000-1000-8000-00805f9b34fb enable: true
D/BtGatt.GattService(31894): registerForNotification() - address=88:0F:10:92:xx:xx enable: true
D/BtGatt.GattService(31894): onRegisterForNotifications() - address=null, status=0, registered=1, charUuid=0000ff0c-0000-1000-8000-00805f9b34fb
D/BluetoothGatt( 3020): setCharacteristicNotification() - uuid: 0000ff0e-0000-1000-8000-00805f9b34fb enable: true
D/BtGatt.GattService(31894): registerForNotification() - address=88:0F:10:92:xx:xx enable: true
D/BtGatt.GattService(31894): onRegisterForNotifications() - address=null, status=0, registered=1, charUuid=0000ff0e-0000-1000-8000-00805f9b34fb
E/MainNormalActivity( 3020): Sync fail: data null
I/BTCommandManager( 3020): handleControlPoint GOT DATA:0x       6

Rename resources to avoid conflict

Hi @betomaluje,
Any chance we can rename the resources used by the library?

Currently, @drawable/ic_launcher and @string/app_name are declared and this causes a conflict when importing the library via jCenter to an Android Studio-generated project.

Q: Mi Band Sync Activity Data Protocol

Hi,

Thanks for the useful repo.

This is actually just a question. Can we get activity data and/or sleep data? If so, mind to share what are the example command sent to the activity control characteristic in term of bytes? is it something like this "\x01\x01\xE2\x07\x05\x03\x11\x2F\x00\x08"?

I believe this is the one called for activity notification but can anyone help me to understand the parsing?

I would appreciate if you can help. Thank you.

Vibration no longer working with new firmware

Hi @betomaluje,
First of all, thanks for this awesome Android library!

I'm thinking of integrating it with my RedAlert app, so that deaf people will know there is a rocket alert in their area (via vibration mostly).

I tried the MiBandExample project, and it works pretty nicely (everything except for the vibration, which doesn't really do anything for some reason) -- is this something you are aware of?

My bet is that they changed something in the new firmware.

Thanks!

Cannot connect

Hi all
I'm trying out the example app, but I cannot get it to connect. The band is working fine with its official app, but, when I try this one, I get:

02-09 08:56:08.699 26181-26181/? I/BTConnectionManager: trying to connect
02-09 08:56:08.703 26181-26181/? I/BTConnectionManager: connecting...
02-09 08:56:08.706 26181-26181/? I/BTConnectionManager: not already paired
02-09 08:56:08.706 26181-26181/? D/BluetoothAdapter: stopLeScan()
02-09 08:56:08.706 26181-26181/? D/BluetoothAdapter: STATE_ON
02-09 08:56:08.707 26181-26181/? I/BTConnectionManager: Starting BTLE Discovery
02-09 08:56:08.709 26181-26181/? D/BluetoothAdapter: startLeScan(): null
02-09 08:56:08.710 26181-26181/? D/BluetoothAdapter: STATE_ON
02-09 08:56:08.712 26181-6142/? D/BluetoothLeScanner: onClientRegistered() - status=0 clientIf=6
02-09 08:56:08.717 26181-26181/? V/BTConnectionManager: starting scan
02-09 08:56:53.730 26181-26181/? I/BTConnectionManager: Stopping discovery
02-09 08:56:53.732 26181-26181/? E/miband-android: Fail: No bluetooth devices
02-09 08:56:53.732 26181-26181/? E/MainNormalActivity: Fail: No bluetooth devices
02-09 08:56:53.732 26181-26181/? D/MainNormalActivity: not found

I'm having the same issue with the Activity and the Service. I'm working with Android 6. Band firmware is 1.0.9.55. Any help, please?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.