Java tutorial
/* * Numenta Platform for Intelligent Computing (NuPIC) * Copyright (C) 2015, Numenta, Inc. Unless you have purchased from * Numenta, Inc. a separate commercial license for this software code, the * following terms and conditions apply: * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero Public License version 3 as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU Affero Public License for more details. * * You should have received a copy of the GNU Affero Public License * along with this program. If not, see http://www.gnu.org/licenses. * * http://numenta.org/licenses/ * */ package com.groksolutions.grok.mobile.metric; import com.google.android.gms.analytics.HitBuilders; import com.google.android.gms.analytics.Tracker; import com.groksolutions.grok.mobile.HTMITApplication; import com.groksolutions.grok.mobile.HourDayWeekActivity; import com.groksolutions.grok.mobile.R; import com.groksolutions.grok.mobile.preference.PreferencesConstants; import com.groksolutions.grok.mobile.service.HTMClientImpl; import com.numenta.core.data.AggregationType; import com.numenta.core.data.Metric; import com.numenta.core.utils.Log; import org.json.JSONException; import org.json.JSONObject; import android.app.ActionBar.Tab; import android.app.AlertDialog; import android.app.FragmentTransaction; import android.content.DialogInterface; import android.content.SharedPreferences; import android.os.AsyncTask; import android.preference.PreferenceManager; import android.support.v4.app.Fragment; import android.view.MenuItem; import java.util.Date; import static java.util.concurrent.TimeUnit.DAYS; import static java.util.concurrent.TimeUnit.MILLISECONDS; import static java.util.concurrent.TimeUnit.MINUTES; public class MetricDetailActivity extends HourDayWeekActivity { public static final String EXTRA_METRIC = "com.groksolutions.grok.mobile.metric"; public static final String EXTRA_DATE = "com.groksolutions.grok.mobile.metric.date"; private static final String TAG = MetricDetailActivity.class.getCanonicalName(); private Date _currentDate; private AggregationType _oldAggregation; private AggregationType _aggregation; /* * (non-Javadoc) * @see com.groksolutions.grok.mobile.BaseActivity#getResourceView() */ @Override protected int getResourceView() { return R.layout.activity_metric_detail; } /* * (non-Javadoc) * @see * com.groksolutions.grok.mobile.BaseActivity#createTabFragment(android. * app.ActionBar.Tab) */ @Override protected Fragment createTabFragment(Tab tab) { MetricDetailFragment fragment = new MetricDetailFragment(); AggregationType type = (AggregationType) tab.getTag(); Metric metric = getMetric(); MetricAnomalyChartData metricData = new MetricAnomalyChartData(metric, type); Date endDate = new Date(); if (getDate() != null) { final long currentSpan = endDate.getTime() - getDate().getTime(); final int halfWeekMinutes = (AggregationType.Week.minutes() * HTMITApplication.getTotalBarsOnChart()) / 2; int numMinutes = AggregationType.Hour.minutes() * HTMITApplication.getTotalBarsOnChart() / 4; if (AggregationType.Day.equals(type)) { numMinutes = AggregationType.Day.minutes() * HTMITApplication.getTotalBarsOnChart() / 2; } else if (AggregationType.Week.equals(type)) { long maxWeekSpan = MINUTES.convert(HTMITApplication.getNumberOfDaysToSync(), DAYS) - AggregationType.Week.minutes() * HTMITApplication.getTotalBarsOnChart(); if (MINUTES.convert(currentSpan, MILLISECONDS) > maxWeekSpan) { numMinutes = (int) maxWeekSpan; } else if (MINUTES.convert(currentSpan, MILLISECONDS) > halfWeekMinutes) { numMinutes = (int) MINUTES.convert(currentSpan, MILLISECONDS); } else { numMinutes = halfWeekMinutes; } } final long maxSpan = MILLISECONDS.convert(numMinutes, MINUTES); if (currentSpan > maxSpan) { endDate.setTime(getDate().getTime() + maxSpan); } } if (HTMITApplication.getAggregation().equals(type)) { metricData.setEndDate(endDate); setCurrentDate(endDate); } fragment.setMetricAnomalyData(metricData); // Google Analytics: Track metric name as first Custom Dimension for // this App. Tracker tracker = HTMITApplication.getInstance().getGoogleAnalyticsTracker(); tracker.send(new HitBuilders.AppViewBuilder().setCustomDimension(1, metric.getName()).build()); return fragment; } public Date getDate() { Date date = null; try { Long timestamp = (Long) getIntent().getExtras().getSerializable(EXTRA_DATE); if (timestamp != null) { date = new Date(timestamp); } } catch (Exception e) { Log.e(TAG, "Failed to get date from Intent"); } return date; } public void setCurrentDate(Date date) { this._currentDate = date; } public Date getCurrentDate() { return _currentDate; } public Metric getMetric() { Metric metric = null; try { String id = (String) getIntent().getExtras().getSerializable(EXTRA_METRIC); if (id != null) { metric = HTMITApplication.getDatabase().getMetric(id); } } catch (Exception e) { Log.e(TAG, "Failed to get Metric from Intent"); } return metric; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case R.id.menu_feedback: // Create remote feedback data and start an email message with // a screenshot to support Log.i(TAG, "{TAG:ANDROID.ACTION.TAB.FEEDBACK} Feedback tab selected."); // NOTE: this request completes asynchronously AlertDialog.Builder builder = new AlertDialog.Builder(MetricDetailActivity.this); builder.setMessage(getString(R.string.feedback_dialog_message)); builder.setTitle(getString(R.string.title_feedback_dialog)); builder.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { MetricDetailActivity.this.submitUserFeedbackAsync(); } }); builder.setNegativeButton(android.R.string.cancel, null); builder.show(); break; default: return super.onOptionsItemSelected(item); } return true; } /** * Submit user feedback; completes asynchronously */ private void submitUserFeedbackAsync() { // Wrap network I/O in AsyncTask to avoid // android.os.NetworkOnMainThreadException new AsyncTask<Void, Void, String>() { @Override protected String doInBackground(Void... params) { String uploadId = uploadFeedbackDataFromGrok(); if (uploadId == null) { uploadId = "Error uploading log file to S3"; } return uploadId; } @Override protected void onPostExecute(String uploadId) { emailFeedback(uploadId); } }.execute(); } /** * Request Grok API to upload feedback data for the user feedback feature * <p> * <b>NOTE</b>: this method performs network I/O and therefore MUST be * wrapped in AsyncTask or similar to avoid * {@link android.os.NetworkOnMainThreadException}. * </p> * * @return id string of the uploaded feedback data; null on error */ private String uploadFeedbackDataFromGrok() { String uploadId; // Connect to grok HTMClientImpl grok = null; final SharedPreferences prefs = PreferenceManager .getDefaultSharedPreferences(HTMITApplication.getContext()); String serverUrl = prefs.getString(PreferencesConstants.PREF_SERVER_URL, null); if (serverUrl != null) { serverUrl = serverUrl.trim(); String password = prefs.getString(PreferencesConstants.PREF_PASSWORD, null); try { grok = (HTMClientImpl) HTMITApplication.getInstance().connectToServer(serverUrl, password); grok.login(); Log.d(TAG, "Service connected to " + serverUrl); } catch (Exception e) { grok = null; Log.e(TAG, "Unable to connect to Grok.", e); } } else { Log.e(TAG, "Unable to connect to Grok. Missing server URL."); } if (grok == null) { return "Connection failed while uploading log file to S3"; } // Create the request // // The request data is a JSON object; the uid property is the metric // uid; // additional properties are optional; e.g.: // { // "uid": "2a123bb1dd4d46e7a806d62efc29cbb9", // "otherInfo": "Some arbitrary info." // } // // The response body is the uploadId string JSONObject request; try { request = new JSONObject(); request.put("uid", getMetric().getId()); } catch (JSONException e) { Log.e(TAG, "JSON error.", e); return "Failed to parse log information for uploading to S3"; } // Send the request to grok try { uploadId = grok.post(serverUrl + "/_logging/feedback", request.toString()); } catch (Exception e) { Log.e(TAG, "Grok _logging/feedback request failed.", e); return "Received an HTTP error while uploading log data to S3"; } if (uploadId == null) { uploadId = "Received null HTTP response from feedback upload request."; Log.e(TAG, uploadId); } return uploadId; } /* * (non-Javadoc) * @see * com.groksolutions.grok.mobile.HourDayWeekActivity#onTabSelected(android * .app.ActionBar.Tab, android.app.FragmentTransaction) */ @Override public void onTabSelected(Tab tab, FragmentTransaction fragmentTransaction) { this._oldAggregation = HTMITApplication.getAggregation(); super.onTabSelected(tab, fragmentTransaction); this._aggregation = HTMITApplication.getAggregation(); } /** * @return the oldAggregation */ public AggregationType getOldAggregation() { return this._oldAggregation; } /** * @return the aggregation */ public AggregationType getAggregation() { return this._aggregation; } }