#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 youg 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.



#此存储库不再维护。 由于个人问题,本项目不再维护。你仍然可以使用它。还可以看到这个很棒的项目:

  • Pangliang 与他的图书馆我开始与我的
  • Gadgetbridge 我收到了所有的活动和一些来自他们的指导意见。

#Mi乐队 甜美简单的Android实现,以控制您的小米米乐队的某些方面。

  • 连接并断开连接
  • 启动振动(具有预定义和海关值)
  • 更改led的颜色(具有预定义和习俗值)
  • 获取电池信息
  • 与您的Mi乐队同步(步骤,睡眠时间等)
  • 实时计数器

##用法 Mi-Band是超简单的使用!只需按照这一步:

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

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

就是这样!你准备好了!

注意:这是由于新的Android Studio使用jCenter而不是MavenCentral。要看到这一点,你可以打开你的主要的 build.gradle 文件,在存储库下,你应该看到 jcenter()。如果没有,请将其添加为存储库

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

现在,要开始测试,您可以在活动,片段,甚至服务! 另外,您也可以使用预先定义的 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();
     }
    

##动作 现在有趣的部分:发送命令到您的乐队。

###振动 对于振动,您可以使用以下方法:

    //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();

还有一种自定义振动方法

    miBand.customVibration(times, on_time, off_time);

其中 times 是一个int值,用于确定 将振动多少次(我建议仅使用1-3次) 而 on_time 是以毫秒为单位的时间,每个振动将(不超过500毫秒) 而 off_time 是连续振动之间的暂停

### LED颜色 要更改LED颜色,可以使用

    miBand.setLedColor(color);

其中 color 是表示您想要的颜色的int值

为了方便起见,有一个 ColorPickerDialog 类来帮助选择颜色的int值

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

或您可以使用

    miBand.setLedColor(flash_time, color, pause_time);

其中 flash_time 是一个int值,用于确定led闪光灯的几倍(我建议仅使用1-3个值) 而 color 是颜色的int pause_time 是每个闪光灯之间的毫秒级的暂停

###电池信息 要获取电池信息,只需使用

    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 要与yor Mi Band同步数据,请使用

    miBand.startListeningSync();

这将启动同步过程。也可以

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

完成与乐队同步后,您可以使用

访问信息
    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());

获取睡眠数据使用

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

并使用

获取活动数据
    ActivitySQLite.getInstance(MyActivitiesActivity.this).getActivitySamples(int timestamp_from, int timestamp_to)

获取所有数据使用

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

####活动示例

    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;
    }

####睡眠示例

    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;
        }
    }

此外,您还可以跟踪睡眠比较

    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());
        }
    }
已知问题 ###第一次连接 你第一次连接你的Mi乐队请耐心等待。大约需要45秒之后,如果您无法连接到它,请尝试以下

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

### Mi Fit应用程序不兼容 如果您还安装了Mi Fit应用程序,则可能会丢失一些有关同步信息的信息,因为Mi Fit和您的应用将战斗同步Mi Band数据。一旦Mi Band数据被同步,它将被从频带删除,并永远丢失。

此外,每次从应用切换时,配对过程可能会发生多次,因为您将丢失每个应用的配对信息。

然而,如果您正在使用这两个应用程序,您仍然可以向Mi Band发送命令。不要强制卸载Mi Fit以使用此库。

##确认 感谢

  1. Pangliang with his library I started with mine
  2. Gadgetbridge I got all the activities part and some command ideas from them
贡献 欢迎您的贡献,无论是反馈,bugreports,文档,翻译,研究或代码。随时可以使用任何开放的问题;只需留下您正在努力的评论,以避免重复的工作。




相关问题推荐