Java tutorial
//Copyright (c) Microsoft Corporation All rights reserved. // //MIT License: // //Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated //documentation files (the "Software"), to deal in the Software without restriction, including without limitation //the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and //to permit persons to whom the Software is furnished to do so, subject to the following conditions: // //The above copyright notice and this permission notice shall be included in all copies or substantial portions of //the Software. // //THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED //TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL //THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF //CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS //IN THE SOFTWARE. package com.microsoft.band.sdksample; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.concurrent.atomic.AtomicReference; import com.microsoft.band.BandException; import com.microsoft.band.sensors.BandContactEvent; import com.microsoft.band.sensors.BandContactEventListener; import com.microsoft.band.sensors.BandGyroscopeEvent; import com.microsoft.band.sensors.BandGyroscopeEventListener; import com.microsoft.band.sensors.BandSensorManager; import com.microsoft.band.sensors.SampleRate; import android.content.Context; import android.graphics.Color; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; import android.os.Handler; import android.support.v4.app.Fragment; import android.app.Activity; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.RadioGroup; import android.widget.Switch; import android.widget.TableLayout; import android.widget.TextView; import android.widget.Toast; public class SensorsFragment extends Fragment implements FragmentListener, SensorEventListener { private SensorManager senSensorManager1; private SensorManager senSensorManager2; private Sensor senGyroscope; private Sensor senAccelerometer; private TableLayout mTableAcc; private TextView mTextAccX; private TextView mTextAccY; private TextView mTextAccZ; private TextView mTextAngX; private TextView mTextAngY; private TextView mTextAngZ; private TextView mTextLong; private TextView mTextLat; private TextView mTextTime; // Gyroscope controls private TableLayout mTableGyro; private TextView mTextGyroAccX; private TextView mTextGyroAccY; private TextView mTextGyroAccZ; private TextView mTextGyroAngX; private TextView mTextGyroAngY; private TextView mTextGyroAngZ; private double[] temp_list; // 0-5 phone, 6-11 band, 12-13 are loc private ArrayList<Double> list = new ArrayList<Double>(); // 0-5 band, 6-11 are phone, 12-13 are loc Handler handler = new Handler(); Runnable runnable = new Runnable() { public void run() { timerCollect(); } }; public void timerCollect() { for (int i = 0; i < temp_list.length; i++) { list.add(temp_list[i]); // mTextTime.setText(Double.toString(temp_list[i])); } mTextTime.setText(Double.toString(c)); c = c + 1; handler.postDelayed(runnable, 100); } private double c; // Contact sensor controls private TableLayout mTableContact; private TextView mTextContact; private String contact_value; // Each sensor switch has an associated TableLayout containing it's display controls. // The TableLayout remains hidden until the corresponding sensor switch is turned on. private HashMap<Switch, TableLayout> mSensorMap; // // For managing communication between the incoming sensor events and the UI thread // private volatile boolean mIsHandlerScheduled; private AtomicReference<BandGyroscopeEvent> mPendingGyroscopeEvent = new AtomicReference<BandGyroscopeEvent>(); private AtomicReference<BandContactEvent> mPendingContactEvent = new AtomicReference<BandContactEvent>(); @Override public void onSensorChanged(SensorEvent sensorEvent) { Sensor mySensor = sensorEvent.sensor; if (mySensor.getType() == Sensor.TYPE_GYROSCOPE) { temp_list[3] = (double) sensorEvent.values[0] * 180 / Math.PI; temp_list[4] = (double) sensorEvent.values[1] * 180 / Math.PI; temp_list[5] = (double) sensorEvent.values[2] * 180 / Math.PI; mTextAngX.setText(String.format("%.2f", temp_list[3])); mTextAngY.setText(String.format("%.2f", temp_list[4])); mTextAngZ.setText(String.format("%.2f", temp_list[5])); } else if (mySensor.getType() == Sensor.TYPE_ACCELEROMETER) { temp_list[0] = (double) sensorEvent.values[0]; temp_list[1] = (double) sensorEvent.values[1]; temp_list[2] = (double) sensorEvent.values[2]; mTextAccX.setText(String.format("%.3f", temp_list[0])); mTextAccY.setText(String.format("%.3f", temp_list[1])); mTextAccZ.setText(String.format("%.3f", temp_list[2])); } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } public SensorsFragment() { } public void onFragmentSelected() { return; } @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { View rootView = inflater.inflate(R.layout.fragment_sensors, container, false); senSensorManager1 = (SensorManager) getActivity().getSystemService(Context.SENSOR_SERVICE); senSensorManager2 = (SensorManager) getActivity().getSystemService(Context.SENSOR_SERVICE); senGyroscope = senSensorManager1.getDefaultSensor(Sensor.TYPE_GYROSCOPE); senSensorManager1.registerListener(this, senGyroscope, SensorManager.SENSOR_DELAY_NORMAL); senAccelerometer = senSensorManager2.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); senSensorManager2.registerListener(this, senAccelerometer, SensorManager.SENSOR_DELAY_NORMAL); mTableAcc = (TableLayout) rootView.findViewById(R.id.tableAcc); mTableAcc.setVisibility(View.GONE); mTextAccX = (TextView) rootView.findViewById(R.id.textAccX); mTextAccY = (TextView) rootView.findViewById(R.id.textAccY); mTextAccZ = (TextView) rootView.findViewById(R.id.textAccZ); mTextAngX = (TextView) rootView.findViewById(R.id.textPAngX); mTextAngY = (TextView) rootView.findViewById(R.id.textPAngY); mTextAngZ = (TextView) rootView.findViewById(R.id.textPAngZ); mTextLong = (TextView) rootView.findViewById(R.id.textLong); mTextLat = (TextView) rootView.findViewById(R.id.textLat); mTextTime = (TextView) rootView.findViewById(R.id.textTime); temp_list = new double[14]; c = 0; // Acquire a reference to the system Location Manager LocationManager locationManager = (LocationManager) getActivity() .getSystemService(Context.LOCATION_SERVICE); // Define a listener that responds to location updates LocationListener locationListener = new LocationListener() { public void onLocationChanged(Location location) { // Called when a new location is found by the network location provider. temp_list[12] = location.getLongitude(); temp_list[13] = location.getLatitude(); mTextLong.setText(Double.toString(temp_list[12])); mTextLat.setText(Double.toString(temp_list[13])); } public void onStatusChanged(String provider, int status, Bundle extras) { } public void onProviderEnabled(String provider) { } public void onProviderDisabled(String provider) { } }; // Register the listener with the Location Manager to receive location updates locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListener); runnable.run(); // // Gyro setup // mTableGyro = (TableLayout) rootView.findViewById(R.id.tableGyro); mTableGyro.setVisibility(View.GONE); mTextGyroAccX = (TextView) rootView.findViewById(R.id.textGyroAccX); mTextGyroAccY = (TextView) rootView.findViewById(R.id.textGyroAccY); mTextGyroAccZ = (TextView) rootView.findViewById(R.id.textGyroAccZ); mTextGyroAngX = (TextView) rootView.findViewById(R.id.textAngX); mTextGyroAngY = (TextView) rootView.findViewById(R.id.textAngY); mTextGyroAngZ = (TextView) rootView.findViewById(R.id.textAngZ); // // Contact setup // mTableContact = (TableLayout) rootView.findViewById(R.id.tableContact); mTableContact.setVisibility(View.GONE); mTextContact = (TextView) rootView.findViewById(R.id.textContact); turnOnSensors(); return rootView; } // // When pausing, turn off any active sensors. // @Override public void onPause() { super.onPause(); senSensorManager1.unregisterListener(this); senSensorManager2.unregisterListener(this); } private void turnOnSensors() { BandSensorManager sensorMgr = Model.getInstance().getClient().getSensorManager(); try { // contact sensor enabling mTableContact.setVisibility(View.VISIBLE); mTextContact.setText(""); sensorMgr.registerContactEventListener(mContactEventListener); // gyroscope enabling SampleRate rate; rate = SampleRate.MS128; mTableGyro.setVisibility(View.VISIBLE); mTextGyroAccX.setText(""); mTextGyroAccY.setText(""); mTextGyroAccZ.setText(""); mTextGyroAngX.setText(""); mTextGyroAngY.setText(""); mTextGyroAngZ.setText(""); sensorMgr.registerGyroscopeEventListener(mGyroEventListener, rate); mTableAcc.setVisibility(View.VISIBLE); mTextAccX.setText(""); mTextAccY.setText(""); mTextAccZ.setText(""); mTextAngX.setText(""); mTextAngY.setText(""); mTextAngZ.setText(""); } catch (BandException ex) { Util.showExceptionAlert(getActivity(), "Register sensor listener", ex); } } // // This method is scheduled to run on the UI thread after a sensor event has been received. // We clear our "is scheduled" flag and then update the UI controls for any new sensor // events (which we also clear). // private void handlePendingSensorReports() { // Because we clear this flag before reading the sensor events, it's possible that a // newly-generated event will schedule the handler to run unnecessarily. This is // harmless. If we update the flag after checking the sensors, we could fail to call // the handler at all. mIsHandlerScheduled = false; BandContactEvent contactEvent = mPendingContactEvent.getAndSet(null); BandGyroscopeEvent gyroscopeEvent = mPendingGyroscopeEvent.getAndSet(null); if (contactEvent != null) { contact_value = contactEvent.getContactStatus().toString(); mTextContact.setText(contact_value); } if (gyroscopeEvent != null) { if (contact_value.equals("WORN")) { temp_list[6] = (double) gyroscopeEvent.getAccelerationX() * 10; temp_list[7] = (double) gyroscopeEvent.getAccelerationY() * 10; temp_list[8] = (double) gyroscopeEvent.getAccelerationZ() * 10; temp_list[9] = (double) gyroscopeEvent.getAngularVelocityX() / 32.8; temp_list[10] = (double) gyroscopeEvent.getAngularVelocityY() / 32.8; temp_list[11] = (double) gyroscopeEvent.getAngularVelocityZ() / 32.8; mTextGyroAccX.setText(String.format("%.3f", temp_list[6])); mTextGyroAccY.setText(String.format("%.3f", temp_list[7])); mTextGyroAccZ.setText(String.format("%.3f", temp_list[8])); mTextGyroAngX.setText(String.format("%.2f", temp_list[9])); mTextGyroAngY.setText(String.format("%.2f", temp_list[10])); mTextGyroAngZ.setText(String.format("%.2f", temp_list[11])); // save data to array here } } } // // Queue an action to run on the UI thread to process sensor updates. Make sure // that we have at most one callback queued for the UI thread. // private synchronized void scheduleSensorHandler() { if (mIsHandlerScheduled) { return; } Activity activity = getActivity(); if (activity != null) { mIsHandlerScheduled = true; activity.runOnUiThread(new Runnable() { @Override public void run() { handlePendingSensorReports(); } }); } } // // Sensor event handlers - each handler just writes the new sample to an atomic // reference where it will be read by the UI thread. Samples that arrive faster // than they can be processed by the UI thread overwrite older samples. Each // handler calls scheduleSensorHandler() which makes sure that at most one call // is queued to the UI thread to update all of the sensor displays. // private BandGyroscopeEventListener mGyroEventListener = new BandGyroscopeEventListener() { @Override public void onBandGyroscopeChanged(final BandGyroscopeEvent event) { mPendingGyroscopeEvent.set(event); scheduleSensorHandler(); } }; private BandContactEventListener mContactEventListener = new BandContactEventListener() { @Override public void onBandContactChanged(final BandContactEvent event) { mPendingContactEvent.set(event); scheduleSensorHandler(); } }; // // Other helpers // private static void setChildrenEnabled(RadioGroup radioGroup, boolean enabled) { for (int i = radioGroup.getChildCount() - 1; i >= 0; i--) { radioGroup.getChildAt(i).setEnabled(enabled); } } }