Monday, January 25, 2010

Android Accelerometer and Orientation Example

Following is an example of how to use the Android accelerometer and orientation API’s. This example is based on Frank Ableson’s “Tapping into Android’s sensors” article over at IBM DeveloperWorks. I’ve made a change to the UI to use the Android TableView and implemented it as a Resource.

To get going, all you need to do is
  1. Create a new Android project 
  2. Replace the contents of main.xml with the xml in this sample 
  3. Replace the contents of your Activity class with the code in this sample

    Following is the new main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:stretchColumns="1">

        <TableRow>
            <TextView
                android:id="@+id/accelerometer_label"
                android:layout_column="1"
                android:text="Accelerometer"
                android:textSize="9pt"
                android:padding="3dip" />
        </TableRow>
      
        <TableRow>
            <TextView
                android:id="@+id/accel_x_label"
                android:layout_column="1"
                android:text="X:"
                android:textSize="8pt"
                android:padding="3dip" />
            <TextView
                android:id="@+id/accel_x_value"
                android:gravity="right"
                android:textSize="8pt"
                android:padding="3dip" />
        </TableRow>

        <TableRow>
            <TextView
                android:id="@+id/accel_y_label"
                android:layout_column="1"
                android:text="Y:"
                android:textSize="8pt"
                android:padding="3dip" />
            <TextView
                android:id="@+id/accel_y_value"
                android:gravity="right"
                android:textSize="8pt"
                android:padding="3dip" />
        </TableRow>

        <TableRow>
            <TextView
                android:id="@+id/accel_z_label"
                android:layout_column="1"
                android:text="Z:"
                android:textSize="8pt"
                android:padding="3dip" />
            <TextView
                android:id="@+id/accel_z_value"
                android:gravity="right"
                android:textSize="8pt"
                android:padding="3dip" />
        </TableRow>

        <View
            android:layout_height="2dip"
            android:background="#FF909090" />
          
    <TableRow>
            <TextView
                android:id="@+id/orientation_label"
                android:layout_column="1"
                android:text="Orientation"
                android:textSize="9pt"
                android:padding="3dip" />
        </TableRow>
      
        <TableRow>
            <TextView
                android:id="@+id/orient_x_label"
                android:layout_column="1"
                android:text="X:"
                android:textSize="8pt"
                android:padding="3dip" />
            <TextView
                android:id="@+id/orient_x_value"
                android:gravity="right"
                android:textSize="8pt"
                android:padding="3dip" />
        </TableRow>

        <TableRow>
            <TextView
                android:id="@+id/orient_y_label"
                android:layout_column="1"
                android:text="Y:"
                android:textSize="8pt"
                android:padding="3dip" />
            <TextView
                android:id="@+id/orient_y_value"
                android:gravity="right"
                android:textSize="8pt"
                android:padding="3dip" />
        </TableRow>

        <TableRow>
            <TextView
                android:id="@+id/orient_z_label"
                android:layout_column="1"
                android:text="Z:"
                android:textSize="8pt"
                android:padding="3dip" />
            <TextView
                android:id="@+id/orient_z_value"
                android:gravity="right"
                android:textSize="8pt"
                android:padding="3dip" />
        </TableRow>

    </TableLayout>





    Following is the new Android Activity Java class

    package com.blogspot.mobilestrategist;



    import com.blogspot.mobilestrategist.R;

    import android.app.Activity;
    import android.hardware.Sensor;
    import android.hardware.SensorEvent;
    import android.hardware.SensorEventListener;
    import android.hardware.SensorManager;
    import android.os.Bundle;
    import android.widget.TextView;

    public class AccelOrientExample extends Activity implements SensorEventListener {
    // Accelerometer X, Y, and Z values
    private TextView accelXValue;
    private TextView accelYValue;
    private TextView accelZValue;
    // Orientation X, Y, and Z values
    private TextView orientXValue;
    private TextView orientYValue;
    private TextView orientZValue;
    private SensorManager sensorManager = null;
        /** Called when the activity is first created. */
        @Override
        public void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            // Get a reference to a SensorManager
            sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
            setContentView(R.layout.main);
          
            // Capture accelerometer related view elements
            accelXValue = (TextView) findViewById(R.id.accel_x_value);
            accelYValue = (TextView) findViewById(R.id.accel_y_value);
            accelZValue = (TextView) findViewById(R.id.accel_z_value);
          
            // Capture orientation related view elements
            orientXValue = (TextView) findViewById(R.id.orient_x_value);
            orientYValue = (TextView) findViewById(R.id.orient_y_value);
            orientZValue = (TextView) findViewById(R.id.orient_z_value);
          
            // Initialize accelerometer related view elements
            accelXValue.setText("0.00");
            accelYValue.setText("0.00");
            accelZValue.setText("0.00");
          
            // Initialize orientation related view elements
            orientXValue.setText("0.00");
            orientYValue.setText("0.00");
            orientZValue.setText("0.00");      
        }
      
        // This method will update the UI on new sensor events
        public void onSensorChanged(SensorEvent sensorEvent) {
        synchronized (this) {
        if (sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
        accelXValue.setText(Float.toString(sensorEvent.values[0]));
        accelYValue.setText(Float.toString(sensorEvent.values[1]));
        accelZValue.setText(Float.toString(sensorEvent.values[2]));    
        }
        
        if (sensorEvent.sensor.getType() == Sensor.TYPE_ORIENTATION) {
        orientXValue.setText(Float.toString(sensorEvent.values[0]));
        orientYValue.setText(Float.toString(sensorEvent.values[1]));
        orientZValue.setText(Float.toString(sensorEvent.values[2]));    
        }
        }
        }
      
        // I've chosen to not implement this method
        public void onAccuracyChanged(Sensor arg0, int arg1) {
    // TODO Auto-generated method stub
    }
      
        @Override
        protected void onResume() {
        super.onResume();
        // Register this class as a listener for the accelerometer sensor
        sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
        // ...and the orientation sensor
        sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION), SensorManager.SENSOR_DELAY_NORMAL);
        }
      
        @Override
        protected void onStop() {
        // Unregister the listener
        sensorManager.unregisterListener(this);
        super.onStop();
        }
    }

    Android in the Enterprise: A Roadmap: Phase 1

    There has been a lot of discussion recently regarding Google's Nexus One and whether or not it is a suitable device for enterprise use. Instead of answering that question directly, I will discuss the broad requirements that most enterprises must satisfy before allowing mobile devices to connect to IT services.

    Mobile devices must be able to connect to enterprise messaging systems. Though the best mobile platforms have moved beyond being just messaging tools, email is still the killer application for mobile devices and support for enterprise messaging systems should be a core part of any enterprise grade mobile platform. To be specific, deep support for Exchange ActiveSync (EAS) is required. EAS is becoming the de-facto standard for syncing email and personal information manager (PIM) data to mobile devices, and is supported by Lotus Domino, Google Sync, and others in addition to Microsoft Exchange. The EAS protocol even supports pushing security policies to the device over the air.

    Many of the articles and blogs around the topic of Android in the enterprise have focused on the inherit ability of the phone to be secured and managed by enterprise IT. Google has designed a security architecture for Android that is focused on ensuring that applications running on the platform adhere to specific security policies that govern access to private user data, data owned by other applications, and device resources such as network access, Bluetooth access, etc. You can read more about the Android security model here.

    This security model, however necessary, solves a qualitatively different problem than the security burden placed on IT personnel charged with implementing a mobility solution for their organizations.
    Enterprise IT's primary mobile related security threat is physical loss of the device. Therefore a robust device loss protection (DLP) solution is required to address this problem. At minimum, most sophisticated IT organizations require that mobile device platforms provide the following capabilities before being allowed to access enterprise resources:
    Device Lock, i.e. a PIN or alphanumeric password is required to unlock the device
    Data-at-rest encryption for all sensitive corporate data and in some cases personal data
    Remote wipe capability, i.e. a remote wipe command sent via an IT administrative console to destroy data in the event of device loss
    Local wipe policies, to destroy data after a given number of failed unlock attempts--i.e. Enter a PIN five times, the device automatically wipes all data
    A mechanism to ingest a security policy configurations from a mobility management system

    Here I'll propose a simplified hypothetical Phase 1 roadmap for the Nexus One, and Android writ large, to become an enterprise class mobile platform.

    Support for Exchange ActiveSync

    Exchange ActiveSync is supported by most major mobile OS platforms, including iPhone OS, Windows Mobile, Symbian, and the Palm's webOS. Some Android handsets do support EAS, but those have tended to be handset vendor specific implementations, namely from HTC and Motorola. The Android platform itself is behind the curve here and should accelerate investment in EAS as a core platform capability.

    Exchange ActiveSync 2.5 and 12.1 and later
    Email Sync
    Contacts Sync
    Calendar Sync
    Ability to accept meetings
    Ability to Schedule meetings and send invites
    Security Policies: PIN, Encryption, Remote and Local Wipe


    Device Loss Protection

    Device loss is, at this time, the top mobile computing security threat faced by enterprise IT organizations. Therefore device loss protection mechanisms should be a core component of a comprehensive security model built into enterprise class mobile computing platforms.

    A robust PIN and/or alphanumeric device lock facility to prevent unauthorized access to the device itself
    Robust and transparent data-at-rest encryption
    Fast, seamless
    Multiple entropy, e.g. user's PIN as entropy, with PIN caching to allow for background sync while the device is locked
    Remote wipe: respond to remote wipe commands
    Local wipe capabilities
    Based on number of failed password attempts

    In a follow on post, I'll propose an extension to the roadmap to include device management, and enterprise integration.

    ShareThis