Skip to content

Commit add6bd2

Browse files
committed
CGMS profile added, ver 1.18.0
+ minor fixes
1 parent 173de83 commit add6bd2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

45 files changed

+1778
-35
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ It contains applications demonstrating Bluetooth Smart profiles:
99
* **Blood Pressure Monitor**,
1010
* **Health Thermometer Monitor**,
1111
* **Glucose Monitor**,
12+
* **Continuous Glucose Monitor**,
1213
* **Proximity Monitor**.
1314

1415
Since version 1.10.0 the *nRF Toolbox* also supports the **Nordic UART Service** which may be used for bidirectional text communication between devices.

app/build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@ android {
88
applicationId "no.nordicsemi.android.nrftoolbox"
99
minSdkVersion 18
1010
targetSdkVersion 24
11-
versionCode 46
12-
versionName "1.17.0"
11+
versionCode 47
12+
versionName "1.18.0"
1313
}
1414
buildTypes {
1515
release {

app/src/main/AndroidManifest.xml

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
~ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
2020
~ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
2121
~ USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
22-
-->
22+
-->
2323
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
2424
package="no.nordicsemi.android.nrftoolbox"
2525
android:installLocation="auto">
@@ -201,6 +201,16 @@
201201
<category android:name="no.nordicsemi.android.nrftoolbox.LAUNCHER" />
202202
</intent-filter>
203203
</activity>
204+
<activity android:name="no.nordicsemi.android.nrftoolbox.cgms.CGMSActivity"
205+
android:icon="@drawable/ic_cgms_feature"
206+
android:label="@string/cgms_feature_title"
207+
android:launchMode="singleTask">
208+
<intent-filter>
209+
<action android:name="android.intent.action.MAIN" />
210+
211+
<category android:name="no.nordicsemi.android.nrftoolbox.LAUNCHER" />
212+
</intent-filter>
213+
</activity>
204214

205215
<service
206216
android:name="no.nordicsemi.android.nrftoolbox.proximity.ProximityService"
@@ -228,6 +238,9 @@
228238
</intent-filter>
229239
</activity>
230240

241+
<service
242+
android:name="no.nordicsemi.android.nrftoolbox.cgms.CGMService"
243+
android:label="@string/cgms_feature_title" />
231244
<service
232245
android:name="no.nordicsemi.android.nrftoolbox.rsc.RSCService"
233246
android:label="@string/rsc_feature_title" />
Lines changed: 292 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,292 @@
1+
/*
2+
* Copyright (c) 2016, Nordic Semiconductor
3+
* All rights reserved.
4+
*
5+
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6+
*
7+
* 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
8+
*
9+
* 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the
10+
* documentation and/or other materials provided with the distribution.
11+
*
12+
* 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this
13+
* software without specific prior written permission.
14+
*
15+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
17+
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
18+
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
19+
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
20+
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
21+
*/
22+
23+
package no.nordicsemi.android.nrftoolbox.cgms;
24+
25+
import android.content.BroadcastReceiver;
26+
import android.content.Context;
27+
import android.content.Intent;
28+
import android.content.IntentFilter;
29+
import android.os.Bundle;
30+
import android.support.v4.content.LocalBroadcastManager;
31+
import android.util.SparseArray;
32+
import android.view.MenuInflater;
33+
import android.view.MenuItem;
34+
import android.view.View;
35+
import android.widget.ListView;
36+
import android.widget.PopupMenu;
37+
import android.widget.TextView;
38+
39+
import java.util.UUID;
40+
41+
import no.nordicsemi.android.nrftoolbox.R;
42+
import no.nordicsemi.android.nrftoolbox.profile.BleProfileService;
43+
import no.nordicsemi.android.nrftoolbox.profile.BleProfileServiceReadyActivity;
44+
45+
public class CGMSActivity extends BleProfileServiceReadyActivity<CGMService.CGMSBinder> implements PopupMenu.OnMenuItemClickListener {
46+
47+
private View mControlPanelStd;
48+
private View mControlPanelAbort;
49+
private TextView mUnitView;
50+
private ListView mRecordsListView;
51+
private CGMSRecordsAdapter mCgmsRecordsAdapter;
52+
53+
private CGMService.CGMSBinder mBinder;
54+
55+
@Override
56+
protected void onCreateView(Bundle savedInstanceState) {
57+
setContentView(R.layout.activity_feature_cgms);
58+
setGUI();
59+
}
60+
61+
@Override
62+
protected void onInitialize(Bundle savedInstanceState) {
63+
LocalBroadcastManager.getInstance(this).registerReceiver(mBroadcastReceiver, makeIntentFilter());
64+
}
65+
66+
private void setGUI() {
67+
mRecordsListView = (ListView) findViewById(R.id.list);
68+
mUnitView = (TextView) findViewById(R.id.unit);
69+
mControlPanelStd = findViewById(R.id.cgms_control_std);
70+
mControlPanelAbort = findViewById(R.id.cgms_control_abort);
71+
72+
findViewById(R.id.action_last).setOnClickListener(new View.OnClickListener() {
73+
@Override
74+
public void onClick(View v) {
75+
clearRecords();
76+
if(mBinder != null) {
77+
mBinder.clear();
78+
mBinder.getLastRecord();
79+
}
80+
}
81+
});
82+
findViewById(R.id.action_all).setOnClickListener(new View.OnClickListener() {
83+
@Override
84+
public void onClick(View v) {
85+
clearRecords();
86+
if(mBinder != null){
87+
clearRecords();
88+
mBinder.getAllRecords();
89+
}
90+
}
91+
});
92+
findViewById(R.id.action_abort).setOnClickListener(new View.OnClickListener() {
93+
@Override
94+
public void onClick(View v) {
95+
if(mBinder != null){
96+
mBinder.abort();
97+
}
98+
}
99+
});
100+
101+
// create popup menu attached to the button More
102+
findViewById(R.id.action_more).setOnClickListener(new View.OnClickListener() {
103+
@Override
104+
public void onClick(View v) {
105+
PopupMenu menu = new PopupMenu(CGMSActivity.this, v);
106+
menu.setOnMenuItemClickListener(CGMSActivity.this);
107+
MenuInflater inflater = menu.getMenuInflater();
108+
inflater.inflate(R.menu.gls_more, menu.getMenu());
109+
menu.show();
110+
}
111+
});
112+
}
113+
114+
private void loadAdapter(SparseArray<CGMSRecord> records){
115+
for(int i = 0; i < records.size(); i++){
116+
mCgmsRecordsAdapter.addItem(records.get(i));
117+
}
118+
mCgmsRecordsAdapter.notifyDataSetChanged();
119+
}
120+
121+
@Override
122+
protected void onDestroy() {
123+
super.onDestroy();
124+
LocalBroadcastManager.getInstance(this).unregisterReceiver(mBroadcastReceiver);
125+
}
126+
127+
@Override
128+
protected void onServiceBinded(CGMService.CGMSBinder binder) {
129+
mBinder = binder;
130+
SparseArray<CGMSRecord> cgmsRecords = binder.getCgmsRecords();
131+
if(cgmsRecords != null && cgmsRecords.size() > 0){
132+
if(mCgmsRecordsAdapter == null) {
133+
mCgmsRecordsAdapter = new CGMSRecordsAdapter(CGMSActivity.this);
134+
mRecordsListView.setAdapter(mCgmsRecordsAdapter);
135+
}
136+
loadAdapter(cgmsRecords);
137+
}
138+
}
139+
140+
@Override
141+
protected void onServiceUnbinded() {
142+
mBinder = null;
143+
}
144+
145+
@Override
146+
protected Class<? extends BleProfileService> getServiceClass() {
147+
return CGMService.class;
148+
}
149+
150+
@Override
151+
protected int getLoggerProfileTitle() {
152+
return R.string.cgms_feature_title;
153+
}
154+
155+
@Override
156+
protected int getAboutTextId() {
157+
return R.string.cgms_about_text;
158+
}
159+
160+
@Override
161+
protected int getDefaultDeviceName() {
162+
return R.string.cgms_default_name;
163+
}
164+
165+
@Override
166+
protected UUID getFilterUUID() {
167+
return CGMSManager.CGMS_UUID;
168+
}
169+
170+
@Override
171+
public void onServicesDiscovered(final boolean optionalServicesFound) {
172+
// this may notify user or show some views
173+
}
174+
175+
@Override
176+
public void onDeviceReady() {
177+
178+
}
179+
180+
private void setOperationInProgress(final boolean progress) {
181+
runOnUiThread(new Runnable() {
182+
@Override
183+
public void run() {
184+
// setSupportProgressBarIndeterminateVisibility(progress);
185+
mControlPanelStd.setVisibility(!progress ? View.VISIBLE : View.GONE);
186+
mControlPanelAbort.setVisibility(progress ? View.VISIBLE : View.GONE);
187+
}
188+
});
189+
}
190+
191+
@Override
192+
public void onDeviceDisconnected() {
193+
super.onDeviceDisconnected();
194+
setOperationInProgress(false);
195+
clearRecords();
196+
}
197+
198+
@Override
199+
protected void setDefaultUI() {
200+
201+
}
202+
203+
@Override
204+
public boolean onMenuItemClick(MenuItem menuItem) {
205+
switch (menuItem.getItemId()) {
206+
case R.id.action_refresh:
207+
/*if(mBinder != null)
208+
mBinder.refreshRecords();*/
209+
break;
210+
case R.id.action_first:
211+
clearRecords();
212+
if(mBinder != null)
213+
mBinder.getFirstRecord();
214+
break;
215+
case R.id.action_clear:
216+
clearRecords();
217+
if(mBinder != null)
218+
mBinder.clear();
219+
break;
220+
case R.id.action_delete_all:
221+
clearRecords();
222+
if(mBinder != null)
223+
mBinder.deleteAllRecords();
224+
break;
225+
}
226+
return true;
227+
}
228+
229+
private void clearRecords(){
230+
runOnUiThread(new Runnable() {
231+
@Override
232+
public void run() {
233+
if(mCgmsRecordsAdapter != null){
234+
mCgmsRecordsAdapter.clear();
235+
mCgmsRecordsAdapter.notifyDataSetChanged();
236+
}
237+
}
238+
});
239+
}
240+
241+
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
242+
@Override
243+
public void onReceive(final Context context, final Intent intent) {
244+
final String action = intent.getAction();
245+
if (CGMService.BROADCAST_CGMS_VALUES.equals(action)) {
246+
CGMSRecord cgmsRecord = intent.getExtras().getParcelable(CGMService.EXTRA_CGMS_RECORD);
247+
if(mCgmsRecordsAdapter == null){
248+
mCgmsRecordsAdapter = new CGMSRecordsAdapter(CGMSActivity.this);
249+
mRecordsListView.setAdapter(mCgmsRecordsAdapter);
250+
}
251+
mCgmsRecordsAdapter.addItem(cgmsRecord);
252+
mCgmsRecordsAdapter.notifyDataSetChanged();
253+
254+
} else if (CGMService.BROADCAST_DATA_SET_CHANGED.equals(action)) {
255+
// Update GUI
256+
clearRecords();
257+
} else if (CGMService.OPERATION_STARTED.equals(action)) {
258+
// Update GUI
259+
setOperationInProgress(true);
260+
} else if (CGMService.OPERATION_COMPLETED.equals(action)) {
261+
// Update GUI
262+
setOperationInProgress(false);
263+
} else if (CGMService.OPERATION_SUPPORTED.equals(action)) {
264+
// Update GUI
265+
setOperationInProgress(false);
266+
} else if (CGMService.OPERATION_NOT_SUPPORTED.equals(action)) {
267+
// Update GUI
268+
setOperationInProgress(false);
269+
} else if (CGMService.OPERATION_ABORTED.equals(action)) {
270+
// Update GUI
271+
setOperationInProgress(false);
272+
} else if (CGMService.OPERATION_FAILED.equals(action)) {
273+
// Update GUI
274+
setOperationInProgress(false);
275+
showToast(R.string.gls_operation_failed);
276+
}
277+
}
278+
};
279+
280+
private static IntentFilter makeIntentFilter() {
281+
final IntentFilter intentFilter = new IntentFilter();
282+
intentFilter.addAction(CGMService.BROADCAST_CGMS_VALUES);
283+
intentFilter.addAction(CGMService.BROADCAST_DATA_SET_CHANGED);
284+
intentFilter.addAction(CGMService.OPERATION_STARTED);
285+
intentFilter.addAction(CGMService.OPERATION_COMPLETED);
286+
intentFilter.addAction(CGMService.OPERATION_SUPPORTED);
287+
intentFilter.addAction(CGMService.OPERATION_NOT_SUPPORTED);
288+
intentFilter.addAction(CGMService.OPERATION_ABORTED);
289+
intentFilter.addAction(CGMService.OPERATION_FAILED);
290+
return intentFilter;
291+
}
292+
}

0 commit comments

Comments
 (0)