Wednesday 9 November 2011

Android: Programmatically sending (text) SMS messages

Quick and easy one:

...
  android.telephony.SmsManager shortMessageManager;
  shortMessageManager=SmsManager.getDefault();
  
  String phoneNumber="1110001100";
  String message="test text message";

  shortMessageManager.sendTextMessage(phoneNumber, null, message, null, null);
...

Very simple, the second NULL parameter to sendTextMessage is the address of the service center. Set it to NULL to use the phone's default setting (recommended).

If you want to know if the message was sent successfully or failed, create a pending intent and pass it as the forth argument to sendTextMessage. If you want to be notified when the message is delivered, create another pending intent and pass it as the last argument to the same method.

Good luck!

Thursday 27 October 2011

Android: Getting battery status, health, level

How to get the battery level of your android device?

Let's say you want to create a battery indicator that shows that level and health. The easiest way to do it is installing a broadcast listener for the intent ACTION_BATTERY_CHANGED.

In this example code

public class BatteryChangeBroadcastReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {
      int batteryLevel=intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
      int maxLevel=intent.getIntExtra(BatteryManager.EXTRA_SCALE, 0);  
      int batteryHealth=intent.getIntExtra(BatteryManager.EXTRA_HEALTH, 
                         BatteryManager.BATTERY_HEALTH_UNKNOWN);                
      float batteryPercentage=((float)batteryLevel/(float)maxLevel) * 100;

      //Do something with batteryPercentage and batteryHealth. 
      //batteryPercentage here ranges 0-100
 }
}

onReceive runs every time the battery level changes. More details about what batteryHealth means can be found here.

The caveat here is that this broadcast  receiver can start activities, i.e, it won't work if defined in the manifest file.
You need to manually register and unregister in your app code. This means your app must be running to receive the battery status.
Here's how it would look like using the broadcast listener above.

@Override
public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      mBatteryLevelReceiver=new BatteryChangeBroadcastReceiver();
      registerReceiver(mBatteryLevelReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
}


@Override
public void onDestroy(){
       super.onDestroy();
       unregisterReceiver(mBatteryLevelReceiver);
}


Unregistering the receiver after the app finishes is very important. You may even want to register/unregister during pause/resume.

And remember, the app must be running for this to work. I'm sure you can find a neat way of doing that ;)

Have fun

Monday 24 October 2011

Android: Programmatically loading large image/bitmap files

Hello!

The use of imagery in our Apps is practically mandatory. After all, the Man said "make it look great".
Embedding icons and images as resources in an App is trivial and the Resources class makes loading them even easier.

But have you tried lately loading a large image file, let's say like an 8Mp picture? Well if you haven't, try it and you'll see that there's not enough memory for that. And don't ever embed a picture that large as a resource in your app.

So how can we load something that we can't load because there's not enough memory? Very carefully and in steps.

1) Loading bitmaps
The Android Bitmap class possesses several factory methods to create bitmaps but unfortunately it does not solve our problems - and I understand is also not recommended. What is left to us is the super awesome BitmapFactory class.
To create a bitmap object using BitmapFactory just call one of its several decode* factory methods, for instance:

...
Bitmap testBitmap=BitmapFactoryClass.decodeResource(resources, R.drawable.myimage);
// do stuff with testBitmap
// recycle testBitmap
...

this creates a Bitmap from the resource  myimage and stores in testBitmap. We can also load from a file on, let's say, the SD card

...
Bitmap testBitmap=BitmapFactoryClass.decodeFile("/mnt/sdcard/picture.jpg";
// do stuff with testBitmap
// recycle testBitmap
...


if we do that to load a 3000x4000 pixels large picture, it will blowup in our faces. It will probably run out of memory loading an image half this size.

To get around this problem, we need to sample the image during the decoding phase.

2) Sampling a large bitmap
the code snippet below does all the hard work of sampling an image and returning it as a Bitmap object.
A few notes before you use it:

BitmapFactoriy.Options is the secret weapon, more specifically the field inJustDecodeBounds. Setting it to true will tell the framework to not try loading the image, instead just return its size (returned in options.outHeight and options.outWidth). Once we have the dimensions of the image, we can read it scaled down by a factor defined in the field inSampleSize.

The SDK recomends using inSampleSize in powers of 2 so the line

int sampleSize=(int) Math.pow(2, Math.floor(Math.sqrt(factor)));
 
tries to find the best power of 2 close to the sample rate you requested. It's simplistic but works  fine for almost all cases. My suggestion is you find what's best for your app. I recommend sampling the image to a bigger size than what you really want and then use Bitmap.createScaledBitmap to set the image to the size you want.
  
BitmapFactory.Options options=new BitmapFactory.Options();
options.inJustDecodeBounds=true;
BitmapFactory.decodeFile(fileName, options);
     
long totalImagePixes=options.outHeight*options.outWidth;
totalScreenPixels=__some_maximum_number_of_pixels_supported;
   
if(totalImagePixes>totalScreenPixels){    
 double factor=(float)totalImagePixes/(float)(totalScreenPixels);
 int sampleSize=(int) Math.pow(2, Math.floor(Math.sqrt(factor)));
 options.inJustDecodeBounds=false;
 options.inSampleSize=sampleSize;
 return BitmapFactory.decodeFile(fileName, options);
}
      
return BitmapFactory.decodeFile(fileName); 
 
Also, not this the variable sets the maximum number of pixels (i.e, total bytes used) that we want the sampled image to have.
You can use an approach like that or just find a sample size based on your needs. Again, it's simplistic but works majority of cases.

To recap, all  you need is to set inJustDecodeBounds to true, call decodeFile, set inSampleSize to the desired value (power of 2 preferably) and call decodeFile again.

Have fun!

Tuesday 18 October 2011

Android 4.0 Ice Cream Sandwich is here!

Exciting new SDK!

Some of the amazing new features for developers:

  • Unified UI framework for phones, tablets
  • Social API
  • Calendar API
  • Visual voicemail API
  • Android Beam
  • Low-level streaming multimedia
  • Media effects for transforming images and video
  • New media codecs and containers (support for Matroska!!)
  • Wi-Fi Direct
  • OpenGL ES texture views
  • Hardware-accelerated 2D drawing
  • VPN client API

And a lot more! Checkout the full change log here
Developers, don't forget to read the hightlights and the differences report.

oh, and watch the cool promo video

Tuesday 11 October 2011

Android: Getting the version of your App

(AKA how to get the version of the app from the manifest file)

I wrote previously here how to add logging to your app and one of the things you most certainly want to put in your log is the version of your software.
In fact I got a ton of messages asking how to do that, reason why I'm writing this quick and short post :)

There are two version fields that we should get: version name and version code.
Version name is however you want to call the version of your app and version code is an integer number that basically says "this version is new that the other one".
Both fields are attributes if the same name in the manifest file. You need to set it manually so look for android:versionCode and android:versionName.
Programmatically reading versionName and versionCode.

The attributes we set manually in the manifest file re available in the PackageInfo class.
To get an instance of PackageInfo with the fields for your app we will have to utilize the PackageManager class.
Example:

PackageManager pm=new PackageManager();
PackageInfo info=pm.getPackageInfo(getPackageName(),0);
Log.d("TestApp", "version name "+info.versionName);
Log.d("TestApp","version code "+info.versionCode);


Note that getPackageInfo takes 2 arguments. The first is the name of the package from which we want to get the version.
The method Context.getPackageName() gives us the name of the package for the current app (actually the app in the calling context).
The second are flags indicating what king of extra information we want. In our case 0 is sufficient but if you want to know more, check the documentation.

That's it, see you next time!

---
Programming tricks and tips for android developers

Wednesday 5 October 2011

Kindle Fire: Five reasons why we should get one

Amazon is really impressive.
Apparently Kindle Fire pre-orders are in the thousands per day already. I knew they would be successful but really? Thousands ? (I think the number yesterday was 50k/day).

Well, regardless I think it will not be an iPad-killer (gut feeling only) BUT I'm sure (gut sure) Kindle Fire will be a strong competitor to all tablets and pads alike.
Unless Samsung decides to cut violently the prices of their tablets, here's why I would buy a Kindle Fire:

1) Replace my old Kindle
Have a Kindle or any other e-Ink based e-reader but not a tablet? Buy a Kindle Fire. Even with the heroic efforts of makers of e-readers to add additional functionality like web browsing to their devices, we all know it sucks. Sure it can be used to reply that urgent e-mail if you don't have another option. Lots of patience required though. If only I had an Android device..

2) Amazon is behind it
New hardware is often expensive and whether you're a first adopter or not, the thought "what happens if anything goes wrong?" always crosses our mind.
And it's when things break that we all want quality customer service, something most people will agree Amazon is very competent at.

3) Small and light
I want a portable device not a tennis racket. Sure there are plenty of portable-sized tablets but are they really worth? Which takes us to the next reason

4) Very, very very affordable
Almost half its competitors price.
Sure the specs are not mind blowing but I don't think a tablet's camera will make much difference in my life (Fire doesn't have camera if you don't know). If I want descent pictures I'll use a proper digital camera. If not, I'll probably use my phone.

5) It's a Kindle on steroids
OK, not much of a reason my friends say, but if enjoy your kindle, you know what I'm talking about.

Now, have fun with your knew toy and remember: don't pay attention to what I just wrote. Follow your pragmatic inner voice.

Sunday 2 October 2011

Android: Implementing logging in your app


How much logging does one need?
How frequently should I log?
(How to use java.util.logging?)

Programming logging in your Android application
Eternal questions about logging and often they don't have a simple answer. Logs are important, even vital sometimes. I don't write anything that does not have some level of logging.
And when we're talking about logging for mobile apps, things can get more complicated.
Why? Well, logs are resources and resources in a mobile device are scarce (that's how I like to think anyway).

By telling the app to log something we are consuming CPU and generating I/O. So if we are iterating a large list something and logging every single iteration, we're probably using a lot of resources.

Which, again could be fine if the user is not being affected by that (if anything we're consuming power). It's all about how the user perceives the app whilst running.
So how to safely implement logging in your Android app?
Here's a few suggestions:

1) Use only 1 log file (do not rollover)
2) Limit it to a size you think is sufficient to capture enough information throughout the app's life cycle
3) collect error logs (by let's say, sending it to your app's remote server) but ONLY with user's agreement
4) log only what you need but with as much information as you can. You'll have to find the right balance for your app.
5) use the logging facilities existing in the SDK.

OK, less talk more code.
First let's learn how to create a logging mechanism using the java.util.logging package (that's right, not Android specific).

The java logging is very flexibly but basically we need 3 things
- a Logger object;
- a log handler;
- a log formatter;

the most simple combination of this 3 is used in the code snippet below

Logger myAppLog=Logger.getLogger("myAppLog"); FileHandler logHandler=new FileHandler("path_to_log.file",false); SimpleFormatter formatter=new SimpleFormatter(); logHandler.setFormatter(formatter); myAppLog.addHandler(logHandler);

The code uses a file as the output for the log messages and a simple text formatter.  By default the log file is in XML. You can write your own formatters just by extending one of the formatting classes.

We are done with the basic stuff, just call myAppLog.log(...), myAppLog.severe(...) or myAppLog.warning(...) however you think necessary. More information about these methods can be found here.

There are however a few details we must observe. All in this line of code

FileHandler logHandler=new FileHandler("path_to_log.file",false);

First the path to the log file. I recommend using the internal memory. I know, less space but has a faster access time. You can use methods like Context.getDir() to properly set a location for your log file.

The second parameter (boolean true) tells the log handler that we don't want to append, i.e, a new file is created every time.

Another thing is the size and number of log files. Remember that I suggested not rolling logs over and limiting the size? Well, we can't do that with the construction above.
For that we need to change that line to

FileHandler logHandler=new FileHandler("path_to_log.file", 100*1024, 1, false);

here we're telling the handler to limit the file to 100kb (100*1024) and to keep only 1 log file, always creating a new one.

Simple isn't it?
Let people know if you like this ;)


---
Programming tricks and tips for android developers

Sometimes I think Nokia is bipolar or something

And they are my favorite company ever, best hardware in the world.
But, man, they how like to change directions!
Check this out.
Nokia Aims Software At Low-End Phones

Android: Localizing your Android app - Part 2

Part two or our little localization tutorial. For a quick recap, we learned first here how to use string resources to leverage translation in localized applications.
The image below can help refresh your memory.

This solves the problem of translating the content of strings we put in your layout xml files. But what if we need to access those strings programmatically? Thanks to the fantastic Android framework, it couldn't be easier.
Using the Resources class you can access and resource embedded in your app, including strings.
Call Resources.getString(int resourceID) to get the desired string. Resource strings are defined under R.string.*.

For instance, consider the following resource string

<resources>
    <string name="app_title">Test app</string>
</resources> 



calling getString(R.string.app_title) returns "Test app".
You can call getResources() from the the app context to get ta resource object. More information here.

Now, what if I need different images and icons for different countries? Like the exit signs in English and French.
No problem, just name the drawable directory the same way we learned to name the values directory.
For instance, drawable-fr contains icons/images for the French locale, drawable-es for Spanish and you got the idea.
But we all learned that we should use different drawables for different screen densities, that's why we have by default the directories drawable-ldpi, drawable-mdpi and drawable-hdpi. In order to have localizable icon/images taking density under consideration, combine both qualifiers in the name of the directory. Like: drawable-fr-mdpi, which contains drawable resources for French and high density devices. More details about how to combine different qualifiers can be found here.

Ok, enough with translation, let's go talk about something more interesting now.
No, wait! Just a few more things about translating your app:
  1. Keep in mind that translated text will most likely have a different length than the original one. People say sentences in English are shorter than in French. I can't vouch for that :) but design the layout of your app considering text of variable size;
  2. it's a good idea to use resource strings for any text that will be displayed, even if that text does not need translation
  3. translating is not just about "replacing words". Be careful with the cultural significance of sentences and words.

To the other good stuff now: localizing: making your app support other cultural attributes like currency, date/time and number format.
1) The Locale class
All starts with the Locale class, which let's you get information about the current locale and all other available locales installed. To get an instance of the default Locale call the static method Locale.getDefault().
To get an instance of another available locale use one of the public fields in Locale, like Locale.GERMAN (default locale for Germany).
We'll talk more about it in the next sessions but you can find all you need to know about Locale here.

2) Date and Time
If you just want to access date or time formatted for the current locale, the easiest way is to use Calendar. (Actually I recommend calendar for and Date/Time reference. Never instantiate a Date object directly).
To get a Calendar object for a specific locale call the factory method Calendar.getInstance(Locale)
For instance
Calendar.getInstance(Locale.getDefault()) returns the calendar for the default locale
Calendar.getInstance(Locale.FRENCH) returns the calendar for the default French locale. Note that the locale in this case is more about country/culture than language.

Remember when dealing with dates you have to consider the time zone (no, just setting the locale isn't enough). To get a Calendar for a specific locale and time zone call Locale.getInstance(Timezone, Locale).
More information here.

More formatting
Formatting date and time is a very common task and to do it properly - taking the Locale under consideration - it's better to use SimpleDateFormat.This class provides facilities to format date and time anyway you need.
To instantiate a SimpleDateFormat object with a pattern and locale use SimpleDateFormat(String template, Locale locale). Don't forget to set the time zone calling SimpleDateFormat.setTimeZone(). More information here.

3) Currency and number
Formatting currency and numbers in general kind of go together. But not quite :)

First, to get general information about number formatting (like decimal separator, infinity representation, etc), use DecimalFormalSymbols. To get the decimal symbols for a particular locale use the constructor DecimalFormatSymbols(Locale).

The CurrencyClass helps us to get currency symbols for several locales (although you can get the almost the same things from DecimalFormatSymbol). Use CurrencyClass.getInstance(Locale) to get an instance representing currency for the target locale.

Formatting currency and numbers in general is a more elaborate task. The class used to format numbers in general is DecimalFormat.
DecimalFormat will take in consideration the current locale so the code prints

DecimalFormat formatter=new DecimalFormat("##.#");
System.out.println(formatter.format(123.4);

123.4 for a US (English) locale and
123,4 for a French locale.

Consult the documentation to learn more about formatting patterns but on you want to keep in mind is "$", used to format currency.

The problem with DecimalFormat is that it's not possible to get a localized instance of a DecimalFormat object through the class itself (to the moment, AFAIK).To get a localized object we need to use NumberFormat.
A call to NumberFormat.getInstance(Locale) will return an localized version of an object that has NumberFormat as base class. The documentation says it's possible that this object will not be a DecimalFormat object but so far the Android SDK always returns DecimalFormat (since it's the only numeric subclass of NumericFormat).

Calling NumberFormat.getInstance(Locale) will return a NumberFormat object that can be used to format numbers in general. If you don't care about a pattern, just call format(...) and you're done. If you need to specify a custom pattern for formatting, call applyLocalizedPattern if the pattern is already localized or applyPattern if the pattern is not localized (not using localized numeric symbols).

And this concludes our localization chat.
Have fun!


---
Programming tricks and tips for android developers

Friday 30 September 2011

Android: Programmatically receiving SMS messags

As I`m sure you already know or at least suspect by now, it`s possible to programmatically "intercept" incoming short messages like SMS and/or MMS. All you need is the right permissions and a few lines of code.
Preparing the manifest file
The first thing we're going to do is to give the app permission to receive SMS messages. Just add the uses permission android.permission.RECEIVE_SMS using the manifest editor or the xml tag
 
<uses-permission android:name="android.permission.RECEIVE_SMS"> 

directly into the manifest file.

Now that we can receive SMS messages, we need to register an Intent Broadcast Rreceiver that will be called whenever a message arrives. More information about broadcast receivers can be found here.

Before we continue with the changes to the manifest file, let's talk about implementing our broadcast receiver class. Fortunately the framework already has a handy base class for that so we just need to extend it and override the proper method.

In our example we'll use the following class:

class MySMSReceiver extends BroadcastReceiver{
  @Override
  public void onReceiver(Context context, Intent intent){
    //do something with the message received
  }
}

To register a broadcast receiver, in the application section of your manifest file add

<receiver android:name=".MySMSReceiver "> 
    <intent-filter> 
            <action android:name="android.provider.Telephony.SMS_RECEIVED" /> 
    </intent-filter> 
</receiver> 

The most important thing to notice in the xml snippet above is android:name=".MySMSReceiver ". the name attribute sets the class to be instantiated when the broadcast for the intent is received. The "." is not a type, we're just telling android to find the class MySMSReceiver in the current package.

Also note that the receiver has an intent filter tag, meaning that only that type of intent will be passed to the intent receiver. Android will make sure the receiver code runs even if your app is not running.

Now let's see how to get the content of the the received message.

The SMS messages in Android use the PDU format (Protocol Description Unit) meaning that the content (sender, body, etc) is available in text mode albeit encoded. But fear not, the API can easily decode PDU data.

The message received by the broadcast receiver is available in the extras of the intent under the tag "pdus". Let's change our receiver to decode the first PDU of the message received

  class MySMSReceiver extends BroadcastReceiver{
  @Override
  public void onReceiver(Context context, Intent intent){
    Object[] pdus=(Object[])intent.getExtras().get("pdus");
    SmsMessage shortMessage=SmsMessage.createFromPdu((byte[]) pdus[0]);

    Log.d("SMSReceiver","SMS message sender: "+
       shortMessage.getOriginatingAddress());
    Log.d("SMSReceiver","SMS message text: "+
       shortMessage.getDisplayMessageBody());
  }
}

And there we have it! You can find more about the fields in the message in the SDK documentation. Remember that SMS messages can be relayed through email-to-sms relays, meaning that the sender can often be an email address and not a phone number.

Wait, did you notice that pdus is an array? That's because the SMS protocol allows for 160 characters long messages only. If the message is longer than that, several PDU objects will be created.
So to assemble a message broken down into several PDUs, just iterate the array:

...
    Object[] pdus=(Object[])intent.getExtras().get("pdus");
    String sender="";
    StringBuilder text=new StringBuilder();
    // get sender from first PDU
    SmsMessage shortMessage=SmsMessage.createFromPdu((byte[]) pdus[0]);
    sender=shortMessage.getOriginatingAddress();
    for(int i=0;i<pdus.length;i++){
      shortMessage=SmsMessage.createFromPdu((byte[]) pdus[i]);
      text.append(shortMessage.getDisplayMessageBody());
    } 
...

Next post I will talk about sending SMS messages, which is much easier  ;)

---
Programming tricks and tips for android developers

32 (or so) big mobile fails

Whatever Happened to the iPad Rivals of 2010?
The (mostly) sad fates of 32 early answers to Apple's tablet.

Full story here.

RIM still betting on Playbook

I had to post it here. Mostly because I think it's funny.
Rumors suggesting that the BlackBerry PlayBook is being discontinued are pure fiction," RIM spokeswoman Marisa Conway said in an emailed statement. "RIM remains highly committed to the tablet market and the future of QNX in its platform."
Source here

Thursday 29 September 2011

Android: Localizing your Android app - Part 1

Nowadays one could think that everybody speaks English so your English-only app is probably good enough.
Well, localizing software is not just about translating, there are several cultural and behavioral aspects you have to consider.
The Android framework brilliantly provides us with several resources to make our apps shine anywhere in the world.

As I said, depending on the app, we need more than just translating to make it localized. A financial app definitely wants to use the correct currency and number formatting of the targeted country/culture.

That said, today we will start small: learning how to write our apps so it can be easily translated to other languages.


1) Using string resources
One  of the first things we learn (or should have learned) in computer programming is to never leave hardcoded strings (text) lying around in the code. That, by the way, is a code smell and it's why we make constants.

However when we're talking translation of text to another languages, the simple use of constants is not useful anymore.
We need to put ALL strings/text that will be DISPLAYED to the user in a separate place. The Android solution for that is the use of string resources.

By default, a file called strings.xml is created by Eclipse under res/values/ and it looks somewhat like this:

<xml version="1.0" encoding="utf-8">
<resources>
    <string name="app_title">Test app</string>
</resources> 


Eclipse has a nice editor to help you edit and add more strings but you'll find that editing the XML directly is more efficient. So to add a new string (anything you want to localize), just add a new string node setting the attribute name to something you know to be unique.

The name is how we refer to that string in our app. For instance, if my title of the application is displayed in a TextView sitting on the activity's layout like

<TextView android:text="Test app"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/> 


the "localizable" version of the TextView would look like

<TextView android:text="@string/app_title"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/> 


by referring to the content using @string we are telling the framework to find the string resource where name=app_title and use it as text for the TextView.

Tips when working with string resources:
  1. use them even if you're not planning to translate your app;
  2. the default file is called strings.xml but what really matters is the xml tags so you can name your string resource files the way you find more appropriate;
  3. if your app has several activities and/or fragments, it's probably a good idea to create multiple string resource files;
  4. name (remember name="..." attribute?) the strings as if you're naming variables: you'll need to refer to them quite often.
  5. you can use xml tags in your string resource files and the framework will automatically interpreted them for you. For example if you put Test app as the content of the string, android will display the text in bold letters.

2) Creating string resources for each of the languages
Now to the interesting part: the translated resources.
I wrote somewhere above that the string resources reside under res/values. Well, the name of directory values is that one that tells android what language the string resources are. The name of the directory is prefixed with a dash "-" plus the locale code for the language in question.

 
So a directory called values-fr will have content in French, values-es in Spanish and so on. Creating another strings.xml under res/values-es with the content



<xml version="1.0" encoding="utf-8">
<resources>
    <string name="app_title">Aplicación de Test</string>
</resources>



will make your app automatically display the content in Spanish for devices using Spanish locale.
notice that the name "app_title" is the same and must be the same for any locale.

The directory res/values contains the default string resources for any locale and it's always a good practice to have defaults.

3) Testing your app

Testing the translated version of your app is simple, just change the locale of the phone/emulator and reboot it (at least I always had to reboot for the change to take effect).
To change the locale in the emulator, click on the apps button and you should see an app called Custom Locales. Select an existing one or create your own.
Reboot the emulator and done!

Next post I will talk about using resource strings in the code and how to localize other types of resources.



---
Programming tricks and tips for android developers

2011 ig Nobel Prize is out

A little off topic but interesting nonetheless.

From The 2011 Ig® Nobel Prize Ceremony:
The 2011 Ig Nobel Prize Ceremony Thursday, September 29, 7:30 pm. Sanders Theater, Harvard University, Cambridge, Massachusetts The 21st First Annual Ig Nobel Prize Ceremony will introduce ten new Ig Nobel Prize winners. The winners will travel to the ceremony, at their own expense, from several continents. The Prizes will be handed to them by a group of genuine, genuinely bemused Nobel Laureates, assisted by a large number of assorted Ig personnel, all before a perpetually standing-room only audience.
Past winners list

Wednesday 28 September 2011

Kindle Fire: E-Ink goodness is no more

I think even the dead know by now that Amazon has announced their own Android tab: called Kindle Fire, AKA iPad Killer (or Galaxy Tab Killer, Xoom Killer, *Killer).

Smart move but the media here in North America have no idea what they're talking about when they say this device could cause Apple et al problems. Not that I'm defending any of the already established tablets, it's just that nobody is looking at the hardware specs.

Granted not much is known about what's inside Fire's case but it's clearly not a challenge for, let's say, an iPad  - the new Kindle doesn't even have a camera.

Ok, most Kindle users probably will not care for the hardware because the price is exceptionally good when compared to other tablets. Some Samsung's tabs have similar hardware and are much more expensive.

I have a traditional Kindle reader and in my opinion it's an awesome reader only because of the e-Ink screen. Kindle Fire sports a LCD IPS display, which is not so great for reading.
Will Kindle Fire potential buyers realize that before rushing to the e-store? Maybe the new IPS display is better than I think it is and in this case I apologize Amazon.

My point here is that there's no point. Tabs and Phones are all about the apps and in Amazon's case: books. Android market+Amazon store have more than enough stuff to keep you busy.
If you want an e-book reader and a tablet, you will probably buy the Fire.

It's not out until November but Amazon is accepting orders (last time I checked).

Samsung shipping Galaxy Tab 8.9 in October in US


Samsung Galaxy Tab 8.9 Pre-Order Goes Live, Galaxy Players 4.0 And 5.0 To Follow Checkout the full news

Tuesday 27 September 2011

Android: Creating a transparent/translucent applications (activity)

Recent posts:
Android: Localizing your Android app - Part 1
Android: displaying widgets in a grid-like layout
Android: displaying widgets in a grid-like layout - Part 2, The TableLayout
Android: Getting all and maximum megapixels supported by the camera
Android: Taking pictures without a preview window
Android: Sending emails without user intervention

I get this question all the time and the solution is very simple.
Just set the theme of the app to one of the following:

  • Theme.Translucent
  • Theme.Translucent.NoTitleBar
  • Theme.Translucent.NoTitleBar.Fullscreen

To do that, just edit the manifest file and add, in the application section, android:theme="@android:style/Theme.Translucent" (or any of the above)

for instance
<application android:icon="@drawable/icon" android:label="@string/app_name" android:theme="@android:style/Theme.Translucent">
...

This will make your app look like this


Theme.Translucent.NoTitleBar and Theme.Translucent.NoTitleBar.Fullscreen  produce


I think Theme.Translucent.NoTitleBar.Fullscreen was supposed to hide the system's status bar but what happens is that the status bar is never hidden. When using any of the *Fullscreen themes, the app window just extends on top of the status bar.

Have fun.


---
Programming tricks and tips for android developers

Monday 26 September 2011

Apple reportedly cuts iPad orders by 25% for Q4 – or production shifts to Brazil

Holly crap! Could it really be? Full story here

Sunday 25 September 2011

Is project Kal-El really the future of mobile gaming?

Don't know, but so far it's looking very cool, check out the video.



More here

Friday 23 September 2011

Android: displaying widgets in a grid-like layout - Part 2, The TableLayout

Continuing the layout series, I'll talk about how to display content in a grid style using TableLayout.

To make use of the TableLayout we need 2 elements: TableLayout and TableRow. One TableLayout element can have multiple TableRows. Each TableRow represents a row (I'm so obvious) and everything we put inside a TableRow creates 1 column.

For example

<TableLayout android:layout_width="match_parent" android:layout_height="wrap_content">
  <TableRow android:layout_width="wrap_content" android:layout_height="wrap_content" >
    <TextView android:background="#555555" android:text="Cras in eros nunc" android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
    <TextView android:background="#999999" android:text="non viverra justo" android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
  </TableRow>
</TableLayout>


this layout snipped will produce this

Each text view is one column. I again changed the background colour just to make it easier to differentiate each column.

and when I add 2 more TextViews like this


<TableLayout android:layout_width="match_parent" android:layout_height="wrap_content">
  <TableRow android:layout_width="wrap_content" android:layout_height="wrap_content" >
    <TextView android:background="#555555" android:text="Cras in eros nunc" android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
    <TextView android:background="#999999" android:text="non viverra justo" android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView> 


    <TextView android:background="#555555" android:text="1" android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
    <TextView android:background="#999999" android:text="01/01/2011" android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
  </TableRow>
</TableLayout>



I get this

2 more columns, which is pretty cool, except for the fact they look like a single string of text.

To make the columns use all available width, we just need to the table which columns we want to "stretch" changing the attribute android:stretchColumns. This attribute takes a list of columns indices (zero-based), separated by commas if you want to stretch more than one.


For instance, I want to give more space for the last two columns (2 and 3)

<TableLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:stretchColumns="2,3">
  <TableRow android:layout_width="wrap_content" android:layout_height="wrap_content" >
    <TextView android:background="#555555" android:text="Cras in eros nunc" android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
    <TextView android:background="#999999" android:text="non viverra justo" android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView> 


    <TextView android:background="#555555" android:text="1" android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
    <TextView android:background="#999999" android:text="01/01/2011" android:layout_width="wrap_content" android:layout_height="wrap_content"></TextView>
  </TableRow>
</TableLayout>


This makes my table look like this



Much better but still not very good. Let's tell the table to stretch all columns. Just put a * as the value for stretchColumns

<TableLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:stretchColumns="*">

and bang, there you have it


We can also do the opposite, instead of giving more space for columns, we can shrink them using android:shrinkColumns. Let's say that 3rd column ( index 2), the one with the number "1" is using too much space. Changing the TableLayout definition to 


<TableLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:stretchColumns="0,1,3" android:shrinkColumns="2">


produces


To hide (collapse) a column, use android:collapseColumns again passing the indices of the columns you want to get rid of.

And if you want more lines in your table, just keep adding TableRows. You can put virtually anything inside a TableRow just remember that the column with the largest width wins!

Naturally you'll have to find what fits your app best. Remember to test with different screen densities and orientations. Be aware of TABS!!


---
Programming tricks and tips for android developers

Wednesday 21 September 2011

Android: displaying widgets in a grid-like layout

(UPDATE)
Now that Ice Cream sandwich is here, we also can user the new GridLayout. I'll write about it as soon as I have time.

It sounds simple but I get this question all the time: How do I make TextView, EditText, Buttons, and such to be evenly distributed in a grid like layout?

There are many ways to do that (I think) but the simplest one is using a standard LinearLayout with android:orientation="horizontal", adjusting the property layout_weight of each widget inside the layout.

If we create a layout like this


<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Cras in eros nunc"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="non viverra justo"/>
</LinearLayout>


we'll get this

which one could say doesn't look very good.
But if we add android:layout_weight="1" to each of the text views, like 

<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Cras in eros nunc"/>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="non viverra justo"/>
</LinearLayout>


the 2 text views will use respectively 50% of the width of the parent, looking like this

 android:layout_weight basically set how much of the usable area a widget can use. It accepts floating numbers so we can do things like this:

<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.1"
android:background="#ff0000"
android:text="Cras in eros nunc"/>

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="0.9"
android:background="#0000ff"
android:text="non viverra justo"/>
</LinearLayout>




and get this

note that I changed the background colour just to make the difference more visible.

As I mentioned, the weight is applied to the available area inside the parent and in the examples above, the parent has android:layout_width="fill_parent". If we change it to android:layout_width="wrap_content" this happens.


So be aware of your surroundings!

Next post I'll talk about TableLayouts and TableRows.

Have a good one!

Tuesday 20 September 2011

Android: Getting all and maximum megapixels supported by the camera (s)

In your camera app you often need to give the user options for picture size, supported by the camera that is. Or even if it's not an options, you might want to set the picture size to the maximum possible.

To do that you first need to get a list of supported image sizes. The method
Camera.Parameters.getSupportedPictureSizes
( documented here) can help us with this task. The returned value is a list of picure sizes which (among other things) contains the width and height of the supported picture size. With some simple math we can get the number of Megapixels supported by the camera.

So less talk more code


public List getAllSupportedMegapixelsByCamera(int cameraID){
  List mpList=new ArrayList();
  Camera myCamera=Camera.open(cameraID) ; // use Camera.open() for the default back facing camera or if you're supporting an older sdk version.
  
  // make sure the camera is not in use or something.
  if(myCamera!=null){
    Camera.Parameters allParams=myCamera.getParameters();
    for(Camera.Size pictureSize: allParams.getSupportedPictureSizes ()){
      int sizeInMegapixel=Math.round((pictureSize.width*pictureSize.height)/1000000);
      mpList.add(sizeInMegapixel);
    }
  }

  return mpList;
}
The returned list will contain values like 2 5 7 ... meaning that the camera supports pictures of size 2 5 and 7 megapixels.

Two not-so-popular and really cool Android games

Since I started talking about apps, I tried 2 puzzles this weekend that are the kind of thing developers like. The first one is Isaac Newton's Gravity. Several physics puzzles that can be quite challenging and make you spend hours trying to crack them.

The other one is Minesweeper 3D. Not much to say about it, except that it's a great revamping of a classic.

Monday 19 September 2011

Top (free) financial apps for Android

A little off topic (or not) but I'd like to share my excitement when I found that most major banks (and Canadian top 5 banks) have free financial apps for their customers. It's probably obvious and one could argue that the app is not actually free since you need a bank account. But since even King Kong has a bank account these days, it's probably worth checking out the apps before expending too much money on a paid one that does the same thing.

Sunday 18 September 2011

Android: Taking pictures without a preview window

Why on earth one would want to take a picture with your Android phone without knowing what's going to be capture? Well, apps have their reasons, like the SOS app NoDistress.


Taking pictures programmatically is easy: do the same thing you'd do but set a dummy surface view to the camera.

Example

public void takePictureNoPreview(Context context){
  // open back facing camera by default
  Camera myCamera=Camera.open();

  if(myCamera!=null){
    try{
      //set camera parameters if you want to
      //...

      // here, the unused surface view and holder
      SurfaceView dummy=new SurfaceView(context)
      myCamera.setPreviewDisplay(dummy.getHolder());    
      myCamera.startPreview(); 
      
      myCamera.takePicture(null, null, getJpegCallback()):
      
    }finally{
      myCamera.close();
    }      

  }else{
    //booo, failed!
  }


  private PictureCallback getJpegCallback(){
    PictureCallback jpeg=new PictureCallback() {   
      @Override
      public void onPictureTaken(byte[] data, Camera camera) {
        FileOutputStream fos;
        try {
          fos = new FileOutputStream("test.jpeg");
          fos.write(data);
          fos.close();
        }  catch (IOException e) {
          //do something about it
        }
      }
    };
  }
}


---
Programming tricks and tips for android developers

Android: Sending emails without user intervention (Using Javax Mail API).

Android API doesn't have support for any email protocols but the good news is that there's a javax implementation (a very good one by the way) here.
Download here these files:

  • mail.jar
  • additionnal.jar
  • activation.jar

and add them to your Android project as external jars. To do that in Eclipse, open the project properties (right click on the project name and click properties) and select Java Build Path. Click on the tab Libraries and them Add External JARs. Select the downloaded files and that's it.


Here's a simple example to programmatically send emails using SMTP with authentication but NO SSL/TLS:

public class MySMTPSendMail extends javax.mail.Authenticator {

  private String mUserName;
  private String mPassword;
  private String mHostName;

  public void sendEmailTo(String user, String password, String hostname, String recipient, String body)  throws AddressException, MessagingException{

    mUserName=user;
    mPassword=password;
    mHostName=hostname;

    Properties props = getProperties();


    // this object will handle the authentication
    Session session=Session.getInstance(props,this);
    MimeMessage emailMessage=new MimeMessage(session);
    BodyPart msgBody=new MimeBodyPart();
    MimeMultipart bodyMultipart=new MimeMultipart();


    emailMessage.setFrom(new InternetAddress(mUserName));
    emailMessage.setRecipient(MimeMessage.RecipientType.TO, new InternetAddress(recipient));  

    emailMessage.setSubject(body);    
    msgBody.setText(body);   
    bodyMultipart.addBodyPart(msgBody);
    emailMessage.setContent(bodyMultipart);

    Transport.send(emailMessage);
  }

  private Properties getProperties(){
    Properties props = new Properties(); 
   
    props.put("mail.smtp.host", mHostName);   
    props.put("mail.smtp.auth", "true");           
    // default SMTP port
    props.put("mail.smtp.port", "25"); 
  }

  @Override 
  public PasswordAuthentication getPasswordAuthentication() { 
    return new PasswordAuthentication(mUserName, mPassword); 
  } 
}

To send emails using SSL encryption, just change the method getProperties() to something like

  private Properties getProperties(){
    Properties props = new Properties(); 
   
    props.put("mail.smtp.host", mHostName);   
    props.put("mail.smtp.auth", "true");           
    // default SMTP over SSL port
    props.put("mail.smtp.port", "465"); 
    props.put("mail.smtp.socketFactory.port", "465");
    props.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory"); 
    props.put("mail.smtp.socketFactory.fallback", "false"); 
  }


To send emails using TLS encryption (e.g, live.com) change the method getProperties() to

  private Properties getProperties(){
    Properties props = new Properties(); 
   
    props.put("mail.smtp.host", mHostName);   
    props.put("mail.smtp.auth", "true");           
    // default SMTP over SSL port
    props.put("mail.smtp.port", "465"); 
    props.put("mail.smtp.socketFactory.port", "465");
    props.put("mail.smtp.starttls.enable", "true");   
  }

Good luck!! ;)

Saturday 17 September 2011

Android: Modifying UI elements from inside a Thread

Just don't do what the title says :)

Modifying anything that extends the View class from inside a thread is bound to fail. This is very common in any widget/UI SDK and Google brilliantly provided us with a few options.

The first one - that I will not talk about much - is Activity.runOnUIThread. Just create a class extending Runnable and call this method. If the current thread is not the UI thread, the runnable will be posted to the main thread event queue and processed later. So DON'T abuse this call or you may overwhelm the main thread.

A much more flexible and interesting approach is to use AsyncTask, which allows you to neatly organize code that must run asynchronously an in the main (UI) thread.
Again you'll have to create your on class extending AsyncTaks with 3 generic types: Parameters, Progress and Result.

The most common use of your class would be:
  1. override the method doInBackground implementing all that stuff that has to happen in background;
  2. override onPostExecute implementing the code that MUST run in the UI thread
  3. Call execute(Params...) to start the task;

For instance:


public class CalculateMD5 extends AsyncThread<String, int, String>{
  @Override
  protected String doInBackground(String... filename){
    // running in background
    // calculate md5 of files
    ...
  }

  @Override
  protected onPostExecute(String result){
    // running in the UI thread
    myTextView.setText("MD5: "+result);
  }
}

 

if you wan to display the progress to the user, call publishProgress from doInBackground and override the method onProgressUpdated, which also runs in the UI thread.

public class CalculateMD5 extends AsyncThread<String, int, String>{
  @Override
  protected String doInBackground(String... filename){
    // running in background
    // calculate md5 of files
    publishProgress(number_of_bytes_processed/total_bytes);
    ...
  }

  @Override
  protected onPostExecute(String result){
    // running in the UI thread
    myTextView.setText("MD5: "+result);
  }

  @Override
  protected void onProgressUpdate(int... progress){
    //% processed ...
  }
}

 
and last but nor least, if you need to prepare things before the background processing starts, override onPreExecute, another method that runs in the UI thread.

You must start the task from the UI thread.
You should always check if the task is not cancelled in your doInBackground method. Use isCancelled for that.

Simple isn't it? So recaping what runs where:
  • UI Thread
    • onPreExecute
    • onProgressUpdate
    • onPostExecute
    • onCancelled
  • Backgroun thread
    • doInBackground
---
Programming tricks and tips for android developers