/** * Global Sensor Networks (GSN) Source Code * Copyright (c) 2006-2014, Ecole Polytechnique Federale de Lausanne (EPFL) * <p/> * This file is part of GSN. * <p/> * GSN is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * <p/> * GSN 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 General Public License for more details. * <p/> * You should have received a copy of the GNU General Public License * along with GSN. If not, see <http://www.gnu.org/licenses/>. * <p/> * File: gsn-tiny/src/tinygsn/gui/android/ActivityViewDataNew.java * * @author Do Ngoc Hoan */ package tinygsn.gui.android; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Calendar; import java.util.Collections; import java.util.Comparator; import java.util.List; import java.util.Locale; import tinygsn.beans.StreamElement; import tinygsn.controller.AndroidControllerVS; import tinygsn.gui.android.chart.AbstractChart; import tinygsn.gui.android.chart.SensorValuesChart; import tinygsn.gui.android.utils.VSListAdapter; import tinygsn.model.vsensor.AbstractVirtualSensor; import android.app.DatePickerDialog; import android.app.TimePickerDialog; import android.content.Intent; import android.graphics.Color; import android.os.AsyncTask; import android.os.Bundle; import android.support.v4.app.DialogFragment; import android.text.Editable; import android.text.InputType; import android.text.TextWatcher; import android.view.LayoutInflater; import android.view.View; import android.view.View.OnClickListener; import android.view.ViewGroup; import android.widget.AdapterView; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.ArrayAdapter; import android.widget.Button; import android.widget.DatePicker; import android.widget.EditText; import android.widget.Spinner; import android.widget.TableLayout; import android.widget.TableLayout.LayoutParams; import android.widget.TableRow; import android.widget.TextView; import android.widget.TimePicker; import android.view.MenuItem; public class ActivityViewData extends AbstractFragmentActivity { static int TEXT_SIZE = 10; private AndroidControllerVS controller = new AndroidControllerVS(); private TextView lblOutput = null; private Spinner spinnerVS, spinnerField, spinnerViewMode; private TableLayout table_view_mode = null; private List<StreamElement> streamElements = null; private String vsName = null; private String vsNameFromExtra = null; protected String fieldName; private int numLatest = 10; protected int viewMode = 1; private TextView txtStartDate, txtStartTime, txtEndDate, txtEndTime; private Calendar startTime = Calendar.getInstance(); private Calendar endTime = Calendar.getInstance(); @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_view_data); lblOutput = (TextView) findViewById(R.id.txbViewData); spinnerField = (Spinner) findViewById(R.id.spinner_field); spinnerVS = (Spinner) findViewById(R.id.spinner_vs); spinnerViewMode = (Spinner) findViewById(R.id.spinner_view_mode); lblOutput.setTextSize(TEXT_SIZE); startTime.add(Calendar.MINUTE, -1); Bundle extras = getIntent().getExtras(); if (extras != null) { vsNameFromExtra = extras.getString(VSListAdapter.EXTRA_VS_NAME); } getActionBar().setDisplayHomeAsUpEnabled(true); loadVSList(); loadViewMode(); setListeners(); addTableViewModeLatest(); } public void loadVSList() { new AsyncTask<AndroidControllerVS, Void, List<String>>() { @Override protected List<String> doInBackground(AndroidControllerVS... params) { List<String> list = new ArrayList<String>(); for (AbstractVirtualSensor vs : params[0].loadListVS()) { list.add(vs.getConfig().getName()); } return list; } @Override protected void onPostExecute(List<String> result) { ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(ActivityViewData.this, R.layout.spinner_item, result); dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinnerVS.setAdapter(dataAdapter); int index = 0; if (vsNameFromExtra != null) { for (String s : result) { if (s.equals(vsNameFromExtra)) { spinnerVS.setSelection(index); } index++; } } } }.execute(controller); } private void loadViewMode() { List<String> list = new ArrayList<String>(); list.add("Latest values"); list.add("Customize time"); ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(this, R.layout.spinner_item, list); dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinnerViewMode.setAdapter(dataAdapter); } public void setListeners() { spinnerVS.setOnItemSelectedListener(new OnItemSelectedListener() { public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) { vsName = parent.getItemAtPosition(pos).toString(); new AsyncTask<String, Void, List<String>>() { @Override protected List<String> doInBackground(String... params) { List<String> list = controller.loadListFields(params[0]); return list; } @Override protected void onPostExecute(List<String> result) { List<String> list = new ArrayList<String>(); for (String s : result) { list.add(s); } ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(ActivityViewData.this, R.layout.spinner_item, list); dataAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); spinnerField.setAdapter(dataAdapter); } }.execute(parent.getItemAtPosition(pos).toString()); } @Override public void onNothingSelected(AdapterView<?> arg0) { } }); spinnerField.setOnItemSelectedListener(new OnItemSelectedListener() { public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) { if (vsName == null) return; fieldName = parent.getItemAtPosition(pos).toString(); updateData(); } @Override public void onNothingSelected(AdapterView<?> arg0) { } }); spinnerViewMode.setOnItemSelectedListener(new OnItemSelectedListener() { public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) { if (vsName == null) return; viewMode = pos + 1; if (viewMode == 1) { addTableViewModeLatest(); } else { addTableViewModeCustomize(); } updateData(); } @Override public void onNothingSelected(AdapterView<?> arg0) { } }); } private void updateData() { new AsyncTask<Void, Void, List<StreamElement>>() { @Override protected List<StreamElement> doInBackground(Void... params) { List<StreamElement> list = new ArrayList<StreamElement>(); if (viewMode == 1) { list.addAll(controller.loadLatestData(numLatest, vsName)); } else { list.addAll(controller.loadRangeData(vsName, startTime.getTimeInMillis(), endTime.getTimeInMillis())); } return list; } @Override protected void onPostExecute(List<StreamElement> result) { streamElements = result; StringBuilder sb = new StringBuilder(); for (StreamElement se : result) { sb.append(se.toString()); } lblOutput.setText(sb); } }.execute((Void) null); } private void addTableViewModeLatest() { table_view_mode = (TableLayout) findViewById(R.id.table_view_mode); // table_view_mode.setLayoutParams(new // TableLayout.LayoutParams(LayoutParams.FILL_PARENT, // LayoutParams.WRAP_CONTENT)); table_view_mode.removeAllViews(); TableRow row = new TableRow(this); TextView txt = new TextView(this); txt.setText(" View "); row.addView(txt); final EditText editText_numLatest = new EditText(this); editText_numLatest.setText("10"); editText_numLatest.setInputType(InputType.TYPE_CLASS_NUMBER); editText_numLatest.requestFocus(); row.addView(editText_numLatest); editText_numLatest.addTextChangedListener(new TextWatcher() { @Override public void onTextChanged(CharSequence s, int start, int before, int count) { } @Override public void beforeTextChanged(CharSequence s, int start, int count, int after) { } @Override public void afterTextChanged(Editable s) { try { numLatest = Integer.parseInt(editText_numLatest.getText().toString()); updateData(); } catch (NumberFormatException e) { e.printStackTrace(); } } }); txt = new TextView(this); txt.setText(" latest values"); row.addView(txt); txt = new TextView(this); txt.setText(" "); row.addView(txt); table_view_mode.addView(row); row = new TableRow(this); Button detailBtn = new Button(this); detailBtn.setText("Detail"); detailBtn.setTextSize(TEXT_SIZE + 2); detailBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { showDialogDetail(); } }); Button plotDataBtn = new Button(this); plotDataBtn.setText("Plot data"); plotDataBtn.setTextSize(TEXT_SIZE + 2); plotDataBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { viewChart(); } }); TableRow.LayoutParams rowParams = new TableRow.LayoutParams(); rowParams.span = 2; row.addView(detailBtn, rowParams); row.addView(plotDataBtn, rowParams); row.setLayoutParams(new TableLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)); table_view_mode.addView(row); } private void addTableViewModeCustomize() { table_view_mode = (TableLayout) findViewById(R.id.table_view_mode); table_view_mode.removeAllViews(); // Row From TableRow row = new TableRow(this); TextView txt = new TextView(this); txt.setText("From: "); row.addView(txt); // Start Time SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss", Locale.ENGLISH); txtStartTime = new TextView(this); txtStartTime.setText(formatter.format(startTime.getTime()) + ""); txtStartTime.setBackgroundColor(Color.parseColor("#8dc63f")); row.addView(txtStartTime); txtStartTime.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { new TimePickerDialog(ActivityViewData.this, startTimeSetListener, startTime.get(Calendar.HOUR_OF_DAY) - 1, startTime.get(Calendar.MINUTE), true).show(); } }); // Add space txt = new TextView(this); txt.setText(" "); row.addView(txt); // Start Date formatter = new SimpleDateFormat("dd/MM/yyyy", Locale.ENGLISH); // txtStartDate, txtStartTime txtStartDate = new TextView(this); txtStartDate.setText(formatter.format(startTime.getTime()) + ""); txtStartDate.setBackgroundColor(Color.parseColor("#8dc63f")); row.addView(txtStartDate); txtStartDate.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { new DatePickerDialog(ActivityViewData.this, startDateSetListener, startTime.get(Calendar.YEAR), startTime.get(Calendar.MONTH), startTime.get(Calendar.DAY_OF_MONTH)).show(); } }); table_view_mode.addView(row); // Add a space row row = new TableRow(this); txt = new TextView(this); txt.setText("-"); row.addView(txt); table_view_mode.addView(row); // Row To row = new TableRow(this); txt = new TextView(this); txt.setText("To"); row.addView(txt); // End Time formatter = new SimpleDateFormat("HH:mm:ss", Locale.ENGLISH); txtEndTime = new TextView(this); txtEndTime.setText(formatter.format(endTime.getTime()) + ""); txtEndTime.setBackgroundColor(Color.parseColor("#8dc63f")); row.addView(txtEndTime); txtEndTime.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { new TimePickerDialog(ActivityViewData.this, endTimeSetListener, endTime.get(Calendar.HOUR_OF_DAY), endTime.get(Calendar.MINUTE), true).show(); } }); // Add space txt = new TextView(this); txt.setText(" "); row.addView(txt); // End Date formatter = new SimpleDateFormat("dd/MM/yyyy", Locale.ENGLISH); // txtStartDate, txtStartTime txtEndDate = new TextView(this); txtEndDate.setText(formatter.format(endTime.getTime()) + ""); txtEndDate.setBackgroundColor(Color.parseColor("#8dc63f")); row.addView(txtEndDate); txtEndDate.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { new DatePickerDialog(ActivityViewData.this, endDateSetListener, endTime.get(Calendar.YEAR), endTime.get(Calendar.MONTH), endTime.get(Calendar.DAY_OF_MONTH)).show(); } }); table_view_mode.addView(row); // Row row = new TableRow(this); Button detailBtn = new Button(this); detailBtn.setTextSize(TEXT_SIZE + 2); detailBtn.setText("Detail"); detailBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { showDialogDetail(); } }); Button plotDataBtn = new Button(this); plotDataBtn.setTextSize(TEXT_SIZE + 2); plotDataBtn.setText("Plot data"); plotDataBtn.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { viewChart(); } }); TableRow.LayoutParams params = new TableRow.LayoutParams(); // params.addRule(TableRow.LayoutParams.FILL_PARENT); params.span = 2; row.addView(detailBtn, params); row.addView(plotDataBtn, params); row.setLayoutParams(new TableLayout.LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT)); table_view_mode.addView(row); } DatePickerDialog.OnDateSetListener startDateSetListener = new DatePickerDialog.OnDateSetListener() { public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { startTime.set(year, monthOfYear, dayOfMonth); updateStartLabel(); } }; TimePickerDialog.OnTimeSetListener startTimeSetListener = new TimePickerDialog.OnTimeSetListener() { public void onTimeSet(TimePicker view, int hourOfDay, int minute) { startTime.set(Calendar.MINUTE, minute); startTime.set(Calendar.HOUR_OF_DAY, hourOfDay); updateStartLabel(); } }; DatePickerDialog.OnDateSetListener endDateSetListener = new DatePickerDialog.OnDateSetListener() { public void onDateSet(DatePicker view, int year, int monthOfYear, int dayOfMonth) { endTime.set(year, monthOfYear, dayOfMonth); updateEndLabel(); } }; TimePickerDialog.OnTimeSetListener endTimeSetListener = new TimePickerDialog.OnTimeSetListener() { public void onTimeSet(TimePicker view, int hourOfDay, int minute) { endTime.set(Calendar.HOUR_OF_DAY, hourOfDay); endTime.set(Calendar.MINUTE, minute); updateEndLabel(); } }; protected void updateEndLabel() { SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss", Locale.ENGLISH); txtEndTime.setText(formatter.format(endTime.getTime()) + ""); formatter = new SimpleDateFormat("dd/MM/yyyy", Locale.ENGLISH); txtEndDate.setText(formatter.format(endTime.getTime()) + ""); updateData(); } protected void updateStartLabel() { SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss", Locale.ENGLISH); txtStartTime.setText(formatter.format(startTime.getTime()) + ""); formatter = new SimpleDateFormat("dd/MM/yyyy", Locale.ENGLISH); txtStartDate.setText(formatter.format(startTime.getTime()) + ""); updateData(); } public void viewChart() { if (streamElements == null) return; if (streamElements.size() == 0) return; Collections.sort(streamElements, new Comparator<StreamElement>() { @Override public int compare(StreamElement lhs, StreamElement rhs) { return (int) (lhs.getTimeStamp() - rhs.getTimeStamp()); } }); ArrayList<Long> x = new ArrayList<Long>(); ArrayList<Double> y = new ArrayList<Double>(); for (int i = 0; i < streamElements.size(); i++) { y.add((Double) streamElements.get(i).getData(fieldName)); x.add(streamElements.get(i).getTimeStamp()); } Intent intent = null; AbstractChart chart = new SensorValuesChart(vsName, fieldName, x, y); intent = chart.execute(this); startActivity(intent); } public boolean onMenuItemSelected(int featureId, MenuItem item) { int itemId = item.getItemId(); switch (itemId) { case android.R.id.home: finish(); break; } return true; } private String getDataOutput() { if (streamElements == null) return ""; String out = streamElements.size() + " stream data are loaded:\n"; for (int i = 0; i < streamElements.size(); i++) { out += streamElements.get(i).toString() + "\n"; } return out; } private void showDialogDetail() { String out = getDataOutput(); DialogFragment newFragment = DetailedDataFragment.newInstance(out); newFragment.setStyle(DialogFragment.STYLE_NO_TITLE, 0); newFragment.show(getSupportFragmentManager(), "dialog"); } public static class DetailedDataFragment extends DialogFragment { String text; public String getText() { return text; } public void setText(String text) { this.text = text; } public static DetailedDataFragment newInstance(String text) { DetailedDataFragment i = new DetailedDataFragment(); i.setText(text); return i; } public DetailedDataFragment() {} @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View v = inflater.inflate(R.layout.text, container, false); View tv = v.findViewById(R.id.text); ((TextView) tv).setText(text); return v; } } }