Archive

This morning I found an email in my inbox that looked like this:
The first impression was like “What?!”. It’s true that recently Google Play Developer Policies were modified, and I heard stories from developers who had their accounts terminated because of violations of content policy. So in the current context this email seemed like true.

However, after a closer examination I noticed a few suspect things.
1. Firstly, the email address ivopi44@abv.bg was too suspicious to believe that it is from Google.
2. Secondly, the email was sent not only to me, but to a list of people.
3. All the links appearing in the email pointed to the same and one url.
4. And lastly, the real urls were masked behind goo.gl URL Shortener, which again I found it suspicious.

So I opened one of the links in the email in a private window, and the following page was displayed.
The google Sign in box, the text that appears in the page, and the color scheme, makes it appear as something known for an Android developer.
However if you take a closer look at the page url, you may notice that the page is not hosted on Google servers, but on some address, savegaselectricity(dot)com. Also, it has a parameter named “continue” with the real google play page as value. Probably after successfully logging, to redirect you to real Google Play Developer Console page, so you won’t see notice anything strange.

The technique used by the attacker in fact is not new, it is one variation of impersonation attacks, where an attacker impersonates a legitimate site, tricking the users to log in and stealing their passwords.

So, if you will receive such an email, delete it, your google play account most probably is ok. If however you already used the fake page to login, change your password immediately.

As a rule of thumb, always be skeptical.
Do not click on links, download files or open attachments in emails from unknown senders. If you get one of these emails and are worried that there may be a real problem with your account, open up a new browser window, go directly to your Developer Console site and sign in there.

If you are working on a relatively complex project, chances are that you may need to build the application against different environments, such as a development, a staging, and a production environment. Assuming you are using Maven as a build tool, here’s one solution how Maven could help with this.

For the sake of this example let assume that you are working on an Android app that consumes web services. You have a dedicated development environment where you spent most of the time, but once every two weeks you need to make a version of the app that is built for production.

Let assume that the endpoint for the testing environment is dev.mysite.com, and for the production environment is: prod.mysite.com.
But as an aspiring developer and after reading a bunch of books about best practices, you can no longer accept to just go and manually edit the source files by changing all over the place one environment with another, and you ask yourself if Maven could help with this.

It can, and here’s how.
The main idea is to store all the properties, in this particular example all the urls, in separate resource files. Then, using maven resource plugin copy the corresponding property file into values/environment.xml.

This is a refactored version of a previous rss application example which had 1 major issue and gathered some discutions around that tutorial.
Starting with Android 3.0 and higher when trying to perform a network operation from the UI thread, the NetworkOnMainThreadException is thrown. The previous example did not address this issue. Why? Well… the tutorial didn’t have the purpose to present a stable application from all points of view, its main intention was to show how to use the XmlPullParser to parse an XML file.
The new tutorial fixes that issue, and along with that brings some improvements that will make this example easily adaptable to your specific needs.

What is new in version 2:
a) The RSS content is downloaded and parsed in an IntentService, thus it does not block anymore the UI thread.

b) The application now uses Fragments, thus being able to handle properly configuration changes like screen orientation, while performing the background work.

c) The application uses a custom adapter instead of built in ArrayAdapter. This will allow us to work with custom objects, rather than using string arrays like in previous example.

d) The rss parser was modified and now the code is much simpler. With minor adjustments it can be easily adapted to parse a different rss feed.

Requirements didn’t change, we still need to parse the PCWorld’s rss feed (http://www.pcworld.com/index.rss) and display the headlines in a ListView. When clicking on a list item, the built in web browser opens and user is redirected to the corresponding article.

Lets begin first with modification of AndroidManifest file.1. Add the internet permission:

<uses-permission android:name="android.permission.INTERNET" />

2. As the application uses a Service, it should be specified in the AndroidManifest too:

The MainActivity simply adds the RssFragment to the activity. First we check the savedInstanceState to see if it’s null, if so, it means we are entering the activity for the first time and the fragment can be added, otherwise we are returning from a configuration change, so we don’t need to add the fragment once again.

We are using the setRetainInstance() method to automatically save the fragment’s state across screen configuration changes. There’s however one thing that we should take in account. The onCreateView() method will be called each time on screen orientation. If the XML layout will be inflated again, you will loose the state of the views.
The solution is to keep the root of view hierarchy as a field in the fragment, so that is saved after configuration change. However, this view is still attached to the old hierarchy, so you need to remove it and re-attach it to the current hierarchy:

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
if (view == null) {
view = inflater.inflate(R.layout.fragment_layout, container, false);
//.....
} else {
// If we are returning from a configuration change:
// "view" is still attached to the previous view hierarchy
// so we need to remove it and re-attach it to the current one
ViewGroup parent = (ViewGroup) view.getParent();
parent.removeView(view);
}
return view;
}

To get the result from the service, we are using the ResultReceiver. This class allows us to receive a callback result from the service once the task is finished. The only thing we need to do, is to override the onReceiveResult().
Notice how the resultReceiver is passed to the RssService, before starting it:

A common task in Android is to perform some background activity in another thread, meanwhile displaying a ProgressDialog to the user. Example of these tasks include downloading some data from internet, logging into an application, etc. Implementing an AsyncTask is fairly a simple job, the big challenge is how to handle it properly when an orientation change occurs.

In this article I will walk though a series of potential solutions to address the screen orientation issues when using an AsyncTask.

So, lets create a proof of concept application that makes use of an AsyncTask which does not handle configuration changes yet, and then present a few solutions.

Here’s the AsyncTask implementation that we will be using during the tutorial:

– doInBackground() – this will be called by the AsyncTask on a background thread, and performs all the heavy work. For the sake of this example, I just wrote a simple loop with a delay of 1 sec between iterations to simulate a task that takes some time.
– The constructor of the class takes a listener as a parameter. The listener will be used to delegate the work of onPreExecute()/onPostExecute() to the calling Activity.

The Activity implements the TaskListener interface and provides appropriate implementation for its methods, displaying the ProgressDialog when the task is started, and dismissing it when the task is finished. The AsyncTask is fired when clicking on a button.

Now, if you run this example without changing the screen orientation, the AsyncTask will start and finish its work normally. Problems begin to appear when the device orientation is changed while the AsyncTask is in the middle of the work. The application will crash, and an exception similar to these ones will be thrown: java.lang.IllegalArgumentException: View not attached to window manager, or Activity has leaked window com.android.internal.policy….

The cause relies in the Activity life cycle. A change in device orientation is interpreted as a configuration change which causes the current activity to be destroyed and then recreated. Android calls onPause(), onStop(), and onDestroy() on currently instance of activity, then a new instance of the same activity is recreated calling onCreate(), onStart(), and onResume(). The reason why Android have to do this, is because depending of screen orientation, portrait or landscape, we may need to load and display different resources, and only through re-creation Android can guarantee that all our resources will be re-requested.

But don’t panic, you are not alone, there are several solutions that will help us to deal with this situation.

Solution 1 – Think twice if you really need an AsyncTask.

AsyncTasks are good for performing background work, but they are bound to the Activity which adds some complexity. For things like making HTTP requests to a server perhaps you should consider an IntentService. IntentService used in conjunction with a BroadcastReceiver or ResultReceiver to deliver results, could do a better job than an AsyncTask in certain situations.

Solution 2 – Put the AsyncTask in a Fragment.

Using fragments probably is the cleanest way to handle configuration changes. By default, Android destroys and recreates the fragments just like activities, however, fragments have the ability to retain their instances, simply by calling: setRetainInstance(true), in one of its callback methods, for example in the onCreate().

There’s however one aspect that should be taken in consideration in order to achieve the desired result. Our AsyncTask uses a ProgressDialog to signal when the AsyncTask is started, and dismisses it when the task is done. This complicates a bit the things because even if we are using setRetainInstance(true), we should close all windows and dialogs when the Activity is destroyed, otherwise we will get an: Activity has leaked window com.android.internal.policy… exception. This happens when you try to show a dialog after you have exited the Activity.

In order to address this issue, we will add some logic to keep track of AsyncTask status (running/not running). We will dismiss the ProgressDialog when the fragment is detached from activity, and check in onActivityCreated() the status of AsyncTask. If the status is “running”, this means we are returning from a screen orientation and we will just re-create and display the ProgressDialog to show that the AsyncTask is still working.

Solution 4 – Prevent the Activity from being recreated.

This is the easiest way to handle configuration changes, but the less advised. The only thing you need to do is to specify the configChanges attribute followed by a list of values that specifies when the activity should prevent itself from restarting.

Using this approach however, is not recommended, and this is clearly stated in the Android documentation:Using this attribute should be avoided and used only as a last-resort.

You may ask what’s wrong with this approach. Well, if you build the above example against Android 2.2 it will work fine, but if you build it against Android 3.0 and higher, you may notice that the application still crashes on orientation change. This is because starting with Android 3.0 you need also to handle the screenSize, and smallestScreenSize:

As it turns out, not only a screen orientation causes the Activity to recreate, there are also other events which may produce configuration changes and restart the Activity, and there’s a good chance that we won’t handle them all. This is why the use of this technique is discouraged.

By default Android comes with three standard fonts: Droid Sans (default font), Droid Serif, and Droid Sans Mono. They all can be applied to any view that supports styling, such as TextView, Button, by specifying the “android:typeface” attribute in the XML declaration with any of these values: sans, serif, monospace.

Using custom fonts in Android is pretty straightforward. First find a free font and put it in the assets/fonts directory. (It’s not mandatory to have a /fonts directory, but if I have a lot of stuff in the /assets directory I organize them in separate directories). Then get a reference to your TextView and create a Typeface object specifying the font path. Lastly, apply the typeface to the TextView.

If you get this exception while trying to integrate the custom font into your application, make sure the path to the font file is correct, and the font name is spelled correctly. I noticed I was getting this exception when my font path was misspelled, for example writing “.tff” instead of “.ttf”, or forgetting to add the “fonts/” prefix to the path.

The Google Analytics SDK for Android makes it easy for developers to collect valuable statics about how the users are using their app.

Here are some features that Android Google Analytics SDK offers:

The number of active users that are using the application

Usage of specific features

The number and type of application crashes

From where in the world the application is used

And many other useful metrics.

Just to illustrate the integration process lets create a simple proof of concept application with 2 activities: MainActivity and AboutActivity, and 2 buttons: Rate and Share.

Our mission is to integrate Google Analytics SDK with the application, to:

track activity views, (MainActivity and About)

track events (how many times the buttons “Rate”, and “Share” are clicked)

If you are searching for Google Analytics I’m assuming you are already pretty familiar with Android and could create the proof of concept application yourself, so I will skip this step and concentrate solely on integration.

At the moment of writing this post, Google provides two versions: version 1.5.1 (legacy), and version 2.0 beta. Still if the Version 2 of SDK is beta, I highly suggest you choose this version, over the 1.5.1 (legacy).
The reason not to choose SDK 1.5.1 is that it uses a tracking model that is designed to track visitors to traditional websites and interaction with widgets in traditional web pages.

The new “App” profiles and reports will only accept data from version 2 or higher of the SDK.

In version 2 of Google Analytics SDK for Android, the tracking settings are managed from an xml resource file called: analytics.xml. You will need to create this file in res/values directory, and add your tracking ID as well as other settings here.

One thing to note here is that EasyTraker requires a context before you can use it. If you attempt to call any of its methods but did not pass first a context, you may end up with an IllegalStateException.

In the above example, in the onStart() and onStop() methods the context is passed as an argument to activityStart() and activityStop(), but if you need to make EasyTracker calls in other classes or methods, you’ll need to call EasyTracker’s setContext(Context context) method first:

Context context= this; // Get current context.
EasyTracker.getInstance().setContext(context); // Set context
// EasyTracker is now ready for use.

6. Tracking events

Tracking events is just as easy as tracking activities, you just need a Tracker object and call the trackEvent(String category, String action, String label, int value) method.

In this particular example I don’t need a label nor a value, that is why I set for the last 2 parameters of trackEvent() method, an empty string a 0 (zero), but depending of your needs you may populate them with some data.

7. Debugging

Debugging helps you deal with troubleshooting, and make you sure that the data actually is sent to the server. To set the Google Analytics in debug mode, add the following setting in the analytics.xml

<bool name="ga_debug">true</bool>

Once your are in debug mode, you can watch the log information in LogCat:

Waiting for the big moment!

If everything is configured correctly, the reports should appear on live. Usually it takes about 24 hours to see the data in your account.

What happens if my application is used when no network is available?

Just in case you asked this yourself…, all the events are persisted in a local storage, and they will be sent the next time your app is running and dispatch is called.

Last but not least

One important thing not to be forgotten: you must indicate to your users, either in the application itself or in your terms of service, that you reserve the right to anonymously track and report a user’s activity inside of your app.