diff --git a/.metadata/.lock b/.metadata/.lock new file mode 100644 index 0000000..e69de29 diff --git a/.metadata/.log b/.metadata/.log new file mode 100644 index 0000000..f4568a5 --- /dev/null +++ b/.metadata/.log @@ -0,0 +1,562 @@ +!SESSION 2014-12-19 23:01:44.389 ----------------------------------------------- +eclipse.buildId=4.4.1.M20140925-0400 +java.version=1.8.0_20 +java.vendor=Oracle Corporation +BootLoader constants: OS=macosx, ARCH=x86_64, WS=cocoa, NL=en_US +Framework arguments: -product org.eclipse.epp.package.java.product -product org.eclipse.epp.package.java.product -keyring /Users/paul/.eclipse_keyring -showlocation +Command-line arguments: -os macosx -ws cocoa -arch x86_64 -product org.eclipse.epp.package.java.product -data /Users/paul/Documents/MiBandAndroid -product org.eclipse.epp.package.java.product -keyring /Users/paul/.eclipse_keyring -showlocation + +!ENTRY org.eclipse.m2e.logback.configuration 2 0 2014-12-19 23:01:46.249 +!MESSAGE Exception while setting up logging:org.eclipse.osgi.internal.framework.EquinoxConfiguration$1 cannot be cast to java.lang.String +!STACK 0 +java.lang.ClassCastException: org.eclipse.osgi.internal.framework.EquinoxConfiguration$1 cannot be cast to java.lang.String + at org.eclipse.m2e.logback.configuration.LogHelper.logJavaProperties(LogHelper.java:26) + at org.eclipse.m2e.logback.configuration.LogPlugin.loadConfiguration(LogPlugin.java:189) + at org.eclipse.m2e.logback.configuration.LogPlugin.configureLogback(LogPlugin.java:144) + at org.eclipse.m2e.logback.configuration.LogPlugin.access$2(LogPlugin.java:107) + at org.eclipse.m2e.logback.configuration.LogPlugin$1.run(LogPlugin.java:62) + at java.util.TimerThread.mainLoop(Timer.java:555) + at java.util.TimerThread.run(Timer.java:505) + +!ENTRY org.eclipse.core.net 1 0 2014-12-19 23:01:48.000 +!MESSAGE System property http.nonProxyHosts has been set to local|*.local|169.254/16|*.169.254/16 by an external source. This value will be overwritten using the values from the preferences + +!ENTRY com.android.ide.eclipse.adt 4 0 2014-12-19 23:14:02.169 +!MESSAGE Failed to load properties file for project 'MiBand' + +!ENTRY com.android.ide.eclipse.adt 2 0 2014-12-19 23:14:15.171 +!MESSAGE Failed to render set of icons for TabHost + +!ENTRY com.android.ide.eclipse.adt 4 0 2014-12-19 23:14:15.172 +!MESSAGE Could not create tab content because could not find view with id -1 +!STACK 0 +java.lang.RuntimeException: Could not create tab content because could not find view with id -1 + at android.widget.TabHost$ViewIdContentStrategy.(TabHost.java:695) + at android.widget.TabHost$ViewIdContentStrategy.(TabHost.java:686) + at android.widget.TabHost$TabSpec.setContent(TabHost.java:535) + at com.android.layoutlib.bridge.impl.RenderSessionImpl.setupTabHost(RenderSessionImpl.java:1373) + at com.android.layoutlib.bridge.impl.RenderSessionImpl.postInflateProcess(RenderSessionImpl.java:1218) + at com.android.layoutlib.bridge.impl.RenderSessionImpl.postInflateProcess(RenderSessionImpl.java:1296) + at com.android.layoutlib.bridge.impl.RenderSessionImpl.postInflateProcess(RenderSessionImpl.java:1296) + at com.android.layoutlib.bridge.impl.RenderSessionImpl.inflate(RenderSessionImpl.java:411) + at com.android.layoutlib.bridge.Bridge.createSession(Bridge.java:332) + at com.android.ide.common.rendering.LayoutLibrary.createSession(LayoutLibrary.java:332) + at com.android.ide.eclipse.adt.internal.editors.layout.gle2.RenderService.createRenderSession(RenderService.java:517) + at com.android.ide.eclipse.adt.internal.editors.layout.gle2.PreviewIconFactory.render(PreviewIconFactory.java:273) + at com.android.ide.eclipse.adt.internal.editors.layout.gle2.PreviewIconFactory.initColors(PreviewIconFactory.java:595) + at com.android.ide.eclipse.adt.internal.editors.layout.gle2.PreviewIconFactory.getBackgroundColor(PreviewIconFactory.java:570) + at com.android.ide.eclipse.adt.internal.editors.layout.gle2.PaletteControl.reloadPalette(PaletteControl.java:437) + at com.android.ide.eclipse.adt.internal.editors.layout.gle2.GraphicalEditorPart.reloadPalette(GraphicalEditorPart.java:1327) + at com.android.ide.eclipse.adt.internal.editors.layout.gle2.GraphicalEditorPart.changed(GraphicalEditorPart.java:771) + at com.android.ide.eclipse.adt.internal.editors.layout.gle2.GraphicalEditorPart.onTargetChange(GraphicalEditorPart.java:1196) + at com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate.onDescriptorsChanged(LayoutEditorDelegate.java:916) + at com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate.delegateInitUiRootNode(LayoutEditorDelegate.java:835) + at com.android.ide.eclipse.adt.internal.editors.layout.gle2.GraphicalEditorPart$TargetListener.updateEditor(GraphicalEditorPart.java:953) + at com.android.ide.eclipse.adt.internal.editors.layout.gle2.GraphicalEditorPart$TargetListener.onTargetLoaded(GraphicalEditorPart.java:917) + at com.android.ide.eclipse.adt.AdtPlugin$11.run(AdtPlugin.java:1749) + at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35) + at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:136) + at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3983) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3660) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$9.run(PartRenderingEngine.java:1151) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1032) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:148) + at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:636) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:579) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:150) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:135) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:380) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:235) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:483) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:648) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:603) + at org.eclipse.equinox.launcher.Main.run(Main.java:1465) + +!ENTRY com.android.ide.eclipse.adt 2 0 2014-12-19 23:14:15.180 +!MESSAGE Failed to render set of icons for TabWidget + +!ENTRY com.android.ide.eclipse.adt 4 0 2014-12-19 23:14:15.180 +!MESSAGE Could not create tab content because could not find view with id -1 +!STACK 0 +java.lang.RuntimeException: Could not create tab content because could not find view with id -1 + at android.widget.TabHost$ViewIdContentStrategy.(TabHost.java:695) + at android.widget.TabHost$ViewIdContentStrategy.(TabHost.java:686) + at android.widget.TabHost$TabSpec.setContent(TabHost.java:535) + at com.android.layoutlib.bridge.impl.RenderSessionImpl.setupTabHost(RenderSessionImpl.java:1373) + at com.android.layoutlib.bridge.impl.RenderSessionImpl.postInflateProcess(RenderSessionImpl.java:1218) + at com.android.layoutlib.bridge.impl.RenderSessionImpl.postInflateProcess(RenderSessionImpl.java:1296) + at com.android.layoutlib.bridge.impl.RenderSessionImpl.postInflateProcess(RenderSessionImpl.java:1296) + at com.android.layoutlib.bridge.impl.RenderSessionImpl.inflate(RenderSessionImpl.java:411) + at com.android.layoutlib.bridge.Bridge.createSession(Bridge.java:332) + at com.android.ide.common.rendering.LayoutLibrary.createSession(LayoutLibrary.java:332) + at com.android.ide.eclipse.adt.internal.editors.layout.gle2.RenderService.createRenderSession(RenderService.java:517) + at com.android.ide.eclipse.adt.internal.editors.layout.gle2.PreviewIconFactory.render(PreviewIconFactory.java:273) + at com.android.ide.eclipse.adt.internal.editors.layout.gle2.PreviewIconFactory.initColors(PreviewIconFactory.java:595) + at com.android.ide.eclipse.adt.internal.editors.layout.gle2.PreviewIconFactory.getBackgroundColor(PreviewIconFactory.java:570) + at com.android.ide.eclipse.adt.internal.editors.layout.gle2.PaletteControl.reloadPalette(PaletteControl.java:437) + at com.android.ide.eclipse.adt.internal.editors.layout.gle2.GraphicalEditorPart.reloadPalette(GraphicalEditorPart.java:1327) + at com.android.ide.eclipse.adt.internal.editors.layout.gle2.GraphicalEditorPart.changed(GraphicalEditorPart.java:771) + at com.android.ide.eclipse.adt.internal.editors.layout.gle2.GraphicalEditorPart.onTargetChange(GraphicalEditorPart.java:1196) + at com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate.onDescriptorsChanged(LayoutEditorDelegate.java:916) + at com.android.ide.eclipse.adt.internal.editors.layout.LayoutEditorDelegate.delegateInitUiRootNode(LayoutEditorDelegate.java:835) + at com.android.ide.eclipse.adt.internal.editors.layout.gle2.GraphicalEditorPart$TargetListener.updateEditor(GraphicalEditorPart.java:953) + at com.android.ide.eclipse.adt.internal.editors.layout.gle2.GraphicalEditorPart$TargetListener.onTargetLoaded(GraphicalEditorPart.java:917) + at com.android.ide.eclipse.adt.AdtPlugin$11.run(AdtPlugin.java:1749) + at org.eclipse.swt.widgets.RunnableLock.run(RunnableLock.java:35) + at org.eclipse.swt.widgets.Synchronizer.runAsyncMessages(Synchronizer.java:136) + at org.eclipse.swt.widgets.Display.runAsyncMessages(Display.java:3983) + at org.eclipse.swt.widgets.Display.readAndDispatch(Display.java:3660) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine$9.run(PartRenderingEngine.java:1151) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332) + at org.eclipse.e4.ui.internal.workbench.swt.PartRenderingEngine.run(PartRenderingEngine.java:1032) + at org.eclipse.e4.ui.internal.workbench.E4Workbench.createAndRunUI(E4Workbench.java:148) + at org.eclipse.ui.internal.Workbench$5.run(Workbench.java:636) + at org.eclipse.core.databinding.observable.Realm.runWithDefault(Realm.java:332) + at org.eclipse.ui.internal.Workbench.createAndRunWorkbench(Workbench.java:579) + at org.eclipse.ui.PlatformUI.createAndRunWorkbench(PlatformUI.java:150) + at org.eclipse.ui.internal.ide.application.IDEApplication.start(IDEApplication.java:135) + at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:196) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:134) + at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:104) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:380) + at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:235) + at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) + at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) + at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) + at java.lang.reflect.Method.invoke(Method.java:483) + at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:648) + at org.eclipse.equinox.launcher.Main.basicRun(Main.java:603) + at org.eclipse.equinox.launcher.Main.run(Main.java:1465) +!SESSION 2014-12-19 23:18:20.463 ----------------------------------------------- +eclipse.buildId=4.4.1.M20140925-0400 +java.version=1.8.0_20 +java.vendor=Oracle Corporation +BootLoader constants: OS=macosx, ARCH=x86_64, WS=cocoa, NL=en_US +Framework arguments: -product org.eclipse.epp.package.java.product -keyring /Users/paul/.eclipse_keyring -showlocation +Command-line arguments: -os macosx -ws cocoa -arch x86_64 -product org.eclipse.epp.package.java.product -keyring /Users/paul/.eclipse_keyring -showlocation + +!ENTRY org.eclipse.m2e.logback.configuration 2 0 2014-12-19 23:18:22.707 +!MESSAGE Exception while setting up logging:org.eclipse.osgi.internal.framework.EquinoxConfiguration$1 cannot be cast to java.lang.String +!STACK 0 +java.lang.ClassCastException: org.eclipse.osgi.internal.framework.EquinoxConfiguration$1 cannot be cast to java.lang.String + at org.eclipse.m2e.logback.configuration.LogHelper.logJavaProperties(LogHelper.java:26) + at org.eclipse.m2e.logback.configuration.LogPlugin.loadConfiguration(LogPlugin.java:189) + at org.eclipse.m2e.logback.configuration.LogPlugin.configureLogback(LogPlugin.java:144) + at org.eclipse.m2e.logback.configuration.LogPlugin.access$2(LogPlugin.java:107) + at org.eclipse.m2e.logback.configuration.LogPlugin$1.run(LogPlugin.java:62) + at java.util.TimerThread.mainLoop(Timer.java:555) + at java.util.TimerThread.run(Timer.java:505) + +!ENTRY org.eclipse.core.net 1 0 2014-12-19 23:18:24.572 +!MESSAGE System property http.nonProxyHosts has been set to local|*.local|169.254/16|*.169.254/16 by an external source. This value will be overwritten using the values from the preferences + +!ENTRY com.android.ide.eclipse.adt 4 0 2014-12-19 23:30:05.287 +!MESSAGE Failed to load properties file for project 'MiBand' + +!ENTRY org.eclipse.jface 2 0 2014-12-19 23:39:51.774 +!MESSAGE Keybinding conflicts occurred. They may interfere with normal accelerator operation. +!SUBENTRY 1 org.eclipse.jface 2 0 2014-12-19 23:39:51.774 +!MESSAGE A conflict occurred for COMMAND+SHIFT+C: +Binding(COMMAND+SHIFT+C, + ParameterizedCommand(Command(org.eclipse.jdt.ui.edit.text.java.toggle.comment,Toggle Comment, + Toggle comment the selected lines, + Category(org.eclipse.jdt.ui.category.source,Source,Java Source Actions,true), + org.eclipse.ui.internal.WorkbenchHandlerServiceHandler@19469022, + ,,true),null), + org.eclipse.ui.defaultAcceleratorConfiguration, + org.eclipse.jdt.ui.javaEditorScope,,,system) +Binding(COMMAND+SHIFT+C, + ParameterizedCommand(Command(org.eclipse.wst.sse.ui.toggle.comment,Toggle Comment, + Toggle Comment, + Category(org.eclipse.ui.category.edit,Edit,null,true), + org.eclipse.ui.internal.WorkbenchHandlerServiceHandler@76104df5, + ,,true),null), + org.eclipse.ui.defaultAcceleratorConfiguration, + org.eclipse.wst.sse.ui.structuredTextEditorScope,,,system) +!SUBENTRY 1 org.eclipse.jface 2 0 2014-12-19 23:39:51.774 +!MESSAGE A conflict occurred for COMMAND+SHIFT+\: +Binding(COMMAND+SHIFT+\, + ParameterizedCommand(Command(org.eclipse.jdt.ui.edit.text.java.remove.block.comment,Remove Block Comment, + Remove the block comment enclosing the selection, + Category(org.eclipse.jdt.ui.category.source,Source,Java Source Actions,true), + org.eclipse.ui.internal.WorkbenchHandlerServiceHandler@491d31d9, + ,,true),null), + org.eclipse.ui.defaultAcceleratorConfiguration, + org.eclipse.jdt.ui.javaEditorScope,,,system) +Binding(COMMAND+SHIFT+\, + ParameterizedCommand(Command(org.eclipse.wst.sse.ui.remove.block.comment,Remove Block Comment, + Remove Block Comment, + Category(org.eclipse.ui.category.edit,Edit,null,true), + org.eclipse.ui.internal.WorkbenchHandlerServiceHandler@3c17794e, + ,,true),null), + org.eclipse.ui.defaultAcceleratorConfiguration, + org.eclipse.wst.sse.ui.structuredTextEditorScope,,,system) +!SUBENTRY 1 org.eclipse.jface 2 0 2014-12-19 23:39:51.774 +!MESSAGE A conflict occurred for COMMAND+I: +Binding(COMMAND+I, + ParameterizedCommand(Command(org.eclipse.jdt.ui.edit.text.java.indent,Correct Indentation, + Corrects the indentation of the selected lines, + Category(org.eclipse.jdt.ui.category.source,Source,Java Source Actions,true), + org.eclipse.ui.internal.WorkbenchHandlerServiceHandler@5baab8b6, + ,,true),null), + org.eclipse.ui.defaultAcceleratorConfiguration, + org.eclipse.jdt.ui.javaEditorScope,,,system) +Binding(COMMAND+I, + ParameterizedCommand(Command(org.eclipse.wst.sse.ui.format.active.elements,Format Active Elements, + Format active elements, + Category(org.eclipse.ui.category.edit,Edit,null,true), + org.eclipse.ui.internal.WorkbenchHandlerServiceHandler@68550d86, + ,,true),null), + org.eclipse.ui.defaultAcceleratorConfiguration, + org.eclipse.wst.sse.ui.structuredTextEditorScope,,,system) +Binding(COMMAND+I, + ParameterizedCommand(Command(org.eclipse.ui.file.properties,Properties, + Display the properties of the selected item, + Category(org.eclipse.ui.category.file,File,null,true), + org.eclipse.ui.internal.WorkbenchHandlerServiceHandler@7b9d1a4, + ,,true),null), + org.eclipse.ui.defaultAcceleratorConfiguration, + org.eclipse.ui.contexts.window,,cocoa,system) +!SUBENTRY 1 org.eclipse.jface 2 0 2014-12-19 23:39:51.774 +!MESSAGE A conflict occurred for COMMAND+SHIFT+F: +Binding(COMMAND+SHIFT+F, + ParameterizedCommand(Command(org.eclipse.jdt.ui.edit.text.java.format,Format, + Format the selected text, + Category(org.eclipse.jdt.ui.category.source,Source,Java Source Actions,true), + org.eclipse.ui.internal.WorkbenchHandlerServiceHandler@5c6204e5, + ,,true),null), + org.eclipse.ui.defaultAcceleratorConfiguration, + org.eclipse.jdt.ui.javaEditorScope,,,system) +Binding(COMMAND+SHIFT+F, + ParameterizedCommand(Command(org.eclipse.wst.sse.ui.format.document,Format, + Format selection, + Category(org.eclipse.ui.category.edit,Edit,null,true), + org.eclipse.ui.internal.WorkbenchHandlerServiceHandler@282c5075, + ,,true),null), + org.eclipse.ui.defaultAcceleratorConfiguration, + org.eclipse.wst.sse.ui.structuredTextEditorScope,,,system) +!SUBENTRY 1 org.eclipse.jface 2 0 2014-12-19 23:39:51.775 +!MESSAGE A conflict occurred for COMMAND+/: +Binding(COMMAND+/, + ParameterizedCommand(Command(org.eclipse.jdt.ui.edit.text.java.toggle.comment,Toggle Comment, + Toggle comment the selected lines, + Category(org.eclipse.jdt.ui.category.source,Source,Java Source Actions,true), + org.eclipse.ui.internal.WorkbenchHandlerServiceHandler@19469022, + ,,true),null), + org.eclipse.ui.defaultAcceleratorConfiguration, + org.eclipse.jdt.ui.javaEditorScope,,,system) +Binding(COMMAND+/, + ParameterizedCommand(Command(org.eclipse.wst.sse.ui.add.block.comment,Add Block Comment, + Add Block Comment, + Category(org.eclipse.ui.category.edit,Edit,null,true), + org.eclipse.ui.internal.WorkbenchHandlerServiceHandler@3a5e4f32, + ,,true),null), + org.eclipse.ui.defaultAcceleratorConfiguration, + org.eclipse.wst.sse.ui.structuredTextEditorScope,,cocoa,system) +!SUBENTRY 1 org.eclipse.jface 2 0 2014-12-19 23:39:51.775 +!MESSAGE A conflict occurred for COMMAND+SHIFT+P: +Binding(COMMAND+SHIFT+P, + ParameterizedCommand(Command(org.eclipse.jdt.ui.edit.text.java.goto.matching.bracket,Go to Matching Bracket, + Moves the cursor to the matching bracket, + Category(org.eclipse.ui.category.navigate,Navigate,null,true), + org.eclipse.ui.internal.WorkbenchHandlerServiceHandler@718858cb, + ,,true),null), + org.eclipse.ui.defaultAcceleratorConfiguration, + org.eclipse.jdt.ui.javaEditorScope,,,system) +Binding(COMMAND+SHIFT+P, + ParameterizedCommand(Command(org.eclipse.wst.sse.ui.goto.matching.bracket,Matching Character, + Go to Matching Character, + Category(org.eclipse.ui.category.navigate,Navigate,null,true), + org.eclipse.ui.internal.WorkbenchHandlerServiceHandler@5a31abe9, + ,,true),null), + org.eclipse.ui.defaultAcceleratorConfiguration, + org.eclipse.wst.sse.ui.structuredTextEditorScope,,,system) +!SUBENTRY 1 org.eclipse.jface 2 0 2014-12-19 23:39:51.775 +!MESSAGE A conflict occurred for COMMAND+O: +Binding(COMMAND+O, + ParameterizedCommand(Command(org.eclipse.jdt.ui.edit.text.java.show.outline,Quick Outline, + Show the quick outline for the editor input, + Category(org.eclipse.ui.category.navigate,Navigate,null,true), + org.eclipse.ui.internal.WorkbenchHandlerServiceHandler@513b2cda, + ,,true),null), + org.eclipse.ui.defaultAcceleratorConfiguration, + org.eclipse.jdt.ui.javaEditorScope,,,system) +Binding(COMMAND+O, + ParameterizedCommand(Command(org.eclipse.wst.sse.ui.quick_outline,Quick Outline, + Show the quick outline for the editor input, + Category(org.eclipse.ui.category.navigate,Navigate,null,true), + org.eclipse.ui.internal.WorkbenchHandlerServiceHandler@5f5a5143, + ,,true),null), + org.eclipse.ui.defaultAcceleratorConfiguration, + org.eclipse.wst.sse.ui.structuredTextEditorScope,,,system) + +!ENTRY org.eclipse.ui 4 4 2014-12-20 00:41:43.711 +!MESSAGE Referenced part does not exist yet: org.eclipse.ui.views.ProblemView. + +!ENTRY org.eclipse.ltk.core.refactoring 4 0 2014-12-20 01:07:10.933 +!MESSAGE The refactoring executed at Jan 1, 1970, 12:59:59 AM contributed a refactoring descriptor with invalid format: +!SUBENTRY 1 org.eclipse.ltk.core.refactoring 4 0 2014-12-20 01:07:10.933 +!MESSAGE Extracts string 'MiBand not found. Is it in range?' into R.string.not_found + +!ENTRY org.eclipse.ltk.core.refactoring 4 10000 2014-12-20 01:07:10.934 +!MESSAGE Internal Error +!STACK 1 +org.eclipse.core.runtime.CoreException: The value of key 'xml-attr-name' is not a string + at org.eclipse.ltk.internal.core.refactoring.history.RefactoringHistoryManager.checkArgumentMap(RefactoringHistoryManager.java:131) + at org.eclipse.ltk.internal.core.refactoring.history.RefactoringHistoryService.checkDescriptor(RefactoringHistoryService.java:613) + at org.eclipse.ltk.internal.core.refactoring.history.RefactoringHistoryService.performHistoryNotification(RefactoringHistoryService.java:955) + at org.eclipse.ltk.internal.core.refactoring.history.RefactoringHistoryService.access$0(RefactoringHistoryService.java:949) + at org.eclipse.ltk.internal.core.refactoring.history.RefactoringHistoryService$2.historyNotification(RefactoringHistoryService.java:379) + at org.eclipse.core.commands.operations.DefaultOperationHistory$2.run(DefaultOperationHistory.java:941) + at org.eclipse.core.runtime.SafeRunner.run(SafeRunner.java:42) + at org.eclipse.core.commands.operations.DefaultOperationHistory.notifyListeners(DefaultOperationHistory.java:930) + at org.eclipse.core.commands.operations.DefaultOperationHistory.notifyAboutToExecute(DefaultOperationHistory.java:953) + at org.eclipse.core.commands.operations.DefaultOperationHistory.openOperation(DefaultOperationHistory.java:1335) + at org.eclipse.ltk.internal.core.refactoring.UndoManager2.aboutToPerformChange(UndoManager2.java:139) + at org.eclipse.ltk.core.refactoring.PerformChangeOperation$1.run(PerformChangeOperation.java:254) + at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2313) + at org.eclipse.ltk.core.refactoring.PerformChangeOperation.executeChange(PerformChangeOperation.java:306) + at org.eclipse.ltk.internal.ui.refactoring.UIPerformChangeOperation.executeChange(UIPerformChangeOperation.java:92) + at org.eclipse.ltk.core.refactoring.PerformChangeOperation.run(PerformChangeOperation.java:218) + at org.eclipse.core.internal.resources.Workspace.run(Workspace.java:2313) + at org.eclipse.ltk.internal.ui.refactoring.WorkbenchRunnableAdapter.run(WorkbenchRunnableAdapter.java:87) + at org.eclipse.jface.operation.ModalContext$ModalContextThread.run(ModalContext.java:122) +!SUBENTRY 1 org.eclipse.ltk.core.refactoring 4 10007 2014-12-20 01:07:10.935 +!MESSAGE The value of key 'xml-attr-name' is not a string + +!ENTRY com.android.ide.eclipse.adt 4 0 2014-12-20 01:08:57.633 +!MESSAGE Warning: Ignoring name conflict in resource file for name hello_world + +!ENTRY org.eclipse.recommenders.rcp 4 5 2014-12-20 01:11:09.415 +!MESSAGE Failed to resolve selection in ‘=MiBand/src + + + + + + + + \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/1/70b49fdad98700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/1/70b49fdad98700141885aa2aa9523af4 new file mode 100644 index 0000000..6ce89c7 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/1/70b49fdad98700141885aa2aa9523af4 @@ -0,0 +1,20 @@ + + + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/1/d0e8eaf4df8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/1/d0e8eaf4df8700141885aa2aa9523af4 new file mode 100644 index 0000000..5d3fcec --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/1/d0e8eaf4df8700141885aa2aa9523af4 @@ -0,0 +1,46 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + mMiBand.connectGatt(this, false, this); + } + + @Override + public void onResume() { + super.onResume(); + + } + + @Override + public void onPause() { + super.onPause(); + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/10/c07a171bed870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/10/c07a171bed870014196aa5e86be5823c new file mode 100644 index 0000000..317cbfc --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/10/c07a171bed870014196aa5e86be5823c @@ -0,0 +1,36 @@ + + + + + + + + + \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/13/603c9935db8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/13/603c9935db8700141885aa2aa9523af4 new file mode 100644 index 0000000..f1f0eee --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/13/603c9935db8700141885aa2aa9523af4 @@ -0,0 +1,26 @@ + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/14/20df9f7bdb8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/14/20df9f7bdb8700141885aa2aa9523af4 new file mode 100644 index 0000000..97b9890 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/14/20df9f7bdb8700141885aa2aa9523af4 @@ -0,0 +1,25 @@ + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/14/809d9b59f7870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/14/809d9b59f7870014196aa5e86be5823c new file mode 100644 index 0000000..73780c0 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/14/809d9b59f7870014196aa5e86be5823c @@ -0,0 +1,208 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Observable; +import java.util.Observer; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.LeParams; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity implements Observer { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_CONTROL_POINT = UUID + .fromString("0000ff05-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_LE_PARAMS = UUID + .fromString("0000ff09-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + // BLUETOOTH + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + private MiBand mMiBand = new MiBand(); + + // UI + private TextView mTVSteps; + private TextView mTVBatteryLevel; + private ProgressBar mLoading; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.addObserver(this); + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + + mTVSteps = (TextView) findViewById(R.id.text_steps); + mTVBatteryLevel = (TextView) findViewById(R.id.text_battery_level); + mLoading = (ProgressBar) findViewById(R.id.laoding); + + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private void setColor(byte r, byte g, byte b) { + BluetoothGattCharacteristic theme = getMiliService().getCharacteristic( + UUID_CHAR_CONTROL_POINT); + theme.setValue(new byte[] { 14, r, g, b, 0 }); + mGatt.writeCharacteristic(theme); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() + // setColor((byte)127, (byte)0, (byte)0); + // request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + + //handle value + if (characteristic.getUuid().equals(UUID_CHAR_REALTIME_STEPS)) + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + else if (characteristic.getUuid().equals(UUID_CHAR_BATTERY)) { + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + } else if (characteristic.getUuid().equals(UUID_CHAR_DEVICE_NAME)) { + mMiBand.setName(new String(b)); + } else if (characteristic.getUuid().equals(UUID_CHAR_LE_PARAMS)) { + LeParams params = LeParams.fromByte(b); + mMiBand.setLeParams(params); + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_DEVICE_NAME); + break; + case 3: + request(UUID_CHAR_LE_PARAMS); + break; + } + } + }; + + @Override + public void update(Observable observable, Object data) { + runOnUiThread(new Runnable() { + + @Override + public void run() { + mLoading.setVisibility(View.GONE); + ((LinearLayout) findViewById(R.id.textHolder)) + .setVisibility(View.VISIBLE); + mTVSteps.setText(mMiBand.mSteps + ""); + if (mMiBand.mBattery != null) + mTVBatteryLevel.setText(mMiBand.mBattery.mBatteryLevel + + "%"); + } + }); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/16/201cc50ff9870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/16/201cc50ff9870014196aa5e86be5823c new file mode 100644 index 0000000..e69de29 diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/17/a07453a4e9870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/17/a07453a4e9870014196aa5e86be5823c new file mode 100644 index 0000000..fbdb723 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/17/a07453a4e9870014196aa5e86be5823c @@ -0,0 +1,15 @@ +package com.motioncoding.miband.model; + +import java.util.Calendar; + +public class MiBand { + + public String mBTAddress; + public int mSteps; + public Battery mBattery; + + public void setBattery(Battery battery) { + mBattery = battery; + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/18/a0833b17ee870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/18/a0833b17ee870014196aa5e86be5823c new file mode 100644 index 0000000..8444dc2 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/18/a0833b17ee870014196aa5e86be5823c @@ -0,0 +1,182 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Observable; +import java.util.Observer; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.ProgressBar; +import android.widget.Spinner; +import android.widget.TextView; + +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity implements Observer { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_CONTROL_POINT = UUID + .fromString("0000ff05-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + //BLUETOOTH + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + + private MiBand mMiBand = new MiBand(); + + //UI + private TextView mTVSteps; + private TextView mTVBatteryLevel; + private ProgressBar mLoading; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.addObserver(this); + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + + mTVSteps = (TextView) findViewById(R.id.text_steps); + mLoading = (Spinner) findViewById(R.id.laoding); + + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() + request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + switch (state) { + case 0: + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + break; + case 1: + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + break; + case 2: + mMiBand.setName(new String(b)); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_DEVICE_NAME); + break; + } + } + }; + + @Override + public void update(Observable observable, Object data) { + mLoading.setVisibility(View.GONE); + mTVSteps.setText(mMiBand.mSteps); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/18/d0598389d88700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/18/d0598389d88700141885aa2aa9523af4 new file mode 100644 index 0000000..e6f9ee5 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/18/d0598389d88700141885aa2aa9523af4 @@ -0,0 +1,70 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothAdapter.LeScanCallback; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.os.Bundle; +import android.os.Handler; + +public class MiActivity extends Activity implements LeScanCallback { + + private BluetoothAdapter mBluetoothAdapter; + private boolean mScanning; + private Handler mHandler = new Handler(); + // Stops scanning after 10 seconds. + private static final long SCAN_PERIOD = 10000; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_mi); + mBluetoothAdapter = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)).getAdapter(); + } + + @Override + public void onResume() { + super.onResume(); + scanLeDevice(true); + } + + + + @SuppressWarnings("deprecation") // L Apis are buggy and crap! + private void scanLeDevice(final boolean enable) { + if (enable) { + // Stops scanning after a pre-defined scan period. + mHandler.postDelayed(new Runnable() { + + @Override + public void run() { + mScanning = false; + mBluetoothAdapter.stopLeScan(MiActivity.this); + scanLeDevice(true); + } + }, SCAN_PERIOD); + + mScanning = true; + mBluetoothAdapter.startLeScan(this); + } else { + mScanning = false; + mBluetoothAdapter.stopLeScan(this); + } + } + + @Override + public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { + if(device != null && device.getName() != null & device.getName().equals("MI")) { + System.out.println(device.getAddress()); + scanLeDevice(false); // we only care about one miband so that's enough + } + } + + @Override + public void onPause() { + super.onPause(); + scanLeDevice(false); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/19/20314991de8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/19/20314991de8700141885aa2aa9523af4 new file mode 100644 index 0000000..4a7195e --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/19/20314991de8700141885aa2aa9523af4 @@ -0,0 +1,17 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + private String mDeviceAddress; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/19/50ab4003f3870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/19/50ab4003f3870014196aa5e86be5823c new file mode 100644 index 0000000..4568304 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/19/50ab4003f3870014196aa5e86be5823c @@ -0,0 +1,193 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Observable; +import java.util.Observer; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity implements Observer { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_CONTROL_POINT = UUID + .fromString("0000ff05-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + // BLUETOOTH + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + private MiBand mMiBand = new MiBand(); + + // UI + private TextView mTVSteps; + private TextView mTVBatteryLevel; + private ProgressBar mLoading; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.addObserver(this); + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + + mTVSteps = (TextView) findViewById(R.id.text_steps); + mTVBatteryLevel = (TextView) findViewById(R.id.text_battery_level); + mLoading = (ProgressBar) findViewById(R.id.laoding); + + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() + request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + switch (state) { + case 0: + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + break; + case 1: + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + break; + case 2: + mMiBand.setName(new String(b)); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_DEVICE_NAME); + break; + } + } + }; + + @Override + public void update(Observable observable, Object data) { + runOnUiThread(new Runnable() { + + @Override + public void run() { + mLoading.setVisibility(View.GONE); + ((LinearLayout) findViewById(R.id.textHolder)) + .setVisibility(View.VISIBLE); + mTVSteps.setText(mMiBand.mSteps + ""); + if (mMiBand.mBattery != null) + mTVBatteryLevel.setText(mMiBand.mBattery.mBatteryLevel + + "%"); + } + }); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/1a/a0e36e87d68700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/1a/a0e36e87d68700141885aa2aa9523af4 new file mode 100644 index 0000000..2acfdf9 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/1a/a0e36e87d68700141885aa2aa9523af4 @@ -0,0 +1,27 @@ + + + + + + + + + + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/1c/4025d149f8870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/1c/4025d149f8870014196aa5e86be5823c new file mode 100644 index 0000000..38104d0 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/1c/4025d149f8870014196aa5e86be5823c @@ -0,0 +1,235 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Observable; +import java.util.Observer; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.motioncoding.debugging.L; +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.LeParams; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity implements Observer { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_CONTROL_POINT = UUID + .fromString("0000ff05-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_LE_PARAMS = UUID + .fromString("0000ff09-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + // BLUETOOTH + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + private MiBand mMiBand = new MiBand(); + + // UI + private TextView mTVSteps; + private TextView mTVBatteryLevel; + private ProgressBar mLoading; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.addObserver(this); + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + + mTVSteps = (TextView) findViewById(R.id.text_steps); + mTVBatteryLevel = (TextView) findViewById(R.id.text_battery_level); + mLoading = (ProgressBar) findViewById(R.id.laoding); + + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.menu_overview, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.action_leparams: + if(mMiBand.mLeParams == null) { + L.toast(this, "No LE params received yet"); + return true; + } + Intent intent = new Intent(getApplicationContext(), MiLeParamsActivity.class); + intent.putExtra("params", mMiBand.mLeParams); + break; + } + return true; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private void setColor(byte r, byte g, byte b) { + BluetoothGattCharacteristic theme = getMiliService().getCharacteristic( + UUID_CHAR_CONTROL_POINT); + theme.setValue(new byte[] { 14, r, g, b, 0 }); + mGatt.writeCharacteristic(theme); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() + // setColor((byte)127, (byte)0, (byte)0); + request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + + // handle value + if (characteristic.getUuid().equals(UUID_CHAR_REALTIME_STEPS)) + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + else if (characteristic.getUuid().equals(UUID_CHAR_BATTERY)) { + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + } else if (characteristic.getUuid().equals(UUID_CHAR_DEVICE_NAME)) { + mMiBand.setName(new String(b)); + } else if (characteristic.getUuid().equals(UUID_CHAR_LE_PARAMS)) { + LeParams params = LeParams.fromByte(b); + mMiBand.setLeParams(params); + } + + // proceed with state machine (called in the beginning) + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_DEVICE_NAME); + break; + case 3: + request(UUID_CHAR_LE_PARAMS); + break; + } + } + }; + + @Override + public void update(Observable observable, Object data) { + runOnUiThread(new Runnable() { + + @Override + public void run() { + mLoading.setVisibility(View.GONE); + ((LinearLayout) findViewById(R.id.textHolder)) + .setVisibility(View.VISIBLE); + mTVSteps.setText(mMiBand.mSteps + ""); + if (mMiBand.mBattery != null) + mTVBatteryLevel.setText(mMiBand.mBattery.mBatteryLevel + + "%"); + } + }); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/1c/40b86b85e4870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/1c/40b86b85e4870014196aa5e86be5823c new file mode 100644 index 0000000..1f11d6d --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/1c/40b86b85e4870014196aa5e86be5823c @@ -0,0 +1,31 @@ +package com.motioncoding.miband.model; + +import java.util.Calendar; + +public class MiBand { + + String mBTAddress; + int mSteps; + + + static class Battery { + int mBatteryLevel; + int mCycles; + Calendar mLastCharged; + + static enum Status { + LOW, FULL, CHARGING, NOT_CHARGING + + public static Status fromByte(byte b) { + switch (b) { + case 1: return LOW; + case 2: return CHARGING; + case 3: return FULL; + case 4: return NOT_CHARGING; + + default: return null; + } + } + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/1c/d0973b39d88700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/1c/d0973b39d88700141885aa2aa9523af4 new file mode 100644 index 0000000..be4065a --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/1c/d0973b39d88700141885aa2aa9523af4 @@ -0,0 +1,68 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothAdapter.LeScanCallback; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.os.Bundle; +import android.os.Handler; + +public class MiActivity extends Activity implements LeScanCallback { + + private BluetoothAdapter mBluetoothAdapter; + private boolean mScanning; + private Handler mHandler; + // Stops scanning after 10 seconds. + private static final long SCAN_PERIOD = 10000; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_mi); + mBluetoothAdapter = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)).getAdapter(); + } + + @Override + public void onResume() { + super.onResume(); + scanLeDevice(true); + } + + + + + private void scanLeDevice(final boolean enable) { + if (enable) { + // Stops scanning after a pre-defined scan period. + mHandler.postDelayed(new Runnable() { + @Override + public void run() { + mScanning = false; + mBluetoothAdapter.stopLeScan(MiActivity.this); + } + }, SCAN_PERIOD); + + mScanning = true; + mBluetoothAdapter.startLeScan(this); + } else { + mScanning = false; + mBluetoothAdapter.stopLeScan(this); + } + } + + @Override + public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { + if(device != null && device.getName() != null & device.getName().equals("MI")) { + System.out.println(device.getAddress()); + scanLeDevice(false); // we only care about one miband so that's enough + } + } + + @Override + public void onPause() { + super.onPause(); + scanLeDevice(false); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/1e/0005cc07e18700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/1e/0005cc07e18700141885aa2aa9523af4 new file mode 100644 index 0000000..4d3a6d8 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/1e/0005cc07e18700141885aa2aa9523af4 @@ -0,0 +1,78 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + for(BluetoothGattService service : gatt.getServices()) { + for (BluetoothGattCharacteristic character : service.get()) {} + } + } + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if(status == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/1e/40866795ce8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/1e/40866795ce8700141885aa2aa9523af4 new file mode 100644 index 0000000..548ca95 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/1e/40866795ce8700141885aa2aa9523af4 @@ -0,0 +1,3 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/1f/c0f5aeb9e18700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/1f/c0f5aeb9e18700141885aa2aa9523af4 new file mode 100644 index 0000000..eb852a8 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/1f/c0f5aeb9e18700141885aa2aa9523af4 @@ -0,0 +1,82 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + for (BluetoothGattService srvs : gatt.getServices()) { + System.out.println("Service: "+srvs.getUuid()); + for (BluetoothGattCharacteristic chrt : srvs + .getCharacteristics()) { + System.out.println("Characteristic: "+chrt.getUuid()+" permissions: "+chrt.getPermissions()); + } + } + } + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (status == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/1f/d0aee612f6870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/1f/d0aee612f6870014196aa5e86be5823c new file mode 100644 index 0000000..076ed47 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/1f/d0aee612f6870014196aa5e86be5823c @@ -0,0 +1,65 @@ +package com.motioncoding.miband.model; + +public class LeParams implements Parcelable { + public int connIntMin; + public int connIntMax; + public int latency; + public int timeout; + public int connInt; + public int advInt; + + public static LeParams fromByte(byte[] b) { + LeParams params = new LeParams(); + + params.connIntMax = 0xffff & (0xff & b[0] | (0xff & b[1]) << 8); + params.connIntMax = 0xffff & (0xff & b[2] | (0xff & b[3]) << 8); + params.latency = 0xffff & (0xff & b[4] | (0xff & b[5]) << 8); + params.timeout = 0xffff & (0xff & b[6] | (0xff & b[7]) << 8); + params.connInt = 0xffff & (0xff & b[8] | (0xff & b[9]) << 8); + params.advInt = 0xffff & (0xff & b[10] | (0xff & b[11]) << 8); + + params.connIntMin *= 1.25; + params.connIntMax *= 1.25; + params.advInt *= 0.625; + params.timeout *= 10; + + return params; + } + + protected LeParams(Parcel in) { + connIntMin = in.readInt(); + connIntMax = in.readInt(); + latency = in.readInt(); + timeout = in.readInt(); + connInt = in.readInt(); + advInt = in.readInt(); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(connIntMin); + dest.writeInt(connIntMax); + dest.writeInt(latency); + dest.writeInt(timeout); + dest.writeInt(connInt); + dest.writeInt(advInt); + } + + @SuppressWarnings("unused") + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + @Override + public LeParams createFromParcel(Parcel in) { + return new LeParams(in); + } + + @Override + public LeParams[] newArray(int size) { + return new LeParams[size]; + } + }; +} \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/21/b0e8e801e18700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/21/b0e8e801e18700141885aa2aa9523af4 new file mode 100644 index 0000000..5d1f05d --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/21/b0e8e801e18700141885aa2aa9523af4 @@ -0,0 +1,78 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + for(BluetoothGattService service : gatt.getServices())) { + + } + } + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if(status == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/22/10c7d4c0e8870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/22/10c7d4c0e8870014196aa5e86be5823c new file mode 100644 index 0000000..43f39e4 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/22/10c7d4c0e8870014196aa5e86be5823c @@ -0,0 +1,38 @@ +package com.motioncoding.miband.model; + +import java.util.Calendar; + +public class Battery { + public int mBatteryLevel; + public int mCycles; + public Calendar mLastCharged; + public Status mStatus; + + public static Battery fromByte(byte[] b) { + Battery battery = new Battery(); + battery.mBatteryLevel = b[0]; + battery.status = Status.fromByte(b[9]) + + return battery; + } + + static enum Status { + LOW, FULL, CHARGING, NOT_CHARGING; + + public static Status fromByte(byte b) { + switch (b) { + case 1: + return LOW; + case 2: + return CHARGING; + case 3: + return FULL; + case 4: + return NOT_CHARGING; + + default: + return null; + } + } + } +} \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/23/3008771ee7870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/23/3008771ee7870014196aa5e86be5823c new file mode 100644 index 0000000..5b46776 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/23/3008771ee7870014196aa5e86be5823c @@ -0,0 +1,129 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; + +public class MiOverviewActivity extends Activity { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_AUTH = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void auth() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_AUTH); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("Auth sent"); + } + + private void request(BluetoothGattCharacteristic chrt) + mGatt.readCharacteristic(chrt); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + auth(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + switch (state) { + case 0: + requestSteps(); + break; + } + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(characteristic.getValue())); + switch (state) { + case 0: + System.out.println(characteristic.getIntValue(0, 0)); + break; + } + state++; + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/24/60a7b01fec870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/24/60a7b01fec870014196aa5e86be5823c new file mode 100644 index 0000000..883afb6 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/24/60a7b01fec870014196aa5e86be5823c @@ -0,0 +1,65 @@ +package com.motioncoding.debugging; + +import android.content.Context; +import android.util.Log; +import android.widget.Toast; + +public class L { + + public static enum LogType { + CLASS, CLASS_AND_METHOD, CLASS_AND_METHOD_AND_LINE, CLASS_AND_LINE + } + + private static LogType mType = LogType.CLASS_AND_METHOD; + + + public static void toast(Context context, String msg) { + Toast.makeText(context, msg, Toast.LENGTH_SHORT).show(); + } + + public static void setLogType(LogType type) { + mType = type; + } + + public static void e(String msg) { + Log.e(getTag(), msg); + } + + public static void i(String msg) { + Log.i(getTag(), msg); + } + + public static void d(String msg) { + Log.d(getTag(), msg); + } + + public static void v(String msg) { + Log.v(getTag(), msg); + } + + public static void w(String msg) { + Log.w(getTag(), msg); + } + + public static void wtf(String msg) { + Log.wtf(getTag(), msg); + } + + private static String getTag() { + StackTraceElement[] s = Thread.currentThread().getStackTrace(); + switch (mType) { + case CLASS: + return s[4].getClassName(); + case CLASS_AND_LINE: + return s[4].getClassName()+":"+s[4].getLineNumber(); + case CLASS_AND_METHOD: + return s[4].getClassName()+"."+s[4].getMethodName(); + case CLASS_AND_METHOD_AND_LINE: + return s[4].getClassName()+"."+s[4].getMethodName()+":"+s[4].getLineNumber(); + default: + break; + } + return null; + } +} + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/24/b052e324dc8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/24/b052e324dc8700141885aa2aa9523af4 new file mode 100644 index 0000000..58c5b24 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/24/b052e324dc8700141885aa2aa9523af4 @@ -0,0 +1,7 @@ + + + + MiBand + Hello world! + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/25/b0895a09e08700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/25/b0895a09e08700141885aa2aa9523af4 new file mode 100644 index 0000000..d381f87 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/25/b0895a09e08700141885aa2aa9523af4 @@ -0,0 +1,46 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + mMiBand.connectGatt(this, false, mGattCallback); + } + + @Override + public void onResume() { + super.onResume(); + + } + + @Override + public void onPause() { + super.onPause(); + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/26/00c411b9e4870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/26/00c411b9e4870014196aa5e86be5823c new file mode 100644 index 0000000..bb76ec7 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/26/00c411b9e4870014196aa5e86be5823c @@ -0,0 +1,12 @@ +package com.motioncoding.miband.model; + +import java.util.Calendar; + +public class MiBand { + + String mBTAddress; + int mSteps; + + + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/26/d07ddf9bf5870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/26/d07ddf9bf5870014196aa5e86be5823c new file mode 100644 index 0000000..d8ed867 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/26/d07ddf9bf5870014196aa5e86be5823c @@ -0,0 +1,211 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Observable; +import java.util.Observer; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.LeParams; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity implements Observer { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_CONTROL_POINT = UUID + .fromString("0000ff05-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_LE_PARAMS = UUID + .fromString("0000ff09-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + // BLUETOOTH + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + private MiBand mMiBand = new MiBand(); + + // UI + private TextView mTVSteps; + private TextView mTVBatteryLevel; + private ProgressBar mLoading; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.addObserver(this); + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + + mTVSteps = (TextView) findViewById(R.id.text_steps); + mTVBatteryLevel = (TextView) findViewById(R.id.text_battery_level); + mLoading = (ProgressBar) findViewById(R.id.laoding); + + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private void setColor(byte r, byte g, byte b) { + BluetoothGattCharacteristic theme = getMiliService() + .getCharacteristic(UUID_CHAR_CONTROL_POINT); + theme.setValue(new byte[] { 14, r, g, b, 0 }); + mGatt.writeCharacteristic(theme); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() +// setColor((byte)127, (byte)0, (byte)0); +// request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + switch (state) { + case 0: + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + break; + case 1: + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + break; + case 2: + mMiBand.setName(new String(b)); + break; + case 3: + LeParams params = LeParams.fromByte(b); + mMiBand.setLeParams(params); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_DEVICE_NAME); + break; + case 3: + request(UUID_LE_PARAMS); + break; + } + } + }; + + @Override + public void update(Observable observable, Object data) { + runOnUiThread(new Runnable() { + + @Override + public void run() { + mLoading.setVisibility(View.GONE); + ((LinearLayout) findViewById(R.id.textHolder)) + .setVisibility(View.VISIBLE); + mTVSteps.setText(mMiBand.mSteps + ""); + if (mMiBand.mBattery != null) + mTVBatteryLevel.setText(mMiBand.mBattery.mBatteryLevel + + "%"); + } + }); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/27/10e7f38fee870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/27/10e7f38fee870014196aa5e86be5823c new file mode 100644 index 0000000..841dc46 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/27/10e7f38fee870014196aa5e86be5823c @@ -0,0 +1,37 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/28/6086e11adc8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/28/6086e11adc8700141885aa2aa9523af4 new file mode 100644 index 0000000..319bddf --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/28/6086e11adc8700141885aa2aa9523af4 @@ -0,0 +1,73 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothAdapter.LeScanCallback; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.os.Bundle; +import android.os.Handler; + +public class MiActivity extends Activity implements LeScanCallback { + + private BluetoothAdapter mBluetoothAdapter; + private boolean mScanning; + private Handler mHandler = new Handler(); + // Stops scanning after 10 seconds. + private static final long SCAN_PERIOD = 10000; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + + + setContentView(R.layout.activity_mi); + mBluetoothAdapter = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)).getAdapter(); + } + + @Override + public void onResume() { + super.onResume(); + scanLeDevice(true); + } + + + + @SuppressWarnings("deprecation") // L Apis are buggy and crap! + private void scanLeDevice(final boolean enable) { + if (enable) { + // Stops scanning after a pre-defined scan period. + mHandler.postDelayed(new Runnable() { + + @Override + public void run() { + mScanning = false; + mBluetoothAdapter.stopLeScan(MiActivity.this); + } + }, SCAN_PERIOD); + + mScanning = true; + mBluetoothAdapter.startLeScan(this); + } else { + mScanning = false; + mBluetoothAdapter.stopLeScan(this); + } + } + + @Override + public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { + System.out.println(device.getName()+" "+device.getAddress()); + if(device != null && device.getName() != null & device.getName().equals("MI")) { + System.out.println(device.getAddress()); + scanLeDevice(false); // we only care about one miband so that's enough + } + } + + @Override + public void onPause() { + super.onPause(); + scanLeDevice(false); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/28/b0074003f6870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/28/b0074003f6870014196aa5e86be5823c new file mode 100644 index 0000000..16b0ed8 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/28/b0074003f6870014196aa5e86be5823c @@ -0,0 +1,93 @@ +package com.motioncoding.miband.model; + +public class LeParams { + public int connIntMin; + public int connIntMax; + public int latency; + public int timeout; + public int connInt; + public int advInt; + + public static LeParams fromByte(byte[] b) { + LeParams params = new LeParams(); + + params.connIntMax = 0xffff & (0xff & b[0] | (0xff & b[1]) << 8); + params.connIntMax = 0xffff & (0xff & b[2] | (0xff & b[3]) << 8); + params.latency = 0xffff & (0xff & b[4] | (0xff & b[5]) << 8); + params.timeout = 0xffff & (0xff & b[6] | (0xff & b[7]) << 8); + params.connInt = 0xffff & (0xff & b[8] | (0xff & b[9]) << 8); + params.advInt = 0xffff & (0xff & b[10] | (0xff & b[11]) << 8); + + params.connIntMin *= 1.25; + params.connIntMax *= 1.25; + params.advInt *= 0.625; + params.timeout *= 10; + + return params; + } +} +package com.motioncoding.miband.model; + +public class LeParams implements Parcelable { + public int connIntMin; + public int connIntMax; + public int latency; + public int timeout; + public int connInt; + public int advInt; + + public static LeParams fromByte(byte[] b) { + LeParams params = new LeParams(); + + params.connIntMax = 0xffff & (0xff & b[0] | (0xff & b[1]) << 8); + params.connIntMax = 0xffff & (0xff & b[2] | (0xff & b[3]) << 8); + params.latency = 0xffff & (0xff & b[4] | (0xff & b[5]) << 8); + params.timeout = 0xffff & (0xff & b[6] | (0xff & b[7]) << 8); + params.connInt = 0xffff & (0xff & b[8] | (0xff & b[9]) << 8); + params.advInt = 0xffff & (0xff & b[10] | (0xff & b[11]) << 8); + + params.connIntMin *= 1.25; + params.connIntMax *= 1.25; + params.advInt *= 0.625; + params.timeout *= 10; + + return params; + } + + protected LeParams(Parcel in) { + connIntMin = in.readInt(); + connIntMax = in.readInt(); + latency = in.readInt(); + timeout = in.readInt(); + connInt = in.readInt(); + advInt = in.readInt(); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(connIntMin); + dest.writeInt(connIntMax); + dest.writeInt(latency); + dest.writeInt(timeout); + dest.writeInt(connInt); + dest.writeInt(advInt); + } + + @SuppressWarnings("unused") + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + @Override + public LeParams createFromParcel(Parcel in) { + return new LeParams(in); + } + + @Override + public LeParams[] newArray(int size) { + return new LeParams[size]; + } + }; +} \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/28/b07ee274f7870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/28/b07ee274f7870014196aa5e86be5823c new file mode 100644 index 0000000..3c1112f --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/28/b07ee274f7870014196aa5e86be5823c @@ -0,0 +1,218 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Observable; +import java.util.Observer; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.LeParams; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity implements Observer { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_CONTROL_POINT = UUID + .fromString("0000ff05-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_LE_PARAMS = UUID + .fromString("0000ff09-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + // BLUETOOTH + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + private MiBand mMiBand = new MiBand(); + + // UI + private TextView mTVSteps; + private TextView mTVBatteryLevel; + private ProgressBar mLoading; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.addObserver(this); + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + + mTVSteps = (TextView) findViewById(R.id.text_steps); + mTVBatteryLevel = (TextView) findViewById(R.id.text_battery_level); + mLoading = (ProgressBar) findViewById(R.id.laoding); + + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.menu_overview, menu); + return true; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private void setColor(byte r, byte g, byte b) { + BluetoothGattCharacteristic theme = getMiliService().getCharacteristic( + UUID_CHAR_CONTROL_POINT); + theme.setValue(new byte[] { 14, r, g, b, 0 }); + mGatt.writeCharacteristic(theme); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() + // setColor((byte)127, (byte)0, (byte)0); + // request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + + // handle value + if (characteristic.getUuid().equals(UUID_CHAR_REALTIME_STEPS)) + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + else if (characteristic.getUuid().equals(UUID_CHAR_BATTERY)) { + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + } else if (characteristic.getUuid().equals(UUID_CHAR_DEVICE_NAME)) { + mMiBand.setName(new String(b)); + } else if (characteristic.getUuid().equals(UUID_CHAR_LE_PARAMS)) { + LeParams params = LeParams.fromByte(b); + mMiBand.setLeParams(params); + } + + // proceed with state machine (called in the beginning) + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_DEVICE_NAME); + break; + case 3: + request(UUID_CHAR_LE_PARAMS); + break; + } + } + }; + + @Override + public void update(Observable observable, Object data) { + runOnUiThread(new Runnable() { + + @Override + public void run() { + mLoading.setVisibility(View.GONE); + ((LinearLayout) findViewById(R.id.textHolder)) + .setVisibility(View.VISIBLE); + mTVSteps.setText(mMiBand.mSteps + ""); + if (mMiBand.mBattery != null) + mTVBatteryLevel.setText(mMiBand.mBattery.mBatteryLevel + + "%"); + } + }); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/28/c0c02d64e8870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/28/c0c02d64e8870014196aa5e86be5823c new file mode 100644 index 0000000..c64122d --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/28/c0c02d64e8870014196aa5e86be5823c @@ -0,0 +1,145 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; + +public class MiOverviewActivity extends Activity { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_AUTH = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void auth() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_AUTH); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("Auth sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + auth(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after auth() + request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(characteristic.getValue())); + switch (state) { + case 0: + System.out.println(characteristic.getIntValue(0, 0)); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_ACTIVITY); + break; + case 3: + request(UUID_CHAR_DEVICE_NAME); + break; + } + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/29/b0ac3b10ee870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/29/b0ac3b10ee870014196aa5e86be5823c new file mode 100644 index 0000000..98d0a92 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/29/b0ac3b10ee870014196aa5e86be5823c @@ -0,0 +1,181 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Observable; +import java.util.Observer; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.Spinner; +import android.widget.TextView; + +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity implements Observer { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_CONTROL_POINT = UUID + .fromString("0000ff05-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + //BLUETOOTH + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + + private MiBand mMiBand = new MiBand(); + + //UI + private TextView mTVSteps; + private TextView mTVBatteryLevel; + private Progressbar mLoading; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.addObserver(this); + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + + mTVSteps = (TextView) findViewById(R.id.text_steps); + mLoading = (Spinner) findViewById(R.id.laoding); + + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() + request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + switch (state) { + case 0: + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + break; + case 1: + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + break; + case 2: + mMiBand.setName(new String(b)); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_DEVICE_NAME); + break; + } + } + }; + + @Override + public void update(Observable observable, Object data) { + mLoading.setVisibility(View.GONE); + mTVSteps.setText(mMiBand.mSteps); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/2d/50070725dc8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/2d/50070725dc8700141885aa2aa9523af4 new file mode 100644 index 0000000..086aad0 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/2d/50070725dc8700141885aa2aa9523af4 @@ -0,0 +1,77 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothAdapter.LeScanCallback; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.os.Bundle; +import android.os.Handler; +import android.widget.TextView; + +public class MiActivity extends Activity implements LeScanCallback { + + private BluetoothAdapter mBluetoothAdapter; + private boolean mScanning; + private TextView mTextView; + private Handler mHandler = new Handler(); + // Stops scanning after 10 seconds. + private static final long SCAN_PERIOD = 10000; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + setContentView(R.layout.activity_mi); + mTextView = (TextView) findViewById(R.id.text_search); + mBluetoothAdapter = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)) + .getAdapter(); + } + + @Override + public void onResume() { + super.onResume(); + scanLeDevice(true); + } + + @SuppressWarnings("deprecation") + // L Apis are buggy and crap! + private void scanLeDevice(final boolean enable) { + if (enable) { + // Stops scanning after a pre-defined scan period. + mHandler.postDelayed(new Runnable() { + + @Override + public void run() { + mScanning = false; + mBluetoothAdapter.stopLeScan(MiActivity.this); + mTextView.setText("MiBand not found. Is it in range?"); + } + }, SCAN_PERIOD); + + mScanning = true; + mBluetoothAdapter.startLeScan(this); + } else { + mScanning = false; + mBluetoothAdapter.stopLeScan(this); + } + } + + @Override + public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { + System.out.println(device.getName() + " " + device.getAddress()); + if (device != null && device.getName() != null + & device.getName().equals("MI")) { + System.out.println(device.getAddress()); + scanLeDevice(false); // we only care about one miband so that's + // enough + } + } + + @Override + public void onPause() { + super.onPause(); + scanLeDevice(false); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/2f/00d29edfdc8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/2f/00d29edfdc8700141885aa2aa9523af4 new file mode 100644 index 0000000..c7c6ac3 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/2f/00d29edfdc8700141885aa2aa9523af4 @@ -0,0 +1,77 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothAdapter.LeScanCallback; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.os.Bundle; +import android.os.Handler; +import android.widget.TextView; + +public class MiActivity extends Activity implements LeScanCallback { + + private BluetoothAdapter mBluetoothAdapter; + private boolean mScanning; + private TextView mTextView; + private Handler mHandler = new Handler(); + // Stops scanning after 10 seconds. + private static final long SCAN_PERIOD = 10000; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + setContentView(R.layout.activity_mi); + mTextView = (TextView) findViewById(R.id.text_search); + mBluetoothAdapter = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)) + .getAdapter(); + } + + @Override + public void onResume() { + super.onResume(); + scanLeDevice(true); + } + + @SuppressWarnings("deprecation") + // L Apis are buggy and crap! + private void scanLeDevice(final boolean enable) { + if (enable) { + // Stops scanning after a pre-defined scan period. + mHandler.postDelayed(new Runnable() { + + @Override + public void run() { + mScanning = false; + mBluetoothAdapter.stopLeScan(MiActivity.this); + mTextView.setText(R.string.not_found); + } + }, SCAN_PERIOD); + + mScanning = true; + mBluetoothAdapter.startLeScan(this); + } else { + mScanning = false; + mBluetoothAdapter.stopLeScan(this); + } + } + + @Override + public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { + System.out.println(device.getName() + " " + device.getAddress()); + if (device != null && device.getName() != null + & device.getName().equals("MI")) { + System.out.println(device.getAddress()); + scanLeDevice(false); // we only care about one miband so that's + // enough + } + } + + @Override + public void onPause() { + super.onPause(); + scanLeDevice(false); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/3/00eab3efea870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/3/00eab3efea870014196aa5e86be5823c new file mode 100644 index 0000000..2ddb557 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/3/00eab3efea870014196aa5e86be5823c @@ -0,0 +1,23 @@ +package com.motioncoding.miband.model; + +import java.util.Observable; + + +public class MiBand extends Observable { + + public String mBTAddress; + public int mSteps; + public Battery mBattery; + + + public void setSteps(int steps) { + mSteps = steps; + notifyObservers(); + } + + public void setBattery(Battery battery) { + mBattery = battery; + notifyObservers(); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/3/b0314761df8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/3/b0314761df8700141885aa2aa9523af4 new file mode 100644 index 0000000..b51b94f --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/3/b0314761df8700141885aa2aa9523af4 @@ -0,0 +1,39 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + private String mDeviceAddress; + private BluetoothAdapter mBluetoothAdapter; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothAdapter = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)) + .getAdapter(); + } + + + @Override + public void onResume() { + super.onResume(); + + } + + @Override + public void onPause() { + super.onPause(); + } + + + + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/3/c016be3cf7870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/3/c016be3cf7870014196aa5e86be5823c new file mode 100644 index 0000000..ad6e3c3 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/3/c016be3cf7870014196aa5e86be5823c @@ -0,0 +1,25 @@ +package com.motioncoding.miband; + +import android.app.ListActivity; +import android.os.Bundle; +import android.widget.ArrayAdapter; + +import com.motioncoding.miband.model.LeParams; + +public class MiLeParamsActivity extends ListActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + setContentView(R.layout.activity_mi_le_params); + + LeParams params = (LeParams) getIntent().getParcelableExtra("params"); + + String[] values = new String[]; + + ArrayAdapter adapter = new ArrayAdapter(getActivity(), + android.R.layout.simple_list_item_1, values); + this.setListAdapter(adapter); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/3/f06b8a09e38700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/3/f06b8a09e38700141885aa2aa9523af4 new file mode 100644 index 0000000..4904d96 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/3/f06b8a09e38700141885aa2aa9523af4 @@ -0,0 +1,97 @@ +package com.motioncoding.miband; + +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void auth() { + BluetoothGattService service = mGatt.getService(UUID.fromString("00001800-0000-1000-8000-00805f9b34fb")); + BluetoothGattCharacteristic chrt = service.getCharacteristic(UUID.fromString("0000ff0f-0000-1000-8000-00805f9b34fb")); + + chrt.setValue(new byte[] {2}); + + mGatt.writeCharacteristic(chrt); + System.out.println("Auth sent"); + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { +// if (status == BluetoothGatt.GATT_SUCCESS) { +// for (BluetoothGattService srvs : gatt.getServices()) { +// System.out.println("Service: "+srvs.getUuid()); +// for (BluetoothGattCharacteristic chrt : srvs +// .getCharacteristics()) { +// System.out.println("Characteristic: "+chrt.getUuid()+" with "+chrt.getProperties()); +// } +// } +// } + + auth(); + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/30/c043bdede28700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/30/c043bdede28700141885aa2aa9523af4 new file mode 100644 index 0000000..efbf140 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/30/c043bdede28700141885aa2aa9523af4 @@ -0,0 +1,97 @@ +package com.motioncoding.miband; + +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void auth() { + BluetoothGattService service = mGatt.getService(UUID.fromString("00001800-0000-1000-8000-00805f9b34fb")); + BluetoothGattCharacteristic chrt = service.getCharacteristic(UUID.fromString("0000ff0f-0000-1000-8000-00805f9b34fb")); + + chrt.setValue(new byte[] {2}); + + mGatt.writeCharacteristic(chrt); + System.out.println("Auth1"); + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { +// if (status == BluetoothGatt.GATT_SUCCESS) { +// for (BluetoothGattService srvs : gatt.getServices()) { +// System.out.println("Service: "+srvs.getUuid()); +// for (BluetoothGattCharacteristic chrt : srvs +// .getCharacteristics()) { +// System.out.println("Characteristic: "+chrt.getUuid()+" with "+chrt.getProperties()); +// } +// } +// } + + auth(); + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/31/e04a80c6e38700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/31/e04a80c6e38700141885aa2aa9523af4 new file mode 100644 index 0000000..e69de29 diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/31/f05462bcec870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/31/f05462bcec870014196aa5e86be5823c new file mode 100644 index 0000000..33f8d6a --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/31/f05462bcec870014196aa5e86be5823c @@ -0,0 +1,7 @@ + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/32/40ab3976ec870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/32/40ab3976ec870014196aa5e86be5823c new file mode 100644 index 0000000..57a5154 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/32/40ab3976ec870014196aa5e86be5823c @@ -0,0 +1,55 @@ +package com.motioncoding.miband.model; + +import java.util.Calendar; + +public class Battery { + public int mBatteryLevel; + public int mCycles; + public Calendar mLastCharged; + public Status mStatus; + + public static Battery fromByte(byte[] b) { + Battery battery = new Battery(); + battery.mBatteryLevel = b[0]; + battery.mStatus = Status.fromByte(b[9]); + battery.mLastCharged = Calendar.getInstance(); + + battery.mLastCharged.set(Calendar.YEAR, b[1]+2000); + battery.mLastCharged.set(Calendar.MONTH, b[2]); + battery.mLastCharged.set(Calendar.DATE, b[3]); + + battery.mLastCharged.set(Calendar.HOUR_OF_DAY, b[4]); + battery.mLastCharged.set(Calendar.MINUTE, b[5]); + battery.mLastCharged.set(Calendar.SECOND, b[6]); + + + + battery.mCycles = 0xffff & (0xff & b[7] | (0xff & b[8]) << 8); + return battery; + } + + @Override + public String toString() { + return String.format("Level: %s percent Cycles: %s State: %s Last Charged: %s", mBatteryLevel, mCycles, mStatus.toString(), mLastCharged.toString()); + } + + static enum Status { + LOW, FULL, CHARGING, NOT_CHARGING; + + public static Status fromByte(byte b) { + switch (b) { + case 1: + return LOW; + case 2: + return CHARGING; + case 3: + return FULL; + case 4: + return NOT_CHARGING; + + default: + return null; + } + } + } +} \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/32/a0709064dc8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/32/a0709064dc8700141885aa2aa9523af4 new file mode 100644 index 0000000..4f16ff7 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/32/a0709064dc8700141885aa2aa9523af4 @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/34/0002d7f1f3870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/34/0002d7f1f3870014196aa5e86be5823c new file mode 100644 index 0000000..e69de29 diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/34/509de358e5870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/34/509de358e5870014196aa5e86be5823c new file mode 100644 index 0000000..d8ad6ac --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/34/509de358e5870014196aa5e86be5823c @@ -0,0 +1,109 @@ +package com.motioncoding.miband; + +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_AUTH = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void auth() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_AUTH); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("Auth sent"); + } + + private void requestSteps() { + int steps = getMiliService().getCharacteristic(UUID_CHAR_REALTIME_STEPS).getIntValue(0, 0); + System.out.println(steps); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + auth(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/35/60c49bf8f6870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/35/60c49bf8f6870014196aa5e86be5823c new file mode 100644 index 0000000..8a65044 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/35/60c49bf8f6870014196aa5e86be5823c @@ -0,0 +1,22 @@ +package com.motioncoding.miband; + +import android.app.ListActivity; +import android.os.Bundle; + +import com.motioncoding.miband.model.LeParams; + +public class MiLeParamsActivity extends ListActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + setContentView(R.layout.activity_mi_le_params); + + LeParams params = (LeParams) getIntent().getParcelableExtra("params"); + + final StableArrayAdapter adapter = new StableArrayAdapter(this, + android.R.layout.simple_list_item_1, list); + this.setListAdapter(adapter); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/35/c0ed5f6df8870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/35/c0ed5f6df8870014196aa5e86be5823c new file mode 100644 index 0000000..50fe8d0 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/35/c0ed5f6df8870014196aa5e86be5823c @@ -0,0 +1,12 @@ + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/35/d0746695ce8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/35/d0746695ce8700141885aa2aa9523af4 new file mode 100644 index 0000000..d45dd56 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/35/d0746695ce8700141885aa2aa9523af4 @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.compliance=1.6 diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/35/e03e5dcfe6870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/35/e03e5dcfe6870014196aa5e86be5823c new file mode 100644 index 0000000..79048e5 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/35/e03e5dcfe6870014196aa5e86be5823c @@ -0,0 +1,131 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; + +public class MiOverviewActivity extends Activity { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_AUTH = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void auth() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_AUTH); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("Auth sent"); + } + + private void requestSteps() { + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_REALTIME_STEPS); + mGatt.readCharacteristic(chrt); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + auth(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + switch (state) { + case 0: + requestSteps(); + break; + } + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + Log.i(characteristic.getUuid().toString(),"state: "+state+" value:" + Arrays.toString(characteristic.getValue())); + switch (state) { + case 0: + + break; + } + state++; + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/37/700c4f98e7870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/37/700c4f98e7870014196aa5e86be5823c new file mode 100644 index 0000000..c6dd0b4 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/37/700c4f98e7870014196aa5e86be5823c @@ -0,0 +1,139 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; + +public class MiOverviewActivity extends Activity { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_AUTH = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void auth() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_AUTH); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("Auth sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + auth(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after auth() + request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(characteristic.getValue())); + switch (state) { + case 0: + System.out.println(characteristic.getIntValue(0, 0)); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + } + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/38/4028145fe38700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/38/4028145fe38700141885aa2aa9523af4 new file mode 100644 index 0000000..ed3ae48 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/38/4028145fe38700141885aa2aa9523af4 @@ -0,0 +1,97 @@ +package com.motioncoding.miband; + +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void auth() { + BluetoothGattService service = mGatt.getService(UUID.fromString("00001800-0000-1000-8000-00805f9b34fb")); + BluetoothGattCharacteristic chrt = service.getCharacteristic(UUID.fromString("0000ff0f-0000-1000-8000-00805f9b34fb")); + + chrt.setValue(new byte[] {2}); + + mGatt.writeCharacteristic(chrt); + System.out.println("Auth sent"); + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + for (BluetoothGattService srvs : gatt.getServices()) { + System.out.println("Service: "+srvs.getUuid()); + for (BluetoothGattCharacteristic chrt : srvs + .getCharacteristics()) { + System.out.println("Characteristic: "+chrt.getUuid()+" with "+chrt.getProperties()); + } + } + } + + auth(); + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/38/602c3f93ec870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/38/602c3f93ec870014196aa5e86be5823c new file mode 100644 index 0000000..0296466 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/38/602c3f93ec870014196aa5e86be5823c @@ -0,0 +1,55 @@ +package com.motioncoding.miband.model; + +import java.util.Calendar; + +public class Battery { + public int mBatteryLevel; + public int mCycles; + public Calendar mLastCharged; + public Status mStatus; + + public static Battery fromByte(byte[] b) { + Battery battery = new Battery(); + battery.mBatteryLevel = b[0]; + battery.mStatus = Status.fromByte(b[9]); + battery.mLastCharged = Calendar.getInstance(); + + battery.mLastCharged.set(Calendar.YEAR, b[1]+2000); + battery.mLastCharged.set(Calendar.MONTH, b[2]); + battery.mLastCharged.set(Calendar.DATE, b[3]); + + battery.mLastCharged.set(Calendar.HOUR_OF_DAY, b[4]); + battery.mLastCharged.set(Calendar.MINUTE, b[5]); + battery.mLastCharged.set(Calendar.SECOND, b[6]); + + + + battery.mCycles = 0xffff & (0xff & b[7] | (0xff & b[8]) << 8); + return battery; + } + + @Override + public String toString() { + return String.format("Level: %s Cycles: %s State: %s Last Charged: %s", mBatteryLevel, mCycles, mStatus.toString(), mLastCharged.toString()); + } + + static enum Status { + LOW, FULL, CHARGING, NOT_CHARGING; + + public static Status fromByte(byte b) { + switch (b) { + case 1: + return LOW; + case 2: + return CHARGING; + case 3: + return FULL; + case 4: + return NOT_CHARGING; + + default: + return null; + } + } + } +} \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/3e/40798e9de8870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/3e/40798e9de8870014196aa5e86be5823c new file mode 100644 index 0000000..8ea85a1 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/3e/40798e9de8870014196aa5e86be5823c @@ -0,0 +1,33 @@ +package com.motioncoding.miband.model; + +import java.util.Calendar; + +public class Battery { + public int mBatteryLevel; + public int mCycles; + public Calendar mLastCharged; + + public static Battery fromByte(byte[] b) { + return this; + } + + static enum Status { + LOW, FULL, CHARGING, NOT_CHARGING; + + public static Status fromByte(byte b) { + switch (b) { + case 1: + return LOW; + case 2: + return CHARGING; + case 3: + return FULL; + case 4: + return NOT_CHARGING; + + default: + return null; + } + } + } +} \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/3e/e05675d7d68700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/3e/e05675d7d68700141885aa2aa9523af4 new file mode 100644 index 0000000..b308209 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/3e/e05675d7d68700141885aa2aa9523af4 @@ -0,0 +1,26 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.os.Bundle; + +public class MiActivity extends Activity { + + private BluetoothManager bluetoothManager; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_mi); + + bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); + + lookForMiBand(); + } + + private void lookForMiBand() { + // TODO Auto-generated method stub + + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/3f/70518c37e9870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/3f/70518c37e9870014196aa5e86be5823c new file mode 100644 index 0000000..7738674 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/3f/70518c37e9870014196aa5e86be5823c @@ -0,0 +1,152 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.UUID; + +import com.motioncoding.miband.model.MiBand; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; + +public class MiOverviewActivity extends Activity { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_AUTH = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + private MiBand mMiBand = new MiBand(); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand. + + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void auth() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_AUTH); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("Auth sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + auth(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after auth() + request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(characteristic.getValue())); + switch (state) { + case 0: + System.out.println(characteristic.getIntValue(0, 0)); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_ACTIVITY); + break; + case 3: + request(UUID_CHAR_DEVICE_NAME); + break; + } + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/3f/f0677c5af4870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/3f/f0677c5af4870014196aa5e86be5823c new file mode 100644 index 0000000..989f389 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/3f/f0677c5af4870014196aa5e86be5823c @@ -0,0 +1,206 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Observable; +import java.util.Observer; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity implements Observer { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_CONTROL_POINT = UUID + .fromString("0000ff05-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_LE_PARAMS = UUID + .fromString("0000ff09-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + // BLUETOOTH + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + private MiBand mMiBand = new MiBand(); + + // UI + private TextView mTVSteps; + private TextView mTVBatteryLevel; + private ProgressBar mLoading; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.addObserver(this); + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + + mTVSteps = (TextView) findViewById(R.id.text_steps); + mTVBatteryLevel = (TextView) findViewById(R.id.text_battery_level); + mLoading = (ProgressBar) findViewById(R.id.laoding); + + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private void setColor(byte r, byte g, byte b) { + BluetoothGattCharacteristic theme = getMiliService() + .getCharacteristic(UUID_CHAR_CONTROL_POINT); + theme.setValue(new byte[] { 14, r, g, b, 0 }); + mGatt.writeCharacteristic(theme); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() +// setColor((byte)127, (byte)0, (byte)0); +// request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + switch (state) { + case 0: + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + break; + case 1: + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + break; + case 2: + mMiBand.setName(new String(b)); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_DEVICE_NAME); + break; + case 3: + + break; + } + } + }; + + @Override + public void update(Observable observable, Object data) { + runOnUiThread(new Runnable() { + + @Override + public void run() { + mLoading.setVisibility(View.GONE); + ((LinearLayout) findViewById(R.id.textHolder)) + .setVisibility(View.VISIBLE); + mTVSteps.setText(mMiBand.mSteps + ""); + if (mMiBand.mBattery != null) + mTVBatteryLevel.setText(mMiBand.mBattery.mBatteryLevel + + "%"); + } + }); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/43/008907e5ee870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/43/008907e5ee870014196aa5e86be5823c new file mode 100644 index 0000000..b63a5b2 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/43/008907e5ee870014196aa5e86be5823c @@ -0,0 +1,190 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Observable; +import java.util.Observer; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity implements Observer { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_CONTROL_POINT = UUID + .fromString("0000ff05-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + //BLUETOOTH + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + + private MiBand mMiBand = new MiBand(); + + //UI + private TextView mTVSteps; + private TextView mTVBatteryLevel; + private ProgressBar mLoading; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.addObserver(this); + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + + mTVSteps = (TextView) findViewById(R.id.text_steps); + mTVBatteryLevel = (TextView) findViewById(R.id.text_battery_level); + mLoading = (ProgressBar) findViewById(R.id.laoding); + + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() + request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + switch (state) { + case 0: + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + break; + case 1: + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + break; + case 2: + mMiBand.setName(new String(b)); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_DEVICE_NAME); + break; + } + } + }; + + @Override + public void update(Observable observable, Object data) { + runOnUiThread(new Runnable() { + + @Override + public void run() { + mLoading.setVisibility(View.GONE); + ((LinearLayout) findViewById(R.id.textHolder)).setVisibility(View.GONE); + mTVSteps.setText(mMiBand.mSteps+""); + } + }); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/44/30d2e947f9870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/44/30d2e947f9870014196aa5e86be5823c new file mode 100644 index 0000000..0c49be6 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/44/30d2e947f9870014196aa5e86be5823c @@ -0,0 +1,6 @@ + + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/44/70b159bde5870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/44/70b159bde5870014196aa5e86be5823c new file mode 100644 index 0000000..2553edc --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/44/70b159bde5870014196aa5e86be5823c @@ -0,0 +1,111 @@ +package com.motioncoding.miband; + +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_AUTH = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void auth() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_AUTH); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("Auth sent"); + } + + private void requestSteps() { + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic(UUID_CHAR_REALTIME_STEPS); + int steps = chrt.getIntValue(0, 0); + System.out.println(steps); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + auth(); + requestSteps(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/46/30832483eb870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/46/30832483eb870014196aa5e86be5823c new file mode 100644 index 0000000..c31c567 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/46/30832483eb870014196aa5e86be5823c @@ -0,0 +1,158 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; + +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_CONTROL_POINT = UUID + .fromString("0000ff05-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + private MiBand mMiBand = new MiBand(); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() + request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + switch (state) { + case 0: + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + break; + case 1: + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_ACTIVITY); + break; + case 3: + request(UUID_CHAR_DEVICE_NAME); + break; + } + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/48/000f1098e4870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/48/000f1098e4870014196aa5e86be5823c new file mode 100644 index 0000000..b86c879 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/48/000f1098e4870014196aa5e86be5823c @@ -0,0 +1,31 @@ +package com.motioncoding.miband.model; + +import java.util.Calendar; + +public class MiBand { + + String mBTAddress; + int mSteps; + + + static class Battery { + int mBatteryLevel; + int mCycles; + Calendar mLastCharged; + + static enum Status { + LOW, FULL, CHARGING, NOT_CHARGING; + + public static Status fromByte(byte b) { + switch (b) { + case 1: return LOW; + case 2: return CHARGING; + case 3: return FULL; + case 4: return NOT_CHARGING; + + default: return null; + } + } + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/4b/3076006dd88700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/4b/3076006dd88700141885aa2aa9523af4 new file mode 100644 index 0000000..9a823a5 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/4b/3076006dd88700141885aa2aa9523af4 @@ -0,0 +1,69 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothAdapter.LeScanCallback; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.os.Bundle; +import android.os.Handler; + +public class MiActivity extends Activity implements LeScanCallback { + + private BluetoothAdapter mBluetoothAdapter; + private boolean mScanning; + private Handler mHandler = new Handler(); + // Stops scanning after 10 seconds. + private static final long SCAN_PERIOD = 10000; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_mi); + mBluetoothAdapter = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)).getAdapter(); + } + + @Override + public void onResume() { + super.onResume(); + scanLeDevice(true); + } + + + + @SuppressWarnings("deprecation") // L Apis are buggy and crap! + private void scanLeDevice(final boolean enable) { + if (enable) { + // Stops scanning after a pre-defined scan period. + mHandler.postDelayed(new Runnable() { + + @Override + public void run() { + mScanning = false; + mBluetoothAdapter.stopLeScan(MiActivity.this); + } + }, SCAN_PERIOD); + + mScanning = true; + mBluetoothAdapter.startLeScan(this); + } else { + mScanning = false; + mBluetoothAdapter.stopLeScan(this); + } + } + + @Override + public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { + if(device != null && device.getName() != null & device.getName().equals("MI")) { + System.out.println(device.getAddress()); + scanLeDevice(false); // we only care about one miband so that's enough + } + } + + @Override + public void onPause() { + super.onPause(); + scanLeDevice(false); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/4b/30818ae5d98700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/4b/30818ae5d98700141885aa2aa9523af4 new file mode 100644 index 0000000..3c02242 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/4b/30818ae5d98700141885aa2aa9523af4 @@ -0,0 +1,11 @@ + + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/4b/80e7dddbde8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/4b/80e7dddbde8700141885aa2aa9523af4 new file mode 100644 index 0000000..bb40e7f --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/4b/80e7dddbde8700141885aa2aa9523af4 @@ -0,0 +1,23 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + private String mDeviceAddress; + private BluetoothAdapter mBluetoothAdapter; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothAdapter = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)) + .getAdapter(); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/4e/c0adfb16e9870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/4e/c0adfb16e9870014196aa5e86be5823c new file mode 100644 index 0000000..fc73b9f --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/4e/c0adfb16e9870014196aa5e86be5823c @@ -0,0 +1,149 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.UUID; + +import com.motioncoding.miband.model.MiBand; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; + +public class MiOverviewActivity extends Activity { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_AUTH = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + private MiBand mMiBand + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void auth() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_AUTH); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("Auth sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + auth(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after auth() + request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(characteristic.getValue())); + switch (state) { + case 0: + System.out.println(characteristic.getIntValue(0, 0)); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_ACTIVITY); + break; + case 3: + request(UUID_CHAR_DEVICE_NAME); + break; + } + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/5/605fa0fbd68700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/5/605fa0fbd68700141885aa2aa9523af4 new file mode 100644 index 0000000..d472406 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/5/605fa0fbd68700141885aa2aa9523af4 @@ -0,0 +1,30 @@ +package com.motioncoding.miband; + +import android.annotation.TargetApi; +import android.app.Activity; +import android.bluetooth.BluetoothManager; +import android.bluetooth.le.ScanCallback; +import android.content.Context; +import android.os.Build; +import android.os.Bundle; + +@TargetApi(21) public class MiActivity extends Activity { + + private BluetoothManager bluetoothManager; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_mi); + + bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); + + lookForMiBand(); + } + + private void lookForMiBand() { + bluetoothManager.getAdapter().getBluetoothLeScanner() + .startScan(new ScanCallback() { + }); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/51/70dbab7cdc8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/51/70dbab7cdc8700141885aa2aa9523af4 new file mode 100644 index 0000000..7f70228 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/51/70dbab7cdc8700141885aa2aa9523af4 @@ -0,0 +1,27 @@ + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/51/907d51def4870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/51/907d51def4870014196aa5e86be5823c new file mode 100644 index 0000000..c9c648d --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/51/907d51def4870014196aa5e86be5823c @@ -0,0 +1,24 @@ +package com.motioncoding.miband.model; + +public class LeParams { + public int connIntMin, connIntMax, latency, timeout, connInt, advInt; + + public static LeParams fromByte(byte[] b) { + LeParams params = new LeParams(); + + params.connIntMax = 0xffff & (0xff & b[0] | (0xff & b[1]) << 8); + params.connIntMax = 0xffff & (0xff & b[2] | (0xff & b[3]) << 8); + params.latency = 0xffff & (0xff & b[4] | (0xff & b[5]) << 8); + params.timeout = 0xffff & (0xff & b[6] | (0xff & b[7]) << 8); + params.connInt = 0xffff & (0xff & b[8] | (0xff & b[9]) << 8); + params.advInt = 0xffff & (0xff & b[10] | (0xff & b[11]) << 8); + + params.connIntMin *= 1.25; + params.connIntMax *= 1.25; + params.advInt *= 0.625; + params.timeout *= 10; + + + return params; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/51/a01ed591f8870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/51/a01ed591f8870014196aa5e86be5823c new file mode 100644 index 0000000..81b6403 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/51/a01ed591f8870014196aa5e86be5823c @@ -0,0 +1,33 @@ +package com.motioncoding.miband; + +import android.app.ListActivity; +import android.os.Bundle; +import android.widget.ArrayAdapter; + +import com.motioncoding.miband.model.LeParams; + +public class MiLeParamsActivity extends ListActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + + LeParams params = (LeParams) getIntent().getParcelableExtra("params"); + + String[] values = new String[6]; + + values[0] = String.format("Connection Intervall\n %s ms", params.connInt); + values[1] = String.format("Connection Intervall Min\n %s ms", params.connIntMin); + values[2] = String.format("Connection Intervall Max\n %s ms", params.connIntMax); + + values[3] = String.format("Advertising Intervall\n %s ms", params.advInt); + values[4] = String.format("Latency\n %s ms", params.latency); + values[5] = String.format("Timeout\n %s ms", params.timeout); + + + ArrayAdapter adapter = new ArrayAdapter(this, + android.R.layout.simple_list_item_1, values); + this.setListAdapter(adapter); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/52/00e855d0ec870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/52/00e855d0ec870014196aa5e86be5823c new file mode 100644 index 0000000..a479ff4 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/52/00e855d0ec870014196aa5e86be5823c @@ -0,0 +1,23 @@ + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/52/20689590f7870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/52/20689590f7870014196aa5e86be5823c new file mode 100644 index 0000000..416afb8 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/52/20689590f7870014196aa5e86be5823c @@ -0,0 +1,228 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Observable; +import java.util.Observer; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.LeParams; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity implements Observer { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_CONTROL_POINT = UUID + .fromString("0000ff05-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_LE_PARAMS = UUID + .fromString("0000ff09-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + // BLUETOOTH + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + private MiBand mMiBand = new MiBand(); + + // UI + private TextView mTVSteps; + private TextView mTVBatteryLevel; + private ProgressBar mLoading; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.addObserver(this); + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + + mTVSteps = (TextView) findViewById(R.id.text_steps); + mTVBatteryLevel = (TextView) findViewById(R.id.text_battery_level); + mLoading = (ProgressBar) findViewById(R.id.laoding); + + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.menu_overview, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.action_leparams: + break; + } + return true; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private void setColor(byte r, byte g, byte b) { + BluetoothGattCharacteristic theme = getMiliService().getCharacteristic( + UUID_CHAR_CONTROL_POINT); + theme.setValue(new byte[] { 14, r, g, b, 0 }); + mGatt.writeCharacteristic(theme); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() + // setColor((byte)127, (byte)0, (byte)0); + // request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + + // handle value + if (characteristic.getUuid().equals(UUID_CHAR_REALTIME_STEPS)) + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + else if (characteristic.getUuid().equals(UUID_CHAR_BATTERY)) { + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + } else if (characteristic.getUuid().equals(UUID_CHAR_DEVICE_NAME)) { + mMiBand.setName(new String(b)); + } else if (characteristic.getUuid().equals(UUID_CHAR_LE_PARAMS)) { + LeParams params = LeParams.fromByte(b); + mMiBand.setLeParams(params); + } + + // proceed with state machine (called in the beginning) + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_DEVICE_NAME); + break; + case 3: + request(UUID_CHAR_LE_PARAMS); + break; + } + } + }; + + @Override + public void update(Observable observable, Object data) { + runOnUiThread(new Runnable() { + + @Override + public void run() { + mLoading.setVisibility(View.GONE); + ((LinearLayout) findViewById(R.id.textHolder)) + .setVisibility(View.VISIBLE); + mTVSteps.setText(mMiBand.mSteps + ""); + if (mMiBand.mBattery != null) + mTVBatteryLevel.setText(mMiBand.mBattery.mBatteryLevel + + "%"); + } + }); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/53/50ba50e2d68700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/53/50ba50e2d68700141885aa2aa9523af4 new file mode 100644 index 0000000..7a8ff49 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/53/50ba50e2d68700141885aa2aa9523af4 @@ -0,0 +1,28 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothManager; +import android.bluetooth.le.ScanCallback; +import android.content.Context; +import android.os.Bundle; + +public class MiActivity extends Activity { + + private BluetoothManager bluetoothManager; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_mi); + + bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); + + lookForMiBand(); + } + + private void lookForMiBand() { + bluetoothManager.getAdapter().getBluetoothLeScanner() + .startScan(new ScanCallback() { + }); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/53/b0d5fc67de8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/53/b0d5fc67de8700141885aa2aa9523af4 new file mode 100644 index 0000000..eec0329 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/53/b0d5fc67de8700141885aa2aa9523af4 @@ -0,0 +1,13 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_mi_overview); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/55/70e4f6dfd98700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/55/70e4f6dfd98700141885aa2aa9523af4 new file mode 100644 index 0000000..a91fd03 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/55/70e4f6dfd98700141885aa2aa9523af4 @@ -0,0 +1,12 @@ + + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/57/005656c7d78700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/57/005656c7d78700141885aa2aa9523af4 new file mode 100644 index 0000000..206bf7b --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/57/005656c7d78700141885aa2aa9523af4 @@ -0,0 +1,68 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothAdapter.LeScanCallback; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.os.Bundle; +import android.os.Handler; + +public class MiActivity extends Activity implements LeScanCallback { + + private BluetoothManager bluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private boolean mScanning; + private Handler mHandler; + // Stops scanning after 10 seconds. + private static final long SCAN_PERIOD = 10000; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_mi); + bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); + } + + @Override + public void onResume() { + super.onResume(); + } + + + + + private void scanLeDevice(final boolean enable) { + if (enable) { + // Stops scanning after a pre-defined scan period. + mHandler.postDelayed(new Runnable() { + @Override + public void run() { + mScanning = false; + mBluetoothAdapter.stopLeScan(this); + } + }, SCAN_PERIOD); + + mScanning = true; + mBluetoothAdapter.startLeScan(this); + } else { + mScanning = false; + mBluetoothAdapter.stopLeScan(this); + } + } + + @Override + public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { + if(device != null && device.getName() != null & device.getName().equals("MI")) { + System.out.println(device.getAddress()); + bluetoothManager.getAdapter().stopLeScan(this); + } + } + + @Override + public void onPause() { + super.onPause(); + bluetoothManager.getAdapter().stopLeScan(this); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/57/10e23bc9db8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/57/10e23bc9db8700141885aa2aa9523af4 new file mode 100644 index 0000000..81c318c --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/57/10e23bc9db8700141885aa2aa9523af4 @@ -0,0 +1,26 @@ + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/57/b0c31529da8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/57/b0c31529da8700141885aa2aa9523af4 new file mode 100644 index 0000000..3e61a52 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/57/b0c31529da8700141885aa2aa9523af4 @@ -0,0 +1,12 @@ + + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/57/c03bfee9e9870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/57/c03bfee9e9870014196aa5e86be5823c new file mode 100644 index 0000000..59b7aaa --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/57/c03bfee9e9870014196aa5e86be5823c @@ -0,0 +1,155 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; + +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_AUTH = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + private MiBand mMiBand = new MiBand(); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void auth() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_AUTH); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("Auth sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + auth(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after auth() + request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(characteristic.getValue())); + switch (state) { + case 0: + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + break; + case 1: + Battery battery = Battery.fromByte(characteristic.getValue()); + mMiBand.setBattery(battery); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_ACTIVITY); + break; + case 3: + request(UUID_CHAR_DEVICE_NAME); + break; + } + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/58/b02315c3f4870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/58/b02315c3f4870014196aa5e86be5823c new file mode 100644 index 0000000..ce29091 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/58/b02315c3f4870014196aa5e86be5823c @@ -0,0 +1,20 @@ +package com.motioncoding.miband.model; + +public class LeParams { + public int connIntMin, connIntMax, latency, timeout, connInt, advInt; + + public static LeParams fromByte(byte[] b) { + LeParams params = new LeParams(); + + params.connIntMax = 0xffff & (0xff & b[0] | (0xff & b[1]) << 8); + params.connIntMax = 0xffff & (0xff & b[2] | (0xff & b[3]) << 8); + params.latency = 0xffff & (0xff & b[4] | (0xff & b[5]) << 8); + params.timeout = 0xffff & (0xff & b[6] | (0xff & b[7]) << 8); + params.connInt = 0xffff & (0xff & b[8] | (0xff & b[9]) << 8); + params.advInt = 0xffff & (0xff & b[10] | (0xff & b[11]) << 8); + + params.connIntMin *= 1.25f; + + return params; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/59/0087ef07eb870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/59/0087ef07eb870014196aa5e86be5823c new file mode 100644 index 0000000..77a16e5 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/59/0087ef07eb870014196aa5e86be5823c @@ -0,0 +1,156 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; + +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_AUTH = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + private MiBand mMiBand = new MiBand(); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void auth() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_AUTH); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("Auth sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + auth(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after auth() + request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + switch (state) { + case 0: + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + break; + case 1: + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_ACTIVITY); + break; + case 3: + request(UUID_CHAR_DEVICE_NAME); + break; + } + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/59/407870a9dd8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/59/407870a9dd8700141885aa2aa9523af4 new file mode 100644 index 0000000..6beafe7 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/59/407870a9dd8700141885aa2aa9523af4 @@ -0,0 +1,82 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothAdapter.LeScanCallback; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.widget.TextView; + +public class MiActivity extends Activity implements LeScanCallback { + + private BluetoothAdapter mBluetoothAdapter; + private boolean mScanning; + private TextView mTextView; + private Handler mHandler = new Handler(); + // Stops scanning after 10 seconds. + private static final long SCAN_PERIOD = 10000; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + setContentView(R.layout.activity_mi); + mTextView = (TextView) findViewById(R.id.text_search); + mBluetoothAdapter = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)) + .getAdapter(); + } + + @Override + public void onResume() { + super.onResume(); + scanLeDevice(true); + } + + @SuppressWarnings("deprecation") + // L Apis are buggy and crap! + private void scanLeDevice(final boolean enable) { + if (enable) { + // Stops scanning after a pre-defined scan period. + mHandler.postDelayed(new Runnable() { + + @Override + public void run() { + mScanning = false; + mBluetoothAdapter.stopLeScan(MiActivity.this); + scanLeDevice(true); +// mTextView.setText(R.string.not_found); + } + }, SCAN_PERIOD); + + mScanning = true; + mBluetoothAdapter.startLeScan(this); + } else { + mScanning = false; + mBluetoothAdapter.stopLeScan(this); + } + } + + @Override + public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { + System.out.println(device.getName() + " " + device.getAddress()); + if (device != null && device.getName() != null + & device.getName().equals("MI")) { + System.out.println(device.getAddress()); + scanLeDevice(false); // we only care about one miband so that's + // enough + Intent intent = new Intent(getApplicationContext(), MiOverviewActivity.class); + intent.putExtra("address", device.getAddress()); + startActivity(intent); + } + } + + @Override + public void onPause() { + super.onPause(); + scanLeDevice(false); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/59/60488e56f5870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/59/60488e56f5870014196aa5e86be5823c new file mode 100644 index 0000000..1d122d5 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/59/60488e56f5870014196aa5e86be5823c @@ -0,0 +1,206 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Observable; +import java.util.Observer; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity implements Observer { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_CONTROL_POINT = UUID + .fromString("0000ff05-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_LE_PARAMS = UUID + .fromString("0000ff09-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + // BLUETOOTH + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + private MiBand mMiBand = new MiBand(); + + // UI + private TextView mTVSteps; + private TextView mTVBatteryLevel; + private ProgressBar mLoading; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.addObserver(this); + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + + mTVSteps = (TextView) findViewById(R.id.text_steps); + mTVBatteryLevel = (TextView) findViewById(R.id.text_battery_level); + mLoading = (ProgressBar) findViewById(R.id.laoding); + + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private void setColor(byte r, byte g, byte b) { + BluetoothGattCharacteristic theme = getMiliService() + .getCharacteristic(UUID_CHAR_CONTROL_POINT); + theme.setValue(new byte[] { 14, r, g, b, 0 }); + mGatt.writeCharacteristic(theme); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() +// setColor((byte)127, (byte)0, (byte)0); +// request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + switch (state) { + case 0: + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + break; + case 1: + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + break; + case 2: + mMiBand.setName(new String(b)); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_DEVICE_NAME); + break; + case 3: + request(UUID_LE_PARAMS); + break; + } + } + }; + + @Override + public void update(Observable observable, Object data) { + runOnUiThread(new Runnable() { + + @Override + public void run() { + mLoading.setVisibility(View.GONE); + ((LinearLayout) findViewById(R.id.textHolder)) + .setVisibility(View.VISIBLE); + mTVSteps.setText(mMiBand.mSteps + ""); + if (mMiBand.mBattery != null) + mTVBatteryLevel.setText(mMiBand.mBattery.mBatteryLevel + + "%"); + } + }); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/59/80f225b8e6870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/59/80f225b8e6870014196aa5e86be5823c new file mode 100644 index 0000000..74c2704 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/59/80f225b8e6870014196aa5e86be5823c @@ -0,0 +1,117 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; + +public class MiOverviewActivity extends Activity { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_AUTH = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void auth() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_AUTH); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("Auth sent"); + } + + private void requestSteps() { + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_REALTIME_STEPS); + mGatt.readCharacteristic(chrt); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + auth(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + requestSteps(); + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + Log.i(characteristic.getUuid().toString(), + Arrays.toString(characteristic.getValue())); + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/59/d05cba9eed870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/59/d05cba9eed870014196aa5e86be5823c new file mode 100644 index 0000000..e9c937c --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/59/d05cba9eed870014196aa5e86be5823c @@ -0,0 +1,158 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; + +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_CONTROL_POINT = UUID + .fromString("0000ff05-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + private MiBand mMiBand = new MiBand(); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() + request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + switch (state) { + case 0: + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + break; + case 1: + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + break; + case 2: + mMiBand.setName(new String(b)); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_DEVICE_NAME); + break; + } + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/5d/4051e238f9870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/5d/4051e238f9870014196aa5e86be5823c new file mode 100644 index 0000000..403bb1d --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/5d/4051e238f9870014196aa5e86be5823c @@ -0,0 +1,307 @@ +package com.motioncoding.miband.view; + +import android.R; +import android.app.Dialog; +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.LinearGradient; +import android.graphics.Paint; +import android.graphics.Shader; +import android.os.Bundle; +import android.view.MotionEvent; +import android.view.View; + +public class ColorPickerDialog extends Dialog { + + public interface OnColorChangedListener { + void colorChanged(String key, int color); + } + + private OnColorChangedListener mListener; + private int mInitialColor, mDefaultColor; + private String mKey; + + private static class ColorPickerView extends View { + private Paint mPaint; + private float mCurrentHue = 0; + private int mCurrentX = 0, mCurrentY = 0; + private int mCurrentColor, mDefaultColor; + private final int[] mHueBarColors = new int[258]; + private int[] mMainColors = new int[65536]; + private OnColorChangedListener mListener; + + ColorPickerView(Context c, OnColorChangedListener l, int color, + int defaultColor) { + super(c); + mListener = l; + mDefaultColor = defaultColor; + + // Get the current hue from the current color and update the main + // color field + float[] hsv = new float[3]; + Color.colorToHSV(color, hsv); + mCurrentHue = hsv[0]; + updateMainColors(); + + mCurrentColor = color; + + // Initialize the colors of the hue slider bar + int index = 0; + for (float i = 0; i < 256; i += 256 / 42) // Red (#f00) to pink + // (#f0f) + { + mHueBarColors[index] = Color.rgb(255, 0, (int) i); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) // Pink (#f0f) to blue + // (#00f) + { + mHueBarColors[index] = Color.rgb(255 - (int) i, 0, 255); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) // Blue (#00f) to light + // blue (#0ff) + { + mHueBarColors[index] = Color.rgb(0, (int) i, 255); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) // Light blue (#0ff) to + // green (#0f0) + { + mHueBarColors[index] = Color.rgb(0, 255, 255 - (int) i); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) // Green (#0f0) to yellow + // (#ff0) + { + mHueBarColors[index] = Color.rgb((int) i, 255, 0); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) // Yellow (#ff0) to red + // (#f00) + { + mHueBarColors[index] = Color.rgb(255, 255 - (int) i, 0); + index++; + } + + // Initializes the Paint that will draw the View + mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + mPaint.setTextAlign(Paint.Align.CENTER); + mPaint.setTextSize(12); + } + + // Get the current selected color from the hue bar + private int getCurrentMainColor() { + int translatedHue = 255 - (int) (mCurrentHue * 255 / 360); + int index = 0; + for (float i = 0; i < 256; i += 256 / 42) { + if (index == translatedHue) + return Color.rgb(255, 0, (int) i); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) { + if (index == translatedHue) + return Color.rgb(255 - (int) i, 0, 255); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) { + if (index == translatedHue) + return Color.rgb(0, (int) i, 255); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) { + if (index == translatedHue) + return Color.rgb(0, 255, 255 - (int) i); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) { + if (index == translatedHue) + return Color.rgb((int) i, 255, 0); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) { + if (index == translatedHue) + return Color.rgb(255, 255 - (int) i, 0); + index++; + } + return Color.RED; + } + + // Update the main field colors depending on the current selected hue + private void updateMainColors() { + int mainColor = getCurrentMainColor(); + int index = 0; + int[] topColors = new int[256]; + for (int y = 0; y < 256; y++) { + for (int x = 0; x < 256; x++) { + if (y == 0) { + mMainColors[index] = Color.rgb( + 255 - (255 - Color.red(mainColor)) * x / 255, + 255 - (255 - Color.green(mainColor)) * x / 255, + 255 - (255 - Color.blue(mainColor)) * x / 255); + topColors[x] = mMainColors[index]; + } else + mMainColors[index] = Color.rgb( + (255 - y) * Color.red(topColors[x]) / 255, + (255 - y) * Color.green(topColors[x]) / 255, + (255 - y) * Color.blue(topColors[x]) / 255); + index++; + } + } + } + + @Override + protected void onDraw(Canvas canvas) { + int translatedHue = 255 - (int) (mCurrentHue * 255 / 360); + // Display all the colors of the hue bar with lines + for (int x = 0; x < 256; x++) { + // If this is not the current selected hue, display the actual + // color + if (translatedHue != x) { + mPaint.setColor(mHueBarColors[x]); + mPaint.setStrokeWidth(1); + } else // else display a slightly larger black line + { + mPaint.setColor(Color.BLACK); + mPaint.setStrokeWidth(3); + } + canvas.drawLine(x + 10, 0, x + 10, 40, mPaint); + // canvas.drawLine(0, x+10, 40, x+10, mPaint); + } + + // Display the main field colors using LinearGradient + for (int x = 0; x < 256; x++) { + int[] colors = new int[2]; + colors[0] = mMainColors[x]; + colors[1] = Color.BLACK; + Shader shader = new LinearGradient(0, 50, 0, 306, colors, null, + Shader.TileMode.REPEAT); + mPaint.setShader(shader); + canvas.drawLine(x + 10, 50, x + 10, 306, mPaint); + } + mPaint.setShader(null); + + // Display the circle around the currently selected color in the + // main field + if (mCurrentX != 0 && mCurrentY != 0) { + mPaint.setStyle(Paint.Style.STROKE); + mPaint.setColor(Color.BLACK); + canvas.drawCircle(mCurrentX, mCurrentY, 10, mPaint); + } + + // Draw a 'button' with the currently selected color + mPaint.setStyle(Paint.Style.FILL); + mPaint.setColor(mCurrentColor); + canvas.drawRect(10, 316, 138, 356, mPaint); + + // Set the text color according to the brightness of the color + if (Color.red(mCurrentColor) + Color.green(mCurrentColor) + + Color.blue(mCurrentColor) < 384) + mPaint.setColor(Color.WHITE); + else + mPaint.setColor(Color.BLACK); + canvas.drawText( + "bg", 74, + 340, mPaint); + + // Draw a 'button' with the default color + mPaint.setStyle(Paint.Style.FILL); + mPaint.setColor(mDefaultColor); + canvas.drawRect(138, 316, 266, 356, mPaint); + + // Set the text color according to the brightness of the color + if (Color.red(mDefaultColor) + Color.green(mDefaultColor) + + Color.blue(mDefaultColor) < 384) + mPaint.setColor(Color.WHITE); + else + mPaint.setColor(Color.BLACK); + canvas.drawText( + "edf", 202, 340, + mPaint); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + setMeasuredDimension(276, 366); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + if (event.getAction() != MotionEvent.ACTION_DOWN) + return true; + float x = event.getX(); + float y = event.getY(); + + // If the touch event is located in the hue bar + if (x > 10 && x < 266 && y > 0 && y < 40) { + // Update the main field colors + mCurrentHue = (255 - x) * 360 / 255; + updateMainColors(); + + // Update the current selected color + int transX = mCurrentX - 10; + int transY = mCurrentY - 60; + int index = 256 * (transY - 1) + transX; + if (index > 0 && index < mMainColors.length) + mCurrentColor = mMainColors[256 * (transY - 1) + transX]; + + // Force the redraw of the dialog + invalidate(); + } + + // If the touch event is located in the main field + if (x > 10 && x < 266 && y > 50 && y < 306) { + mCurrentX = (int) x; + mCurrentY = (int) y; + int transX = mCurrentX - 10; + int transY = mCurrentY - 60; + int index = 256 * (transY - 1) + transX; + if (index > 0 && index < mMainColors.length) { + // Update the current color + mCurrentColor = mMainColors[index]; + // Force the redraw of the dialog + invalidate(); + } + } + + // If the touch event is located in the left button, notify the + // listener with the current color + if (x > 10 && x < 138 && y > 316 && y < 356) + mListener.colorChanged("", mCurrentColor); + + // If the touch event is located in the right button, notify the + // listener with the default color + if (x > 138 && x < 266 && y > 316 && y < 356) + mListener.colorChanged("", mDefaultColor); + + return true; + } + } + + public ColorPickerDialog(Context context, OnColorChangedListener listener, + String key, int initialColor, int defaultColor) { + super(context); + + mListener = listener; + mKey = key; + mInitialColor = initialColor; + mDefaultColor = defaultColor; + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + OnColorChangedListener l = new OnColorChangedListener() { + public void colorChanged(String key, int color) { + mListener.colorChanged(mKey, color); + dismiss(); + } + }; + + setContentView(new ColorPickerView(getContext(), l, mInitialColor, + mDefaultColor)); + setTitle("Set LED Color"); + + } +} \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/5d/6096e2b5df8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/5d/6096e2b5df8700141885aa2aa9523af4 new file mode 100644 index 0000000..968bce4 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/5d/6096e2b5df8700141885aa2aa9523af4 @@ -0,0 +1,44 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + + } + + + @Override + public void onResume() { + super.onResume(); + + } + + @Override + public void onPause() { + super.onPause(); + } + + + + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/5d/b0dfbaa8e4870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/5d/b0dfbaa8e4870014196aa5e86be5823c new file mode 100644 index 0000000..55b425b --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/5d/b0dfbaa8e4870014196aa5e86be5823c @@ -0,0 +1,35 @@ +package com.motioncoding.miband.model; + +import java.util.Calendar; + +public class MiBand { + + String mBTAddress; + int mSteps; + + + static class Battery { + int mBatteryLevel; + int mCycles; + Calendar mLastCharged; + + public static Battery fromByte(byte[] b) { + return null; + } + + static enum Status { + LOW, FULL, CHARGING, NOT_CHARGING; + + public static Status fromByte(byte b) { + switch (b) { + case 1: return LOW; + case 2: return CHARGING; + case 3: return FULL; + case 4: return NOT_CHARGING; + + default: return null; + } + } + } + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/5e/5082c18adc8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/5e/5082c18adc8700141885aa2aa9523af4 new file mode 100644 index 0000000..a2374b4 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/5e/5082c18adc8700141885aa2aa9523af4 @@ -0,0 +1,20 @@ + + + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/5f/1015cee3e28700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/5f/1015cee3e28700141885aa2aa9523af4 new file mode 100644 index 0000000..475ac9c --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/5f/1015cee3e28700141885aa2aa9523af4 @@ -0,0 +1,96 @@ +package com.motioncoding.miband; + +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void auth() { + BluetoothGattService service = mGatt.getService(UUID.fromString("00001800-0000-1000-8000-00805f9b34fb")); + BluetoothGattCharacteristic chrt = service.getCharacteristic(UUID.fromString("0000ff0f-0000-1000-8000-00805f9b34fb")); + + chrt.setValue(new byte[] {2}); + + mGatt.writeCharacteristic(chrt); + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + for (BluetoothGattService srvs : gatt.getServices()) { + System.out.println("Service: "+srvs.getUuid()); + for (BluetoothGattCharacteristic chrt : srvs + .getCharacteristics()) { + System.out.println("Characteristic: "+chrt.getUuid()+" with "+chrt.getProperties()); + } + } + } + + auth(); + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/6/a0c491d5e8870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/6/a0c491d5e8870014196aa5e86be5823c new file mode 100644 index 0000000..575092a --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/6/a0c491d5e8870014196aa5e86be5823c @@ -0,0 +1,38 @@ +package com.motioncoding.miband.model; + +import java.util.Calendar; + +public class Battery { + public int mBatteryLevel; + public int mCycles; + public Calendar mLastCharged; + public Status mStatus; + + public static Battery fromByte(byte[] b) { + Battery battery = new Battery(); + battery.mBatteryLevel = b[0]; + battery.mStatus = Status.fromByte(b[9]); + + return battery; + } + + static enum Status { + LOW, FULL, CHARGING, NOT_CHARGING; + + public static Status fromByte(byte b) { + switch (b) { + case 1: + return LOW; + case 2: + return CHARGING; + case 3: + return FULL; + case 4: + return NOT_CHARGING; + + default: + return null; + } + } + } +} \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/61/c0b48cf8ec870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/61/c0b48cf8ec870014196aa5e86be5823c new file mode 100644 index 0000000..d9871f1 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/61/c0b48cf8ec870014196aa5e86be5823c @@ -0,0 +1,38 @@ + + + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/62/4005706df6870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/62/4005706df6870014196aa5e86be5823c new file mode 100644 index 0000000..dadf73f --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/62/4005706df6870014196aa5e86be5823c @@ -0,0 +1,15 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; + +public class MiLeParamsActivity extends ListActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_mi_le_params); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/62/80b62d30da8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/62/80b62d30da8700141885aa2aa9523af4 new file mode 100644 index 0000000..b0ce582 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/62/80b62d30da8700141885aa2aa9523af4 @@ -0,0 +1,76 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothAdapter.LeScanCallback; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; + +public class MiActivity extends Activity implements LeScanCallback { + + private BluetoothAdapter mBluetoothAdapter; + private boolean mScanning; + private Handler mHandler = new Handler(); + // Stops scanning after 10 seconds. + private static final long SCAN_PERIOD = 10000; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + if(Build.VERSION.SDK_INT >= 14) { + getActionBar().hide(); + } + + setContentView(R.layout.activity_mi); + mBluetoothAdapter = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)).getAdapter(); + } + + @Override + public void onResume() { + super.onResume(); + scanLeDevice(true); + } + + + + @SuppressWarnings("deprecation") // L Apis are buggy and crap! + private void scanLeDevice(final boolean enable) { + if (enable) { + // Stops scanning after a pre-defined scan period. + mHandler.postDelayed(new Runnable() { + + @Override + public void run() { + mScanning = false; + mBluetoothAdapter.stopLeScan(MiActivity.this); + scanLeDevice(true); + } + }, SCAN_PERIOD); + + mScanning = true; + mBluetoothAdapter.startLeScan(this); + } else { + mScanning = false; + mBluetoothAdapter.stopLeScan(this); + } + } + + @Override + public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { + System.out.println(device.getName()+" "+device.getAddress()); + if(device != null && device.getName() != null & device.getName().equals("MI")) { + System.out.println(device.getAddress()); + scanLeDevice(false); // we only care about one miband so that's enough + } + } + + @Override + public void onPause() { + super.onPause(); + scanLeDevice(false); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/63/f058ef1cf6870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/63/f058ef1cf6870014196aa5e86be5823c new file mode 100644 index 0000000..a0fa936 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/63/f058ef1cf6870014196aa5e86be5823c @@ -0,0 +1,68 @@ +package com.motioncoding.miband.model; + +import android.os.Parcel; +import android.os.Parcelable; + +public class LeParams implements Parcelable { + public int connIntMin; + public int connIntMax; + public int latency; + public int timeout; + public int connInt; + public int advInt; + + public static LeParams fromByte(byte[] b) { + LeParams params = new LeParams(); + + params.connIntMax = 0xffff & (0xff & b[0] | (0xff & b[1]) << 8); + params.connIntMax = 0xffff & (0xff & b[2] | (0xff & b[3]) << 8); + params.latency = 0xffff & (0xff & b[4] | (0xff & b[5]) << 8); + params.timeout = 0xffff & (0xff & b[6] | (0xff & b[7]) << 8); + params.connInt = 0xffff & (0xff & b[8] | (0xff & b[9]) << 8); + params.advInt = 0xffff & (0xff & b[10] | (0xff & b[11]) << 8); + + params.connIntMin *= 1.25; + params.connIntMax *= 1.25; + params.advInt *= 0.625; + params.timeout *= 10; + + return params; + } + + protected LeParams(Parcel in) { + connIntMin = in.readInt(); + connIntMax = in.readInt(); + latency = in.readInt(); + timeout = in.readInt(); + connInt = in.readInt(); + advInt = in.readInt(); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(connIntMin); + dest.writeInt(connIntMax); + dest.writeInt(latency); + dest.writeInt(timeout); + dest.writeInt(connInt); + dest.writeInt(advInt); + } + + @SuppressWarnings("unused") + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + @Override + public LeParams createFromParcel(Parcel in) { + return new LeParams(in); + } + + @Override + public LeParams[] newArray(int size) { + return new LeParams[size]; + } + }; +} \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/67/105366f2da8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/67/105366f2da8700141885aa2aa9523af4 new file mode 100644 index 0000000..df37681 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/67/105366f2da8700141885aa2aa9523af4 @@ -0,0 +1,8 @@ + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/68/808d3ab6f7870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/68/808d3ab6f7870014196aa5e86be5823c new file mode 100644 index 0000000..add767b --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/68/808d3ab6f7870014196aa5e86be5823c @@ -0,0 +1,231 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Observable; +import java.util.Observer; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.LeParams; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity implements Observer { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_CONTROL_POINT = UUID + .fromString("0000ff05-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_LE_PARAMS = UUID + .fromString("0000ff09-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + // BLUETOOTH + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + private MiBand mMiBand = new MiBand(); + + // UI + private TextView mTVSteps; + private TextView mTVBatteryLevel; + private ProgressBar mLoading; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.addObserver(this); + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + + mTVSteps = (TextView) findViewById(R.id.text_steps); + mTVBatteryLevel = (TextView) findViewById(R.id.text_battery_level); + mLoading = (ProgressBar) findViewById(R.id.laoding); + + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.menu_overview, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.action_leparams: + Intent intent = new Intent(getApplicationContext(), MiLeParamsActivity.class); + intent.putExtra("params", mMiBand.mLeParams); + break; + } + return true; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private void setColor(byte r, byte g, byte b) { + BluetoothGattCharacteristic theme = getMiliService().getCharacteristic( + UUID_CHAR_CONTROL_POINT); + theme.setValue(new byte[] { 14, r, g, b, 0 }); + mGatt.writeCharacteristic(theme); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() + // setColor((byte)127, (byte)0, (byte)0); + // request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + + // handle value + if (characteristic.getUuid().equals(UUID_CHAR_REALTIME_STEPS)) + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + else if (characteristic.getUuid().equals(UUID_CHAR_BATTERY)) { + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + } else if (characteristic.getUuid().equals(UUID_CHAR_DEVICE_NAME)) { + mMiBand.setName(new String(b)); + } else if (characteristic.getUuid().equals(UUID_CHAR_LE_PARAMS)) { + LeParams params = LeParams.fromByte(b); + mMiBand.setLeParams(params); + } + + // proceed with state machine (called in the beginning) + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_DEVICE_NAME); + break; + case 3: + request(UUID_CHAR_LE_PARAMS); + break; + } + } + }; + + @Override + public void update(Observable observable, Object data) { + runOnUiThread(new Runnable() { + + @Override + public void run() { + mLoading.setVisibility(View.GONE); + ((LinearLayout) findViewById(R.id.textHolder)) + .setVisibility(View.VISIBLE); + mTVSteps.setText(mMiBand.mSteps + ""); + if (mMiBand.mBattery != null) + mTVBatteryLevel.setText(mMiBand.mBattery.mBatteryLevel + + "%"); + } + }); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/6b/a008d1b0e4870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/6b/a008d1b0e4870014196aa5e86be5823c new file mode 100644 index 0000000..0a3d7e3 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/6b/a008d1b0e4870014196aa5e86be5823c @@ -0,0 +1,5 @@ +package com.motioncoding.miband.model; + +public class Battery { + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/6c/00dcede8cf8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/6c/00dcede8cf8700141885aa2aa9523af4 new file mode 100644 index 0000000..a91fd03 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/6c/00dcede8cf8700141885aa2aa9523af4 @@ -0,0 +1,12 @@ + + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/6c/50740a3bec870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/6c/50740a3bec870014196aa5e86be5823c new file mode 100644 index 0000000..8a67111 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/6c/50740a3bec870014196aa5e86be5823c @@ -0,0 +1,34 @@ +package com.motioncoding.miband.model; + +import java.util.Observable; + +import com.motioncoding.debugging.L; + + +public class MiBand extends Observable { + + public String mBTAddress; + public int mSteps; + public String mName; + public Battery mBattery; + + + + public void setName(String name) { + mName = name; + notifyObservers(); + } + + public void setSteps(int steps) { + mSteps = steps; + L.i("setting "+steps+" steps"); + notifyObservers(); + } + + public void setBattery(Battery battery) { + mBattery = battery; + L.i(battery.toString()); + notifyObservers(); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/6e/50cd0ee9d68700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/6e/50cd0ee9d68700141885aa2aa9523af4 new file mode 100644 index 0000000..ead3598 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/6e/50cd0ee9d68700141885aa2aa9523af4 @@ -0,0 +1,30 @@ +package com.motioncoding.miband; + +import android.annotation.TargetApi; +import android.app.Activity; +import android.bluetooth.BluetoothManager; +import android.bluetooth.le.ScanCallback; +import android.content.Context; +import android.os.Build; +import android.os.Bundle; + +@TargetApi(Build.VERSION_CODES.L) public class MiActivity extends Activity { + + private BluetoothManager bluetoothManager; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_mi); + + bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); + + lookForMiBand(); + } + + private void lookForMiBand() { + bluetoothManager.getAdapter().getBluetoothLeScanner() + .startScan(new ScanCallback() { + }); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/6e/80e6d462f3870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/6e/80e6d462f3870014196aa5e86be5823c new file mode 100644 index 0000000..1bb5350 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/6e/80e6d462f3870014196aa5e86be5823c @@ -0,0 +1,204 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Observable; +import java.util.Observer; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity implements Observer { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_CONTROL_POINT = UUID + .fromString("0000ff05-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + // BLUETOOTH + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + private MiBand mMiBand = new MiBand(); + + // UI + private TextView mTVSteps; + private TextView mTVBatteryLevel; + private ProgressBar mLoading; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.addObserver(this); + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + + mTVSteps = (TextView) findViewById(R.id.text_steps); + mTVBatteryLevel = (TextView) findViewById(R.id.text_battery_level); + mLoading = (ProgressBar) findViewById(R.id.laoding); + + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private void setColor(byte r, byte g, byte b) { + BluetoothGattCharacteristic theme = getMiliService() + .getCharacteristic(UUID_CHAR_CONTROL_POINT); + theme.setValue(new byte[] { 14, r, g, b, 0 }); + mGatt.writeCharacteristic(theme); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() + setColor(127, 0, 0); +// request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + switch (state) { + case 0: + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + break; + case 1: + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + break; + case 2: + mMiBand.setName(new String(b)); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_DEVICE_NAME); + break; + case 3: + + break; + } + } + }; + + @Override + public void update(Observable observable, Object data) { + runOnUiThread(new Runnable() { + + @Override + public void run() { + mLoading.setVisibility(View.GONE); + ((LinearLayout) findViewById(R.id.textHolder)) + .setVisibility(View.VISIBLE); + mTVSteps.setText(mMiBand.mSteps + ""); + if (mMiBand.mBattery != null) + mTVBatteryLevel.setText(mMiBand.mBattery.mBatteryLevel + + "%"); + } + }); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/6e/c0192c29f9870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/6e/c0192c29f9870014196aa5e86be5823c new file mode 100644 index 0000000..c13b566 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/6e/c0192c29f9870014196aa5e86be5823c @@ -0,0 +1,309 @@ +package com.motioncoding.miband.view; + +import android.R; +import android.app.Dialog; +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.LinearGradient; +import android.graphics.Paint; +import android.graphics.Shader; +import android.os.Bundle; +import android.view.MotionEvent; +import android.view.View; + +public class ColorPickerDialog extends Dialog { + + public interface OnColorChangedListener { + void colorChanged(String key, int color); + } + + private OnColorChangedListener mListener; + private int mInitialColor, mDefaultColor; + private String mKey; + + private static class ColorPickerView extends View { + private Paint mPaint; + private float mCurrentHue = 0; + private int mCurrentX = 0, mCurrentY = 0; + private int mCurrentColor, mDefaultColor; + private final int[] mHueBarColors = new int[258]; + private int[] mMainColors = new int[65536]; + private OnColorChangedListener mListener; + + ColorPickerView(Context c, OnColorChangedListener l, int color, + int defaultColor) { + super(c); + mListener = l; + mDefaultColor = defaultColor; + + // Get the current hue from the current color and update the main + // color field + float[] hsv = new float[3]; + Color.colorToHSV(color, hsv); + mCurrentHue = hsv[0]; + updateMainColors(); + + mCurrentColor = color; + + // Initialize the colors of the hue slider bar + int index = 0; + for (float i = 0; i < 256; i += 256 / 42) // Red (#f00) to pink + // (#f0f) + { + mHueBarColors[index] = Color.rgb(255, 0, (int) i); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) // Pink (#f0f) to blue + // (#00f) + { + mHueBarColors[index] = Color.rgb(255 - (int) i, 0, 255); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) // Blue (#00f) to light + // blue (#0ff) + { + mHueBarColors[index] = Color.rgb(0, (int) i, 255); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) // Light blue (#0ff) to + // green (#0f0) + { + mHueBarColors[index] = Color.rgb(0, 255, 255 - (int) i); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) // Green (#0f0) to yellow + // (#ff0) + { + mHueBarColors[index] = Color.rgb((int) i, 255, 0); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) // Yellow (#ff0) to red + // (#f00) + { + mHueBarColors[index] = Color.rgb(255, 255 - (int) i, 0); + index++; + } + + // Initializes the Paint that will draw the View + mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + mPaint.setTextAlign(Paint.Align.CENTER); + mPaint.setTextSize(12); + } + + // Get the current selected color from the hue bar + private int getCurrentMainColor() { + int translatedHue = 255 - (int) (mCurrentHue * 255 / 360); + int index = 0; + for (float i = 0; i < 256; i += 256 / 42) { + if (index == translatedHue) + return Color.rgb(255, 0, (int) i); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) { + if (index == translatedHue) + return Color.rgb(255 - (int) i, 0, 255); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) { + if (index == translatedHue) + return Color.rgb(0, (int) i, 255); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) { + if (index == translatedHue) + return Color.rgb(0, 255, 255 - (int) i); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) { + if (index == translatedHue) + return Color.rgb((int) i, 255, 0); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) { + if (index == translatedHue) + return Color.rgb(255, 255 - (int) i, 0); + index++; + } + return Color.RED; + } + + // Update the main field colors depending on the current selected hue + private void updateMainColors() { + int mainColor = getCurrentMainColor(); + int index = 0; + int[] topColors = new int[256]; + for (int y = 0; y < 256; y++) { + for (int x = 0; x < 256; x++) { + if (y == 0) { + mMainColors[index] = Color.rgb( + 255 - (255 - Color.red(mainColor)) * x / 255, + 255 - (255 - Color.green(mainColor)) * x / 255, + 255 - (255 - Color.blue(mainColor)) * x / 255); + topColors[x] = mMainColors[index]; + } else + mMainColors[index] = Color.rgb( + (255 - y) * Color.red(topColors[x]) / 255, + (255 - y) * Color.green(topColors[x]) / 255, + (255 - y) * Color.blue(topColors[x]) / 255); + index++; + } + } + } + + @Override + protected void onDraw(Canvas canvas) { + int translatedHue = 255 - (int) (mCurrentHue * 255 / 360); + // Display all the colors of the hue bar with lines + for (int x = 0; x < 256; x++) { + // If this is not the current selected hue, display the actual + // color + if (translatedHue != x) { + mPaint.setColor(mHueBarColors[x]); + mPaint.setStrokeWidth(1); + } else // else display a slightly larger black line + { + mPaint.setColor(Color.BLACK); + mPaint.setStrokeWidth(3); + } + canvas.drawLine(x + 10, 0, x + 10, 40, mPaint); + // canvas.drawLine(0, x+10, 40, x+10, mPaint); + } + + // Display the main field colors using LinearGradient + for (int x = 0; x < 256; x++) { + int[] colors = new int[2]; + colors[0] = mMainColors[x]; + colors[1] = Color.BLACK; + Shader shader = new LinearGradient(0, 50, 0, 306, colors, null, + Shader.TileMode.REPEAT); + mPaint.setShader(shader); + canvas.drawLine(x + 10, 50, x + 10, 306, mPaint); + } + mPaint.setShader(null); + + // Display the circle around the currently selected color in the + // main field + if (mCurrentX != 0 && mCurrentY != 0) { + mPaint.setStyle(Paint.Style.STROKE); + mPaint.setColor(Color.BLACK); + canvas.drawCircle(mCurrentX, mCurrentY, 10, mPaint); + } + + // Draw a 'button' with the currently selected color + mPaint.setStyle(Paint.Style.FILL); + mPaint.setColor(mCurrentColor); + canvas.drawRect(10, 316, 138, 356, mPaint); + + // Set the text color according to the brightness of the color + if (Color.red(mCurrentColor) + Color.green(mCurrentColor) + + Color.blue(mCurrentColor) < 384) + mPaint.setColor(Color.WHITE); + else + mPaint.setColor(Color.BLACK); + canvas.drawText( + getResources() + .getString(R.string.settings_bg_color_confirm), 74, + 340, mPaint); + + // Draw a 'button' with the default color + mPaint.setStyle(Paint.Style.FILL); + mPaint.setColor(mDefaultColor); + canvas.drawRect(138, 316, 266, 356, mPaint); + + // Set the text color according to the brightness of the color + if (Color.red(mDefaultColor) + Color.green(mDefaultColor) + + Color.blue(mDefaultColor) < 384) + mPaint.setColor(Color.WHITE); + else + mPaint.setColor(Color.BLACK); + canvas.drawText( + getResources().getString( + R.string.settings_default_color_confirm), 202, 340, + mPaint); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + setMeasuredDimension(276, 366); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + if (event.getAction() != MotionEvent.ACTION_DOWN) + return true; + float x = event.getX(); + float y = event.getY(); + + // If the touch event is located in the hue bar + if (x > 10 && x < 266 && y > 0 && y < 40) { + // Update the main field colors + mCurrentHue = (255 - x) * 360 / 255; + updateMainColors(); + + // Update the current selected color + int transX = mCurrentX - 10; + int transY = mCurrentY - 60; + int index = 256 * (transY - 1) + transX; + if (index > 0 && index < mMainColors.length) + mCurrentColor = mMainColors[256 * (transY - 1) + transX]; + + // Force the redraw of the dialog + invalidate(); + } + + // If the touch event is located in the main field + if (x > 10 && x < 266 && y > 50 && y < 306) { + mCurrentX = (int) x; + mCurrentY = (int) y; + int transX = mCurrentX - 10; + int transY = mCurrentY - 60; + int index = 256 * (transY - 1) + transX; + if (index > 0 && index < mMainColors.length) { + // Update the current color + mCurrentColor = mMainColors[index]; + // Force the redraw of the dialog + invalidate(); + } + } + + // If the touch event is located in the left button, notify the + // listener with the current color + if (x > 10 && x < 138 && y > 316 && y < 356) + mListener.colorChanged("", mCurrentColor); + + // If the touch event is located in the right button, notify the + // listener with the default color + if (x > 138 && x < 266 && y > 316 && y < 356) + mListener.colorChanged("", mDefaultColor); + + return true; + } + } + + public ColorPickerDialog(Context context, OnColorChangedListener listener, + String key, int initialColor, int defaultColor) { + super(context); + + mListener = listener; + mKey = key; + mInitialColor = initialColor; + mDefaultColor = defaultColor; + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + OnColorChangedListener l = new OnColorChangedListener() { + public void colorChanged(String key, int color) { + mListener.colorChanged(mKey, color); + dismiss(); + } + }; + + setContentView(new ColorPickerView(getContext(), l, mInitialColor, + mDefaultColor)); + setTitle("Pick a color"); + + } +} \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/6f/30114ff0ed870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/6f/30114ff0ed870014196aa5e86be5823c new file mode 100644 index 0000000..151753a --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/6f/30114ff0ed870014196aa5e86be5823c @@ -0,0 +1,166 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Observable; +import java.util.Observer; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; + +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity implements Observer { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_CONTROL_POINT = UUID + .fromString("0000ff05-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + private MiBand mMiBand = new MiBand(); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.addObserver(this); + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() + request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + switch (state) { + case 0: + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + break; + case 1: + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + break; + case 2: + mMiBand.setName(new String(b)); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_DEVICE_NAME); + break; + } + } + }; + + @Override + public void update(Observable observable, Object data) { + + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/73/90c89f2dee870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/73/90c89f2dee870014196aa5e86be5823c new file mode 100644 index 0000000..ecbc12a --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/73/90c89f2dee870014196aa5e86be5823c @@ -0,0 +1,182 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Observable; +import java.util.Observer; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.ProgressBar; +import android.widget.Spinner; +import android.widget.TextView; + +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity implements Observer { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_CONTROL_POINT = UUID + .fromString("0000ff05-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + //BLUETOOTH + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + + private MiBand mMiBand = new MiBand(); + + //UI + private TextView mTVSteps; + private TextView mTVBatteryLevel; + private ProgressBar mLoading; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.addObserver(this); + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + + mTVSteps = (TextView) findViewById(R.id.text_steps); + mLoading = (ProgressBar) findViewById(R.id.laoding); + + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() + request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + switch (state) { + case 0: + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + break; + case 1: + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + break; + case 2: + mMiBand.setName(new String(b)); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_DEVICE_NAME); + break; + } + } + }; + + @Override + public void update(Observable observable, Object data) { + mLoading.setVisibility(View.GONE); + mTVSteps.setText(mMiBand.mSteps); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/73/d0e350e6ec870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/73/d0e350e6ec870014196aa5e86be5823c new file mode 100644 index 0000000..3209d40 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/73/d0e350e6ec870014196aa5e86be5823c @@ -0,0 +1,25 @@ + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/75/d08c2eaeee870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/75/d08c2eaeee870014196aa5e86be5823c new file mode 100644 index 0000000..aa8d0f1 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/75/d08c2eaeee870014196aa5e86be5823c @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/76/10d8ee12e9870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/76/10d8ee12e9870014196aa5e86be5823c new file mode 100644 index 0000000..baa0ccd --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/76/10d8ee12e9870014196aa5e86be5823c @@ -0,0 +1,38 @@ +package com.motioncoding.miband.model; + +import java.util.Calendar; + +public class Battery { + public int mBatteryLevel; + public int mCycles; + public Calendar mLastCharged; + public Status mStatus; + + public static Battery fromByte(byte[] b) { + Battery battery = new Battery(); + battery.mBatteryLevel = b[0]; + battery.mStatus = Status.fromByte(b[9]); + battery.mCycles = 0xffff & (0xff & b[7] | (0xff & b[8]) << 8); + return battery; + } + + static enum Status { + LOW, FULL, CHARGING, NOT_CHARGING; + + public static Status fromByte(byte b) { + switch (b) { + case 1: + return LOW; + case 2: + return CHARGING; + case 3: + return FULL; + case 4: + return NOT_CHARGING; + + default: + return null; + } + } + } +} \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/76/e0ac720ce5870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/76/e0ac720ce5870014196aa5e86be5823c new file mode 100644 index 0000000..c26f1a3 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/76/e0ac720ce5870014196aa5e86be5823c @@ -0,0 +1,102 @@ +package com.motioncoding.miband; + +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + private static final UUID UUID_MILI_SERVICE = UUID.fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_AUTH =UUID.fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS=UUID.fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY =UUID.fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void auth() { + BluetoothGattService service = mGatt.getService(UUID_MILI_SERVICE); + BluetoothGattCharacteristic chrt = service.getCharacteristic(UUID_CHAR_AUTH); + + chrt.setValue(new byte[] {2}); + + mGatt.writeCharacteristic(chrt); + System.out.println("Auth sent"); + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + for (BluetoothGattService srvs : gatt.getServices()) { + System.out.println("Service: "+srvs.getUuid()); + for (BluetoothGattCharacteristic chrt : srvs + .getCharacteristics()) { + System.out.println("Characteristic: "+chrt.getUuid()+" with "+chrt.getProperties()); + } + } + } + + auth(); + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/77/70327500f7870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/77/70327500f7870014196aa5e86be5823c new file mode 100644 index 0000000..d55d791 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/77/70327500f7870014196aa5e86be5823c @@ -0,0 +1,70 @@ +package com.motioncoding.miband.model; + +import android.os.Parcel; +import android.os.Parcelable; + +public class LeParams implements Parcelable { + public int connIntMin; + public int connIntMax; + public int latency; + public int timeout; + public int connInt; + public int advInt; + + public static LeParams fromByte(byte[] b) { + LeParams params = new LeParams(); + + params.connIntMax = 0xffff & (0xff & b[0] | (0xff & b[1]) << 8); + params.connIntMax = 0xffff & (0xff & b[2] | (0xff & b[3]) << 8); + params.latency = 0xffff & (0xff & b[4] | (0xff & b[5]) << 8); + params.timeout = 0xffff & (0xff & b[6] | (0xff & b[7]) << 8); + params.connInt = 0xffff & (0xff & b[8] | (0xff & b[9]) << 8); + params.advInt = 0xffff & (0xff & b[10] | (0xff & b[11]) << 8); + + params.connIntMin *= 1.25; + params.connIntMax *= 1.25; + params.advInt *= 0.625; + params.timeout *= 10; + + return params; + } + + protected LeParams() {} + + protected LeParams(Parcel in) { + connIntMin = in.readInt(); + connIntMax = in.readInt(); + latency = in.readInt(); + timeout = in.readInt(); + connInt = in.readInt(); + advInt = in.readInt(); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(connIntMin); + dest.writeInt(connIntMax); + dest.writeInt(latency); + dest.writeInt(timeout); + dest.writeInt(connInt); + dest.writeInt(advInt); + } + + @SuppressWarnings("unused") + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + @Override + public LeParams createFromParcel(Parcel in) { + return new LeParams(in); + } + + @Override + public LeParams[] newArray(int size) { + return new LeParams[size]; + } + }; +} \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/78/308299a3e38700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/78/308299a3e38700141885aa2aa9523af4 new file mode 100644 index 0000000..75b24f6 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/78/308299a3e38700141885aa2aa9523af4 @@ -0,0 +1,98 @@ +package com.motioncoding.miband; + +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + private static final UUID UUID_MILI_SERVICE = UUID.fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void auth() { + BluetoothGattService service = mGatt.getService(UUID_MILI_SERVICE); + BluetoothGattCharacteristic chrt = service.getCharacteristic(UUID.fromString("0000ff0f-0000-1000-8000-00805f9b34fb")); + + chrt.setValue(new byte[] {2}); + + mGatt.writeCharacteristic(chrt); + System.out.println("Auth sent"); + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + for (BluetoothGattService srvs : gatt.getServices()) { + System.out.println("Service: "+srvs.getUuid()); + for (BluetoothGattCharacteristic chrt : srvs + .getCharacteristics()) { + System.out.println("Characteristic: "+chrt.getUuid()+" with "+chrt.getProperties()); + } + } + } + + auth(); + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/79/10cae10de18700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/79/10cae10de18700141885aa2aa9523af4 new file mode 100644 index 0000000..c7d2912 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/79/10cae10de18700141885aa2aa9523af4 @@ -0,0 +1,80 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + for (BluetoothGattService service : gatt.getServices()) { + for (BluetoothGattCharacteristic chrt : service + .getCharacteristics()) { + } + } + } + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (status == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/79/e07057f2d88700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/79/e07057f2d88700141885aa2aa9523af4 new file mode 100644 index 0000000..2c10201 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/79/e07057f2d88700141885aa2aa9523af4 @@ -0,0 +1,71 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothAdapter.LeScanCallback; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.os.Bundle; +import android.os.Handler; + +public class MiActivity extends Activity implements LeScanCallback { + + private BluetoothAdapter mBluetoothAdapter; + private boolean mScanning; + private Handler mHandler = new Handler(); + // Stops scanning after 10 seconds. + private static final long SCAN_PERIOD = 10000; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_mi); + mBluetoothAdapter = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)).getAdapter(); + } + + @Override + public void onResume() { + super.onResume(); + scanLeDevice(true); + } + + + + @SuppressWarnings("deprecation") // L Apis are buggy and crap! + private void scanLeDevice(final boolean enable) { + if (enable) { + // Stops scanning after a pre-defined scan period. + mHandler.postDelayed(new Runnable() { + + @Override + public void run() { + mScanning = false; + mBluetoothAdapter.stopLeScan(MiActivity.this); + scanLeDevice(true); + } + }, SCAN_PERIOD); + + mScanning = true; + mBluetoothAdapter.startLeScan(this); + } else { + mScanning = false; + mBluetoothAdapter.stopLeScan(this); + } + } + + @Override + public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { + + if(device != null && device.getName() != null & device.getName().equals("MI")) { + System.out.println(device.getAddress()); + scanLeDevice(false); // we only care about one miband so that's enough + } + } + + @Override + public void onPause() { + super.onPause(); + scanLeDevice(false); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/7a/108362d9e5870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/7a/108362d9e5870014196aa5e86be5823c new file mode 100644 index 0000000..dcfdcdb --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/7a/108362d9e5870014196aa5e86be5823c @@ -0,0 +1,112 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_AUTH = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void auth() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_AUTH); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("Auth sent"); + } + + private void requestSteps() { + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic(UUID_CHAR_REALTIME_STEPS); + mGatt.readCharacteristic(chrt); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + auth(); + requestSteps(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + Log.i(characteristic.getUuid().toString(), Arrays.toString(characteristic.getValue())); + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/7b/0005672cef870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/7b/0005672cef870014196aa5e86be5823c new file mode 100644 index 0000000..980c988 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/7b/0005672cef870014196aa5e86be5823c @@ -0,0 +1,193 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Observable; +import java.util.Observer; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity implements Observer { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_CONTROL_POINT = UUID + .fromString("0000ff05-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + // BLUETOOTH + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + private MiBand mMiBand = new MiBand(); + + // UI + private TextView mTVSteps; + private TextView mTVBatteryLevel; + private ProgressBar mLoading; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.addObserver(this); + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + + mTVSteps = (TextView) findViewById(R.id.text_steps); + mTVBatteryLevel = (TextView) findViewById(R.id.text_battery_level); + mLoading = (ProgressBar) findViewById(R.id.laoding); + + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() + request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + switch (state) { + case 0: + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + break; + case 1: + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + break; + case 2: + mMiBand.setName(new String(b)); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_DEVICE_NAME); + break; + } + } + }; + + @Override + public void update(Observable observable, Object data) { + runOnUiThread(new Runnable() { + + @Override + public void run() { + mLoading.setVisibility(View.GONE); + ((LinearLayout) findViewById(R.id.textHolder)) + .setVisibility(View.GONE); + mTVSteps.setText(mMiBand.mSteps + ""); + if (mMiBand.mBattery != null) + mTVBatteryLevel.setText(mMiBand.mBattery.mBatteryLevel + + "%"); + } + }); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/7c/8020c9c3eb870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/7c/8020c9c3eb870014196aa5e86be5823c new file mode 100644 index 0000000..4c96e54 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/7c/8020c9c3eb870014196aa5e86be5823c @@ -0,0 +1,155 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; + +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_CONTROL_POINT = UUID + .fromString("0000ff05-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + private MiBand mMiBand = new MiBand(); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() + request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + switch (state) { + case 0: + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + break; + case 1: + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_DEVICE_NAME); + break; + } + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/7d/005b9164dc8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/7d/005b9164dc8700141885aa2aa9523af4 new file mode 100644 index 0000000..416f1bf --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/7d/005b9164dc8700141885aa2aa9523af4 @@ -0,0 +1,8 @@ + + + + MiBand + Hello world! + MiBand not found. Is it in range? + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/7d/007705efe9870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/7d/007705efe9870014196aa5e86be5823c new file mode 100644 index 0000000..ce1fdaf --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/7d/007705efe9870014196aa5e86be5823c @@ -0,0 +1,14 @@ +package com.motioncoding.miband.model; + + +public class MiBand { + + public String mBTAddress; + public int mSteps; + public Battery mBattery; + + public void setBattery(Battery battery) { + mBattery = battery; + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/7d/70fdcc1ff6870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/7d/70fdcc1ff6870014196aa5e86be5823c new file mode 100644 index 0000000..030d307 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/7d/70fdcc1ff6870014196aa5e86be5823c @@ -0,0 +1,70 @@ +package com.motioncoding.miband.model; + +import android.os.Parcel; +import android.os.Parcelable; + +public class LeParams implements Parcelable { + public int connIntMin; + public int connIntMax; + public int latency; + public int timeout; + public int connInt; + public int advInt; + + public static LeParams fromByte(byte[] b) { + LeParams params = new LeParams(); + + params.connIntMax = 0xffff & (0xff & b[0] | (0xff & b[1]) << 8); + params.connIntMax = 0xffff & (0xff & b[2] | (0xff & b[3]) << 8); + params.latency = 0xffff & (0xff & b[4] | (0xff & b[5]) << 8); + params.timeout = 0xffff & (0xff & b[6] | (0xff & b[7]) << 8); + params.connInt = 0xffff & (0xff & b[8] | (0xff & b[9]) << 8); + params.advInt = 0xffff & (0xff & b[10] | (0xff & b[11]) << 8); + + params.connIntMin *= 1.25; + params.connIntMax *= 1.25; + params.advInt *= 0.625; + params.timeout *= 10; + + return params; + } + + protected LeParams() {} + + protected LeParams(Parcel in) { + connIntMin = in.readInt(); + connIntMax = in.readInt(); + latency = in.readInt(); + timeout = in.readInt(); + connInt = in.readInt(); + advInt = in.readInt(); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(connIntMin); + dest.writeInt(connIntMax); + dest.writeInt(latency); + dest.writeInt(timeout); + dest.writeInt(connInt); + dest.writeInt(advInt); + } + + @SuppressWarnings("unused") + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + @Override + public LeParams createFromParcel(Parcel in) { + return new LeParams(in); + } + + @Override + public LeParams[] newArray(int size) { + return new LeParams[size]; + } + }; +} \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/7e/406193bdf4870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/7e/406193bdf4870014196aa5e86be5823c new file mode 100644 index 0000000..cacec49 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/7e/406193bdf4870014196aa5e86be5823c @@ -0,0 +1,13 @@ +package com.motioncoding.miband.model; + +public class LeParams { + public int connIntMin, connIntMax, latency, timeout, connInt, advInt; + + public static LeParams fromByte(byte[] b) { + LeParams params = new LeParams(); + + + + return params; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/7e/900bfedde28700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/7e/900bfedde28700141885aa2aa9523af4 new file mode 100644 index 0000000..b302808 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/7e/900bfedde28700141885aa2aa9523af4 @@ -0,0 +1,94 @@ +package com.motioncoding.miband; + +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void auth() { + BluetoothGattService service = mGatt.getService(UUID.fromString("00001800-0000-1000-8000-00805f9b34fb")); + BluetoothGattCharacteristic chrt = service.getCharacteristic(UUID.fromString("0000ff0f-0000-1000-8000-00805f9b34fb")); + mGatt.writeCharacteristic(chrt); +// mGatt.writeCharacteristic(); + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + for (BluetoothGattService srvs : gatt.getServices()) { + System.out.println("Service: "+srvs.getUuid()); + for (BluetoothGattCharacteristic chrt : srvs + .getCharacteristics()) { + System.out.println("Characteristic: "+chrt.getUuid()+" with "+chrt.getProperties()); + } + } + } + + auth(); + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/8/50195647db8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/8/50195647db8700141885aa2aa9523af4 new file mode 100644 index 0000000..f21631c --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/8/50195647db8700141885aa2aa9523af4 @@ -0,0 +1,26 @@ + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/80/20e8cf3ee9870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/80/20e8cf3ee9870014196aa5e86be5823c new file mode 100644 index 0000000..7b09067 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/80/20e8cf3ee9870014196aa5e86be5823c @@ -0,0 +1,151 @@ +package com.motioncoding.miband; + +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.os.Bundle; + +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_AUTH = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + private MiBand mMiBand = new MiBand(); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void auth() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_AUTH); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("Auth sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + auth(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after auth() + request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(characteristic.getValue())); + switch (state) { + case 0: + System.out.println(characteristic.getIntValue(0, 0)); + break; + case 1: + Battery bat = Battery.fromByte(characteristic.getValue()); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_ACTIVITY); + break; + case 3: + request(UUID_CHAR_DEVICE_NAME); + break; + } + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/82/30cbfcb7dc8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/82/30cbfcb7dc8700141885aa2aa9523af4 new file mode 100644 index 0000000..50fe8d0 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/82/30cbfcb7dc8700141885aa2aa9523af4 @@ -0,0 +1,12 @@ + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/83/104252ece28700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/83/104252ece28700141885aa2aa9523af4 new file mode 100644 index 0000000..dac96d9 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/83/104252ece28700141885aa2aa9523af4 @@ -0,0 +1,96 @@ +package com.motioncoding.miband; + +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void auth() { + BluetoothGattService service = mGatt.getService(UUID.fromString("00001800-0000-1000-8000-00805f9b34fb")); + BluetoothGattCharacteristic chrt = service.getCharacteristic(UUID.fromString("0000ff0f-0000-1000-8000-00805f9b34fb")); + + chrt.setValue(new byte[] {2}); + + mGatt.writeCharacteristic(chrt); + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { +// if (status == BluetoothGatt.GATT_SUCCESS) { +// for (BluetoothGattService srvs : gatt.getServices()) { +// System.out.println("Service: "+srvs.getUuid()); +// for (BluetoothGattCharacteristic chrt : srvs +// .getCharacteristics()) { +// System.out.println("Characteristic: "+chrt.getUuid()+" with "+chrt.getProperties()); +// } +// } +// } + + auth(); + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/83/6089b2dbec870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/83/6089b2dbec870014196aa5e86be5823c new file mode 100644 index 0000000..c9a20c3 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/83/6089b2dbec870014196aa5e86be5823c @@ -0,0 +1,25 @@ + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/86/4068d810f6870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/86/4068d810f6870014196aa5e86be5823c new file mode 100644 index 0000000..c002108 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/86/4068d810f6870014196aa5e86be5823c @@ -0,0 +1,96 @@ +package com.motioncoding.miband.model; + +import android.os.Parcel; +import android.os.Parcelable; + +public class LeParams { + public int connIntMin; + public int connIntMax; + public int latency; + public int timeout; + public int connInt; + public int advInt; + + public static LeParams fromByte(byte[] b) { + LeParams params = new LeParams(); + + params.connIntMax = 0xffff & (0xff & b[0] | (0xff & b[1]) << 8); + params.connIntMax = 0xffff & (0xff & b[2] | (0xff & b[3]) << 8); + params.latency = 0xffff & (0xff & b[4] | (0xff & b[5]) << 8); + params.timeout = 0xffff & (0xff & b[6] | (0xff & b[7]) << 8); + params.connInt = 0xffff & (0xff & b[8] | (0xff & b[9]) << 8); + params.advInt = 0xffff & (0xff & b[10] | (0xff & b[11]) << 8); + + params.connIntMin *= 1.25; + params.connIntMax *= 1.25; + params.advInt *= 0.625; + params.timeout *= 10; + + return params; + } +} +package com.motioncoding.miband.model; + +public class LeParams implements Parcelable { + public int connIntMin; + public int connIntMax; + public int latency; + public int timeout; + public int connInt; + public int advInt; + + public static LeParams fromByte(byte[] b) { + LeParams params = new LeParams(); + + params.connIntMax = 0xffff & (0xff & b[0] | (0xff & b[1]) << 8); + params.connIntMax = 0xffff & (0xff & b[2] | (0xff & b[3]) << 8); + params.latency = 0xffff & (0xff & b[4] | (0xff & b[5]) << 8); + params.timeout = 0xffff & (0xff & b[6] | (0xff & b[7]) << 8); + params.connInt = 0xffff & (0xff & b[8] | (0xff & b[9]) << 8); + params.advInt = 0xffff & (0xff & b[10] | (0xff & b[11]) << 8); + + params.connIntMin *= 1.25; + params.connIntMax *= 1.25; + params.advInt *= 0.625; + params.timeout *= 10; + + return params; + } + + protected LeParams(Parcel in) { + connIntMin = in.readInt(); + connIntMax = in.readInt(); + latency = in.readInt(); + timeout = in.readInt(); + connInt = in.readInt(); + advInt = in.readInt(); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(connIntMin); + dest.writeInt(connIntMax); + dest.writeInt(latency); + dest.writeInt(timeout); + dest.writeInt(connInt); + dest.writeInt(advInt); + } + + @SuppressWarnings("unused") + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + @Override + public LeParams createFromParcel(Parcel in) { + return new LeParams(in); + } + + @Override + public LeParams[] newArray(int size) { + return new LeParams[size]; + } + }; +} \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/86/d01d9e4ed08700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/86/d01d9e4ed08700141885aa2aa9523af4 new file mode 100644 index 0000000..439594d --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/86/d01d9e4ed08700141885aa2aa9523af4 @@ -0,0 +1,12 @@ + + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/87/5053714aec870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/87/5053714aec870014196aa5e86be5823c new file mode 100644 index 0000000..0296466 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/87/5053714aec870014196aa5e86be5823c @@ -0,0 +1,55 @@ +package com.motioncoding.miband.model; + +import java.util.Calendar; + +public class Battery { + public int mBatteryLevel; + public int mCycles; + public Calendar mLastCharged; + public Status mStatus; + + public static Battery fromByte(byte[] b) { + Battery battery = new Battery(); + battery.mBatteryLevel = b[0]; + battery.mStatus = Status.fromByte(b[9]); + battery.mLastCharged = Calendar.getInstance(); + + battery.mLastCharged.set(Calendar.YEAR, b[1]+2000); + battery.mLastCharged.set(Calendar.MONTH, b[2]); + battery.mLastCharged.set(Calendar.DATE, b[3]); + + battery.mLastCharged.set(Calendar.HOUR_OF_DAY, b[4]); + battery.mLastCharged.set(Calendar.MINUTE, b[5]); + battery.mLastCharged.set(Calendar.SECOND, b[6]); + + + + battery.mCycles = 0xffff & (0xff & b[7] | (0xff & b[8]) << 8); + return battery; + } + + @Override + public String toString() { + return String.format("Level: %s Cycles: %s State: %s Last Charged: %s", mBatteryLevel, mCycles, mStatus.toString(), mLastCharged.toString()); + } + + static enum Status { + LOW, FULL, CHARGING, NOT_CHARGING; + + public static Status fromByte(byte b) { + switch (b) { + case 1: + return LOW; + case 2: + return CHARGING; + case 3: + return FULL; + case 4: + return NOT_CHARGING; + + default: + return null; + } + } + } +} \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/8b/b066a8b4f5870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/8b/b066a8b4f5870014196aa5e86be5823c new file mode 100644 index 0000000..d385310 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/8b/b066a8b4f5870014196aa5e86be5823c @@ -0,0 +1,207 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Observable; +import java.util.Observer; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.LeParams; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity implements Observer { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_CONTROL_POINT = UUID + .fromString("0000ff05-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_LE_PARAMS = UUID + .fromString("0000ff09-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + // BLUETOOTH + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + private MiBand mMiBand = new MiBand(); + + // UI + private TextView mTVSteps; + private TextView mTVBatteryLevel; + private ProgressBar mLoading; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.addObserver(this); + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + + mTVSteps = (TextView) findViewById(R.id.text_steps); + mTVBatteryLevel = (TextView) findViewById(R.id.text_battery_level); + mLoading = (ProgressBar) findViewById(R.id.laoding); + + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private void setColor(byte r, byte g, byte b) { + BluetoothGattCharacteristic theme = getMiliService() + .getCharacteristic(UUID_CHAR_CONTROL_POINT); + theme.setValue(new byte[] { 14, r, g, b, 0 }); + mGatt.writeCharacteristic(theme); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() +// setColor((byte)127, (byte)0, (byte)0); +// request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + if(characteristic.getUuid().equals(UUID_CHAR_REALTIME_STEPS)) + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + else if(characteristic.getUuid().equals(UUID_CHAR_BATTERY)) { + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + } else if(characteristic.getUuid().equals(UUID_CHAR_DEVICE_NAME)) { + mMiBand.setName(new String(b)); + } else if(characteristic.getUuid().equals(UUID_CHAR_LE_PARAMS)) { + LeParams params = LeParams.fromByte(b); + mMiBand.setLeParams(params); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_DEVICE_NAME); + break; + case 3: + request(UUID_CHAR_LE_PARAMS); + break; + } + } + }; + + @Override + public void update(Observable observable, Object data) { + runOnUiThread(new Runnable() { + + @Override + public void run() { + mLoading.setVisibility(View.GONE); + ((LinearLayout) findViewById(R.id.textHolder)) + .setVisibility(View.VISIBLE); + mTVSteps.setText(mMiBand.mSteps + ""); + if (mMiBand.mBattery != null) + mTVBatteryLevel.setText(mMiBand.mBattery.mBatteryLevel + + "%"); + } + }); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/8b/e090d076e8870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/8b/e090d076e8870014196aa5e86be5823c new file mode 100644 index 0000000..3818315 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/8b/e090d076e8870014196aa5e86be5823c @@ -0,0 +1,12 @@ +package com.motioncoding.miband.model; + +import java.util.Calendar; + +public class MiBand { + + String mBTAddress; + int mSteps; + Battery mBattery; + + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/8b/f07427bfd78700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/8b/f07427bfd78700141885aa2aa9523af4 new file mode 100644 index 0000000..25ac15f --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/8b/f07427bfd78700141885aa2aa9523af4 @@ -0,0 +1,40 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter.LeScanCallback; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.os.Bundle; + +public class MiActivity extends Activity implements LeScanCallback { + + private BluetoothManager bluetoothManager; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_mi); + bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); + } + + @Override + public void onResume() { + super.onResume(); + bluetoothManager.getAdapter().startLeScan(this); + } + + @Override + public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { + if(device != null && device.getName() != null & device.getName().equals("MI")) { + System.out.println(device.getAddress()); + bluetoothManager.getAdapter().stopLeScan(this); + } + } + + @Override + public void onPause() { + super.onPause(); + bluetoothManager.getAdapter().stopLeScan(this); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/9/50b11535d78700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/9/50b11535d78700141885aa2aa9523af4 new file mode 100644 index 0000000..7a8ff49 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/9/50b11535d78700141885aa2aa9523af4 @@ -0,0 +1,28 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothManager; +import android.bluetooth.le.ScanCallback; +import android.content.Context; +import android.os.Bundle; + +public class MiActivity extends Activity { + + private BluetoothManager bluetoothManager; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_mi); + + bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); + + lookForMiBand(); + } + + private void lookForMiBand() { + bluetoothManager.getAdapter().getBluetoothLeScanner() + .startScan(new ScanCallback() { + }); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/92/d0e40a4af6870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/92/d0e40a4af6870014196aa5e86be5823c new file mode 100644 index 0000000..7899f41 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/92/d0e40a4af6870014196aa5e86be5823c @@ -0,0 +1,10 @@ + + + + MiBand + Hello world! + MiBand not found. Is it in range? + MiOverviewActivity + Looking for MiBand + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/95/10e503dce9870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/95/10e503dce9870014196aa5e86be5823c new file mode 100644 index 0000000..787e001 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/95/10e503dce9870014196aa5e86be5823c @@ -0,0 +1,155 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; + +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_AUTH = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + private MiBand mMiBand = new MiBand(); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void auth() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_AUTH); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("Auth sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + auth(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after auth() + request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(characteristic.getValue())); + switch (state) { + case 0: + System.out.println(characteristic.getIntValue(0, 0)); + break; + case 1: + Battery bat = Battery.fromByte(characteristic.getValue()); + System.out.println(); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_ACTIVITY); + break; + case 3: + request(UUID_CHAR_DEVICE_NAME); + break; + } + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/95/50eef3efec870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/95/50eef3efec870014196aa5e86be5823c new file mode 100644 index 0000000..adb0f3e --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/95/50eef3efec870014196aa5e86be5823c @@ -0,0 +1,26 @@ + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/95/e0119313ea870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/95/e0119313ea870014196aa5e86be5823c new file mode 100644 index 0000000..3a4668f --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/95/e0119313ea870014196aa5e86be5823c @@ -0,0 +1,21 @@ +package com.motioncoding.miband.model; + +import java.util.Observable; + + +public class MiBand extends Observable{ + + public String mBTAddress; + public int mSteps; + public Battery mBattery; + + + public void setSteps(int steps) { + mSteps = steps; + } + + public void setBattery(Battery battery) { + mBattery = battery; + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/96/30f593a3e9870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/96/30f593a3e9870014196aa5e86be5823c new file mode 100644 index 0000000..e1ac145 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/96/30f593a3e9870014196aa5e86be5823c @@ -0,0 +1,12 @@ +package com.motioncoding.miband.model; + +import java.util.Calendar; + +public class MiBand { + + public String mBTAddress; + public int mSteps; + public Battery mBattery; + + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/97/90d345a1f6870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/97/90d345a1f6870014196aa5e86be5823c new file mode 100644 index 0000000..a1703d7 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/97/90d345a1f6870014196aa5e86be5823c @@ -0,0 +1,6 @@ + + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/9a/406dce4cd88700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/9a/406dce4cd88700141885aa2aa9523af4 new file mode 100644 index 0000000..ccf79e3 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/9a/406dce4cd88700141885aa2aa9523af4 @@ -0,0 +1,69 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothAdapter.LeScanCallback; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.os.Bundle; +import android.os.Handler; + +public class MiActivity extends Activity implements LeScanCallback { + + private BluetoothAdapter mBluetoothAdapter; + private boolean mScanning; + private Handler mHandler; + // Stops scanning after 10 seconds. + private static final long SCAN_PERIOD = 10000; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_mi); + mBluetoothAdapter = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)).getAdapter(); + } + + @Override + public void onResume() { + super.onResume(); + scanLeDevice(true); + } + + + + @SuppressWarnings("deprecation") // L Apis are buggy and crap! + private void scanLeDevice(final boolean enable) { + if (enable) { + // Stops scanning after a pre-defined scan period. + mHandler.postDelayed(new Runnable() { + + @Override + public void run() { + mScanning = false; + mBluetoothAdapter.stopLeScan(MiActivity.this); + } + }, SCAN_PERIOD); + + mScanning = true; + mBluetoothAdapter.startLeScan(this); + } else { + mScanning = false; + mBluetoothAdapter.stopLeScan(this); + } + } + + @Override + public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { + if(device != null && device.getName() != null & device.getName().equals("MI")) { + System.out.println(device.getAddress()); + scanLeDevice(false); // we only care about one miband so that's enough + } + } + + @Override + public void onPause() { + super.onPause(); + scanLeDevice(false); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/9a/902a44cee28700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/9a/902a44cee28700141885aa2aa9523af4 new file mode 100644 index 0000000..36cfb42 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/9a/902a44cee28700141885aa2aa9523af4 @@ -0,0 +1,82 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + for (BluetoothGattService srvs : gatt.getServices()) { + System.out.println("Service: "+srvs.getUuid()); + for (BluetoothGattCharacteristic chrt : srvs + .getCharacteristics()) { + System.out.println("Characteristic: "+chrt.getUuid()+" with "+chrt.getProperties()); + } + } + } + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/9a/b086a6bce8870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/9a/b086a6bce8870014196aa5e86be5823c new file mode 100644 index 0000000..19b61c1 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/9a/b086a6bce8870014196aa5e86be5823c @@ -0,0 +1,36 @@ +package com.motioncoding.miband.model; + +import java.util.Calendar; + +public class Battery { + public int mBatteryLevel; + public int mCycles; + public Calendar mLastCharged; + + public static Battery fromByte(byte[] b) { + Battery battery = new Battery(); + battery.mBatteryLevel = b[0]; + + return battery; + } + + static enum Status { + LOW, FULL, CHARGING, NOT_CHARGING; + + public static Status fromByte(byte b) { + switch (b) { + case 1: + return LOW; + case 2: + return CHARGING; + case 3: + return FULL; + case 4: + return NOT_CHARGING; + + default: + return null; + } + } + } +} \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/9a/f0e5928ce7870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/9a/f0e5928ce7870014196aa5e86be5823c new file mode 100644 index 0000000..6ebe536 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/9a/f0e5928ce7870014196aa5e86be5823c @@ -0,0 +1,137 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; + +public class MiOverviewActivity extends Activity { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_AUTH = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void auth() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_AUTH); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("Auth sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + auth(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after auth() + request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(characteristic.getValue())); + switch (state) { + case 0: + System.out.println(characteristic.getIntValue(0, 0)); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + } + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/9b/301c16a3f5870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/9b/301c16a3f5870014196aa5e86be5823c new file mode 100644 index 0000000..2aef266 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/9b/301c16a3f5870014196aa5e86be5823c @@ -0,0 +1,207 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Observable; +import java.util.Observer; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.LeParams; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity implements Observer { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_CONTROL_POINT = UUID + .fromString("0000ff05-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_LE_PARAMS = UUID + .fromString("0000ff09-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + // BLUETOOTH + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + private MiBand mMiBand = new MiBand(); + + // UI + private TextView mTVSteps; + private TextView mTVBatteryLevel; + private ProgressBar mLoading; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.addObserver(this); + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + + mTVSteps = (TextView) findViewById(R.id.text_steps); + mTVBatteryLevel = (TextView) findViewById(R.id.text_battery_level); + mLoading = (ProgressBar) findViewById(R.id.laoding); + + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private void setColor(byte r, byte g, byte b) { + BluetoothGattCharacteristic theme = getMiliService() + .getCharacteristic(UUID_CHAR_CONTROL_POINT); + theme.setValue(new byte[] { 14, r, g, b, 0 }); + mGatt.writeCharacteristic(theme); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() +// setColor((byte)127, (byte)0, (byte)0); +// request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + if(characteristic.getUuid().equals(UUID_CHAR_REALTIME_STEPS)) + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + else if(characteristic.getUuid().equals(UUID_CHAR_BATTERY)) { + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + } else if(characteristic.getUuid().equals(UUID_CHAR_DEVICE_NAME)) { + mMiBand.setName(new String(b)); + } else if(characteristic.getUuid().equals(UUID_CHAR_)) { + LeParams params = LeParams.fromByte(b); + mMiBand.setLeParams(params); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_DEVICE_NAME); + break; + case 3: + request(UUID_LE_PARAMS); + break; + } + } + }; + + @Override + public void update(Observable observable, Object data) { + runOnUiThread(new Runnable() { + + @Override + public void run() { + mLoading.setVisibility(View.GONE); + ((LinearLayout) findViewById(R.id.textHolder)) + .setVisibility(View.VISIBLE); + mTVSteps.setText(mMiBand.mSteps + ""); + if (mMiBand.mBattery != null) + mTVBatteryLevel.setText(mMiBand.mBattery.mBatteryLevel + + "%"); + } + }); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/9b/80ddf6d3e18700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/9b/80ddf6d3e18700141885aa2aa9523af4 new file mode 100644 index 0000000..05374fa --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/9b/80ddf6d3e18700141885aa2aa9523af4 @@ -0,0 +1,82 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + for (BluetoothGattService srvs : gatt.getServices()) { + System.out.println("Service: "+srvs.getUuid()); + for (BluetoothGattCharacteristic chrt : srvs + .getCharacteristics()) { + System.out.println("Characteristic: "+chrt.getUuid()+" rwx: "+chrt.getProperties()); + } + } + } + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/9e/1032dea1ed870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/9e/1032dea1ed870014196aa5e86be5823c new file mode 100644 index 0000000..fa7aa41 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/9e/1032dea1ed870014196aa5e86be5823c @@ -0,0 +1,167 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Observable; +import java.util.Observer; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; + +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity implements Observer { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_CONTROL_POINT = UUID + .fromString("0000ff05-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + private MiBand mMiBand = new MiBand(); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.addObserver(this); + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() + request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + switch (state) { + case 0: + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + break; + case 1: + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + break; + case 2: + mMiBand.setName(new String(b)); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_DEVICE_NAME); + break; + } + } + }; + + @Override + public void update(Observable observable, Object data) { + // TODO Auto-generated method stub + + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/9e/9062150ef4870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/9e/9062150ef4870014196aa5e86be5823c new file mode 100644 index 0000000..0f8ffc9 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/9e/9062150ef4870014196aa5e86be5823c @@ -0,0 +1,5 @@ +package com.motioncoding.miband.model; + +public class LeParams { + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a/b0ebe737f9870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/a/b0ebe737f9870014196aa5e86be5823c new file mode 100644 index 0000000..eb50bec --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a/b0ebe737f9870014196aa5e86be5823c @@ -0,0 +1,309 @@ +package com.motioncoding.miband.view; + +import android.R; +import android.app.Dialog; +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.LinearGradient; +import android.graphics.Paint; +import android.graphics.Shader; +import android.os.Bundle; +import android.view.MotionEvent; +import android.view.View; + +public class ColorPickerDialog extends Dialog { + + public interface OnColorChangedListener { + void colorChanged(String key, int color); + } + + private OnColorChangedListener mListener; + private int mInitialColor, mDefaultColor; + private String mKey; + + private static class ColorPickerView extends View { + private Paint mPaint; + private float mCurrentHue = 0; + private int mCurrentX = 0, mCurrentY = 0; + private int mCurrentColor, mDefaultColor; + private final int[] mHueBarColors = new int[258]; + private int[] mMainColors = new int[65536]; + private OnColorChangedListener mListener; + + ColorPickerView(Context c, OnColorChangedListener l, int color, + int defaultColor) { + super(c); + mListener = l; + mDefaultColor = defaultColor; + + // Get the current hue from the current color and update the main + // color field + float[] hsv = new float[3]; + Color.colorToHSV(color, hsv); + mCurrentHue = hsv[0]; + updateMainColors(); + + mCurrentColor = color; + + // Initialize the colors of the hue slider bar + int index = 0; + for (float i = 0; i < 256; i += 256 / 42) // Red (#f00) to pink + // (#f0f) + { + mHueBarColors[index] = Color.rgb(255, 0, (int) i); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) // Pink (#f0f) to blue + // (#00f) + { + mHueBarColors[index] = Color.rgb(255 - (int) i, 0, 255); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) // Blue (#00f) to light + // blue (#0ff) + { + mHueBarColors[index] = Color.rgb(0, (int) i, 255); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) // Light blue (#0ff) to + // green (#0f0) + { + mHueBarColors[index] = Color.rgb(0, 255, 255 - (int) i); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) // Green (#0f0) to yellow + // (#ff0) + { + mHueBarColors[index] = Color.rgb((int) i, 255, 0); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) // Yellow (#ff0) to red + // (#f00) + { + mHueBarColors[index] = Color.rgb(255, 255 - (int) i, 0); + index++; + } + + // Initializes the Paint that will draw the View + mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + mPaint.setTextAlign(Paint.Align.CENTER); + mPaint.setTextSize(12); + } + + // Get the current selected color from the hue bar + private int getCurrentMainColor() { + int translatedHue = 255 - (int) (mCurrentHue * 255 / 360); + int index = 0; + for (float i = 0; i < 256; i += 256 / 42) { + if (index == translatedHue) + return Color.rgb(255, 0, (int) i); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) { + if (index == translatedHue) + return Color.rgb(255 - (int) i, 0, 255); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) { + if (index == translatedHue) + return Color.rgb(0, (int) i, 255); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) { + if (index == translatedHue) + return Color.rgb(0, 255, 255 - (int) i); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) { + if (index == translatedHue) + return Color.rgb((int) i, 255, 0); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) { + if (index == translatedHue) + return Color.rgb(255, 255 - (int) i, 0); + index++; + } + return Color.RED; + } + + // Update the main field colors depending on the current selected hue + private void updateMainColors() { + int mainColor = getCurrentMainColor(); + int index = 0; + int[] topColors = new int[256]; + for (int y = 0; y < 256; y++) { + for (int x = 0; x < 256; x++) { + if (y == 0) { + mMainColors[index] = Color.rgb( + 255 - (255 - Color.red(mainColor)) * x / 255, + 255 - (255 - Color.green(mainColor)) * x / 255, + 255 - (255 - Color.blue(mainColor)) * x / 255); + topColors[x] = mMainColors[index]; + } else + mMainColors[index] = Color.rgb( + (255 - y) * Color.red(topColors[x]) / 255, + (255 - y) * Color.green(topColors[x]) / 255, + (255 - y) * Color.blue(topColors[x]) / 255); + index++; + } + } + } + + @Override + protected void onDraw(Canvas canvas) { + int translatedHue = 255 - (int) (mCurrentHue * 255 / 360); + // Display all the colors of the hue bar with lines + for (int x = 0; x < 256; x++) { + // If this is not the current selected hue, display the actual + // color + if (translatedHue != x) { + mPaint.setColor(mHueBarColors[x]); + mPaint.setStrokeWidth(1); + } else // else display a slightly larger black line + { + mPaint.setColor(Color.BLACK); + mPaint.setStrokeWidth(3); + } + canvas.drawLine(x + 10, 0, x + 10, 40, mPaint); + // canvas.drawLine(0, x+10, 40, x+10, mPaint); + } + + // Display the main field colors using LinearGradient + for (int x = 0; x < 256; x++) { + int[] colors = new int[2]; + colors[0] = mMainColors[x]; + colors[1] = Color.BLACK; + Shader shader = new LinearGradient(0, 50, 0, 306, colors, null, + Shader.TileMode.REPEAT); + mPaint.setShader(shader); + canvas.drawLine(x + 10, 50, x + 10, 306, mPaint); + } + mPaint.setShader(null); + + // Display the circle around the currently selected color in the + // main field + if (mCurrentX != 0 && mCurrentY != 0) { + mPaint.setStyle(Paint.Style.STROKE); + mPaint.setColor(Color.BLACK); + canvas.drawCircle(mCurrentX, mCurrentY, 10, mPaint); + } + + // Draw a 'button' with the currently selected color + mPaint.setStyle(Paint.Style.FILL); + mPaint.setColor(mCurrentColor); + canvas.drawRect(10, 316, 138, 356, mPaint); + + // Set the text color according to the brightness of the color + if (Color.red(mCurrentColor) + Color.green(mCurrentColor) + + Color.blue(mCurrentColor) < 384) + mPaint.setColor(Color.WHITE); + else + mPaint.setColor(Color.BLACK); + canvas.drawText( + getResources() + .getString(R.string.settings_bg_color_confirm), 74, + 340, mPaint); + + // Draw a 'button' with the default color + mPaint.setStyle(Paint.Style.FILL); + mPaint.setColor(mDefaultColor); + canvas.drawRect(138, 316, 266, 356, mPaint); + + // Set the text color according to the brightness of the color + if (Color.red(mDefaultColor) + Color.green(mDefaultColor) + + Color.blue(mDefaultColor) < 384) + mPaint.setColor(Color.WHITE); + else + mPaint.setColor(Color.BLACK); + canvas.drawText( + getResources().getString( + R.string.settings_default_color_confirm), 202, 340, + mPaint); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + setMeasuredDimension(276, 366); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + if (event.getAction() != MotionEvent.ACTION_DOWN) + return true; + float x = event.getX(); + float y = event.getY(); + + // If the touch event is located in the hue bar + if (x > 10 && x < 266 && y > 0 && y < 40) { + // Update the main field colors + mCurrentHue = (255 - x) * 360 / 255; + updateMainColors(); + + // Update the current selected color + int transX = mCurrentX - 10; + int transY = mCurrentY - 60; + int index = 256 * (transY - 1) + transX; + if (index > 0 && index < mMainColors.length) + mCurrentColor = mMainColors[256 * (transY - 1) + transX]; + + // Force the redraw of the dialog + invalidate(); + } + + // If the touch event is located in the main field + if (x > 10 && x < 266 && y > 50 && y < 306) { + mCurrentX = (int) x; + mCurrentY = (int) y; + int transX = mCurrentX - 10; + int transY = mCurrentY - 60; + int index = 256 * (transY - 1) + transX; + if (index > 0 && index < mMainColors.length) { + // Update the current color + mCurrentColor = mMainColors[index]; + // Force the redraw of the dialog + invalidate(); + } + } + + // If the touch event is located in the left button, notify the + // listener with the current color + if (x > 10 && x < 138 && y > 316 && y < 356) + mListener.colorChanged("", mCurrentColor); + + // If the touch event is located in the right button, notify the + // listener with the default color + if (x > 138 && x < 266 && y > 316 && y < 356) + mListener.colorChanged("", mDefaultColor); + + return true; + } + } + + public ColorPickerDialog(Context context, OnColorChangedListener listener, + String key, int initialColor, int defaultColor) { + super(context); + + mListener = listener; + mKey = key; + mInitialColor = initialColor; + mDefaultColor = defaultColor; + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + OnColorChangedListener l = new OnColorChangedListener() { + public void colorChanged(String key, int color) { + mListener.colorChanged(mKey, color); + dismiss(); + } + }; + + setContentView(new ColorPickerView(getContext(), l, mInitialColor, + mDefaultColor)); + setTitle("Set LED Color"); + + } +} \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a1/9038e59cf6870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/a1/9038e59cf6870014196aa5e86be5823c new file mode 100644 index 0000000..82186b3 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a1/9038e59cf6870014196aa5e86be5823c @@ -0,0 +1,5 @@ + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a2/004604ade08700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/a2/004604ade08700141885aa2aa9523af4 new file mode 100644 index 0000000..a2874c3 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a2/004604ade08700141885aa2aa9523af4 @@ -0,0 +1,50 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a3/c07968d6e18700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/a3/c07968d6e18700141885aa2aa9523af4 new file mode 100644 index 0000000..af98c63 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a3/c07968d6e18700141885aa2aa9523af4 @@ -0,0 +1,82 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + for (BluetoothGattService srvs : gatt.getServices()) { + System.out.println("Service: "+srvs.getUuid()); + for (BluetoothGattCharacteristic chrt : srvs + .getCharacteristics()) { + System.out.println("Characteristic: "+chrt.getUuid()+" with"+chrt.getProperties()); + } + } + } + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a4/10c3906eec870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/a4/10c3906eec870014196aa5e86be5823c new file mode 100644 index 0000000..9eccc8b --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a4/10c3906eec870014196aa5e86be5823c @@ -0,0 +1,55 @@ +package com.motioncoding.miband.model; + +import java.util.Calendar; + +public class Battery { + public int mBatteryLevel; + public int mCycles; + public Calendar mLastCharged; + public Status mStatus; + + public static Battery fromByte(byte[] b) { + Battery battery = new Battery(); + battery.mBatteryLevel = b[0]; + battery.mStatus = Status.fromByte(b[9]); + battery.mLastCharged = Calendar.getInstance(); + + battery.mLastCharged.set(Calendar.YEAR, b[1]+2000); + battery.mLastCharged.set(Calendar.MONTH, b[2]); + battery.mLastCharged.set(Calendar.DATE, b[3]); + + battery.mLastCharged.set(Calendar.HOUR_OF_DAY, b[4]); + battery.mLastCharged.set(Calendar.MINUTE, b[5]); + battery.mLastCharged.set(Calendar.SECOND, b[6]); + + + + battery.mCycles = 0xffff & (0xff & b[7] | (0xff & b[8]) << 8); + return battery; + } + + @Override + public String toString() { + return String.format("Level: %s% Cycles: %s State: %s Last Charged: %s", mBatteryLevel, mCycles, mStatus.toString(), mLastCharged.toString()); + } + + static enum Status { + LOW, FULL, CHARGING, NOT_CHARGING; + + public static Status fromByte(byte b) { + switch (b) { + case 1: + return LOW; + case 2: + return CHARGING; + case 3: + return FULL; + case 4: + return NOT_CHARGING; + + default: + return null; + } + } + } +} \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a4/9011961af4870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/a4/9011961af4870014196aa5e86be5823c new file mode 100644 index 0000000..14f3d2f --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a4/9011961af4870014196aa5e86be5823c @@ -0,0 +1,38 @@ +package com.motioncoding.miband.model; + +import java.util.Observable; + +import com.motioncoding.debugging.L; + + +public class MiBand extends Observable { + + public String mBTAddress; + public int mSteps; + public String mName; + public Battery mBattery; + + + + public void setName(String name) { + mName = name; + L.i("setting "+name+" as BLE name"); + setChanged(); + notifyObservers(); + } + + public void setSteps(int steps) { + mSteps = steps; + L.i("setting "+steps+" steps"); + setChanged(); + notifyObservers(); + } + + public void setBattery(Battery battery) { + mBattery = battery; + L.i(battery.toString()); + setChanged(); + notifyObservers(); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a5/504a2a1ced870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/a5/504a2a1ced870014196aa5e86be5823c new file mode 100644 index 0000000..433d6c2 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a5/504a2a1ced870014196aa5e86be5823c @@ -0,0 +1,36 @@ + + + + + + + + + \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a6/c0c6a60eec870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/a6/c0c6a60eec870014196aa5e86be5823c new file mode 100644 index 0000000..f618c1b --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a6/c0c6a60eec870014196aa5e86be5823c @@ -0,0 +1,50 @@ +package com.motioncoding.miband.model; + +import java.util.Calendar; + +public class Battery { + public int mBatteryLevel; + public int mCycles; + public Calendar mLastCharged; + public Status mStatus; + + public static Battery fromByte(byte[] b) { + Battery battery = new Battery(); + battery.mBatteryLevel = b[0]; + battery.mStatus = Status.fromByte(b[9]); + battery.mLastCharged = Calendar.getInstance(); + + battery.mLastCharged.set(Calendar.YEAR, b[1]+2000); + battery.mLastCharged.set(Calendar.MONTH, b[2]); + battery.mLastCharged.set(Calendar.DATE, b[3]); + + battery.mLastCharged.set(Calendar.HOUR_OF_DAY, b[4]); + battery.mLastCharged.set(Calendar.MINUTE, b[5]); + battery.mLastCharged.set(Calendar.SECOND, b[6]); + + + + battery.mCycles = 0xffff & (0xff & b[7] | (0xff & b[8]) << 8); + return battery; + } + + static enum Status { + LOW, FULL, CHARGING, NOT_CHARGING; + + public static Status fromByte(byte b) { + switch (b) { + case 1: + return LOW; + case 2: + return CHARGING; + case 3: + return FULL; + case 4: + return NOT_CHARGING; + + default: + return null; + } + } + } +} \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a6/f0cb20ddd78700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/a6/f0cb20ddd78700141885aa2aa9523af4 new file mode 100644 index 0000000..67aa6fa --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a6/f0cb20ddd78700141885aa2aa9523af4 @@ -0,0 +1,69 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothAdapter.LeScanCallback; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.os.Bundle; +import android.os.Handler; + +public class MiActivity extends Activity implements LeScanCallback { + + private BluetoothManager bluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private boolean mScanning; + private Handler mHandler; + // Stops scanning after 10 seconds. + private static final long SCAN_PERIOD = 10000; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_mi); + bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); + } + + @Override + public void onResume() { + super.onResume(); + scanLeDevice(true); + } + + + + + private void scanLeDevice(final boolean enable) { + if (enable) { + // Stops scanning after a pre-defined scan period. + mHandler.postDelayed(new Runnable() { + @Override + public void run() { + mScanning = false; + mBluetoothAdapter.stopLeScan(MiActivity.this); + } + }, SCAN_PERIOD); + + mScanning = true; + mBluetoothAdapter.startLeScan(this); + } else { + mScanning = false; + mBluetoothAdapter.stopLeScan(this); + } + } + + @Override + public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { + if(device != null && device.getName() != null & device.getName().equals("MI")) { + System.out.println(device.getAddress()); + scanLeDevice(false); + } + } + + @Override + public void onPause() { + super.onPause(); + scanLeDevice(false); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/a7/00cafe74db8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/a7/00cafe74db8700141885aa2aa9523af4 new file mode 100644 index 0000000..09a36ce --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/a7/00cafe74db8700141885aa2aa9523af4 @@ -0,0 +1,25 @@ + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ab/e06cb73de18700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/ab/e06cb73de18700141885aa2aa9523af4 new file mode 100644 index 0000000..1833528 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ab/e06cb73de18700141885aa2aa9523af4 @@ -0,0 +1,80 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + for (BluetoothGattService srvs : gatt.getServices()) { + for (BluetoothGattCharacteristic chrt : service + .getCharacteristics()) { + } + } + } + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (status == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ac/c0c1f7d7e08700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/ac/c0c1f7d7e08700141885aa2aa9523af4 new file mode 100644 index 0000000..fc11a35 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ac/c0c1f7d7e08700141885aa2aa9523af4 @@ -0,0 +1,71 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + mGatt.discoverServices(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + } + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + } + + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ad/500115f0e08700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/ad/500115f0e08700141885aa2aa9523af4 new file mode 100644 index 0000000..e2f79c5 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ad/500115f0e08700141885aa2aa9523af4 @@ -0,0 +1,74 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + } + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if(status == BluetoothProfile.STATE_CONNECTED) { + mGatt.discoverServices(); + } + } + + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ae/10e22875ed870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/ae/10e22875ed870014196aa5e86be5823c new file mode 100644 index 0000000..1e58e4b --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ae/10e22875ed870014196aa5e86be5823c @@ -0,0 +1,35 @@ +package com.motioncoding.miband.model; + +import java.util.Observable; + +import com.motioncoding.debugging.L; + + +public class MiBand extends Observable { + + public String mBTAddress; + public int mSteps; + public String mName; + public Battery mBattery; + + + + public void setName(String name) { + mName = name; + L.i("setting "+name+" as BLE name"); + notifyObservers(); + } + + public void setSteps(int steps) { + mSteps = steps; + L.i("setting "+steps+" steps"); + notifyObservers(); + } + + public void setBattery(Battery battery) { + mBattery = battery; + L.i(battery.toString()); + notifyObservers(); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ae/e0ff8bd9ec870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/ae/e0ff8bd9ec870014196aa5e86be5823c new file mode 100644 index 0000000..7dae85c --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ae/e0ff8bd9ec870014196aa5e86be5823c @@ -0,0 +1,25 @@ + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ae/f046801df9870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/ae/f046801df9870014196aa5e86be5823c new file mode 100644 index 0000000..287607e --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ae/f046801df9870014196aa5e86be5823c @@ -0,0 +1,5 @@ +package com.motioncoding.miband.view; + +public class ColorPickerDialog { + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/af/90751529da8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/af/90751529da8700141885aa2aa9523af4 new file mode 100644 index 0000000..4460dcf --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/af/90751529da8700141885aa2aa9523af4 @@ -0,0 +1,11 @@ + + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b/40108f54e5870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/b/40108f54e5870014196aa5e86be5823c new file mode 100644 index 0000000..5c8b2e9 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b/40108f54e5870014196aa5e86be5823c @@ -0,0 +1,113 @@ +package com.motioncoding.miband; + +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_AUTH = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void auth() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_AUTH); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("Auth sent"); + } + + private BluetoothGattCharacteristic getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + for (BluetoothGattService srvs : gatt.getServices()) { + System.out.println("Service: " + srvs.getUuid()); + for (BluetoothGattCharacteristic chrt : srvs + .getCharacteristics()) { + System.out.println("Characteristic: " + chrt.getUuid() + + " with " + chrt.getProperties()); + } + } + } + + auth(); + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b2/504bc6c0ec870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/b2/504bc6c0ec870014196aa5e86be5823c new file mode 100644 index 0000000..01d70ed --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b2/504bc6c0ec870014196aa5e86be5823c @@ -0,0 +1,23 @@ + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b3/409e3627ec870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/b3/409e3627ec870014196aa5e86be5823c new file mode 100644 index 0000000..0d4f2a9 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b3/409e3627ec870014196aa5e86be5823c @@ -0,0 +1,30 @@ +package com.motioncoding.miband.model; + +import java.util.Observable; + + +public class MiBand extends Observable { + + public String mBTAddress; + public int mSteps; + public String mName; + public Battery mBattery; + + + + public void setName(String name) { + mName = name; + notifyObservers(); + } + + public void setSteps(int steps) { + mSteps = steps; + notifyObservers(); + } + + public void setBattery(Battery battery) { + mBattery = battery; + notifyObservers(); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b3/c08db071f9870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/b3/c08db071f9870014196aa5e86be5823c new file mode 100644 index 0000000..4c5cfe6 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b3/c08db071f9870014196aa5e86be5823c @@ -0,0 +1,33 @@ +package com.motioncoding.miband; + +import android.app.ListActivity; +import android.os.Bundle; +import android.widget.ArrayAdapter; + +import com.motioncoding.miband.model.LeParams; + +public class MiLeParamsActivity extends ListActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + + LeParams params = (LeParams) getIntent().getParcelableExtra("params"); + + String[] values = new String[6]; + + values[0] = String.format("Connection Intervall\n%s ms", params.connInt); + values[1] = String.format("Connection Intervall Min\n%s ms", params.connIntMin); + values[2] = String.format("Connection Intervall Max\n %s ms", params.connIntMax); + + values[3] = String.format("Advertising Intervall\n%s ms", params.advInt); + values[4] = String.format("Latency\n%s ms", params.latency); + values[5] = String.format("Timeout\n%s ms", params.timeout); + + + ArrayAdapter adapter = new ArrayAdapter(this, + android.R.layout.simple_list_item_1, values); + this.setListAdapter(adapter); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b6/60d5d97aee870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/b6/60d5d97aee870014196aa5e86be5823c new file mode 100644 index 0000000..6ec6d98 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b6/60d5d97aee870014196aa5e86be5823c @@ -0,0 +1,35 @@ + + + + + + + + + \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b7/30f19140ee870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/b7/30f19140ee870014196aa5e86be5823c new file mode 100644 index 0000000..8bc4cc1 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b7/30f19140ee870014196aa5e86be5823c @@ -0,0 +1,188 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Observable; +import java.util.Observer; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.ProgressBar; +import android.widget.Spinner; +import android.widget.TextView; + +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity implements Observer { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_CONTROL_POINT = UUID + .fromString("0000ff05-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + //BLUETOOTH + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + + private MiBand mMiBand = new MiBand(); + + //UI + private TextView mTVSteps; + private TextView mTVBatteryLevel; + private ProgressBar mLoading; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.addObserver(this); + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + + mTVSteps = (TextView) findViewById(R.id.text_steps); + mLoading = (ProgressBar) findViewById(R.id.laoding); + + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() + request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + switch (state) { + case 0: + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + break; + case 1: + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + break; + case 2: + mMiBand.setName(new String(b)); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_DEVICE_NAME); + break; + } + } + }; + + @Override + public void update(Observable observable, Object data) { + runOnUiThread(new Runnable() { + + @Override + public void run() { + mLoading.setVisibility(View.GONE); + mTVSteps.setText(mMiBand.mSteps); + } + }); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b7/40aac0d4ee870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/b7/40aac0d4ee870014196aa5e86be5823c new file mode 100644 index 0000000..a39fbcc --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b7/40aac0d4ee870014196aa5e86be5823c @@ -0,0 +1,188 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Observable; +import java.util.Observer; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.ProgressBar; +import android.widget.Spinner; +import android.widget.TextView; + +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity implements Observer { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_CONTROL_POINT = UUID + .fromString("0000ff05-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + //BLUETOOTH + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + + private MiBand mMiBand = new MiBand(); + + //UI + private TextView mTVSteps; + private TextView mTVBatteryLevel; + private ProgressBar mLoading; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.addObserver(this); + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + + mTVSteps = (TextView) findViewById(R.id.text_steps); + mLoading = (ProgressBar) findViewById(R.id.laoding); + + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() + request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + switch (state) { + case 0: + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + break; + case 1: + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + break; + case 2: + mMiBand.setName(new String(b)); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_DEVICE_NAME); + break; + } + } + }; + + @Override + public void update(Observable observable, Object data) { + runOnUiThread(new Runnable() { + + @Override + public void run() { + mLoading.setVisibility(View.GONE); + mTVSteps.setText(mMiBand.mSteps+""); + } + }); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b8/a06f609cdf8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/b8/a06f609cdf8700141885aa2aa9523af4 new file mode 100644 index 0000000..7f6f76d --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b8/a06f609cdf8700141885aa2aa9523af4 @@ -0,0 +1,43 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + + } + + + @Override + public void onResume() { + super.onResume(); + + } + + @Override + public void onPause() { + super.onPause(); + } + + + + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b8/d0769f1bea870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/b8/d0769f1bea870014196aa5e86be5823c new file mode 100644 index 0000000..037affd --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b8/d0769f1bea870014196aa5e86be5823c @@ -0,0 +1,23 @@ +package com.motioncoding.miband.model; + +import java.util.Observable; + + +public class MiBand extends Observable{ + + public String mBTAddress; + public int mSteps; + public Battery mBattery; + + + public void setSteps(int steps) { + mSteps = steps; + notifyObservers(); + } + + public void setBattery(Battery battery) { + mBattery = battery; + notifyObservers(); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b9/207b4d2df4870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/b9/207b4d2df4870014196aa5e86be5823c new file mode 100644 index 0000000..5b9caa3 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b9/207b4d2df4870014196aa5e86be5823c @@ -0,0 +1,204 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Observable; +import java.util.Observer; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity implements Observer { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_CONTROL_POINT = UUID + .fromString("0000ff05-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + // BLUETOOTH + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + private MiBand mMiBand = new MiBand(); + + // UI + private TextView mTVSteps; + private TextView mTVBatteryLevel; + private ProgressBar mLoading; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.addObserver(this); + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + + mTVSteps = (TextView) findViewById(R.id.text_steps); + mTVBatteryLevel = (TextView) findViewById(R.id.text_battery_level); + mLoading = (ProgressBar) findViewById(R.id.laoding); + + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private void setColor(byte r, byte g, byte b) { + BluetoothGattCharacteristic theme = getMiliService() + .getCharacteristic(UUID_CHAR_CONTROL_POINT); + theme.setValue(new byte[] { 14, r, g, b, 0 }); + mGatt.writeCharacteristic(theme); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() +// setColor((byte)127, (byte)0, (byte)0); +// request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + switch (state) { + case 0: + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + break; + case 1: + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + break; + case 2: + mMiBand.setName(new String(b)); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_DEVICE_NAME); + break; + case 3: + + break; + } + } + }; + + @Override + public void update(Observable observable, Object data) { + runOnUiThread(new Runnable() { + + @Override + public void run() { + mLoading.setVisibility(View.GONE); + ((LinearLayout) findViewById(R.id.textHolder)) + .setVisibility(View.VISIBLE); + mTVSteps.setText(mMiBand.mSteps + ""); + if (mMiBand.mBattery != null) + mTVBatteryLevel.setText(mMiBand.mBattery.mBatteryLevel + + "%"); + } + }); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/b9/d09dfc5adb8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/b9/d09dfc5adb8700141885aa2aa9523af4 new file mode 100644 index 0000000..ae18b77 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/b9/d09dfc5adb8700141885aa2aa9523af4 @@ -0,0 +1,27 @@ + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ba/a0036100f6870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/ba/a0036100f6870014196aa5e86be5823c new file mode 100644 index 0000000..37dcdc7 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ba/a0036100f6870014196aa5e86be5823c @@ -0,0 +1,23 @@ +package com.motioncoding.miband.model; + +public class LeParams { + public int connIntMin, connIntMax, latency, timeout, connInt, advInt; + + public static LeParams fromByte(byte[] b) { + LeParams params = new LeParams(); + + params.connIntMax = 0xffff & (0xff & b[0] | (0xff & b[1]) << 8); + params.connIntMax = 0xffff & (0xff & b[2] | (0xff & b[3]) << 8); + params.latency = 0xffff & (0xff & b[4] | (0xff & b[5]) << 8); + params.timeout = 0xffff & (0xff & b[6] | (0xff & b[7]) << 8); + params.connInt = 0xffff & (0xff & b[8] | (0xff & b[9]) << 8); + params.advInt = 0xffff & (0xff & b[10] | (0xff & b[11]) << 8); + + params.connIntMin *= 1.25; + params.connIntMax *= 1.25; + params.advInt *= 0.625; + params.timeout *= 10; + + return params; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/bb/80158594ce8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/bb/80158594ce8700141885aa2aa9523af4 new file mode 100644 index 0000000..91e3772 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/bb/80158594ce8700141885aa2aa9523af4 @@ -0,0 +1,5 @@ + + + MiBand + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/bc/e0f1b249d78700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/bc/e0f1b249d78700141885aa2aa9523af4 new file mode 100644 index 0000000..e066711 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/bc/e0f1b249d78700141885aa2aa9523af4 @@ -0,0 +1,35 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter.LeScanCallback; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.os.Bundle; + +public class MiActivity extends Activity implements LeScanCallback { + + private BluetoothManager bluetoothManager; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_mi); + + bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); + + lookForMiBand(); + } + + private void lookForMiBand() { + bluetoothManager.getAdapter().startLeScan(this); + } + + @Override + public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { + if(device != null && device.getName() != null & device.getName().equals("MI")) { + System.out.println(device.getAddress()); + } + bluetoothManager.getAdapter().stopLeScan(this); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/bc/f0b45cafe08700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/bc/f0b45cafe08700141885aa2aa9523af4 new file mode 100644 index 0000000..45cfbe1 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/bc/f0b45cafe08700141885aa2aa9523af4 @@ -0,0 +1,71 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + mGatt.discoverServices(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + } + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + } + + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/be/60a5eb7ef4870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/be/60a5eb7ef4870014196aa5e86be5823c new file mode 100644 index 0000000..2c242e9 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/be/60a5eb7ef4870014196aa5e86be5823c @@ -0,0 +1,5 @@ +package com.motioncoding.miband.model; + +public class LeParams { + public int connIntMin, connIntMax, latency, timeout, connInt, advInt; +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/c0/20425253f3870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/c0/20425253f3870014196aa5e86be5823c new file mode 100644 index 0000000..bdf3967 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/c0/20425253f3870014196aa5e86be5823c @@ -0,0 +1,199 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Observable; +import java.util.Observer; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity implements Observer { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_CONTROL_POINT = UUID + .fromString("0000ff05-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + // BLUETOOTH + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + private MiBand mMiBand = new MiBand(); + + // UI + private TextView mTVSteps; + private TextView mTVBatteryLevel; + private ProgressBar mLoading; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.addObserver(this); + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + + mTVSteps = (TextView) findViewById(R.id.text_steps); + mTVBatteryLevel = (TextView) findViewById(R.id.text_battery_level); + mLoading = (ProgressBar) findViewById(R.id.laoding); + + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() + request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + switch (state) { + case 0: + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + break; + case 1: + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + break; + case 2: + mMiBand.setName(new String(b)); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_DEVICE_NAME); + break; + case 3: + BluetoothGattCharacteristic theme = getMiliService() + .getCharacteristic(UUID_CHAR_CONTROL_POINT); + theme.setValue(new byte[] { 14, 127, 0, 127, 0 }); + gatt.writeCharacteristic(theme); + break; + } + } + }; + + @Override + public void update(Observable observable, Object data) { + runOnUiThread(new Runnable() { + + @Override + public void run() { + mLoading.setVisibility(View.GONE); + ((LinearLayout) findViewById(R.id.textHolder)) + .setVisibility(View.VISIBLE); + mTVSteps.setText(mMiBand.mSteps + ""); + if (mMiBand.mBattery != null) + mTVBatteryLevel.setText(mMiBand.mBattery.mBatteryLevel + + "%"); + } + }); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/c1/f0a757efe4870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/c1/f0a757efe4870014196aa5e86be5823c new file mode 100644 index 0000000..6b5da00 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/c1/f0a757efe4870014196aa5e86be5823c @@ -0,0 +1,101 @@ +package com.motioncoding.miband; + +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + private static final UUID UUID_MILI_SERVICE = UUID.fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_AUTH =UUID.fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS=UUID.fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY =UUID.fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void auth() { + BluetoothGattService service = mGatt.getService(UUID_MILI_SERVICE); + BluetoothGattCharacteristic chrt = service.getCharacteristic(UUID_CHAR_AUTH); + + chrt.setValue(new byte[] {2}); + + mGatt.writeCharacteristic(chrt); + System.out.println("Auth sent"); + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + for (BluetoothGattService srvs : gatt.getServices()) { + System.out.println("Service: "+srvs.getUuid()); + for (BluetoothGattCharacteristic chrt : srvs + .getCharacteristics()) { + System.out.println("Characteristic: "+chrt.getUuid()+" with "+chrt.getProperties()); + } + } + } + + auth(); + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/c3/808fd516e6870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/c3/808fd516e6870014196aa5e86be5823c new file mode 100644 index 0000000..55ba225 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/c3/808fd516e6870014196aa5e86be5823c @@ -0,0 +1,115 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; + +public class MiOverviewActivity extends Activity { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_AUTH = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void auth() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_AUTH); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("Auth sent"); + } + + private void requestSteps() { + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_REALTIME_STEPS); + mGatt.readCharacteristic(chrt); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + auth(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + requestSteps(); + } + + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + Log.i(characteristic.getUuid().toString(), + Arrays.toString(characteristic.getValue())); + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/c3/b0274622de8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/c3/b0274622de8700141885aa2aa9523af4 new file mode 100644 index 0000000..87dc7ef --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/c3/b0274622de8700141885aa2aa9523af4 @@ -0,0 +1,9 @@ + + + + MiBand + Hello world! + MiBand not found. Is it in range? + MiOverviewActivity + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/c4/00bdaf1fec870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/c4/00bdaf1fec870014196aa5e86be5823c new file mode 100644 index 0000000..883afb6 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/c4/00bdaf1fec870014196aa5e86be5823c @@ -0,0 +1,65 @@ +package com.motioncoding.debugging; + +import android.content.Context; +import android.util.Log; +import android.widget.Toast; + +public class L { + + public static enum LogType { + CLASS, CLASS_AND_METHOD, CLASS_AND_METHOD_AND_LINE, CLASS_AND_LINE + } + + private static LogType mType = LogType.CLASS_AND_METHOD; + + + public static void toast(Context context, String msg) { + Toast.makeText(context, msg, Toast.LENGTH_SHORT).show(); + } + + public static void setLogType(LogType type) { + mType = type; + } + + public static void e(String msg) { + Log.e(getTag(), msg); + } + + public static void i(String msg) { + Log.i(getTag(), msg); + } + + public static void d(String msg) { + Log.d(getTag(), msg); + } + + public static void v(String msg) { + Log.v(getTag(), msg); + } + + public static void w(String msg) { + Log.w(getTag(), msg); + } + + public static void wtf(String msg) { + Log.wtf(getTag(), msg); + } + + private static String getTag() { + StackTraceElement[] s = Thread.currentThread().getStackTrace(); + switch (mType) { + case CLASS: + return s[4].getClassName(); + case CLASS_AND_LINE: + return s[4].getClassName()+":"+s[4].getLineNumber(); + case CLASS_AND_METHOD: + return s[4].getClassName()+"."+s[4].getMethodName(); + case CLASS_AND_METHOD_AND_LINE: + return s[4].getClassName()+"."+s[4].getMethodName()+":"+s[4].getLineNumber(); + default: + break; + } + return null; + } +} + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/c4/2068bc04ee870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/c4/2068bc04ee870014196aa5e86be5823c new file mode 100644 index 0000000..1e496ae --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/c4/2068bc04ee870014196aa5e86be5823c @@ -0,0 +1,180 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Observable; +import java.util.Observer; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.Spinner; +import android.widget.TextView; + +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity implements Observer { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_CONTROL_POINT = UUID + .fromString("0000ff05-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + //BLUETOOTH + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + + private MiBand mMiBand = new MiBand(); + + //UI + private TextView mTVSteps; + private Spinner mLoading; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.addObserver(this); + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + + mTVSteps = (TextView) findViewById(R.id.text_steps); + mLoading = (Spinner) findViewById(R.id.laoding); + + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() + request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + switch (state) { + case 0: + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + break; + case 1: + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + break; + case 2: + mMiBand.setName(new String(b)); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_DEVICE_NAME); + break; + } + } + }; + + @Override + public void update(Observable observable, Object data) { + mLoading.setVisibility(View.GONE); + mTVSteps.setText(mMiBand.mSteps); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/c4/60253401e6870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/c4/60253401e6870014196aa5e86be5823c new file mode 100644 index 0000000..c9bf44a --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/c4/60253401e6870014196aa5e86be5823c @@ -0,0 +1,115 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; + +public class MiOverviewActivity extends Activity { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_AUTH = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void auth() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_AUTH); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("Auth sent"); + } + + private void requestSteps() { + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_REALTIME_STEPS); + mGatt.readCharacteristic(chrt); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + auth(); + requestSteps(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + Log.i(characteristic.getUuid().toString(), + Arrays.toString(characteristic.getValue())); + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/c4/902c54b9d68700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/c4/902c54b9d68700141885aa2aa9523af4 new file mode 100644 index 0000000..3c3dd48 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/c4/902c54b9d68700141885aa2aa9523af4 @@ -0,0 +1,15 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; + +public class MiActivity extends Activity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_mi); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/c6/f03faa2dda8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/c6/f03faa2dda8700141885aa2aa9523af4 new file mode 100644 index 0000000..bf65b14 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/c6/f03faa2dda8700141885aa2aa9523af4 @@ -0,0 +1,20 @@ + + + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/c8/60276e25f9870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/c8/60276e25f9870014196aa5e86be5823c new file mode 100644 index 0000000..35ea9d9 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/c8/60276e25f9870014196aa5e86be5823c @@ -0,0 +1,309 @@ +package com.motioncoding.miband.view; + +import android.R; +import android.app.Dialog; +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.LinearGradient; +import android.graphics.Paint; +import android.graphics.Shader; +import android.os.Bundle; +import android.view.MotionEvent; +import android.view.View; + +public class ColorPickerDialog extends Dialog { + + public interface OnColorChangedListener { + void colorChanged(String key, int color); + } + + private OnColorChangedListener mListener; + private int mInitialColor, mDefaultColor; + private String mKey; + + private static class ColorPickerView extends View { + private Paint mPaint; + private float mCurrentHue = 0; + private int mCurrentX = 0, mCurrentY = 0; + private int mCurrentColor, mDefaultColor; + private final int[] mHueBarColors = new int[258]; + private int[] mMainColors = new int[65536]; + private OnColorChangedListener mListener; + + ColorPickerView(Context c, OnColorChangedListener l, int color, + int defaultColor) { + super(c); + mListener = l; + mDefaultColor = defaultColor; + + // Get the current hue from the current color and update the main + // color field + float[] hsv = new float[3]; + Color.colorToHSV(color, hsv); + mCurrentHue = hsv[0]; + updateMainColors(); + + mCurrentColor = color; + + // Initialize the colors of the hue slider bar + int index = 0; + for (float i = 0; i < 256; i += 256 / 42) // Red (#f00) to pink + // (#f0f) + { + mHueBarColors[index] = Color.rgb(255, 0, (int) i); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) // Pink (#f0f) to blue + // (#00f) + { + mHueBarColors[index] = Color.rgb(255 - (int) i, 0, 255); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) // Blue (#00f) to light + // blue (#0ff) + { + mHueBarColors[index] = Color.rgb(0, (int) i, 255); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) // Light blue (#0ff) to + // green (#0f0) + { + mHueBarColors[index] = Color.rgb(0, 255, 255 - (int) i); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) // Green (#0f0) to yellow + // (#ff0) + { + mHueBarColors[index] = Color.rgb((int) i, 255, 0); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) // Yellow (#ff0) to red + // (#f00) + { + mHueBarColors[index] = Color.rgb(255, 255 - (int) i, 0); + index++; + } + + // Initializes the Paint that will draw the View + mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + mPaint.setTextAlign(Paint.Align.CENTER); + mPaint.setTextSize(12); + } + + // Get the current selected color from the hue bar + private int getCurrentMainColor() { + int translatedHue = 255 - (int) (mCurrentHue * 255 / 360); + int index = 0; + for (float i = 0; i < 256; i += 256 / 42) { + if (index == translatedHue) + return Color.rgb(255, 0, (int) i); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) { + if (index == translatedHue) + return Color.rgb(255 - (int) i, 0, 255); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) { + if (index == translatedHue) + return Color.rgb(0, (int) i, 255); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) { + if (index == translatedHue) + return Color.rgb(0, 255, 255 - (int) i); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) { + if (index == translatedHue) + return Color.rgb((int) i, 255, 0); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) { + if (index == translatedHue) + return Color.rgb(255, 255 - (int) i, 0); + index++; + } + return Color.RED; + } + + // Update the main field colors depending on the current selected hue + private void updateMainColors() { + int mainColor = getCurrentMainColor(); + int index = 0; + int[] topColors = new int[256]; + for (int y = 0; y < 256; y++) { + for (int x = 0; x < 256; x++) { + if (y == 0) { + mMainColors[index] = Color.rgb( + 255 - (255 - Color.red(mainColor)) * x / 255, + 255 - (255 - Color.green(mainColor)) * x / 255, + 255 - (255 - Color.blue(mainColor)) * x / 255); + topColors[x] = mMainColors[index]; + } else + mMainColors[index] = Color.rgb( + (255 - y) * Color.red(topColors[x]) / 255, + (255 - y) * Color.green(topColors[x]) / 255, + (255 - y) * Color.blue(topColors[x]) / 255); + index++; + } + } + } + + @Override + protected void onDraw(Canvas canvas) { + int translatedHue = 255 - (int) (mCurrentHue * 255 / 360); + // Display all the colors of the hue bar with lines + for (int x = 0; x < 256; x++) { + // If this is not the current selected hue, display the actual + // color + if (translatedHue != x) { + mPaint.setColor(mHueBarColors[x]); + mPaint.setStrokeWidth(1); + } else // else display a slightly larger black line + { + mPaint.setColor(Color.BLACK); + mPaint.setStrokeWidth(3); + } + canvas.drawLine(x + 10, 0, x + 10, 40, mPaint); + // canvas.drawLine(0, x+10, 40, x+10, mPaint); + } + + // Display the main field colors using LinearGradient + for (int x = 0; x < 256; x++) { + int[] colors = new int[2]; + colors[0] = mMainColors[x]; + colors[1] = Color.BLACK; + Shader shader = new LinearGradient(0, 50, 0, 306, colors, null, + Shader.TileMode.REPEAT); + mPaint.setShader(shader); + canvas.drawLine(x + 10, 50, x + 10, 306, mPaint); + } + mPaint.setShader(null); + + // Display the circle around the currently selected color in the + // main field + if (mCurrentX != 0 && mCurrentY != 0) { + mPaint.setStyle(Paint.Style.STROKE); + mPaint.setColor(Color.BLACK); + canvas.drawCircle(mCurrentX, mCurrentY, 10, mPaint); + } + + // Draw a 'button' with the currently selected color + mPaint.setStyle(Paint.Style.FILL); + mPaint.setColor(mCurrentColor); + canvas.drawRect(10, 316, 138, 356, mPaint); + + // Set the text color according to the brightness of the color + if (Color.red(mCurrentColor) + Color.green(mCurrentColor) + + Color.blue(mCurrentColor) < 384) + mPaint.setColor(Color.WHITE); + else + mPaint.setColor(Color.BLACK); + canvas.drawText( + getResources() + .getString(R.string.settings_bg_color_confirm), 74, + 340, mPaint); + + // Draw a 'button' with the default color + mPaint.setStyle(Paint.Style.FILL); + mPaint.setColor(mDefaultColor); + canvas.drawRect(138, 316, 266, 356, mPaint); + + // Set the text color according to the brightness of the color + if (Color.red(mDefaultColor) + Color.green(mDefaultColor) + + Color.blue(mDefaultColor) < 384) + mPaint.setColor(Color.WHITE); + else + mPaint.setColor(Color.BLACK); + canvas.drawText( + getResources().getString( + R.string.settings_default_color_confirm), 202, 340, + mPaint); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + setMeasuredDimension(276, 366); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + if (event.getAction() != MotionEvent.ACTION_DOWN) + return true; + float x = event.getX(); + float y = event.getY(); + + // If the touch event is located in the hue bar + if (x > 10 && x < 266 && y > 0 && y < 40) { + // Update the main field colors + mCurrentHue = (255 - x) * 360 / 255; + updateMainColors(); + + // Update the current selected color + int transX = mCurrentX - 10; + int transY = mCurrentY - 60; + int index = 256 * (transY - 1) + transX; + if (index > 0 && index < mMainColors.length) + mCurrentColor = mMainColors[256 * (transY - 1) + transX]; + + // Force the redraw of the dialog + invalidate(); + } + + // If the touch event is located in the main field + if (x > 10 && x < 266 && y > 50 && y < 306) { + mCurrentX = (int) x; + mCurrentY = (int) y; + int transX = mCurrentX - 10; + int transY = mCurrentY - 60; + int index = 256 * (transY - 1) + transX; + if (index > 0 && index < mMainColors.length) { + // Update the current color + mCurrentColor = mMainColors[index]; + // Force the redraw of the dialog + invalidate(); + } + } + + // If the touch event is located in the left button, notify the + // listener with the current color + if (x > 10 && x < 138 && y > 316 && y < 356) + mListener.colorChanged("", mCurrentColor); + + // If the touch event is located in the right button, notify the + // listener with the default color + if (x > 138 && x < 266 && y > 316 && y < 356) + mListener.colorChanged("", mDefaultColor); + + return true; + } + } + + public ColorPickerDialog(Context context, OnColorChangedListener listener, + String key, int initialColor, int defaultColor) { + super(context); + + mListener = listener; + mKey = key; + mInitialColor = initialColor; + mDefaultColor = defaultColor; + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + OnColorChangedListener l = new OnColorChangedListener() { + public void colorChanged(String key, int color) { + mListener.colorChanged(mKey, color); + dismiss(); + } + }; + + setContentView(new ColorPickerView(getContext(), l, mInitialColor, + mDefaultColor)); + setTitle(R.string.settings_bg_color_dialog); + + } +} \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/c8/8095736af3870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/c8/8095736af3870014196aa5e86be5823c new file mode 100644 index 0000000..d18e5a3 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/c8/8095736af3870014196aa5e86be5823c @@ -0,0 +1,204 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Observable; +import java.util.Observer; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity implements Observer { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_CONTROL_POINT = UUID + .fromString("0000ff05-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + // BLUETOOTH + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + private MiBand mMiBand = new MiBand(); + + // UI + private TextView mTVSteps; + private TextView mTVBatteryLevel; + private ProgressBar mLoading; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.addObserver(this); + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + + mTVSteps = (TextView) findViewById(R.id.text_steps); + mTVBatteryLevel = (TextView) findViewById(R.id.text_battery_level); + mLoading = (ProgressBar) findViewById(R.id.laoding); + + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private void setColor(byte r, byte g, byte b) { + BluetoothGattCharacteristic theme = getMiliService() + .getCharacteristic(UUID_CHAR_CONTROL_POINT); + theme.setValue(new byte[] { 14, r, g, b, 0 }); + mGatt.writeCharacteristic(theme); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() + setColor(0, 0, 0); +// request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + switch (state) { + case 0: + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + break; + case 1: + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + break; + case 2: + mMiBand.setName(new String(b)); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_DEVICE_NAME); + break; + case 3: + + break; + } + } + }; + + @Override + public void update(Observable observable, Object data) { + runOnUiThread(new Runnable() { + + @Override + public void run() { + mLoading.setVisibility(View.GONE); + ((LinearLayout) findViewById(R.id.textHolder)) + .setVisibility(View.VISIBLE); + mTVSteps.setText(mMiBand.mSteps + ""); + if (mMiBand.mBattery != null) + mTVBatteryLevel.setText(mMiBand.mBattery.mBatteryLevel + + "%"); + } + }); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/c8/f0f4152be48700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/c8/f0f4152be48700141885aa2aa9523af4 new file mode 100644 index 0000000..f16c4c6 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/c8/f0f4152be48700141885aa2aa9523af4 @@ -0,0 +1,16 @@ +package com.motioncoding.miband.model; + +import java.util.Calendar; + +public class MiBand { + + String mBTAddress; + int mSteps; + + + static class Battery { + int mBatteryLevel; + int mCycles; + Calendar mLastCharged; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/cb/f0b0df75d78700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/cb/f0b0df75d78700141885aa2aa9523af4 new file mode 100644 index 0000000..722f5a8 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/cb/f0b0df75d78700141885aa2aa9523af4 @@ -0,0 +1,37 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter.LeScanCallback; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.os.Bundle; + +public class MiActivity extends Activity implements LeScanCallback { + + private BluetoothManager bluetoothManager; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_mi); + bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); + } + + public void onResume() { + bluetoothManager.getAdapter().startLeScan(this); + } + + @Override + public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { + if(device != null && device.getName() != null & device.getName().equals("MI")) { + System.out.println(device.getAddress()); + bluetoothManager.getAdapter().stopLeScan(this); + } + } + + public void onPause() { + super.onPause(); + bluetoothManager.getAdapter().stopLeScan(this); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/cc/802e23b9f7870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/cc/802e23b9f7870014196aa5e86be5823c new file mode 100644 index 0000000..77d2383 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/cc/802e23b9f7870014196aa5e86be5823c @@ -0,0 +1,236 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Observable; +import java.util.Observer; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.motioncoding.debugging.L; +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.LeParams; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity implements Observer { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_CONTROL_POINT = UUID + .fromString("0000ff05-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_LE_PARAMS = UUID + .fromString("0000ff09-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + // BLUETOOTH + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + private MiBand mMiBand = new MiBand(); + + // UI + private TextView mTVSteps; + private TextView mTVBatteryLevel; + private ProgressBar mLoading; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.addObserver(this); + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + + mTVSteps = (TextView) findViewById(R.id.text_steps); + mTVBatteryLevel = (TextView) findViewById(R.id.text_battery_level); + mLoading = (ProgressBar) findViewById(R.id.laoding); + + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.menu_overview, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.action_leparams: + if(mMiBand.mLeParams == null) { + L.toast(this, "No Params received yet"); + return true; + } + Intent intent = new Intent(getApplicationContext(), MiLeParamsActivity.class); + intent.putExtra("params", mMiBand.mLeParams); + break; + } + return true; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private void setColor(byte r, byte g, byte b) { + BluetoothGattCharacteristic theme = getMiliService().getCharacteristic( + UUID_CHAR_CONTROL_POINT); + theme.setValue(new byte[] { 14, r, g, b, 0 }); + mGatt.writeCharacteristic(theme); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() + // setColor((byte)127, (byte)0, (byte)0); + // request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + + // handle value + if (characteristic.getUuid().equals(UUID_CHAR_REALTIME_STEPS)) + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + else if (characteristic.getUuid().equals(UUID_CHAR_BATTERY)) { + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + } else if (characteristic.getUuid().equals(UUID_CHAR_DEVICE_NAME)) { + mMiBand.setName(new String(b)); + } else if (characteristic.getUuid().equals(UUID_CHAR_LE_PARAMS)) { + LeParams params = LeParams.fromByte(b); + mMiBand.setLeParams(params); + } + + // proceed with state machine (called in the beginning) + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_DEVICE_NAME); + break; + case 3: + request(UUID_CHAR_LE_PARAMS); + break; + } + } + }; + + @Override + public void update(Observable observable, Object data) { + runOnUiThread(new Runnable() { + + @Override + public void run() { + mLoading.setVisibility(View.GONE); + ((LinearLayout) findViewById(R.id.textHolder)) + .setVisibility(View.VISIBLE); + mTVSteps.setText(mMiBand.mSteps + ""); + if (mMiBand.mBattery != null) + mTVBatteryLevel.setText(mMiBand.mBattery.mBatteryLevel + + "%"); + } + }); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/cc/f0690e2bdb8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/cc/f0690e2bdb8700141885aa2aa9523af4 new file mode 100644 index 0000000..b88df37 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.history/cc/f0690e2bdb8700141885aa2aa9523af4 differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/cd/50365a13e48700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/cd/50365a13e48700141885aa2aa9523af4 new file mode 100644 index 0000000..1910e69 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/cd/50365a13e48700141885aa2aa9523af4 @@ -0,0 +1,5 @@ +package com.motioncoding.miband.model; + +public class MiBand { + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/cf/0004e2d4e5870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/cf/0004e2d4e5870014196aa5e86be5823c new file mode 100644 index 0000000..2615ef8 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/cf/0004e2d4e5870014196aa5e86be5823c @@ -0,0 +1,110 @@ +package com.motioncoding.miband; + +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_AUTH = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void auth() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_AUTH); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("Auth sent"); + } + + private void requestSteps() { + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic(UUID_CHAR_REALTIME_STEPS); + mGatt.readCharacteristic(chrt) + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + auth(); + requestSteps(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/d/d0f23014da8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/d/d0f23014da8700141885aa2aa9523af4 new file mode 100644 index 0000000..82ae807 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/d/d0f23014da8700141885aa2aa9523af4 @@ -0,0 +1,20 @@ + + + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/d2/5069d1e7ec870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/d2/5069d1e7ec870014196aa5e86be5823c new file mode 100644 index 0000000..5e54d79 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/d2/5069d1e7ec870014196aa5e86be5823c @@ -0,0 +1,26 @@ + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/d3/a0adcc4cda8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/d3/a0adcc4cda8700141885aa2aa9523af4 new file mode 100644 index 0000000..440b330 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/d3/a0adcc4cda8700141885aa2aa9523af4 @@ -0,0 +1,75 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothAdapter.LeScanCallback; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.os.Build; +import android.os.Bundle; +import android.os.Handler; + +public class MiActivity extends Activity implements LeScanCallback { + + private BluetoothAdapter mBluetoothAdapter; + private boolean mScanning; + private Handler mHandler = new Handler(); + // Stops scanning after 10 seconds. + private static final long SCAN_PERIOD = 10000; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + + + setContentView(R.layout.activity_mi); + mBluetoothAdapter = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)).getAdapter(); + } + + @Override + public void onResume() { + super.onResume(); + scanLeDevice(true); + } + + + + @SuppressWarnings("deprecation") // L Apis are buggy and crap! + private void scanLeDevice(final boolean enable) { + if (enable) { + // Stops scanning after a pre-defined scan period. + mHandler.postDelayed(new Runnable() { + + @Override + public void run() { + mScanning = false; + mBluetoothAdapter.stopLeScan(MiActivity.this); + scanLeDevice(true); + } + }, SCAN_PERIOD); + + mScanning = true; + mBluetoothAdapter.startLeScan(this); + } else { + mScanning = false; + mBluetoothAdapter.stopLeScan(this); + } + } + + @Override + public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { + System.out.println(device.getName()+" "+device.getAddress()); + if(device != null && device.getName() != null & device.getName().equals("MI")) { + System.out.println(device.getAddress()); + scanLeDevice(false); // we only care about one miband so that's enough + } + } + + @Override + public void onPause() { + super.onPause(); + scanLeDevice(false); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/d5/30ee32ddf4870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/d5/30ee32ddf4870014196aa5e86be5823c new file mode 100644 index 0000000..c4d61f4 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/d5/30ee32ddf4870014196aa5e86be5823c @@ -0,0 +1,20 @@ +package com.motioncoding.miband.model; + +public class LeParams { + public int connIntMin, connIntMax, latency, timeout, connInt, advInt; + + public static LeParams fromByte(byte[] b) { + LeParams params = new LeParams(); + + params.connIntMax = 0xffff & (0xff & b[0] | (0xff & b[1]) << 8); + params.connIntMax = 0xffff & (0xff & b[2] | (0xff & b[3]) << 8); + params.latency = 0xffff & (0xff & b[4] | (0xff & b[5]) << 8); + params.timeout = 0xffff & (0xff & b[6] | (0xff & b[7]) << 8); + params.connInt = 0xffff & (0xff & b[8] | (0xff & b[9]) << 8); + params.advInt = 0xffff & (0xff & b[10] | (0xff & b[11]) << 8); + + params.connIntMin *= 1.25; + + return params; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/d6/d0e9018ee8870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/d6/d0e9018ee8870014196aa5e86be5823c new file mode 100644 index 0000000..a6c6c28 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/d6/d0e9018ee8870014196aa5e86be5823c @@ -0,0 +1,33 @@ +package com.motioncoding.miband.model; + +import java.util.Calendar; + +public class Battery { + public int mBatteryLevel; + public int mCycles; + public Calendar mLastCharged; + + public static Battery fromByte(byte[] b) { + return null; + } + + static enum Status { + LOW, FULL, CHARGING, NOT_CHARGING; + + public static Status fromByte(byte b) { + switch (b) { + case 1: + return LOW; + case 2: + return CHARGING; + case 3: + return FULL; + case 4: + return NOT_CHARGING; + + default: + return null; + } + } + } +} \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/d7/60888a66db8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/d7/60888a66db8700141885aa2aa9523af4 new file mode 100644 index 0000000..09d0c79 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/d7/60888a66db8700141885aa2aa9523af4 @@ -0,0 +1,25 @@ + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/d8/b0bd8fd0e18700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/d8/b0bd8fd0e18700141885aa2aa9523af4 new file mode 100644 index 0000000..2fdf7e2 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/d8/b0bd8fd0e18700141885aa2aa9523af4 @@ -0,0 +1,82 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + for (BluetoothGattService srvs : gatt.getServices()) { + System.out.println("Service: "+srvs.getUuid()); + for (BluetoothGattCharacteristic chrt : srvs + .getCharacteristics()) { + System.out.println("Characteristic: "+chrt.getUuid()+" permissions: "+chrt.getPermissions()); + } + } + } + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/da/00b6a28dec870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/da/00b6a28dec870014196aa5e86be5823c new file mode 100644 index 0000000..8d89459 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/da/00b6a28dec870014196aa5e86be5823c @@ -0,0 +1,55 @@ +package com.motioncoding.miband.model; + +import java.util.Calendar; + +public class Battery { + public int mBatteryLevel; + public int mCycles; + public Calendar mLastCharged; + public Status mStatus; + + public static Battery fromByte(byte[] b) { + Battery battery = new Battery(); + battery.mBatteryLevel = b[0]; + battery.mStatus = Status.fromByte(b[9]); + battery.mLastCharged = Calendar.getInstance(); + + battery.mLastCharged.set(Calendar.YEAR, b[1]+2000); + battery.mLastCharged.set(Calendar.MONTH, b[2]); + battery.mLastCharged.set(Calendar.DATE, b[3]); + + battery.mLastCharged.set(Calendar.HOUR_OF_DAY, b[4]); + battery.mLastCharged.set(Calendar.MINUTE, b[5]); + battery.mLastCharged.set(Calendar.SECOND, b[6]); + + + + battery.mCycles = 0xffff & (0xff & b[7] | (0xff & b[8]) << 8); + return battery; + } + + @Override + public String toString() { + return String.format("Level: %s % Cycles: %s State: %s Last Charged: %s", mBatteryLevel, mCycles, mStatus.toString(), mLastCharged.toString()); + } + + static enum Status { + LOW, FULL, CHARGING, NOT_CHARGING; + + public static Status fromByte(byte b) { + switch (b) { + case 1: + return LOW; + case 2: + return CHARGING; + case 3: + return FULL; + case 4: + return NOT_CHARGING; + + default: + return null; + } + } + } +} \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/da/b08df6d4f6870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/da/b08df6d4f6870014196aa5e86be5823c new file mode 100644 index 0000000..57597aa --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/da/b08df6d4f6870014196aa5e86be5823c @@ -0,0 +1,18 @@ +package com.motioncoding.miband; + +import android.app.ListActivity; +import android.os.Bundle; + +import com.motioncoding.miband.model.LeParams; + +public class MiLeParamsActivity extends ListActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + setContentView(R.layout.activity_mi_le_params); + + LeParams params = (LeParams) getIntent().getParcelableExtra("params"); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/da/d060735df4870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/da/d060735df4870014196aa5e86be5823c new file mode 100644 index 0000000..73550e3 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/da/d060735df4870014196aa5e86be5823c @@ -0,0 +1,207 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Observable; +import java.util.Observer; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity implements Observer { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_CONTROL_POINT = UUID + .fromString("0000ff05-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_LE_PARAMS = UUID + .fromString("0000ff09-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + // BLUETOOTH + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + private MiBand mMiBand = new MiBand(); + + // UI + private TextView mTVSteps; + private TextView mTVBatteryLevel; + private ProgressBar mLoading; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.addObserver(this); + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + + mTVSteps = (TextView) findViewById(R.id.text_steps); + mTVBatteryLevel = (TextView) findViewById(R.id.text_battery_level); + mLoading = (ProgressBar) findViewById(R.id.laoding); + + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private void setColor(byte r, byte g, byte b) { + BluetoothGattCharacteristic theme = getMiliService() + .getCharacteristic(UUID_CHAR_CONTROL_POINT); + theme.setValue(new byte[] { 14, r, g, b, 0 }); + mGatt.writeCharacteristic(theme); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() +// setColor((byte)127, (byte)0, (byte)0); +// request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + switch (state) { + case 0: + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + break; + case 1: + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + break; + case 2: + mMiBand.setName(new String(b)); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_DEVICE_NAME); + break; + case 3: + request(UUID_LE_PARAMS); + break; + break; + } + } + }; + + @Override + public void update(Observable observable, Object data) { + runOnUiThread(new Runnable() { + + @Override + public void run() { + mLoading.setVisibility(View.GONE); + ((LinearLayout) findViewById(R.id.textHolder)) + .setVisibility(View.VISIBLE); + mTVSteps.setText(mMiBand.mSteps + ""); + if (mMiBand.mBattery != null) + mTVBatteryLevel.setText(mMiBand.mBattery.mBatteryLevel + + "%"); + } + }); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/db/50ac094af6870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/db/50ac094af6870014196aa5e86be5823c new file mode 100644 index 0000000..ebbe832 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/db/50ac094af6870014196aa5e86be5823c @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/dc/20348c81e4870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/dc/20348c81e4870014196aa5e86be5823c new file mode 100644 index 0000000..2da39f2 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/dc/20348c81e4870014196aa5e86be5823c @@ -0,0 +1,17 @@ +package com.motioncoding.miband.model; + +import java.util.Calendar; + +public class MiBand { + + String mBTAddress; + int mSteps; + + + static class Battery { + int mBatteryLevel; + int mCycles; + Calendar mLastCharged; + + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/dc/50c55822de8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/dc/50c55822de8700141885aa2aa9523af4 new file mode 100644 index 0000000..b6c10ad --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/dc/50c55822de8700141885aa2aa9523af4 @@ -0,0 +1,26 @@ + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/df/b0d5dfb7ce8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/df/b0d5dfb7ce8700141885aa2aa9523af4 new file mode 100644 index 0000000..50fe8d0 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/df/b0d5dfb7ce8700141885aa2aa9523af4 @@ -0,0 +1,12 @@ + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e/40450240f7870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/e/40450240f7870014196aa5e86be5823c new file mode 100644 index 0000000..dbde3e2 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/e/40450240f7870014196aa5e86be5823c @@ -0,0 +1,34 @@ +package com.motioncoding.miband; + +import android.app.ListActivity; +import android.os.Bundle; +import android.widget.ArrayAdapter; + +import com.motioncoding.miband.model.LeParams; + +public class MiLeParamsActivity extends ListActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + setContentView(R.layout.activity_mi_le_params); + + LeParams params = (LeParams) getIntent().getParcelableExtra("params"); + + String[] values = new String[6]; + + values[0] = String.format("Connection Intervall\n %s ms", params.connInt); + values[1] = String.format("Connection Intervall Min\n %s ms", params.connIntMin); + values[2] = String.format("Connection Intervall Max\n %s ms", params.connIntMax); + + values[3] = String.format("Advertising Intervall\n %s ms", params.advInt); + values[4] = String.format("Latency\n %s ms", params.latency); + values[5] = String.format("Timeout\n %s ms", params.timeout); + + + ArrayAdapter adapter = new ArrayAdapter(getActivity(), + android.R.layout.simple_list_item_1, values); + this.setListAdapter(adapter); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e/b09a10c4f4870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/e/b09a10c4f4870014196aa5e86be5823c new file mode 100644 index 0000000..ce29091 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/e/b09a10c4f4870014196aa5e86be5823c @@ -0,0 +1,20 @@ +package com.motioncoding.miband.model; + +public class LeParams { + public int connIntMin, connIntMax, latency, timeout, connInt, advInt; + + public static LeParams fromByte(byte[] b) { + LeParams params = new LeParams(); + + params.connIntMax = 0xffff & (0xff & b[0] | (0xff & b[1]) << 8); + params.connIntMax = 0xffff & (0xff & b[2] | (0xff & b[3]) << 8); + params.latency = 0xffff & (0xff & b[4] | (0xff & b[5]) << 8); + params.timeout = 0xffff & (0xff & b[6] | (0xff & b[7]) << 8); + params.connInt = 0xffff & (0xff & b[8] | (0xff & b[9]) << 8); + params.advInt = 0xffff & (0xff & b[10] | (0xff & b[11]) << 8); + + params.connIntMin *= 1.25f; + + return params; + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e0/0067276ef9870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/e0/0067276ef9870014196aa5e86be5823c new file mode 100644 index 0000000..3b9cf70 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/e0/0067276ef9870014196aa5e86be5823c @@ -0,0 +1,236 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Observable; +import java.util.Observer; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.motioncoding.debugging.L; +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.LeParams; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity implements Observer { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_CONTROL_POINT = UUID + .fromString("0000ff05-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_LE_PARAMS = UUID + .fromString("0000ff09-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + // BLUETOOTH + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + private MiBand mMiBand = new MiBand(); + + // UI + private TextView mTVSteps; + private TextView mTVBatteryLevel; + private ProgressBar mLoading; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.addObserver(this); + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + + mTVSteps = (TextView) findViewById(R.id.text_steps); + mTVBatteryLevel = (TextView) findViewById(R.id.text_battery_level); + mLoading = (ProgressBar) findViewById(R.id.laoding); + + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.menu_overview, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.action_leparams: + if(mMiBand.mLeParams == null) { + L.toast(this, "No LE params received yet"); + return true; + } + Intent intent = new Intent(getApplicationContext(), MiLeParamsActivity.class); + intent.putExtra("params", mMiBand.mLeParams); + startActivity(intent); + break; + } + return true; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private void setColor(byte r, byte g, byte b) { + BluetoothGattCharacteristic theme = getMiliService().getCharacteristic( + UUID_CHAR_CONTROL_POINT); + theme.setValue(new byte[] { 14, r, g, b, 0 }); + mGatt.writeCharacteristic(theme); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() + // setColor((byte)127, (byte)0, (byte)0); + request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + + // handle value + if (characteristic.getUuid().equals(UUID_CHAR_REALTIME_STEPS)) + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + else if (characteristic.getUuid().equals(UUID_CHAR_BATTERY)) { + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + } else if (characteristic.getUuid().equals(UUID_CHAR_DEVICE_NAME)) { + mMiBand.setName(new String(b)); + } else if (characteristic.getUuid().equals(UUID_CHAR_LE_PARAMS)) { + LeParams params = LeParams.fromByte(b); + mMiBand.setLeParams(params); + } + + // proceed with state machine (called in the beginning) + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_DEVICE_NAME); + break; + case 3: + request(UUID_CHAR_LE_PARAMS); + break; + } + } + }; + + @Override + public void update(Observable observable, Object data) { + runOnUiThread(new Runnable() { + + @Override + public void run() { + mLoading.setVisibility(View.GONE); + ((LinearLayout) findViewById(R.id.textHolder)) + .setVisibility(View.VISIBLE); + mTVSteps.setText(mMiBand.mSteps + ""); + if (mMiBand.mBattery != null) + mTVBatteryLevel.setText(mMiBand.mBattery.mBatteryLevel + + "%"); + } + }); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e1/c0b7caabe4870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/e1/c0b7caabe4870014196aa5e86be5823c new file mode 100644 index 0000000..e69de29 diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e2/308b1a57e7870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/e2/308b1a57e7870014196aa5e86be5823c new file mode 100644 index 0000000..0e4b0ac --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/e2/308b1a57e7870014196aa5e86be5823c @@ -0,0 +1,132 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; + +public class MiOverviewActivity extends Activity { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_AUTH = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void auth() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_AUTH); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("Auth sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + auth(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + } + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(characteristic.getValue())); + switch (state) { + case 0: + System.out.println(characteristic.getIntValue(0, 0)); + break; + } + state++; + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e2/e063ca1edd8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/e2/e063ca1edd8700141885aa2aa9523af4 new file mode 100644 index 0000000..336b358 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/e2/e063ca1edd8700141885aa2aa9523af4 @@ -0,0 +1,81 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothAdapter.LeScanCallback; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.widget.TextView; + +public class MiActivity extends Activity implements LeScanCallback { + + private BluetoothAdapter mBluetoothAdapter; + private boolean mScanning; + private TextView mTextView; + private Handler mHandler = new Handler(); + // Stops scanning after 10 seconds. + private static final long SCAN_PERIOD = 10000; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + setContentView(R.layout.activity_mi); + mTextView = (TextView) findViewById(R.id.text_search); + mBluetoothAdapter = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)) + .getAdapter(); + } + + @Override + public void onResume() { + super.onResume(); + scanLeDevice(true); + } + + @SuppressWarnings("deprecation") + // L Apis are buggy and crap! + private void scanLeDevice(final boolean enable) { + if (enable) { + // Stops scanning after a pre-defined scan period. + mHandler.postDelayed(new Runnable() { + + @Override + public void run() { + mScanning = false; + mBluetoothAdapter.stopLeScan(MiActivity.this); + mTextView.setText(R.string.not_found); + } + }, SCAN_PERIOD); + + mScanning = true; + mBluetoothAdapter.startLeScan(this); + } else { + mScanning = false; + mBluetoothAdapter.stopLeScan(this); + } + } + + @Override + public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { + System.out.println(device.getName() + " " + device.getAddress()); + if (device != null && device.getName() != null + & device.getName().equals("MI")) { + System.out.println(device.getAddress()); + scanLeDevice(false); // we only care about one miband so that's + // enough + Intent intent = new Intent(getApplicationContext(), MiOverviewActivity.class); + intent.putExtra("address", device.getAddress()); + startActivity(intent); + } + } + + @Override + public void onPause() { + super.onPause(); + scanLeDevice(false); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e3/60ffa197ee870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/e3/60ffa197ee870014196aa5e86be5823c new file mode 100644 index 0000000..bbc4cf1 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/e3/60ffa197ee870014196aa5e86be5823c @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e4/b0a2a807da8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/e4/b0a2a807da8700141885aa2aa9523af4 new file mode 100644 index 0000000..73c1349 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/e4/b0a2a807da8700141885aa2aa9523af4 @@ -0,0 +1,71 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothAdapter.LeScanCallback; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.os.Bundle; +import android.os.Handler; + +public class MiActivity extends Activity implements LeScanCallback { + + private BluetoothAdapter mBluetoothAdapter; + private boolean mScanning; + private Handler mHandler = new Handler(); + // Stops scanning after 10 seconds. + private static final long SCAN_PERIOD = 10000; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_mi); + mBluetoothAdapter = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)).getAdapter(); + } + + @Override + public void onResume() { + super.onResume(); + scanLeDevice(true); + } + + + + @SuppressWarnings("deprecation") // L Apis are buggy and crap! + private void scanLeDevice(final boolean enable) { + if (enable) { + // Stops scanning after a pre-defined scan period. + mHandler.postDelayed(new Runnable() { + + @Override + public void run() { + mScanning = false; + mBluetoothAdapter.stopLeScan(MiActivity.this); + scanLeDevice(true); + } + }, SCAN_PERIOD); + + mScanning = true; + mBluetoothAdapter.startLeScan(this); + } else { + mScanning = false; + mBluetoothAdapter.stopLeScan(this); + } + } + + @Override + public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { + System.out.println(device.getName()+" "+device.getAddress()); + if(device != null && device.getName() != null & device.getName().equals("MI")) { + System.out.println(device.getAddress()); + scanLeDevice(false); // we only care about one miband so that's enough + } + } + + @Override + public void onPause() { + super.onPause(); + scanLeDevice(false); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e5/00bd3ee8df8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/e5/00bd3ee8df8700141885aa2aa9523af4 new file mode 100644 index 0000000..c476427 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/e5/00bd3ee8df8700141885aa2aa9523af4 @@ -0,0 +1,45 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + mMiBand.connectGatt(this, false, this); + } + + + @Override + public void onResume() { + super.onResume(); + + } + + @Override + public void onPause() { + super.onPause(); + } + + + + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e6/006d9cd3d78700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/e6/006d9cd3d78700141885aa2aa9523af4 new file mode 100644 index 0000000..fe7a4e2 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/e6/006d9cd3d78700141885aa2aa9523af4 @@ -0,0 +1,68 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothAdapter.LeScanCallback; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.os.Bundle; +import android.os.Handler; + +public class MiActivity extends Activity implements LeScanCallback { + + private BluetoothManager bluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private boolean mScanning; + private Handler mHandler; + // Stops scanning after 10 seconds. + private static final long SCAN_PERIOD = 10000; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_mi); + bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); + } + + @Override + public void onResume() { + super.onResume(); + } + + + + + private void scanLeDevice(final boolean enable) { + if (enable) { + // Stops scanning after a pre-defined scan period. + mHandler.postDelayed(new Runnable() { + @Override + public void run() { + mScanning = false; + mBluetoothAdapter.stopLeScan(MiActivity.this); + } + }, SCAN_PERIOD); + + mScanning = true; + mBluetoothAdapter.startLeScan(this); + } else { + mScanning = false; + mBluetoothAdapter.stopLeScan(this); + } + } + + @Override + public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { + if(device != null && device.getName() != null & device.getName().equals("MI")) { + System.out.println(device.getAddress()); + bluetoothManager.getAdapter().stopLeScan(this); + } + } + + @Override + public void onPause() { + super.onPause(); + bluetoothManager.getAdapter().stopLeScan(this); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e7/c03d63d5ec870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/e7/c03d63d5ec870014196aa5e86be5823c new file mode 100644 index 0000000..d25efdd --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/e7/c03d63d5ec870014196aa5e86be5823c @@ -0,0 +1,24 @@ + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e8/10048494ce8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/e8/10048494ce8700141885aa2aa9523af4 new file mode 100644 index 0000000..3392810 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/e8/10048494ce8700141885aa2aa9523af4 @@ -0,0 +1,17 @@ + + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e8/b024d197f9870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/e8/b024d197f9870014196aa5e86be5823c new file mode 100644 index 0000000..5322495 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/e8/b024d197f9870014196aa5e86be5823c @@ -0,0 +1,307 @@ +package com.motioncoding.miband.view; + +import android.R; +import android.app.Dialog; +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.LinearGradient; +import android.graphics.Paint; +import android.graphics.Shader; +import android.os.Bundle; +import android.view.MotionEvent; +import android.view.View; + +public class ColorPickerDialog extends Dialog { + + public interface OnColorChangedListener { + void colorChanged(String key, int color); + } + + private OnColorChangedListener mListener; + private int mInitialColor, mDefaultColor; + private String mKey; + + private static class ColorPickerView extends View { + private Paint mPaint; + private float mCurrentHue = 0; + private int mCurrentX = 0, mCurrentY = 0; + private int mCurrentColor, mDefaultColor; + private final int[] mHueBarColors = new int[258]; + private int[] mMainColors = new int[65536]; + private OnColorChangedListener mListener; + + ColorPickerView(Context c, OnColorChangedListener l, int color, + int defaultColor) { + super(c); + mListener = l; + mDefaultColor = defaultColor; + + // Get the current hue from the current color and update the main + // color field + float[] hsv = new float[3]; + Color.colorToHSV(color, hsv); + mCurrentHue = hsv[0]; + updateMainColors(); + + mCurrentColor = color; + + // Initialize the colors of the hue slider bar + int index = 0; + for (float i = 0; i < 256; i += 256 / 42) // Red (#f00) to pink + // (#f0f) + { + mHueBarColors[index] = Color.rgb(255, 0, (int) i); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) // Pink (#f0f) to blue + // (#00f) + { + mHueBarColors[index] = Color.rgb(255 - (int) i, 0, 255); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) // Blue (#00f) to light + // blue (#0ff) + { + mHueBarColors[index] = Color.rgb(0, (int) i, 255); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) // Light blue (#0ff) to + // green (#0f0) + { + mHueBarColors[index] = Color.rgb(0, 255, 255 - (int) i); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) // Green (#0f0) to yellow + // (#ff0) + { + mHueBarColors[index] = Color.rgb((int) i, 255, 0); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) // Yellow (#ff0) to red + // (#f00) + { + mHueBarColors[index] = Color.rgb(255, 255 - (int) i, 0); + index++; + } + + // Initializes the Paint that will draw the View + mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + mPaint.setTextAlign(Paint.Align.CENTER); + mPaint.setTextSize(12); + } + + // Get the current selected color from the hue bar + private int getCurrentMainColor() { + int translatedHue = 255 - (int) (mCurrentHue * 255 / 360); + int index = 0; + for (float i = 0; i < 256; i += 256 / 42) { + if (index == translatedHue) + return Color.rgb(255, 0, (int) i); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) { + if (index == translatedHue) + return Color.rgb(255 - (int) i, 0, 255); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) { + if (index == translatedHue) + return Color.rgb(0, (int) i, 255); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) { + if (index == translatedHue) + return Color.rgb(0, 255, 255 - (int) i); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) { + if (index == translatedHue) + return Color.rgb((int) i, 255, 0); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) { + if (index == translatedHue) + return Color.rgb(255, 255 - (int) i, 0); + index++; + } + return Color.RED; + } + + // Update the main field colors depending on the current selected hue + private void updateMainColors() { + int mainColor = getCurrentMainColor(); + int index = 0; + int[] topColors = new int[256]; + for (int y = 0; y < 256; y++) { + for (int x = 0; x < 256; x++) { + if (y == 0) { + mMainColors[index] = Color.rgb( + 255 - (255 - Color.red(mainColor)) * x / 255, + 255 - (255 - Color.green(mainColor)) * x / 255, + 255 - (255 - Color.blue(mainColor)) * x / 255); + topColors[x] = mMainColors[index]; + } else + mMainColors[index] = Color.rgb( + (255 - y) * Color.red(topColors[x]) / 255, + (255 - y) * Color.green(topColors[x]) / 255, + (255 - y) * Color.blue(topColors[x]) / 255); + index++; + } + } + } + + @Override + protected void onDraw(Canvas canvas) { + int translatedHue = 255 - (int) (mCurrentHue * 255 / 360); + // Display all the colors of the hue bar with lines + for (int x = 0; x < 256; x++) { + // If this is not the current selected hue, display the actual + // color + if (translatedHue != x) { + mPaint.setColor(mHueBarColors[x]); + mPaint.setStrokeWidth(1); + } else // else display a slightly larger black line + { + mPaint.setColor(Color.BLACK); + mPaint.setStrokeWidth(3); + } + canvas.drawLine(x + 10, 0, x + 10, 40, mPaint); + // canvas.drawLine(0, x+10, 40, x+10, mPaint); + } + + // Display the main field colors using LinearGradient + for (int x = 0; x < 256; x++) { + int[] colors = new int[2]; + colors[0] = mMainColors[x]; + colors[1] = Color.BLACK; + Shader shader = new LinearGradient(0, 50, 0, 306, colors, null, + Shader.TileMode.REPEAT); + mPaint.setShader(shader); + canvas.drawLine(x + 10, 50, x + 10, 306, mPaint); + } + mPaint.setShader(null); + + // Display the circle around the currently selected color in the + // main field + if (mCurrentX != 0 && mCurrentY != 0) { + mPaint.setStyle(Paint.Style.STROKE); + mPaint.setColor(Color.BLACK); + canvas.drawCircle(mCurrentX, mCurrentY, 10, mPaint); + } + + // Draw a 'button' with the currently selected color + mPaint.setStyle(Paint.Style.FILL); + mPaint.setColor(mCurrentColor); + canvas.drawRect(10, 316, 138, 356, mPaint); + + // Set the text color according to the brightness of the color + if (Color.red(mCurrentColor) + Color.green(mCurrentColor) + + Color.blue(mCurrentColor) < 384) + mPaint.setColor(Color.WHITE); + else + mPaint.setColor(Color.BLACK); + canvas.drawText( + "bg", 74, + 340, mPaint); + + // Draw a 'button' with the default color + mPaint.setStyle(Paint.Style.FILL); + mPaint.setColor(mDefaultColor); + canvas.drawRect(138, 316, 266, 356, mPaint); + + // Set the text color according to the brightness of the color + if (Color.red(mDefaultColor) + Color.green(mDefaultColor) + + Color.blue(mDefaultColor) < 384) + mPaint.setColor(Color.WHITE); + else + mPaint.setColor(Color.BLACK); + canvas.drawText( + "def", 202, 340, + mPaint); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + setMeasuredDimension(276, 366); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + if (event.getAction() != MotionEvent.ACTION_DOWN) + return true; + float x = event.getX(); + float y = event.getY(); + + // If the touch event is located in the hue bar + if (x > 10 && x < 266 && y > 0 && y < 40) { + // Update the main field colors + mCurrentHue = (255 - x) * 360 / 255; + updateMainColors(); + + // Update the current selected color + int transX = mCurrentX - 10; + int transY = mCurrentY - 60; + int index = 256 * (transY - 1) + transX; + if (index > 0 && index < mMainColors.length) + mCurrentColor = mMainColors[256 * (transY - 1) + transX]; + + // Force the redraw of the dialog + invalidate(); + } + + // If the touch event is located in the main field + if (x > 10 && x < 266 && y > 50 && y < 306) { + mCurrentX = (int) x; + mCurrentY = (int) y; + int transX = mCurrentX - 10; + int transY = mCurrentY - 60; + int index = 256 * (transY - 1) + transX; + if (index > 0 && index < mMainColors.length) { + // Update the current color + mCurrentColor = mMainColors[index]; + // Force the redraw of the dialog + invalidate(); + } + } + + // If the touch event is located in the left button, notify the + // listener with the current color + if (x > 10 && x < 138 && y > 316 && y < 356) + mListener.colorChanged("", mCurrentColor); + + // If the touch event is located in the right button, notify the + // listener with the default color + if (x > 138 && x < 266 && y > 316 && y < 356) + mListener.colorChanged("", mDefaultColor); + + return true; + } + } + + public ColorPickerDialog(Context context, OnColorChangedListener listener, + String key, int initialColor, int defaultColor) { + super(context); + + mListener = listener; + mKey = key; + mInitialColor = initialColor; + mDefaultColor = defaultColor; + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + OnColorChangedListener l = new OnColorChangedListener() { + public void colorChanged(String key, int color) { + mListener.colorChanged(mKey, color); + dismiss(); + } + }; + + setContentView(new ColorPickerView(getContext(), l, mInitialColor, + mDefaultColor)); + setTitle("Set LED Color"); + + } +} \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e8/b0b65633ec870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/e8/b0b65633ec870014196aa5e86be5823c new file mode 100644 index 0000000..6c4450b --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/e8/b0b65633ec870014196aa5e86be5823c @@ -0,0 +1,33 @@ +package com.motioncoding.miband.model; + +import java.util.Observable; + +import com.motioncoding.debugging.L; + + +public class MiBand extends Observable { + + public String mBTAddress; + public int mSteps; + public String mName; + public Battery mBattery; + + + + public void setName(String name) { + mName = name; + notifyObservers(); + } + + public void setSteps(int steps) { + mSteps = steps; + notifyObservers(); + } + + public void setBattery(Battery battery) { + mBattery = battery; + L.i(battery.toString()); + notifyObservers(); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/e9/20f5e61ef4870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/e9/20f5e61ef4870014196aa5e86be5823c new file mode 100644 index 0000000..283cb02 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/e9/20f5e61ef4870014196aa5e86be5823c @@ -0,0 +1,204 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Observable; +import java.util.Observer; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity implements Observer { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_CONTROL_POINT = UUID + .fromString("0000ff05-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + // BLUETOOTH + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + private MiBand mMiBand = new MiBand(); + + // UI + private TextView mTVSteps; + private TextView mTVBatteryLevel; + private ProgressBar mLoading; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.addObserver(this); + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + + mTVSteps = (TextView) findViewById(R.id.text_steps); + mTVBatteryLevel = (TextView) findViewById(R.id.text_battery_level); + mLoading = (ProgressBar) findViewById(R.id.laoding); + + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private void setColor(byte r, byte g, byte b) { + BluetoothGattCharacteristic theme = getMiliService() + .getCharacteristic(UUID_CHAR_CONTROL_POINT); + theme.setValue(new byte[] { 14, r, g, b, 0 }); + mGatt.writeCharacteristic(theme); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() + setColor((byte)127, (byte)0, (byte)0); +// request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + switch (state) { + case 0: + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + break; + case 1: + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + break; + case 2: + mMiBand.setName(new String(b)); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_DEVICE_NAME); + break; + case 3: + + break; + } + } + }; + + @Override + public void update(Observable observable, Object data) { + runOnUiThread(new Runnable() { + + @Override + public void run() { + mLoading.setVisibility(View.GONE); + ((LinearLayout) findViewById(R.id.textHolder)) + .setVisibility(View.VISIBLE); + mTVSteps.setText(mMiBand.mSteps + ""); + if (mMiBand.mBattery != null) + mTVBatteryLevel.setText(mMiBand.mBattery.mBatteryLevel + + "%"); + } + }); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/eb/50ab32fae6870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/eb/50ab32fae6870014196aa5e86be5823c new file mode 100644 index 0000000..4e9e1f4 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/eb/50ab32fae6870014196aa5e86be5823c @@ -0,0 +1,131 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; + +public class MiOverviewActivity extends Activity { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_AUTH = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void auth() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_AUTH); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("Auth sent"); + } + + private void requestSteps() { + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_REALTIME_STEPS); + mGatt.readCharacteristic(chrt); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + auth(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + switch (state) { + case 0: + requestSteps(); + break; + } + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(characteristic.getValue())); + switch (state) { + case 0: + System.out.println(characteristic.getIntValue(0, 0)); + break; + } + state++; + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ed/003a3572ec870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/ed/003a3572ec870014196aa5e86be5823c new file mode 100644 index 0000000..f3ec95a --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ed/003a3572ec870014196aa5e86be5823c @@ -0,0 +1,55 @@ +package com.motioncoding.miband.model; + +import java.util.Calendar; + +public class Battery { + public int mBatteryLevel; + public int mCycles; + public Calendar mLastCharged; + public Status mStatus; + + public static Battery fromByte(byte[] b) { + Battery battery = new Battery(); + battery.mBatteryLevel = b[0]; + battery.mStatus = Status.fromByte(b[9]); + battery.mLastCharged = Calendar.getInstance(); + + battery.mLastCharged.set(Calendar.YEAR, b[1]+2000); + battery.mLastCharged.set(Calendar.MONTH, b[2]); + battery.mLastCharged.set(Calendar.DATE, b[3]); + + battery.mLastCharged.set(Calendar.HOUR_OF_DAY, b[4]); + battery.mLastCharged.set(Calendar.MINUTE, b[5]); + battery.mLastCharged.set(Calendar.SECOND, b[6]); + + + + battery.mCycles = 0xffff & (0xff & b[7] | (0xff & b[8]) << 8); + return battery; + } + + @Override + public String toString() { + return String.format("Level: %s \% Cycles: %s State: %s Last Charged: %s", mBatteryLevel, mCycles, mStatus.toString(), mLastCharged.toString()); + } + + static enum Status { + LOW, FULL, CHARGING, NOT_CHARGING; + + public static Status fromByte(byte b) { + switch (b) { + case 1: + return LOW; + case 2: + return CHARGING; + case 3: + return FULL; + case 4: + return NOT_CHARGING; + + default: + return null; + } + } + } +} \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ed/708cb2d1d98700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/ed/708cb2d1d98700141885aa2aa9523af4 new file mode 100644 index 0000000..33f8d6a --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ed/708cb2d1d98700141885aa2aa9523af4 @@ -0,0 +1,7 @@ + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ed/a0d8bd0be18700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/ed/a0d8bd0be18700141885aa2aa9523af4 new file mode 100644 index 0000000..5b97a65 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ed/a0d8bd0be18700141885aa2aa9523af4 @@ -0,0 +1,80 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + for (BluetoothGattService service : gatt.getServices()) { + for (BluetoothGattCharacteristic character : service + .getCharacteristics()) { + } + } + } + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (status == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ee/6030aac3f7870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/ee/6030aac3f7870014196aa5e86be5823c new file mode 100644 index 0000000..2ea5fba --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ee/6030aac3f7870014196aa5e86be5823c @@ -0,0 +1,236 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Observable; +import java.util.Observer; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.motioncoding.debugging.L; +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.LeParams; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity implements Observer { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_CONTROL_POINT = UUID + .fromString("0000ff05-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_LE_PARAMS = UUID + .fromString("0000ff09-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + // BLUETOOTH + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + private MiBand mMiBand = new MiBand(); + + // UI + private TextView mTVSteps; + private TextView mTVBatteryLevel; + private ProgressBar mLoading; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.addObserver(this); + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + + mTVSteps = (TextView) findViewById(R.id.text_steps); + mTVBatteryLevel = (TextView) findViewById(R.id.text_battery_level); + mLoading = (ProgressBar) findViewById(R.id.laoding); + + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.menu_overview, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.action_leparams: + if(mMiBand.mLeParams == null) { + L.toast(this, "No LE params received yet"); + return true; + } + Intent intent = new Intent(getApplicationContext(), MiLeParamsActivity.class); + intent.putExtra("params", mMiBand.mLeParams); + break; + } + return true; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private void setColor(byte r, byte g, byte b) { + BluetoothGattCharacteristic theme = getMiliService().getCharacteristic( + UUID_CHAR_CONTROL_POINT); + theme.setValue(new byte[] { 14, r, g, b, 0 }); + mGatt.writeCharacteristic(theme); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() + // setColor((byte)127, (byte)0, (byte)0); + // request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + + // handle value + if (characteristic.getUuid().equals(UUID_CHAR_REALTIME_STEPS)) + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + else if (characteristic.getUuid().equals(UUID_CHAR_BATTERY)) { + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + } else if (characteristic.getUuid().equals(UUID_CHAR_DEVICE_NAME)) { + mMiBand.setName(new String(b)); + } else if (characteristic.getUuid().equals(UUID_CHAR_LE_PARAMS)) { + LeParams params = LeParams.fromByte(b); + mMiBand.setLeParams(params); + } + + // proceed with state machine (called in the beginning) + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_DEVICE_NAME); + break; + case 3: + request(UUID_CHAR_LE_PARAMS); + break; + } + } + }; + + @Override + public void update(Observable observable, Object data) { + runOnUiThread(new Runnable() { + + @Override + public void run() { + mLoading.setVisibility(View.GONE); + ((LinearLayout) findViewById(R.id.textHolder)) + .setVisibility(View.VISIBLE); + mTVSteps.setText(mMiBand.mSteps + ""); + if (mMiBand.mBattery != null) + mTVBatteryLevel.setText(mMiBand.mBattery.mBatteryLevel + + "%"); + } + }); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ee/c0c44450d78700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/ee/c0c44450d78700141885aa2aa9523af4 new file mode 100644 index 0000000..1e9a337 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ee/c0c44450d78700141885aa2aa9523af4 @@ -0,0 +1,38 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter.LeScanCallback; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.os.Bundle; + +public class MiActivity extends Activity implements LeScanCallback { + + private BluetoothManager bluetoothManager; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_mi); + + bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); + + + public void onResume() { + bluetoothManager.getAdapter().startLeScan(this); + } + + @Override + public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { + if(device != null && device.getName() != null & device.getName().equals("MI")) { + System.out.println(device.getAddress()); + } + bluetoothManager.getAdapter().stopLeScan(this); + } + + public void onPause() { + super.onPause(); + bluetoothManager.getAdapter().stopLeScan(this); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ef/20b441b3dc8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/ef/20b441b3dc8700141885aa2aa9523af4 new file mode 100644 index 0000000..503d725 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ef/20b441b3dc8700141885aa2aa9523af4 @@ -0,0 +1,15 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; + +public class MiOverviewActivity extends Activity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_mi_overview); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ef/d0e3bf06ef870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/ef/d0e3bf06ef870014196aa5e86be5823c new file mode 100644 index 0000000..3e44425 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ef/d0e3bf06ef870014196aa5e86be5823c @@ -0,0 +1,191 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Observable; +import java.util.Observer; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity implements Observer { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_CONTROL_POINT = UUID + .fromString("0000ff05-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + //BLUETOOTH + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + + private MiBand mMiBand = new MiBand(); + + //UI + private TextView mTVSteps; + private TextView mTVBatteryLevel; + private ProgressBar mLoading; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.addObserver(this); + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + + mTVSteps = (TextView) findViewById(R.id.text_steps); + mTVBatteryLevel = (TextView) findViewById(R.id.text_battery_level); + mLoading = (ProgressBar) findViewById(R.id.laoding); + + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() + request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + switch (state) { + case 0: + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + break; + case 1: + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + break; + case 2: + mMiBand.setName(new String(b)); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_DEVICE_NAME); + break; + } + } + }; + + @Override + public void update(Observable observable, Object data) { + runOnUiThread(new Runnable() { + + @Override + public void run() { + mLoading.setVisibility(View.GONE); + ((LinearLayout) findViewById(R.id.textHolder)).setVisibility(View.GONE); + mTVSteps.setText(mMiBand.mSteps+""); + mTVBatteryLevel.setText(mMiBand.mBattery.mBatteryLevel+"%"); + } + }); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/f/30ea5384e5870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/f/30ea5384e5870014196aa5e86be5823c new file mode 100644 index 0000000..b42f462 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/f/30ea5384e5870014196aa5e86be5823c @@ -0,0 +1,110 @@ +package com.motioncoding.miband; + +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_AUTH = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void auth() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_AUTH); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("Auth sent"); + } + + private void requestSteps() { + int steps = getMiliService().getCharacteristic(UUID_CHAR_REALTIME_STEPS).getIntValue(0, 0); + System.out.println(steps); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + auth(); + requestSteps(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/f0/507caf71f9870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/f0/507caf71f9870014196aa5e86be5823c new file mode 100644 index 0000000..e291ff8 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/f0/507caf71f9870014196aa5e86be5823c @@ -0,0 +1,241 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Observable; +import java.util.Observer; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.content.Intent; +import android.graphics.Color; +import android.os.Bundle; +import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.motioncoding.debugging.L; +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.LeParams; +import com.motioncoding.miband.model.MiBand; +import com.motioncoding.miband.view.ColorPickerDialog; + +public class MiOverviewActivity extends Activity implements Observer { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_CONTROL_POINT = UUID + .fromString("0000ff05-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_LE_PARAMS = UUID + .fromString("0000ff09-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + // BLUETOOTH + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + private MiBand mMiBand = new MiBand(); + + // UI + private TextView mTVSteps; + private TextView mTVBatteryLevel; + private ProgressBar mLoading; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.addObserver(this); + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + + mTVSteps = (TextView) findViewById(R.id.text_steps); + mTVBatteryLevel = (TextView) findViewById(R.id.text_battery_level); + mLoading = (ProgressBar) findViewById(R.id.laoding); + + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.menu_overview, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.action_leparams: + if(mMiBand.mLeParams == null) { + L.toast(this, "No LE params received yet"); + return true; + } + Intent intent = new Intent(getApplicationContext(), MiLeParamsActivity.class); + intent.putExtra("params", mMiBand.mLeParams); + startActivity(intent); + break; + case R.id.action_ledcolor: + new ColorPickerDialog(this, null, "", Color.BLUE, Color.RED).show();; + break; + } + return true; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private void setColor(byte r, byte g, byte b) { + BluetoothGattCharacteristic theme = getMiliService().getCharacteristic( + UUID_CHAR_CONTROL_POINT); + theme.setValue(new byte[] { 14, r, g, b, 0 }); + mGatt.writeCharacteristic(theme); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() + // setColor((byte)127, (byte)0, (byte)0); + request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + + // handle value + if (characteristic.getUuid().equals(UUID_CHAR_REALTIME_STEPS)) + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + else if (characteristic.getUuid().equals(UUID_CHAR_BATTERY)) { + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + } else if (characteristic.getUuid().equals(UUID_CHAR_DEVICE_NAME)) { + mMiBand.setName(new String(b)); + } else if (characteristic.getUuid().equals(UUID_CHAR_LE_PARAMS)) { + LeParams params = LeParams.fromByte(b); + mMiBand.setLeParams(params); + } + + // proceed with state machine (called in the beginning) + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_DEVICE_NAME); + break; + case 3: + request(UUID_CHAR_LE_PARAMS); + break; + } + } + }; + + @Override + public void update(Observable observable, Object data) { + runOnUiThread(new Runnable() { + + @Override + public void run() { + mLoading.setVisibility(View.GONE); + ((LinearLayout) findViewById(R.id.textHolder)) + .setVisibility(View.VISIBLE); + mTVSteps.setText(mMiBand.mSteps + ""); + if (mMiBand.mBattery != null) + mTVBatteryLevel.setText(mMiBand.mBattery.mBatteryLevel + + "%"); + } + }); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/f1/b002584ff6870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/f1/b002584ff6870014196aa5e86be5823c new file mode 100644 index 0000000..bebfe58 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/f1/b002584ff6870014196aa5e86be5823c @@ -0,0 +1,15 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.os.Bundle; +import android.view.Menu; +import android.view.MenuItem; + +public class MiLeParamsActivity extends Activity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_mi_le_params); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/f2/209c627be8870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/f2/209c627be8870014196aa5e86be5823c new file mode 100644 index 0000000..071cc7c --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/f2/209c627be8870014196aa5e86be5823c @@ -0,0 +1,33 @@ +package com.motioncoding.miband.model; + +import java.util.Calendar; + +public class Battery { + int mBatteryLevel; + int mCycles; + Calendar mLastCharged; + + public static Battery fromByte(byte[] b) { + return null; + } + + static enum Status { + LOW, FULL, CHARGING, NOT_CHARGING; + + public static Status fromByte(byte b) { + switch (b) { + case 1: + return LOW; + case 2: + return CHARGING; + case 3: + return FULL; + case 4: + return NOT_CHARGING; + + default: + return null; + } + } + } +} \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/f7/60e50729f8870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/f7/60e50729f8870014196aa5e86be5823c new file mode 100644 index 0000000..2a97e03 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/f7/60e50729f8870014196aa5e86be5823c @@ -0,0 +1,235 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Observable; +import java.util.Observer; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.motioncoding.debugging.L; +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.LeParams; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity implements Observer { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_CONTROL_POINT = UUID + .fromString("0000ff05-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_LE_PARAMS = UUID + .fromString("0000ff09-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + // BLUETOOTH + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + private MiBand mMiBand = new MiBand(); + + // UI + private TextView mTVSteps; + private TextView mTVBatteryLevel; + private ProgressBar mLoading; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.addObserver(this); + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + + mTVSteps = (TextView) findViewById(R.id.text_steps); + mTVBatteryLevel = (TextView) findViewById(R.id.text_battery_level); + mLoading = (ProgressBar) findViewById(R.id.laoding); + + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.menu_overview, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.action_leparams: + if(mMiBand.mLeParams == null) { + L.toast(this, "No LE params received yet"); + return true; + } + Intent intent = new Intent(getApplicationContext(), MiLeParamsActivity.class); + intent.putExtra("params", mMiBand.mLeParams); + break; + } + return true; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private void setColor(byte r, byte g, byte b) { + BluetoothGattCharacteristic theme = getMiliService().getCharacteristic( + UUID_CHAR_CONTROL_POINT); + theme.setValue(new byte[] { 14, r, g, b, 0 }); + mGatt.writeCharacteristic(theme); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() + // setColor((byte)127, (byte)0, (byte)0); + // request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + + // handle value + if (characteristic.getUuid().equals(UUID_CHAR_REALTIME_STEPS)) + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + else if (characteristic.getUuid().equals(UUID_CHAR_BATTERY)) { + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + } else if (characteristic.getUuid().equals(UUID_CHAR_DEVICE_NAME)) { + mMiBand.setName(new String(b)); + } else if (characteristic.getUuid().equals(UUID_CHAR_LE_PARAMS)) { + LeParams params = LeParams.fromByte(b); + mMiBand.setLeParams(params); + } + + // proceed with state machine (called in the beginning) + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_DEVICE_NAME); + break; + case 3: + request(UUID_CHAR_LE_PARAMS); + break; + } + } + }; + + @Override + public void update(Observable observable, Object data) { + runOnUiThread(new Runnable() { + + @Override + public void run() { + mLoading.setVisibility(View.GONE); + ((LinearLayout) findViewById(R.id.textHolder)) + .setVisibility(View.VISIBLE); + mTVSteps.setText(mMiBand.mSteps + ""); + if (mMiBand.mBattery != null) + mTVBatteryLevel.setText(mMiBand.mBattery.mBatteryLevel + + "%"); + } + }); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/f7/e045743cde8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/f7/e045743cde8700141885aa2aa9523af4 new file mode 100644 index 0000000..336b358 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/f7/e045743cde8700141885aa2aa9523af4 @@ -0,0 +1,81 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothAdapter.LeScanCallback; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.widget.TextView; + +public class MiActivity extends Activity implements LeScanCallback { + + private BluetoothAdapter mBluetoothAdapter; + private boolean mScanning; + private TextView mTextView; + private Handler mHandler = new Handler(); + // Stops scanning after 10 seconds. + private static final long SCAN_PERIOD = 10000; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + setContentView(R.layout.activity_mi); + mTextView = (TextView) findViewById(R.id.text_search); + mBluetoothAdapter = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)) + .getAdapter(); + } + + @Override + public void onResume() { + super.onResume(); + scanLeDevice(true); + } + + @SuppressWarnings("deprecation") + // L Apis are buggy and crap! + private void scanLeDevice(final boolean enable) { + if (enable) { + // Stops scanning after a pre-defined scan period. + mHandler.postDelayed(new Runnable() { + + @Override + public void run() { + mScanning = false; + mBluetoothAdapter.stopLeScan(MiActivity.this); + mTextView.setText(R.string.not_found); + } + }, SCAN_PERIOD); + + mScanning = true; + mBluetoothAdapter.startLeScan(this); + } else { + mScanning = false; + mBluetoothAdapter.stopLeScan(this); + } + } + + @Override + public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { + System.out.println(device.getName() + " " + device.getAddress()); + if (device != null && device.getName() != null + & device.getName().equals("MI")) { + System.out.println(device.getAddress()); + scanLeDevice(false); // we only care about one miband so that's + // enough + Intent intent = new Intent(getApplicationContext(), MiOverviewActivity.class); + intent.putExtra("address", device.getAddress()); + startActivity(intent); + } + } + + @Override + public void onPause() { + super.onPause(); + scanLeDevice(false); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/f9/30c53e80e7870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/f9/30c53e80e7870014196aa5e86be5823c new file mode 100644 index 0000000..5c0d5ad --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/f9/30c53e80e7870014196aa5e86be5823c @@ -0,0 +1,135 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; + +public class MiOverviewActivity extends Activity { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_AUTH = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void auth() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_AUTH); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("Auth sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + auth(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after auth() + request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(characteristic.getValue())); + switch (state) { + case 0: + System.out.println(characteristic.getIntValue(0, 0)); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + } + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/fa/20ca1b6bf8870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/fa/20ca1b6bf8870014196aa5e86be5823c new file mode 100644 index 0000000..6eadaf4 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/fa/20ca1b6bf8870014196aa5e86be5823c @@ -0,0 +1,34 @@ +package com.motioncoding.miband; + +import android.app.ListActivity; +import android.os.Bundle; +import android.widget.ArrayAdapter; + +import com.motioncoding.miband.model.LeParams; + +public class MiLeParamsActivity extends ListActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + setContentView(R.layout.activity_mi_le_params); + + LeParams params = (LeParams) getIntent().getParcelableExtra("params"); + + String[] values = new String[6]; + + values[0] = String.format("Connection Intervall\n %s ms", params.connInt); + values[1] = String.format("Connection Intervall Min\n %s ms", params.connIntMin); + values[2] = String.format("Connection Intervall Max\n %s ms", params.connIntMax); + + values[3] = String.format("Advertising Intervall\n %s ms", params.advInt); + values[4] = String.format("Latency\n %s ms", params.latency); + values[5] = String.format("Timeout\n %s ms", params.timeout); + + + ArrayAdapter adapter = new ArrayAdapter(this, + android.R.layout.simple_list_item_1, values); + this.setListAdapter(adapter); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/fa/602842a9f5870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/fa/602842a9f5870014196aa5e86be5823c new file mode 100644 index 0000000..640144b --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/fa/602842a9f5870014196aa5e86be5823c @@ -0,0 +1,207 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Observable; +import java.util.Observer; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.LeParams; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity implements Observer { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_CONTROL_POINT = UUID + .fromString("0000ff05-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_LE_PARAMS = UUID + .fromString("0000ff09-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + // BLUETOOTH + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + private MiBand mMiBand = new MiBand(); + + // UI + private TextView mTVSteps; + private TextView mTVBatteryLevel; + private ProgressBar mLoading; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.addObserver(this); + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + + mTVSteps = (TextView) findViewById(R.id.text_steps); + mTVBatteryLevel = (TextView) findViewById(R.id.text_battery_level); + mLoading = (ProgressBar) findViewById(R.id.laoding); + + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private void setColor(byte r, byte g, byte b) { + BluetoothGattCharacteristic theme = getMiliService() + .getCharacteristic(UUID_CHAR_CONTROL_POINT); + theme.setValue(new byte[] { 14, r, g, b, 0 }); + mGatt.writeCharacteristic(theme); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() +// setColor((byte)127, (byte)0, (byte)0); +// request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + if(characteristic.getUuid().equals(UUID_CHAR_REALTIME_STEPS)) + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + else if(characteristic.getUuid().equals(UUID_CHAR_BATTERY)) { + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + } else if(characteristic.getUuid().equals(UUID_CHAR_DEVICE_NAME)) { + mMiBand.setName(new String(b)); + } else if(characteristic.getUuid().equals(UUID_CHAR_)) { + LeParams params = LeParams.fromByte(b); + mMiBand.setLeParams(params); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_DEVICE_NAME); + break; + case 3: + request(UUID_LE_PARAMS); + break; + } + } + }; + + @Override + public void update(Observable observable, Object data) { + runOnUiThread(new Runnable() { + + @Override + public void run() { + mLoading.setVisibility(View.GONE); + ((LinearLayout) findViewById(R.id.textHolder)) + .setVisibility(View.VISIBLE); + mTVSteps.setText(mMiBand.mSteps + ""); + if (mMiBand.mBattery != null) + mTVBatteryLevel.setText(mMiBand.mBattery.mBatteryLevel + + "%"); + } + }); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/fa/60457be2d98700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/fa/60457be2d98700141885aa2aa9523af4 new file mode 100644 index 0000000..3e61a52 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/fa/60457be2d98700141885aa2aa9523af4 @@ -0,0 +1,12 @@ + + + + + + diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/fb/f0272abadb8700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/fb/f0272abadb8700141885aa2aa9523af4 new file mode 100644 index 0000000..b8aded1 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/fb/f0272abadb8700141885aa2aa9523af4 @@ -0,0 +1,74 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothAdapter.LeScanCallback; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.os.Bundle; +import android.os.Handler; + +public class MiActivity extends Activity implements LeScanCallback { + + private BluetoothAdapter mBluetoothAdapter; + private boolean mScanning; + private Handler mHandler = new Handler(); + // Stops scanning after 10 seconds. + private static final long SCAN_PERIOD = 10000; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + + + setContentView(R.layout.activity_mi); + mBluetoothAdapter = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)).getAdapter(); + } + + @Override + public void onResume() { + super.onResume(); + scanLeDevice(true); + } + + + + @SuppressWarnings("deprecation") // L Apis are buggy and crap! + private void scanLeDevice(final boolean enable) { + if (enable) { + // Stops scanning after a pre-defined scan period. + mHandler.postDelayed(new Runnable() { + + @Override + public void run() { + mScanning = false; + mBluetoothAdapter.stopLeScan(MiActivity.this); + scanLeDevice(true); + } + }, SCAN_PERIOD); + + mScanning = true; + mBluetoothAdapter.startLeScan(this); + } else { + mScanning = false; + mBluetoothAdapter.stopLeScan(this); + } + } + + @Override + public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { + System.out.println(device.getName()+" "+device.getAddress()); + if(device != null && device.getName() != null & device.getName().equals("MI")) { + System.out.println(device.getAddress()); + scanLeDevice(false); // we only care about one miband so that's enough + } + } + + @Override + public void onPause() { + super.onPause(); + scanLeDevice(false); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/fc/905f8b26eb870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/fc/905f8b26eb870014196aa5e86be5823c new file mode 100644 index 0000000..eee7c6d --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/fc/905f8b26eb870014196aa5e86be5823c @@ -0,0 +1,156 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; + +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + private MiBand mMiBand = new MiBand(); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() + request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + switch (state) { + case 0: + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + break; + case 1: + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_ACTIVITY); + break; + case 3: + request(UUID_CHAR_DEVICE_NAME); + break; + } + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/fd/804e2405ea870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/fd/804e2405ea870014196aa5e86be5823c new file mode 100644 index 0000000..135fa4c --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/fd/804e2405ea870014196aa5e86be5823c @@ -0,0 +1,19 @@ +package com.motioncoding.miband.model; + + +public class MiBand { + + public String mBTAddress; + public int mSteps; + public Battery mBattery; + + + public void setSteps(int steps) { + mSteps = steps; + } + + public void setBattery(Battery battery) { + mBattery = battery; + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/fd/e0907d58d78700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/fd/e0907d58d78700141885aa2aa9523af4 new file mode 100644 index 0000000..0662f28 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/fd/e0907d58d78700141885aa2aa9523af4 @@ -0,0 +1,37 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter.LeScanCallback; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.os.Bundle; + +public class MiActivity extends Activity implements LeScanCallback { + + private BluetoothManager bluetoothManager; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_mi); + bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); + } + + public void onResume() { + bluetoothManager.getAdapter().startLeScan(this); + } + + @Override + public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { + if(device != null && device.getName() != null & device.getName().equals("MI")) { + System.out.println(device.getAddress()); + } + bluetoothManager.getAdapter().stopLeScan(this); + } + + public void onPause() { + super.onPause(); + bluetoothManager.getAdapter().stopLeScan(this); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ff/20983376e9870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/ff/20983376e9870014196aa5e86be5823c new file mode 100644 index 0000000..d875c68 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ff/20983376e9870014196aa5e86be5823c @@ -0,0 +1,154 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; +import android.util.Log; + +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.MiBand; + +public class MiOverviewActivity extends Activity { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_AUTH = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + private MiBand mMiBand = new MiBand(); + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void auth() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_AUTH); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("Auth sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + auth(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after auth() + request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(characteristic.getValue())); + switch (state) { + case 0: + System.out.println(characteristic.getIntValue(0, 0)); + break; + case 1: + Battery bat = Battery.fromByte(characteristic.getValue()); + break; + } + + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_ACTIVITY); + break; + case 3: + request(UUID_CHAR_DEVICE_NAME); + break; + } + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ff/20ae37ede4870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/ff/20ae37ede4870014196aa5e86be5823c new file mode 100644 index 0000000..08f999e --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ff/20ae37ede4870014196aa5e86be5823c @@ -0,0 +1,99 @@ +package com.motioncoding.miband; + +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.os.Bundle; + +public class MiOverviewActivity extends Activity { + + private static final UUID UUID_MILI_SERVICE = UUID.fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_AUTH =UUID.fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mMiBand; + private BluetoothGatt mGatt; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + mDeviceAddress = getIntent().getStringExtra("address"); + setContentView(R.layout.activity_mi_overview); + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mMiBand = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mMiBand.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + private void auth() { + BluetoothGattService service = mGatt.getService(UUID_MILI_SERVICE); + BluetoothGattCharacteristic chrt = service.getCharacteristic(UUID_CHAR_AUTH); + + chrt.setValue(new byte[] {2}); + + mGatt.writeCharacteristic(chrt); + System.out.println("Auth sent"); + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + for (BluetoothGattService srvs : gatt.getServices()) { + System.out.println("Service: "+srvs.getUuid()); + for (BluetoothGattCharacteristic chrt : srvs + .getCharacteristics()) { + System.out.println("Characteristic: "+chrt.getUuid()+" with "+chrt.getProperties()); + } + } + } + + auth(); + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + } + }; + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ff/303eea10d88700141885aa2aa9523af4 b/.metadata/.plugins/org.eclipse.core.resources/.history/ff/303eea10d88700141885aa2aa9523af4 new file mode 100644 index 0000000..e8f52a9 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ff/303eea10d88700141885aa2aa9523af4 @@ -0,0 +1,69 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothAdapter.LeScanCallback; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.os.Bundle; +import android.os.Handler; + +public class MiActivity extends Activity implements LeScanCallback { + + private BluetoothManager bluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private boolean mScanning; + private Handler mHandler; + // Stops scanning after 10 seconds. + private static final long SCAN_PERIOD = 10000; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_mi); + bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); + } + + @Override + public void onResume() { + super.onResume(); + scanLeDevice(true); + } + + + + + private void scanLeDevice(final boolean enable) { + if (enable) { + // Stops scanning after a pre-defined scan period. + mHandler.postDelayed(new Runnable() { + @Override + public void run() { + mScanning = false; + mBluetoothAdapter.stopLeScan(MiActivity.this); + } + }, SCAN_PERIOD); + + mScanning = true; + mBluetoothAdapter.startLeScan(this); + } else { + mScanning = false; + mBluetoothAdapter.stopLeScan(this); + } + } + + @Override + public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { + if(device != null && device.getName() != null & device.getName().equals("MI")) { + System.out.println(device.getAddress()); + scanLeDevice(false); // we only care about one miband so that's enough + } + } + + @Override + public void onPause() { + super.onPause(); + scanLeDevice(false); + } +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.history/ff/508a085ff5870014196aa5e86be5823c b/.metadata/.plugins/org.eclipse.core.resources/.history/ff/508a085ff5870014196aa5e86be5823c new file mode 100644 index 0000000..08ccb90 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.history/ff/508a085ff5870014196aa5e86be5823c @@ -0,0 +1,39 @@ +package com.motioncoding.miband.model; + +import java.util.Observable; + +import com.motioncoding.debugging.L; + + +public class MiBand extends Observable { + + public String mBTAddress; + public int mSteps; + public String mName; + public Battery mBattery; + public LeParams mLeParams; + + + + public void setName(String name) { + mName = name; + L.i("setting "+name+" as BLE name"); + setChanged(); + notifyObservers(); + } + + public void setSteps(int steps) { + mSteps = steps; + L.i("setting "+steps+" steps"); + setChanged(); + notifyObservers(); + } + + public void setBattery(Battery battery) { + mBattery = battery; + L.i(battery.toString()); + setChanged(); + notifyObservers(); + } + +} diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/.org.eclipse.jdt.core.external.folders/.location b/.metadata/.plugins/org.eclipse.core.resources/.projects/.org.eclipse.jdt.core.external.folders/.location new file mode 100644 index 0000000..0b0aba6 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.projects/.org.eclipse.jdt.core.external.folders/.location differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/.org.eclipse.jdt.core.external.folders/.markers.snap b/.metadata/.plugins/org.eclipse.core.resources/.projects/.org.eclipse.jdt.core.external.folders/.markers.snap new file mode 100644 index 0000000..533f00e Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.projects/.org.eclipse.jdt.core.external.folders/.markers.snap differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/.org.eclipse.jdt.core.external.folders/.syncinfo.snap b/.metadata/.plugins/org.eclipse.core.resources/.projects/.org.eclipse.jdt.core.external.folders/.syncinfo.snap new file mode 100644 index 0000000..533f00e Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.projects/.org.eclipse.jdt.core.external.folders/.syncinfo.snap differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/a0/4/history.index b/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/a0/4/history.index new file mode 100644 index 0000000..b655702 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/a0/4/history.index differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/a0/5f/history.index b/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/a0/5f/history.index new file mode 100644 index 0000000..db6c4a8 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/a0/5f/history.index differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/a0/5f/properties.index b/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/a0/5f/properties.index new file mode 100644 index 0000000..c7f0dbd Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/a0/5f/properties.index differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/a0/d6/history.index b/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/a0/d6/history.index new file mode 100644 index 0000000..c45bcad Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/a0/d6/history.index differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/a0/d6/properties.index b/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/a0/d6/properties.index new file mode 100644 index 0000000..774ddb7 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/a0/d6/properties.index differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/a0/de/history.index b/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/a0/de/history.index new file mode 100644 index 0000000..1fd8f42 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/a0/de/history.index differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/a0/de/properties.index b/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/a0/de/properties.index new file mode 100644 index 0000000..d523e7c Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/a0/de/properties.index differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/a0/eb/history.index b/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/a0/eb/history.index new file mode 100644 index 0000000..c254945 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/a0/eb/history.index differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/a0/ee/history.index b/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/a0/ee/history.index new file mode 100644 index 0000000..99ceeab Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/a0/ee/history.index differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/af/history.index b/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/af/history.index new file mode 100644 index 0000000..f662492 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/af/history.index differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/e4/81/60/12/history.index b/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/e4/81/60/12/history.index new file mode 100644 index 0000000..c58ebc2 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/e4/81/60/12/history.index differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/e4/81/60/2f/29/history.index b/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/e4/81/60/2f/29/history.index new file mode 100644 index 0000000..d9db43c Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/e4/81/60/2f/29/history.index differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/e4/81/60/2f/a5/history.index b/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/e4/81/60/2f/a5/history.index new file mode 100644 index 0000000..84d4cbb Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/e4/81/60/2f/a5/history.index differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/e4/81/60/2f/history.index b/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/e4/81/60/2f/history.index new file mode 100644 index 0000000..ab05ff1 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/e4/81/60/2f/history.index differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/history.index b/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/history.index new file mode 100644 index 0000000..7abe705 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/history.index differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/properties.index b/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/properties.index new file mode 100644 index 0000000..c5b057f Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.indexes/properties.index differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.markers b/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.markers new file mode 100644 index 0000000..11dd007 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.markers differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.markers.snap b/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.markers.snap new file mode 100644 index 0000000..f351dc2 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.markers.snap differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.syncinfo.snap b/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.syncinfo.snap new file mode 100644 index 0000000..533f00e Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.projects/MiBand/.syncinfo.snap differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/history.version b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/history.version new file mode 100644 index 0000000..25cb955 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/history.version @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.index b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.index new file mode 100644 index 0000000..2b38052 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.index differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.version b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.version new file mode 100644 index 0000000..6b2aaa7 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.resources/.root/.indexes/properties.version @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.core.resources/.root/.markers.snap b/.metadata/.plugins/org.eclipse.core.resources/.root/.markers.snap new file mode 100644 index 0000000..fd32ba1 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.root/.markers.snap differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.root/2.tree b/.metadata/.plugins/org.eclipse.core.resources/.root/2.tree new file mode 100644 index 0000000..093363b Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.root/2.tree differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources b/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources new file mode 100644 index 0000000..27773f9 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/.safetable/org.eclipse.core.resources differ diff --git a/.metadata/.plugins/org.eclipse.core.resources/2.snap b/.metadata/.plugins/org.eclipse.core.resources/2.snap new file mode 100644 index 0000000..df12401 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.core.resources/2.snap differ diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.android.ide.eclipse.adt.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.android.ide.eclipse.adt.prefs new file mode 100644 index 0000000..15d93cc --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.android.ide.eclipse.adt.prefs @@ -0,0 +1,4 @@ +com.android.ide.eclipse.adt.fixLegacyEditors=1 +com.android.ide.eclipse.adt.sdk=/Applications/adt-bundle-mac-x86_64-20140624/sdk +com.android.ide.eclipse.adt.xmlEditor=true +eclipse.preferences.version=1 diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.android.ide.eclipse.ddms.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.android.ide.eclipse.ddms.prefs new file mode 100644 index 0000000..a1647e4 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/com.android.ide.eclipse.ddms.prefs @@ -0,0 +1,10 @@ +ddms.logcat.auotmonitor.level=error +ddms.logcat.automonitor.userprompt=true +eclipse.preferences.version=1 +logcat.view.colsize.Application=133 +logcat.view.colsize.Level=18 +logcat.view.colsize.PID=44 +logcat.view.colsize.TID=44 +logcat.view.colsize.Tag=98 +logcat.view.colsize.Text=541 +logcat.view.colsize.Time=131 diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.cdt.debug.core.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.cdt.debug.core.prefs new file mode 100644 index 0000000..b8c9267 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.cdt.debug.core.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +org.eclipse.cdt.debug.core.cDebug.default_source_containers=\n\n\n\n\n\n\n\n diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.cdt.ui.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.cdt.ui.prefs new file mode 100644 index 0000000..5e2da66 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.cdt.ui.prefs @@ -0,0 +1,4 @@ +eclipse.preferences.version=1 +spelling_locale_initialized=true +useAnnotationsPrefPage=true +useQuickDiffPrefPage=true diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.core.resources.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.core.resources.prefs new file mode 100644 index 0000000..dffc6b5 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.core.resources.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +version=1 diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.debug.core.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.debug.core.prefs new file mode 100644 index 0000000..03da32b --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.debug.core.prefs @@ -0,0 +1,4 @@ +//org.eclipse.debug.core.PREFERRED_DELEGATES/org.eclipse.cdt.launch.applicationLaunchType=org.eclipse.cdt.dsf.gdb.launch.localCLaunch,debug,;org.eclipse.cdt.cdi.launch.localCLaunch,run,; +//org.eclipse.debug.core.PREFERRED_DELEGATES/org.eclipse.cdt.launch.attachLaunchType=org.eclipse.cdt.dsf.gdb.launch.attachCLaunch,debug,; +//org.eclipse.debug.core.PREFERRED_DELEGATES/org.eclipse.cdt.launch.postmortemLaunchType=org.eclipse.cdt.dsf.gdb.launch.coreCLaunch,debug,; +eclipse.preferences.version=1 diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.debug.ui.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.debug.ui.prefs new file mode 100644 index 0000000..e2e6b29 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.debug.ui.prefs @@ -0,0 +1,7 @@ +eclipse.preferences.version=1 +org.eclipse.debug.ui.PREF_LAUNCH_PERSPECTIVES=\n\n +org.eclipse.debug.ui.switch_perspective_on_suspend=always +pref_state_memento.org.eclipse.debug.ui.BreakpointView=\n\n\n\n\n +pref_state_memento.org.eclipse.debug.ui.VariableView=\n\n\n +preferredDetailPanes=org.eclipse.jdt.debug.ui.DETAIL_PANE_LINE_BREAKPOINT\:org.eclipse.jdt.debug.ui.DETAIL_PANE_LINE_BREAKPOINT|DefaultDetailPane\:DefaultDetailPane| +preferredTargets=default\:default| diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.core.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..3315632 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,12 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.builder.resourceCopyExclusionFilter= +org.eclipse.jdt.core.classpathVariable.JRE_LIB=/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/jre/lib/rt.jar +org.eclipse.jdt.core.classpathVariable.JRE_SRC=/Library/Java/JavaVirtualMachines/jdk1.8.0_20.jdk/Contents/Home/src.zip +org.eclipse.jdt.core.classpathVariable.JRE_SRCROOT=src +org.eclipse.jdt.core.codeComplete.visibilityCheck=enabled +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 +org.eclipse.jdt.core.compiler.compliance=1.8 +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.8 diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.launching.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.launching.prefs new file mode 100644 index 0000000..25e673f --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.launching.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.launching.PREF_VM_XML=\n\n\n\n\n\n\n\n\n\n diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.ui.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.ui.prefs new file mode 100644 index 0000000..00773a0 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.jdt.ui.prefs @@ -0,0 +1,20 @@ +content_assist_disabled_computers=org.eclipse.jdt.ui.textProposalCategory\u0000org.eclipse.recommenders.calls.rcp.proposalCategory.templates\u0000org.eclipse.mylyn.java.ui.javaAllProposalCategory\u0000org.eclipse.jdt.ui.javaAllProposalCategory\u0000org.eclipse.jdt.ui.javaTypeProposalCategory\u0000org.eclipse.jdt.ui.javaNoTypeProposalCategory\u0000org.eclipse.recommenders.chain.rcp.proposalCategory.chain\u0000 +content_assist_lru_history= +content_assist_number_of_computers=19 +content_assist_proposals_background=255,255,255 +content_assist_proposals_foreground=0,0,0 +eclipse.preferences.version=1 +fontPropagated=true +org.eclipse.jdt.ui.editor.tab.width= +org.eclipse.jdt.ui.formatterprofiles.version=12 +org.eclipse.jdt.ui.javadoclocations.migrated=true +org.eclipse.jdt.ui.text.code_templates_migrated=true +org.eclipse.jdt.ui.text.custom_code_templates= +org.eclipse.jdt.ui.text.custom_templates= +org.eclipse.jdt.ui.text.templates_migrated=true +org.eclipse.jface.textfont=1|Monaco|11.0|0|COCOA|1|; +proposalOrderMigrated=true +spelling_locale_initialized=true +tabWidthPropagated=true +useAnnotationsPrefPage=true +useQuickDiffPrefPage=true diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.m2e.discovery.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.m2e.discovery.prefs new file mode 100644 index 0000000..67b1d96 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.m2e.discovery.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +org.eclipse.m2e.discovery.pref.projects= diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.mylyn.context.core.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.mylyn.context.core.prefs new file mode 100644 index 0000000..43e97e4 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.mylyn.context.core.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +mylyn.attention.migrated=true diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.mylyn.java.ui.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.mylyn.java.ui.prefs new file mode 100644 index 0000000..2a6fe50 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.mylyn.java.ui.prefs @@ -0,0 +1,3 @@ +eclipse.preferences.version=1 +org.eclipse.mylyn.java.ui.run.count.3_10_0=1 +org.eclipse.mylyn.java.ui.run.count.3_1_0=1 diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.mylyn.monitor.ui.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.mylyn.monitor.ui.prefs new file mode 100644 index 0000000..8d462a6 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.mylyn.monitor.ui.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +org.eclipse.mylyn.monitor.activity.tracking.enabled.checked=true diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.mylyn.tasks.ui.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.mylyn.tasks.ui.prefs new file mode 100644 index 0000000..5330e43 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.mylyn.tasks.ui.prefs @@ -0,0 +1,4 @@ +eclipse.preferences.version=1 +migrated.task.repositories.secure.store=true +org.eclipse.mylyn.tasks.ui.filters.nonmatching=true +org.eclipse.mylyn.tasks.ui.filters.nonmatching.encouraged=true diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.recommenders.completion.rcp.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.recommenders.completion.rcp.prefs new file mode 100644 index 0000000..d81163d --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.recommenders.completion.rcp.prefs @@ -0,0 +1,2 @@ +completion_tips_seen=org.eclipse.recommenders.completion.rcp.tips.discovery\:org.eclipse.recommenders.subwords.rcp.tips.enableSubwords +eclipse.preferences.version=1 diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.team.cvs.ui.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.team.cvs.ui.prefs new file mode 100644 index 0000000..f9e585b --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.team.cvs.ui.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +pref_first_startup=false diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.team.ui.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.team.ui.prefs new file mode 100644 index 0000000..56cd496 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.team.ui.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +org.eclipse.team.ui.first_time=false diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.editors.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.editors.prefs new file mode 100644 index 0000000..61f3bb8 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.editors.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +overviewRuler_migration=migrated_3.1 diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs new file mode 100644 index 0000000..e786736 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.ide.prefs @@ -0,0 +1,7 @@ +IMPORT_FILES_AND_FOLDERS_RELATIVE=true +IMPORT_FILES_AND_FOLDERS_TYPE=23,1 +PROBLEMS_FILTERS_MIGRATE=true +eclipse.preferences.version=1 +platformState=1413155649259 +quickStart=false +tipsAndTricks=true diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.prefs new file mode 100644 index 0000000..08076f2 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.prefs @@ -0,0 +1,2 @@ +eclipse.preferences.version=1 +showIntro=false diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.workbench.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.workbench.prefs new file mode 100644 index 0000000..15acb8a --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.ui.workbench.prefs @@ -0,0 +1,3 @@ +ENABLED_DECORATORS=org.eclipse.m2e.core.mavenVersionDecorator\:false,com.android.ide.eclipse.adt.project.FolderDecorator\:true,org.eclipse.cdt.ui.indexedFiles\:false,org.eclipse.cdt.managedbuilder.ui.excludedFile\:true,org.eclipse.cdt.managedbuilder.ui.includeFolder\:true,org.eclipse.cdt.internal.ui.CustomBuildSettingsDecorator\:true,org.eclipse.egit.ui.internal.decorators.GitLightweightDecorator\:true,org.eclipse.jdt.ui.override.decorator\:true,org.eclipse.jdt.ui.interface.decorator\:false,org.eclipse.jdt.ui.buildpath.decorator\:true,org.eclipse.m2e.core.maven2decorator\:true,org.eclipse.mylyn.context.ui.decorator.interest\:true,org.eclipse.mylyn.tasks.ui.decorators.task\:true,org.eclipse.mylyn.team.ui.changeset.decorator\:true,org.eclipse.team.cvs.ui.decorator\:true,org.eclipse.ui.LinkedResourceDecorator\:true,org.eclipse.ui.SymlinkDecorator\:true,org.eclipse.ui.VirtualResourceDecorator\:true,org.eclipse.ui.ContentTypeDecorator\:true,org.eclipse.ui.ResourceFilterDecorator\:false, +PLUGINS_NOT_ACTIVATED_ON_STARTUP=org.eclipse.m2e.discovery; +eclipse.preferences.version=1 diff --git a/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.wst.sse.ui.prefs b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.wst.sse.ui.prefs new file mode 100644 index 0000000..4fd0cd3 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.core.runtime/.settings/org.eclipse.wst.sse.ui.prefs @@ -0,0 +1,4 @@ +content_assist_number_of_computers=2 +eclipse.preferences.version=1 +useAnnotationsPrefPage=true +useQuickDiffPrefPage=true diff --git a/.metadata/.plugins/org.eclipse.debug.core/.launches/MiBand.launch b/.metadata/.plugins/org.eclipse.debug.core/.launches/MiBand.launch new file mode 100644 index 0000000..6fb6c68 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.debug.core/.launches/MiBand.launch @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.debug.ui/launchConfigurationHistory.xml b/.metadata/.plugins/org.eclipse.debug.ui/launchConfigurationHistory.xml new file mode 100644 index 0000000..32e893c --- /dev/null +++ b/.metadata/.plugins/org.eclipse.debug.ui/launchConfigurationHistory.xml @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi b/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi new file mode 100644 index 0000000..fe3eb4b --- /dev/null +++ b/.metadata/.plugins/org.eclipse.e4.workbench/workbench.xmi @@ -0,0 +1,3202 @@ + + + + activeSchemeId:org.eclipse.ui.defaultAcceleratorConfiguration + ModelMigrationProcessor.001 + + + + + + topLevel + shellMaximized + + + + + persp.actionSet:org.eclipse.mylyn.doc.actionSet + persp.actionSet:org.eclipse.mylyn.tasks.ui.navigation + persp.actionSet:org.eclipse.ui.cheatsheets.actionSet + persp.actionSet:org.eclipse.search.searchActionSet + persp.actionSet:org.eclipse.ui.edit.text.actionSet.annotationNavigation + persp.actionSet:org.eclipse.ui.edit.text.actionSet.navigation + persp.actionSet:org.eclipse.ui.edit.text.actionSet.convertLineDelimitersTo + persp.actionSet:org.eclipse.ui.externaltools.ExternalToolsSet + persp.actionSet:org.eclipse.ui.actionSet.keyBindings + persp.actionSet:org.eclipse.ui.actionSet.openFiles + persp.actionSet:org.eclipse.wb.core.ui.actionset + persp.actionSet:org.eclipse.debug.ui.launchActionSet + persp.actionSet:org.eclipse.jdt.ui.JavaActionSet + persp.actionSet:org.eclipse.jdt.ui.JavaElementCreationActionSet + persp.actionSet:org.eclipse.ui.NavigateActionSet + persp.viewSC:org.eclipse.jdt.ui.PackageExplorer + persp.viewSC:org.eclipse.jdt.ui.TypeHierarchy + persp.viewSC:org.eclipse.jdt.ui.SourceView + persp.viewSC:org.eclipse.jdt.ui.JavadocView + persp.viewSC:org.eclipse.search.ui.views.SearchView + persp.viewSC:org.eclipse.ui.console.ConsoleView + persp.viewSC:org.eclipse.ui.views.ContentOutline + persp.viewSC:org.eclipse.ui.views.ProblemView + persp.viewSC:org.eclipse.ui.views.ResourceNavigator + persp.viewSC:org.eclipse.ui.views.TaskList + persp.viewSC:org.eclipse.ui.views.ProgressView + persp.viewSC:org.eclipse.ui.navigator.ProjectExplorer + persp.viewSC:org.eclipse.ui.texteditor.TemplatesView + persp.viewSC:org.eclipse.pde.runtime.LogView + persp.newWizSC:org.eclipse.jdt.ui.wizards.JavaProjectWizard + persp.newWizSC:org.eclipse.jdt.ui.wizards.NewPackageCreationWizard + persp.newWizSC:org.eclipse.jdt.ui.wizards.NewClassCreationWizard + persp.newWizSC:org.eclipse.jdt.ui.wizards.NewInterfaceCreationWizard + persp.newWizSC:org.eclipse.jdt.ui.wizards.NewEnumCreationWizard + persp.newWizSC:org.eclipse.jdt.ui.wizards.NewAnnotationCreationWizard + persp.newWizSC:org.eclipse.jdt.ui.wizards.NewSourceFolderCreationWizard + persp.newWizSC:org.eclipse.jdt.ui.wizards.NewSnippetFileCreationWizard + persp.newWizSC:org.eclipse.jdt.ui.wizards.NewJavaWorkingSetWizard + persp.newWizSC:org.eclipse.ui.wizards.new.folder + persp.newWizSC:org.eclipse.ui.wizards.new.file + persp.newWizSC:org.eclipse.ui.editors.wizards.UntitledTextFileWizard + persp.perspSC:org.eclipse.jdt.ui.JavaBrowsingPerspective + persp.perspSC:org.eclipse.debug.ui.DebugPerspective + persp.newWizSC:com.android.ide.eclipse.adt.project.NewProjectWizard + persp.newWizSC:com.android.ide.eclipse.editors.wizards.NewXmlFileWizard + persp.actionSet:adt.actionSet.wizards + persp.actionSet:adt.actionSet.avdManager + persp.actionSet:adt.actionSet.lint + persp.actionSet:adt.actionSet.refactorings + persp.perspSC:com.android.ide.eclipse.ddms.Perspective + persp.perspSC:com.android.ide.eclipse.hierarchyviewer.PixelPerfectPespective + persp.perspSC:com.android.ide.eclipse.hierarchyviewer.TreeViewPerspective + persp.viewSC:org.eclipse.ant.ui.views.AntView + persp.showIn:org.eclipse.egit.ui.RepositoriesView + persp.actionSet:org.eclipse.debug.ui.breakpointActionSet + persp.actionSet:org.eclipse.jdt.debug.ui.JDTDebugActionSet + persp.newWizSC:org.eclipse.jdt.junit.wizards.NewTestCaseCreationWizard + persp.actionSet:org.eclipse.jdt.junit.JUnitActionSet + persp.showIn:org.eclipse.jdt.ui.PackageExplorer + persp.showIn:org.eclipse.team.ui.GenericHistoryView + persp.showIn:org.eclipse.ui.views.ResourceNavigator + persp.showIn:org.eclipse.ui.navigator.ProjectExplorer + persp.viewSC:org.eclipse.mylyn.tasks.ui.views.tasks + persp.newWizSC:org.eclipse.mylyn.tasks.ui.wizards.new.repository.task + persp.viewSC:org.eclipse.wb.core.StructureView + persp.viewSC:org.eclipse.wb.core.PaletteView + + + + newtablook + org.eclipse.e4.primaryNavigationStack + active + noFocus + + + + + + + + + + newtablook + + + + + + + + + newtablook + + + + newtablook + org.eclipse.e4.secondaryNavigationStack + + + + + + + + newtablook + org.eclipse.e4.secondaryDataStack + + + + + + + + + + + + + + + persp.actionSet:org.eclipse.mylyn.doc.actionSet + persp.actionSet:org.eclipse.mylyn.tasks.ui.navigation + persp.actionSet:org.eclipse.ui.cheatsheets.actionSet + persp.actionSet:org.eclipse.search.searchActionSet + persp.actionSet:org.eclipse.ui.edit.text.actionSet.annotationNavigation + persp.actionSet:org.eclipse.ui.edit.text.actionSet.navigation + persp.actionSet:org.eclipse.ui.edit.text.actionSet.convertLineDelimitersTo + persp.actionSet:org.eclipse.ui.externaltools.ExternalToolsSet + persp.actionSet:org.eclipse.ui.actionSet.keyBindings + persp.actionSet:org.eclipse.ui.actionSet.openFiles + persp.actionSet:org.eclipse.wb.core.ui.actionset + persp.actionSet:org.eclipse.debug.ui.launchActionSet + persp.actionSet:org.eclipse.debug.ui.debugActionSet + persp.viewSC:org.eclipse.debug.ui.DebugView + persp.viewSC:org.eclipse.debug.ui.VariableView + persp.viewSC:org.eclipse.debug.ui.BreakpointView + persp.viewSC:org.eclipse.debug.ui.ExpressionView + persp.viewSC:org.eclipse.ui.views.ContentOutline + persp.viewSC:org.eclipse.ui.console.ConsoleView + persp.viewSC:org.eclipse.ui.views.TaskList + persp.viewSC:com.android.ide.eclipse.ddms.views.LogCatView + persp.viewSC:com.android.ide.eclipse.ddms.views.DeviceView + persp.perspSC:com.android.ide.eclipse.ddms.Perspective + persp.viewSC:org.eclipse.ant.ui.views.AntView + persp.viewSC:org.eclipse.cdt.debug.ui.SignalsView + persp.viewSC:org.eclipse.debug.ui.RegisterView + persp.viewSC:org.eclipse.debug.ui.ModuleView + persp.viewSC:org.eclipse.debug.ui.MemoryView + persp.viewSC:org.eclipse.ui.views.ProblemView + persp.viewSC:org.eclipse.cdt.debug.ui.executablesView + persp.actionSet:org.eclipse.cdt.debug.ui.debugActionSet + persp.viewSC:org.eclipse.cdt.dsf.gdb.ui.tracecontrol.view + persp.viewSC:org.eclipse.cdt.dsf.debug.ui.disassembly.view + persp.perspSC:org.eclipse.cdt.ui.CPerspective + persp.actionSet:org.eclipse.ui.NavigateActionSet + persp.actionSet:org.eclipse.debug.ui.breakpointActionSet + persp.viewSC:org.eclipse.pde.runtime.LogView + persp.showIn:org.eclipse.egit.ui.RepositoriesView + persp.actionSet:org.eclipse.jdt.debug.ui.JDTDebugActionSet + persp.viewSC:org.eclipse.jdt.debug.ui.DisplayView + persp.perspSC:org.eclipse.jdt.ui.JavaPerspective + persp.perspSC:org.eclipse.jdt.ui.JavaBrowsingPerspective + persp.actionSet:org.eclipse.jdt.ui.JavaActionSet + persp.showIn:org.eclipse.jdt.ui.PackageExplorer + persp.perspSC:org.eclipse.wst.xml.ui.perspective + + + + + + newtablook + org.eclipse.e4.primaryNavigationStack + + + + + + + newtablook + + + + + newtablook + + + + + + + + + + + + newtablook + org.eclipse.e4.secondaryNavigationStack + + + + + + + + + newtablook + + + + newtablook + org.eclipse.e4.secondaryDataStack + + + + + + + + + + + + + + + + + + + + + View + categoryTag:Help + + + View + categoryTag:General + + ViewMenu + menuContribution:menu + + + + + View + categoryTag:Help + + + + newtablook + org.eclipse.e4.primaryDataStack + EditorStack + noFocus + + + Editor + org.eclipse.jdt.ui.CompilationUnitEditor + removeOnHide + + menuContribution:popup + popup:#CompilationUnitEditorContext + popup:org.eclipse.jdt.ui.CompilationUnitEditor.EditorContext + popup:#AbstractTextEditorContext + + + menuContribution:popup + popup:#CompilationUnitRulerContext + popup:org.eclipse.jdt.ui.CompilationUnitEditor.RulerContext + popup:#AbstractTextEditorRulerContext + + + menuContribution:popup + popup:#OverviewRulerContext + + + + + Editor + org.eclipse.jdt.ui.CompilationUnitEditor + removeOnHide + + menuContribution:popup + popup:#CompilationUnitEditorContext + popup:org.eclipse.jdt.ui.CompilationUnitEditor.EditorContext + popup:#AbstractTextEditorContext + + + menuContribution:popup + popup:#CompilationUnitRulerContext + popup:org.eclipse.jdt.ui.CompilationUnitEditor.RulerContext + popup:#AbstractTextEditorRulerContext + + + menuContribution:popup + popup:#OverviewRulerContext + + + + + Editor + org.eclipse.jdt.ui.CompilationUnitEditor + removeOnHide + + menuContribution:popup + popup:#CompilationUnitEditorContext + popup:org.eclipse.jdt.ui.CompilationUnitEditor.EditorContext + popup:#AbstractTextEditorContext + + + menuContribution:popup + popup:#CompilationUnitRulerContext + popup:org.eclipse.jdt.ui.CompilationUnitEditor.RulerContext + popup:#AbstractTextEditorRulerContext + + + menuContribution:popup + popup:#OverviewRulerContext + + + + + Editor + org.eclipse.jdt.ui.CompilationUnitEditor + removeOnHide + + menuContribution:popup + popup:#CompilationUnitEditorContext + popup:org.eclipse.jdt.ui.CompilationUnitEditor.EditorContext + popup:#AbstractTextEditorContext + + + menuContribution:popup + popup:#CompilationUnitRulerContext + popup:org.eclipse.jdt.ui.CompilationUnitEditor.RulerContext + popup:#AbstractTextEditorRulerContext + + + menuContribution:popup + popup:#OverviewRulerContext + + + + + Editor + com.android.ide.eclipse.editors.CommonXmlEditor + removeOnHide + + menuContribution:popup + popup:org.eclipse.core.runtime.xml.source.EditorContext + popup:.EditorContext + popup:#AbstractTextEditorContext + + + menuContribution:popup + popup:org.eclipse.core.runtime.xml.source.RulerContext + popup:.RulerContext + popup:#AbstractTextEditorRulerContext + + + menuContribution:popup + popup:#OverviewRulerContext + + + menuContribution:popup + popup:org.eclipse.core.runtime.xml.source.EditorContext + popup:.source.EditorContext + popup:org.eclipse.wst.sse.ui.StructuredTextEditor.EditorContext + + + menuContribution:popup + popup:org.eclipse.core.runtime.xml.source.RulerContext + popup:.source.RulerContext + popup:org.eclipse.wst.sse.ui.StructuredTextEditor.RulerContext + + + + + + + View + categoryTag:Java + active + + ViewMenu + menuContribution:menu + + + menuContribution:popup + popup:org.eclipse.jdt.ui.PackageExplorer + + + + + View + categoryTag:Java + + + View + categoryTag:General + + + View + categoryTag:General + + + + View + categoryTag:General + + ViewMenu + menuContribution:menu + + + menuContribution:popup + popup:org.eclipse.ui.views.ProblemView + popup:org.eclipse.ui.ide.MarkersView + + + + + View + categoryTag:Java + + + View + categoryTag:Java + + + View + categoryTag:General + + + + View + categoryTag:General + highlighted + + ViewMenu + menuContribution:menu + + + menuContribution:popup + popup:org.eclipse.ui.MessageConsole.#ContextMenu + + + menuContribution:popup + popup:org.eclipse.ui.MessageConsole.#ContextMenu + + + + + View + categoryTag:General + + + View + categoryTag:General + + + + View + categoryTag:General + + ViewMenu + menuContribution:menu + + + menuContribution:popup + popup:org.eclipse.jdt.ui.outline + + + menuContribution:popup + popup:org.eclipse.jdt.ui.outline + + + menuContribution:popup + popup:org.eclipse.jdt.ui.outline + + + menuContribution:popup + popup:org.eclipse.jdt.ui.outline + + + menuContribution:popup + popup:org.eclipse.core.runtime.xml.source.OutlineContext + popup:com.android.ide.eclipse.editors.CommonXmlEditor.source.OutlineContext + popup:org.eclipse.wst.sse.ui.StructuredTextEditor.OutlineContext + + + + + View + categoryTag:General + + + View + categoryTag:Ant + + + View + categoryTag:Git + + + View + categoryTag:Java + + + + View + categoryTag:Mylyn + + ViewMenu + menuContribution:menu + + + + + View + categoryTag:WindowBuilder + + + View + categoryTag:WindowBuilder + + + + View + categoryTag:Android + + ViewMenu + menuContribution:menu + + + + + View + categoryTag:General + + + View + categoryTag:General + + + + View + categoryTag:Debug + + ViewMenu + menuContribution:menu + + + menuContribution:popup + popup:org.eclipse.debug.ui.DebugView + + + menuContribution:popup + popup:org.eclipse.debug.ui.DebugView + + + + + + View + categoryTag:Debug + + ViewMenu + menuContribution:menu + + + menuContribution:popup + popup:org.eclipse.debug.ui.VariableView.detail + + + menuContribution:popup + popup:org.eclipse.debug.ui.VariableView + + + + + + View + categoryTag:Debug + + ViewMenu + menuContribution:menu + + + menuContribution:popup + popup:org.eclipse.debug.ui.VariableView.detail + + + menuContribution:popup + popup:org.eclipse.debug.ui.BreakpointView + + + + + View + categoryTag:Debug + + + View + categoryTag:Debug + + + View + categoryTag:Debug + + + View + categoryTag:Debug + + + View + categoryTag:Debug + + + View + categoryTag:Debug + + + View + categoryTag:Debug + + + View + categoryTag:Debug + + + View + categoryTag:General + + + + toolbarSeparator + + + + Draggable + + Opaque + + + Opaque + + + Opaque + + + Opaque + + + Opaque + + + Opaque + + + Opaque + + + + Opaque + + + Opaque + + + Opaque + + + Opaque + + + Opaque + + + + toolbarSeparator + + + + Draggable + + Opaque + + + Opaque + + + Opaque + + + + Draggable + + Opaque + + + Opaque + + + + Draggable + + Opaque + + + Opaque + + + + Draggable + + Opaque + + + Opaque + + + Opaque + + + Opaque + + + + Draggable + + Opaque + + + Opaque + + + Opaque + + + Opaque + + + + Draggable + + Opaque + + + Opaque + + + Opaque + + + Opaque + + + + Draggable + + Opaque + + + Opaque + + + Opaque + + + Opaque + + + Opaque + + + Opaque + + + Opaque + + + + toolbarSeparator + + + + Draggable + + Opaque + + + Opaque + + + Opaque + + + Opaque + + + Opaque + + + + Opaque + + + Opaque + + + Opaque + + + + Draggable + + + Draggable + + + toolbarSeparator + + + + toolbarSeparator + + + + Draggable + + Opaque + + + Opaque + + + + stretch + SHOW_RESTORE_MENU + + + Draggable + HIDEABLE + SHOW_RESTORE_MENU + + + + + stretch + + + Draggable + + + Draggable + + + + + + TrimStack + + + + + + + + + + + + + + + + platform:cocoa + + + + + + + + + platform:cocoa + + + + + + + + + + + + + + platform:cocoa + + + platform:cocoa + + + + platform:cocoa + + + platform:cocoa + + + + + + + + + + + platform:cocoa + + + + + + + platform:cocoa + + + + platform:cocoa + + + + platform:cocoa + + + platform:cocoa + + + platform:cocoa + + + platform:cocoa + + + platform:cocoa + + + platform:cocoa + + + + + + + + + + + + + + + + + + platform:cocoa + + + platform:cocoa + + + + platform:cocoa + + + + + + platform:cocoa + + + + platform:cocoa + + + platform:cocoa + + + + platform:cocoa + + + + + platform:cocoa + + + platform:cocoa + + + platform:cocoa + + + platform:cocoa + + + + + + + + + + + + + + + platform:cocoa + + + + platform:cocoa + + + + platform:cocoa + + + platform:cocoa + + + + platform:cocoa + + + + + platform:cocoa + + + + + + + + + + + + platform:cocoa + + + + platform:cocoa + + + + platform:cocoa + + + + + + + platform:cocoa + + + + platform:cocoa + + + + + + + + platform:cocoa + + + + platform:cocoa + + + platform:cocoa + + + + + + platform:cocoa + + + platform:cocoa + + + platform:cocoa + + + + + platform:cocoa + + + + platform:cocoa + + + platform:cocoa + + + + + + + + platform:cocoa + + + platform:cocoa + + + + + + platform:cocoa + + + platform:cocoa + + + + + + + + + platform:cocoa + + + + platform:cocoa + + + + platform:cocoa + + + platform:cocoa + + + platform:cocoa + + + platform:cocoa + + + + platform:cocoa + + + platform:cocoa + + + + platform:cocoa + + + platform:cocoa + + + + platform:cocoa + + + + platform:cocoa + + + + platform:cocoa + + + + platform:cocoa + + + + platform:cocoa + + + + platform:cocoa + + + + platform:cocoa + + + + + platform:cocoa + + + + platform:cocoa + + + + platform:cocoa + + + + + + + + platform:cocoa + + + platform:cocoa + + + + platform:cocoa + + + + + platform:cocoa + + + platform:cocoa + + + platform:cocoa + + + + platform:cocoa + + + platform:cocoa + + + platform:cocoa + + + + + + + + + platform:cocoa + + + platform:cocoa + + + + + + + + + + + + + + + platform:cocoa + + + + + platform:cocoa + + + + + + platform:cocoa + + + + + + + + + platform:cocoa + + + platform:cocoa + + + + + platform:cocoa + + + platform:cocoa + + + + + platform:cocoa + + + platform:cocoa + + + + + platform:cocoa + + + + + + + + + + + + + + + + platform:cocoa + + + platform:cocoa + + + + platform:cocoa + + + + + + platform:cocoa + + + platform:cocoa + + + platform:cocoa + + + + platform:cocoa + + + + + + platform:cocoa + + + platform:cocoa + + + platform:cocoa + + + platform:cocoa + + + platform:cocoa + + + platform:cocoa + + + + + + + + platform:cocoa + + + + platform:cocoa + + + + + + + + + + + + + platform:cocoa + + + + + platform:cocoa + + + + + + + + + platform:cocoa + + + + + + + + platform:cocoa + + + platform:cocoa + + + + + + + + + + platform:cocoa + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + platform:cocoa + + + + platform:cocoa + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Editor + + + View + categoryTag:Ant + + + View + categoryTag:Debug + + + View + categoryTag:Debug + + + View + categoryTag:Debug + + + View + categoryTag:Debug + + + View + categoryTag:Debug + + + View + categoryTag:Debug + + + View + categoryTag:Debug + + + View + categoryTag:Git + + + View + categoryTag:Git + + + View + categoryTag:Git + + + View + categoryTag:Git + + + View + categoryTag:Git + + + View + categoryTag:General + + + View + categoryTag:Help + + + View + categoryTag:Debug + + + View + categoryTag:Java + + + View + categoryTag:Java + + + View + categoryTag:Java + + + View + categoryTag:Java Browsing + + + View + categoryTag:Java Browsing + + + View + categoryTag:Java Browsing + + + View + categoryTag:Java Browsing + + + View + categoryTag:Java + + + View + categoryTag:General + + + View + categoryTag:Java + + + View + categoryTag:Java + + + View + categoryTag:Maven + + + View + categoryTag:Maven + + + View + categoryTag:Mylyn + + + View + categoryTag:Mylyn + + + View + categoryTag:Mylyn + + + View + categoryTag:Mylyn + + + View + categoryTag:Code Recommenders + + + View + categoryTag:Code Recommenders + + + View + categoryTag:Code Recommenders + + + View + categoryTag:Code Recommenders + + + View + categoryTag:General + + + View + categoryTag:General + + + View + categoryTag:CVS + + + View + categoryTag:CVS + + + View + categoryTag:Team + + + View + categoryTag:Team + + + View + categoryTag:General + + + View + categoryTag:General + + + View + categoryTag:Help + + + View + categoryTag:General + + + View + categoryTag:General + + + View + categoryTag:General + + + View + categoryTag:General + + + View + categoryTag:General + + + View + categoryTag:General + + + View + categoryTag:General + + + View + categoryTag:General + + + View + categoryTag:General + + + View + categoryTag:General + + + View + categoryTag:General + + + View + categoryTag:WindowBuilder + + + View + categoryTag:WindowBuilder + + + View + categoryTag:General + + + View + categoryTag:XML + + + View + categoryTag:XML + + + View + categoryTag:Android + + + View + categoryTag:Android + + + View + categoryTag:Android + + + View + categoryTag:Android + + + View + categoryTag:Android + + + View + categoryTag:Android + + + View + categoryTag:Android + + + View + categoryTag:Android + + + View + categoryTag:Android + + + View + categoryTag:Android + + + View + categoryTag:Android + + + View + categoryTag:Android + + + View + categoryTag:Tracer for OpenGL ES + + + View + categoryTag:Tracer for OpenGL ES + + + View + categoryTag:Tracer for OpenGL ES + + + View + categoryTag:Android + + + View + categoryTag:Android + + + View + categoryTag:Android + + + View + categoryTag:Android + + + View + categoryTag:Android + + + View + categoryTag:Android + + + View + categoryTag:Android + + + View + categoryTag:Android + + + View + categoryTag:&C/C++ + + + View + categoryTag:Debug + + + View + categoryTag:Debug + + + View + categoryTag:Debug + + + View + categoryTag:Debug + + + View + categoryTag:Debug + + + View + categoryTag:Make + + + View + categoryTag:&C/C++ + + + View + categoryTag:&C/C++ + + + View + categoryTag:&C/C++ + + + View + categoryTag:&C/C++ + + + View + categoryTag:&C/C++ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.jdt.core/.org.eclipse.jdt.core.external.folders/.project b/.metadata/.plugins/org.eclipse.jdt.core/.org.eclipse.jdt.core.external.folders/.project new file mode 100644 index 0000000..6d6be74 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.jdt.core/.org.eclipse.jdt.core.external.folders/.project @@ -0,0 +1,18 @@ + + + .org.eclipse.jdt.core.external.folders + + + + + + + + + + .link0 + 2 + /Applications/adt-bundle-mac-x86_64-20140624/sdk/sources/android-21 + + + diff --git a/.metadata/.plugins/org.eclipse.jdt.core/1255426124.index b/.metadata/.plugins/org.eclipse.jdt.core/1255426124.index new file mode 100644 index 0000000..d441e73 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.jdt.core/1255426124.index differ diff --git a/.metadata/.plugins/org.eclipse.jdt.core/77043017.index b/.metadata/.plugins/org.eclipse.jdt.core/77043017.index new file mode 100644 index 0000000..4f41152 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.jdt.core/77043017.index differ diff --git a/.metadata/.plugins/org.eclipse.jdt.core/811295056.index b/.metadata/.plugins/org.eclipse.jdt.core/811295056.index new file mode 100644 index 0000000..c0c55a2 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.jdt.core/811295056.index differ diff --git a/.metadata/.plugins/org.eclipse.jdt.core/assumedExternalFilesCache b/.metadata/.plugins/org.eclipse.jdt.core/assumedExternalFilesCache new file mode 100644 index 0000000..593f470 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.jdt.core/assumedExternalFilesCache differ diff --git a/.metadata/.plugins/org.eclipse.jdt.core/externalFilesCache b/.metadata/.plugins/org.eclipse.jdt.core/externalFilesCache new file mode 100644 index 0000000..2d62d77 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.jdt.core/externalFilesCache differ diff --git a/.metadata/.plugins/org.eclipse.jdt.core/externalLibsTimeStamps b/.metadata/.plugins/org.eclipse.jdt.core/externalLibsTimeStamps new file mode 100644 index 0000000..f9cef07 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.jdt.core/externalLibsTimeStamps differ diff --git a/.metadata/.plugins/org.eclipse.jdt.core/invalidArchivesCache b/.metadata/.plugins/org.eclipse.jdt.core/invalidArchivesCache new file mode 100644 index 0000000..593f470 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.jdt.core/invalidArchivesCache differ diff --git a/.metadata/.plugins/org.eclipse.jdt.core/javaLikeNames.txt b/.metadata/.plugins/org.eclipse.jdt.core/javaLikeNames.txt new file mode 100644 index 0000000..8586397 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.jdt.core/javaLikeNames.txt @@ -0,0 +1 @@ +java \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.jdt.core/nonChainingJarsCache b/.metadata/.plugins/org.eclipse.jdt.core/nonChainingJarsCache new file mode 100644 index 0000000..2d62d77 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.jdt.core/nonChainingJarsCache differ diff --git a/.metadata/.plugins/org.eclipse.jdt.core/savedIndexNames.txt b/.metadata/.plugins/org.eclipse.jdt.core/savedIndexNames.txt new file mode 100644 index 0000000..5c0d976 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.jdt.core/savedIndexNames.txt @@ -0,0 +1,4 @@ +INDEX VERSION 1.127+/Users/paul/Documents/MiBandAndroid/.metadata/.plugins/org.eclipse.jdt.core +77043017.index +811295056.index +1255426124.index diff --git a/.metadata/.plugins/org.eclipse.jdt.core/variablesAndContainers.dat b/.metadata/.plugins/org.eclipse.jdt.core/variablesAndContainers.dat new file mode 100644 index 0000000..9313c1b Binary files /dev/null and b/.metadata/.plugins/org.eclipse.jdt.core/variablesAndContainers.dat differ diff --git a/.metadata/.plugins/org.eclipse.jdt.debug.ui/dialog_settings.xml b/.metadata/.plugins/org.eclipse.jdt.debug.ui/dialog_settings.xml new file mode 100644 index 0000000..05173e2 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.jdt.debug.ui/dialog_settings.xml @@ -0,0 +1,9 @@ + +
+
+ + + + +
+
diff --git a/.metadata/.plugins/org.eclipse.jdt.launching/.install.xml b/.metadata/.plugins/org.eclipse.jdt.launching/.install.xml new file mode 100644 index 0000000..84bab7e --- /dev/null +++ b/.metadata/.plugins/org.eclipse.jdt.launching/.install.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.jdt.launching/libraryInfos.xml b/.metadata/.plugins/org.eclipse.jdt.launching/libraryInfos.xml new file mode 100644 index 0000000..575f473 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.jdt.launching/libraryInfos.xml @@ -0,0 +1,117 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/OpenTypeHistory.xml b/.metadata/.plugins/org.eclipse.jdt.ui/OpenTypeHistory.xml new file mode 100644 index 0000000..a4ee3cb --- /dev/null +++ b/.metadata/.plugins/org.eclipse.jdt.ui/OpenTypeHistory.xml @@ -0,0 +1,2 @@ + + diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml b/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml new file mode 100644 index 0000000..266b329 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.jdt.ui/QualifiedTypeNameHistory.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml b/.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml new file mode 100644 index 0000000..065570a --- /dev/null +++ b/.metadata/.plugins/org.eclipse.jdt.ui/dialog_settings.xml @@ -0,0 +1,26 @@ + +
+
+ + + + + +
+
+ + +
+
+ +
+
+
+
+ +
+
+
+
+
+
diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/0.png b/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/0.png new file mode 100644 index 0000000..2856a9f Binary files /dev/null and b/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/0.png differ diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/1.png b/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/1.png new file mode 100644 index 0000000..56554ec Binary files /dev/null and b/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/1.png differ diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/10.png b/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/10.png new file mode 100644 index 0000000..c5df4a4 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/10.png differ diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/11.png b/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/11.png new file mode 100644 index 0000000..31311ab Binary files /dev/null and b/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/11.png differ diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/2.png b/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/2.png new file mode 100644 index 0000000..a6abcd8 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/2.png differ diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/3.png b/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/3.png new file mode 100644 index 0000000..ebe6698 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/3.png differ diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/4.png b/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/4.png new file mode 100644 index 0000000..89944ce Binary files /dev/null and b/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/4.png differ diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/5.png b/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/5.png new file mode 100644 index 0000000..9abe3c5 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/5.png differ diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/6.png b/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/6.png new file mode 100644 index 0000000..3629023 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/6.png differ diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/7.png b/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/7.png new file mode 100644 index 0000000..d198a93 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/7.png differ diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/8.png b/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/8.png new file mode 100644 index 0000000..a930fe1 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/8.png differ diff --git a/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/9.png b/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/9.png new file mode 100644 index 0000000..a95f608 Binary files /dev/null and b/.metadata/.plugins/org.eclipse.jdt.ui/jdt-images/9.png differ diff --git a/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/.workspace/2014/12/51/refactorings.history b/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/.workspace/2014/12/51/refactorings.history new file mode 100644 index 0000000..0a8038c --- /dev/null +++ b/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/.workspace/2014/12/51/refactorings.history @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/.workspace/2014/12/51/refactorings.index b/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/.workspace/2014/12/51/refactorings.index new file mode 100644 index 0000000..23a9736 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/.workspace/2014/12/51/refactorings.index @@ -0,0 +1 @@ +1419027709795 Delete resource 'MiBand' diff --git a/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/MiBand/2014/12/51/refactorings.history b/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/MiBand/2014/12/51/refactorings.history new file mode 100644 index 0000000..22a0731 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/MiBand/2014/12/51/refactorings.history @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/MiBand/2014/12/51/refactorings.index b/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/MiBand/2014/12/51/refactorings.index new file mode 100644 index 0000000..85b0d2a --- /dev/null +++ b/.metadata/.plugins/org.eclipse.ltk.core.refactoring/.refactorings/MiBand/2014/12/51/refactorings.index @@ -0,0 +1,4 @@ +1419033178990 Delete elements +1419033611793 Delete element +1419034885673 Extracts string 'Looking for MiBand' into R.string.looking_for_miband +1419046178464 Delete element diff --git a/.metadata/.plugins/org.eclipse.ltk.ui.refactoring/dialog_settings.xml b/.metadata/.plugins/org.eclipse.ltk.ui.refactoring/dialog_settings.xml new file mode 100644 index 0000000..aa26784 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.ltk.ui.refactoring/dialog_settings.xml @@ -0,0 +1,7 @@ + +
+
+ + +
+
diff --git a/.metadata/.plugins/org.eclipse.m2e.logback.configuration/0.log b/.metadata/.plugins/org.eclipse.m2e.logback.configuration/0.log new file mode 100644 index 0000000..e69de29 diff --git a/.metadata/.plugins/org.eclipse.m2e.logback.configuration/logback.1.5.0.20140606-0033.xml b/.metadata/.plugins/org.eclipse.m2e.logback.configuration/logback.1.5.0.20140606-0033.xml new file mode 100644 index 0000000..e33758c --- /dev/null +++ b/.metadata/.plugins/org.eclipse.m2e.logback.configuration/logback.1.5.0.20140606-0033.xml @@ -0,0 +1,43 @@ + + + + %date [%thread] %-5level %logger{35} - %msg%n + + + OFF + + + + + ${org.eclipse.m2e.log.dir}/0.log + + ${org.eclipse.m2e.log.dir}/%i.log + 1 + 10 + + + 100MB + + + %date [%thread] %-5level %logger{35} - %msg%n + + + + + + WARN + + + + + + + + + + + + + + + diff --git a/.metadata/.plugins/org.eclipse.team.cvs.core/.running b/.metadata/.plugins/org.eclipse.team.cvs.core/.running new file mode 100644 index 0000000..e69de29 diff --git a/.metadata/.plugins/org.eclipse.ui.intro/dialog_settings.xml b/.metadata/.plugins/org.eclipse.ui.intro/dialog_settings.xml new file mode 100644 index 0000000..f118f02 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.ui.intro/dialog_settings.xml @@ -0,0 +1,4 @@ + +
+ +
diff --git a/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml b/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml new file mode 100644 index 0000000..a104b4d --- /dev/null +++ b/.metadata/.plugins/org.eclipse.ui.workbench/dialog_settings.xml @@ -0,0 +1,21 @@ + +
+
+ + + + + + + + + + +
+
+ + + + +
+
diff --git a/.metadata/.plugins/org.eclipse.ui.workbench/workingsets.xml b/.metadata/.plugins/org.eclipse.ui.workbench/workingsets.xml new file mode 100644 index 0000000..33e1a1c --- /dev/null +++ b/.metadata/.plugins/org.eclipse.ui.workbench/workingsets.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.wst.internet.cache/cache.xml b/.metadata/.plugins/org.eclipse.wst.internet.cache/cache.xml new file mode 100644 index 0000000..6574033 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.wst.internet.cache/cache.xml @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/.metadata/.plugins/org.eclipse.wst.sse.core/task-tags.properties b/.metadata/.plugins/org.eclipse.wst.sse.core/task-tags.properties new file mode 100644 index 0000000..0ece294 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.wst.sse.core/task-tags.properties @@ -0,0 +1,3 @@ +# +#Fri Dec 19 23:30:09 CET 2014 +task-tag-projects-already-scanned=MiBand diff --git a/.metadata/.plugins/org.eclipse.wst.sse.ui/dialog_settings.xml b/.metadata/.plugins/org.eclipse.wst.sse.ui/dialog_settings.xml new file mode 100644 index 0000000..63fae25 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.wst.sse.ui/dialog_settings.xml @@ -0,0 +1,5 @@ + +
+
+
+
diff --git a/.metadata/.plugins/org.eclipse.wst.xml.core/default_catalog.xml b/.metadata/.plugins/org.eclipse.wst.xml.core/default_catalog.xml new file mode 100644 index 0000000..37faa16 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.wst.xml.core/default_catalog.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/.metadata/.plugins/org.eclipse.wst.xml.core/system_catalog.xml b/.metadata/.plugins/org.eclipse.wst.xml.core/system_catalog.xml new file mode 100644 index 0000000..173bb65 --- /dev/null +++ b/.metadata/.plugins/org.eclipse.wst.xml.core/system_catalog.xml @@ -0,0 +1,37 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/.metadata/version.ini b/.metadata/version.ini new file mode 100644 index 0000000..73304b2 --- /dev/null +++ b/.metadata/version.ini @@ -0,0 +1,3 @@ +#Sat Dec 20 02:04:42 CET 2014 +org.eclipse.core.runtime=2 +org.eclipse.platform=4.4.0.v20140925-0400 diff --git a/.recommenders/caches/identified-project-coordinates.json b/.recommenders/caches/identified-project-coordinates.json new file mode 100644 index 0000000..877efab --- /dev/null +++ b/.recommenders/caches/identified-project-coordinates.json @@ -0,0 +1 @@ +[[{"location":"/Users/paul/Documents/MiBandAndroid/MiBand","type":"PROJECT","hints":{"PROJECT_NAME":"MiBand"}},"ABSENT"]] \ No newline at end of file diff --git a/.recommenders/caches/manual-mappings.json b/.recommenders/caches/manual-mappings.json new file mode 100644 index 0000000..9e26dfe --- /dev/null +++ b/.recommenders/caches/manual-mappings.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/.recommenders/index/http___download_eclipse_org_recommenders_models_luna_/_1.fdt b/.recommenders/index/http___download_eclipse_org_recommenders_models_luna_/_1.fdt new file mode 100644 index 0000000..049188e Binary files /dev/null and b/.recommenders/index/http___download_eclipse_org_recommenders_models_luna_/_1.fdt differ diff --git a/.recommenders/index/http___download_eclipse_org_recommenders_models_luna_/_1.fdx b/.recommenders/index/http___download_eclipse_org_recommenders_models_luna_/_1.fdx new file mode 100644 index 0000000..9a66b2a Binary files /dev/null and b/.recommenders/index/http___download_eclipse_org_recommenders_models_luna_/_1.fdx differ diff --git a/.recommenders/index/http___download_eclipse_org_recommenders_models_luna_/_1.fnm b/.recommenders/index/http___download_eclipse_org_recommenders_models_luna_/_1.fnm new file mode 100644 index 0000000..a3b6104 --- /dev/null +++ b/.recommenders/index/http___download_eclipse_org_recommenders_models_luna_/_1.fnm @@ -0,0 +1,4 @@ + + +coordinate fingerprintssymbolic-names +classifiercallovrdselfcovrpselfmovrm \ No newline at end of file diff --git a/.recommenders/index/http___download_eclipse_org_recommenders_models_luna_/_1.frq b/.recommenders/index/http___download_eclipse_org_recommenders_models_luna_/_1.frq new file mode 100644 index 0000000..3fdfc98 --- /dev/null +++ b/.recommenders/index/http___download_eclipse_org_recommenders_models_luna_/_1.frq @@ -0,0 +1,652 @@ +I!< /0 (;!6 '( +04D;' +(&    /914A #- ]ACYaG "K C7$O5>LG(5FINA22E.M36!7 +65CNB #.L+)08 , E +4D7!5+L $'2A +I-F(#"# #?=42O(E L"!: D7 +: OP -> ?/#<1)Bm!K= I=*A%) $1I)2;$A,@- I( 8;)@P09#7#KGOoc/15FO'CL&I=FME1y'F>05+K: DD8L;A "@ o%9" DH +9"C=_!=:E7 1 3 AFLB"N83?*'"*IBJDG49L*D<? P58)I)-7)BO/'C8?9-1*5&%K& < +6PM,9Jy)"%!#1Ig wKA0+:F3 D% +O G1B1.'K.BI[.?B= =/-@ ++*!!DG %+&"Ns%(7 +E +7&* .D8) 8 28& :A ) 0-(219F&."%( (U # 7$)D9J + +600  2 ! 3? )"!@E>8&$" D 6 K8,! 3:> +*: +1 &; Ko,!3 ;.5E-18.# +')( +*F! +#5/ B  ?(O/ A( !?$EG5 + H 2 +E,m) =3N*35+?I, '-+ #().@*  */ ? :k= *6$ >+D:M*68>+.K$ J 8 ;-#;<(A:KF0$ )/ 7 ?/)C L(0=-')(<,> & . %' : +I 1#!561<9N+E8*2 L6 5 2-3   ( ?#%#=$!1 !*? N+ B0 + +6%>OH ).6#%3/)?#E OFOD 8-PH64EPH<1 F@*-7B. E;E >#5-23. 5=N'2CKJAH!"4JL /F4& / )%!D0 C% "2M>96. .H5," ", &L8* &22G<3( (0&(!J :'<9M #<& +A 7;3) 1o!1LLL " D.60IF3 C*E> 9"5?N')@>C"/'* + !" 5 .1'&!"&648 8?* +)}'3B +&&G'-%& E! 1- ;0+A < + #D5#  !)# < 1% E,! .5 #%JK'#.'E-.6 %+0;39-8&=%2 ;9, %=L +.2*+EE%,O2 F B:E0K#PP,%- 7B# C G +&<#/ ++'' 4377(<4 !( C+?#4"EKJ::+9NO) +!-  0;B $*2I-IC-"#)MG&@& + %L;> "? &5 2;$/+$J)?O;/D6C6( 4C ,?{I +< / "6# 7 A>6@2GK333 CH*'1LLFPD): @*$3*K#6> $O?,;56 <:D @%E -'-N16F.!& KE -9? + 9 4 .! , * )'.=;-D&3I=A= '- L,9 +"  +< @ '= 4 (.a? 4<9 2  9+!>68>*"+%!! +;:: " F: +,*&"(%/ ;-55 32 / / +/@ 51= 0  +@ 2@! !":. + 6# $&IH  &'($81 +3 +#&I $=55?G'630H206'5"?,$+IF.{$  , 4F"K5#:C) )!% 4I 1 M/Cm)k? 8L.K22' *!G/* +>+!8= 6FG3 HG OL%%AN +; 6M'>: " @5,+,!J% 9!-%.2"<#*(/( +C"J06? ) =;+?P +M9;2 +( )- /< +0+D% E7 )+= C7'HH,! */K/?,%F,#F9>1NE5:E-CJB8 9!J# .$ /A & : 3,$G< ?I'B O51 QM$OG)-%%""104% 3HACN> /;A0$3N@2,@$ I$-77#K=0I8%i+HO3!AN-@B-C1 +D22=9HI 5/1,$5-:N&2F N 37%I $-E0M#CM 58(88FFE9A6$ +<K?GY/<F52&C7F=?1,8 ).6C+NF1O="-"0, AE& GCu >+$- +INI%0'GJ#= $P<=&$# +;H +72 < +. 74'; <;J,P>BBOME&-B =!$35(/; I0 +H!/*>(DB# LA.!$H?.8)B K6O%3";L%AMG$%KMI0G :97H-$25 .BK"" ;E! *E"('0@=6C" > 13*/+'37 /2 *M% =1F(;N8:CK/(EL 2-#5D&*HEH+/%F$00G954)M 9+.12. +FI,<'NBP4<>8I2/'8KO%$/ !(9,)%*#  + 1#?%.HB40 5 +>/7,8)0 OIHKIGI +@O ,2..*N+B 4A'!K32 ' $J$J.G +?+D&> $6GHN ?5> L*O<<?AJ< *F cO?DC%OGKH$ $- 8.A)9/(8M,01O=H + O;.D#>$+P0&21>A & C16 GNG/D< =% +" +;#J'7>0.- G+?7IO 8 % 5#3L6(KA!%- -9N%47@' +>( 8. +?9A-! +/:0@)G*D<*'  H&!H96S86*  9+= 9G&95D&&0 ( =9:&F4D <&ED $M/F & + BJ!> I%A +  O#)< +7,C'4#$"*<' $*,?1*4 /:#I70$O)  M?6 +#E74>7#MOD5>&461/,*;@%'C"1HA  ?JI, +:+$ L$E9 IDHI( H@=37.)$)3 +=6"4// '2'$+U!*I5$ |0`                                                                                                                        f0`"!! !                                                                                                                        f0`"!! !                                                                                                                        f0`"!! !                                                                                                                        f0`# !  #                                                                                           n0`"I7!H"L. +D28J@EG/F(('33N:;3HM/"B B?#&#%AG&)D{7 19P -PJ ,I;/ 'DK4!# ,MO +H #E- ]CD  "# (=C7$O5>LG(5FINA22E.M36!7 +A5CNB #.L+)08 ' ,@ OE&4D7!G+N% ;$'2A +I-5F(;#E#0 #)?=4E2O(E L."!:GD7 +N 0OP 7>"L /@05+K: DD8L;A "@ %9."DH' +9"C=_!=:E7 1 3 AFLB"N83?*'"*IBJDG49L*D<? P58)I)-7)BO/'C8?9-1*5&%K& < +APM1,9KJC"*->E!91II + KA0+:HC'D% +O G1B1.'KFBI/[?B>= K/-@J+*K%!GG C%(/;&;"BNO?%0H7EA +&?* .D@0)B 28:% :AKAG8EG(HCI9F(I+3N%7(H U+ EM$JD9M* + +AF0!0<; +82,' !5 GM)K)!@G>M98&J"8!M6 K8,! !KL> +4? % +1N 2C"K-o:M;K5GH-/D1JB#0C+'.+/( +4IF2! +-5/=F J (@O/ A( !!* H?<E,GO5@ OH 284 E,Jm)4=3N*35+?I, '(+57().@C% #*>8 K Gk=K*?6$ >+D:M*68>+.K$ J 8 ;-#;<(A:KF0$ )/ 7 ?/)C L(&$%;6BIOAL3" -N@#@24&O!M 3;. /'2N6 9,+J+> E#L56IJ1$E717!*DOH7 5.6#%3/)?4#E OFOD 8FPH64HEJPH@16 F@*-7B. E;E >#5-23. 5=N'2CKJAH!"4JL /F4:& 5. 4 ,&=DDGP %."NM>96. .HN3,6 !))D"&LM8*2 7KEG<9< (J0-)<?J =:'A 9"5DN:>@>C=/B(G*4 <",K I9D @0*.51<6D4M8: 5>I#2JKG'(B.'L-F<+.1C67%2?060 #;KDB-8G&?8%7 -;;,8=>-N +92*'+EE%?,O2 F B:E0K#PP,,- 7:"B#,C G1'.<#&9/?85'4F43778(<4* ( C$+"?#&4"EKJ::+9NO) +!7-& 02;B $*2I4L-.C-"#)MG&@1&"OAL"F J"9>%JID&?B5CON+NN::< %*=B +CDM46G(9 +@:L +3 +N==3(&   +A-"+<( 6 >0A 2E= 0I<@+ .:JF-' +=8"?%M77M!1 )K)- D1J<*F N3.$32*K! A+D? %L0M=$B- 479A17I, +=;<% g8 B0;:A:J?&-4);3E=M(O," +C*AO:DG @LM(K;E -L?B&:5; ;K$/+$J)?O;/D6C6(6KHC) 0?@IJF + ;) ,0:D6@B %A>6@2GK333 CH*'1LLFPD): @*$3*K6G>L$O?,;96 <:D @%E -'-N16F.!& !K E""K9?J E N4 H.!B:,< BBD.=;->H@&3I=A= '9-;PLI9D/*"  +H<"J@?N4O*(B. H+B5!N>E6>C*M+?%F:! +>:8:G">!FG:A6 +DI&M(/4" P;-H68E57 '3B?2;/<9/#L/.@G - B31=PP0) &@LED@8!84":O.8" 6:# ,$>CIH  >&-'P68L <1=3#,7&L8()$=5=?G'6340JHB56F(>3"?,O$KNF/.$0*8,4F"KKA#:C))K%/9"> /1C*)%%?0 8L.K22'( L*L6/, +I46:8=?LG3 HG OL%%AN +; 6M*'>:F(1K HEEN,NJ%2=3-) .62E)1NE5:E-CJB8 9!J# .$ /A & : 3,$G< ?I'B O51 QM$OG)-%%""104% 3HACN> /;A0$3N@2,@$ I$-77#K=0I8%i+HO3!AN-@B-C1 +D22=9HI 5/1,$5-:N&2F N 37%I $-E0M#CM 58(88FFE9A6$ +<K?GY/<F52&C7F=?1,8 ).6C+NF1O="-"N7,AELBBOME&-B =!$35(/; I0 +H!/*>(DB# LA.!$H?.8)B K6O%3";L%AMG$%KMI0G!:=7H-'25 .BK"" ;E! *E"('0@=6C" > 13*/+'37B/2 **0%=1F(;N8:CK/(EL 2-#5D&*HEH+/%F$00G954)M 9+.12. +FI,<'NBP4<>8I2/'8KO%$/ !*9,)%@*=)1" +( L#?:.HB40 5 9>/7,98)0 OIHKIGI +@O ,2..*N+B 4A'!K32 ' $J$J.G +?+D&C> $6GHN ?5> L*O<<?AJ< *F cO?DC%OGKH$ $- 8.A)9/(8M,01O=H + O;.D#>$+P0&21>A & C16 GNG/D< =% +; +;#J'7>0.- )E!E:LC2:3)$F05A=31"751.J ; +O5W6DP&81H3B;#:)HH< 5%B$H81K!" 320A$ M#+?;+BM C?8#JDO6IIC:6 F A,9 K$H+6<&;MO+6(1$:,3J=%P=7@/G? 3JF&G& +!=L4D/O8+3./ +2L/A>G+?7IO 8 % 5#3L6(KA%% 9N447@' +>+ J87 +J49A-N,9 +?I@')2%H0*CGDB,* !#K&6!HK(?6=S966* &9@+= 9G&95D-&0=(F 9>:&>FDDH &ED 0MEF &0O O=J> I8%=MA4!O3#)I<=9'>7,C<'44#$9M"K'-!O$@??$*A4F:#I7G0,1O)G: 4 M2?6 . +E)74>F7#@MOML5>74621,*;@%'C01HMAH  ?JI, +:@:L$E9 IDHI( H@.=N37P-L.>B$<)3+ >6N1" "4;/?+5/B9'D*L'K+,!*I5%$1,0(#>< J3L/H#,AA +F"-8GK&OB">4<'K G7*PNABO=H!3L*@E/@ &!&>5%:+ 5/ADQ@!0H9F 2AK(o;- #3K-OH 2"D-/J17$MFD+K80B!LA.E3L/NP.5%!D.5F:9, ,LF,?O) ;9%(47N*9I) '.J<<4L"BF07.g$O +"M #@"H8 @.4(.L20 +,6$;2-&( #% :*.4!'NMK#07/N. +@! *19-O22B'N=YL'H C<$D7? AEC.7'F(,I +8B 9 O2E KK# =AN,B;0+8I +B 'FO:U>( +7( +J0H 0D>K ; A7>C* ;FE6B<.(O!-5/D%6/ )C9 2H==':75F-GC-F> (,EJ>"3"%<%@%   =8$6;N;";A 11079*$FC;&G&AD21F8&7%(4 N%,/ /#N98M 4NAGC7KIDHD"C7G**>D< L *2*>N3(K%K/<-+K%F( +%<4*@ 5! +@D O1&NNH M=B !+< /*D: H3$L: 1?$ +@-34$33E4;? ?EJ#D?-5@ <3$#= ";2"JHB:OL @69IA"6L9 DG15*$ )A'$;#OD57A9N *?+.F*,O9N+): P@@O F) #+ +8) ; +!O8=6 +HO3+<7O>@,;L33H.J7-/M*C=! +6AI # $"@ ?D63I 31 ++!F8I60F,(@CMI5 $+3B/PE F8O; ,  >G4PD7<$I":(#6=-I2H."(6G4:<+JID)D*>ML$BG?BCA=5H %: )->!.,,'< -=C=7H -@9.N=K=9!JKA58-1 J + )81 E@A:D&+.;KGI 8!I$< FN/2A3DM&J=+A2=4A)>#99$@0( !' O.91)2:GBI3C 4H6=/H/N?<(?B/ ))$N5@LGID7- 'E O"9IJ!CJ;<6+ GL,6@3J *K'H.I #L#1 +!?&*)/' =M*8 J'O=4N-2#:-E%M7<N8C<6L 5%58(>@9$L4:%0LH5 +>'?/KC6?)&6+#"G:%& +?M0O*0"M'.&4=B'3# .6CE7Bu -LHM +1H$4,B!"2K:6:@9MaHD094JM>C.&8&3;AD08$ +2:027%8>MN/+?2FS*;9<,>M(B>14MK: I 6L A5<>#L8"N(F/A7IK(13 N<7G +CP5.+M?FH*<CJ;+L)>F71'COHJE5 AF"@ $ /.H1!56 "*%A8J.HE$!; 8K?F0JF5&E"+"1 D?G$4)  A6BO.'1<E,0A75IM=/*OO1-O-:8N2@"I:MI* 1FM1-E 9:F2 ,;#( $LG + : +G752;:%4;"%D,2?'& 8:OE0M00O="@O= & 3 <-+&F674B5D3G - 396D%A#:*/)7%22J9 2L,8)&D(M+.1JC# #&C0K9!<4N M&IG7CFMI 1#JF*/4%I:8J,G B, =J(D(--%(<$'/@1?04"C-L03I4@2G/G -M8AM3+!/1LH#)E!J9;'O.L;76?;M&;>E I'2C5?,* CJ!GJ+AB6B/DF;=H:8:' "+MB'3? & +$=8(H c O9 +-6&D: @ N@' +K J2FJ3DMEBK;J -!)E='9)" A /M7@#F& :"I0P<,7P +#AJP'  MN6!HB +;>.H8&w9&;/D58/@K*F9I);)FD$25D0>!21)M4!(9:O+/3><%9-/OJ4EB3E#K;G %(.'C*&- (7CNDLN?/E<,K(4 CJ;)B( +N;NB:&4 I8?G5. N,3C;@0:09 +&=&@&FI#L96 +B7J$%#28!>3& 0 9- 06* ?#@I)#?#09)L 5&/H!7GJ2$$=1/P!NN+G/NC/2BL ,7 ?7.1,7%>$B>B/%, -H5?665$GMA:? H9/73*(9M@"KIG8+2F=:*1 AI10[E2.& 5 JE>$E@2"#0 /G@=CF$,P(O@E:': ";IK*1B! C<0 M8" ?G3>)@ 1@*DI6J=16)L?;' 4.%*" 94D7OM7; +CL2;J/" B)>,(4G3>GB18K/-OOC># J BM KF.EL % +,#4!) +IIF(90C$@ K .%)%B NFBJ>M +:>=B +!DL GF5 'F>@6B A1H" H84'B:6<>2;, )9!6)'3LJNL%1>9"#,7 /I=I!/;5)O> +"3+N:D,2 3<41)8KF #2C.3?(MI?= 6@*.+.E5$KDA4PA)3K8910! K*0(IDML54! %14)(M "(!L ),FC9;D7/ +GFA*K E:@*CM44 .G +:*OE= ;+9=7E7 '%H?2)PH=DG)N 1=AK6,=+ *N51->GJ$'6#P":2N 3+C,=159@EOAA ;H???"P+$#P 9 8.$8D!/):2CH0F&>B(A ,$I--C!')%7A +?'!NH=O-2P40H3C0M&$!0-N)1,L(-=_3 E?' +D ()N0 +OD'%eAI5*+ML$< P!>8G% 3'O%3 # "--LG??G+*.#1'O0+%M8#G!= >@ <.L,O-5:& C$K914?? B$K?H9:6767LF,F2AD6J0@. +A-4+L=MLBKP(*/<II MI;=<2 ;8$6=K9  + K K25G D8C +-)! m7@+ 00-D5*5 M#*BO*7%0 E E>4OE"'AC40' =>0J$@:A& 6.L+?($#*?D#KM7*"8 -KEAA3 i4A,#<N+G5 !*'HH3&;,H +FL J!&;B. +G,OAOG2F&J/';F*L +BBB= "H 6EJ$ 2F$2< -OE@'>% .OC 0K5LK%(=?/;" >'/C0M6NM8(?%83%">NL%2K #JL&') )(-5F%*C EH:&;M,1 A,I&%1 8 +7J#? ; @1%2FA67F! +!7 +608 + 44$/ +?)/M-E%118'(783 B! *GH &-- +L +*4IOEE>>=,34 .&4=A.0ND, 0 +&6=( 2 +;' G&+"I 8 /*GN# ++ #%L +5C8kI qD(BJ&6"CI=67KB&NK3.(9>;L1I/0 (;6 '4;(&   14A<!? :+/ +*! ;:N;<7 C7L9F.5< )"6'BN-76$)"F #- ]A "7O5>G(5FN2E.M3!7 +65B #. ,E +475+L $2A-F(#"# #?2L"!: D7 +: OP ->/#<1)Bm!K= I*A%$1I)2;$A,@- ( ;)P09#7KOocCL&I=FME1y'F>5K:DD8L;A "@ o%9" DH_!=:E7 1 3 AFL"NIBDLD<? P58I)-7)'C9-1*5&%K&< +6M,Jy)"%!#1 wK+:F3 D%OB1.B=/-@ +D %%(7 +E&* .8 88& :A  0-(21&"%( (U 79J + 0  2!3)" D6 K! 3:> +*1 &;! ;.5E-8.+')( +*! +#5/ B  ?(  !G5 + H +,m) =3N*35+?I '-#.@  * :k= *6$>+D68>K$ J 8 (A:KF$)/ ?)L(<(9L N&JM'07'DK4! +'  NA #6B +MA "@#@24&CqO =#?3;18;&%11=')<, & %' :  1#!61<9+8* 5 -  ( ?#=$!1!*?N 0 6%O ).6#%/)?#EF 8-64EH<1 F@-B. EE523. 5=N2JH"4J F4& / )!DM>965,"", L8* &22G<(0&!:'9M #< +A 7;31o1LLL " D.60IF3 C*E "?N')@>C"* +!" 5 .1&!"&648 8?* +)}'3 +&G'-%&  1 ;0A < +D5 !) 1% .#%J'E-%+98=%2, %=L +.2*EE%,O F :K#P,%-7BC  +&<#/ ++' 4377(<4 !( C+?#4"EKJ:N) +!-  0; $*2I-I)&@ < :9%;D0*5 N: :8 %A + @=2( +5 : +( + +=)   + +(6 0 2 10 @ $J6-%M4#/3 +*!) 4< L."-41 +=<% g B0;::)=,# +A >%L& 2$+$J?;/66C,?{# A>6@333HLFP): @*K#> ?,;56 <: %E -'N1! E -9? + 4.*)'.=-D&A=',9 +" +< @ '= 4a? 9 2  9+!>68>*"+%!! +;:" F*&"(% ;-5 2 /   0 ! . +6# $&IH  &'($1 +3 +#I =55'30206'5"?F$  , 4F"K:C) 4 1 M/m)k8L.K22 *!/*+!8= 6FG3HG OL%%AN +; 6M>:  @,,!J% 9!."<( +C"J06? ) +?P +M92 +( )< +0+D% E7 )+= C'H,! *//,%F#95:E-CJB 9J . /A & :3,G ?I'B 51 /;A032,$ I$-7#K=0I8%HO3!AN@B1 +=9HI 5/1$5-:N&2 N 7I-M#CM58(88FFE9 +<K?GY/<F52&C7F=?6CNF1O="-"0, AE& GCu >$- +INI0J==&$# +; +72< +.74';J,PB =!$5(/;0 +*>(DB!BKO"LAG%G :9H$25 K"" ;*"('0@=6C" > 13*/'37 *M% =F(N8:CK/(E&*H/%FG954) 92FI,'4I2'8KO$(%*# 1#?% +>/7,80IHIGI,2..*N+4A'!K ' $J$J.G +? $6GHN 5> <?AJ< *F c?DC%OGKH$-)9(8M,01O= + O;.#$01>A C1 G/ =% +" +J'7>0.-  I%A  #)<,C'#$<' $*,/:#I70$O)  6 +#E74>7#OD5>&61/,*;%'C"1A  ?,+$$E9 II(H@37.)$)3 +=6"// '2'$+U*5$I/0 (;6 '4;(&   14A<!? :+/ +*! ;:N;<7 C7L9F.5< )"6'BN-76$)"F #- ]A "7O5>G(5FN2E.M3!7 +65B #. ,E +475+L $2A-F(#"# #?2L"!: D7 +: OP ->/#<1)Bm!K= I*A%$1I)2;$A,@- ( ;)P09#7KOocCL&I=FME1y'F>5K:DD8L;A "@ o%9" DH_!=:E7 1 3 AFL"NIBDLD<? P58I)-7)'C9-1*5&%K&< +6M,Jy)"%!#1 wK+:F3 D%OB1.B=/-@ +D %%(7 +E&* .8 88& :A  0-(21&"%( (U 79J + 0  2!3)" D6 K! 3:> +*1 &;! ;.5E-8.+')( +*! +#5/ B  ?(  !G5 + H +,m) =3N*35+?I '-#.@  * :k= *6$>+D68>K$ J 8 (A:KF$)/ ?)L(<(9L N&JM'07'DK4! +'  NA #6B +MA "@#@24&CqO =#?3;18;&%11=')<, & %' :  1#!61<9+8* 5 -  ( ?#=$!1!*?N 0 6%O ).6#%/)?#EF 8-64EH<1 F@-B. EE523. 5=N2JH"4J F4& / )!DM>965,"", L8* &22G<(0&!:'9M #< +A 7;31o1LLL " D.60IF3 C*E "?N')@>C"* +!" 5 .1&!"&648 8?* +)}'3 +&G'-%&  1 ;0A < +D5 !) 1% .#%J'E-%+98=%2, %=L +.2*EE%,O F :K#P,%-7BC  +&<#/ ++' 4377(<4 !( C+?#4"EKJ:N) +!-  0; $*2I-I)&@ < :9%;D0*5 N: :8 %A + @=2( +5 : +( + +=)   + +(6 0 2 10 @ $J6-%M4#/3 +*!) 4< L."-41 +=<% g B0;::)=,# +A >%L& 2$+$J?;/66C,?{# A>6@333HLFP): @*K#> ?,;56 <: %E -'N1! E -9? + 4.*)'.=-D&A=',9 +" +< @ '= 4a? 9 2  9+!>68>*"+%!! +;:" F*&"(% ;-5 2 /   0 ! . +6# $&IH  &'($1 +3 +#I =55'30206'5"?F$  , 4F"K:C) 4 1 M/m)k8L.K22 *!/*+!8= 6FG3HG OL%%AN +; 6M>:  @,,!J% 9!."<( +C"J06? ) +?P +M92 +( )< +0+D% E7 )+= C'H,! *//,%F#95:E-CJB 9J . /A & :3,G ?I'B 51 /;A032,$ I$-7#K=0I8%HO3!AN@B1 +=9HI 5/1$5-:N&2 N 7I-M#CM58(88FFE9 +<K?GY/<F52&C7F=?6CNF1O="-"0, AE& GCu >$- +INI0J==&$# +; +72< +.74';J,PB =!$5(/;0 +*>(DB!BKO"LAG%G :9H$25 K"" ;*"('0@=6C" > 13*/'37 *M% =F(N8:CK/(E&*H/%FG954) 92FI,'4I2'8KO$(%*# 1#?% +>/7,80IHIGI,2..*N+4A'!K ' $J$J.G +? $6GHN 5> <?AJ< *F c?DC%OGKH$-)9(8M,01O= + O;.#$01>A C1 G/ =% +" +J'7>0.-  I%A  #)<,C'#$<' $*,/:#I70$O)  6 +#E74>7#OD5>&61/,*;%'C"1A  ?,+$$E9 II(H@37.)$)3 +=6"// '2'$+U*5$I/0 (;6 '4;(&   14A<!? :+/ +*! ;:N;<7 C7L9F.5< )"6'BN-76$)"F #- ]A "7O5>G(5FN2E.M3!7 +65B #. ,E +475+L $2A-F(#"# #?2L"!: D7 +: OP ->/#<1)Bm!K= I*A%$1I)2;$A,@- ( ;)P09#7KOocCL&I=FME1y'F>5K:DD8L;A "@ o%9" DH_!=:E7 1 3 AFL"NIBDLD<? P58I)-7)'C9-1*5&%K&< +6M,Jy)"%!#1 wK+:F3 D%OB1.B=/-@ +D %%(7 +E&* .8 88& :A  0-(21&"%( (U 79J + 0  2!3)" D6 K! 3:> +*1 &;! ;.5E-8.+')( +*! +#5/ B  ?(  !G5 + H +,m) =3N*35+?I '-#.@  * :k= *6$>+D68>K$ J 8 (A:KF$)/ ?)L(<(9L N&JM'07'DK4! +'  NA #6B +MA "@#@24&CqO =#?3;18;&%11=')<, & %' :  1#!61<9+8* 5 -  ( ?#=$!1!*?N 0 6%O ).6#%/)?#EF 8-64EH<1 F@-B. EE523. 5=N2JH"4J F4& / )!DM>965,"", L8* &22G<(0&!:'9M #< +A 7;31o1LLL " D.60IF3 C*E "?N')@>C"* +!" 5 .1&!"&648 8?* +)}'3 +&G'-%&  1 ;0A < +D5 !) 1% .#%J'E-%+98=%2, %=L +.2*EE%,O F :K#P,%-7BC  +&<#/ ++' 4377(<4 !( C+?#4"EKJ:N) +!-  0; $*2I-I)&@ < :9%;D0*5 N: :8 %A + @=2( +5 : +( + +=)   + +(6 0 2 10 @ $J6-%M4#/3 +*!) 4< L."-41 +=<% g B0;::)=,# +A >%L& 2$+$J?;/66C,?{# A>6@333HLFP): @*K#> ?,;56 <: %E -'N1! E -9? + 4.*)'.=-D&A=',9 +" +< @ '= 4a? 9 2  9+!>68>*"+%!! +;:" F*&"(% ;-5 2 /   0 ! . +6# $&IH  &'($1 +3 +#I =55'30206'5"?F$  , 4F"K:C) 4 1 M/m)k8L.K22 *!/*+!8= 6FG3HG OL%%AN +; 6M>:  @,,!J% 9!."<( +C"J06? ) +?P +M92 +( )< +0+D% E7 )+= C'H,! *//,%F#95:E-CJB 9J . /A & :3,G ?I'B 51 /;A032,$ I$-7#K=0I8%HO3!AN@B1 +=9HI 5/1$5-:N&2 N 7I-M#CM58(88FFE9 +<K?GY/<F52&C7F=?6CNF1O="-"0, AE& GCu >$- +INI0J==&$# +; +72< +.74';J,PB =!$5(/;0 +*>(DB!BKO"LAG%G :9H$25 K"" ;*"('0@=6C" > 13*/'37 *M% =F(N8:CK/(E&*H/%FG954) 92FI,'4I2'8KO$(%*# 1#?% +>/7,80IHIGI,2..*N+4A'!K ' $J$J.G +? $6GHN 5> <?AJ< *F c?DC%OGKH$-)9(8M,01O= + O;.#$01>A C1 G/ =% +" +J'7>0.-  I%A  #)<,C'#$<' $*,/:#I70$O)  6 +#E74>7#OD5>&61/,*;%'C"1A  ?,+$$E9 II(H@37.)$)3 +=6"// '2'$+U*5$I/0 (;6 '4;(&   14A<!? :+/ +*! ;:N;<7 C7L9F.5< )"6'BN-76$)"F #- ]A "7O5>G(5FN2E.M3!7 +65B #. ,E +475+L $2A-F(#"# #?2L"!: D7 +: OP ->/#<1)Bm!K= I*A%$1I)2;$A,@- ( ;)P09#7KOocCL&I=FME1y'F>5K:DD8L;A "@ o%9" DH_!=:E7 1 3 AFL"NIBDLD<? P58I)-7)'C9-1*5&%K&< +6M,Jy)"%!#1 wK+:F3 D%OB1.B=/-@ +D %%(7 +E&* .8 88& :A  0-(21&"%( (U 79J + 0  2!3)" D6 K! 3:> +*1 &;! ;.5E-8.+')( +*! +#5/ B  ?(  !G5 + H +,m) =3N*35+?I '-#.@  * :k= *6$>+D68>K$ J 8 (A:KF$)/ ?)L(<(9L N&JM'07'DK4! +'  NA #6B +MA "@#@24&CqO =#?3;18;&%11=')<, & %' :  1#!61<9+8* 5 -  ( ?#=$!1!*?N 0 6%O ).6#%/)?#EF 8-64EH<1 F@-B. EE523. 5=N2JH"4J F4& / )!DM>965,"", L8* &22G<(0&!:'9M #< +A 7;31o1LLL " D.60IF3 C*E "?N')@>C"* +!" 5 .1&!"&648 8?* +)}'3 +&G'-%&  1 ;0A < +D5 !) 1% .#%J'E-%+98=%2, %=L +.2*EE%,O F :K#P,%-7BC  +&<#/ ++' 4377(<4 !( C+?#4"EKJ:N) +!-  0; $*2I-I)&@ < :9%;D0*5 N: :8 %A + @=2( +5 : +( + +=)   + +(6 0 2 10 @ $J6-%M4#/3 +*!) 4< L."-41 +=<% g B0;::)=,# +A >%L& 2$+$J?;/66C,?{# A>6@333HLFP): @*K#> ?,;56 <: %E -'N1! E -9? + 4.*)'.-D&A=',9 +" +< @ '= 4a? 9 2  9+!>68>*"+%!! +;:" F*&"(% ;-5 2 /   0 ! . +6# $&IH  &'($1 +3 +#I =55'30206'5"?F$  , 4F"K:C) 4 1 M/m)k8L.K22 *!/*+!8= 6FG3HG OL%%AN +; 6M>:  @,,!J% 9!."<( +C"J06? ) +?P +M92 +( )< +0+D% E7 )+= C'H,! *//,%F#95:E-CJB 9J . /A & :3, ?I'B 51 /;A032,$ I$-7#K=0I8%HO3!AN@B1 +=9HI 5/1$5-:N&2 N 7I-M#CM58(88FFE9 +<K?GY/<F52&C7F=?6CNF1O="-"0, AE& GCu >$- +INI0J==&$# +; +72< +.74';J,PB =!$5(/;0 +*>(DB!BKO"LAG%G :9H$25 K"" ;*"('0@=6C" > 13*/'37 *M% =F(N8:CK/(E&*H/%FG954) 92FI,'4I2'8KO$(%*# 1#?% +>/7,80IHIGI,2..*N+4A'!K ' $J$J.G +? $6GHN 5> <?AJ< *F c?DC%OGKH$-)9(8M,01O= + O;.#$01>A C1 G/ =% +" +J'7>0.-  I%A  #)<,C'#$<' $*,/:#I70$O)  6 +#E74>7#OD5>&61/,*;%'C"1A  ?,+$$E9 II(H@37.)$)3 +=6"// '2'$+U*5$/0 (;6 '4;(&    14A<!? :+@ / +*! ;:N;<7 C7L9F.5< )"6'BN-76)"F #-]A "7O>G(FN2E.M3!7 +65B #.) ,E +4D7!5+L $2A-F(#"# #?2OL"!: +: OP ->/#<1)Bm= I*A%$1I)2;$A,@- ( ;)P09#7KOocCL&I=FME1y'F>5+K:DD8L;A "@ o%9" DH +9"=_!=:E7 1 3FL"N8IBDLD<? P58I)-7)/'C8?9-1*5&%K& +6PM,9Jy)"%!#1Ig wKA+:F3 D%O1B1.BIB=/-@ +DG %+%(7 +E&* .8) 828& :A  0-(21&"%( (U 79J + 0  2!3)"&$ D6 K! 3:> +*1 &;! ;.5E-8.+')( +*! +#5/ B ?(O  !G5 + H +,m) =3N*35+?I '-+ #.@  * :k= *6$>+D68>K$ J 8 <(A:KF$ )/ 7 ?)L(<(9L9 N&J M'07'DK4! +  NA # 6B +MA "@#@24&CqO =#:?3;181;E +&%&1 1=')<, & %' :  1#!61<9+E8*2 L 5 -  ( ?#=$!1!*?N 0 6%O ).6#%3/)?#EFD 8-64EPH<1 @-.EE535=N'2H!"4JL F& / )%!D% "2M>96H5,"", L8* &22<3((0&!J:'9M #<& +A 7;3)1o1LLL " D.60IF3 C*E 9"?N')@>C"'* +!" 5 .1&!"&648 8?* +)}'3 +&G'-%&  1 ;0A < +D5 !)< 1% .#%JK'E-%+98=%2, %=L +.2*EE%,O2 F :EK#PP,%-7BC +&#/ ++' 4(< !( C+?#4"EKJ:N) +!-  0;B $*-I)&@ < :9%;D0*5 LNN: :8 %A + @=2( +5 : +( + +=)   + (6 0 52 10 @ $5J6-%44##/3 +*!) 4< ."-4A1, +=<% g B0;:A:)=,# +A >%L& 2$+$J;/66C ,?{ +< 6# 7 A>6@333H'LFP): @*K#6> O?,;56 <: %E -'N1F!E -9? + 4.*)'.=-D&A='," +< @ '= 4 a? 9 2  9+!>68>*"+%!! +;:" F*&"(% ;-5 /   0 2! ". +6# $&IH  &'($1 +3 +#I =55'30206'5"?F$  , 4F"K:C 4 1 M/m)k8L.K22 *!/*+!8= 6FG3HG OL%%AN +; 6M>:  @,,!J% 9!%."<#*(/( +C"J06? ) +?P +M92 +( )< +0+D% E7 )+= C'H,! *//?,%F#9NE5:E-CJB8 9J# .$ /A & :3,< ?I'B 51 /;A032,$ I$-7#K=0I8%i+HO3!AN@B1 +=9HI 5/1,$5-:N&2 N 7I-M#CM58(88FFE9A +<K?GY/<F52&C7F=?,6CNF1O="-0, E& GCu >+$- +NI0J=&$# +;H +72 < +.74';J,P>B =!$5(/; +*(DB#!8BKO%3";LAG$%0G :9H-$25 K"" ;!*"('0@=6C" > 13*/'37 2*M% =F(N8:CK/(EL2&*H+/%F0G954) 92. +I,<'4<>I2/'8KO$(,)%*#  + 1#?% +>/7,8)0 OIHIGI,2..*N+4A'!K ' $JJ.G +?+&> $6GHN 5> L<<?AJ< *F c?DC%OGKH$ $-8.)9M,01 + O.D$021>A 1G/ =% +"'7>0.-  I%A + #)< +7C'#$"*<' $*,?1/7$)6 +#4>7#OD5>&61/,*;%'C"1A  ?,+$ $E9 II(H@=37.)$)3 +=6"// '2'$+U*5$!/< 0 (6;! '( +04D;(' +&   1 9/4JA={6 P ; D.  ,M -# ]ACYaG "K C7$O5>GL(52FINA2E.M36!7 +650;># + L+)08 , E +54D7!$ +L'A2 +I-F(#"# #?=42O(LE "!:: D7 + >OP - ?#/<1)Bm!K= - I=*2A% )$1I);$@A,I; (8@)0P#79K#OoGc/1F5'OCIL&=FMEy1'F>05+KD: D8;L A@" o%9" DH"!9)_ *: +  5F",+2*"B9D4F*#= B01 E)) / 4'8** %&$  +6MP,9Jy)"%!#1 wIgD"%+3F & +1O G.B'K.[.B?= =-@ +(+*!!DG% +&"%Ns'7 +E +7&D !8) 82 8 A :)( 0-219F"&.%(J (U  7#$)9D + +60 0 2 ! ?3)" E!@> 8&$" D ?,  5 +:3>8; & +*:1 + Ko,.! 3;5E-1.# +')(! +*F( +#5/ B ?O/ (A !?$EG , +H2 E) mN=3*35+?I ,'-#+ @(.)* * k*/ ? := 8$6+ 2$*#6+.K J8 ;-#;<F(KA: 0/) 7 ?/)C L((0'=-)'  (<,> & %. : +I1 1#!569<N+E8*2 L6 5  -2#3 (  ?%#1=$!?!*N  +0B+ +6%>O )H#6.#%/3?) EO FDO-8E6PH4HP<1 F@*-7B. E;E> 5#-23. 5=N'2CKJAH!"4J L/F4&/  )%!D0" C% 2M9>6. .H5," ", &L8*& 22G<3(!( 0&(J: '9< 9?"5N'@)C>" /'5* +! " .41'&!"&6 88?* +}')3B& +&'G-%&1 E !- ;A 0+< + #D5)#  !# < % 1E,! .5 #%JK'#'.E-6 .%+09;38-&=%L2;9 , %= +.*2,+0?%O2 F B:E0K#PP,%- 7# BC G& +<#/ ++4'' 3(77 <4 !(C5+# "EJ::N+9O) +! ;B-I $2*I&C-"# G& + <A + :"'9%;D0*5 LN NN: :( 8 %A + =@=M2 +( +5 : + +=)  + -(+ 620 5 10 @+ $56J-%8 +"%"44!, # +#)" /+* %3 +$*!), 4< L.B( 4 9717 +,=;%: +%L;> "? &5;0+$J)?O;/6 C4( C ,?{ +  #7?5,6 <:D @% %-'-1 6F. E K-? +9 94 . ! , *)' .=;-D&=3IA=- 'L, 9 + " +< @  '=4 (a?. 4< +; 29  9+>!68*">+%!!:: " F: +,*&"(%/- ; 55/ 32 0 / +/ @ 5 =1 + 2@ @! !. +": 6# $&HI & '($81 +3 +#&I $=55?G3'60H0256'"?I,$+$ F.{ , 4"(5#'0) )!% 4I 1 M/Cm)k? 8.22' *!G/* +>+!8= 6F3D3 G .%'+ +C66M!: '>"5 @,,!+9J% -%.2"<#*( +(/C"! 0J 6 +=;?P +9M +(;2 )< +- /0+D E% 7+) C=7,**,/K?/% 9!B1 NE5:EC-JB98 !J# .$ A/ , /  6$#<'" 1<1H&89J*#$ J44+!@! +!9K!7A 0F+C;#&&.+ 7:w;&7-JFQ $7$OG)-"%%"0}4% 3KA (97 #'0@$3N,@I$ )#/0 /F%i*3! K- @-$152+=71 )/1,$-:&14 . 37%IE#*0CH 5!("69 Fk>$- +1Y?G/-& 5)7 %#,#8 ,1K'#O=" , "0EA& GCu >+$- +INI%0'=GJ# $P<=#&$ +;H +72 < +. 4' 0;8,#-!0BOBME&- 3( /; I0 +H!/*(B# L =.!$H?8.)B K6O%3 ;K AGA %KMI0G (97H-$25 .B") E! *E("'0@=C6 " >1 /3*+'3 /%M 1=F%;8N:/(EL &2-#5DEH.+F%0$0G954)M 9.+12. +FI,<'NBP4<>8I2/'8OK$%/ !(,9)%* #  +1#?%.HB40 5 +/>7,8)0O I +0/*G C +6.,+#( &A!)%2)  J.G +4 H6GN5 ?> L*O<$+0P&21A> & C16 GNG/D< =%" +J +;#7'>.0-  (8. +?9A-!0 +/:*@)GH J!I%A +  #O)<7 +,'C#4$<"* '/$*,?1*4 #:7I$0O) M ? + 6E747>#MOD5&>41/6,*;@% "'A 1HA  ?JI, +/+$ L$ 9  )(!DE&+U3=)7.$)3= +"6/4/ ''$25!*I$ \ No newline at end of file diff --git a/.recommenders/index/http___download_eclipse_org_recommenders_models_luna_/_1.nrm b/.recommenders/index/http___download_eclipse_org_recommenders_models_luna_/_1.nrm new file mode 100644 index 0000000..f756001 --- /dev/null +++ b/.recommenders/index/http___download_eclipse_org_recommenders_models_luna_/_1.nrm @@ -0,0 +1 @@ +NRM|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||vvvvv|vw|yvvyyv|v|||v|vvy|vvyvvvvv|v||vvvvvv|vvvvvvyvv|v|vyv|vvvv|vv|vvvvvvvvvv|||yv|v||vv|v|vvvwvvvy|vv|vvvvvvvvv|vv|vvvvv|vvv||vvvvvvyyvvvv|vvvv|vvvvv|vvv|vv|v|v|v||||vvvvvvvv|v|vv|vvv|vvv||vvvy||vw||yvyvvvvvvvvvvvvv||vvv||v|vvvv|yyv||vvyvvvvvvvvyv||vvyvv|vv|vvvv|vvvvvv|vyvvv||v|vvvvvv|||y|v|vvvvv|||v|yvv|v|wvvy|vvvvvv|||yv|vvyvv|vv|vvvv|vv|vvvv||w|vv|vvyv|vyvvvvvvvvvvvv|vv||vvvvvyv|xvv|vv|yv|vv|vvvvvv|vvvyvyv|vv|vvvvvvvv|v|vvv|v|yvvv|vvvvvvv|vvvv||yvvvvvvvwvw||v|y|vyv||vvvvvvvvyv|||vv|vvvvvyy|vvvvv|vvvvvv|vv|v|yv|vvvwvv|v|vvv|vvv|vvvvvvv|vyvvvvvwv|vyvvv||v|vv|vvvvvvvvv|wvvv|vvvvv||v|vvvvvvvvvyv|v||wvvvvv|vyvvv|||vv||vvvvwvvvvvvvv||vvvvwvvvvvv|yv|vv|vv|vv|vvvvyvvvv|vvvyyyvvv|vv|vvvvvv||vvvv|vvv|v|||v|v||vv|vvvvvvvv||vv|vvv|vvvvvvy|vvv|vyvvvv||v||v|vvwvv||vv|v|v|vvyvv|vv||vvv||vvvv||vvv||||vwvvvvv|vvvvvvvv|v|v|||vvvyvvv|vvvv|||vv|vvvvvwvv|vvwv|v|v|vvyyvvvvv|v|v|||vyvv|vvv|vwvwvvvv|v|v|vvvvvv||vvvyv|vvvv|vvvvvvv|||vvvvvy|yv|v||vvv|vvvv||vv|v||vvv|||v|vvvv||vv|vvvvv|vvvvvv|vv|vvvv|||vvvv|vvvyvv||vvvv||v|vvvvvvvy|y|vv||vvv|v|v|v|yvvvvvvvv|||v||vvv||v||vv|vvvv|||v||v||v|vvvyv|vvvvwvv|||v|vv||vv|vvvvvvvv||v|vvvv|yvvvvv|yvvvy|v|vvvv|vvvvvvvv|||vvvvvvvyv|vvvvvv||vvvvvvvvvvvvvvvvv|vvyv|vwwvvv|vvvvvvyvv|v|vvvy|||vvvv||vwvwv|vvvvvvyyy|vvwvvvvvv|vvy|w|vvvvvvvvv||vvv|vv||vv|vvyv|v||vvyvv|v|v|vvvwvvvvyv|vvvxvvvv|vv|vv|vvv|vvv||vvv|yvvwvvwvvvvvv|vv|vwvvvvvvvvv||vvv|vy||v||v|vyvvvvvvvwvy|vvwv|v||vvvv|vvv|v||vvyvv|v|v|v||v|vvv||vvvv|yvv|vywwvvvvvvwvvvvvv||v|vvvv|v|v|vvv|yvv|v|v|vvvvv|y|||vvvvvvvvvvvvvvvvvy|yy|vvvvvyvvvvvvvvvvvv|y||v|vvvvvvvvvvvwv|vvv|vvv|vvvvvv|v||vvv|vvvv|y|vvyvvvvy|vvvvv||vvvvv|vvvvvvvy||vvvv|vvvyvvv|vvyv|yv|v|vwv|v|vvvv|v|vvvv||v|vv|vvvv||vvvvvwvvv|v|vvv||vv|vv|vvvyvv|wvvvv|||||vvvv|yv|vv||vvv|vvv|yvvyvv|v|vvvvvvvvvvyvvvvvyvv||vvv|vvy|vvv|vvwv|vvvvvv|vvvvvvv|v|vvvv|vvvvv||yvvvvvvvvv|y||vvvvvvvvvv|vv|vvv|||vv|vwyvvvv|wvvv|vvv|vwvy|v|w|v|vvyv|v|vwyv|yvv|v|vvvvvvw||v||vv|vvv|vvvvvvvvvwvvvv||||v|||||v|yv|vvv|vv|yv|v|vvvv||vvyvvv|||vvvv|v|vvy|v|vwvv|v|yv|vv||v|v|y|vvvv|v|v|v|v|vvvv|vvvvy|vv||y|vw||vvw|v|vvvvv|vvwv|vv|vy|vvvvvvvvvv|yvwv||vv|vvvv|vvvvwv||v|vy|v|v|vvv|vvv|vvvv||y|vvvv|vvv|vv|v|||vvvvv|wy|vvvvvv||vvvyvvvvvy||v||vv|||v||vvvvyvvvvvvvvwv|v||yv||vvvv|v||vvvy|vv||vyyvyvv||vvv|vvvv|vvv|vvvvv|v|v|vv||vvvv|vvv|vvvvvvvyv|||vvvy|vvvvy|v|vvv||vyvvvvvyvvvv|vwvvw||vvvvvvvvvyvwvv|v|vvvvvv|vv||y|vv||vvv|y||vvv||||vvvy|vvv|vwyv|yvvvv|y|vv|||vvvvv|vvyvvv|v|||vvvvvvvvvvvvvvvv|vyvvvvv|v|vvvvv|v|vvvvvvvvvvvv|yw|wyvvv||vv|||vv||vyvv|v|vv|vv|vvvyvvvvvvvyvv|vvvvvvvvvvw|v||v||v|vvv|vvv||vvv|vvv|vvvv|vyvyvvyvvv|vvvvvvv||vvvvv|vv|vvvvvv|v||vvvvvvv||vwvvvvvvvvv|vvvyv|vv|vv||vvvv|v|v|yv|vvvwvyvv|vvvvv|w||vvyvv|vy|vvyvyvv|vvvvy|wv|vyyvvvv|v|vvy|vvv|yy|vv|vv||wvv|vvvvvvvv|||yvv||vv|v|vvy|vvvvvvvv||vvvvvv|vvv|vvv|v|vvvvv|vvv|vvv||w|vv|v||yv|v|v|vv|yvvvvv|vyyvvvv|vvyvvv|vvw|vv|vwyvy|vv|vvvvvvwvvv|yvvvvvvv|vvyvvvvvvvv|vvvwv|vv|yvvvvvvwvyv||vvvvv|y||||v|vvvvvvvvvv||yv|vv|||||||vv|vvv|||vvvvvv|vvvvvv|yvvvvvv|vvvvvvvvvyvyv||v|v|v|v|vvvv|vv||||v|v||vwvvv|v|v|||vv|vvvv|||v|vvyv|||vyvvvvvyv|vv||vvvvyvvvv||||v|vy||v|v|vv|||vvvvvvv|vvv|vvv||vvwvvvv||yv|vvv||y|v|vvv|vvvv|vvvvvvv||vv|vvv||v|vyvyv|vwv|v|v|vv|vv|yvvvv|v|vvv|vv|vv|vvyvvvvvvvvv|vyvyyvvvv|vvvvvv||vvv|vvvv||v||wvvvvvvvvvvvvvvvvvvv|vy|vyv|y|wvyw|||vw|vvv|vvvvv||vvyvv|vv|vv|||vvvvy|vv||v|vv||v||vvw|vvv|vvvvv|||vvvvvv|vv|v|vv||v||vvwvvvvvvvvv|vvvvvv|yv||vv|vvv|v|v||wvw|vw|vv|vvvv|vv|yvvvvvvvvv|vvv|vvvvvvvwvvvv|vv||v||wvvvvvv|vvvvvvvvv|y|vv|vvvvv|vvwv||v|vv|vvvv|v|vvvvvv|vyv|v|vvvvvvyv|vvy|vv|vvvvvvv|vvvv|||v||vvvvvvvvv|vvvvvvvvvwvv|v|yyw|vv|wvv|v|yvvx|vvy|vvvvyvvwvvvyvvvvvv|vvvvvvvvvvv|v|v||v|vvvyvvvvvv|||vvyw|y|v|v|v||vv|vv|v|vvvyvyvvvv|vvvv|yyv|vvvvvyvvvvvv|vvvv|vvyvvvvvvvvvvv|yvvvy|vvvv|yv|||yw|v|vv|vv|vwvyvvvvvv|v|vvvyvv||yvvvvv|vvvvvvvvwvvvv|vvvvv|vvvwyvvvvv|v|yvvvvvvvvv|v||v|vv||w||vvvv|v||||vv|v||vv|vv|v||v|v|vvv|vvvvv||v||vvvv|vvvv||v|v|vvvvvyvvyvvvv|||v|vvvvvvwv|vvy|vvvvwvvv|v|vvvyvvvvvvvvvy|y|vvwwyvvvvv|v||vvwvvvv|vvvvvvvvv|vvwvv|v|vvvv|vvvvv|vvvvv|vvyvvvvvvvyvvvyvvv|vv|v|vvvvvvvv|vvv|vvvv|vvvvvyv|wvvvvvv|vvv|yvvvvv|||v|vvv|vvvyyv||vvvvvvvvv|yvvv|vv||vvvvvv|w|vvvvv|y|v|vvvvw|vvvvvvvvvv|v|vvv||v|vv|vvvyvvyv|v||vvyvvvv|vvvvvv||v|vv|vwv|vv|y|vvvv|v|vw||v|vyvy|v|vyvvvvvvv|vvvv||vvvvvyvvvvv|vv|y||v||vvvvv|v|ywvvv|vvv|v|vvvwvv|vvv|vvvvvy|vyvvvvv|||v|vv|y|v|v|vvvv|vy||v|||vv|||vv|vvvvvvvvvvvv|vv|vvvvvwvvvvv|v||vvvvvvv|vvvv|||vv|||vvvvvvv||v|vwvv|vwv||vvy||vy||||vv|ywvvvv|||vvwv||v||vyvyvvvv|vvvv|v||vv|wvvv|v|vvvv|vyvvvvwvvvyvy||||v|yvv|vyv||yvvvvv|vvv|v|vvv||vvvvv|vvv|vvvvvwvv|y|vvvvvvv|vv|vvvvwvvvvvvvvvvv|vvvyvvv|vwv|vvv|yw|vv|yyv|yvvvvvvv|y|vvvvv|vvvv|vyvy||||v|vwv|yvv|vvvvvwxvv||vvw|v|vvv|vvvv|v|vv|vvvvvvvv||||vv|vvv|v|vy|vvvv|vvvvvvvvv|v|vvvwvvv|y|vvvvvyvvvvv|wyyvvvv|v|vvvvvv||||vvv|||vvvvvvvv|vwvwvy|vwv|yvy|v|yvvvvvv|v|vvvvvvvvv|vvvv|wvvvvvv|vvvvvvvv|vvv|v|yvvvv|vw|v||vvyv|vv|vvvvv|y|wy|v|vvvv|||vvvvyvvvvv|vvv|vvvv|vv|vv||v|||||vv|vvvv|vvv|w|v|vvv|vvvvvv|vvvv|vvvvvvvvv|v|yyv|vv||vvv|w|y|v|y|vvv|vvvvvvvv|vvvvvwvvv|vvyvvv|yv|v|vvv|vvv|v|v|v|v|||v|vv||v||vy|vvvv|||vvvyvvvvyv|vvvv|vvvvvv|||vvvvvvvvvv||vvvv|vv|vvvv|vv|yv|vvvvvvvvvy|vv|vy|vvvv|v|vvvvw||vv||y|wv||v|vvvvv|y||v|vvvvv|vyyyvyvv||vv|v|v|v|vv|vvv|vv|vyv|v|vyyvv|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| \ No newline at end of file diff --git a/.recommenders/index/http___download_eclipse_org_recommenders_models_luna_/_1.prx b/.recommenders/index/http___download_eclipse_org_recommenders_models_luna_/_1.prx new file mode 100644 index 0000000..37b83ae Binary files /dev/null and b/.recommenders/index/http___download_eclipse_org_recommenders_models_luna_/_1.prx differ diff --git a/.recommenders/index/http___download_eclipse_org_recommenders_models_luna_/_1.tii b/.recommenders/index/http___download_eclipse_org_recommenders_models_luna_/_1.tii new file mode 100644 index 0000000..a21e151 Binary files /dev/null and b/.recommenders/index/http___download_eclipse_org_recommenders_models_luna_/_1.tii differ diff --git a/.recommenders/index/http___download_eclipse_org_recommenders_models_luna_/_1.tis b/.recommenders/index/http___download_eclipse_org_recommenders_models_luna_/_1.tis new file mode 100644 index 0000000..cec602b Binary files /dev/null and b/.recommenders/index/http___download_eclipse_org_recommenders_models_luna_/_1.tis differ diff --git a/.recommenders/index/http___download_eclipse_org_recommenders_models_luna_/segments.gen b/.recommenders/index/http___download_eclipse_org_recommenders_models_luna_/segments.gen new file mode 100644 index 0000000..225a55b Binary files /dev/null and b/.recommenders/index/http___download_eclipse_org_recommenders_models_luna_/segments.gen differ diff --git a/.recommenders/index/http___download_eclipse_org_recommenders_models_luna_/segments_2 b/.recommenders/index/http___download_eclipse_org_recommenders_models_luna_/segments_2 new file mode 100644 index 0000000..6345472 Binary files /dev/null and b/.recommenders/index/http___download_eclipse_org_recommenders_models_luna_/segments_2 differ diff --git a/.recommenders/index/http___download_eclipse_org_recommenders_models_luna_/write.lock b/.recommenders/index/http___download_eclipse_org_recommenders_models_luna_/write.lock new file mode 100644 index 0000000..e69de29 diff --git a/.recommenders/repository/http___download_eclipse_org_recommenders_models_luna_/org/eclipse/recommenders/index/0.0.0-SNAPSHOT/_remote.repositories b/.recommenders/repository/http___download_eclipse_org_recommenders_models_luna_/org/eclipse/recommenders/index/0.0.0-SNAPSHOT/_remote.repositories new file mode 100644 index 0000000..f3c5702 --- /dev/null +++ b/.recommenders/repository/http___download_eclipse_org_recommenders_models_luna_/org/eclipse/recommenders/index/0.0.0-SNAPSHOT/_remote.repositories @@ -0,0 +1,3 @@ +#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice. +#Sat Dec 20 00:28:34 CET 2014 +index-0.0.0-20140605.014212-1.zip>models= diff --git a/.recommenders/repository/http___download_eclipse_org_recommenders_models_luna_/org/eclipse/recommenders/index/0.0.0-SNAPSHOT/index-0.0.0-20140605.014212-1.zip b/.recommenders/repository/http___download_eclipse_org_recommenders_models_luna_/org/eclipse/recommenders/index/0.0.0-SNAPSHOT/index-0.0.0-20140605.014212-1.zip new file mode 100644 index 0000000..1bd4917 Binary files /dev/null and b/.recommenders/repository/http___download_eclipse_org_recommenders_models_luna_/org/eclipse/recommenders/index/0.0.0-SNAPSHOT/index-0.0.0-20140605.014212-1.zip differ diff --git a/.recommenders/repository/http___download_eclipse_org_recommenders_models_luna_/org/eclipse/recommenders/index/0.0.0-SNAPSHOT/maven-metadata-models.xml b/.recommenders/repository/http___download_eclipse_org_recommenders_models_luna_/org/eclipse/recommenders/index/0.0.0-SNAPSHOT/maven-metadata-models.xml new file mode 100644 index 0000000..9f95b90 --- /dev/null +++ b/.recommenders/repository/http___download_eclipse_org_recommenders_models_luna_/org/eclipse/recommenders/index/0.0.0-SNAPSHOT/maven-metadata-models.xml @@ -0,0 +1,20 @@ + + + org.eclipse.recommenders + index + 0.0.0-SNAPSHOT + + + 20140605.014212 + 1 + + 20140605014212 + + + zip + 0.0.0-20140605.014212-1 + 20140605014212 + + + + diff --git a/.recommenders/repository/http___download_eclipse_org_recommenders_models_luna_/org/eclipse/recommenders/index/0.0.0-SNAPSHOT/resolver-status.properties b/.recommenders/repository/http___download_eclipse_org_recommenders_models_luna_/org/eclipse/recommenders/index/0.0.0-SNAPSHOT/resolver-status.properties new file mode 100644 index 0000000..c4ff861 --- /dev/null +++ b/.recommenders/repository/http___download_eclipse_org_recommenders_models_luna_/org/eclipse/recommenders/index/0.0.0-SNAPSHOT/resolver-status.properties @@ -0,0 +1,3 @@ +#NOTE: This is an Aether internal implementation file, its format can be changed without prior notice. +#Sat Dec 20 02:06:11 CET 2014 +maven-metadata-models.xml.lastUpdated=1419037571226 diff --git a/MiBand/.classpath b/MiBand/.classpath new file mode 100644 index 0000000..7bc01d9 --- /dev/null +++ b/MiBand/.classpath @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/MiBand/.project b/MiBand/.project new file mode 100644 index 0000000..ed8820a --- /dev/null +++ b/MiBand/.project @@ -0,0 +1,33 @@ + + + MiBand + + + + + + com.android.ide.eclipse.adt.ResourceManagerBuilder + + + + + com.android.ide.eclipse.adt.PreCompilerBuilder + + + + + org.eclipse.jdt.core.javabuilder + + + + + com.android.ide.eclipse.adt.ApkBuilder + + + + + + com.android.ide.eclipse.adt.AndroidNature + org.eclipse.jdt.core.javanature + + diff --git a/MiBand/.settings/org.eclipse.jdt.core.prefs b/MiBand/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..b080d2d --- /dev/null +++ b/MiBand/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,4 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/MiBand/AndroidManifest.xml b/MiBand/AndroidManifest.xml new file mode 100644 index 0000000..610501e --- /dev/null +++ b/MiBand/AndroidManifest.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MiBand/bin/AndroidManifest.xml b/MiBand/bin/AndroidManifest.xml new file mode 100644 index 0000000..610501e --- /dev/null +++ b/MiBand/bin/AndroidManifest.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MiBand/bin/MiBand.apk b/MiBand/bin/MiBand.apk new file mode 100644 index 0000000..d176ed5 Binary files /dev/null and b/MiBand/bin/MiBand.apk differ diff --git a/MiBand/bin/classes.dex b/MiBand/bin/classes.dex new file mode 100644 index 0000000..05d2acf Binary files /dev/null and b/MiBand/bin/classes.dex differ diff --git a/MiBand/bin/classes/com/motioncoding/debugging/L$LogType.class b/MiBand/bin/classes/com/motioncoding/debugging/L$LogType.class new file mode 100644 index 0000000..0fca381 Binary files /dev/null and b/MiBand/bin/classes/com/motioncoding/debugging/L$LogType.class differ diff --git a/MiBand/bin/classes/com/motioncoding/debugging/L.class b/MiBand/bin/classes/com/motioncoding/debugging/L.class new file mode 100644 index 0000000..613b797 Binary files /dev/null and b/MiBand/bin/classes/com/motioncoding/debugging/L.class differ diff --git a/MiBand/bin/classes/com/motioncoding/miband/BuildConfig.class b/MiBand/bin/classes/com/motioncoding/miband/BuildConfig.class new file mode 100644 index 0000000..d27f008 Binary files /dev/null and b/MiBand/bin/classes/com/motioncoding/miband/BuildConfig.class differ diff --git a/MiBand/bin/classes/com/motioncoding/miband/MiActivity$1.class b/MiBand/bin/classes/com/motioncoding/miband/MiActivity$1.class new file mode 100644 index 0000000..be3e82f Binary files /dev/null and b/MiBand/bin/classes/com/motioncoding/miband/MiActivity$1.class differ diff --git a/MiBand/bin/classes/com/motioncoding/miband/MiActivity.class b/MiBand/bin/classes/com/motioncoding/miband/MiActivity.class new file mode 100644 index 0000000..2be7796 Binary files /dev/null and b/MiBand/bin/classes/com/motioncoding/miband/MiActivity.class differ diff --git a/MiBand/bin/classes/com/motioncoding/miband/MiLeParamsActivity.class b/MiBand/bin/classes/com/motioncoding/miband/MiLeParamsActivity.class new file mode 100644 index 0000000..f7dc2e3 Binary files /dev/null and b/MiBand/bin/classes/com/motioncoding/miband/MiLeParamsActivity.class differ diff --git a/MiBand/bin/classes/com/motioncoding/miband/MiOverviewActivity$1.class b/MiBand/bin/classes/com/motioncoding/miband/MiOverviewActivity$1.class new file mode 100644 index 0000000..29503ec Binary files /dev/null and b/MiBand/bin/classes/com/motioncoding/miband/MiOverviewActivity$1.class differ diff --git a/MiBand/bin/classes/com/motioncoding/miband/MiOverviewActivity$2.class b/MiBand/bin/classes/com/motioncoding/miband/MiOverviewActivity$2.class new file mode 100644 index 0000000..0fdbaa6 Binary files /dev/null and b/MiBand/bin/classes/com/motioncoding/miband/MiOverviewActivity$2.class differ diff --git a/MiBand/bin/classes/com/motioncoding/miband/MiOverviewActivity.class b/MiBand/bin/classes/com/motioncoding/miband/MiOverviewActivity.class new file mode 100644 index 0000000..c60d5d1 Binary files /dev/null and b/MiBand/bin/classes/com/motioncoding/miband/MiOverviewActivity.class differ diff --git a/MiBand/bin/classes/com/motioncoding/miband/R$attr.class b/MiBand/bin/classes/com/motioncoding/miband/R$attr.class new file mode 100644 index 0000000..bb3516d Binary files /dev/null and b/MiBand/bin/classes/com/motioncoding/miband/R$attr.class differ diff --git a/MiBand/bin/classes/com/motioncoding/miband/R$drawable.class b/MiBand/bin/classes/com/motioncoding/miband/R$drawable.class new file mode 100644 index 0000000..09efd51 Binary files /dev/null and b/MiBand/bin/classes/com/motioncoding/miband/R$drawable.class differ diff --git a/MiBand/bin/classes/com/motioncoding/miband/R$id.class b/MiBand/bin/classes/com/motioncoding/miband/R$id.class new file mode 100644 index 0000000..88b0820 Binary files /dev/null and b/MiBand/bin/classes/com/motioncoding/miband/R$id.class differ diff --git a/MiBand/bin/classes/com/motioncoding/miband/R$layout.class b/MiBand/bin/classes/com/motioncoding/miband/R$layout.class new file mode 100644 index 0000000..8d1a57d Binary files /dev/null and b/MiBand/bin/classes/com/motioncoding/miband/R$layout.class differ diff --git a/MiBand/bin/classes/com/motioncoding/miband/R$menu.class b/MiBand/bin/classes/com/motioncoding/miband/R$menu.class new file mode 100644 index 0000000..1b030b2 Binary files /dev/null and b/MiBand/bin/classes/com/motioncoding/miband/R$menu.class differ diff --git a/MiBand/bin/classes/com/motioncoding/miband/R$string.class b/MiBand/bin/classes/com/motioncoding/miband/R$string.class new file mode 100644 index 0000000..27747df Binary files /dev/null and b/MiBand/bin/classes/com/motioncoding/miband/R$string.class differ diff --git a/MiBand/bin/classes/com/motioncoding/miband/R$style.class b/MiBand/bin/classes/com/motioncoding/miband/R$style.class new file mode 100644 index 0000000..c06de6e Binary files /dev/null and b/MiBand/bin/classes/com/motioncoding/miband/R$style.class differ diff --git a/MiBand/bin/classes/com/motioncoding/miband/R.class b/MiBand/bin/classes/com/motioncoding/miband/R.class new file mode 100644 index 0000000..4ffc8e1 Binary files /dev/null and b/MiBand/bin/classes/com/motioncoding/miband/R.class differ diff --git a/MiBand/bin/classes/com/motioncoding/miband/model/Battery$Status.class b/MiBand/bin/classes/com/motioncoding/miband/model/Battery$Status.class new file mode 100644 index 0000000..3d4f633 Binary files /dev/null and b/MiBand/bin/classes/com/motioncoding/miband/model/Battery$Status.class differ diff --git a/MiBand/bin/classes/com/motioncoding/miband/model/Battery.class b/MiBand/bin/classes/com/motioncoding/miband/model/Battery.class new file mode 100644 index 0000000..496605c Binary files /dev/null and b/MiBand/bin/classes/com/motioncoding/miband/model/Battery.class differ diff --git a/MiBand/bin/classes/com/motioncoding/miband/model/LeParams$1.class b/MiBand/bin/classes/com/motioncoding/miband/model/LeParams$1.class new file mode 100644 index 0000000..d9a1287 Binary files /dev/null and b/MiBand/bin/classes/com/motioncoding/miband/model/LeParams$1.class differ diff --git a/MiBand/bin/classes/com/motioncoding/miband/model/LeParams.class b/MiBand/bin/classes/com/motioncoding/miband/model/LeParams.class new file mode 100644 index 0000000..3d6eb1f Binary files /dev/null and b/MiBand/bin/classes/com/motioncoding/miband/model/LeParams.class differ diff --git a/MiBand/bin/classes/com/motioncoding/miband/model/MiBand.class b/MiBand/bin/classes/com/motioncoding/miband/model/MiBand.class new file mode 100644 index 0000000..344671b Binary files /dev/null and b/MiBand/bin/classes/com/motioncoding/miband/model/MiBand.class differ diff --git a/MiBand/bin/classes/com/motioncoding/miband/view/ColorPickerDialog$1.class b/MiBand/bin/classes/com/motioncoding/miband/view/ColorPickerDialog$1.class new file mode 100644 index 0000000..3deffa4 Binary files /dev/null and b/MiBand/bin/classes/com/motioncoding/miband/view/ColorPickerDialog$1.class differ diff --git a/MiBand/bin/classes/com/motioncoding/miband/view/ColorPickerDialog$ColorPickerView.class b/MiBand/bin/classes/com/motioncoding/miband/view/ColorPickerDialog$ColorPickerView.class new file mode 100644 index 0000000..71ce284 Binary files /dev/null and b/MiBand/bin/classes/com/motioncoding/miband/view/ColorPickerDialog$ColorPickerView.class differ diff --git a/MiBand/bin/classes/com/motioncoding/miband/view/ColorPickerDialog$OnColorChangedListener.class b/MiBand/bin/classes/com/motioncoding/miband/view/ColorPickerDialog$OnColorChangedListener.class new file mode 100644 index 0000000..5a06606 Binary files /dev/null and b/MiBand/bin/classes/com/motioncoding/miband/view/ColorPickerDialog$OnColorChangedListener.class differ diff --git a/MiBand/bin/classes/com/motioncoding/miband/view/ColorPickerDialog.class b/MiBand/bin/classes/com/motioncoding/miband/view/ColorPickerDialog.class new file mode 100644 index 0000000..8d46998 Binary files /dev/null and b/MiBand/bin/classes/com/motioncoding/miband/view/ColorPickerDialog.class differ diff --git a/MiBand/bin/dexedLibs/android-support-v4-30a8292059eb8e12a9fe0cd4181a4ef1.jar b/MiBand/bin/dexedLibs/android-support-v4-30a8292059eb8e12a9fe0cd4181a4ef1.jar new file mode 100644 index 0000000..9939cdf Binary files /dev/null and b/MiBand/bin/dexedLibs/android-support-v4-30a8292059eb8e12a9fe0cd4181a4ef1.jar differ diff --git a/MiBand/bin/jarlist.cache b/MiBand/bin/jarlist.cache new file mode 100644 index 0000000..0565465 --- /dev/null +++ b/MiBand/bin/jarlist.cache @@ -0,0 +1,3 @@ +# cache for current jar dependency. DO NOT EDIT. +# format is +# Encoding is UTF-8 diff --git a/MiBand/bin/res/crunch/drawable-hdpi/ic_launcher.png b/MiBand/bin/res/crunch/drawable-hdpi/ic_launcher.png new file mode 100644 index 0000000..415cf3f Binary files /dev/null and b/MiBand/bin/res/crunch/drawable-hdpi/ic_launcher.png differ diff --git a/MiBand/bin/res/crunch/drawable-mdpi/ic_launcher.png b/MiBand/bin/res/crunch/drawable-mdpi/ic_launcher.png new file mode 100644 index 0000000..a2c5aef Binary files /dev/null and b/MiBand/bin/res/crunch/drawable-mdpi/ic_launcher.png differ diff --git a/MiBand/bin/res/crunch/drawable-xhdpi/ic_launcher.png b/MiBand/bin/res/crunch/drawable-xhdpi/ic_launcher.png new file mode 100644 index 0000000..9912694 Binary files /dev/null and b/MiBand/bin/res/crunch/drawable-xhdpi/ic_launcher.png differ diff --git a/MiBand/bin/res/crunch/drawable-xxhdpi/ic_launcher.png b/MiBand/bin/res/crunch/drawable-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..33eb6c0 Binary files /dev/null and b/MiBand/bin/res/crunch/drawable-xxhdpi/ic_launcher.png differ diff --git a/MiBand/bin/res/crunch/drawable-xxhdpi/searching_mili_icon.png b/MiBand/bin/res/crunch/drawable-xxhdpi/searching_mili_icon.png new file mode 100644 index 0000000..31b56dd Binary files /dev/null and b/MiBand/bin/res/crunch/drawable-xxhdpi/searching_mili_icon.png differ diff --git a/MiBand/bin/resources.ap_ b/MiBand/bin/resources.ap_ new file mode 100644 index 0000000..7402af2 Binary files /dev/null and b/MiBand/bin/resources.ap_ differ diff --git a/MiBand/gen/com/motioncoding/miband/BuildConfig.java b/MiBand/gen/com/motioncoding/miband/BuildConfig.java new file mode 100644 index 0000000..28a6137 --- /dev/null +++ b/MiBand/gen/com/motioncoding/miband/BuildConfig.java @@ -0,0 +1,6 @@ +/** Automatically generated file. DO NOT MODIFY */ +package com.motioncoding.miband; + +public final class BuildConfig { + public final static boolean DEBUG = true; +} \ No newline at end of file diff --git a/MiBand/gen/com/motioncoding/miband/R.java b/MiBand/gen/com/motioncoding/miband/R.java new file mode 100644 index 0000000..0e878a1 --- /dev/null +++ b/MiBand/gen/com/motioncoding/miband/R.java @@ -0,0 +1,59 @@ +/* AUTO-GENERATED FILE. DO NOT MODIFY. + * + * This class was automatically generated by the + * aapt tool from the resource data it found. It + * should not be modified by hand. + */ + +package com.motioncoding.miband; + +public final class R { + public static final class attr { + } + public static final class drawable { + public static final int ic_launcher=0x7f020000; + public static final int searching_mili_icon=0x7f020001; + } + public static final class id { + public static final int action_ledcolor=0x7f070007; + public static final int action_leparams=0x7f070006; + public static final int image_miscan=0x7f070000; + public static final int laoding=0x7f070002; + public static final int textHolder=0x7f070003; + public static final int text_battery_level=0x7f070005; + public static final int text_search=0x7f070001; + public static final int text_steps=0x7f070004; + } + public static final class layout { + public static final int activity_mi=0x7f030000; + public static final int activity_mi_overview=0x7f030001; + } + public static final class menu { + public static final int menu_overview=0x7f060000; + } + public static final class string { + public static final int app_name=0x7f040000; + public static final int hello_world=0x7f040001; + public static final int looking_for_miband=0x7f040004; + public static final int not_found=0x7f040002; + public static final int title_activity_mi_le_params=0x7f040005; + public static final int title_activity_mi_overview=0x7f040003; + } + public static final class style { + /** + Base application theme, dependent on API level. This theme is replaced + by AppBaseTheme from res/values-vXX/styles.xml on newer devices. + + + Theme customizations available in newer API levels can go in + res/values-vXX/styles.xml, while customizations related to + backward-compatibility can go here. + + */ + public static final int AppBaseTheme=0x7f050000; + /** Application theme. + All customizations that are NOT specific to a particular API-level can go here. + */ + public static final int AppTheme=0x7f050001; + } +} diff --git a/MiBand/ic_launcher-web.png b/MiBand/ic_launcher-web.png new file mode 100644 index 0000000..9ff23e5 Binary files /dev/null and b/MiBand/ic_launcher-web.png differ diff --git a/MiBand/libs/android-support-v4.jar b/MiBand/libs/android-support-v4.jar new file mode 100644 index 0000000..4ebdaa9 Binary files /dev/null and b/MiBand/libs/android-support-v4.jar differ diff --git a/MiBand/proguard-project.txt b/MiBand/proguard-project.txt new file mode 100644 index 0000000..f2fe155 --- /dev/null +++ b/MiBand/proguard-project.txt @@ -0,0 +1,20 @@ +# To enable ProGuard in your project, edit project.properties +# to define the proguard.config property as described in that file. +# +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in ${sdk.dir}/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the ProGuard +# include property in project.properties. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/MiBand/project.properties b/MiBand/project.properties new file mode 100644 index 0000000..6e18427 --- /dev/null +++ b/MiBand/project.properties @@ -0,0 +1,14 @@ +# This file is automatically generated by Android Tools. +# Do not modify this file -- YOUR CHANGES WILL BE ERASED! +# +# This file must be checked in Version Control Systems. +# +# To customize properties used by the Ant build system edit +# "ant.properties", and override values to adapt the script to your +# project structure. +# +# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): +#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt + +# Project target. +target=android-21 diff --git a/MiBand/res/drawable-hdpi/ic_launcher.png b/MiBand/res/drawable-hdpi/ic_launcher.png new file mode 100644 index 0000000..8610fb1 Binary files /dev/null and b/MiBand/res/drawable-hdpi/ic_launcher.png differ diff --git a/MiBand/res/drawable-mdpi/ic_launcher.png b/MiBand/res/drawable-mdpi/ic_launcher.png new file mode 100644 index 0000000..d328782 Binary files /dev/null and b/MiBand/res/drawable-mdpi/ic_launcher.png differ diff --git a/MiBand/res/drawable-xhdpi/ic_launcher.png b/MiBand/res/drawable-xhdpi/ic_launcher.png new file mode 100644 index 0000000..ec81539 Binary files /dev/null and b/MiBand/res/drawable-xhdpi/ic_launcher.png differ diff --git a/MiBand/res/drawable-xxhdpi/ic_launcher.png b/MiBand/res/drawable-xxhdpi/ic_launcher.png new file mode 100644 index 0000000..66c6fd1 Binary files /dev/null and b/MiBand/res/drawable-xxhdpi/ic_launcher.png differ diff --git a/MiBand/res/drawable-xxhdpi/searching_mili_icon.png b/MiBand/res/drawable-xxhdpi/searching_mili_icon.png new file mode 100644 index 0000000..31b56dd Binary files /dev/null and b/MiBand/res/drawable-xxhdpi/searching_mili_icon.png differ diff --git a/MiBand/res/layout/activity_mi.xml b/MiBand/res/layout/activity_mi.xml new file mode 100644 index 0000000..d4ca30e --- /dev/null +++ b/MiBand/res/layout/activity_mi.xml @@ -0,0 +1,26 @@ + + + + + + + diff --git a/MiBand/res/layout/activity_mi_overview.xml b/MiBand/res/layout/activity_mi_overview.xml new file mode 100644 index 0000000..1c0894d --- /dev/null +++ b/MiBand/res/layout/activity_mi_overview.xml @@ -0,0 +1,55 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/MiBand/res/menu/menu_overview.xml b/MiBand/res/menu/menu_overview.xml new file mode 100644 index 0000000..c01307a --- /dev/null +++ b/MiBand/res/menu/menu_overview.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/MiBand/res/values/strings.xml b/MiBand/res/values/strings.xml new file mode 100644 index 0000000..21f7bcb --- /dev/null +++ b/MiBand/res/values/strings.xml @@ -0,0 +1,11 @@ + + + + MiBand + Hello world! + MiBand not found. Is it in range? + MiOverviewActivity + Looking for MiBand + MiLeParamsActivity + + diff --git a/MiBand/res/values/styles.xml b/MiBand/res/values/styles.xml new file mode 100644 index 0000000..003224e --- /dev/null +++ b/MiBand/res/values/styles.xml @@ -0,0 +1,21 @@ + + + + + + + + + diff --git a/MiBand/src/com/motioncoding/debugging/L.java b/MiBand/src/com/motioncoding/debugging/L.java new file mode 100644 index 0000000..883afb6 --- /dev/null +++ b/MiBand/src/com/motioncoding/debugging/L.java @@ -0,0 +1,65 @@ +package com.motioncoding.debugging; + +import android.content.Context; +import android.util.Log; +import android.widget.Toast; + +public class L { + + public static enum LogType { + CLASS, CLASS_AND_METHOD, CLASS_AND_METHOD_AND_LINE, CLASS_AND_LINE + } + + private static LogType mType = LogType.CLASS_AND_METHOD; + + + public static void toast(Context context, String msg) { + Toast.makeText(context, msg, Toast.LENGTH_SHORT).show(); + } + + public static void setLogType(LogType type) { + mType = type; + } + + public static void e(String msg) { + Log.e(getTag(), msg); + } + + public static void i(String msg) { + Log.i(getTag(), msg); + } + + public static void d(String msg) { + Log.d(getTag(), msg); + } + + public static void v(String msg) { + Log.v(getTag(), msg); + } + + public static void w(String msg) { + Log.w(getTag(), msg); + } + + public static void wtf(String msg) { + Log.wtf(getTag(), msg); + } + + private static String getTag() { + StackTraceElement[] s = Thread.currentThread().getStackTrace(); + switch (mType) { + case CLASS: + return s[4].getClassName(); + case CLASS_AND_LINE: + return s[4].getClassName()+":"+s[4].getLineNumber(); + case CLASS_AND_METHOD: + return s[4].getClassName()+"."+s[4].getMethodName(); + case CLASS_AND_METHOD_AND_LINE: + return s[4].getClassName()+"."+s[4].getMethodName()+":"+s[4].getLineNumber(); + default: + break; + } + return null; + } +} + diff --git a/MiBand/src/com/motioncoding/miband/MiActivity.java b/MiBand/src/com/motioncoding/miband/MiActivity.java new file mode 100644 index 0000000..8a26cb2 --- /dev/null +++ b/MiBand/src/com/motioncoding/miband/MiActivity.java @@ -0,0 +1,81 @@ +package com.motioncoding.miband; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothAdapter.LeScanCallback; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothManager; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.widget.TextView; + +public class MiActivity extends Activity implements LeScanCallback { + + private BluetoothAdapter mBluetoothAdapter; + private boolean mScanning; + private TextView mTextView; + private Handler mHandler = new Handler(); + // Stops scanning after 10 seconds. + private static final long SCAN_PERIOD = 10000; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + setContentView(R.layout.activity_mi); + mTextView = (TextView) findViewById(R.id.text_search); + mBluetoothAdapter = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)) + .getAdapter(); + } + + @Override + public void onResume() { + super.onResume(); + scanLeDevice(true); + } + + @SuppressWarnings("deprecation") + // L Apis are buggy and crap! + private void scanLeDevice(final boolean enable) { + if (enable) { + mTextView.setText(R.string.looking_for_miband); + // Stops scanning after a pre-defined scan period. + mHandler.postDelayed(new Runnable() { + + @Override + public void run() { + mScanning = false; + mBluetoothAdapter.stopLeScan(MiActivity.this); + mTextView.setText(R.string.not_found); + } + }, SCAN_PERIOD); + + mScanning = true; + mBluetoothAdapter.startLeScan(this); + } else { + mScanning = false; + mBluetoothAdapter.stopLeScan(this); + } + } + + @Override + public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { + if (device != null && device.getName() != null + & device.getName().equals("MI")) { + System.out.println(device.getAddress()); + scanLeDevice(false); // we only care about one miband so that's + // enough + Intent intent = new Intent(getApplicationContext(), MiOverviewActivity.class); + intent.putExtra("address", device.getAddress()); + startActivity(intent); + } + } + + @Override + public void onPause() { + super.onPause(); + scanLeDevice(false); + } +} diff --git a/MiBand/src/com/motioncoding/miband/MiLeParamsActivity.java b/MiBand/src/com/motioncoding/miband/MiLeParamsActivity.java new file mode 100644 index 0000000..637ab37 --- /dev/null +++ b/MiBand/src/com/motioncoding/miband/MiLeParamsActivity.java @@ -0,0 +1,33 @@ +package com.motioncoding.miband; + +import android.app.ListActivity; +import android.os.Bundle; +import android.widget.ArrayAdapter; + +import com.motioncoding.miband.model.LeParams; + +public class MiLeParamsActivity extends ListActivity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + getActionBar().hide(); + + LeParams params = (LeParams) getIntent().getParcelableExtra("params"); + + String[] values = new String[6]; + + values[0] = String.format("Connection Intervall\n%s ms", params.connInt); + values[1] = String.format("Connection Intervall Min\n%s ms", params.connIntMin); + values[2] = String.format("Connection Intervall Max\n%s ms", params.connIntMax); + + values[3] = String.format("Advertising Intervall\n%s ms", params.advInt); + values[4] = String.format("Latency\n%s ms", params.latency); + values[5] = String.format("Timeout\n%s ms", params.timeout); + + + ArrayAdapter adapter = new ArrayAdapter(this, + android.R.layout.simple_list_item_1, values); + this.setListAdapter(adapter); + } +} diff --git a/MiBand/src/com/motioncoding/miband/MiOverviewActivity.java b/MiBand/src/com/motioncoding/miband/MiOverviewActivity.java new file mode 100644 index 0000000..453083f --- /dev/null +++ b/MiBand/src/com/motioncoding/miband/MiOverviewActivity.java @@ -0,0 +1,241 @@ +package com.motioncoding.miband; + +import java.util.Arrays; +import java.util.Observable; +import java.util.Observer; +import java.util.UUID; + +import android.app.Activity; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; +import android.content.Context; +import android.content.Intent; +import android.graphics.Color; +import android.os.Bundle; +import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.TextView; + +import com.motioncoding.debugging.L; +import com.motioncoding.miband.model.Battery; +import com.motioncoding.miband.model.LeParams; +import com.motioncoding.miband.model.MiBand; +import com.motioncoding.miband.view.ColorPickerDialog; + +public class MiOverviewActivity extends Activity implements Observer { + + private static final UUID UUID_MILI_SERVICE = UUID + .fromString("0000fee0-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_pair = UUID + .fromString("0000ff0f-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_CONTROL_POINT = UUID + .fromString("0000ff05-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_REALTIME_STEPS = UUID + .fromString("0000ff06-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_ACTIVITY = UUID + .fromString("0000ff07-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_LE_PARAMS = UUID + .fromString("0000ff09-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_DEVICE_NAME = UUID + .fromString("0000ff02-0000-1000-8000-00805f9b34fb"); + private static final UUID UUID_CHAR_BATTERY = UUID + .fromString("0000ff0c-0000-1000-8000-00805f9b34fb"); + + // BLUETOOTH + private String mDeviceAddress; + private BluetoothManager mBluetoothManager; + private BluetoothAdapter mBluetoothAdapter; + private BluetoothDevice mBluetoothMi; + private BluetoothGatt mGatt; + + private MiBand mMiBand = new MiBand(); + + // UI + private TextView mTVSteps; + private TextView mTVBatteryLevel; + private ProgressBar mLoading; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + mDeviceAddress = getIntent().getStringExtra("address"); + + mMiBand.addObserver(this); + mMiBand.mBTAddress = mDeviceAddress; + + setContentView(R.layout.activity_mi_overview); + + mTVSteps = (TextView) findViewById(R.id.text_steps); + mTVBatteryLevel = (TextView) findViewById(R.id.text_battery_level); + mLoading = (ProgressBar) findViewById(R.id.laoding); + + mBluetoothManager = ((BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE)); + mBluetoothAdapter = mBluetoothManager.getAdapter(); + mBluetoothMi = mBluetoothAdapter.getRemoteDevice(mDeviceAddress); + + } + + @Override + public void onResume() { + super.onResume(); + mGatt = mBluetoothMi.connectGatt(this, false, mGattCallback); + mGatt.connect(); + } + + @Override + public void onPause() { + super.onPause(); + mGatt.disconnect(); + mGatt.close(); + mGatt = null; + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.menu_overview, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case R.id.action_leparams: + if(mMiBand.mLeParams == null) { + L.toast(this, "No LE params received yet"); + return true; + } + Intent intent = new Intent(getApplicationContext(), MiLeParamsActivity.class); + intent.putExtra("params", mMiBand.mLeParams); + startActivity(intent); + break; + case R.id.action_ledcolor: + new ColorPickerDialog(this, null, "", Color.BLUE, Color.RED).show(); + break; + } + return true; + } + + private void pair() { + + BluetoothGattCharacteristic chrt = getMiliService().getCharacteristic( + UUID_CHAR_pair); + + chrt.setValue(new byte[] { 2 }); + + mGatt.writeCharacteristic(chrt); + System.out.println("pair sent"); + } + + private void request(UUID what) { + mGatt.readCharacteristic(getMiliService().getCharacteristic(what)); + } + + private void setColor(byte r, byte g, byte b) { + BluetoothGattCharacteristic theme = getMiliService().getCharacteristic( + UUID_CHAR_CONTROL_POINT); + theme.setValue(new byte[] { 14, r, g, b, 0 }); + mGatt.writeCharacteristic(theme); + } + + private BluetoothGattService getMiliService() { + return mGatt.getService(UUID_MILI_SERVICE); + + } + + private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { + + int state = 0; + + @Override + public void onServicesDiscovered(BluetoothGatt gatt, int status) { + if (status == BluetoothGatt.GATT_SUCCESS) { + pair(); + } + + } + + @Override + public void onConnectionStateChange(BluetoothGatt gatt, int status, + int newState) { + if (newState == BluetoothProfile.STATE_CONNECTED) { + gatt.discoverServices(); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + // this is called tight after pair() + // setColor((byte)127, (byte)0, (byte)0); + request(UUID_CHAR_REALTIME_STEPS); // start with steps + } + + @Override + public void onCharacteristicRead(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + byte[] b = characteristic.getValue(); + Log.i(characteristic.getUuid().toString(), "state: " + state + + " value:" + Arrays.toString(b)); + + // handle value + if (characteristic.getUuid().equals(UUID_CHAR_REALTIME_STEPS)) + mMiBand.setSteps(0xff & b[0] | (0xff & b[1]) << 8); + else if (characteristic.getUuid().equals(UUID_CHAR_BATTERY)) { + Battery battery = Battery.fromByte(b); + mMiBand.setBattery(battery); + } else if (characteristic.getUuid().equals(UUID_CHAR_DEVICE_NAME)) { + mMiBand.setName(new String(b)); + } else if (characteristic.getUuid().equals(UUID_CHAR_LE_PARAMS)) { + LeParams params = LeParams.fromByte(b); + mMiBand.setLeParams(params); + } + + // proceed with state machine (called in the beginning) + state++; + switch (state) { + case 0: + request(UUID_CHAR_REALTIME_STEPS); + break; + case 1: + request(UUID_CHAR_BATTERY); + break; + case 2: + request(UUID_CHAR_DEVICE_NAME); + break; + case 3: + request(UUID_CHAR_LE_PARAMS); + break; + } + } + }; + + @Override + public void update(Observable observable, Object data) { + runOnUiThread(new Runnable() { + + @Override + public void run() { + mLoading.setVisibility(View.GONE); + ((LinearLayout) findViewById(R.id.textHolder)) + .setVisibility(View.VISIBLE); + mTVSteps.setText(mMiBand.mSteps + ""); + if (mMiBand.mBattery != null) + mTVBatteryLevel.setText(mMiBand.mBattery.mBatteryLevel + + "%"); + } + }); + } + +} diff --git a/MiBand/src/com/motioncoding/miband/model/Battery.java b/MiBand/src/com/motioncoding/miband/model/Battery.java new file mode 100644 index 0000000..7c27188 --- /dev/null +++ b/MiBand/src/com/motioncoding/miband/model/Battery.java @@ -0,0 +1,53 @@ +package com.motioncoding.miband.model; + +import java.util.Calendar; + +public class Battery { + public int mBatteryLevel; + public int mCycles; + public Calendar mLastCharged; + public Status mStatus; + + public static Battery fromByte(byte[] b) { + Battery battery = new Battery(); + battery.mBatteryLevel = b[0]; + battery.mStatus = Status.fromByte(b[9]); + battery.mLastCharged = Calendar.getInstance(); + + battery.mLastCharged.set(Calendar.YEAR, b[1]+2000); + battery.mLastCharged.set(Calendar.MONTH, b[2]); + battery.mLastCharged.set(Calendar.DATE, b[3]); + + battery.mLastCharged.set(Calendar.HOUR_OF_DAY, b[4]); + battery.mLastCharged.set(Calendar.MINUTE, b[5]); + battery.mLastCharged.set(Calendar.SECOND, b[6]); + + battery.mCycles = 0xffff & (0xff & b[7] | (0xff & b[8]) << 8); + return battery; + } + + @Override + public String toString() { + return String.format("Level: %s Cycles: %s State: %s Last Charged: %s", mBatteryLevel, mCycles, mStatus.toString(), mLastCharged.toString()); + } + + static enum Status { + LOW, FULL, CHARGING, NOT_CHARGING; + + public static Status fromByte(byte b) { + switch (b) { + case 1: + return LOW; + case 2: + return CHARGING; + case 3: + return FULL; + case 4: + return NOT_CHARGING; + + default: + return null; + } + } + } +} \ No newline at end of file diff --git a/MiBand/src/com/motioncoding/miband/model/LeParams.java b/MiBand/src/com/motioncoding/miband/model/LeParams.java new file mode 100644 index 0000000..5589def --- /dev/null +++ b/MiBand/src/com/motioncoding/miband/model/LeParams.java @@ -0,0 +1,71 @@ +package com.motioncoding.miband.model; + +import android.os.Parcel; +import android.os.Parcelable; + +public class LeParams implements Parcelable { + public int connIntMin; + public int connIntMax; + public int connInt; + + public int latency; + public int timeout; + public int advInt; + + public static LeParams fromByte(byte[] b) { + LeParams params = new LeParams(); + + params.connIntMax = 0xffff & (0xff & b[0] | (0xff & b[1]) << 8); + params.connIntMax = 0xffff & (0xff & b[2] | (0xff & b[3]) << 8); + params.latency = 0xffff & (0xff & b[4] | (0xff & b[5]) << 8); + params.timeout = 0xffff & (0xff & b[6] | (0xff & b[7]) << 8); + params.connInt = 0xffff & (0xff & b[8] | (0xff & b[9]) << 8); + params.advInt = 0xffff & (0xff & b[10] | (0xff & b[11]) << 8); + + params.connIntMin *= 1.25; + params.connIntMax *= 1.25; + params.advInt *= 0.625; + params.timeout *= 10; + + return params; + } + + protected LeParams() {} + + protected LeParams(Parcel in) { + connIntMin = in.readInt(); + connIntMax = in.readInt(); + latency = in.readInt(); + timeout = in.readInt(); + connInt = in.readInt(); + advInt = in.readInt(); + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(connIntMin); + dest.writeInt(connIntMax); + dest.writeInt(latency); + dest.writeInt(timeout); + dest.writeInt(connInt); + dest.writeInt(advInt); + } + + @SuppressWarnings("unused") + public static final Parcelable.Creator CREATOR = new Parcelable.Creator() { + @Override + public LeParams createFromParcel(Parcel in) { + return new LeParams(in); + } + + @Override + public LeParams[] newArray(int size) { + return new LeParams[size]; + } + }; +} \ No newline at end of file diff --git a/MiBand/src/com/motioncoding/miband/model/MiBand.java b/MiBand/src/com/motioncoding/miband/model/MiBand.java new file mode 100644 index 0000000..749f58b --- /dev/null +++ b/MiBand/src/com/motioncoding/miband/model/MiBand.java @@ -0,0 +1,43 @@ +package com.motioncoding.miband.model; + +import java.util.Observable; + +import com.motioncoding.debugging.L; + + +public class MiBand extends Observable { + + public String mBTAddress; + public int mSteps; + public String mName; + public Battery mBattery; + public LeParams mLeParams; + + + + public void setName(String name) { + mName = name; + L.i("setting "+name+" as BLE name"); + setChanged(); + notifyObservers(); + } + + public void setSteps(int steps) { + mSteps = steps; + L.i("setting "+steps+" steps"); + setChanged(); + notifyObservers(); + } + + public void setBattery(Battery battery) { + mBattery = battery; + L.i(battery.toString()); + setChanged(); + notifyObservers(); + } + + public void setLeParams(LeParams params) { + mLeParams = params; + } + +} diff --git a/MiBand/src/com/motioncoding/miband/view/ColorPickerDialog.java b/MiBand/src/com/motioncoding/miband/view/ColorPickerDialog.java new file mode 100644 index 0000000..3c0eefa --- /dev/null +++ b/MiBand/src/com/motioncoding/miband/view/ColorPickerDialog.java @@ -0,0 +1,304 @@ +package com.motioncoding.miband.view; + +import android.R; +import android.app.Dialog; +import android.content.Context; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.LinearGradient; +import android.graphics.Paint; +import android.graphics.Shader; +import android.os.Bundle; +import android.view.MotionEvent; +import android.view.View; + +public class ColorPickerDialog extends Dialog { + + public interface OnColorChangedListener { + void colorChanged(String key, int color); + } + + private OnColorChangedListener mListener; + private int mInitialColor, mDefaultColor; + private String mKey; + + private static class ColorPickerView extends View { + private Paint mPaint; + private float mCurrentHue = 0; + private int mCurrentX = 0, mCurrentY = 0; + private int mCurrentColor, mDefaultColor; + private final int[] mHueBarColors = new int[258]; + private int[] mMainColors = new int[65536]; + private OnColorChangedListener mListener; + + ColorPickerView(Context c, OnColorChangedListener l, int color, + int defaultColor) { + super(c); + mListener = l; + mDefaultColor = defaultColor; + + // Get the current hue from the current color and update the main + // color field + float[] hsv = new float[3]; + Color.colorToHSV(color, hsv); + mCurrentHue = hsv[0]; + updateMainColors(); + + mCurrentColor = color; + + // Initialize the colors of the hue slider bar + int index = 0; + for (float i = 0; i < 256; i += 256 / 42) // Red (#f00) to pink + // (#f0f) + { + mHueBarColors[index] = Color.rgb(255, 0, (int) i); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) // Pink (#f0f) to blue + // (#00f) + { + mHueBarColors[index] = Color.rgb(255 - (int) i, 0, 255); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) // Blue (#00f) to light + // blue (#0ff) + { + mHueBarColors[index] = Color.rgb(0, (int) i, 255); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) // Light blue (#0ff) to + // green (#0f0) + { + mHueBarColors[index] = Color.rgb(0, 255, 255 - (int) i); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) // Green (#0f0) to yellow + // (#ff0) + { + mHueBarColors[index] = Color.rgb((int) i, 255, 0); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) // Yellow (#ff0) to red + // (#f00) + { + mHueBarColors[index] = Color.rgb(255, 255 - (int) i, 0); + index++; + } + + // Initializes the Paint that will draw the View + mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); + mPaint.setTextAlign(Paint.Align.CENTER); + mPaint.setTextSize(12); + } + + // Get the current selected color from the hue bar + private int getCurrentMainColor() { + int translatedHue = 255 - (int) (mCurrentHue * 255 / 360); + int index = 0; + for (float i = 0; i < 256; i += 256 / 42) { + if (index == translatedHue) + return Color.rgb(255, 0, (int) i); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) { + if (index == translatedHue) + return Color.rgb(255 - (int) i, 0, 255); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) { + if (index == translatedHue) + return Color.rgb(0, (int) i, 255); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) { + if (index == translatedHue) + return Color.rgb(0, 255, 255 - (int) i); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) { + if (index == translatedHue) + return Color.rgb((int) i, 255, 0); + index++; + } + for (float i = 0; i < 256; i += 256 / 42) { + if (index == translatedHue) + return Color.rgb(255, 255 - (int) i, 0); + index++; + } + return Color.RED; + } + + // Update the main field colors depending on the current selected hue + private void updateMainColors() { + int mainColor = getCurrentMainColor(); + int index = 0; + int[] topColors = new int[256]; + for (int y = 0; y < 256; y++) { + for (int x = 0; x < 256; x++) { + if (y == 0) { + mMainColors[index] = Color.rgb( + 255 - (255 - Color.red(mainColor)) * x / 255, + 255 - (255 - Color.green(mainColor)) * x / 255, + 255 - (255 - Color.blue(mainColor)) * x / 255); + topColors[x] = mMainColors[index]; + } else + mMainColors[index] = Color.rgb( + (255 - y) * Color.red(topColors[x]) / 255, + (255 - y) * Color.green(topColors[x]) / 255, + (255 - y) * Color.blue(topColors[x]) / 255); + index++; + } + } + } + + @Override + protected void onDraw(Canvas canvas) { + int translatedHue = 255 - (int) (mCurrentHue * 255 / 360); + // Display all the colors of the hue bar with lines + for (int x = 0; x < 256; x++) { + // If this is not the current selected hue, display the actual + // color + if (translatedHue != x) { + mPaint.setColor(mHueBarColors[x]); + mPaint.setStrokeWidth(1); + } else // else display a slightly larger black line + { + mPaint.setColor(Color.BLACK); + mPaint.setStrokeWidth(3); + } + canvas.drawLine(x + 10, 0, x + 10, 40, mPaint); + // canvas.drawLine(0, x+10, 40, x+10, mPaint); + } + + // Display the main field colors using LinearGradient + for (int x = 0; x < 256; x++) { + int[] colors = new int[2]; + colors[0] = mMainColors[x]; + colors[1] = Color.BLACK; + Shader shader = new LinearGradient(0, 50, 0, 306, colors, null, + Shader.TileMode.REPEAT); + mPaint.setShader(shader); + canvas.drawLine(x + 10, 50, x + 10, 306, mPaint); + } + mPaint.setShader(null); + + // Display the circle around the currently selected color in the + // main field + if (mCurrentX != 0 && mCurrentY != 0) { + mPaint.setStyle(Paint.Style.STROKE); + mPaint.setColor(Color.BLACK); + canvas.drawCircle(mCurrentX, mCurrentY, 10, mPaint); + } + + // Draw a 'button' with the currently selected color + mPaint.setStyle(Paint.Style.FILL); + mPaint.setColor(mCurrentColor); + canvas.drawRect(10, 316, 138, 356, mPaint); + + // Set the text color according to the brightness of the color + if (Color.red(mCurrentColor) + Color.green(mCurrentColor) + + Color.blue(mCurrentColor) < 384) + mPaint.setColor(Color.WHITE); + else + mPaint.setColor(Color.BLACK); + canvas.drawText("bg", 74, 340, mPaint); + + // Draw a 'button' with the default color + mPaint.setStyle(Paint.Style.FILL); + mPaint.setColor(mDefaultColor); + canvas.drawRect(138, 316, 266, 356, mPaint); + + // Set the text color according to the brightness of the color + if (Color.red(mDefaultColor) + Color.green(mDefaultColor) + + Color.blue(mDefaultColor) < 384) + mPaint.setColor(Color.WHITE); + else + mPaint.setColor(Color.BLACK); + canvas.drawText("def", 202, 340, mPaint); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + setMeasuredDimension(276, 366); + } + + @Override + public boolean onTouchEvent(MotionEvent event) { + if (event.getAction() != MotionEvent.ACTION_DOWN) + return true; + float x = event.getX(); + float y = event.getY(); + + // If the touch event is located in the hue bar + if (x > 10 && x < 266 && y > 0 && y < 40) { + // Update the main field colors + mCurrentHue = (255 - x) * 360 / 255; + updateMainColors(); + + // Update the current selected color + int transX = mCurrentX - 10; + int transY = mCurrentY - 60; + int index = 256 * (transY - 1) + transX; + if (index > 0 && index < mMainColors.length) + mCurrentColor = mMainColors[256 * (transY - 1) + transX]; + + // Force the redraw of the dialog + invalidate(); + } + + // If the touch event is located in the main field + if (x > 10 && x < 266 && y > 50 && y < 306) { + mCurrentX = (int) x; + mCurrentY = (int) y; + int transX = mCurrentX - 10; + int transY = mCurrentY - 60; + int index = 256 * (transY - 1) + transX; + if (index > 0 && index < mMainColors.length) { + // Update the current color + mCurrentColor = mMainColors[index]; + // Force the redraw of the dialog + invalidate(); + } + } + + // If the touch event is located in the left button, notify the + // listener with the current color + if (x > 10 && x < 138 && y > 316 && y < 356) + mListener.colorChanged("", mCurrentColor); + + // If the touch event is located in the right button, notify the + // listener with the default color + if (x > 138 && x < 266 && y > 316 && y < 356) + mListener.colorChanged("", mDefaultColor); + + return true; + } + } + + public ColorPickerDialog(Context context, OnColorChangedListener listener, + String key, int initialColor, int defaultColor) { + super(context); + + mListener = listener; + mKey = key; + mInitialColor = initialColor; + mDefaultColor = defaultColor; + } + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + OnColorChangedListener l = new OnColorChangedListener() { + public void colorChanged(String key, int color) { + if (mListener != null) + mListener.colorChanged(mKey, color); + dismiss(); + } + }; + + setContentView(new ColorPickerView(getContext(), l, mInitialColor, + mDefaultColor)); + setTitle("Set LED Color"); + + } +} \ No newline at end of file