com.microsoft.band.sdksample.SensorsFragment.java Source code

Java tutorial

Introduction

Here is the source code for com.microsoft.band.sdksample.SensorsFragment.java

Source

//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);
        }
    }

}