Tuesday, October 18, 2011

The Best New Features in Android 4.0 Ice Cream Sandwich



Google just unveiled their new Nexus phone, the Galaxy Nexus, along with a preview of Android 4.0 Ice Cream Sandwich, coming to phones next year. Here's a look at the creamy new update to the Android operating system.
Most of what's gone into Ice Cream Sandwich is polish, making Android slicker, easier to use, and (finally) more consistent across the board. It's mostly filled with small improvements and tweaks that Google rattled off pretty quickly, so we've listed our favorites here in bulleted form. This isn't a comprehensive list; this is just what Google demoed at today's event—so there's probably even more to come.

Basic Improvements to Android

Google's made a lot of improvements in the way Android looks and feels, from the home screen to the notification drawer to the keyboard, including:
  • A new stylish lock screen, complete with facial recognition features that let you unlock your phone with a front-facing camera, as well as the ability to launch right into the camera with one gesture
  • A bigger emphasis on consistency with the way gestures work. For example, in the app drawer, you now swipe left to right to see other pages of apps, more like the home screens.
  • Widgets are now stored on another tab in the app drawer, making them easier to add to your home screen. They're also resizable.
  • Folders are now easier to create and use. Just drag one app on top of another, iOS-style to create a folder. You can rearrange them in the folder the same way, and it's all very fluid.
  • Ice Cream Sandwich's dock is customizable, and you can even put folders into it for quick access to apps and contacts.
  • Screenshot taking is now built-in. You can snap one by pressing Volume down + Power.Finally.

  • Notifications (pictured) are prettier and a tad more useful, showing small contact pictures next to notifications pertaining to email, SMS messages, and so on.
  • You can swipe from left to right to clear single notifications from the drawer, so your notifications aren't so cluttered.CyanogenMod users will be quite familiar with this feature.
  • You can open the notification drawer from the lock screen, without unlocking your phone. This is actually very convenient.
  • The new keyboard has better targeting, a simpler recommendations bar, and inline spell checking. Copy and paste has also been improved, and you can even select text and just drag it around within your message fluidly.
  • Speech-to-text now decodes your phrases in real time. When you say a word, you see that word show up in the window, before you move on to the next one—you no longer have to finish an entire sentence before seeing it show up in the text window.
  • A new default typeface, humorously labeled "Roboto" (but that actually looks pretty good)
Ice Cream Sandwich also sets the stage for button-less phones, à la the Honeycomb tablets. The Galaxy Nexus has no buttons on the front; it's all built-in to the OS. It also raises icon resolution, among other things, so it'll look good on higher-res phones—again, like the 4.65 inch, 1280x720 screen on the Galaxy Nexus.

The Browser

The Best New Features in Android 4.0 Ice Cream SandwichThe browser has a few nice features, but the biggest is certainly bookmark syncing with Chrome. Now, Andorid's browser will automatically use your Google account to sync all Chrome bookmarks to your phone. It also has a feature that'll take you from a web site's mobile page to the desktop page in one tap, which is really great. Tab management is similar to the old browser, but you can now "flick" tabs away to close them, which looks almost WebOS-like. And, lastly, it has a new "save for offline" feature for those articles you want to save for later. It won't tear out the article and make it more "readable", likeRead It Later does, but rather save the entire page in its current state for offline viewing.

Gmail

Gmail's entire interface has been revamped, featuring a very large, easy-to-read inbox with 2-line previews so you can more easily view your messages without even opening them. The action bar at the bottom has also improved, with simple buttons for creating a new message, viewing your labels, searching your inbox, and more. And, speaking of inbox search, Gmail now downloads the last 30 days worth of messages for searching, a value that you can change as much as you want in the settings. Lastly, when you're viewing a message, you can quickly transition to the next message with a swipe gesture—going back to their whole point of "making gestures consistent across the OS". It's a nice touch.

Calendar

The new calendar app is also nice, mostly in the realm of touch gestures. Like Gmail, you can swipe from side to side to move from day to day, and you can even pinch to zoom in on a specific block of the day. The whole thing is very smooth and fluid, moving as your fingers pinch to the exact block you specify.

Data Tracking

You can now track your data usage from Android's settings, and it looks really slick. Not only do you have the typical "this is how much data you've used this month" chart, as well as app-by-app usage to see which apps are the worst offenders, but you can pinpoint any block of time on the graph and see data usage for just that timeframe. For example, if there's a huge jump in data usage over a two-day period of time, you can "zoom in" on those two days and see which apps were using the most data during just those two days. It's a really effective way of tracking your usage. You can also add warnings for when you reach a certain threshhold, or even cut off data usage entirely when you go over a certain level—ensuring that you never go over your data cap without your say so.

Camera & Gallery

The Best New Features in Android 4.0 Ice Cream SandwichThe new camera app is designed to be fast and easy to use—they've minimized shutter lag, meaning the camera opens quickly and takes pictures instantly, without any loading time between shots. It's difficult to tell how well this will work on non-Galaxy Nexus phones, but the demo on the Galaxy Nexus looked fantastic. You can also access the camera right from the lock screen, making taking those spur-of-the-moment pictures near instantaneous.
The camera also has a built-in panorama mode, in which you just scan the camera from left to right to take a panorama shot—none of this taking-multiple-images-that-sort-of-fit-together business. It'll automatically stitch them together for you. Video recording has also improved, with continuous focus, zoom-while-recording, and time lapse features, not to mention the ability to take snapshots while you're recording video.
As far as the Gallery goes, you get this great "magazine-style" view with large thumbnails for your albums. You can browse your library by album, by location, or even by the people you tag in your photos. It also includes a simple photo editor, letting you remove red eye, crop, tilt, and even add Instagram-like filters to your photos.

People

The new contacts app—dubbed "People"—also brings this "magazine style", large-thumnailed view to Android. It almost looks Metro-like even, with the solid colors and giant tiles. Even clicking a contact card in another app will bring up their quick contact card with a giant picture of their face, which is pretty good looking. And, when someone calls you, you'll see a full screen image of their face, not this tiny-low-res-thumbnail crap that's been in Android for so long. Google Voice messages seem to show up directly in the people app, hinting that Google Voice integration might be much tighter in Ice Cream Sandwich.
One of the cooler new "people" features is the ability to send canned text messages when someone calls you. If someone calls you and you're busy, you can just send them a text message that says "I'm busy, call you later" (or whatever you want) with a simple swipe gesture. There are currently apps that'll do this for you, but it's really nice to have it built in.

Android Beam

The Best New Features in Android 4.0 Ice Cream SandwichLast, but not least, is Android Beam, a new "Bump"-like feature built into Android. If your phone has near-field communication (NFC) capabilities, like the Galaxy Nexus, you can just touch two phones together to send data instantly. You can send articles, maps, or even Market links from one phone to another just by opening it up on one phone and touching the two together, back-to-back. It's one of those features that's very cool, but not so practical yet—especially since not a lot of phones have NFC built-in.


Enhanced by Zemanta

Tuesday, October 11, 2011

Accelerometer Values App Demo

The accelerometer sensor is meant to simulate the acceleration forces like the speed changes that you see while playing games on phones. The values returned by the accelerometer for each axis range between (+/-)0–10. Let's see how to design this app. With three axes in our co-ordinate system, we will need 6 text fields to display 6 different values for (+/-) X, Y and Z axes.


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
       android:orientation="vertical" android:layout_width="fill_parent"
       android:layout_height="fill_parent" android:layout_gravity="center"
       android:background="@android:color/white">
       <TextView android:layout_width="match_parent" android:text="@string/x_axis"
              android:layout_height="wrap_content" android:gravity="center"
              android:textSize="25sp" android:padding="10dip" android:textColor="@android:color/black" />
       <LinearLayout android:id="@+id/x_axis"
              android:layout_width="match_parent" android:layout_height="wrap_content"
              android:background="@android:color/black">
              <TextView android:text="X-AXIS (+)ve:" android:layout_width="wrap_content"
                     android:id="@+id/txtSensorValueLeft" android:textSize="30dip"
                     android:layout_weight="1" android:layout_height="wrap_content"
                     android:gravity="left">TextView>
              <TextView android:layout_width="wrap_content" android:text="X-AXIS (-)ve:"
                     android:textSize="30dip" android:layout_weight="1"
                     android:id="@+id/txtSensorValueRight" android:layout_height="wrap_content"
                     android:gravity="right" />
LinearLayout>

Here, we have laid out a single TextView to display the axis name, followed by two text views to display the positive and negative values of the axis, repeated for Y and Z axes.

<TextView android:layout_width="match_parent" android:text="@string/y_axis"
              android:layout_height="wrap_content" android:gravity="center"
              android:textSize="25sp" android:padding="10dip" android:textColor="@android:color/black" />
       <LinearLayout android:id="@+id/y_axis"
              android:layout_width="fill_parent" android:layout_height="wrap_content"
              android:orientation="vertical" android:gravity="center"
              android:background="@android:color/black">
              <TextView android:layout_width="fill_parent" android:text="Y-AXIS (+)ve:"
                     android:layout_height="wrap_content" android:textSize="30dip"
                     android:layout_weight="1" android:id="@+id/txtSensorValueUp"
                     android:gravity="center" />
              <TextView android:layout_width="fill_parent" android:text="Y-AXIS (-)ve:"
                     android:layout_height="wrap_content" android:textSize="30dip"
                     android:layout_weight="1" android:id="@+id/txtSensorValueDown"
                     android:gravity="center" />
       LinearLayout>
       <LinearLayout android:layout_width="match_parent"
              android:layout_height="wrap_content" android:background="@android:color/black"
              android:padding="5dip">
       LinearLayout>
       <TextView android:layout_width="match_parent" android:text="@string/z_axis"
              android:layout_height="wrap_content" android:gravity="center"
              android:textSize="25sp" android:padding="10dip" android:textColor="@android:color/black"/>
       <LinearLayout android:id="@+id/z_axis"
              android:layout_width="fill_parent" android:layout_height="wrap_content"
              android:orientation="vertical" android:background="@android:color/black">
              <TextView android:layout_width="wrap_content" android:text="Z-AXIS (+)ve"
                     android:layout_height="wrap_content" android:textSize="30dip"
                     android:layout_weight="1" android:id="@+id/txtSensorZValueUp" />
              <TextView android:layout_width="wrap_content" android:text="Z-AXIS (-)ve"
                     android:layout_height="wrap_content" android:textSize="30dip"
                     android:layout_weight="1" android:id="@+id/txtSensorZValueDown" />
LinearLayout>

After laying out the UI, we have to actually get access to the sensor and display the values it returns. First, we need to reference the UI widgets in our Java class, so we declare variables for each:

private SensorManager mSensorManager;
       private Sensor mAccelerometer;
       private TextView mSensorValuesLeft;
       private TextView mSensorValuesRight;
       private TextView mSensorValuesUp;
       private TextView mSensorValuesDown;
       private TextView mSensorValuesZUp;
       private TextView mSensorValuesZDown;

Next, we need to reference them in our Java class; this can be done with the following code.

       /** Called when the activity is first created. */
       @Override
       public void onCreate(Bundle savedInstanceState) {
              super.onCreate(savedInstanceState);
              setContentView(R.layout.main);

              mSensorValuesLeft = (TextView) findViewById(R.id.txtSensorValueLeft);
              mSensorValuesRight = (TextView) findViewById(R.id.txtSensorValueRight);
              mSensorValuesUp = (TextView) findViewById(R.id.txtSensorValueUp);
              mSensorValuesDown = (TextView) findViewById(R.id.txtSensorValueDown);
              mSensorValuesZUp = (TextView) findViewById(R.id.txtSensorZValueUp);
              mSensorValuesZDown = (TextView) findViewById(R.id.txtSensorZValueDown);

The basic classes that we use to access sensors are: SensorManager, Sensor, SensorListener and SensorEvent. The SensorManager class provides an app the ability to access sensors and interact with them. The Sensor class is the model class for sensors, and provides the basic API to get values from the underlying sensor. The SensorListener class is a listener class (like a button onClick listener). It allows the app to register itself with the listener, to receive notifications of changes on the sensors, with the new values. The SensorEvent class interacts with the sensors, and has some basic methods that access sensors and retrieve data in case of any event or change.

Sensors are provided by the system service, so first we have to claim the sensor service from the system service with the following code:

              mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);

Now let's go ahead and use the above to implement our app:

mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(this, mAccelerometer,
                           SensorManager.SENSOR_DELAY_UI);

We start by getting hold of the sensor the using getDefaultSensor() method, which returns the default sensor for the type passed as a parameter. We requested Sensor.TYPE_ACCELEROMETER. After getting the sensor, we register our app with the sensor listener, to be able to listen to changes detected by the sensor, with RegisterListener(). SensorManager.SENSOR_DELAY_UI represents the delay in listening to sensor events. This constant specifies listening at speeds normal for a User Interface, because continuous listening to sensors drains battery very quickly. Other constants are SensorManager.SENSOR_DELAY_FASTEST, SensorManager.SENSOR_DELAY_NORMAL, and SensorManager.SENSOR_DELAY_GAME, whose purposes are obvious.

@Override
       public void onAccuracyChanged(Sensor sensor, int accuracy) {
              /*
               * You could have values defined for x, y and z axes and add these
               * values to the original values while using it in your app
               */
       }

       @Override
       public void onSensorChanged(SensorEvent event) {

       }

There are two methods that need to be overridden: onAccuracyChanged() and onSensorChanged(). The first is used to calibrate the sensor if wanted (you implement it if you want a custom calibration, not the default). OnSensorChanged() is invoked every time a change is detected by the sensor. The SensorEvent parameter will hold the values for all three axes.

@Override
       public void onSensorChanged(SensorEvent event) {
              if (event.sensor.getType() != Sensor.TYPE_ACCELEROMETER)
                     return;
              // X-axis
              if (event.values[0] > 0) {
                     mSensorValuesLeft.setText("X-axis (+)ve: "
                                   + Integer.toString((int) event.values[0]));
              } else if (event.values[0] < 0) {
                     mSensorValuesRight.setText("X-axis (-)ve:: "
                                  + Integer.toString(((int) event.values[0]) * -1));
              }

              float y = event.values[1];
              if (y > 0) {
                     mSensorValuesUp.setText("Y-axis (+)ve: "
                                  + Integer.toString((int) y));
              } else {
                     mSensorValuesDown.setText("Y-axis (-)ve: "
                                  + Integer.toString((int) y * -1));
              }

              float z = event.values[2];
              if (z > 0) {
                     mSensorValuesZUp.setText("Z-axis (+)ve: "
                                  + Integer.toString((int) z));
              } else {
                     mSensorValuesZDown.setText("Z-axis (-)ve: "
                                  + Integer.toString((int) z * -1));
              }
       }

The logic is very simple: the SensorEvent variable is an array holding 3 values corresponding to the X axis (element 0) to Z axis (element 2) respectively. We use simple if-else logic to set the values to their corresponding TextViews, If the value is positive then assign it to the positive value of axis otherwise set the negative value of axis. The negative value is multiplied by (-1) so that it will be displayed as a (+)ve value for (-)ve axis.

@Override
       protected void onPause() {
              // TODO Auto-generated method stub
              super.onPause();
              mSensorManager.unregisterListener(this);
       }

       @Override
       protected void onResume() {
              // TODO Auto-generated method stub
              super.onResume();
              mSensorManager.registerListener(this, mAccelerometer,
                           SensorManager.SENSOR_DELAY_UI);
       }

       @Override
       protected void onStop() {
              // TODO Auto-generated method stub
              super.onStop();
              mSensorManager.unregisterListener(this);
       }

As discussed earlier, we should not be listening to sensors all the time, because it could lead to serious battery drain—so we register in onResume() and un-register in onPause() and onStop(). Now, we can extend this app by showing a list of sensors that when a user clicks one, the respective sensor demo app is opened. To accomplish the above task, I will create another activity, and show a list of sensors supported by the device. 

mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
              mSensorList = mSensorManager.getSensorList(Sensor.TYPE_ALL);
              ArrayList mSensorNames = new ArrayList();

              for (Sensor sensor : mSensorList) {
                     mSensorNames.add(sensor.getName());
              }

              adapter = new ArrayAdapter(MainListActivity.this,
                           android.R.layout.simple_list_item_1, mSensorNames);
              setListAdapter(adapter);

Here, we get the instance of the Sensor service, and then get a list of available sensors using the SensorManager method getSensorList(). We then set up an adapter for the list, and display it to the user.
Enhanced by Zemanta