Sunday, 14 October 2012

Detecting and Handling Button Clicks on Android

In Android apps, there are two common ways to detect and handle user clicks on UI elements such as buttons: by attaching a listener to a layout item in Java or by including an onClick attribute in the item's layout XML code. Either way, you will typically include the Java code to execute on clicks inside the Activity class hosting the layout with the clickable item in it.

Here's an overview of each approach:

Attaching the Listener in Java

Include the button in an XML layout file, assigning it an ID attribute so that you can identify it in the Java Activity code:
<Button
android:id="@+id/your_button_id"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="@string/your_button_label"
/>

The text attribute should be a string included in your res/values/strings.xml file with the specified name:
<string name="your_button_label">Click Me</string>

In the Activity using the layout, applied as follows...
setContentView(R.layout.layout_file_name);

...extend the class to implement the click listener interface:
public class YourActivity extends Activity implements OnClickListener

In your onCreate method, find a reference to the button and attach a click listener to it:
Button yourBtn = (Button)findViewById(R.id.your_button_id);
yourBtn.setOnClickListener(this);

Add the onClick method to the class:
public void onClick(View v) {

}

Inside the method, find out whether your button has been clicked:
if (v.getId()==R.id.your_button_id) {  

}   

Inside the conditional block, you can add whatever code you want to execute when users click the button.

Using the onClick Attribute

Using the onClick attribute is typically a little simpler, although there are some cases in which it isn't possible, for example where UI items are being created programmatically in Java rather than in XML layout files.

To use this approach, include your button in an XML layout file with one additional line:
<Button
android:id="@+id/your_button_id"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="@string/your_button_label"
android:onClick="buttonClicked"
/>

The onClick method should include the name of the method you want to execute when users click the button. In the Activity class, the layout is set as the content view using the same technique as the first approach. When you use the onClick attribute there is no need to implement the click listener interface, to retrieve a reference to the button or to attach an event listener to it. Instead of providing the onClick method, include the method listed as your XML attribute in the Activity class hosting the layout with the button in it:
public void buttonClicked(View view){

}

The method name must match what you included in your XML attribute. Whatever method you list as an onClick attribute will receive a view parameter representing the UI item clicked. This allows you to use the same method to handle clicks on more than one item, just check which one has been clicked using the passed view parameter. Inside the method, include whatever code you want to execute when users click the button.

The onClick attribute is available on devices running Android API 4.0 and up.

Tuesday, 9 October 2012

Developing Android Clock Widgets

I recently created a tutorial series for Mobiletuts+ on creating an Android clock widget. It was the first time I had attempted the task, so I thought I'd share a couple of the things I discovered.

Analog or Digital

First, the process for creating analog and digital clocks is totally different. For an analog clock widget, the process is pretty straightforward, in fact the most time consuming part is probably creating your clock design. The basic tasks in creating a simple analog clock widget are as follows:

  • Create a widget project, setup the properties in the Manifest and XML resource file.
  • Create images for the dial, minute and hour hands for each density.
  • Add an AnalogClock element to your layout file.
  • Extend AppWidgetProvider and receive updates.

For a digital clock widget, more programming is involved. There is a DigitalClock class/ View, but unlike the AnalogClock, the DigitalClock cannot be used within the layout for a widget, only within standard apps. This means that you need to implement the details yourself, for example using a Service or AlarmManager for updating the widget appearance - there are potentially serious performance issues.

XML Layout

The following code outlines including an AnalogClock element within your widget layout file:
<AnalogClock
android:id="@+id/AnalogClockID"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:dial="@drawable/your_dial_image"
android:hand_hour="@drawable/your_hour_hand_image"
android:hand_minute="@drawable/your_minute_hand_image"
/>
Just replace the dial, minute and hour hand references with the names of your own drawable image files. The minute and hour hands should be included as though pointing at 12 o'clock, with the hands placed centrally horizontally within the dial image.

Clicks

If you do develop an Android clock widget, you need to decide what will happen on user clicks. Users have now come to expect certain behaviour as standard on clicking clock widgets, such as launching the device alarm clock (although there is as yet no standard way of doing this). Another option is to allow the user to configure the clock, choosing between designs - this is what I did in the tutorial series.

Launcher

Although widgets are of course accessed from the device homescreen, there is invariably the issue of users attempting to launch a widget app from the device menu. To accommodate this, you can add a launcher Activity to your widget app, which contains instructions on how to add the widget.

Conclusion

If you haven't attempted any Android widgets yet, don't be afraid to have a go, they are generally not too tough to implement. For clock widgets, it's easy enough as long as you go for analog, a little trickier for digital.

Related Info


Monday, 1 October 2012

Google's Project Glass

When Project Glass hit the headlines earlier this year following Sergey Brin's demo at Google I/O I must admit I wasn't massively interested. I've never thought much about Augmented Reality/ wearable computing other than finding the concept vaguely scary.

However, following the London Olympics/ Paralympics I found myself thinking about the role of technology in sport. It looks as though sport is going to be one of the main areas developers will look to target with Project Glass apps - there are already projects under development to that end.

Although I'm not competitive, I love to swim and started to think about the possibility of smart swimming goggles. Since Project Glass runs Android, I thought about how I would love to come up with some swimming apps. I'm a big fan of swimming techniques including the Shaw Method and Total Immersion, so initial app ideas would probably focus on the quality of the swimming experience rather than exclusively on competitive/ high performance aspects. Following a cursory Google search on the topic, I was pleased to find that the company has indeed acquired a patent for swimming goggles.

Anyway, this development has basically got me excited about programming for the first time in a while. Although I love developing applications, I haven't felt too creatively stimulated recently, mainly because I don't spend enough time working on my own projects. I've got a lot to learn if I do want to target these devices, as I know virtually nothing about AR or wearable computing at the moment. I'll be posting on the topic as I learn more about it, and keep my fingers crossed that the smart goggles do become a reality.

Here are some related links:

Hacking for Fun: Programming a Wearable Android Device
Could Google Glass Change Pro Sports Forever?
Google Googles For The Open Water?
Google Acquires Swimming Goggle Patent
Wikipedia: Project Glass
Project Glass on Google+

Thursday, 2 August 2012

Using the Android Crop Intent and Action

Recently I discovered that using standard intents and actions to capture and crop an image was not as straightforward as I had expected. I had assumed there would be a standard, reliable way to launch any apps that can perform a cropping action on images but was unfortunately wrong. Launching the camera is pretty consistent, but cropping an image you have either allowed the user to capture with the camera or choose from the device, for example with a file explorer app or the standard gallery app, is not so easy.

There is a generic action you can use for cropping that is supported on many user devices, but not all of them. The following represents the closest we have to a standard approach to launching a cropping Activity:

Intent croppingIntent = 
 new Intent("com.android.camera.action.CROP"); 

You need to pass various additional data values to the Intent before starting it, and if you want the cropped image to return to your code you need to call the Intent using startActivityForResult, then implement onActivityResult to process the returned cropped image.

So far so good, but unfortunately there are lots of Android vendors whose devices do not support this action. You have two broad options:

  • Only provide your cropping functionality to users whose devices support this Intent
  • Query the user device in order to target specific cropping Activities

If you opt for the first approach, you can include the code in which you call the Intent in a try block, with a catch block outputting an informative error message letting the user know why they can't complete the cropping action. If you opt for the second approach, you have a more complex task in front of you.

See this Stack Overflow post for an example of how to handle differing device crop Activities:
Android Camera Intent with Crop

For an overview of using the basic crop action above, see my tutorial on Mobiletuts+ for more details:
Capture and Crop an Image with the Device Camera

It seems the Android system is plagued a little by this type of issue. When approaching another task recently I found there is a similar problem when attempting to launch the alarm clock app on a user device - a common aim, particularly for clock widget apps.

Monday, 20 February 2012

Creating an Android Battery Widget


I recently approached the task of developing an Android widget for the first time. I created an Android battery level widget, mainly so that I could write a tutorial on it.

The tutorial was originally published on the Tuts+ marketplace, which has since ceased to operate. Here's a copy of it: Jump Into Android: Create a Battery Level Widget

Anyway, in this article I thought I'd run through a few tips for creating Android widgets, with specific guidance on retrieving and displaying information about aspects of phone state, such as the battery level. We won't go into too much detail here, but hopefully you'll find it a useful overview of Android widget development.


What's the Difference?

In many ways widget development for Android is the same as development for any other app type on the platform. However, although the differences are slight, they can throw you off when you attempt a widget for the first time. I would strongly recommend not attempting a widget as your first app, but instead trying Android widget development after you've tried developing at least one standard application.

You will presumably already know the difference between widgets and other Android apps from the user's point of view, so let's start there. Widgets are not launched from the application menu, but are instead added to the user's homescreen. Some widgets are interactive, normally allowing users to choose settings on pressing the widget once it is on screen, or when it runs for the first time. The download and installation process is basically the same as for other apps.


What you Don't Need to Do

Since widget apps are not launched in the same way as normal apps, your project structure does not need a main Activity class to execute when the application starts up. As well as removing the need for an Activity class file, this means you do not need to include your main launcher Activity in the project Manifest XML file.


What to Do Instead

Instead of a main Activity class, your widget apps need to extend the AppWidgetProvider class. You also need to include your widget provider in the Manifest as a receiver item, specifying a metadata file along with it. If your widget is going to update, you need to indicate this within the Manifest too, using an intent filter. Your metadata file should be saved in "res/xml" and the code within it should define the basic aspects of your widget, including its dimensions and update frequency where appropriate. The metadata file can also specify an initial XML layout resource to use when the widget appears.


Options

That's basically all you need for a widget, but depending on your own project you may need additional elements. For example, you can override the AppWidgetProvider methods, such as onUpdate, specifying what should happen when the widget updates, which will often involve altering the visual display.

You can optionally include an Activity in your app for configuring the widget. Similarly, you can make the widget interactive by supplying a click listener and presenting an options setting section for your users.


Running and Testing

Testing widgets is roughly the same as testing other Android apps, with some exceptions depending on the nature of your own particular projects. For example, when I created my battery level widget, I could only test it properly by running it on a device, because the emulator by default only shows a battery level of 50%. It's always preferable to test your apps on real devices anyway.

Some widgets have serious performance implications. For example, you can use the AlarmManager class to provide more frequent updates to a widget than you can using the XML metadata method. In such apps, you really need to pay extra attention to efficiency, or your users will be dismayed to see their battery levels draining too fast.


Phone State Including Battery Level

So far we've discussed widgets generally, but you have an additional set of considerations if you're creating a widget to indicate phone state such as battery level. To create this type of widget, you need to register for a receiver. This basically means telling the system to inform your app about changes in state.

If you are setting your widget update frequency in the XML metadata, the most often it can receive updates is every 30 minutes. To update more often, you can use a service, implementing an alarm if the widget needs to update when the device is asleep. You will also need a service if your widget is fetching data over the Web.

The Android system issues broadcasts about certain aspects of the device. Some of these are described as "sticky", including the battery level. This means that the last broadcast hangs around the system, allowing your widgets to access the data within it at any time. For a battery level widget that only updates at the frequency set in the XML metadata, this means that the displayed level will actually be whatever the last level broadcast was, which may have been any time in the past half hour at most. Naturally, this is not ideal for all apps, which is why many of them use services and alarms.


Conclusion

So that's an overview of the basics when developing widget apps. Here are a few related links:

Tuesday, 31 January 2012

Object Oriented Concepts for Android Development in Java

If you're learning Android development but have no prior experience of either Java or Object Oriented development in general, you can get yourself up to speed on the essential concepts pretty easily. A few aspects of Object Oriented development can help to make the best of your Android projects, without having to embark on a lengthy training process.

Providing you have programming experience of some kind, you can go some way towards getting to grips with Object Oriented Android by familiarising yourself with the basic principles we'll introduce in this article. Along the way we'll hopefully demystify some potentially confusing language you may have come across on the topic.

Classes and Objects

Object Oriented development essentially means dividing up the processing tasks in an application between a group of objects. Developers begin designing such applications by defining these objects at an abstract level, assigning the various responsibilities required by the app. To implement objects in code, you create class declarations.

A class declaration is normally a single file in a Java project, in which you declare the properties and behaviour that objects of the class will provide. Think of a class declaration as a description of an object in general terms. Once an app has a class declaration, other code within the application can create objects of the class, each of which will match the description outlined in the declaration, but with differences in terms of data.

The following Java code demonstrates a simple class declaration for illustration:

public class Worker {
  //instance variable
 private String name;
 
  //constructor method
 public Worker(String workerName) {
  name=workerName;
 }
 
  //method to return name
 public String getName() { return name; }
} 

Using Objects

Code external to the class, for example within another Java file in the application package, can instantiate objects of this class as follows:

Worker adminHelper = new Worker("Jim");
Worker managementHelper = new Worker("Mary");

This code declares and instantiates two Worker object variables. Stating the name and type of an object is declaring it. Creating an instance of the class and assigning this to the object variable is instantiation. Although these two objects are of the same class, they have different data, in this case simply the string name variable.

When this code executes, Java runs the constructor method within the class declaration. Within the constructor, the code assigns a value to the one class instance variable with the string value passed as a parameter when creating the new object. Once the "customer" code has an object of the class, it can call any public methods in it as follows:

String adminName = adminHelper.getName();

The "getName" method returns the string instance variable. Public methods and variables can be accessed outside the class, while private resources, such as the instance variable, are only available inside the declaration.

These examples are for demonstration and are therefore abstract, we'll get to practical, Android-based examples next.


Android App Classes

If you've already started developing Android apps you will have created classes, although some of them may have a different structure to the example above. The Android platform does certain things slightly differently to the typical Java application, but the same patterns apply.

Your initial Android projects will likely have some Activity classes in them. Unlike a standard Java class, an Activity class is instantiated by the system when your code creates and starts an Intent object, rather than by using the "new" keyword as in the example above. To dictate what should happen when an Activity class is instantiated, you add code to the "onCreate" method rather than a constructor.

You can create standard Java classes to handle specific processing areas within your apps, as well as using the Android classes. When your apps use classes within the Android platform, such as the Activity class, they use inheritance.


Inheritance

If you have any existing Android projects in which you have Activity classes, you have already used inheritance. The class declaration for an Activity starts like this:

public class HelpSection extends Activity

The class name will vary for your own Activities. The phrase "extends Activity" means that the class is inheriting from the Android Activity class. When a Java class extends another class, it inherits the methods of that class. The parent class being extended is referred to as the superclass, with the extending class known as the subclass. The following sample code demonstrates extending the Worker class above:

public class Administrator extends Worker {

 public Administrator(String adminName) {
  super(adminName);
 }
 
}

The constructor method in the subclass calls the constructor for the superclass. This class can provide additional methods and variables that are specific to its own area of responsibility. Inheritance is essentially a way to re-use code, with extending classes able to make use of existing resources within an application or within the Java and Android platforms.

By extending the Android classes, your own classes inherit their functionality, saving you from having to implement certain details. For example, the Activity superclass handles the details of presenting a user interface screen to your users.

The inheritance structures you are most likely to use at first are for user interface elements, but you can extend any existing Java and Android classes you find useful. This is a key feature of Object Oriented development, and allows you to focus your energy on the aspects of your own projects that make them unique.

Overriding

An inheriting class can provide a dedicated implementation of any method in the superclass it is extending. If you provide a method in a subclass that is also in the superclass, this new version of the method overrides the superclass version. If you want to carry out the same processing as the superclass method and then additional processing of your own, you can begin the method implementation by first calling the implementation in the superclass as follows:

public void doSomething() {
super.doSomething();
//additional processing
}


Interfaces

As we have seen, with class declarations, you define the behaviour of object instances. Interfaces are another way to influence object behaviour. An interface in Java is like a contract, specifying a series of methods that implementing classes must provide.

Interface declarations list method signatures, each signature including the method name plus an indication of the parameters and return type. Interfaces do not provide implementation details for the methods, so the implementing classes need to do this. In other words, an interface dictates what the class will do, and the class declaration describes how it will do it.

Again, if you have already started with Android you may have implemented some interfaces. The Android platform provides a range of interfaces for delivering user interaction, such as the "OnClickListener" interface. You can indicate that a class will implement an interface using the following syntax:

public class HelpSection extends Activity implements OnClickListener

If you are programming in an Integrated Development Environment such as Eclipse, the program will display error messages when you initially add this code. This is one of the most useful aspects of an IDE, as it reminds you to provide the interface methods, and will continue to show errors until you do.

For the "OnClickListener" interface, your class must provide the "onClick" method, responding to user interaction with your Activity. Implementing an interface is therefore making a commitment that your class will exhibit certain generic behaviours. It's up to you to decide exactly how your classes implement them.


Developing in Eclipse

Eclipse is designed for developing Object Oriented projects, so it has a number of features you may find useful for your Android apps. The Type Hierarchy view helps to visualise projects with reference to the concepts we've gone over here. For example, if you have a class which is extending another class, you can see its hierarchy within your application, and within the platform as a whole.


To see the Type Hierarchy, open the view by choosing Window, Show View, Hierarchy. The new pane will appear within your Eclipse window. Choose an inheriting class in your application and right-click on a reference to the class name in one of your Java files, then choose Open Type Hierarchy. You should see the hierarchy presented within the new view. All classes in Java ultimately inherit from the class Object, so you will see it at the top of the hierarchy tree structure.


Conclusion

Through OO development, you can work with re-usable code components which preserve the ability to specialise in unique application areas. This is sometimes referred to as polymorphism. The model allows you to make use of a wealth of existing code resources within both the Java language and the Android platform itself.

Regardless of your development background, learning the basics of Object Oriented development needn't be a difficult task, and can have a hugely positive impact on your Android projects.

The OO model is often used by developers working in teams, who need to be able to use one another's code without having to understand the implementation details within any particular section. This idea of an application being made up of code excerpts, each of which has clearly defined behaviours, is the key one to understand, whether you're working with classes and interfaces from your own apps, from the Android platform or from the Java language itself.

Monday, 30 January 2012

Android Text To Speech (TTS) Basics

When I originally attempted implementing TTS functionality in my apps I was yet again surprised by how few practical tutorials there were online. I wrote a detailed, practical one a while back for Mobiletuts+ which runs through a simple app with the Text To Speech engine functions: Using the Text to Speech Engine

However, if you just want to know the basics so that you can get stuck into adding the functionality to create your own Text To Speech apps, here's what you need to do:

Import the TTS Classes
To make use of the Text To Speech API, you need to reference it in your code. Add these import statements to your chosen class for standard functionality - includes the TTS resources and others necessary for basic tasks:

import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.content.Intent;
import java.util.Locale;

Implement the OnInitListener Interface
When using the TTS functions you configure your speech functionality in the onInit method, so you need your class to implement this interface. Add "implements OnInitListener" to the class declaration in which you plan on providing TTS. The following sample code demonstrates:

public class MyLovelyClass extends Activity implements OnInitListener

Check for User Data
Before you start making your apps speak you need to check that the user has the required resources on their device. Add the following instance variable at the top of your class declaration:

private int DATA_CHECKING = 0;

Next add the data checking code to the section of your class that executes when it starts up. I.E. for a standard Java class put it in the constructor method, for an Activity class put it in "onCreate" and so on:

//create an Intent
Intent checkData = new Intent();
//set it up to check for tts data
checkData.setAction(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA);
//start it so that it returns the result
startActivityForResult(checkData, DATA_CHECKING);

Create a TTS Object
So that you can access the Text To Speech object throughout the class, declare it as an instance variable at the top:

private TextToSpeech niceTTS;

When the app receives the result of your data checking operation, the onActivityResult method will execute, so add the code to instantiate the TTS in there:

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
 //do they have the data
 if (requestCode == DATA_CHECKING) {
 //yep - go ahead and instantiate
 if (resultCode == TextToSpeech.Engine.CHECK_VOICE_DATA_PASS)
  niceTTS = new TextToSpeech(this, this);
 //no data, prompt to install it
 else {
  Intent promptInstall = new Intent();
  promptInstall.setAction(TextToSpeech.Engine.ACTION_INSTALL_TTS_DATA);
  startActivity(promptInstall);
  }
 }
}

Most users do have the TTS data now but this code takes care of those cases where they don't.

Provide the onInit Method
Your class is extending the OnInitListener interface so that you can set the TTS object up to function when it initialises. Add the method as follows:

public void onInit(int initStatus) {
 if (initStatus == TextToSpeech.SUCCESS) {
  niceTTS.setLanguage(Locale.UK);
 }
}

This is the basic process for choosing UK English but the engine offers a wide range of possibilities.

Say It Loud
Now all you need to do is speak. Add this code wherever you want the speech to occur, passing a text string to speak:

String myWords = "I love you";
niceTTS.speak(myWords, TextToSpeech.QUEUE_FLUSH, null);

This instructs the app to speak straight away, but you can optionally choose to add it to a queue, waiting for any existing speech to finish. Again, there are lots of options to explore.

These are the basics of creating a TTS app on Android, but as mentioned above there are plenty of areas in which you can tailor and adapt the functionality.

If you're having trouble getting this to work in your apps, have a go at my other tutorial first, then try doing it with your own apps again: Using the Text to Speech Engine

Other resources:
Android Developer Guide: Using Text-to-Speech
Android Developer Reference: public class TextToSpeech