Pages

Thursday 30 June 2011

View visibility

How do I hide and show view controls in my app?
View controls (TextView, EditText, Button, Image, etc) all have a visibility property. This can be set to one of three values:
  • Visible - Displayed
  • Invisible - Hidden but space reserved
  • Gone - Hidden completely
The visibility can be defined in the layout XML:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:orientation="horizontal"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    >
    <Button
     android:id="@+id/button1"
     android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:text="You can see me"
    android:visibility="visible" />
    <Button
     android:id="@+id/button2" android:dr
     android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:text="You cannot see me, but you can see where I am"
    android:visibility="invisible" />
    <Button
     android:id="@+id/button3"
     android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:layout_weight="1"
    android:text="You have no idea that I am here"
    android:visibility="gone" />
</LinearLayout>

For the LinearLayout above, the three buttons laid out horizontally with equal weights will be displayed as below. You can see the first, the space for the second, but not the third:



To set the visibility in code use the public constant available in the static View class:

Button button1 = (TextView)findViewById(R.id.button1);
button1.setVisibility(View.Visible);

You see?

Wednesday 29 June 2011

Quick Tip: Copyright symbol in a string

Very quick tip; to display the copyright symbol in your app, you can use Unicode definition in a string, as shown below:

<TextView
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:text="\u00A9 Android Elements 2011" />


Displaying the copyright notice in an app

Wednesday 22 June 2011

Opening call dialog

How do I make my app call a phone number?
The easiest method is to create an intent which opens the device caller dialog. Because this is not actually initiating the call, no additional permissions are required by your app.

final String phoneNumber = "01234 123456";
startActivity(new Intent(Intent.ACTION_DIAL, Uri.parse("tel:" + phoneNumber)));

Android dialler intent


Monday 20 June 2011

How to close soft keyboard on button press

How can my app hide the soft keyboard when a button is pressed?
A simple example of this requirement would be a search box within your app. This would be defined in your layout markup as a EditText view and a Button view. Once the user has entered some text, they will typically click on the search button. Default behaviour is that the soft keyboard is still visible until the user dismisses it. You can hide the keyboard using the following code, probably on the button click handler:

InputMethodManager inputMgr = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
EditText editText = (EditText)findViewById(R.id.editText);
inputMgr.hideSoftInputFromWindow(editText.getWindowToken(), 0);

The method requires a reference to the EditText view that was the source of the soft keyboard launch.

Wednesday 15 June 2011

First Steps: Returning values from an Activity

How do I return  a value from an Activity?
Below is some simple example code for creating a new Intent to launch an Activity named Activity1. Here we use the startActivityForResult method which takes the intent and an identifier (an arbitrary integer):

Activity1.java:
final static int REQUEST_CODE = 1234;

private void startActivity() {
  Intent myIntent = new Intent(getBaseContext(), Activity2.class);
  myIntent.setAction(Intent.ACTION_VIEW);
  startActivityForResult(myIntent, REQUEST_CODE);
}

In your second activity you should use the following code to return a result value and terminate the activity:

Activity2.java:
...
  setResult(1);
  finish();
...

Returning to your first activity and override the activity's onActivityResult method as below. Check the result code to determine the result is coming from the expected source then you can read resultCode and change logic depending upon its value:

Activity1.java:

...
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  super.onActivityResult(requestCode, resultCode, data);
  if(requestCode == REQUEST_CODE) {
    // Do something with resultCode
  }
}
...

It is worth noting that you can not open activities (or dialogs for that matter) in a modal fashion, in fact nothing is modal in android as that would lock the UI which is not permitted. Listeners are always used to receive the results.

Tuesday 14 June 2011

First Steps - Passing values to an Activity

How do I pass a value to an activity?

To start an Activity you use an Intent. In this intent you can pass data which is returned as a Bundle object.

Android Activities and Intents

Below is some simple example code for creating a new intent to launch an Activity named MyActivity. Note the call to the putExtra method which accepts a key name ("content") and a value:

Intent myIntent = new Intent();
String packageName = this.getPackageName();
myIntent.setClassName(packageName,
packageName + "." + MyActivity.class.getSimpleName());
myIntent.putExtra("content", "my content string");
startActivity(myIntent);

Here is the code for the called activity with the Bundle data extracted from the intent. You can then retrieve the passed extra content from the bundle object:

public class MyActivity extends Activity {

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.contentweb);

    Bundle bundle = getIntent().getExtras();
    String content = bundle.getString("content");
  }
}

All pretty simple when you know how.

Monday 13 June 2011

Android Development Tools ADT and DDMS Version 11 Release

Last week Google released a new version of the Android Development Tools (ADT). If you've not updated to version 11 yet, then DO IT NOW! There are a number of big improvements that will enhance your app development process, particularly regarding layouts and XML editing. Take a look at the video below for details of the update made at Google I/O 2011, if you've been developing on Android for a while, this should really get your juices flowing!



If you're not already then you should be following the Android Developers Blog (or @AndroidDev on Twitter).

How do update my tools in Eclipse?
Make sure you are running Eclipse as Administrator, then go to Help > Check for Updates.
Now just step through the sequence, agree to license terms then restart Eclipse when prompted.

Cannot install Android Development Tools / DDMS

If you see the following error when updating you Android Development Tools and DDMS in Eclipse on a Windows PC, you need to run Eclipse as Administrator.

"The operaton cannot be completed. See the details."

"Cannot complete the install because of a conflicing dependency."

Cannot complete the install because of a conflicing dependency

Thursday 9 June 2011

Creating an Android Preferences Screen

How do I add a preferences / setting screen to my android app?
Thankfully it is very easy to create a preferences screen, much like those you'd find within the Settings on your handset. A preference screen requires a special XML definition, you cannot use standard layouts and views, however this can still be placed within your layout folder.

The PreferenceScreen layout can be separated into sections with a PreferenceCategory which has a title and is displayed as a dividing bar o the screen. There are several preference type views:

EditTextPreference - text box entry (text string)
CheckBoxPreference - tickable check box (true/false boolean)
ListPreference - Selection from array of options (text string)
RingtonePreference - Selection of Uri of ring tones stored on device

A simple example of a preferences screen layout is shown below:

/res/layout/prefs.xml
Preferences screen
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
    android:title="Preferences">

  <PreferenceCategory
     android:title="Options">

     <CheckBoxPreference
       android:key="pref_opt1"
       android:title="Option 1"
       android:summary="Tick to set this option"
       android:defaultValue="true"
       />
    <CheckBoxPreference
       android:key="pref_opt2"
       android:title="Option 2"
       android:summary="Tick to set this option"
       android:defaultValue="true"
       />
  </PreferenceCategory>

  <PreferenceCategory
     android:title="Selection">
      
    <ListPreference
        android:key="pref_type"
        android:title="Type"
        android:summary="Select item from array"
        android:entries="@array/types"
        android:entryValues="@array/types_values"
        android:defaultValue="1"
        />

    <EditTextPreference
        android:key="pref_text"
        android:title="Input text"
        android:summary="Tap to enter some text"
        android:dialogTitle="Enter text"
    />
     
  </PreferenceCategory>

  <Preference
    android:title="Intent"
    android:summary="Open a webpage">

    <intent
      android:action="android.intent.action.VIEW"
      android:data="http://android-elements.blogspot.com/" />

  </Preference>
   
</PreferenceScreen>

The ListPreference in the XML above references two arrays; one for the option text and one for the option values. These should be defined in your strings resource file:

/res/values/strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string-array name="types">
     <item>Type 1</item>
     <item>Type 2</item>
     <item>Type 3</item>
    </string-array>
    <string-array name="types_values">
     <item>1</item>
     <item>2</item>
     <item>3</item>
    </string-array>
</resources>

Your activity must extend the PreferenceActivity rather than a standard activity. This should be defined as below:


src/your.package.name/Prefs.java
package com.example.com;

import android.os.Bundle;
import android.preference.PreferenceActivity;
public class Prefs extends PreferenceActivity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        addPreferencesFromResource(R.layout.prefs);
    }   
}

Don't forget to add this activity to your manifest!
You can read and write the prefence values in code with the following method examples...

// String
    public static String Read(Context context, final String key) {
        SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(context);
        return pref.getString(key, "");
    }
 
    public static void Write(Context context, final String key, final String value) {
          SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
          SharedPreferences.Editor editor = settings.edit();
          editor.putString(key, value);
          editor.commit();        
    }
     
    // Boolean  
    public static boolean ReadBoolean(Context context, final String key, final boolean defaultValue) {
        SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
        return settings.getBoolean(key, defaultValue);
    }
 
    public static void WriteBoolean(Context context, final String key, final boolean value) {
          SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
          SharedPreferences.Editor editor = settings.edit();
          editor.putBoolean(key, value);
          editor.commit();        
    }

Just as an aside, many apps I have build have been based upon a white theme rather than the default android dark. It is easy to set your preferences screen to use the built in Light theme so that it looks more consistent within your app, simply set the theme for the activity within your manifest as follows:

<activity android:name=".Prefs" android:theme="@android:style/Theme.Light">

Then your preferences screen will look something like this:

Preferences Screen (Light theme)

Please see my post on Introducing Themes for more information about themes and styles.

Monday 6 June 2011

Customizing the Title Bar

How do I change the title bar for my app?
Often I find that I want to remove the Android title bar from my app entirely and create my own within the layouts. To achieve this, just set the theme for the entire application, or individual activity to Theme.NoTitleBar then set my own title bar within the layouts as required:

AndroidManifest.xml
<application
  android:icon="@drawable/icon"
  android:label="@string/app_name"     
  android:theme="@android:style/Theme.NoTitleBar"
  <activity android:name=".Main" android:theme="@android:style/Theme.NoTitleBar" />

However, the standard title bar is fairly flexible in terms of background and text options (although centering the title text is not trivial). To modify it we start off by creating our own theme and, in this case, inherit from the default android theme. This theme contains system names for the android title styles and effectively overrides them. Where the name denotes a style, e.g. windowTitleStyle, a reference to a defined style is required.

/res/values/themes.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
  <style name="Theme.myTheme.TitleBar" parent="android:Theme">
    <item name="android:windowTitleBackgroundStyle">@style/windowTitleBackgroundStyle</item>
    <item name="android:windowTitleStyle">@style/windowTitleStyle</item>
    <item name="android:windowTitleSize">50dip</item>
  </style>
</resources>

/res/values/styles.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
  <style name="windowTitleBackgroundStyle">  
    <item name="android:background">@FF000</item>                
  </style>
  <style name="windowTitleStyle">
    <item name="android:textColor">#FFFFFF</item>
    <item name="android:padding">12dip</item>
    <item name="android:textStyle">bold</item>
    <item name="android:textSize">16sp</item>
  </style>
</resources>

Finally set the theme within the manifest for either the application or individual activities...

AndroidManifest.xml
<application
  android:icon="@drawable/icon"
  android:label="@string/app_name"     
  android:theme="@style/Theme.myTheme.TitleBar" >