|
1 | 1 | package com.medavox.diabeticdiary; |
2 | 2 |
|
| 3 | +import android.Manifest; |
| 4 | +import android.content.pm.PackageManager; |
| 5 | +import android.os.Build; |
| 6 | +import android.provider.Telephony; |
3 | 7 | import android.support.v7.app.AppCompatActivity; |
4 | 8 | import android.os.Bundle; |
| 9 | +import android.telephony.SmsManager; |
| 10 | +import android.text.InputFilter; |
| 11 | +import android.text.Spanned; |
| 12 | +import android.util.Log; |
| 13 | +import android.view.View; |
| 14 | +import android.widget.Button; |
| 15 | +import android.widget.CheckBox; |
5 | 16 | import android.widget.EditText; |
6 | 17 | import android.widget.TableLayout; |
| 18 | + |
| 19 | +import com.medavox.util.validate.Validator; |
| 20 | + |
| 21 | +import java.util.regex.Matcher; |
| 22 | +import java.util.regex.Pattern; |
| 23 | + |
| 24 | +import static com.medavox.util.validate.Validator.check; |
7 | 25 | //todo: import numberpicker module from https://github.com/SimonVT/android-numberpicker, |
8 | 26 | //todo: then customise it to my needs |
9 | 27 |
|
10 | 28 | public class MainActivity extends AppCompatActivity { |
| 29 | + private static final int smsSendRequestCode = 42; |
| 30 | + private static final String TAG = "DiabeticDiary"; |
11 | 31 |
|
12 | 32 | @Override |
13 | 33 | protected void onCreate(Bundle savedInstanceState) { |
14 | 34 | super.onCreate(savedInstanceState); |
15 | 35 | setContentView(R.layout.activity_main); |
16 | 36 | //bg, cp, qa, bi, kt |
| 37 | + final String[] names = new String[] {"BG", "CP", "QA", "BI", "KT"}; |
17 | 38 | int[] inputIDs = new int[] {R.id.BGinput, R.id.CPinput, R.id.QAinput, R.id.BIinput, |
18 | 39 | R.id.KTinput}; |
19 | 40 |
|
20 | | - EditText[] inputs = new EditText[inputIDs.length]; |
| 41 | + final EditText[] inputs = new EditText[inputIDs.length]; |
21 | 42 | for(int i = 0; i < inputs.length; i++) { |
22 | 43 | inputs[i] = (EditText) findViewById(inputIDs[i]); |
| 44 | + } |
| 45 | + |
| 46 | + int[] checkboxIDs = new int[] {R.id.BGcheckBox, R.id.CPcheckBox, R.id.QAcheckBox, |
| 47 | + R.id.BIcheckBox, R.id.KTcheckBox}; |
23 | 48 |
|
| 49 | + final CheckBox[] checkBoxes = new CheckBox[checkboxIDs.length]; |
| 50 | + for(int i = 0; i < checkBoxes.length; i++) { |
| 51 | + checkBoxes[i] = (CheckBox)findViewById(checkboxIDs[i]); |
24 | 52 | } |
25 | 53 |
|
| 54 | + try { |
| 55 | + check(checkBoxes.length == inputs.length, |
| 56 | + "the number of names must equal the number of input fields!"); |
| 57 | + } |
| 58 | + catch(Exception e) { |
| 59 | + Log.e("DiabeticDiary", "validation exception:"+e); |
| 60 | + } |
| 61 | + Button recordButton = (Button) findViewById(R.id.button); |
| 62 | + |
| 63 | + //for BG input, only allow 2 digits before the decimal place, and 1 after |
| 64 | + Log.i(TAG, "existing filters: "+inputs[0].getFilters().length); |
| 65 | + inputs[0].setFilters(new InputFilter[]{new DecimalDigitsInputFilter(2,1)}); |
| 66 | + //the same with CP |
| 67 | + inputs[1].setFilters(new InputFilter[]{new DecimalDigitsInputFilter(2,1)}); |
| 68 | + |
| 69 | + //for QA, allow no digits after the decimal point. |
| 70 | + // This might not work, as the field is already integer-constrained |
| 71 | + inputs[2].setFilters(new InputFilter[]{new DecimalDigitsInputFilter(2,0)}); |
| 72 | + |
| 73 | + //with BI, allow 3 digit integers. I used to take ~80, so it's not impossible |
| 74 | + inputs[3].setFilters(new InputFilter[]{new DecimalDigitsInputFilter(3,0)}); |
| 75 | + |
| 76 | + //for KT, i'd be worried if ketones were > 9, but again it's not impossible |
| 77 | + inputs[4].setFilters(new InputFilter[]{new DecimalDigitsInputFilter(2,1)}); |
| 78 | + |
| 79 | + InputFilter filter = new InputFilter() { |
| 80 | + public CharSequence filter(CharSequence source, int start, int end, |
| 81 | + Spanned dest, int dstart, int dend) { |
| 82 | + for (int i = start; i < end; i++) { |
| 83 | + if (!Character.isLetterOrDigit(source.charAt(i))) { |
| 84 | + return ""; |
| 85 | + } |
| 86 | + } |
| 87 | + return null; |
| 88 | + } |
| 89 | + }; |
| 90 | + |
| 91 | + recordButton.setOnClickListener(new View.OnClickListener(){ |
| 92 | + @Override public void onClick(View view) { |
| 93 | + //get time button was pressed as time of reading |
| 94 | + long now = System.currentTimeMillis(); |
| 95 | + //convert to number of 10-second periods (1/6 of a minute) since the epoch |
| 96 | + //this reduces unnecessary precision, and increases the time until we have a Y2K-type issue (in 2038) |
| 97 | + //plus, the time fits within an int, allowing us to use it as the index to an array |
| 98 | + //which can store the log entries |
| 99 | + long hectaMinutes = now/10000; |
| 100 | + //Log.i("DiabeticDiary", "hectaminutes fit within an int:"+ (hectaMinutes < Integer.MAX_VALUE)); |
| 101 | + |
| 102 | + //select which fields have been ticked |
| 103 | + String out = "Diabetic Diary ENTRY {"; |
| 104 | + for(int i = 0; i < checkBoxes.length; i++) { |
| 105 | + if(checkBoxes[i].isChecked()){ |
| 106 | + out += names[i]+":"+inputs[i].getText()+"; "; |
| 107 | + } |
| 108 | + } |
| 109 | + out += "}"; |
| 110 | + Log.i(TAG, out); |
| 111 | + |
| 112 | + //support runtime permission checks on android versions >= 6.0 |
| 113 | + //if we're on android 6+ AND we haven't got location permissions yet, ask for them |
| 114 | + /*if (Build.VERSION.SDK_INT >= 23 && checkSelfPermission(Manifest.permission.SEND_SMS) |
| 115 | + != PackageManager.PERMISSION_GRANTED) { |
| 116 | +
|
| 117 | + // todo: Show an explanation to the user *asynchronously* |
| 118 | + // After the user sees the explanation, try again to request the permission. |
| 119 | +
|
| 120 | + requestPermissions(new String[]{Manifest.permission.SEND_SMS}, smsSendRequestCode); |
| 121 | + } |
| 122 | + else { |
| 123 | +
|
| 124 | + SmsManager.getDefault().sendTextMessage("07516041435", null, out, null, null); |
| 125 | + }*/ |
| 126 | + |
| 127 | + |
| 128 | + } |
| 129 | + }); |
26 | 130 | //TableLayout |
27 | 131 |
|
28 | 132 |
|
@@ -74,5 +178,50 @@ protected void onCreate(Bundle savedInstanceState) { |
74 | 178 | minorKT.setMinValue(0); |
75 | 179 | minorKT.setMaxValue(9); |
76 | 180 | */ |
| 181 | + |
| 182 | + |
| 183 | + } |
| 184 | + //taken from stackoverflow.com/questions/5357455 |
| 185 | + public class DecimalDigitsInputFilter implements InputFilter { |
| 186 | + |
| 187 | + Pattern mPattern; |
| 188 | + public DecimalDigitsInputFilter(int digitsBeforeZero, int digitsAfterZero) { |
| 189 | + String pat="[0-9]{0,"+digitsBeforeZero+"}((\\.[0-9]{0,"+digitsAfterZero+"})|(\\.)?)"; |
| 190 | + mPattern=Pattern.compile(pat); |
| 191 | + Log.i(TAG, "pattern:"+pat); |
| 192 | + } |
| 193 | + |
| 194 | + @Override |
| 195 | + public CharSequence filter(CharSequence source, int start, int end, Spanned dest, int dstart, int dend) { |
| 196 | + Matcher matcher = mPattern.matcher(dest+source.toString()); |
| 197 | + //Log.i(TAG, "dest:"+dest+"; dstart:"+dstart+"; dend:"+dend); |
| 198 | + //Log.i(TAG, "source:"+source+"; start:"+start+"; end:"+end); |
| 199 | + if(!matcher.matches()) { |
| 200 | + return ""; |
| 201 | + } |
| 202 | + return null; |
| 203 | + } |
| 204 | + } |
| 205 | + |
| 206 | + @Override |
| 207 | + public void onRequestPermissionsResult(int requestCode, |
| 208 | + String[] permissions, int[] grantResults) { |
| 209 | + //todo: handle multiple permissions |
| 210 | + //if there are no permissions etc to process, return early. |
| 211 | +//See https://developer.android.com/reference/android/support/v4/app/ActivityCompat.OnRequestPermissionsResultCallback.html#onRequestPermissionsResult%28int,%20java.lang.String[],%20int[]%29 |
| 212 | + if(permissions.length != 1 || grantResults.length != 1) { |
| 213 | + return; |
| 214 | + } |
| 215 | + Log.i(TAG, "permissions results length:" + permissions.length); |
| 216 | + |
| 217 | + |
| 218 | + Log.i(TAG, "permission \"" + permissions[0] + "\" result: " + grantResults[0]); |
| 219 | + if (grantResults[0] != PackageManager.PERMISSION_GRANTED) { |
| 220 | + |
| 221 | + } |
| 222 | + else if(grantResults[0] == PackageManager.PERMISSION_GRANTED) { |
| 223 | + //the user has granted permission, so start the location service |
| 224 | + //this happens by starting the service in onResume() |
| 225 | + } |
77 | 226 | } |
78 | 227 | } |
0 commit comments