Sunday, April 24, 2011

Creating and Using an Android Service

Services are used in an Android application to perform actions that do not require a user interface. The code called by a Service should run in a separate Thread from the application so it can continue even if the user closes the application. I used a service to download PDF and EPUB files from Connexions. Implementing the service called for creating the Service object, adding it to the ApplicationManifest.xml file, and calling the service from the MenuHandler class.

The Service is created by a class extending IntentService, creating a Constructor that calls the super() constructor and overriding the onHandleIntent() method. The onHandleIntent() method should contain the action to be performed by the Service. In the Connexions app, a DownloadHandler object is created to perform the download in a new Thread.

public class DownloadService extends IntentService
{
public DownloadService()
{
super("DownloadService");
}

@Override
protected void onHandleIntent(Intent intent)
{
DownloadHandler dh = new DownloadHandler();
String url = intent.getStringExtra(DOWNLOAD_URL);
String fileName = intent.getStringExtra(DOWNLOAD_FILE_NAME);
dh.downloadFile(getApplicationContext(), url, fileName);

}

}


Adding the Service to the ApplicationManifest.xml is a simple one line addition.



Calling the Service happens in the displayAlert() method in MenuHandler. If the user selects to download the file, the Service is created as an Intent and started.

public void onClick(DialogInterface dialog, int which)
{
String url = currentContent.getUrl().toString();
Intent intent = new Intent(context, DownloadService.class);

if(type.equals("pdf"))
{
intent.putExtra(DownloadService.DOWNLOAD_URL, MenuUtil.fixPdfURL(currentContent.getUrl().toString(), MenuUtil.getContentType(url)));
intent.putExtra(DownloadService.DOWNLOAD_FILE_NAME, MenuUtil.getTitle(currentContent.getTitle()) + ".pdf");
}
else
{
intent.putExtra(DownloadService.DOWNLOAD_URL, MenuUtil.fixEpubURL(currentContent.getUrl().toString(), MenuUtil.getContentType(url)));
intent.putExtra(DownloadService.DOWNLOAD_FILE_NAME, MenuUtil.getTitle(currentContent.getTitle()) + ".epub");
}
context.startService(intent);

} });


There are 2 Extras added to the Intent. These are used to pass parameters values that are needed by DownloadHandler. The URL of the file to download and the file name are passed to the Service and are retrieved in the onHandleIntent() method in the service. You can see the code for retrieving them in the onHandleIntent() example above.

As always, you can browse the source or download a zip file of the source. Connexions for Android is available in the Android Market or from the Connexions website.

Monday, April 4, 2011

Returning to a Specific Tab from Another Activity

In the Connexions for Android app, there is a TabActivity that has 3 tabs as shown in the screenshot. If the user preforms an action in any of the tabs, the next Activity moves outside the TabActivity.

On all of the Activities outside the TabActivity, there is a menu option to return to one of the Tabs (Search, Lenses, Favorites). One of the problems I had to solve was how to get the TabActivity to display the tab selected by the user outside of the TabActivity. All of the menu code is in one class, MenuHandler. In MenuHandler, if a tab is selected from the menu, an extra is added to the intent for the TabActivity. The extra tells the TabActivity which Tab to display.
'''
case R.id.go_to_favs:
  Intent intent = new Intent(context, TabWidget.class);
  intent.putExtra(TabWidget.TAB_ID, new Integer(2));
  context.startActivity(intent);
  return true;
'''

The extra is retrieved in the onCreate() of TabWidget (the TabActivity in the app). If there is a value for the extra, the current tab is set to it, Otherwise the current tab is set to the first tab.
...
Integer bigInt = (Integer)getIntent().getSerializableExtra(TAB_ID);
if(bigInt != null)
{
  tabHost.setCurrentTab(bigInt.intValue());
}
else
{
  tabHost.setCurre ntTab(0);
}


As always, you can browse the source or download a zip file of the source. Connexions for Android is available in the Android Market or from the Connexions website.