Java tutorial
/* * Copyright (C) 2016 Google, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.rsltc.profiledata.main; import android.app.Activity; import android.app.AlertDialog; import android.content.DialogInterface; import android.content.Intent; import android.net.Uri; import android.os.AsyncTask; import android.os.Bundle; import android.os.Environment; import android.support.design.widget.Snackbar; import android.support.v7.app.AppCompatActivity; import android.text.InputType; import android.view.Menu; import android.view.MenuItem; import android.util.Log; import android.view.View; import android.webkit.WebSettings; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.Button; import android.widget.EditText; import android.widget.LinearLayout; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.Scopes; import com.google.android.gms.common.api.GoogleApiClient; import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks; import com.google.android.gms.common.api.Scope; import com.rsltc.profiledata.DailyHeartRate; import com.rsltc.profiledata.DateUtils; import com.rsltc.profiledata.DistanceSummary; import com.rsltc.profiledata.HealthConstants; import com.rsltc.profiledata.HealthStatValidityChecker; import com.rsltc.profiledata.InfoType; import com.rsltc.profiledata.JsonObjectsFromType; import com.rsltc.profiledata.MSCloudLiveIdCredentials; import com.rsltc.profiledata.MSHealthRestClient; import com.rsltc.profiledata.MathUtil; import com.rsltc.profiledata.MicrosoftRestClient; import com.rsltc.profiledata.ProcessSummaries; import com.rsltc.profiledata.R; import com.rsltc.profiledata.SpeedSummary; import com.rsltc.profiledata.Summary; import com.rsltc.profiledata.User; import com.google.android.gms.fitness.Fitness; import com.google.android.gms.fitness.data.Bucket; import com.google.android.gms.fitness.data.DataPoint; import com.google.android.gms.fitness.data.DataSet; import com.google.android.gms.fitness.data.DataType; import com.google.android.gms.fitness.data.Field; import com.google.android.gms.fitness.request.DataReadRequest; import com.google.android.gms.fitness.result.DataReadResult; import com.loopj.android.http.JsonHttpResponseHandler; import com.loopj.android.http.RequestParams; import org.json.JSONException; import org.json.JSONObject; import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.net.URI; import java.net.URISyntaxException; import java.net.URL; import java.net.URLDecoder; import java.net.URLEncoder; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.Locale; import java.util.Map; import java.util.TimeZone; import java.util.concurrent.TimeUnit; import cz.msebera.android.httpclient.Header; import static java.text.DateFormat.getDateInstance; import static java.text.DateFormat.getTimeInstance; public class MainActivity extends AppCompatActivity { public static final String TAG = "BasicHistoryApi"; private static final int REQUEST_OAUTH = 1; private static final String DATE_FORMAT = "yyyy.MM.dd HH:mm:ss"; private Activity thisActivity = this; private final String scopes = "mshealth.ReadDevices mshealth.ReadActivityHistory mshealth.ReadActivityLocation mshealth.ReadDevices"; private final String baseHealthUri = "api.microsofthealth.net/v1/me/"; private final String redirectUri = "https://login.live.com/oauth20_desktop.srf"; private final String clientId = "000000004417D217"; private MSCloudLiveIdCredentials creds = new MSCloudLiveIdCredentials(); /** * Track whether an authorization activity is stacking over the current activity, i.e. when * a known auth error is being resolved, such as showing the account chooser or presenting a * consent dialog. This avoids common duplications as might happen on screen rotations, etc. */ private static final String AUTH_PENDING = "auth_state_pending"; private static boolean authInProgress = false; public static GoogleApiClient mClient = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button loginButton = (Button) findViewById(R.id.button); loginButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { try { AlertDialog.Builder alert = new AlertDialog.Builder(thisActivity); alert.setTitle("Title here"); StringBuilder query = new StringBuilder(); query.append("redirect_uri=" + URLEncoder.encode(redirectUri, "utf-8")); query.append("&client_id=" + URLEncoder.encode(clientId, "utf-8")); query.append("&scope=" + URLEncoder.encode(scopes, "utf-8")); query.append("&response_type=code"); URI uri = new URI("https://login.live.com/oauth20_authorize.srf?" + query.toString()); URL url = uri.toURL(); final WebView wv = new WebView(thisActivity); WebSettings webSettings = wv.getSettings(); webSettings.setJavaScriptEnabled(true); wv.loadUrl(url.toString()); wv.setWebViewClient(new WebViewClient() { @Override public boolean shouldOverrideUrlLoading(WebView view, String location) { Log.e(TAG, location); // TODO: extract to method try { URL url = new URL(location); if (url.getPath().equalsIgnoreCase("/oauth20_desktop.srf")) { System.out.println("Dit werkt al!"); System.out.println(url.getQuery()); Map<String, List<String>> result = splitQuery(url); if (result.containsKey("code")) { System.out.println("bevat code"); if (result.containsKey("error")) { System.out.println(String.format("{0}\r\n{1}", result.get("error"), result.get("errorDesc"))); } System.out.println(result.get("code").get(0)); String tokenError = GetToken(result.get("code").get(0), false); if (tokenError == null || "".equals(tokenError)) { System.out.println("Successful sign-in!"); Log.e(TAG, "Successful sign-in!"); } else { Log.e(TAG, "tokenError: " + tokenError); } } else { System.out.println("Successful sign-out!"); } } } catch (IOException | URISyntaxException e) { e.printStackTrace(); } view.loadUrl(location); return true; } }); LinearLayout linearLayout = new LinearLayout(thisActivity); linearLayout.setMinimumHeight(500); ArrayList<View> views = new ArrayList<View>(); views.add(wv); linearLayout.addView(wv); EditText text = new EditText(thisActivity); text.setVisibility(View.GONE); linearLayout.addView(text); alert.setView(linearLayout); alert.setNegativeButton("Close", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int id) { dialog.dismiss(); } }); alert.show(); } catch (Exception e) { Log.e(TAG, "dd"); } } }); Button showProfile = (Button) findViewById(R.id.button2); showProfile.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { showProfile(); } }); Button showSummmary = (Button) findViewById(R.id.button3); showSummmary.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { showSummaries(); } }); if (savedInstanceState != null) { authInProgress = savedInstanceState.getBoolean(AUTH_PENDING); } buildFitnessClient(); } class PaginatedRequestTask extends AsyncTask<Object, Void, JsonObjectsFromType> { final boolean[] hasNext = { true }; final List<JSONObject>[] jsonObjectList = new List[] { null }; protected JsonObjectsFromType doInBackground(Object... args) { if (args.length != 2) { Log.e(TAG, "Task Cannot be executed"); } final String[] nextPageURL = { (String) args[0] }; jsonObjectList[0] = (List<JSONObject>) args[1]; InfoType type = (InfoType) args[2]; JsonObjectsFromType result = new JsonObjectsFromType(type); try { while (hasNext[0]) { try { URI uri = new URI(nextPageURL[0]); MSHealthRestClient.getAbs(uri.toURL().toString(), new JsonHttpResponseHandler() { @Override public void onSuccess(int statusCode, Header[] headers, final JSONObject response) { Log.e(TAG, response.toString()); jsonObjectList[0].add(response); if (hasNext[0] = response.has("nextPage")) { try { nextPageURL[0] = response.getString("nextPage"); } catch (JSONException e) { Log.e(TAG, "Something went wrong when looking for nextPage"); hasNext[0] = false; } } } @Override public void onFailure(int d, Header[] headers, String mess, Throwable e) { Log.e(TAG, e.getMessage()); } @Override public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONObject errorResponse) { Log.e(TAG, throwable.getMessage()); } }, creds); } catch (Exception ignored) { } } } catch (Exception ignored) { } finally { result.setJsonObjectList(jsonObjectList[0]); return result; } } protected void onProgressUpdate(Integer... progress) { Log.i(TAG, "Still loading pages"); } protected void onPostExecute(JsonObjectsFromType result) { // showSaveDialog(jsonObjectList[0]); new ProcessSummaries().execute(result); } } private void PerformRequest(String relativePath, RequestParams params, final InfoType type) { MSHealthRestClient.get(relativePath, params, new JsonHttpResponseHandler() { @Override public void onSuccess(int statusCode, Header[] headers, final JSONObject response) { try { Log.e(TAG, response.toString()); final List<JSONObject> jsonObjectList = new ArrayList<>(); jsonObjectList.add(response); if (response.has("nextPage")) { String nextPageURL = (String) response.get("nextPage"); // TODO: make async again new PaginatedRequestTask().execute(nextPageURL, jsonObjectList, type); } else { JsonObjectsFromType jsonObjectsFromType = new JsonObjectsFromType(type); jsonObjectsFromType.setJsonObjectList(jsonObjectList); new ProcessSummaries().execute(jsonObjectsFromType); // showSaveDialog(jsonObjectList); } } catch (Exception e) { Log.i(TAG, ""); } } @Override public void onFailure(int d, Header[] headers, String mess, Throwable e) { Log.e(TAG, e.getMessage()); } @Override public void onFailure(int statusCode, Header[] headers, Throwable throwable, JSONObject errorResponse) { super.onFailure(statusCode, headers, throwable, errorResponse); } }, creds); } private void showSaveDialog(final List<JSONObject> jsonObjectList) { AlertDialog.Builder builder = new AlertDialog.Builder(thisActivity); builder.setTitle("Dataset title"); final EditText input = new EditText(thisActivity); input.setInputType(InputType.TYPE_CLASS_TEXT); builder.setView(input); builder.setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { final String m_Text = input.getText().toString(); Runnable r = new Runnable() { @Override public void run() { exportFile(jsonObjectList, m_Text); } }; Thread t = new Thread(r); t.start(); } }); builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { dialog.cancel(); } }); builder.show(); } public void showProfile() { PerformRequest("Profile", new RequestParams(), InfoType.USER_STATS); } public void showSummaries() { RequestParams params = new RequestParams(); TimeZone tz = TimeZone.getTimeZone("UTC"); DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'", Locale.US); df.setTimeZone(tz); String nowAsISOBefore = df.format(new Date("02/01/2016")); String nowAsISO = df.format(new Date()); params.add("startTime", nowAsISOBefore); params.add("endTime", nowAsISO); params.add("maxPagesize", "48"); PerformRequest("Summaries/Daily", params, InfoType.BPM); } public static Map<String, List<String>> splitQuery(URL url) throws UnsupportedEncodingException { final Map<String, List<String>> query_pairs = new LinkedHashMap<String, List<String>>(); final String[] pairs = url.getQuery().split("&"); for (String pair : pairs) { final int idx = pair.indexOf("="); final String key = idx > 0 ? URLDecoder.decode(pair.substring(0, idx), "UTF-8") : pair; if (!query_pairs.containsKey(key)) { query_pairs.put(key, new LinkedList<String>()); } final String value = idx > 0 && pair.length() > idx + 1 ? URLDecoder.decode(pair.substring(idx + 1), "UTF-8") : null; query_pairs.get(key).add(value); } return query_pairs; } private String GetToken(String code, boolean isRefresh) throws IOException, URISyntaxException { RequestParams params = new RequestParams(); params.add("redirect_uri", redirectUri); params.add("client_id", clientId); params.add("scope", scopes); if (isRefresh) { params.add("refresh_token", code); params.add("grant_type", "refresh_token"); } else { params.add("code", code); params.add("grant_type", "authorization_code"); } MicrosoftRestClient.get("", params, new JsonHttpResponseHandler() { @Override public void onSuccess(int statusCode, Header[] headers, JSONObject response) { // Log.e(TAG, response.toString()); try { if (response.has("access_token")) { creds.setAccessToken((String) response.get("access_token")); System.out.println(creds.getAccessToken()); } if (response.has("expires_in")) { creds.setExpiresIn((Integer) response.get("expires_in")); } if (response.has("refresh_token")) { creds.setRefreshToken((String) response.get("refresh_token")); } if (response.has("error")) { // TODO: do something with error // return (String) response.get("error"); } } catch (JSONException e) { e.printStackTrace(); } } }); return null; } private void buildFitnessClient() { mClient = new GoogleApiClient.Builder(this).addApi(Fitness.HISTORY_API) .addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ)).addScope(new Scope(Scopes.FITNESS_BODY_READ)) .addScope(new Scope(Scopes.FITNESS_LOCATION_READ)) .addScope(new Scope(Scopes.FITNESS_NUTRITION_READ)) .addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() { @Override public void onConnected(Bundle bundle) { Log.i(TAG, "Connected!!!"); new InsertAndVerifyDataTask().execute(); } @Override public void onConnectionSuspended(int i) { if (i == ConnectionCallbacks.CAUSE_NETWORK_LOST) { Log.i(TAG, "Connection lost. Cause: Network Lost."); } else if (i == ConnectionCallbacks.CAUSE_SERVICE_DISCONNECTED) { Log.i(TAG, "Connection lost. Reason: Service Disconnected"); } } }).enableAutoManage(this, 0, new GoogleApiClient.OnConnectionFailedListener() { @Override public void onConnectionFailed(ConnectionResult result) { Log.i(TAG, "Google Play services connection failed. Cause: " + result.toString()); Snackbar.make(MainActivity.this.findViewById(R.id.main_activity_view), "Exception while connecting to Google Play services: " + result.getErrorMessage(), Snackbar.LENGTH_INDEFINITE).show(); } }).build(); } private class InsertAndVerifyDataTask extends AsyncTask<Void, Void, Void> { protected Void doInBackground(Void... params) { DataReadRequest readRequest = queryFitnessData(); DataReadResult dataReadResult = Fitness.HistoryApi.readData(mClient, readRequest).await(1, TimeUnit.MINUTES); processData(dataReadResult, InfoType.DISTANCE_SUMMARY); return null; } } public static DataReadRequest queryFitnessData() { Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT")); Date now = new Date(); cal.setTime(now); // cal.add(Calendar.YEAR, -1); // cal.set(2015,7,20); long endTime = cal.getTimeInMillis(); cal.add(Calendar.YEAR, -1); long startTime = cal.getTimeInMillis(); java.text.DateFormat dateFormat = getDateInstance(); Log.i(TAG, "Range Start: " + dateFormat.format(startTime)); Log.i(TAG, "Range End: " + dateFormat.format(endTime)); DataReadRequest readRequest = new DataReadRequest.Builder() .aggregate(DataType.TYPE_DISTANCE_DELTA, DataType.AGGREGATE_DISTANCE_DELTA) // .read(DataType.TYPE_WEIGHT) // .read(DataType.TYPE_HEIGHT) // .read(DataType.TYPE_HEART_RATE_BPM) .bucketByActivitySegment(5, TimeUnit.MINUTES) // .bucketByActivityType(1, TimeUnit.SECONDS) // .bucketByTime(1, TimeUnit.DAYS) .setTimeRange(startTime, endTime, TimeUnit.MILLISECONDS).build(); return readRequest; } public static void processData(DataReadResult dataReadResult, InfoType type) { Log.i(TAG, dataReadResult.toString()); Calendar calendar = Calendar.getInstance(); if (type == InfoType.SPEED_SUMMARY) { Map<String, SpeedSummary> speedsummaries = new HashMap<String, SpeedSummary>(); speedsummaries.put(HealthConstants.ActivityType.ACTIVITY_BIKING, new SpeedSummary(HealthConstants.ActivityType.ACTIVITY_BIKING)); speedsummaries.put(HealthConstants.ActivityType.ACTIVITY_RUNNING, new SpeedSummary(HealthConstants.ActivityType.ACTIVITY_RUNNING)); speedsummaries.put(HealthConstants.ActivityType.ACTIVITY_WALKING, new SpeedSummary(HealthConstants.ActivityType.ACTIVITY_WALKING)); String currentType = ""; if (dataReadResult.getBuckets().size() > 0) { Log.i(TAG, "Number of returned buckets of DataSets is: " + dataReadResult.getBuckets().size()); for (Bucket bucket : dataReadResult.getBuckets()) { if (bucket.getDataSets().get(0).getDataPoints().size() > 0) { if (bucket.getActivity().equals("running")) { currentType = HealthConstants.ActivityType.ACTIVITY_RUNNING; } else if (bucket.getActivity().equals("walking")) { currentType = HealthConstants.ActivityType.ACTIVITY_WALKING; } else if (bucket.getActivity().equals("biking")) { currentType = HealthConstants.ActivityType.ACTIVITY_BIKING; } else { Log.e(TAG, "Activity type not processed: " + bucket.getActivity()); continue; } Log.e(TAG, "Bucket : " + bucket.getActivity()); calendar.setTimeInMillis(bucket.getStartTime(TimeUnit.MILLISECONDS)); Log.i(TAG, "Time: " + calendar.getTime()); List<DataSet> dataSets = bucket.getDataSets(); for (DataSet dataSet : dataSets) { processSpeedSumary(dataSet, type, speedsummaries.get(currentType), currentType); } } } // } else if (dataReadResult.getDataSets().size() > 0) { // Log.i(TAG, "Number of returned DataSets is: " // + dataReadResult.getDataSets().size()); // for (DataSet dataSet : dataReadResult.getDataSets()) { // processDataSet(dataSet, type); // } } Log.e(TAG, speedsummaries.get(HealthConstants.ActivityType.ACTIVITY_BIKING).toString()); Log.e(TAG, speedsummaries.get(HealthConstants.ActivityType.ACTIVITY_WALKING).toString()); Log.e(TAG, speedsummaries.get(HealthConstants.ActivityType.ACTIVITY_RUNNING).toString()); } else if (type == InfoType.DISTANCE_SUMMARY) { Map<String, DistanceSummary> distanceSummmaries = new HashMap<>(); distanceSummmaries.put(HealthConstants.ActivityType.ACTIVITY_BIKING, new DistanceSummary(HealthConstants.ActivityType.ACTIVITY_BIKING)); distanceSummmaries.put(HealthConstants.ActivityType.ACTIVITY_RUNNING, new DistanceSummary(HealthConstants.ActivityType.ACTIVITY_RUNNING)); distanceSummmaries.put(HealthConstants.ActivityType.ACTIVITY_WALKING, new DistanceSummary(HealthConstants.ActivityType.ACTIVITY_WALKING)); String currentType = ""; if (dataReadResult.getBuckets().size() > 0) { Log.i(TAG, "Number of returned buckets of DataSets is: " + dataReadResult.getBuckets().size()); for (Bucket bucket : dataReadResult.getBuckets()) { if (bucket.getDataSets().get(0).getDataPoints().size() > 0) { if (bucket.getActivity().equals("running")) { currentType = HealthConstants.ActivityType.ACTIVITY_RUNNING; } else if (bucket.getActivity().equals("walking")) { currentType = HealthConstants.ActivityType.ACTIVITY_WALKING; } else if (bucket.getActivity().equals("biking")) { currentType = HealthConstants.ActivityType.ACTIVITY_BIKING; } else { Log.e(TAG, "Activity type not processed: " + bucket.getActivity()); continue; } Log.e(TAG, "Bucket : " + bucket.getActivity()); calendar.setTimeInMillis(bucket.getStartTime(TimeUnit.MILLISECONDS)); Log.i(TAG, "Time: " + calendar.getTime()); List<DataSet> dataSets = bucket.getDataSets(); for (DataSet dataSet : dataSets) { processDistanceSummary(dataSet, type, distanceSummmaries.get(currentType)); } } } } Log.e(TAG, distanceSummmaries.get(HealthConstants.ActivityType.ACTIVITY_BIKING).toString()); Log.e(TAG, distanceSummmaries.get(HealthConstants.ActivityType.ACTIVITY_WALKING).toString()); Log.e(TAG, distanceSummmaries.get(HealthConstants.ActivityType.ACTIVITY_RUNNING).toString()); } else { if (dataReadResult.getBuckets().size() > 0) { Log.i(TAG, "Number of returned buckets of DataSets is: " + dataReadResult.getBuckets().size()); for (Bucket bucket : dataReadResult.getBuckets()) { if (bucket.getDataSets().get(0).getDataPoints().size() > 0) { Log.e(TAG, "Bucket : " + bucket.getActivity()); calendar.setTimeInMillis(bucket.getStartTime(TimeUnit.MILLISECONDS)); Log.i(TAG, "Time: " + calendar.getTime()); List<DataSet> dataSets = bucket.getDataSets(); for (DataSet dataSet : dataSets) { processDataSet(dataSet, type); } } } } else if (dataReadResult.getDataSets().size() > 0) { Log.i(TAG, "Number of returned DataSets is: " + dataReadResult.getDataSets().size()); for (DataSet dataSet : dataReadResult.getDataSets()) { processDataSet(dataSet, type); } } } } private static void processSpeedSumary(DataSet dataSet, InfoType type, SpeedSummary summary, String currentType) { Calendar calendar = Calendar.getInstance(); for (DataPoint dp : dataSet.getDataPoints()) { Float min = null, max = null, avg = null; Log.i(TAG, "Data point:"); Log.i(TAG, "\tType: " + dp.getDataType().getName()); Long startTime = dp.getStartTime(TimeUnit.MILLISECONDS); calendar.setTimeInMillis(startTime); Log.i(TAG, "\tStart: " + calendar.getTime()); Long stopTime = dp.getEndTime(TimeUnit.MILLISECONDS); calendar.setTimeInMillis(stopTime); Log.i(TAG, "\tStop: " + calendar.getTime()); Long duration = stopTime - startTime; Log.i(TAG, "Timezone: " + calendar.getTimeZone().getDisplayName()); for (Field field : dp.getDataType().getFields()) { Log.i(TAG, "\tField: " + field.getName() + " Value: " + dp.getValue(field)); if (field.equals(Field.FIELD_AVERAGE)) { avg = dp.getValue(field).asFloat(); } else if (field.equals(Field.FIELD_MIN)) { min = dp.getValue(field).asFloat(); } else if (field.equals(Field.FIELD_MAX)) { max = dp.getValue(field).asFloat(); } else { Log.e(TAG, "Unsupported field found"); } } boolean valid = false; if (min != null && max != null && avg != null) { // TODO: build check for speeds if (!(valid = HealthStatValidityChecker.checkAvgSpeed(avg, currentType))) { avg = (max + min) / 2; valid = HealthStatValidityChecker.checkAvgSpeed(avg, currentType); } } if (valid) { summary.setMaxSpeedIfGreater(max); summary.setMinSpeedIfSmaller(min); summary.setMaxDurationIfLonger(duration); summary.setMinDurationIfShorter(duration); double count = summary.getCount(); summary.setAvgSpeed((summary.getAvgSpeed() * count + avg) / (count + 1)); summary.setAvgDuration((float) ((summary.getAvgDuration() * count + duration) / (count + 1))); summary.increaseCount(); } } } private static void processDataSet(DataSet dataSet, InfoType type) { Log.i(TAG, "Data returned for Data type: " + dataSet.getDataType().getName()); Calendar calendar = Calendar.getInstance(); User user = new User(); for (DataPoint dp : dataSet.getDataPoints()) { if (type == InfoType.BPM) { Float min = null, max = null, avg = null; Log.i(TAG, "Data point:"); Log.i(TAG, "\tType: " + dp.getDataType().getName()); calendar.setTimeInMillis(dp.getStartTime(TimeUnit.MILLISECONDS)); Log.i(TAG, "\tStart: " + calendar.getTime()); calendar.setTimeInMillis(dp.getEndTime(TimeUnit.MILLISECONDS)); Log.i(TAG, "\tStop: " + calendar.getTime()); Log.i(TAG, "Timezone: " + calendar.getTimeZone().getDisplayName()); for (Field field : dp.getDataType().getFields()) { Log.i(TAG, "\tField: " + field.getName() + " Value: " + dp.getValue(field)); if (field.equals(Field.FIELD_AVERAGE)) { avg = dp.getValue(field).asFloat(); } else if (field.equals(Field.FIELD_MIN)) { min = dp.getValue(field).asFloat(); } else if (field.equals(Field.FIELD_MAX)) { max = dp.getValue(field).asFloat(); } else { Log.e(TAG, "Unsupported field found"); } } boolean valid = true; if (min != null && max != null && avg != null) { if (!HealthStatValidityChecker.checkIfNormal(avg, type)) { avg = (max + min) / 2; valid = HealthStatValidityChecker.checkIfNormal(avg, type); } } else { valid = false; } DailyHeartRate dailyHeartRate = new DailyHeartRate(avg != null ? avg : -1, max != null ? max : -1, min != null ? min : -1, valid, DateUtils.dateToDateRelated(calendar)); } else if (type == InfoType.USER_STATS) { Log.e(TAG, dp.toString()); Log.i(TAG, "Data point:"); Log.i(TAG, "\tType: " + dp.getDataType().getName()); DataType datatype = dp.getDataType(); calendar.setTimeInMillis(dp.getStartTime(TimeUnit.MILLISECONDS)); String dayOfMeasurement = DateUtils.dateToDateRelated(calendar); if (datatype.equals(DataType.TYPE_HEIGHT)) { Log.e(TAG, "I have height"); user.setHeight(dp.getValue(dp.getDataType().getFields().get(0)).asFloat()); } else { Log.e(TAG, "I have weight"); user.setWeight(MathUtil.round(dp.getValue(dp.getDataType().getFields().get(0)).asFloat(), 3)); } Log.i(TAG, "\tStart: " + calendar.getTime()); calendar.setTimeInMillis(dp.getEndTime(TimeUnit.MILLISECONDS)); Log.i(TAG, "\tStop: " + calendar.getTime()); for (Field field : dp.getDataType().getFields()) { Log.i(TAG, field.getName() + " " + dp.getValue(field)); } } } if (type == InfoType.USER_STATS) { //persist the user Log.i(TAG, user.toString()); } } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { int id = item.getItemId(); if (id == R.id.action_delete_data) { // deleteData(); return true; } else if (id == R.id.action_update_data) { // Intent intent = new Intent(MainActivity.this, MainActivity2.class); // MainActivity.this.startActivity(intent); } return super.onOptionsItemSelected(item); } private void exportFile(List<JSONObject> jsonObjects, String dataset_name) { final String date = new SimpleDateFormat("yyyyMMdd-HHmmss", Locale.getDefault()).format(new Date()); final String filename = String.format("%s_%s.txt", dataset_name, date); final String directory = Environment.getExternalStorageDirectory().getAbsolutePath() + "/AndroidTesting/"; final File logfile = new File(directory, filename); final File logPath = logfile.getParentFile(); if (!logPath.isDirectory() && !logPath.mkdirs()) { Log.e("SensorDashbaord", "Could not create directory for log files"); } try { FileWriter filewriter = new FileWriter(logfile); BufferedWriter bw = new BufferedWriter(filewriter); // for (JSONObject object : jsonObjects) { bw.write(jsonObjects.toString()); // } bw.flush(); bw.close(); Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND); emailIntent.setType("*/*"); emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, dataset_name + ".csv"); emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(logfile)); startActivity(Intent.createChooser(emailIntent, "Send mail...")); Log.i(TAG, "export finished!"); } catch (IOException ioe) { Log.e(TAG, "IOException while writing Logfile"); Log.e("Enias", ioe.getMessage()); } } private static void processDistanceSummary(DataSet dataSet, InfoType type, DistanceSummary summary) { Calendar calendar = Calendar.getInstance(); for (DataPoint dp : dataSet.getDataPoints()) { Float distance = null; Log.i(TAG, "Data point:"); Log.i(TAG, "\tType: " + dp.getDataType().getName()); Long startTime = dp.getStartTime(TimeUnit.MILLISECONDS); calendar.setTimeInMillis(startTime); Log.i(TAG, "\tStart: " + calendar.getTime()); Long stopTime = dp.getEndTime(TimeUnit.MILLISECONDS); calendar.setTimeInMillis(stopTime); Log.i(TAG, "\tStop: " + calendar.getTime()); Long duration = stopTime - startTime; Log.i(TAG, "Timezone: " + calendar.getTimeZone().getDisplayName()); for (Field field : dp.getDataType().getFields()) { Log.i(TAG, "\tField: " + field.getName() + " Value: " + dp.getValue(field)); if (field.equals(Field.FIELD_DISTANCE)) { distance = dp.getValue(field).asFloat(); } else { Log.e(TAG, "Unsupported field found"); } } boolean valid = false; if (distance != null) { valid = HealthStatValidityChecker.checkIfNormalDistance(distance, type); } if (valid) { summary.setMaxDistanceIfGreater(distance); summary.setMinDistanceIfSmaller(distance); summary.setMaxDurationIfLonger(duration); summary.setMinDurationIfShorter(duration); double count = summary.getCount(); summary.setAvgDistance((summary.getAvgDistance() * count + distance) / (count + 1)); summary.setAvgDuration((float) ((summary.getAvgDuration() * count + duration) / (count + 1))); summary.increaseCount(); } } } }