Microsoft and Client Remote Desktop for Android

Before establish connection between host PC and remote client app, you have to setup in both PC side and client side.

Set up your Remote Desktop in host PC. (This example running Windows 8.1 Pro)

– Enter “Remote Desktop” in Search, select “Select users who can use remote desktop“.

– Under Remote tab, enable “Allow remote connections to this computer” under Remote Desktop. Click the “Select Users” button.

Read More »

Creating a Mobile Event Calendar

Mobile-Calendar_Preview
This tutorial describes how to build an HTML5-based mobile calendar to track conferences and events that run on iOS and Android phones using a mobile version of dhtmlxScheduler (open source, GPL). At the end, users will be able to add and edit events, select the conference location on Google Maps, and see the events in day, month, or list views….

Read More »

 

How to Use Gmail as if It Had Folders and Filters

English: Gmail logo
Are you disheartened by Gmail’s lack of folders? Folders into which you can stick your emails; folders reminiscent of

drawers or trusty file systems; folders whither you can move messages, even automatically?

Well, they might not be called “folders”, but Gmail’s labels act a lot like folders do. Using filters, you can even have Gmail sort your incoming mail by sender, subject or other criteria to your custom folders — out of the Inbox.

Use Gmail as if It Had Folders and Filters

To make Gmail route certain mail to particular “folders”, bypassing your Inbox:

  • Click Create a filter.
  • Enter the desired criteria.
    • To filter all mail from somebody, type their email address in the From: field, for example.
  • Click Next Step ».
  • Make sure Skip the Inbox is checked.
  • Also check Apply the label:.
  • Select an existing label (folder) from the Choose label… menu or:
    • Select New label….
    • Type the desired name for the label (folder).
    • Click OK.
  • Optionally, check Also apply filter to conversations below to move existing messages matching your criteria to the folder.
  • Click Create Filter.

New messages matching your rules will arrive in their labels (i.e. folders) only. If you keep the Labels box on it and an eye on it, you’ll see labels with new messages highlighted.

Reference:http://email.about.com/od/gmailtips/qt/et_gmail_folder.htm

 

Reading and Writing a file to SD card sample program in Android

This sample android program shows you how write and read a file from SD Card in Android. In this program four buttons are shown and a Edit box. When you type some text into the edit box and click, Save to SD Card button, the text is saved to a text file and saved to the SD Card. When you click clear button, the edit box contents are cleared. When you click, Read Sd card button the file is read from the SD card and the contents are copied to the edit box.

The FileDemo2.java file is as follows:

package com.javasamples;
import java.io.*;
import android.app.Activity;
import android.os.Bundle;
import android.view.*;
import android.view.View.OnClickListener;
import android.widget.*;

public class FileDemo2 extends Activity {
	// GUI controls
	EditText txtData;
	Button btnWriteSDFile;
	Button btnReadSDFile;
	Button btnClearScreen;
	Button btnClose;

	@Override
	public void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.main);
	// bind GUI elements with local controls
	txtData = (EditText) findViewById(R.id.txtData);
	txtData.setHint("Enter some lines of data here...");

	btnWriteSDFile = (Button) findViewById(R.id.btnWriteSDFile);
	btnWriteSDFile.setOnClickListener(new OnClickListener() {

	public void onClick(View v) {
		// write on SD card file data in the text box
		try {
			File myFile = new File("/sdcard/mysdfile.txt");
			myFile.createNewFile();
			FileOutputStream fOut = new FileOutputStream(myFile);
			OutputStreamWriter myOutWriter = 
									new OutputStreamWriter(fOut);
			myOutWriter.append(txtData.getText());
			myOutWriter.close();
			fOut.close();
			Toast.makeText(getBaseContext(),
					"Done writing SD 'mysdfile.txt'",
					Toast.LENGTH_SHORT).show();
		} catch (Exception e) {
			Toast.makeText(getBaseContext(), e.getMessage(),
					Toast.LENGTH_SHORT).show();
		}
	}// onClick
	}); // btnWriteSDFile

		btnReadSDFile = (Button) findViewById(R.id.btnReadSDFile);
		btnReadSDFile.setOnClickListener(new OnClickListener() {

		public void onClick(View v) {
			// write on SD card file data in the text box
		try {
			File myFile = new File("/sdcard/mysdfile.txt");
			FileInputStream fIn = new FileInputStream(myFile);
			BufferedReader myReader = new BufferedReader(
					new InputStreamReader(fIn));
			String aDataRow = "";
			String aBuffer = "";
			while ((aDataRow = myReader.readLine()) != null) {
				aBuffer += aDataRow + "\n";
			}
			txtData.setText(aBuffer);
			myReader.close();
			Toast.makeText(getBaseContext(),
					"Done reading SD 'mysdfile.txt'",
					Toast.LENGTH_SHORT).show();
		} catch (Exception e) {
			Toast.makeText(getBaseContext(), e.getMessage(),
					Toast.LENGTH_SHORT).show();
		}
		}// onClick
		}); // btnReadSDFile

		btnClearScreen = (Button) findViewById(R.id.btnClearScreen);
		btnClearScreen.setOnClickListener(new OnClickListener() {

			public void onClick(View v) {
				// clear text box
				txtData.setText("");
			}
		}); // btnClearScreen

		btnClose = (Button) findViewById(R.id.btnClose);
		btnClose.setOnClickListener(new OnClickListener() {

			public void onClick(View v) {
				// clear text box
				finish();
			}
		}); // btnClose

	}// onCreate

}// AndSDcard

The output of this program will be as shown in the android emulator below.

The main.xml file in your res/layout folder is as follows:


<LinearLayout
android:id="@+id/widget28"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="#ff0000ff"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android"
>







 

PhoneGap PayPal-Plugin

by Paul Beusterien, Mobile Developer Solutions, Carl Stehle, Appception Inc. and Tomaz Kregar, Bucka IT

Image representing PayPal as depicted in Crunc...

Adding the Plugin to your project

Using this plugin requires Android Cordova (PhoneGap) and the PayPal Mobile Payments Library. The PayPal Mobile Payments Library can be downloaded here.

  1. Create an Android Cordova project. Details at http://docs.phonegap.com/en/2.0.0/guide_getting-started_android_index.md.html
  2. Put PayPal_MPL.jar into your project’s libs directory and add it to the build path. In Eclipse, right click on PayPal_MPL.jar and select Add to Build Path.
  3. Copy assets/www/ files into your project’s assets/www/ directory
  4. Copy src/com/phonegap/plugin/ files into your project’s src/com/phonegap/plugin/ directory
  5. Make sure your AndroidManifest.xml includes a superset of the permissions shown in the reference AndroidManifest.xml
  6. Add the com.paypal.android.MEP.PayPalActivity as shown in the reference AndroidManifest.xml
  7. Include the plugin registration in /res/xml/config.xml as shown in the reference config.xml
  8. Make sure the cordova.{version}.js filename in index.html matches the filename in your www directory.
  9. Deploy and test the app. The default environment is ENV_NONE.

Using the PayPal Sandbox

  1. Set up a PayPal buyer and seller sandbox account from https://developer.paypal.com/
  2. Update demo.js to use ENV_SANDBOX instead of ENV_NONE. See comments near bottom of demo.js
  3. In index.html, update the pmt_recipient field to your sandbox seller account

 

Helping URl: https://github.com/phonegap/phonegap-plugins/tree/master/Android/PayPalPlugin

 

Enhanced by Zemanta

Android: Speech To Text using API

 

Android has a very cool feature that still many developers dont know. Apps like Any.DO uses speech to text conversion feature quite creatively. In today’s world of Siri, voice commands are of utmost importance. Android natively provides feature of Speech to Text so why not to use it in our app!

I will show you how to use Android’s Speech to Text API in an application.

Let’s make our demo application.

Demo App

The App will be very simple. It will have a button with Mic symbol. On click of which we trigger Android’s Speech to Text Intent which shows a dialog to take speech input. The speech input is then converted into text. The text is then displayed in a text view.

Step 1: Create Basic Android Project in Eclipse

Create a Hello World Android project in Eclipse. Go to New > Project > Android Project. Give the project name as SpeechToTextDemo and select Android Runtime 2.1 or sdk 7. I have given package name net.viralpatel.android.speechtotextdemo.

Once you are done with above steps, you will have a basic hello world Android App.

Step 2: Change the Layout

For our demo, we need simple layout. Just one Image Button to trigger Speech to Text API and one TextView to display result text that is converted from speech.

Open layout/main.xml in your android project and replace its content with following:

File: res/layout/main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_above="@+id/textView1"
    android:layout_toLeftOf="@+id/textView1"
    android:gravity="center"
    android:orientation="vertical" >
    <ImageButton
        android:id="@+id/btnSpeak"
        android:layout_width="fill_parent"
        android:layout_height="wrap_content"
        android:layout_margin="10dp"
        android:layout_marginRight="10dp"
        android:layout_marginTop="10dp"
        android:contentDescription="@string/speak"
        android:src="@android:drawable/ic_btn_speak_now" />
    <TextView
        android:id="@+id/txtText"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginLeft="10dp"
        android:layout_marginRight="10dp"
        android:layout_marginTop="10dp"
        android:textAppearance="?android:attr/textAppearanceLarge" />
</LinearLayout>

The UI is very simply. One LinearLayout to organize the button and text view. Note the id for button: btnSpeak and text view: txtText which we will use in our Java code.

Step 3: Android Java Code to trigger Speech to Text API

Open SpeechToTextDemoActivity class and replace the code with following.

File: SpeechToTextDemoActivity.java

package net.viralpatel.android.speechtotextdemo;
import java.util.ArrayList;
import android.app.Activity;
import android.content.ActivityNotFoundException;
import android.content.Intent;
import android.os.Bundle;
import android.speech.RecognizerIntent;
import android.view.Menu;
import android.view.View;
import android.widget.ImageButton;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
    protected static final int RESULT_SPEECH = 1;
    private ImageButton btnSpeak;
    private TextView txtText;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        txtText = (TextView) findViewById(R.id.txtText);
        btnSpeak = (ImageButton) findViewById(R.id.btnSpeak);
        btnSpeak.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent = new Intent(
                        RecognizerIntent.ACTION_RECOGNIZE_SPEECH);
                intent.putExtra(RecognizerIntent.EXTRA_LANGUAGE_MODEL, "en-US");
                try {
                    startActivityForResult(intent, RESULT_SPEECH);
                    txtText.setText("");
                } catch (ActivityNotFoundException a) {
                    Toast t = Toast.makeText(getApplicationContext(),
                            "Opps! Your device doesn't support Speech to Text",
                            Toast.LENGTH_SHORT);
                    t.show();
                }
            }
        });
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);
        return true;
    }
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        switch (requestCode) {
        case RESULT_SPEECH: {
            if (resultCode == RESULT_OK && null != data) {
                ArrayList<String> text = data
                        .getStringArrayListExtra(RecognizerIntent.EXTRA_RESULTS);
                txtText.setText(text.get(0));
            }
            break;
        }
        }
    }
}

The heart of Speech to text Android API is package android.speech and specifically class android.speech.RecognizerIntent. Basically we trigger an Intent (android.speech.RecognizerIntent) which shows dialog box to recognize speech input. This Activity then converts the speech into text and send backs the result to our calling Activity. When we invoke android.speech.RecognizerIntent intent, we must use startActivityForResult() as we must listen back for result text.

Note how in above code we crate intent android.speech.RecognizerIntent and trigger it. Also we add one extra parameter using .putExtra() method. When invoking RecognizerIntent, we must provide extra RecognizerIntent.EXTRA_LANGUAGE_MODE. Here we are setting its value to en-US.

Since we triggered the RecognizerIntent via startActivityForResult(), we override method onActivityResult(int requestCode, int resultCode, Intent data) to handle the result data. The
RecognizerIntent will convert the speech input to text and send back the result as ArraList with key RecognizerIntent.EXTRA_RESULTS. Generally this list should be ordered in descending order of speech recognizer confidence. Only present when RESULT_OK is returned in an activity result. We just set the text that we got in result in text view txtText using txtText.setText().

One thing worth noting here is how to handle devices/android version that doesn’t support speech to text API. In such case, exception ActivityNotFoundException will be thrown when we try to start activity. In above example, we have catched this exception and displayed a message “Opps! Your device doesn’t support Speech to Text” using Toast.

Screen shots of Android App

And that’s all! Just execute the app in Android emulator or real device and see following output.

android-speech-to-text-api-demo

android-speech-to-text-activity

android-speech-to-text-conversion

android-speech-text

Download Source Code

Android_SpeechToTextDemo.zip (350 KB)

 

IOS Development Tutorial Series: Hello World

Mostly everyone starts out programming with a Hello World exercise, so let’s not stray from the group since it seems they are doing well…

As we go through this series I will explain concepts like Objective-C (the programming language iOS apps are written in), iPhone development, and programming in general…

Lets get started!

1. Open Xcode and click “Create a new Xcode Project”
2. Select “View-Based Application” and click choose…

3.Give your app the name “HelloWorld

When the application project opens you will be presented with a view similar to this…

If you click on the files from the classes folder you will be able to see the code in the right window. As you can see Apple gives you some pre-written code that is commented out. On that note, I’ll explain to you what a comment is… A comment is text that will not be executed by the compiler (Xcode). A comment that is just one line will with start with a “//” and a comment that is more than one line long is started with a “/*” and ended with a “*/”… Comments come in very useful when developing programs. You can use comments to document code for later viewing or to document code for other developers.

Before we start writing our first app I need introduce and explain a few concepts, OOP (Object Oriented Programming), MVC (Modal View Controller), and “.h” and “.m” files. Let me take a shot at explaining OOP to you… The Object in Object Oriented Programming is basically two files of code (.h and .m) that work together so that a developer can call that code in their own programs. This provides a massive framework for developers so that they don’t have to start completely from scratch. If you are having troubles understanding the object oriented programming concept you can ask me questions by emailing me at Derek@homeschooldev.com.

Now lets start with the “.h” and “.m” files. Open up the “HelloWorldViewController.h” file by single clicking on the file. As you can see, the code is displayed in the window to the right. A “.h” (header) file is a basically a blue print to an object and a “.m” (implementation file) is where all the code is implemented and executed from. If you don’t understand this concept yet, that’s ok, we will come back to it…

MVC (Model View Controller) is something that is used when developing apps for iOS and Mac OS X. It is something that splits up the code and the actual interface that the user sees. Model, is the users data and the data you display to the user, View is what the user interfaces with and a controller is your code that manages the link between the view and the model. This concept may seem edgy now, but it will grow on you very quickly and makes the life of a programmer much easier and organized.

Lets get coding!

In the header file, “HelloWorldViewController.h”, we are going to declare an IBOutlet. An IBOutlet is what connects your code to a visual object, such as a label or a button.

3. Between the curly braces type “IBOutlet UILabel *label;” and outside the curly braces type “-(IBAction)button;”

An IBAction is a method (block of code) that can be called. An IBAction is recognized by the view and allows you to connect that specific method (block of code) to a UI item, such as a button so that the button will execute that block of code.

That’s all we need to do in the header file… Now lets start designing the interface.

4. Open the folder named “Resources” and double click the file named “HelloWorldViewController.xib”

This will bring up a window similar to this:

This is the program you use to design your user interface. On the left you are given a list of objects that you can use in your user interface, to the right of that you are given the window where you put the objects to design the interface, the next window isn’t important right now, and the next window is called the inspector and is the window where you can change all the attributes of nearly everything in your UI.

Lets start designing!

5. From the left window, drag a label onto your view.


6. Now that you have your label on your view, resize the label using the blue lines as a guide.


7. Now center the text in the label using the button in the inspector window:

8. Clear the text from the label using the textfield in the inspector window named “Text”

 


9. Now lets put a button on our view and give it a name using the same methods that we just used to put a label on our view.

We are done designing the view, but the code we are about to write has no idea when to be called. We must add a link between the code and the UI element.

10. Select “Files Owner” from the main view and then click the connections tab on the Inspector window.

On the Inspector window, you can see the IBOutlet and IBAction you defined earlier.

11. Click on the plus button next to the label definition and drag it onto the label on the view.

12. Now drag the plus button next to the “button” definition on to the button in the view. A window will popup asking you when you want to perform this action… You can perform the action when the user touches the button and then lets up, touches the button, double taps the button, and a whole bunch of other things. We are going to use “Touch up Inside”, so select it.

13. Click File>Save or Command+S on your keyboard.

We now have our interface designed and our outlet and action linked up to our view. We can now start writing code.

14. Go the the “HelloWorldViewController.m” file (implementation file), this is where all the work gets done and is the place you write your code.

We are going to need to implement the IBAction we define earlier in our header file and give it some code.

15. Under the “@Implementation” line type:

-(IBAction)button {

}

This is called a method, and it is what’s called when the user presses the button (because we linked this IBAction to the button in interface builder).

This method is kinda boring, don’t you think? It doesn’t do anything…. Lets give it some life!

16. In the new method, type:

“label.text = @”Hello World!”;”

This line of code is assigning the text “Hello World!” to the label that we attached to our IBOutlet definition.

We are done!

17. Click File>Save or Command+S on your keyboard so that you don’t lose your progress.

18. Now you can click Build and Run at the top of the window to run your application in the simulator.

If you followed the instructions correctly you application should build and start up in the simulator with no errors or warnings.

You should see something like this:

If your app didn’t start up correctly or gave you errors, feel free to ask any question so that the community or I can help you.

We have learned a lot in this tutorial, hopefully I have explained everything well enough for you to understand…

Some key items you need to understand before moving on to the next tutorial are, the concepts of MVC and OOP. If you felt I didn’t explain these concepts very well you can leave a comment below or email me if you are needing help understanding them.

 

Install SDK + PhoneGap for AppleIOS device

iOS SDK included in Xcode 3.1
Image via Wikipedia
  • 1. Requirements for AppleIOS device

    Necessary for Installing on Device:

  • 2. Install SDK + PhoneGap

    Download and install Xcode from Apple Developer Portal (Membership required)

    Download the latest copy of PhoneGap and extract its contents. Navigate to the iOS directory and run the installer until completion.

  • 3. Setup New Project

    • Launch Xcode, then under the File menu select New and then New Project…
    • Select PhoneGap-based Application from the list of templates

    • Select the Next button, Fill in the “Product Name” & “Company Identifier” for your app

    • Choose a directory to store your app
    • You should see your project in Xcode 4 now. Press the Run button in the top left corner. Your build should succeed and launch in the simulator
    • You should see a error in your simulator informing you index.html was not found
    • To fix this, we need to copy the www directory into the project. Right click on the project in the left navigation window and click show in finder
    • In Finder, you should see the www directory beside your project
    • Next step is IMPORTANT! Drag the www folder into Xcode 4. You can’t just drag the www folder into your app’s folder. It needs to be dragged into Xcode 4!! In my case I would drag it and drop it on HiWorld shown below.

  • After you drag, you should see a prompt with a few options. Make sure to select Create folder references for any added folders. Click Finish
  • 4. Hello World

    Open the folder named www and type <h1>Hello World</h1> after the <body> tag in index.html. You can also add any associated Javascript and CSS files there as well.

  • 5A. Deploy to Simulator

    • Make sure to change the Active SDK in the top left menu to Simulator+version#.
    • Hit Run in your project window header.
  • 5B. Deploy to Device

    • Open [AppName]-Info.plist and change BundleIdentifier to the identifier provided by Apple. If you have a developer license, you can access and run the Assistant at here and register your App.
    • Make sure to change the Active SDK in the top left menu to Device+version#.
    • Hit Run in your project window header.

  • Done!

    You can also checkout more detailed version of this guide here

 

 

User interface design for Android apps

Android x86
By Richard Leggett on November 29, 2011

Android apps can be just as beautiful as their iOS counterparts. Richard Leggett, co-director of Bitmode Ltd, digs deep into the styling and theming and explains how to use just XML and image files to add a fresh look and feel to your app

It’s sometimes the case that Android apps don’t seem to receive as much love and attention from a designer as they deserve. But Android provides an excellent mechanism for styling, skinning and theming your user interfaces. So with that in mind, let’s take a look at how to make your app stand out. The best bit, almost all of this can be done using just XML and PNG files.

Advertisement

Applying a background Drawable

Drawable is the base class for just about anything that can be drawn on screen. We’re talking images, colours, gradients and a few more complex types that just affect other drawables they are wrapped around (for example, clipping and rotation). Drawables usually come in the form of image files, XML files, or are created through code.

To get a better idea of how a drawable is used, we’ll take a look at specifying a PNG for the background property of a button widget. This will change the button from the default Android style, to our own custom style.

To start, import the “Backgrounds” project into Eclipse by choosing the Import option from the File menu. You’ll need to have downloaded the Android 2.2 SDK via the Android SDK Manager in order to run the project. If this is your first time using the Android SDK with the ADT and Eclipse, please follow the instructions on the following page to get up and running: developer.android.com/sdk/eclipse-adt.html.

 

 

If you run the project you’ll see a standard grey button, and also a shiny green button. Here’s how we specify a different background to use for the button:

  • View source
  • Copy code
  1. <Button
  2.         android:layout_width=”wrap_content”
  3.         android:layout_height=”wrap_content”
  4.         android:text=”Green Button”
  5.         android:background=”@drawable/btn_green” />

Any time you use “@drawable/filename” Android will look at all the “drawables” folders in your project until it finds the best match for the device it’s running on. Notice that when you press down on the button we no longer see a different pushed state. We’ll look at how to supply different states later in Selectors.

9-Patch

Some platforms have the concept of splicing a single image up to be applied to a larger element in such a way that only the middle is stretched. This means the corners, which may be rounded, do not stretch and look blurry or pixelated. In CSS3 this is called border-image, and in Flash, 9-slice.

Android has an advanced version of this called “9-Patch”.  Let’s take a look at our green button being scaled up both with and without using 9-patch.

 

 

There’s an app called draw9patch that can be found with the SDK designed to help with creating these.

 

The draw9patch app

 

On the left you can see a zoomed-in version of our PNG with black lines around the border. You can also see a cross-section where the overlaid light-green lines overlap; this is the part of the image that will scale. In this case it’s just a single pixel. On the right we see various scaled versions of the PNG. Notice how the corners don’t stretch and distort, that’s down to the single green pixel being stretched to fill the space.

To use 9-patch just add a 1-pixel transparent border around your image. Then draw solid black lines that run along the top and left edges to dictate which parts should stretch, and two more black lines right and bottom to indicate where content can sit (make sure you turn off anti-aliasing when drawing these lines, it will complain if any pixel in the border is not 100% black or transparent). Finally, save the file with a “.9.png” extension. Android will automatically assume it is a 9-patch based on the extension.

This means for a button we can use a single PNG to define both how it looks and where content (such as text or icons) appear within it! The ability to define the content area also means you can create an off-centre region for content that ignores say, a drop-shadow, when centering content.

Multiple PPI-screens

The screen you’re looking at is probably running at something like 100 PPI (for the sake of argument, when you read PPI, pixels-per-inch, we can treat it pretty much as DPI, dots-per-inch). So at 100 PPI, if you get right in close to your screen, you can pretty easily see the individual dots. With a Samsung Galaxy Nexus we’re up to 316 PPI; pixels are densely packed into a much smaller space to give it that crisp print-like quality, but that brings with it a challenge.

DPI independence is a key concept when designing for screen; be it phone, computer, tablet or TV. If an icon is 48×48 pixels on your laptop screen, it may physically measure as half an inch wide. On a high DPI (HDPI) phone, the pixels are crammed that much tighter that this same icon would appear less than a quarter of an inch wide. You can imagine that an icon appearing as a tiny square is harder to press, so how do we cater for this wide range of screens?

 

A range of icons that will appear the same physical size on low, medium and high-density screens
A range of icons that will appear the same physical size on low, medium and high-density screens

 

Instead of using pixels or “px” to specify the widths and heights of elements on screen, it’s better to use the “dip” (Device Independent Pixel) unit. This is similar to CSS’ px units which are scaled automatically depending on the DPI of the device. As you may have experienced on your phone, this is why some images can look blurry. Along with text, phone browsers scale px measurements of images up to twice the original width and height to help make existing web pages work without additional effort.

Open up the project “UsingDIPs” to see how we specify dip units for widths and heights in the main.xml layout file.

  • View source
  • Copy code
  1. <?xml version=”1.0″ encoding=”utf-8″?>
  2. <LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android&#8221;
  3.    android:layout_width=”fill_parent”
  4.    android:layout_height=”fill_parent”
  5.    android:orientation=”vertical” >
  6.     <Button
  7.        android:layout_width=”200dip”
  8.        android:layout_height=”wrap_content”
  9.        android:text=”I’m 200 dips wide” />
  10. </LinearLayout>

In this layout we have a single button with a width of “200dip” (that’s 200px on a MDPI screen, 1.5x or 300px on a HDPI screen). If you open up the layout in the visual editor you’ll see a dropdown box with “3.7in WVGA (Nexus One)” or similar in the top left. You can switch to various other phone screens here, from LDPI to HDPI. Notice how the button width remains the same proportion of the entire screen. Using DIPs we can make sure that this button is the same physical size across devices, and it doesn’t just apply to buttons, any container or widget can accept DIP sizing. The other key property for building scalable layouts is layout_weight, which acts as a kind of percentage-based layout by sharing available space amongst children based on their “weights”, but that is outside of the scope of this article.

Multiple DPI assets

This subject can cause confusion between designers and developers. So to summarise: the DPI property in Photoshop is not important unless you’re printing… all that matters are the width and height in pixels. As a rule, you multiple by 1.5 to go from medium to high to extra-high DPI; so a 48x48px icon should be designed at 72×72 pixels to appear the same physical size on a HDPI phone (eg Galaxy S2), and at 96x96px for XHDPI (eg Galaxy Nexus).

You tell Android what assets to use by putting the files in the relevant drawables folder… drawable-mdpi, drawable-hdpi and so on.

 

Android’s resource folders let you include assets for various device profiles
Android’s resource folders let you include assets for various device profiles

 

Before you worry about having to design three versions of all your assets, Android will automatically attempt to scale up or down assets for you from whichever sizes you provide. Creating larger HDPI versions of assets will simply improve and crisp up existing assets on high-res screens (you may want to focus on enhancing key assets like buttons, and save on file size for things like background textures by not making super high-res versions as this may not be perceivable).

Selectors: The StateListDrawable and ColorStateList

We’re just starting to dig deeper into the power of the Android platform’s graphical abilities. Next up we’ll look at selectors. These are XML files that tell the UI to use a different drawable depending on the state of a widget. For example whether the user is pressing it, whether it is disabled, selected and so on.

We’ll take another widget, the Checkbox. If you want to import the “Selectors” project you can run the demo and see how we can style a CheckBox across multiple states: checked, un-checked, pressed while checked and of course pressed whilst un-checked. There are a few other possible states such as enabled,  selected or focussed (tabbed-to), but for now these four are enough for our purpose.

 

A wood-style checkbox
A wood-style checkbox

 

Along with android:background, the CheckBox widget has another attribute called android:button. Like the background, this can be set to a drawable. In this case, we’re not specifying just one PNG file, we’re specifying a StateListDrawable XML file.

Our checkbox StateListDrawable:

  • View source
  • Copy code
  1. <?xml version=”1.0″ encoding=”utf-8″?>
  2.     <!– checked, pressed –>
  3.     <item android:state_pressed=”true” android:state_checked=”true”
  4.          android:drawable=”@drawable/btn_check_on_pressed”/>
  5.     <!– checked, pressed –>
  6.     <item android:state_pressed=”true” android:state_checked=”false”
  7.          android:drawable=”@drawable/btn_check_off_pressed”/>
  8.     <!– checked –>
  9.     <item android:state_checked=”true”
  10.          android:drawable=”@drawable/btn_check_on”/>
  11.     <!– default –>
  12.     <item android:drawable=”@drawable/btn_check_off” />
  13. </selector>

You may notice that the text also changes colour when we press the checkbox. This is down to a ColorStateList, which you can find in the /res/color/ folder. We simply set the android:textColor property to “@color/checkbox_text_color” instead of a simple hex value and it does the rest.

The wooden checkbox as it appears in code:

  • View source
  • Copy code
  1. <?xml version=”1.0″ encoding=”utf-8″?>
  2. <LinearLayout xmlns:android=”http://schemas.android.com/apk/res/android&#8221;
  3.    android:layout_width=”fill_parent”
  4.    android:layout_height=”fill_parent”
  5.    android:orientation=”vertical”
  6.    android:background=”#ffffffff” >
  7.     <CheckBox
  8.        android:id=”@+id/checkBox1″
  9.        android:layout_width=”wrap_content”
  10.        android:layout_height=”wrap_content”
  11.        android:text=”CheckBox”
  12.        android:button=”@drawable/checkbox_button”
  13.        android:textColor=”@color/checkbox_text_color” />
  14. </LinearLayout>

Styles and themes

Along with drawables we have the concept of styles and themes. This should be familiar to people that have used CSS, but in Android we use XML to define styles, and styles can inherit from other “parent” styles. Styles apply to widgets and themes apply to activities or apps, a theme is a collection of styles.

Open up the “Styles” project to see the code for this one. We start by creating a “styles.xml” file in the /res/values folder. Android will look in here for our styles.

Our WarningTextView style:

  • View source
  • Copy code
  1. <?xml version=”1.0″ encoding=”utf-8″?>
  2. <resources>
  3.     <style name=”WarningTextView” parent=”@android:style/Widget.TextView”>
  4.         <item name=”android:background”>#ffff00</item>
  5.         <item name=”android:textColor”>#ff0000</item>
  6.         <item name=”android:textSize”>40sp</item>
  7.         <item name=”android:padding”>10dip</item>
  8.     </style>
  9. </resources>

In the XML we define a single style called WarningTextView, and we inherit from the parent built-in Android style Widget.TextView. We then set about overriding four attributes including the background, the text colour and size, and the inside padding. It’s easy to apply this style to any widget by using the style attribute (notice the style attribute isn’t prefixed with “android:”).

Applying the custom style to a TextView:

  • View source
  • Copy code
  1. <TextView
  2.        style=”@style/WarningTextView”
  3.        android:layout_width=”fill_parent”
  4.        android:layout_height=”wrap_content”
  5.        android:text=”Some SERIOUS words” />

With the style hooked up, here’s how it looks, in all its gaudy glory.

 

Comparing a standard TextView with a custom-styled TextView
Comparing a standard TextView with a custom-styled TextView

 

With styles you can override almost any property and apply it to multiple widgets in order to save you time and effort. Additionally you can override all instances of a component by setting the default style for a widget in an activity.

To do this we need to specify a theme. In the “Themes” project you’ll find a couple of styles defined in styles.xml this time.

Defining a theme to style all buttons in an app:

  • View source
  • Copy code
  1. <?xml version=”1.0″ encoding=”utf-8″?>
  2. <resources>
  3.     <style name=”MyTheme” parent=”@android:style/Theme.Black”>
  4.         <item name=”android:buttonStyle”>@style/MyButton</item>
  5.     </style>
  6.     <style name=”MyButton” parent=”@android:style/Widget.Button”>
  7.                 <item name=”android:background”>@drawable/btn_green</item>
  8.     </style>
  9. </resources>

This theme specifies a button style to use for all buttons. In order to apply this theme to our app, we must edit the project’s AndroidManifest.xml and specify a theme attribute for either the application tag, or a single activity.

Applying a theme to a whole application:

  • View source
  • Copy code
  1. <application
  2.        android:icon=”@drawable/ic_launcher”
  3.        android:label=”@string/app_name” android:theme=”@style/MyTheme”>

Wrapping up

We’ve seen how 9-patch can make for scalable graphics, but it’s a little known fact that 9-patch actually supports 25 slices! You just add two black lines on each side and it allows two regions to scale. This means you can have an icon in the centre of the image that is unaffected by scaling, reducing the complexity of your layout and increasing the performance of your apps.

If you really want to get a feel for how Android uses drawables to skin its widgets, dive into the Android SDK folder you extracted onto your machine and look for the SDK/platforms/android-8/data/res/drawable-hdpi folder (8 is the SDK version, Android 2.2 in this case). Find the file named “btn_default_normal.9.png”, this is the default button we replaced earlier. Remember the HDPI folder contains higher-res versions of everything in the MDPI folder. Either way these files provide a valuable starting point for creating your own skins.

From here you may want to also look at the styles.xml and themes.xml files inside the Android SDK res folders. These provide valuable information about how the standard widgets are all styled. Additionally we have the fonts. By default the “typeface” attribute only has a few limited options, but through code you can load and use custom font files with a combination of TypeFace.createFromAsset() and TextView.setTypeface().

In the past Android has been plagued by device manufacturers adding their own custom themes which can make your apps look unpredictable, from HTC’s white buttons to Samsung’s black buttons. With Android 4.0 developers can specify the new Holo theme and know that it will not change across devices regardless of the manufacturer’s custom theme. Either way if you have decided you want to customise the style of your widgets, you should go the whole hog, this way you know it will look exactly as you want and really stand out from standard looking apps.