Beispiel #1
0
        /// <summary>
        /// Main method sort of speak
        /// </summary>
        /// <param name="bundle"></param>
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
            handler = new Handler();
            HeartDebugHandler.debugLog("OnCreate");
            connectionAttempts = 0;
            SetContentView(Resource.Layout.main_activity);
            HeartDebugHandler.debugLog("App Launched");
            SetupViews();
            SetupLists();

            //gridViewContainer

            //gridView = FindViewById<ListView>(Resource.Id.gridViewContainer);
            swipeRefreshLayout = FindViewById <SwipeRefreshLayout>(Resource.Id.swipeRefreshLayout);

            // Elevation helps users understand the relative importance of each element and focus their attention to the task at hand. (Optional)
            // swipeRefreshLayout.Elevation = 10;

            swipeRefreshLayout.Refresh += delegate(object sender, System.EventArgs e)
            {
                swipeRefreshLayout.Refreshing = true;

                Toast.MakeText(this, "Reconnecting", ToastLength.Short).Show();
                if (!mGoogleApiClient.IsConnected && !mGoogleApiClient.IsConnecting)
                {
                    //updateConnectionStatusString("Connecting");
                    connectionStatusHandler.updateStatus("Connecting");
                    mGoogleApiClient.Connect();
                }


                swipeRefreshLayout.Refreshing = false;
            };

            dataStatusHandler       = new StatusHandler(statusTextView, "No data received");
            connectionStatusHandler = new StatusHandler(connectionStatusTextView, "");

            mGoogleApiClient = new GoogleApiClient.Builder(this)
                               .AddApi(WearableClass.API)
                               .AddConnectionCallbacks(this)
                               .AddOnConnectionFailedListener(this)
                               .Build();


            if (!mGoogleApiClient.IsConnected && !mGoogleApiClient.IsConnecting)
            {
                connectionStatusHandler.updateStatus("Connecting");
                mGoogleApiClient.Connect();
            }
        }
        /// <summary>
        /// Takes in a list(QUEUE) and stores it in a file with the provided filename, it then updates the application status(TextView) to make the user aware the file has been saved
        /// </summary>
        /// <param name="hdata">The list of items to be stored</param>
        /// <param name="filename">The filename of the file to store the data in</param>
        /// <param name="dataStatusHandler">the handler of the textview for statuses in the app gui</param>
        public static async void saveData(Queue <HeartDataPoint> hdata, string filename, StatusHandler dataStatusHandler)
        {
            bool cancelOp = false; //if this trips to true, then file won't be stored
            int  selected = -1;


            //handling of "file already being manipulated" checks
            switch (filename)
            {
            case FILENAME_STEPS: selected = 0;
                break;

            case FILENAME_HEARTBEAT: selected = 1;
                break;

            case FILENAME_HEARTRATE: selected = 2;
                break;
            }

            if (selected != -1 && beingSaved[selected] == null)
            {
                beingSaved[selected] = filename;
            }
            else
            {
                cancelOp = true;
            }
            //first file manip check done

            if (!cancelOp)//if file is being manipulated, don't continue
            {
                HeartDebugHandler.debugLog("Save start");
                List <HeartDataPoint> existingData;
                HeartDebugHandler.debugLog("Reading existing data start");
                existingData = await ReadDataPointsTask(filename);

                HeartDebugHandler.debugLog("Reading existing data finished");
                HeartDebugHandler.debugLog("Merging the two datasets");
                if (existingData == null)
                {
                    existingData = new List <HeartDataPoint>();
                }
                else
                {
                    if (existingData.Count > 0)
                    {
                        HeartDebugHandler.debugLog("There was existing data, amount" + existingData.Count.ToString());
                        HeartDebugHandler.debugLog("First datapoint contained: " + existingData[0].heartType.ToString("G") + ";" + existingData[0].amount.ToString() + ";" + existingData[0].timestamp + ".");
                    }
                }
                while (hdata.Any())
                {
                    HeartDataPoint element = hdata.Dequeue();
                    existingData.Add(element);
                }
                HeartDebugHandler.debugLog("Datasets have been merged, final tally: " + existingData.Count.ToString());
                HeartDebugHandler.debugLog("Actually writing the file");
                await storeDataPointsTask(existingData, filename, dataStatusHandler);


                //now reset the file being saved to null, so that the program knows it can be used again
                //TODO: look into whether this can all be handled using a callback instead, and whether that's more efficient
                if (filename.Equals(FILENAME_STEPS))
                {
                    beingSaved[0] = null;
                }
                else if (filename.Equals(FILENAME_HEARTBEAT))
                {
                    beingSaved[1] = null;
                }
                else if (filename.Equals(FILENAME_HEARTRATE))
                {
                    beingSaved[2] = null;
                }
            }
            else
            {
                //setting the status TextView to this string
                dataStatusHandler.updateStatus("Data already being saved");
            }
        }
        /// <summary>
        /// The main task for writing the data to file; it get's the full set of data going in to the file,
        /// it then deletes the current file(if it exists) and creates a new file containing the incoming data, it then updates the status(TextView) of the app
        /// </summary>
        /// <param name="dataPoints"></param>
        /// <param name="fileName"></param>
        /// <param name="dataStatusHandler"></param>
        /// <returns></returns>
        private static async Task storeDataPointsTask(List <HeartDataPoint> dataPoints, string fileName, StatusHandler dataStatusHandler)
        {
            if (dataPoints != null && dataPoints.Count > 0)
            {
                HeartDebugHandler.debugLog("There is data to be written: " + dataPoints.Count.ToString());
                //needed values
                HeartDataType dataType    = dataPoints[0].heartType;
                DateTime      currentTime = DateTime.Now;


                string filePath = System.Environment.GetFolderPath(Environment.SpecialFolder.Personal);

                string backingFile = System.IO.Path.Combine(System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal), fileName);
                // TODO: "FILESTORAGE" [0] this needs a better solution, writing to temp and replacing it solves most file loss, but not ram usage, so should probably use appending so you don't need to read the whole file to memory every time
                // TODO: "FILESTORAGE" cont [1]: this should probably use a version of https://stackoverflow.com/a/39562216 but instead of dropping the last few lines, you store them and add them back into the file after adding the new objects

                Java.IO.File file = new Java.IO.File(backingFile);
                if (file.Exists())//if the file exists, delete it.// TODO: "FILESTORAGE" cont [2]: this is probably where it should be split into two different methods, one for storing and creating a new file, and one for 'appending'
                {
                    HeartDebugHandler.debugLog("File already exists, will be overwritten");
                    file.Delete();
                }

                //string debugString = "";

                using (var writer = System.IO.File.CreateText(backingFile))
                {
                    //made these to make the print statements a bit more readable(although they could probably be made better).
                    var indentOne   = "\t";
                    var indentTwo   = "\t\t";
                    var indentThree = "\t\t\t";
                    await writer.WriteLineAsync("{");                                                               //debugString += "{";

                    await writer.WriteLineAsync(indentOne + "\"updated\": \"" + currentTime.ToString("O") + "\","); //debugString += indentOne + "\"updated\": \"" + currentTime.ToString("O") + "\",";

                    await writer.WriteLineAsync(indentOne + "\"dataType\": \"" + dataType.ToString("G") + "\",");   //debugString += indentOne + "\"dataType\": \"" + dataType.ToString("G") + "\",";

                    await writer.WriteLineAsync(indentOne + "\"data\": [");                                         //debugString += indentOne + "\"data\": [";

                    for (int i = 0; i < dataPoints.Count; i++)
                    {
                        HeartDataPoint point = dataPoints[i];
                        await writer.WriteLineAsync(indentTwo + "{");                                                               //debugString += indentTwo + "{";

                        await writer.WriteLineAsync(indentThree + "\"DateTime\": " + "\"" + point.timestamp.ToString("O") + "\","); //debugString += indentThree + "\"DateTime\": " + "\"" + point.timestamp.ToString("O") + "\",";

                        await writer.WriteLineAsync(indentThree + "\"Value\": " + "\"" + point.amount + "\",");                     //debugString += indentThree + "\"Value\": " + point.amount;

                        await writer.WriteLineAsync(indentThree + "\"accuracy\": " + "\"" + point.accuracy + "\"");

                        string lastLine = "}";
                        if (i < dataPoints.Count - 1)
                        {
                            lastLine += ",";
                        }
                        await writer.WriteLineAsync(indentTwo + lastLine); //debugString += indentTwo + lastLine;
                    }
                    await writer.WriteLineAsync(indentOne + "]");          //debugString += indentOne + "]";

                    await writer.WriteLineAsync("}");                      //debugString += "}";
                }
                dataStatusHandler.updateStatus("File saved");
                //if (debugString != "")
                //{
                //    HeartDebugHandler.debugLog("File that was saved: ");
                //    HeartDebugHandler.debugLog(debugString);
                //}
                //else
                //{
                //    HeartDebugHandler.debugLog("debug string contained nothing");
                //}
            }
            else
            {
                HeartDebugHandler.debugLog("No data to write, operation cancelled");
                dataStatusHandler.updateStatus("No data to store");
            }
        }